permet l'ajout des frameworks et des routes

This commit is contained in:
22107988t
2023-09-25 09:41:55 +02:00
parent 0b9f7d4dfb
commit 361112699c
2787 changed files with 864804 additions and 0 deletions

174
app/node_modules/cejs/application/OS/Windows/Excel.js generated vendored Normal file
View File

@@ -0,0 +1,174 @@
/**
* @name CeL function for Excel
* @fileoverview 本檔案包含了 Excel 專用的 functions。
*
* @since
*/
'use strict';
// 'use asm';
// --------------------------------------------------------------------------------------------
// 不採用 if 陳述式,可以避免 Eclipse JSDoc 與 format 多縮排一層。
typeof CeL === 'function' && CeL.run({
// module name
name : 'application.OS.Windows.Excel',
require : 'data.code.compatibility.|data.native.'
// library_namespace.parse_CSV()
+ '|data.CSV.|application.storage.',
// 設定不匯出的子函式。
// no_extend : '*',
// 為了方便格式化程式碼,因此將 module 函式主體另外抽出。
code : module_code
});
function module_code(library_namespace) {
var module_name = this.id;
/**
* null module constructor
*
* @class Node.js 的 functions
*/
var _// JSDT:_module_
= function() {
// null module constructor
};
/**
* for JSDT: 有 prototype 才會將之當作 Class
*/
_// JSDT:_module_
.prototype = {};
// const: node.js only
var execSync = require('child_process').execSync;
// read .XLSX file → {Array}data list
// 轉成 tsv 再做處理用的 wrapper 函數。
// 必須先安裝 Excel
function read_Excel_file(Excel_file_path, options) {
if (typeof options === 'string') {
options = {
sheet_name : options
};
} else
options = library_namespace.setup_options(options);
// default: save to "%HOMEPATH%\Documents"
if (!Excel_file_path.includes(':\\')
&& !/^[\\\/]/.test(Excel_file_path))
Excel_file_path = library_namespace.working_directory()
+ Excel_file_path;
var sheet_name = options.sheet_name, text_file_path = options.save_to
|| Excel_file_path.replace(/(?:\.[^.]+)?$/, (sheet_name ? '#'
+ sheet_name : '')
+ '.tsv');
if (!text_file_path.includes(':\\') && !/^[\\\/]/.test(text_file_path))
text_file_path = library_namespace.working_directory()
+ text_file_path;
// 先將 Microsoft Office spreadsheets (Excel .XLSX 檔)匯出成 Unicode 文字檔。
// CScript.exe: Microsoft ® Console Based Script Host
// WScript.exe: Microsoft ® Windows Based Script Host
// WScript.exe 會直接跳出,因此必須使用 CScript.exe。
var command = 'CScript.exe //Nologo //B "'
+ library_namespace.get_module_path(module_name,
'Excel_to_text.js') + '" "' + Excel_file_path + '" "'
+ (sheet_name || '') + '" "' + text_file_path + '"';
// check if updated: 若是沒有更新過,那麼用舊的文字檔案就可以。
var target_file_status = library_namespace.fso_status(text_file_path);
if (target_file_status) {
var soutce_file_status = library_namespace
.fso_status(Excel_file_path);
if (Date.parse(target_file_status.mtime)
- Date.parse(soutce_file_status.mtime) > 0)
command = null;
}
if (command) {
if (!require('fs').existsSync(Excel_file_path)) {
library_namespace.error('Excel 檔案不存在! ' + Excel_file_path);
return;
}
library_namespace.debug('Execute command: ' + command, 1,
'read_Excel_file');
// console.log(command);
// console.log(JSON.stringify(command));
execSync(command);
} else {
library_namespace.debug('Using cache file: ' + text_file_path, 1,
'read_Excel_file');
}
// console.log(text_file_path);
// 'auto': Excel 將活頁簿儲存成 "Unicode 文字"時的正常編碼為 UTF-16LE
var content = library_namespace.read_file(text_file_path, 'auto');
// console.log(content);
if (!content) {
library_namespace.error('沒有內容。請檢查工作表是否存在!');
return;
}
if (typeof options.content_processor === 'function') {
content = options.content_processor(content);
}
// content = '' + content;
var remove_title_row = options.remove_title_row;
if (remove_title_row === undefined) {
// auto detect title line
var matched = content.trim().match(/^([^\n]*)\n([^\n]*)/);
if (matched && !matched[1].trim().includes('\t')
// 第一行單純只有一個標題 cell。
&& matched[2].trim().includes('\t')) {
remove_title_row = true;
}
}
if (remove_title_row) {
content = content.replace(/^([^\n]*)\n/,
//
function(line, table_title) {
remove_title_row = table_title;
return '';
});
}
var table = library_namespace.parse_CSV(content, Object.assign({
has_title : true,
field_delimiter : '\t'
}, options));
if (remove_title_row) {
library_namespace.debug('remove title line: ' + remove_title_row,
1, 'read_Excel_file');
table.table_title = remove_title_row;
}
return table;
}
_.read_Excel_file = read_Excel_file;
function write_Excel_file(file_path, content, options) {
library_namespace.write_file(file_path, library_namespace
.to_CSV_String(content, Object.assign({
field_delimiter : '\t',
line_separator : '\r\n'
}, options)));
}
_.write_Excel_file = write_Excel_file;
return (_// JSDT:_module_
);
}

Binary file not shown.

741
app/node_modules/cejs/application/OS/Windows/HTA.js generated vendored Normal file
View File

@@ -0,0 +1,741 @@
/**
* @name CeL function for HTML Applications (HTAs)
* @fileoverview
* 本檔案包含了 Microsoft Windows HTML Applications (HTAs) 的 functions。
* @since
*/
'use strict';
if (typeof CeL === 'function')
CeL.run(
{
name:'application.OS.Windows.HTA',
// includes() @ data.code.compatibility.
require : 'data.code.compatibility.|interact.DOM.select_node|interact.DOM.fill_form',
code : function(library_namespace) {
// requiring
var select_node = this.r('select_node'), fill_form = this.r('fill_form');
/**
* null module constructor
* @class web HTA 的 functions
*/
var _// JSDT:_module_
= function() {
// null module constructor
};
/**
* for JSDT: 有 prototype 才會將之當作 Class
*/
_// JSDT:_module_
.prototype = {
};
/*
TODO:
JavaScript closure and IE 4-6 memory leak
Mozilla ActiveX Project http://www.iol.ie/%7Elocka/mozilla/mozilla.htm
IE臨時文件的位置可以從註冊表鍵值 HKLM\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Cache\paths\Directory 中讀取。
*/
_// JSDT:_module_
.
/**
* Internet Explorer Automation tool
* @param {String} [URL] initial URL
* @returns {IEA}
* @_memberOf _module_
* @see http://msdn.microsoft.com/en-us/library/aa752084(v=vs.85).aspx
*/
IEA = function (URL) {
try {
/* COM objects
WScript.CreateObject("InternetExplorer.Application","Event_");
new ActiveXObject(class[, servername]);
http://www.cnblogs.com/xdotnet/archive/2007/04/09/javascript_object_activexobject.html
var obj=new ActiveXObject(servername,typename[,location]);
servername提供該對象的應用程序名稱
typename要創建的對象地類型或類
location創建該對象得網絡服務器名稱。
*/
this.app = new ActiveXObject("InternetExplorer.Application");
} catch (e) {
library_namespace
.error('IEA: No InternetExplorer.Application object created!');
}
if (!this.app)
return;
// 要先瀏覽了網頁,才能實行 IEApp.Document其他功能。
this.go(URL || '');
return this;
/* other functions
http://msdn2.microsoft.com/en-us/library/aa752085.aspx
http://msdn2.microsoft.com/en-us/library/Aa752084.aspx
IEApp.Visible=true;
IEApp.Offline=true;
IEApp.Document.frames.prompt();
*/
};
/**
* get <frame>
* @param document_object document object
* @param name frame name
* @returns
*/
_.IEA.frame = function(document_object, name) {
try {
document_object = document_object.getElementsByTagName('frame');
return name ? document_object[name].contentWindow.document : document_object;
} catch (e) {
// TODO: handle exception
}
};
_.IEA.prototype = {
/**
* 本 IEA 之 status 是否 OK.<br />
* 以有無視窗,否則以有無內容判別是否 OK.<br />
* 關掉視窗時, typeof this.app.Visible=='unknown'
* @param w window object
* @returns
*/
OK : function(w) {
try {
if (w ? typeof this.app.Visible === 'boolean'
: this.doc().body.innerHTML)
return this.app;
} catch (e) {
// TODO: handle exception
}
},
autoSetBase : true,
baseD : '',
baseP : '',
//init_url : 'about:blank',
timeout : 3e4, // ms>0
setBase : function(URL) {
var m = (URL || '').match(/^([\w\-]+:\/\/[^\/]+)(.*?)$/);
if (m) {
this.baseD = m[1];
this.baseP = m[2].slice(0, m[2].lastIndexOf('/') + 1);
}
//WScript.Echo('IEA.setBase:\ndomin: '+this.baseD+'\npath: '+this.baseP);
return this.baseD;
},
/**
* go to URL. 注意: 若是 .go('URL#hash') 則可能無反應,須改成 .go('URL')。
* @param URL URL or history num
* @returns
*/
go : function(URL) {
try {
if (URL === '' || isNaN(URL)) {
if (URL === '')
URL = 'about:blank';// this.init_url;
if (URL) {
if (!URL.includes(':')
//!URL.includes('://') && !URL.includes('about:')
) {
// 預防操作中 URL 已經改了。
this.setBase(this.href());
URL = this.baseD + (URL.charAt(0) === '/' ? '' : this.baseP) + URL;
}
// IEApp.Document.frames.open(URL); ** 請注意這裡偶爾會造成script停滯並跳出警告視窗
this.app.Navigate(URL);
if (this.autoSetBase)
this.setBase(URL);
this.wait();
// 防止自動關閉: don't work
//this.win().onclose=function(){return false;};//this.win().close=null;
if(library_namespace.is_debug())
this.parse_frame();
}
} else {
this.win().history.go(URL);
this.wait();
}
} catch (e) {
// TODO: handle exception
}
return this;
},
/* 完全載入
TODO:
http://javascript.nwbox.com/IEContentLoaded/
try{document.documentElement.doScroll('left');}
catch(e){setTimeout(arguments.callee, 50);return;}
instead of onload
*/
waitStamp : 0,
waitInterval : 200, // ms
waitState : 3, // 1-4: READYSTATE_COMPLETE=4 usual set to interactive=3
wait : function(w) {
if (!w && !(w = this.waitState) || this.waitStamp)
// !!this.waitStamp: wait 中
return;
this.waitStamp = new Date;
try {
// 可能中途被關掉
while (new Date - this.waitStamp < this.timeout
&& (!this.OK(true) || this.app.busy || this.app.readyState < w))
try {
// Win98的JScript沒有WScript.Sleep
WScript.Sleep(this.waitInterval);
} catch (e) {
// TODO: handle exception
}
} catch (e) {
// TODO: handle exception
}
w = new Date - this.waitStamp;
this.waitStamp = 0;
return w;
},
quit : function(quit_IEA) {
try {
this.app.Quit();
} catch (e) {
// TODO: handle exception
}
this.app = null;
if (quit_IEA) {
// destory IEA on window.onunload().
if (IEA_instance)
IEA_instance.quit();
}
if (typeof CollectGarbage === 'function')
// CollectGarbage(): undocumented IE javascript method: 先置為 null 再 CollectGarbage(); 設置為null,它會斷開對象的引用但是IE為了節省資源經常釋放內存也會佔系統資源因此採用的是延遲釋放策略你調用CollectGarbage函數就會強制立即釋放。
// http://www.cnblogs.com/stupidliao/articles/797659.html
setTimeout(function() {
CollectGarbage();
}, 0);
return;
},
// 用IE.doc().title or IE.app.LocationName 可反映狀況
doc : function() {
try {
return this.app.document;
} catch (e) {
// TODO: handle exception
}
},
// get URL
href : function() {
try {
return this.app.LocationURL;
} catch (e) {
// TODO: handle exception
}
},
win : function() {
try {
return this.doc().parentWindow;
} catch (e) {
// TODO: handle exception
}
},
eval : function(code, scope) {
// IE 11 中無法使用 this.win().eval:
// Error 70 [Error] (facility code 10): 沒有使用權限
return (scope ? this.g(scope).parentWindow : this.win()).eval(code);
},
/*
reload:function(){
try{IE.win().history.go(0);IE.wait();}catch(e){}
},
*/
/**
* get element
* @param e
* @param o
* @returns
*/
get_element : function(e, o) {
try {
return (o || this.doc()).getElementById(e);
} catch (e) {
// TODO: handle exception
}
},
/**
* @deprecated
*/
getE : function() {
return this.get_element.apply(this, arguments);
},
/**
* get tag
* @param e
* @param o
* @returns
*/
get_tag : function(e, o) {
try {
return (o || this.doc()).getElementsByTagName(e);
} catch (e) {
// TODO: handle exception
}
},
/**
* @deprecated
*/
getT : function() {
return this.get_tag.apply(this, arguments);
},
/**
* get node/elements/frame/.. 通用. A simple CSS
* selector with iframe.<br />
* Support #id, type(tag name), .name, .<br />
* TODO:
* 最佳化
*
* @param {String}path
* CSS selector, XPath, ..
* @param {object}[base_space]
* base document/context
* @returns node
* @see Sizzle<br />
*
*/
g : function get_node(selector, base_space) {
if (typeof base_space === 'string' && base_space) {
base_space = this.g(base_space);
}
library_namespace.debug('get [' + selector + ']', 2, 'IEA.get_node');
var node = select_node(selector, base_space || this.doc());
if (library_namespace.is_NodeList(node) && node.length === 1) {
node = node[0];
library_namespace.debug('treat node as single NodeList, 移至 [0]: &lt;' + node.tagName + '&gt;.', 2, 'IEA.get_node');
}
if (node && (('' + node.tagName).toLowerCase() in {
frame : 1,
iframe : 1
})) {
library_namespace.debug('移至 &lt;' + node.tagName + '&gt;.contentWindow.document', 2, 'IEA.get_node');
// IE11: typeof node.contentWindow === 'object', but node.contentWindow.document: 沒有使用權限
node = node.contentWindow.document;
} else if (library_namespace.is_NodeList(node) && library_namespace.is_debug(2)) {
library_namespace.warn('IEA.get_node: get NodeList[' + node.length + '].');
}
return node;
},
// name/id, HTML object to get frame, return document object or not
// .getElementsByName()
// http://www.w3school.com.cn/htmldom/met_doc_getelementsbyname.asp
frame : function(n, f, d) {
try {
f = f ? f.getElementsByTagName('frame') : this.getT('frame');
if (isNaN(n)) {
if (!n)
return f;
for ( var i = 0, l = (f = library_namespace.get_tag_list(f)).length; i < l; i++)
if (f[i].name === n) {
n = i;
break;
}
}
if (!isNaN(n))
return d ? f[n].contentWindow.document : f[n];
} catch (e) {
// TODO: handle exception
}
},
// IE.frames()['*'] IEApp.document.frames
// Cross Site AJAX http://blog.joycode.com/saucer/archive/2006/10/03/84572.aspx
// Cross-Site XMLHttpRequest http://ejohn.org/blog/cross-site-xmlhttprequest/
frames : function() {
try {
var i = 0, f = this.getT('frame'), r = [];
for (r['*'] = []; i < f.length; i++)
r['*'].push(f(i).name), r[f(i).name] = r[i] = f(i);
// use frame.window, frame.document
return r;
} catch (e) {
// TODO: handle exception
}
},
parse_frame : function(frames) {
try {
if (frames || (frames = this.doc()).getElementsByTagName('frame').length)
library_namespace.parse_frame(frames);
} catch (e) {
// TODO: handle exception
}
},
click : function fill(selector, base_space) {
var node = this.g(selector, base_space);
if (typeof node === 'object' && !isNaN(node.length))
node = node[0];
if (node && node.click) {
// http://www.quirksmode.org/dom/events/click.html
// IE 5-8 use the following event order:
// IE 8 中還是有些情況下不能模擬滑鼠點擊!
if (node.mousedown)
node.mousedown();
node.click();
if (node.mouseup)
node.mouseup();
this.wait();
}
},
fill : function fill(pair, submit, base_space, config) {
if (typeof base_space === 'string' && base_space) {
base_space = this.g(base_space);
}
if (!library_namespace.is_Object(config))
config = Object.create(null);
config.window = this.win();
config.base = base_space || this.doc();
config.submit = submit;
fill_form(pair, config);
this.wait();
},
// form name array
// formNA : 0,
// return name&id object. 設置這個還可以強制 do submit 使用 name 為主,不用 id。
fillForm_rtE : 0,
/**
* 自動填寫表單
*
* @param {Object}pair
* 設定 pair: {id/name: value}
* @param submit_id
* do submit(num) 或 button id
* @param form_index
* submit 之 form index 或 id
* @returns
* @deprecated use .fill()
*/
fillForm : function fillForm(parameter, submit_id, form_index) {
try {
var i, j, n = {}, h = 0, f = this.doc().forms[form_index || 0] || {}, t,
// g=f.getElementById,
s = function(o, v) {
t = o.tagName.toLowerCase();
if (t === 'select')
if (isNaN(v) || v < 0 || v >= o.options.length)
o.value = v;
else
// .options[i].value==v
// .selectedIndex= 的設定有些情況下會失效
o.selectedIndex = v;
// 參考 cookieForm
else if (t === 'input') {
t = o.type.toLowerCase(); // .getAttribute('type')
if (t === 'checkbox')
o.checked = v;
else if (t !== 'radio')
o.value = v;
else if (o.value === v)
o.checked = true;
else
return true; // return true: 需要再處理
} else if (t === 'textarea')
o.value = v;
};
/* needless
if(!f){
f=this.getT('form');
for(i in f)if(f[i].name==fi){f=a[i];break;}
}
if(!f)f={};
*/
for (j in parameter)
if (!(i = /* f.getElementById?f.getElementById(j): */this
.get_element(j))
|| s(i, parameter[j]))
n[j] = 1, h = 1;
if ((h || this.fillForm_rtE)
&& (i = f.getElementsByTagName ? f
.getElementsByTagName('input') : this.getT('input')).length)
for (j = 0, i = library_namespace.get_tag_list(i); j < i.length; j++)
if (i[j].name in n)
s(i[j], parameter[i[j].name]);
else if (submit_id && typeof submit_id !== 'object' && submit_id === i[j].name)
submit_id = i[j];
// if(i[j].name in pm)s(i[j],pm[i[j].name]);
if (submit_id) {
if (i = typeof submit_id === 'object' ? submit_id
: /* f.getElementById&&f.getElementById(l)|| */
this.get_element(submit_id))
i.click();
else
f.submit();
this.wait();
} else if (this.fillForm_rtE) {
h = {
'' : i
};
for (j = 0; j < i.length; j++)
if (i[j].name)
h[i[j].name] = i[j];
return h;
}
} catch (e) {
// TODO: handle exception
}
return this;
},
get_form_name : function get_form_name(form_index) {
var i, doc = this.doc(), form = doc.forms[0] || doc,
input = library_namespace.get_tag_list('input'), name, name_array = [];
if(input.length){
library_namespace.debug('All ' + doc.forms.length + ' forms, form[' + form_index + '] gets ' + input.length + ' &gt;input&lt;s.');
for (i=0;i<input.length;i++) {
name = input[i].name || input[i].id;
if (name !== undefined)
name_array.push(name);
}
library_namespace.log(name_array);
}
return name_array;
},
setLoc : function(w, h, l, t) {
try {
var s = this.win().screen;
if (w) {
this.app.Width = w;
if (typeof l === 'undefined')
l = (s.availWidth - w) / 2;
}
if (h) {
this.app.Height = h;
if (typeof t === 'undefined')
t = (s.availHeight - h) / 2;
}
if (l)
this.app.Left = l;
if (t)
this.app.Top = t;
} catch (e) {
// TODO: handle exception
}
return this;
},
write : function(h) {
try {
var d = this.doc();
if (!d)
this.go('');
d.open();
d.write(h || '');
d.close();
} catch (e) {
// TODO: handle exception
}
return this;
},
// 使之成為 dialog 形式的視窗
// http://members.cox.net/tglbatch/wsh/
setDialog : function(w, h, l, t, H) {
try {
this.app.FullScreen = true;
this.app.ToolBar = false;
this.app.StatusBar = false;
} catch (e) {
// TODO: handle exception
}
this.setLoc(w, h, l, t);
if (H)
this.write(H).focus();
try {
// 太早設定 scroll 沒用。
H = this.doc();
H.scroll = 'no';
H.style.borderStyle = 'outset';
H.style.borderWidth = '3px';
} catch (e) {
// TODO: handle exception
}
return this;
},
show : function(s) {
try {
this.app.Visible = typeof s === 'undefined' || s;
} catch (e) {
// TODO: handle exception
}
return this;
},
focus : function(s) {
try {
if (s || typeof s === 'undefined')
this.win().focus();
else
this.win().blur();
} catch (e) {
// TODO: handle exception
}
return this;
},
get_page : function() {
return this.getT('html')[0].outerHTML;
},
save_page : function(path, encoding) {
var text = this.get_page();
if (path && text) {
href = this.href();
l = href.length;
l = (l > 9 ? l > 99 ? l > 999 ? '' : '0' : '00' : '000') + l;
library_namespace.write_file(path, '<!-- saved from url=(' + l + ')' + href + ' -->' + line_separator + text, encoding || TristateTrue);
}
return this;
},
getC : function(class_name) {
return find_class(class_name, this.doc());
}
};
_.IEA.prototype.getE = _.IEA.prototype.get_element;
var IEA_instance;
/**
* get IEA instance.
*
* @param {Boolean}new_1
* get a new one.
* @returns {IEA} IEA instance
*
* @inner
*/
function new_IEA(new_1) {
if (!new_1 && IEA_instance && IEA_instance.OK(true))
return IEA_instance;
// IEA.prototype.init_url='http://www.google.com/';
if (IEA_instance = new IEA)
if (IEA_instance.OK(true))
IEA.instance = IEA_instance;
else {
library_namespace.error('Error to use IEA!');
IEA_instance = null;
}
return IEA_instance;
}
function get_HTML(url) {
if (url && !get_HTML.no_directly) {
library_namespace.debug('Directly get:<br />' + url, 2);
try {
// 當大量 access 時可能被網站擋下。e.g., Google.
var data = library_namespace.get_file(url);
library_namespace.debug('<br />' + data.replace(/</g, '&lt;'), 3);
return data;
} catch (e) {
library_namespace.error('get_HTML: Error to directly access, will try IEA futher:<br />'
+ url);
get_HTML.no_directly = true;
}
}
if(!new_IEA())
return '';
if (url)
IEA_instance.go(url);
IEA_instance.wait();
// https://ipv4.google.com/sorry/IndexRedirect?continue=_url_
if (IEA_instance.href().includes('.google.com/sorry/IndexRedirect')) {
IEA_instance.show(true);
// 如果您使用了自動程式常用的進階字詞,或是快速傳出多項要求,系統可能會要求您進行人機驗證 (Captcha)。
throw new Error('如要繼續,請輸入人機驗證 (Captcha) 字元。');
}
var doc = IEA_instance.doc(), HTML;
if (doc) {
// alert(IEA.instance.doc().getElementsByTagName('html')[0].outerHTML);
if (HTML = doc.getElementsByTagName('html'))
return HTML[0].outerHTML;
library_namespace.warn('No html element found! Use body.');
return doc.body.outerHTML;
}
library_namespace.warn('No document node found!');
}
_.IEA.get_HTML = get_HTML;
// WSH環境中設定剪貼簿的資料多此一舉 http://yuriken.hp.infoseek.co.jp/index3.html http://code.google.com/p/zeroclipboard/
//setClipboardText[generateCode.dLK]='IEA';//,clipboardFunction
function setClipboardText(cData, cType) {
if (typeof clipboardFunction === 'function')
return clipboardFunction();
if (!new_IEA())
return '';
if (!cType)
cType = 'text';
var w = IEA_instance.win();
if (cData)
w.clipboardData.setData(cType, cData);
else
cData = w.clipboardData.getData(cType);
//IEA_instance.quit();
// try{IEApp.Quit();}catch(e){}
return cData || '';
}
_// JSDT:_module_
.
setClipboardText = setClipboardText;
_// JSDT:_module_
.
/**
* WSH 環境中取得剪貼簿的資料
* @_memberOf _module_
*/
getClipboardText = setClipboardText;
return (
_// JSDT:_module_
);
}
});

BIN
app/node_modules/cejs/application/OS/Windows/WMI.js generated vendored Normal file

Binary file not shown.

106
app/node_modules/cejs/application/OS/Windows/Word.js generated vendored Normal file
View File

@@ -0,0 +1,106 @@
/**
* @name CeL function for Word
* @fileoverview 本檔案包含了 Word 專用的 functions。
*
* @since
*/
'use strict';
// 'use asm';
// --------------------------------------------------------------------------------------------
// 不採用 if 陳述式,可以避免 Eclipse JSDoc 與 format 多縮排一層。
typeof CeL === 'function' && CeL.run({
// module name
name : 'application.OS.Windows.Word',
require : 'data.code.compatibility.|data.native.'
// CeL.write_file()
+ '|application.storage.',
// 設定不匯出的子函式。
// no_extend : '*',
// 為了方便格式化程式碼,因此將 module 函式主體另外抽出。
code : module_code
});
function module_code(library_namespace) {
var module_name = this.id;
/**
* null module constructor
*
* @class Node.js 的 functions
*/
var _// JSDT:_module_
= function() {
// null module constructor
};
/**
* for JSDT: 有 prototype 才會將之當作 Class
*/
_// JSDT:_module_
.prototype = {};
// const: node.js only
var execSync = require('child_process').execSync;
// save to .xml file → .docx file
// 必須先安裝 Word。
// 存成 doc 檔案依然可以開啟,但不能以右鍵選單列印。
function xml_save_to_doc(Word_file_path, xml, options) {
if (options === true) {
options = {
// preserve xml file
preserve : options
};
} else
options = library_namespace.setup_options(options);
if (!Word_file_path.includes('.')) {
Word_file_path += '.docx';
}
// default: save to "%HOMEPATH%\Documents"
if (!Word_file_path.includes(':\\') && !/^[\\\/]/.test(Word_file_path))
Word_file_path = library_namespace.working_directory()
+ Word_file_path;
var xml_file_path = Word_file_path.replace(/[^.]*$/, 'xml');
library_namespace.write_file(xml_file_path, xml);
if (!require('fs').existsSync(xml_file_path)) {
library_namespace.error('無法寫入 source xml 檔案! ' + xml_file_path);
return;
}
// CScript.exe: Microsoft ® Console Based Script Host
// WScript.exe: Microsoft ® Windows Based Script Host
// WScript.exe 會直接跳出,因此必須使用 CScript.exe。
var command = 'CScript.exe //Nologo //B "'
+ library_namespace.get_module_path(module_name,
'xml_to_Word.js') + '" "' + xml_file_path + '" "'
+ Word_file_path + '"';
library_namespace.debug('Execute command: ' + command, 1,
'xml_save_to_doc', 3);
library_namespace.debug('xml_save_to_doc: convert ' + xml_file_path
+ ' → ' + Word_file_path);
// console.log(command);
// console.log(JSON.stringify(command));
execSync(command);
if (!options.preserve) {
library_namespace.remove_file(xml_file_path);
}
}
_.xml_save_to_doc = xml_save_to_doc;
return (_// JSDT:_module_
);
}

Binary file not shown.

396
app/node_modules/cejs/application/OS/Windows/archive.js generated vendored Normal file
View File

@@ -0,0 +1,396 @@
/**
* @name CeL function for archive file.
* @fileoverview 本檔案包含了壓縮 compress / archive file 的 functions。
*
* @see CeL.application.storage.archive
*
* @since
*/
'use strict';
// 'use asm';
// --------------------------------------------------------------------------------------------
if (typeof CeL === 'function') {
CeL.run({
// module name
name : 'application.OS.Windows.archive',
require : 'data.code.compatibility.'
//
+ '|application.OS.Windows.execute.run_command',
code : module_code
});
}
function module_code(library_namespace) {
// requiring
var run_command = this.r('run_command');
/**
* null module constructor
*
* @class executing program 的 functions
*/
var _// JSDT:_module_
= function() {
// null module constructor
};
/**
* for JSDT: 有 prototype 才會將之當作 Class
*/
_// JSDT:_module_
.prototype = {};
// 2007/5/31 21:5:16
// default configuration
var compress_tool_set = {
WinRAR : {
// rar.exe
path : '"%ProgramFiles%\\WinRAR\\WinRAR.exe"',
extension : 'rar',
// compress switch
c : {
// cL:command line, c:compress, s:switch
cL : '$path $cmd $s $archive -- $files',
cmd : 'a',
// l:'-ilog logFN',
// -rr1p -s<N> -ap -as -ep1 -tl -x<f> -x@<lf> -z<f> -p[p] -hp[p]
// rar等
// -v690m
s : '-m5 -u -dh -os -r -ts -scuc -ep1 -ilog'
},
// uncompress switch
u : {
// command line
cL : '$path $cmd $archive $eF $eTo',
cmd : 'e'
},
// test switch
t : {
cL : '$path $cmd $archive',
cmd : 't'
},
// command line
command : '%path %command %switch %archive %files'
},
'7-Zip' : {
// The path of p7z executable file.
// TODO: use library_namespace.nodejs.executable_file_path('7z')
// 7zG.exe
path : '"%ProgramFiles%\\7-Zip\\7z.exe"',
extension : '7z',
// compress switch
c : {
cL : '$path $cmd $s $archive $files',
cmd : 'u',
s : '-mx9 -ms -mhe -mmt -uy2'
},
// uncompress switch
u : {
cL : '$path $cmd $s $archive $eF',
// cmd : 'e',
cmd : 'x',
s : function(fO) {
var s = ' -ssc -y';
if (fO.eTo)
s += ' -o"' + fO.eTo + '"';
return s;
}
},
// test switch
t : {
cL : '$path $cmd $archive',
cmd : 't'
}
}
};
/**
* <code>
test:
var base='C:\\kanashimi\\www\\cgi-bin\\program\\misc\\';
compress(base+'jit','_jit.htm',{tool:'7-Zip',s:''});
uncompress(base+'jit',base,{tool:'7-Zip'});
fO={
tool:'WinRAR' // or'7-Zip'
,m:'c' // method
,s:'' // switch
,archive:'' // archivefile
,files='' // whattocompress
,eTo='' // wheretouncompress
,eF='' // whattouncompress
,rcL=1 // rebuildcommandline
}
</code>
*/
// solid, overwrite, compressLevel, password
/**
* compress FSO
*
* @param {Object}fO
* flags object
* @returns
*/
function compressF(fO) {
// 參數檢查: 未完全
if (!fO)
fO = {};
if (typeof fO !== 'object')
return;
if (!fO.tool)
fO.tool = 'WinRAR';
// method
if (false && !fO.m)
fO.m = 'c';
if (!fO.m || !fO.archive && (fO.m !== 'c' || fO.m === 'c' && !fO.files))
return;
if (fO.m === 'c') {
if (typeof fO.files !== 'object')
fO.files = fO.files ? [ fO.files ] : fO.archive.replace(
/\...+$/, '');
if (!fO.archive)
fO.archive = fO.files[0].replace(/[\\\/]$/, '') + _t.extension;
fO.files = '"' + fO.files.join('" "') + '"';
}
var i, _t = compress_tool_set[fO.tool], _m, _c;
if (!_t || !(_m = _t[fO.m]))
return;
else if (!/\.[a-z]+$/.test(fO.archive))
fO.archive += '.' + _t.extension;
if (false && fO.bD)
// base directory, work directory, base folder
fO.archive = fO.bD + (/[\\\/]$/.test(fO.bD) ? '' : '\\')
+ fO.archive;
fO.archive = '"' + fO.archive.replace(/"/g, '""') + '"';
library_namespace.debug('compressF(): check OK.');
// 構築 command line arguments。
if (_m._cL && !fO.rcL) {
_c = _m._cL;
} else {
// rebuild command line arguments
_c = _m.cL.replace(/\$path/, _t.path);
for (i in _m)
if (typeof fO[i] === 'undefined')
_c = _c.replace(new RegExp('\\$' + i),
typeof _m[i] === 'function' ? _m[i](fO) : _m[i]
|| '');
_m._cL = _c;
library_namespace.debug(_c, 2, 'compressF');
}
for (i in fO)
_c = _c.replace(new RegExp('\\$' + i), fO[i] || '');
if (_c.indexOf('$') !== -1) {
library_namespace.debug('compressF() error:\n' + _c);
return;
}
library_namespace.debug('compressF() '
+ (_c.indexOf('$') === -1 ? 'run' : 'error') + ':\n' + _c);
// run
return WshShell.Run(_c, 0, true);
// run_command.Unicode(_c);
}
// compress[generateCode.dLK]='compressF';
/**
* compress files.
*
* @param {String}archive
* compress file path.
* @param {Array}files
* what to compress
* @param {Object}options
* flags object
* @returns
*/
function compress(archive, files, options) {
// 前置處理。
options = library_namespace.setup_options(options);
if (!options.m)
options.m = 'c';
if (archive)
options.archive = archive;
if (files)
options.files = files;
return compressF(options);
}
_.compress = compress;
// uncompress[generateCode.dLK]='uncompressF';
/**
* uncompress archive file
*
* @param archive
* compressed archive file path
* @param eTo
* where to uncompress/target
* @param {Object}
* flag flags
* @returns
*/
function uncompress(archive, eTo, flag) {
if (!flag)
flag = {};
else if (typeof flag !== 'object')
return;
if (!flag.m)
flag.m = 'u';
if (!flag.eF)
flag.eF = '';
if (archive)
flag.archive = archive;
if (eTo)
flag.eTo = eTo;
return compressF(flag);
}
function parse_7z_data(status, log, error) {
if (error && library_namespace.is_debug())
library_namespace.error(error);
var message = log.match(/\nError:\s+(?:[A-Za-z]:)?[^:\n]+: ([^\n]+)/);
if (message) {
if (library_namespace.is_debug())
library_namespace.error(message[1]);
this.callback.call(this['this'], this.path, new Error(message[1]));
return;
}
library_namespace.debug(log.replace(/\n/g, '<br/>'), 4);
message = log
.match(/\r?\n([^\r\n]+)\r?\n([ \-]+)\r?\n((?:.+|\n)+?)\r?\n[ \-]+\r?\n/);
library_namespace.debug(message, 3);
if (!message) {
if (library_namespace.is_debug())
library_namespace.warn('無法 parse header!');
this.callback(this.path, new Error('無法 parse header!'));
return;
}
// TODO: 系統化讀入固定欄位長度之 data。
var header = [], i = 0, length, match, file_list, file_array = [], pattern = [],
//
start = [], end = [];
message[1].replace(/\s*(\S+)/g, function($0, $1) {
library_namespace.debug('header: +[' + $1 + '] / [' + $0 + ']', 2);
header.push($1);
end.push(i += $0.length);
start.push(i - $1.length);
return '';
});
start[0] = 0;
file_list = message[3].replace(/\r/g, '').split(/\n/);
library_namespace.debug(file_list.join('<br />'), 3);
var no_calculate_count = 0, calculate_done = true;
for (i = 0, length = file_list.length; i < length; i++) {
calculate_done = true;
var no_calculate = true;
library_namespace.debug('一個個猜測邊界: ' + i + '/' + length
+ '<br />start: ' + start + '<br />end: ' + end, 2);
for (var j = 1, fragment; j < header.length; j++) {
if (end[j - 1] + 1 < start[j]) {
calculate_done = false;
fragment = file_list[i].slice(end[j - 1], start[j]);
if (match = fragment.match(/^\S+/))
if (match[0].length < fragment.length) {
library_namespace.debug('end: [' + (j - 1)
+ '] += ' + match[0].length, 2);
end[j - 1] += match[0].length;
no_calculate = false;
} else {
library_namespace.warn('無法判別 ' + header[j - 1]
+ ' 與 ' + header[j] + ' 之邊界。fragment: ['
+ fragment + ']');
continue;
}
if (match = fragment.match(/\S+$/)) {
library_namespace.debug('start: [' + j + '] -= '
+ match[0].length, 2);
start[j] -= match[0].length;
no_calculate = false;
}
}
}
if (no_calculate)
++no_calculate_count;
else
no_calculate_count = 0;
if (calculate_done || no_calculate_count > 20) {
library_namespace.debug('於 ' + i + '/' + length + ' 跳出邊界判別作業: '
+ (calculate_done ? '已' : '未') + '完成。');
break;
}
}
for (i = 0; i < header.length - 1; i++)
pattern.push('(.{' + (start[i + 1] - start[i]) + '})');
pattern.push('(.+)');
pattern = new RegExp(pattern.join(''));
library_namespace.debug('header: ['
+ header.join('<b style="color:#e44;">|</b>')
+ '], using pattern ' + pattern);
for (i = 0, length = file_list.length; i < length; i++) {
if (match = file_list[i].match(pattern)) {
var j = 1, data = [];
for (; j < match.length; j++)
data.push(match[j].trim());
library_namespace.debug(data
.join('<b style="color:#e44;">|</b>'), 3);
file_array.push(data);
} else {
library_namespace.warn('無法 parse [' + file_list[i] + ']');
}
}
this.callback(this.path, file_array, header);
}
// List archive file.
// read file list of .7z archive
// callback(status, log, error)
function archive_data(path, callback, options) {
if (path && typeof callback === 'function') {
// 前置處理。
options = Object.assign(Object.create(null), options, {
path : path,
callback : callback
});
run_command.Unicode(compress_tool_set['7-Zip'].path + ' l "' + path
+ '"', parse_7z_data.bind(options));
}
}
_.archive_data = archive_data;
// --------------------------------------------------------------------------------------------
// export 導出.
return (_// JSDT:_module_
);
}

302
app/node_modules/cejs/application/OS/Windows/execute.js generated vendored Normal file
View File

@@ -0,0 +1,302 @@
/**
* @name CeL function for executing program
* @fileoverview 本檔案包含了 executing program 的 functions。
* @since
*/
'use strict';
// 'use asm';
// --------------------------------------------------------------------------------------------
// 不採用 if 陳述式,可以避免 Eclipse JSDoc 與 format 多縮排一層。
typeof CeL === 'function' && CeL.run({
// module name
name : 'application.OS.Windows.execute',
require : 'application.OS.Windows.new_COM'
//
+ '|application.OS.Windows.is_COM',
// 設定不匯出的子函式。
// no_extend : '*',
// 為了方便格式化程式碼,因此將 module 函式主體另外抽出。
code : module_code
});
function module_code(library_namespace) {
// requiring
var new_COM = this.r('new_COM'), is_COM = this.r('is_COM');
/**
* null module constructor
*
* @class executing program 的 functions
*/
var _// JSDT:_module_
= function() {
// null module constructor
};
/**
* for JSDT: 有 prototype 才會將之當作 Class
*/
_// JSDT:_module_
.prototype = {};
/**
* @see also: application.OS.Windows.file.show_in_file_manager()
*
* <code>
2008/8/8 18:29:44
run them with administrator rights runs under administrator privileges.
帳戶控制 Windows Vista使用軟體限制原則對抗未授權的軟體 http://www.microsoft.com/taiwan/technet/windowsvista/security/rstrplcy.mspx
http://4sysops.com/archives/vista%E2%80%99s-uac-how-to-elevate-scripts-vbscript-and-jscript/
http://blogs.msdn.com/aaron_margosis/archive/2007/07/01/scripting-elevation-on-vista.aspx
Software\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA c:\windows\system32\control.exe /name Microsoft.UserAccounts http://www.dashken.net/index.php?/archives/280-VBScript-Check-if-OS-is-Vista-and-Vistas-UAC-status.html
http://msdn.microsoft.com/en-us/magazine/cc163486.aspx
HKEY_LOCAL_MACHINESOFTWARE MicrosoftWindowsCurrentVersionPoliciesSystem\ConsentPromptBehaviorAdmin http://hsu.easynow.com.tw/index.php?load=read&id=28
http://vistavitals.blogspot.com/2008/02/logon-scripts-token-effort.html
runas http://www.merawindows.com/Forums/tabid/324/forumid/82/postid/32458/scope/posts/Default.aspx
http://www.winhelponline.com/articles/185/1/VBScripts-and-UAC-elevation.html
http://forums.techarena.in/vista-security/654643.htm
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace("C:\")
Set objFolderItem = objFolder.ParseName("myhta.hta")
objFolderItem.InvokeVerb "runas"
var WinShell=new ActiveXObject("Shell.Application"),p=location.pathname.replace(/[^\\]+$/,''),o=WinShell.Namespace(p).ParseName(location.pathname.slice(p.length));
o.InvokeVerb("runas");
http://www.zaoxue.com/article/tech-28339_2.htm http://www.lob.cn/vbs/20071126203237.shtml
TODO:
對 prompt 回應不允許時的處理: 若想在受限的情況下使用?
不使用自訂程式 http://msdn.microsoft.com/en-us/library/bb776820(VS.85).aspx
有時執行完就無消息,得多執行幾次。
</code>
*/
function runas(path) {
if (!path)
path = typeof WScript === 'object' ? WScript.ScriptFullName
: unescape(location.pathname);
var host = {
js : 'wscript.exe',
vbs : 'wscript.exe',
hta : 'mshta.exe'
}, extension = path.match(/([^.]+)$/);
host = extension && ((extension = extension[1].toLowerCase()) in host) ? host[extension]
: '';
// 判斷是否有權限
if (!registryF.checkAccess('HKLM\\SOFTWARE\\')) {
// 以管理者權限另外執行新的.
// It will get the UAC prompt if this feature is not disabled.
new ActiveXObject("Shell.Application").ShellExecute(host || path,
host ? path : '', '', 'runas'/* ,5 */);
// 執行完本身則退出: bug: 有時執行完就無消息,得多執行幾次。
if (typeof WScript === 'object')
WScript.Quit();
else if (typeof window === 'object')
window.close();
}
}
// run_command[generateCode.dLK]='initialization_WScript_Objects';
/**
* 執行 command。<br />
* JScript file: check owner, .exe file.<br />
*
* TODO:<br />
* run_command([path, Verb],3): use Shell.Application InvokeVerb<br />
* run_command([path, arg1, arg2,..]): use Shell.Application.ShellExecute<br />
* set timeout.<br />
* cd. WshShell.Run('%COMSPEC% /K ' + ドライブ +' | cd /D '+ パス);// cd
* で他ドライブへ移れないので。
*
* @example <code>
// usage:
// use <a href="http://msdn.microsoft.com/en-us/library/ateytk4a.aspx" accessdate="2012/11/7 18:30" title="Exec Method (Windows Script Host)">WshShell.Exec</a>,
// return [ExitCode, StdOut, StdErr].
run_command(command);
// use <a href="http://msdn.microsoft.com/en-us/library/ateytk4a.aspx" accessdate="2012/11/7 18:30" title="Exec Method (Windows Script Host)">WshShell.Exec</a>,
// run callback.call(WshScriptExec Object, ExitCode, StdOut, StdErr) when done.
run_command(command, function callback(){});
// use <a href="http://msdn.microsoft.com/en-us/library/d5fk67ky.aspx" accessdate="2012/11/7 18:30" title="Run Method (Windows Script Host)">WshShell.Run</a>
run_command([strCommand, [intWindowStyle 0-10], [bWaitOnReturn false: nowait & return 0, true: wait & return error code]]);
// use WshRemote
run_command(script path, remote computer)
// use WMI
run_command(command, remote computer)
* </code>
*
* @param {String}command
* @param {Function|String}[option]
* @param {String}remoteserver
* @returns
*
* @see <a
* href="http://www.microsoft.com/taiwan/technet/scriptcenter/resources/qanda/nov04/hey1115.mspx">我能使用指令碼鎖定工作站嗎?</a>
*/
function run_command(command, callback, remoteserver) {
library_namespace.debug('Run command: [' + command + ']', 1,
'run_command');
var process;
try {
if (!remoteserver)
if (is_COM(process = new_COM('WScript.Shell')))
if (Array.isArray(command)) {
// WshShell.Run(command, [WindowStyle 0-10],
// [WaitonReturn false: nowait & return 0, true: wait &
// return error code])
library_namespace.debug('using WshShell.Run()', 2);
// return process.Run.apply(null, command);
var length = command.length;
return length > 2 ? process.Run(command[0], command[1],
command[2]) :
//
length > 1 ? process.Run(command[0], command[1]) :
//
process.Run(command[0]);
if (typeof callback === 'function')
callback();
}
else {
// WshShell.Exec(), objFolderItem.InvokeVerb()
library_namespace.debug('using WshShell.Exec()', 2);
process = process.Exec(command);
// 預防要輸入密碼。
process.StdIn.Close();
if (typeof WScript !== 'object') {
if (typeof callback === 'function')
run_command.waiting.call({
StdOut : [],
StdErr : []
}, process, callback);
return;
}
while (process.Status === 0)
WScript.Sleep(100);
if (typeof callback === 'function')
callback.call(process, process.ExitCode,
process.StdOut.ReadAll(), process.StdErr
.ReadAll());
else
return [ process.ExitCode,
process.StdOut.ReadAll(),
process.StdErr.ReadAll() ];
}
else {
library_namespace.error('No COM get!');
return;
}
if (/^[^ ]+\.(js|vbs)$/i.test(command)
&& is_COM(process = new_COM('WSHController'))) {
process = process.CreateScript(command, remoteserver);
// TODO
// http://msdn.microsoft.com/en-us/library/d070t67d(v=vs.84).aspx
process.Execute();
// <a
// href="http://msdn.microsoft.com/en-us/library/9z4dddwa.aspx"
// accessdate="2012/11/7 18:55">Status Property (WshRemote)</a>.
// [NoTask, Running, Finished]
while (process.Status !== 2)
WScript.Sleep(100);
return callback.call(process);
}
// TODO
process = GetObject("winmgmts:{impersonationLevel=impersonate}//"
+ (remoteserver || '.') + "/root/cimv2:Win32_Process");
if (false)
if (/^[^ ]+\.(j|vb)s$/i.test(command))
command = "wscript.exe " + command;
// Create 方法會讓這個指令碼在「遠端電腦」上執行。
return process.Create(command/* , null, null, intProcessID */);
} catch (e) {
library_namespace.error(e);
return e;
} finally {
process = null;
}
}
// <a href="http://msdn.microsoft.com/en-us/library/2f38xsxe.aspx"
// accessdate="2012/11/8 18:47">WshScriptExec Object</a>
run_command.waiting = function(process, callback) {
// <a
// href="http://us.generation-nt.com/answer/wsh-exec-hangs-getting-stdout-readall-command-line-winzip-help-59169522.html"
// accessdate="2012/11/8 19:12">Answer : Wsh.exec hangs getting
// StdOut.ReadAll from command line Winzip</a>.
// <a href="http://support.microsoft.com/kb/960246"
// accessdate="2012/11/8 19:44">Hang When Reading StdErr/StdOut
// Properties of WshScriptExec Object</a>
// 因為 <a href="http://msdn.microsoft.com/en-us/library/312a5kbt.aspx"
// accessdate="2012/11/8 19:32">TextStream Object</a> 的 buffer size
// limit 為 4KB超過後 .ReadAll() 便會 hangs (deadlock),因為 .ReadAll() 會等
// EndOfStream character。只好盡可能快點讀出。
// 當程式輸出過快時,仍可能來不及讀,只能使用 output 至檔案的方法。
while (!process.StdOut.AtEndOfStream)
this.StdOut.push(process.StdOut.Read(4096));
while (!process.StdErr.AtEndOfStream)
this.StdErr.push(process.StdErr.Read(4096));
library_namespace.debug('process status: [' + process.Status
+ ']<br />\nStdOut: [' + this.StdOut + '],<br />\nStdErr: ['
+ this.StdErr + ']', 3, 'run_command.waiting');
if (process.Status === 0) {
// The job is still running.
// DoEvent.
// TODO: set timeout.
setTimeout(run_command.waiting.bind(this, process, callback), 0);
return;
}
try {
library_namespace.debug('run callback [' + callback + '].', 3,
'run_command.waiting');
// if (typeof callback === 'function')
callback.call(process, process.ExitCode, this.StdOut.join(''),
this.StdErr.join(''));
} catch (e) {
library_namespace
.warn('run_command.waiting: fault to run callback ['
+ callback + '].');
library_namespace.error(e);
} finally {
process = null;
}
};
// Unicode pipe
run_command.Unicode = function(command, callback, remoteserver) {
command = '%COMSPEC% /U /C "' + command + '"';
return run_command(command, callback, remoteserver);
};
_.run_command = run_command;
return (_// JSDT:_module_
);
}

2704
app/node_modules/cejs/application/OS/Windows/file.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
app/node_modules/cejs/application/OS/Windows/job.js generated vendored Normal file

Binary file not shown.

Binary file not shown.