forked from sheetjs/sheetjs
		
	version bump 0.10.9: pin dependencies
- updated SSF 0.10.0, codepage 1.10.1, CFB 0.12.0, CRC32 / ADLER32 1.1.0 - pinned all devDependencies (fixes #740 h/t @the-spyke) - flow type updates - clarified meteor usage (fixes #751 h/t @NorthDecoder)
This commit is contained in:
		
							parent
							
								
									6732eb76f8
								
							
						
					
					
						commit
						ce37f99ec3
					
				| @ -6,6 +6,7 @@ node_modules/ | ||||
| types/ | ||||
| tests/ | ||||
| test_files | ||||
| *.md | ||||
| 
 | ||||
| *.json | ||||
| *.log | ||||
|  | ||||
| @ -28,6 +28,7 @@ tmp | ||||
| *.sheetjs | ||||
| *.exe | ||||
| .gitignore | ||||
| .fossaignore | ||||
| .eslintrc | ||||
| .jshintrc | ||||
| CONTRIBUTING.md | ||||
|  | ||||
| @ -5,7 +5,7 @@ but not limited to API changes and file location changes.  Minor behavioral | ||||
| changes may not be included if they are not expected to break existing code. | ||||
| 
 | ||||
| 
 | ||||
| ## Unreleased  (2017-??-??) | ||||
| ## 0.10.9 (2017-07-28) | ||||
| 
 | ||||
| * XLML/HTML resolution logic looks further into the data stream to decide type | ||||
| * Errors thrown on suspected RTF files | ||||
|  | ||||
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @ -14,7 +14,7 @@ FLOWTARGET=$(LIB).flow.js | ||||
| FLOWAUX=$(patsubst %.js,%.flow.js,$(AUXTARGETS)) | ||||
| AUXSCPTS=xlsxworker1.js xlsxworker2.js xlsxworker.js | ||||
| FLOWTGTS=$(TARGET) $(AUXTARGETS) $(AUXSCPTS) | ||||
| UGLIFYOPTS=--support-ie8 -c -m | ||||
| UGLIFYOPTS=--support-ie8 | ||||
| CLOSURE=/usr/local/lib/node_modules/google-closure-compiler/compiler.jar | ||||
| 
 | ||||
| ## Main Targets
 | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| XLSX.version = '0.10.8'; | ||||
| XLSX.version = '0.10.9'; | ||||
|  | ||||
							
								
								
									
										180
									
								
								bits/10_ssf.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										180
									
								
								bits/10_ssf.js
									
									
									
									
									
								
							| @ -1,8 +1,8 @@ | ||||
| /* ssf.js (C) 2013-present SheetJS -- http://sheetjs.com */ | ||||
| /*jshint -W041 */ | ||||
| var SSF = {}; | ||||
| var make_ssf = function make_ssf(SSF){ | ||||
| SSF.version = '0.9.4'; | ||||
| var SSF/*:SSFModule*/ = ({}/*:any*/); | ||||
| var make_ssf = function make_ssf(SSF/*:SSFModule*/){ | ||||
| SSF.version = '0.10.0'; | ||||
| function _strrev(x/*:string*/)/*:string*/ { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; } | ||||
| function fill(c/*:string*/,l/*:number*/)/*:string*/ { var o = ""; while(o.length < l) o+=c; return o; } | ||||
| function pad0(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;} | ||||
| @ -13,16 +13,9 @@ function pad0r2(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>= | ||||
| var p2_32 = Math.pow(2,32); | ||||
| function pad0r(v/*:any*/,d/*:number*/)/*:string*/{if(v>p2_32||v<-p2_32) return pad0r1(v,d); var i = Math.round(v); return pad0r2(i,d); } | ||||
| function isgeneral(s/*:string*/, i/*:?number*/)/*:boolean*/ { i = i || 0; return s.length >= 7 + i && (s.charCodeAt(i)|32) === 103 && (s.charCodeAt(i+1)|32) === 101 && (s.charCodeAt(i+2)|32) === 110 && (s.charCodeAt(i+3)|32) === 101 && (s.charCodeAt(i+4)|32) === 114 && (s.charCodeAt(i+5)|32) === 97 && (s.charCodeAt(i+6)|32) === 108; } | ||||
| /* Options */ | ||||
| var opts_fmt/*:Array<Array<any> >*/ = [ | ||||
| 	["date1904", 0], | ||||
| 	["output", ""], | ||||
| 	["WTF", false] | ||||
| ]; | ||||
| function fixopts(o){ | ||||
| 	for(var y = 0; y != opts_fmt.length; ++y) if(o[opts_fmt[y][0]]===undefined) o[opts_fmt[y][0]]=opts_fmt[y][1]; | ||||
| } | ||||
| SSF.opts = opts_fmt; | ||||
| /*:: | ||||
| type SSF_write_num = {(type:string, fmt:string, val:number):string}; | ||||
| */ | ||||
| var days/*:Array<Array<string> >*/ = [ | ||||
| 	['Sun', 'Sunday'], | ||||
| 	['Mon', 'Monday'], | ||||
| @ -101,7 +94,47 @@ function frac(x/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Array<number>*/ | ||||
| 	var q = Math.floor(sgn * P/Q); | ||||
| 	return [q, sgn*P - q*Q, Q]; | ||||
| } | ||||
| function general_fmt_int(v/*:number*/)/*:string*/ { return ""+v; } | ||||
| function parse_date_code(v/*:number*/,opts/*:?any*/,b2/*:?boolean*/) { | ||||
| 	if(v > 2958465 || v < 0) return null; | ||||
| 	var date = (v|0), time = Math.floor(86400 * (v - date)), dow=0; | ||||
| 	var dout=[]; | ||||
| 	var out={D:date, T:time, u:86400*(v-date)-time,y:0,m:0,d:0,H:0,M:0,S:0,q:0}; | ||||
| 	if(Math.abs(out.u) < 1e-6) out.u = 0; | ||||
| 	if(opts && opts.date1904) date += 1462; | ||||
| 	if(out.u > 0.9999) { | ||||
| 		out.u = 0; | ||||
| 		if(++time == 86400) { out.T = time = 0; ++date; ++out.D; } | ||||
| 	} | ||||
| 	if(date === 60) {dout = b2 ? [1317,10,29] : [1900,2,29]; dow=3;} | ||||
| 	else if(date === 0) {dout = b2 ? [1317,8,29] : [1900,1,0]; dow=6;} | ||||
| 	else { | ||||
| 		if(date > 60) --date; | ||||
| 		/* 1 = Jan 1 1900 in Gregorian */ | ||||
| 		var d = new Date(1900, 0, 1); | ||||
| 		d.setDate(d.getDate() + date - 1); | ||||
| 		dout = [d.getFullYear(), d.getMonth()+1,d.getDate()]; | ||||
| 		dow = d.getDay(); | ||||
| 		if(date < 60) dow = (dow + 6) % 7; | ||||
| 		if(b2) dow = fix_hijri(d, dout); | ||||
| 	} | ||||
| 	out.y = dout[0]; out.m = dout[1]; out.d = dout[2]; | ||||
| 	out.S = time % 60; time = Math.floor(time / 60); | ||||
| 	out.M = time % 60; time = Math.floor(time / 60); | ||||
| 	out.H = time; | ||||
| 	out.q = dow; | ||||
| 	return out; | ||||
| } | ||||
| SSF.parse_date_code = parse_date_code; | ||||
| var basedate = new Date(1899, 11, 31, 0, 0, 0); | ||||
| var dnthresh = basedate.getTime(); | ||||
| var base1904 = new Date(1900, 2, 1, 0, 0, 0); | ||||
| function datenum_local(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ { | ||||
| 	var epoch = v.getTime(); | ||||
| 	if(date1904) epoch -= 1461*24*60*60*1000; | ||||
| 	else if(v >= base1904) epoch += 24*60*60*1000; | ||||
| 	return (epoch - (dnthresh + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000)) / (24 * 60 * 60 * 1000); | ||||
| } | ||||
| function general_fmt_int(v/*:number*/)/*:string*/ { return v.toString(10); } | ||||
| SSF._general_int = general_fmt_int; | ||||
| var general_fmt_num = (function make_general_fmt_num() { | ||||
| var gnr1 = /\.(\d*[1-9])0+$/, gnr2 = /\.0*$/, gnr4 = /\.(\d*[1-9])0+/, gnr5 = /\.0*[Ee]/, gnr6 = /(E[+-])(\d)$/; | ||||
| @ -132,50 +165,20 @@ return function general_fmt_num(v/*:number*/)/*:string*/ { | ||||
| 	return gfn5(gfn4(o)); | ||||
| };})(); | ||||
| SSF._general_num = general_fmt_num; | ||||
| function general_fmt(v/*:any*/) { | ||||
| function general_fmt(v/*:any*/, opts/*:any*/) { | ||||
| 	switch(typeof v) { | ||||
| 		case 'string': return v; | ||||
| 		case 'boolean': return v ? "TRUE" : "FALSE"; | ||||
| 		case 'number': return (v|0) === v ? general_fmt_int(v/*, opts*/) : general_fmt_num(v/*, opts*/); | ||||
| 		case 'number': return (v|0) === v ? general_fmt_int(v) : general_fmt_num(v); | ||||
| 		case 'undefined': return ""; | ||||
| 		case 'object': if(v == null) return ""; | ||||
| 		case 'object': | ||||
| 			if(v == null) return ""; | ||||
| 			if(v instanceof Date) return format(14, datenum_local(v, opts && opts.date1904), opts); | ||||
| 	} | ||||
| 	throw new Error("unsupported value in General format: " + v); | ||||
| } | ||||
| SSF._general = general_fmt; | ||||
| function fix_hijri(/*date, o*/) { return 0; } | ||||
| function parse_date_code(v/*:number*/,opts/*:?any*/,b2/*:?boolean*/) { | ||||
| 	if(v > 2958465 || v < 0) return null; | ||||
| 	var date = (v|0), time = Math.floor(86400 * (v - date)), dow=0; | ||||
| 	var dout=[]; | ||||
| 	var out={D:date, T:time, u:86400*(v-date)-time,y:0,m:0,d:0,H:0,M:0,S:0,q:0}; | ||||
| 	if(Math.abs(out.u) < 1e-6) out.u = 0; | ||||
| 	fixopts(opts != null ? opts : (opts=[])); | ||||
| 	if(opts.date1904) date += 1462; | ||||
| 	if(out.u > 0.9999) { | ||||
| 		out.u = 0; | ||||
| 		if(++time == 86400) { out.T = time = 0; ++date; ++out.D; } | ||||
| 	} | ||||
| 	if(date === 60) {dout = b2 ? [1317,10,29] : [1900,2,29]; dow=3;} | ||||
| 	else if(date === 0) {dout = b2 ? [1317,8,29] : [1900,1,0]; dow=6;} | ||||
| 	else { | ||||
| 		if(date > 60) --date; | ||||
| 		/* 1 = Jan 1 1900 in Gregorian */ | ||||
| 		var d = new Date(1900, 0, 1); | ||||
| 		d.setDate(d.getDate() + date - 1); | ||||
| 		dout = [d.getFullYear(), d.getMonth()+1,d.getDate()]; | ||||
| 		dow = d.getDay(); | ||||
| 		if(date < 60) dow = (dow + 6) % 7; | ||||
| 		if(b2) dow = fix_hijri(d, dout); | ||||
| 	} | ||||
| 	out.y = dout[0]; out.m = dout[1]; out.d = dout[2]; | ||||
| 	out.S = time % 60; time = Math.floor(time / 60); | ||||
| 	out.M = time % 60; time = Math.floor(time / 60); | ||||
| 	out.H = time; | ||||
| 	out.q = dow; | ||||
| 	return out; | ||||
| } | ||||
| SSF.parse_date_code = parse_date_code; | ||||
| function fix_hijri(/*::date, o*/) { return 0; } | ||||
| /*jshint -W086 */ | ||||
| function write_date(type/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:string*/ { | ||||
| 	var o="", ss=0, tt=0, y = val.y, out, outl = 0; | ||||
| @ -217,23 +220,17 @@ function write_date(type/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:str | ||||
| 			default: throw 'bad minute format: ' + fmt; | ||||
| 		} break; | ||||
| 		case 115: /* 's' seconds */ | ||||
| 		if(val.u === 0) switch(fmt) { | ||||
| 			case 's': case 'ss': return pad0(val.S, fmt.length); | ||||
| 			case '.0': case '.00': case '.000': | ||||
| 		} | ||||
| 		switch(fmt) { | ||||
| 			case 's': case 'ss': case '.0': case '.00': case '.000': | ||||
| 				/*::if(!ss0) ss0 = 0; */ | ||||
| 				if(ss0 >= 2) tt = ss0 === 3 ? 1000 : 100; | ||||
| 				else tt = ss0 === 1 ? 10 : 1; | ||||
| 				ss = Math.round((tt)*(val.S + val.u)); | ||||
| 				if(ss >= 60*tt) ss = 0; | ||||
| 				if(fmt === 's') return ss === 0 ? "0" : ""+ss/tt; | ||||
| 				o = pad0(ss,2 + ss0); | ||||
| 				if(fmt === 'ss') return o.substr(0,2); | ||||
| 				return "." + o.substr(2,fmt.length-1); | ||||
| 			default: throw 'bad second format: ' + fmt; | ||||
| 		} | ||||
| 			if(fmt != 's' && fmt != 'ss' && fmt != '.0' && fmt != '.00' && fmt != '.000') throw 'bad second format: ' + fmt; | ||||
| 			if(val.u === 0 && (fmt == "s" || fmt == "ss")) return pad0(val.S, fmt.length); | ||||
| 			/*::if(!ss0) ss0 = 0; */ | ||||
| 			if(ss0 >= 2) tt = ss0 === 3 ? 1000 : 100; | ||||
| 			else tt = ss0 === 1 ? 10 : 1; | ||||
| 			ss = Math.round((tt)*(val.S + val.u)); | ||||
| 			if(ss >= 60*tt) ss = 0; | ||||
| 			if(fmt === 's') return ss === 0 ? "0" : ""+ss/tt; | ||||
| 			o = pad0(ss,2 + ss0); | ||||
| 			if(fmt === 'ss') return o.substr(0,2); | ||||
| 			return "." + o.substr(2,fmt.length-1); | ||||
| 		case 90: /* 'Z' absolute time */ | ||||
| 		switch(fmt) { | ||||
| 			case '[h]': case '[hh]': out = val.D*24+val.H; break; | ||||
| @ -248,12 +245,13 @@ function write_date(type/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:str | ||||
| } | ||||
| /*jshint +W086 */ | ||||
| function commaify(s/*:string*/)/*:string*/ { | ||||
| 	if(s.length <= 3) return s; | ||||
| 	var j = (s.length % 3), o = s.substr(0,j); | ||||
| 	for(; j!=s.length; j+=3) o+=(o.length > 0 ? "," : "") + s.substr(j,3); | ||||
| 	var w = 3; | ||||
| 	if(s.length <= w) return s; | ||||
| 	var j = (s.length % w), o = s.substr(0,j); | ||||
| 	for(; j!=s.length; j+=w) o+=(o.length > 0 ? "," : "") + s.substr(j,w); | ||||
| 	return o; | ||||
| } | ||||
| var write_num = (function make_write_num(){ | ||||
| var write_num/*:SSF_write_num*/ = (function make_write_num(){ | ||||
| var pct1 = /%/g; | ||||
| function write_num_pct(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string*/{ | ||||
| 	var sfmt = fmt.replace(pct1,""), mul = fmt.length - sfmt.length; | ||||
| @ -591,7 +589,7 @@ function fmt_is_date(fmt/*:string*/)/*:boolean*/ { | ||||
| } | ||||
| SSF.is_date = fmt_is_date; | ||||
| function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 	var out = [], o = "", i = 0, c = "", lst='t', q, dt, j, cc; | ||||
| 	var out = [], o = "", i = 0, c = "", lst='t', dt, j, cc; | ||||
| 	var hr='H'; | ||||
| 	/* Tokenize */ | ||||
| 	while(i < fmt.length) { | ||||
| @ -619,12 +617,12 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 			case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g': | ||||
| 				if(v < 0) return ""; | ||||
| 				if(dt==null) { dt=parse_date_code(v, opts); if(dt==null) return ""; } | ||||
| 				o = c; while(++i<fmt.length && fmt.charAt(i).toLowerCase() === c) o+=c; | ||||
| 				o = c; while(++i < fmt.length && fmt.charAt(i).toLowerCase() === c) o+=c; | ||||
| 				if(c === 'm' && lst.toLowerCase() === 'h') c = 'M'; | ||||
| 				if(c === 'h') c = hr; | ||||
| 				out[out.length] = {t:c, v:o}; lst = c; break; | ||||
| 			case 'A': case 'a': | ||||
| 				q={t:c, v:c}; | ||||
| 				var q={t:c, v:c}; | ||||
| 				if(dt==null) dt=parse_date_code(v, opts); | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;} | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; } | ||||
| @ -647,7 +645,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 			/* Numbers */ | ||||
| 			case '.': | ||||
| 				if(dt != null) { | ||||
| 					o = c; while((c=fmt.charAt(++i)) === "0") o += c; | ||||
| 					o = c; while(++i < fmt.length && (c=fmt.charAt(i)) === "0") o += c; | ||||
| 					out[out.length] = {t:'s', v:o}; break; | ||||
| 				} | ||||
| 				/* falls through */ | ||||
| @ -656,7 +654,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				out[out.length] = {t:'n', v:o}; break; | ||||
| 			case '?': | ||||
| 				o = c; while(fmt.charAt(++i) === c) o+=c; | ||||
| 				q={t:c, v:o}; out[out.length] = q; lst = c; break; | ||||
| 				out[out.length] = {t:c, v:o}; lst = c; break; | ||||
| 			case '*': ++i; if(fmt.charAt(i) == ' ' || fmt.charAt(i) == '*') ++i; break; // **
 | ||||
| 			case '(': case ')': out[out.length] = {t:(flen===1?'t':c), v:c}; ++i; break; | ||||
| 			case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': | ||||
| @ -807,7 +805,7 @@ function chkcond(v, rr) { | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
| function choose_fmt(f/*:string*/, v) { | ||||
| function choose_fmt(f/*:string*/, v/*:any*/) { | ||||
| 	var fmt = split_fmt(f); | ||||
| 	var l = fmt.length, lat = fmt[l-1].indexOf("@"); | ||||
| 	if(l<4 && lat>-1) --l; | ||||
| @ -842,17 +840,37 @@ function format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) { | ||||
| 			break; | ||||
| 	} | ||||
| 	if(isgeneral(sfmt,0)) return general_fmt(v, o); | ||||
| 	if(v instanceof Date) v = datenum_local(v, o.date1904); | ||||
| 	var f = choose_fmt(sfmt, v); | ||||
| 	if(isgeneral(f[1])) return general_fmt(v, o); | ||||
| 	if(v === true) v = "TRUE"; else if(v === false) v = "FALSE"; | ||||
| 	else if(v === "" || v == null) return ""; | ||||
| 	return eval_fmt(f[1], v, o, f[0]); | ||||
| } | ||||
| function load_entry(fmt/*:string*/, idx/*:?number*/)/*:number*/ { | ||||
| 	if(typeof idx != 'number') { | ||||
| 		idx = +idx || -1; | ||||
| /*::if(typeof idx != 'number') return 0x188; */ | ||||
| 		for(var i = 0; i < 0x0188; ++i) { | ||||
| /*::if(typeof idx != 'number') return 0x188; */ | ||||
| 			if(table_fmt[i] == undefined) { if(idx < 0) idx = i; continue; } | ||||
| 			if(table_fmt[i] == fmt) { idx = i; break; } | ||||
| 		} | ||||
| /*::if(typeof idx != 'number') return 0x188; */ | ||||
| 		if(idx < 0) idx = 0x187; | ||||
| 	} | ||||
| /*::if(typeof idx != 'number') return 0x188; */ | ||||
| 	table_fmt[idx] = fmt; | ||||
| 	return idx; | ||||
| } | ||||
| SSF.load = load_entry; | ||||
| SSF._table = table_fmt; | ||||
| SSF.load = function load_entry(fmt/*:string*/, idx/*:number*/) { table_fmt[idx] = fmt; }; | ||||
| SSF.format = format; | ||||
| SSF.get_table = function get_table() { return table_fmt; }; | ||||
| SSF.load_table = function load_table(tbl/*:{[n:number]:string}*/) { for(var i=0; i!=0x0188; ++i) if(tbl[i] !== undefined) SSF.load(tbl[i], i); }; | ||||
| SSF.get_table = function get_table()/*:SSFTable*/ { return table_fmt; }; | ||||
| SSF.load_table = function load_table(tbl/*:SSFTable*/)/*:void*/ { | ||||
| 	for(var i=0; i!=0x0188; ++i) | ||||
| 		if(tbl[i] !== undefined) load_entry(tbl[i], i); | ||||
| }; | ||||
| SSF.init_table = init_table; | ||||
| SSF.format = format; | ||||
| }; | ||||
| make_ssf(SSF); | ||||
|  | ||||
							
								
								
									
										147
									
								
								bits/18_cfb.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										147
									
								
								bits/18_cfb.js
									
									
									
									
									
								
							| @ -18,20 +18,25 @@ declare var chr1:any; | ||||
| /*jshint eqnull:true */ | ||||
| 
 | ||||
| /*:: | ||||
| declare var DO_NOT_EXPORT_CFB:any; | ||||
| type SectorEntry = any; | ||||
| declare var DO_NOT_EXPORT_CFB:?boolean; | ||||
| type SectorEntry = { | ||||
| 	name?:string; | ||||
| 	nodes?:Array<number>; | ||||
| 	data:RawBytes; | ||||
| }; | ||||
| type SectorList = { | ||||
| 	(k:string|number):SectorEntry; | ||||
| 	[k:string|number]:SectorEntry; | ||||
| 	name:?string; | ||||
| 	fat_addrs:any; | ||||
| 	fat_addrs:Array<number>; | ||||
| 	ssz:number; | ||||
| } | ||||
| type CFBFiles = {[n:string]:CFBEntry}; | ||||
| */ | ||||
| /* [MS-CFB] v20130118 */ | ||||
| var CFB = (function _CFB(){ | ||||
| var exports = {}; | ||||
| exports.version = '0.11.1'; | ||||
| function parse(file) { | ||||
| var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/; | ||||
| exports.version = '0.12.0'; | ||||
| function parse(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/ { | ||||
| var mver = 3; // major version
 | ||||
| var ssz = 512; // sector size
 | ||||
| var nmfs = 0; // number of mini FAT sectors
 | ||||
| @ -40,10 +45,10 @@ var dir_start = 0; // first directory sector location | ||||
| var minifat_start = 0; // first mini FAT sector location
 | ||||
| var difat_start = 0; // first mini FAT sector location
 | ||||
| 
 | ||||
| var fat_addrs = []; // locations of FAT sectors
 | ||||
| var fat_addrs/*:Array<number>*/ = []; // locations of FAT sectors
 | ||||
| 
 | ||||
| /* [MS-CFB] 2.2 Compound File Header */ | ||||
| var blob/*:any*/ = file.slice(0,512); | ||||
| var blob/*:CFBlob*/ = /*::(*/file.slice(0,512)/*:: :any)*/; | ||||
| prep_blob(blob, 0); | ||||
| 
 | ||||
| /* major version */ | ||||
| @ -55,14 +60,14 @@ switch(mver) { | ||||
| } | ||||
| 
 | ||||
| /* reprocess header */ | ||||
| if(ssz !== 512) { blob = file.slice(0,ssz); prep_blob(blob, 28 /* blob.l */); } | ||||
| if(ssz !== 512) { blob = /*::(*/file.slice(0,ssz)/*:: :any)*/; prep_blob(blob, 28 /* blob.l */); } | ||||
| /* Save header for final object */ | ||||
| var header = file.slice(0,ssz); | ||||
| var header/*:RawBytes*/ = file.slice(0,ssz); | ||||
| 
 | ||||
| check_shifts(blob, mver); | ||||
| 
 | ||||
| // Number of Directory Sectors
 | ||||
| var nds = blob.read_shift(4, 'i'); | ||||
| var nds/*:number*/ = blob.read_shift(4, 'i'); | ||||
| if(mver === 3 && nds !== 0) throw new Error('# Directory Sectors: Expected 0 saw ' + nds); | ||||
| 
 | ||||
| // Number of FAT Sectors
 | ||||
| @ -91,14 +96,14 @@ difat_start = blob.read_shift(4, 'i'); | ||||
| ndfs = blob.read_shift(4, 'i'); | ||||
| 
 | ||||
| // Grab FAT Sector Locations
 | ||||
| for(var q, j = 0; j < 109; ++j) { /* 109 = (512 - blob.l)>>>2; */ | ||||
| for(var q = -1, j = 0; j < 109; ++j) { /* 109 = (512 - blob.l)>>>2; */ | ||||
| 	q = blob.read_shift(4, 'i'); | ||||
| 	if(q<0) break; | ||||
| 	fat_addrs[j] = q; | ||||
| } | ||||
| 
 | ||||
| /** Break the file up into sectors */ | ||||
| var sectors = sectorify(file, ssz); | ||||
| var sectors/*:Array<RawBytes>*/ = sectorify(file, ssz); | ||||
| 
 | ||||
| sleuth_fat(difat_start, ndfs, sectors, ssz, fat_addrs); | ||||
| 
 | ||||
| @ -112,13 +117,12 @@ sector_list.fat_addrs = fat_addrs; | ||||
| sector_list.ssz = ssz; | ||||
| 
 | ||||
| /* [MS-CFB] 2.6.1 Compound File Directory Entry */ | ||||
| var files = {}, Paths/*:any*/ = [], FileIndex = [], FullPaths = [], FullPathDir = {}; | ||||
| var files/*:CFBFiles*/ = {}, Paths/*:Array<string>*/ = [], FileIndex/*:CFBFileIndex*/ = [], FullPaths/*:Array<string>*/ = [], FullPathDir = {}; | ||||
| read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex); | ||||
| 
 | ||||
| build_full_paths(FileIndex, FullPathDir, FullPaths, Paths); | ||||
| 
 | ||||
| var root_name = Paths.shift(); | ||||
| Paths.root = root_name; | ||||
| var root_name/*:string*/ = Paths.shift(); | ||||
| 
 | ||||
| /* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */ | ||||
| var find_path = make_find_path(FullPaths, Paths, FileIndex, files, root_name); | ||||
| @ -133,7 +137,7 @@ return { | ||||
| } // parse
 | ||||
| 
 | ||||
| /* [MS-CFB] 2.2 Compound File Header -- read up to major version */ | ||||
| function check_get_mver(blob) { | ||||
| function check_get_mver(blob/*:CFBlob*/)/*:[number, number]*/ { | ||||
| 	// header signature 8
 | ||||
| 	blob.chk(HEADER_SIGNATURE, 'Header Signature: '); | ||||
| 
 | ||||
| @ -141,11 +145,11 @@ function check_get_mver(blob) { | ||||
| 	blob.chk(HEADER_CLSID, 'CLSID: '); | ||||
| 
 | ||||
| 	// minor version 2
 | ||||
| 	var mver = blob.read_shift(2, 'u'); | ||||
| 	var mver/*:number*/ = blob.read_shift(2, 'u'); | ||||
| 
 | ||||
| 	return [blob.read_shift(2,'u'), mver]; | ||||
| } | ||||
| function check_shifts(blob, mver) { | ||||
| function check_shifts(blob/*:CFBlob*/, mver/*:number*/)/*:void*/ { | ||||
| 	var shift = 0x09; | ||||
| 
 | ||||
| 	// Byte Order
 | ||||
| @ -167,18 +171,18 @@ function check_shifts(blob, mver) { | ||||
| } | ||||
| 
 | ||||
| /** Break the file up into sectors */ | ||||
| function sectorify(file, ssz) { | ||||
| function sectorify(file/*:RawBytes*/, ssz/*:number*/)/*:Array<RawBytes>*/ { | ||||
| 	var nsectors = Math.ceil(file.length/ssz)-1; | ||||
| 	var sectors = new Array(nsectors); | ||||
| 	var sectors/*:Array<RawBytes>*/ = []; | ||||
| 	for(var i=1; i < nsectors; ++i) sectors[i-1] = file.slice(i*ssz,(i+1)*ssz); | ||||
| 	sectors[nsectors-1] = file.slice(nsectors*ssz); | ||||
| 	return sectors; | ||||
| } | ||||
| 
 | ||||
| /* [MS-CFB] 2.6.4 Red-Black Tree */ | ||||
| function build_full_paths(FI, FPD, FP, Paths) { | ||||
| function build_full_paths(FI/*:CFBFileIndex*/, FPD/*:CFBFullPathDir*/, FP/*:Array<string>*/, Paths/*:Array<string>*/)/*:void*/ { | ||||
| 	var i = 0, L = 0, R = 0, C = 0, j = 0, pl = Paths.length; | ||||
| 	var dad = new Array(pl), q = new Array(pl); | ||||
| 	var dad/*:Array<number>*/ = [], q/*:Array<number>*/ = []; | ||||
| 
 | ||||
| 	for(; i < pl; ++i) { dad[i]=q[i]=i; FP[i]=Paths[i]; } | ||||
| 
 | ||||
| @ -217,17 +221,17 @@ function build_full_paths(FI, FPD, FP, Paths) { | ||||
| } | ||||
| 
 | ||||
| /* [MS-CFB] 2.6.4 */ | ||||
| function make_find_path(FullPaths, Paths, FileIndex, files, root_name) { | ||||
| 	var UCFullPaths = new Array(FullPaths.length); | ||||
| 	var UCPaths = new Array(Paths.length), i; | ||||
| function make_find_path(FullPaths/*:Array<string>*/, Paths/*:Array<string>*/, FileIndex/*:CFBFileIndex*/, files/*:CFBFiles*/, root_name/*:string*/)/*:CFBFindPath*/ { | ||||
| 	var UCFullPaths/*:Array<string>*/ = []; | ||||
| 	var UCPaths/*:Array<string>*/ = [], i = 0; | ||||
| 	for(i = 0; i < FullPaths.length; ++i) UCFullPaths[i] = FullPaths[i].toUpperCase().replace(chr0,'').replace(chr1,'!'); | ||||
| 	for(i = 0; i < Paths.length; ++i) UCPaths[i] = Paths[i].toUpperCase().replace(chr0,'').replace(chr1,'!'); | ||||
| 	return function find_path(path/*:string*/) { | ||||
| 		var k; | ||||
| 	return function find_path(path/*:string*/)/*:?CFBEntry*/ { | ||||
| 		var k/*:boolean*/ = false; | ||||
| 		if(path.charCodeAt(0) === 47 /* "/" */) { k=true; path = root_name + path; } | ||||
| 		else k = path.indexOf("/") !== -1; | ||||
| 		var UCPath = path.toUpperCase().replace(chr0,'').replace(chr1,'!'); | ||||
| 		var w = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath); | ||||
| 		var UCPath/*:string*/ = path.toUpperCase().replace(chr0,'').replace(chr1,'!'); | ||||
| 		var w/*:number*/ = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath); | ||||
| 		if(w === -1) return null; | ||||
| 		return k === true ? FileIndex[w] : files[Paths[w]]; | ||||
| 	}; | ||||
| @ -235,8 +239,8 @@ function make_find_path(FullPaths, Paths, FileIndex, files, root_name) { | ||||
| 
 | ||||
| /** Chase down the rest of the DIFAT chain to build a comprehensive list | ||||
|     DIFAT chains by storing the next sector number as the last 32 bytes */ | ||||
| function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) { | ||||
| 	var q; | ||||
| function sleuth_fat(idx/*:number*/, cnt/*:number*/, sectors/*:Array<RawBytes>*/, ssz/*:number*/, fat_addrs)/*:void*/ { | ||||
| 	var q/*:number*/ = ENDOFCHAIN; | ||||
| 	if(idx === ENDOFCHAIN) { | ||||
| 		if(cnt !== 0) throw new Error("DIFAT chain shorter than expected"); | ||||
| 	} else if(idx !== -1 /*FREESECT*/) { | ||||
| @ -251,13 +255,11 @@ function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) { | ||||
| } | ||||
| 
 | ||||
| /** Follow the linked list of sectors for a given starting point */ | ||||
| function get_sector_list(sectors, start, fat_addrs, ssz, chkd) { | ||||
| function get_sector_list(sectors/*:Array<RawBytes>*/, start/*:number*/, fat_addrs/*:Array<number>*/, ssz/*:number*/, chkd/*:?Array<boolean>*/)/*:SectorEntry*/ { | ||||
| 	var sl = sectors.length; | ||||
| 	var buf, buf_chain; | ||||
| 	if(!chkd) chkd = new Array(sl); | ||||
| 	var modulus = ssz - 1, j, jj; | ||||
| 	buf = []; | ||||
| 	buf_chain = []; | ||||
| 	var buf/*:Array<number>*/ = [], buf_chain/*:Array<any>*/ = []; | ||||
| 	if(!chkd) chkd = []; | ||||
| 	var modulus = ssz - 1, j = 0, jj = 0; | ||||
| 	for(j=start; j>=0;) { | ||||
| 		chkd[j] = true; | ||||
| 		buf[buf.length] = j; | ||||
| @ -272,44 +274,43 @@ function get_sector_list(sectors, start, fat_addrs, ssz, chkd) { | ||||
| } | ||||
| 
 | ||||
| /** Chase down the sector linked lists */ | ||||
| function make_sector_list(sectors, dir_start, fat_addrs, ssz/*:number*/)/*:any*/ { | ||||
| 	var sl = sectors.length, sector_list = new Array(sl); | ||||
| 	var chkd = new Array(sl), buf, buf_chain; | ||||
| 	var modulus = ssz - 1, i, j, k, jj; | ||||
| function make_sector_list(sectors/*:Array<RawBytes>*/, dir_start/*:number*/, fat_addrs/*:Array<number>*/, ssz/*:number*/)/*:SectorList*/ { | ||||
| 	var sl = sectors.length, sector_list/*:SectorList*/ = ([]/*:any*/); | ||||
| 	var chkd/*:Array<boolean>*/ = [], buf/*:Array<number>*/ = [], buf_chain/*:Array<RawBytes>*/ = []; | ||||
| 	var modulus = ssz - 1, i=0, j=0, k=0, jj=0; | ||||
| 	for(i=0; i < sl; ++i) { | ||||
| 		buf = []; | ||||
| 		buf = ([]/*:Array<number>*/); | ||||
| 		k = (i + dir_start); if(k >= sl) k-=sl; | ||||
| 		if(chkd[k] === true) continue; | ||||
| 		if(chkd[k]) continue; | ||||
| 		buf_chain = []; | ||||
| 		for(j=k; j>=0;) { | ||||
| 			chkd[j] = true; | ||||
| 			buf[buf.length] = j; | ||||
| 			buf_chain.push(sectors[j]); | ||||
| 			var addr = fat_addrs[Math.floor(j*4/ssz)]; | ||||
| 			var addr/*:number*/ = fat_addrs[Math.floor(j*4/ssz)]; | ||||
| 			jj = ((j*4) & modulus); | ||||
| 			if(ssz < 4 + jj) throw new Error("FAT boundary crossed: " + j + " 4 "+ssz); | ||||
| 			if(!sectors[addr]) break; | ||||
| 			j = __readInt32LE(sectors[addr], jj); | ||||
| 		} | ||||
| 		sector_list[k] = {nodes: buf, data:__toBuffer([buf_chain])}; | ||||
| 		sector_list[k] = ({nodes: buf, data:__toBuffer([buf_chain])}/*:SectorEntry*/); | ||||
| 	} | ||||
| 	return sector_list; | ||||
| } | ||||
| 
 | ||||
| /* [MS-CFB] 2.6.1 Compound File Directory Entry */ | ||||
| function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex) { | ||||
| 	var blob; | ||||
| function read_directory(dir_start/*:number*/, sector_list/*:SectorList*/, sectors/*:Array<RawBytes>*/, Paths/*:Array<string>*/, nmfs, files, FileIndex) { | ||||
| 	var minifat_store = 0, pl = (Paths.length?2:0); | ||||
| 	var sector = sector_list[dir_start].data; | ||||
| 	var i = 0, namelen = 0, name, o, ctime, mtime; | ||||
| 	var i = 0, namelen = 0, name; | ||||
| 	for(; i < sector.length; i+= 128) { | ||||
| 		blob = sector.slice(i, i+128); | ||||
| 		var blob/*:CFBlob*/ = /*::(*/sector.slice(i, i+128)/*:: :any)*/; | ||||
| 		prep_blob(blob, 64); | ||||
| 		namelen = blob.read_shift(2); | ||||
| 		if(namelen === 0) continue; | ||||
| 		name = __utf16le(blob,0,namelen-pl); | ||||
| 		Paths.push(name); | ||||
| 		o = ({ | ||||
| 		var o/*:CFBEntry*/ = ({ | ||||
| 			name:  name, | ||||
| 			type:  blob.read_shift(1), | ||||
| 			color: blob.read_shift(1), | ||||
| @ -317,16 +318,14 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil | ||||
| 			R:     blob.read_shift(4, 'i'), | ||||
| 			C:     blob.read_shift(4, 'i'), | ||||
| 			clsid: blob.read_shift(16), | ||||
| 			state: blob.read_shift(4, 'i') | ||||
| 		}/*:any*/); | ||||
| 		ctime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2); | ||||
| 		if(ctime !== 0) { | ||||
| 			o.ctime = ctime; o.ct = read_date(blob, blob.l-8); | ||||
| 		} | ||||
| 		mtime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2); | ||||
| 		if(mtime !== 0) { | ||||
| 			o.mtime = mtime; o.mt = read_date(blob, blob.l-8); | ||||
| 		} | ||||
| 			state: blob.read_shift(4, 'i'), | ||||
| 			start: 0, | ||||
| 			size: 0 | ||||
| 		}); | ||||
| 		var ctime/*:number*/ = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2); | ||||
| 		if(ctime !== 0) o.ct = read_date(blob, blob.l-8); | ||||
| 		var mtime/*:number*/ = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2); | ||||
| 		if(mtime !== 0) o.mt = read_date(blob, blob.l-8); | ||||
| 		o.start = blob.read_shift(4, 'i'); | ||||
| 		o.size = blob.read_shift(4, 'i'); | ||||
| 		if(o.type === 5) { /* root */ | ||||
| @ -337,12 +336,12 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil | ||||
| 			o.storage = 'fat'; | ||||
| 			if(sector_list[o.start] === undefined) sector_list[o.start] = get_sector_list(sectors, o.start, sector_list.fat_addrs, sector_list.ssz); | ||||
| 			sector_list[o.start].name = o.name; | ||||
| 			o.content = sector_list[o.start].data.slice(0,o.size); | ||||
| 			o.content = (sector_list[o.start].data.slice(0,o.size)/*:any*/); | ||||
| 			prep_blob(o.content, 0); | ||||
| 		} else { | ||||
| 			o.storage = 'minifat'; | ||||
| 			if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN) { | ||||
| 				o.content = sector_list[minifat_store].data.slice(o.start*MSSZ,o.start*MSSZ+o.size); | ||||
| 				o.content = (sector_list[minifat_store].data.slice(o.start*MSSZ,o.start*MSSZ+o.size)/*:any*/); | ||||
| 				prep_blob(o.content, 0); | ||||
| 			} | ||||
| 		} | ||||
| @ -351,23 +350,23 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function read_date(blob, offset) { | ||||
| function read_date(blob/*:RawBytes|CFBlob*/, offset/*:number*/)/*:Date*/ { | ||||
| 	return new Date(( ( (__readUInt32LE(blob,offset+4)/1e7)*Math.pow(2,32)+__readUInt32LE(blob,offset)/1e7 ) - 11644473600)*1000); | ||||
| } | ||||
| 
 | ||||
| var fs; | ||||
| function readFileSync(filename/*:string*/, options/*:any*/) { | ||||
| 	if(fs === undefined) fs = require('fs'); | ||||
| var fs/*:: = require('fs'); */; | ||||
| function readFileSync(filename/*:string*/, options/*:CFBReadOpts*/) { | ||||
| 	if(fs == null) fs = require('fs'); | ||||
| 	return parse(fs.readFileSync(filename), options); | ||||
| } | ||||
| 
 | ||||
| function readSync(blob/*:any*/, options/*:any*/) { | ||||
| 	switch(options !== undefined && options.type !== undefined ? options.type : "base64") { | ||||
| 		case "file": return readFileSync(blob, options); | ||||
| 		case "base64": return parse(s2a(Base64.decode(blob)), options); | ||||
| 		case "binary": return parse(s2a(blob), options); | ||||
| function readSync(blob/*:RawBytes|string*/, options/*:CFBReadOpts*/) { | ||||
| 	switch(options && options.type || "base64") { | ||||
| 		case "file": /*:: if(typeof blob !== 'string') throw "Must pass a filename when type='file'"; */return readFileSync(blob, options); | ||||
| 		case "base64": /*:: if(typeof blob !== 'string') throw "Must pass a base64-encoded binary string when type='file'"; */return parse(s2a(Base64.decode(blob)), options); | ||||
| 		case "binary": /*:: if(typeof blob !== 'string') throw "Must pass a binary string when type='file'"; */return parse(s2a(blob), options); | ||||
| 	} | ||||
| 	return parse(blob); | ||||
| 	return parse(/*::typeof blob == 'string' ? new Buffer(blob, 'utf-8') : */blob, options); | ||||
| } | ||||
| 
 | ||||
| /** CFB Constants */ | ||||
|  | ||||
| @ -26,6 +26,24 @@ The write demo: | ||||
| - generates file on client side | ||||
| - triggers a download. | ||||
| 
 | ||||
| This demo uses the FileSaver.js library for writing files, installed through the | ||||
| [`pfafman:filesaver` wrapper](https://atmospherejs.com/pfafman/filesaver): | ||||
| 
 | ||||
| ```bash | ||||
| meteor add pfafman:filesaver | ||||
| ``` | ||||
| 
 | ||||
| ## Setup | ||||
| 
 | ||||
| This tree does not include the `.meteor` structure.  Rebuild the project with: | ||||
| 
 | ||||
| ```bash | ||||
| meteor create . | ||||
| npm install babel-runtime meteor-node-stubs xlsx | ||||
| meteor add pfafman:filesaver | ||||
| meteor | ||||
| ``` | ||||
| 
 | ||||
| 
 | ||||
| ## Environment-specific features | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										2
									
								
								dist/cpexcel.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/cpexcel.js
									
									
									
									
										vendored
									
									
								
							| @ -1,6 +1,6 @@ | ||||
| /* cpexcel.js (C) 2013-present SheetJS -- http://sheetjs.com */ | ||||
| /*jshint -W100 */ | ||||
| var cptable = {version:"1.9.0"}; | ||||
| var cptable = {version:"1.10.0"}; | ||||
| cptable[437] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })(); | ||||
| cptable[620] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàąçêëèïîćÄĄĘęłôöĆûùŚÖܢ٥śƒŹŻóÓńŃźż¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })(); | ||||
| cptable[737] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })(); | ||||
|  | ||||
							
								
								
									
										30
									
								
								dist/xlsx.core.min.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										30
									
								
								dist/xlsx.core.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.core.min.map
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.core.min.map
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										32
									
								
								dist/xlsx.full.min.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										32
									
								
								dist/xlsx.full.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.full.min.map
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.full.min.map
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										512
									
								
								dist/xlsx.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										512
									
								
								dist/xlsx.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										28
									
								
								dist/xlsx.min.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										28
									
								
								dist/xlsx.min.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.min.map
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.min.map
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										114
									
								
								misc/flowdeps.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										114
									
								
								misc/flowdeps.js
									
									
									
									
									
								
							| @ -12,6 +12,120 @@ declare module 'fs' { declare var exports:any; }; | ||||
| 
 | ||||
| type ZIP = any; | ||||
| 
 | ||||
| type SSFTable = {[key:number|string]:string}; | ||||
| type SSFDate = { | ||||
| 	D:number; T:number; | ||||
| 	y:number; m:number; d:number; q:number; | ||||
| 	H:number; M:number; S:number; u:number; | ||||
| }; | ||||
| 
 | ||||
| type SSFModule = { | ||||
| 	format:(fmt:string|number, v:any, o:any)=>string; | ||||
| 
 | ||||
| 	is_date:(fmt:string)=>boolean; | ||||
| 	parse_date_code:(v:number,opts:any)=>?SSFDate; | ||||
| 
 | ||||
| 	load:(fmt:string, idx:?number)=>number; | ||||
| 	get_table:()=>SSFTable; | ||||
| 	load_table:(table:any)=>void; | ||||
| 	_table:SSFTable; | ||||
| 	init_table:any; | ||||
| 
 | ||||
| 	_general_int:(v:number)=>string; | ||||
| 	_general_num:(v:number)=>string; | ||||
| 	_general:(v:number, o:?any)=>string; | ||||
| 	_eval:any; | ||||
| 	_split:any; | ||||
| 	version:string; | ||||
| }; | ||||
| 
 | ||||
| // ----------------------------------------------------------------------------
 | ||||
| // Note: The following override is needed because ReadShift includes more cases
 | ||||
| // ----------------------------------------------------------------------------
 | ||||
| 
 | ||||
| type CFBModule = { | ||||
| 	version:string; | ||||
| 	read:(blob:RawBytes|string, opts:CFBReadOpts)=>CFBContainer; | ||||
| 	parse:(file:RawBytes, opts:CFBReadOpts)=>CFBContainer; | ||||
| 	utils:CFBUtils; | ||||
| }; | ||||
| 
 | ||||
| type CFBFullPathDir = { | ||||
| 	[n:string]: CFBEntry; | ||||
| } | ||||
| 
 | ||||
| type CFBUtils = any; | ||||
| 
 | ||||
| type CheckFieldFunc = {(hexstr:string, fld:string):void;}; | ||||
| 
 | ||||
| type RawBytes = Array<number> | Buffer | Uint8Array; | ||||
| 
 | ||||
| class CFBlobArray extends Array<number> { | ||||
| 	l:number; | ||||
| 	read_shift:ReadShiftFunc; | ||||
| 	chk:CheckFieldFunc; | ||||
| }; | ||||
| interface CFBlobBuffer extends Buffer { | ||||
| 	l:number; | ||||
| 	slice:(start:number, end:?number)=>Buffer; | ||||
| 	read_shift:ReadShiftFunc; | ||||
| 	chk:CheckFieldFunc; | ||||
| }; | ||||
| interface CFBlobUint8 extends Uint8Array { | ||||
| 	l:number; | ||||
| 	slice:(start:number, end:?number)=>Uint8Array; | ||||
| 	read_shift:ReadShiftFunc; | ||||
| 	chk:CheckFieldFunc; | ||||
| }; | ||||
| 
 | ||||
| interface CFBlobber { | ||||
| 	[n:number]:number; | ||||
| 	l:number; | ||||
| 	length:number; | ||||
| 	slice:(start:number, end:?number)=>RawBytes; | ||||
| 	read_shift:ReadShiftFunc; | ||||
| 	chk:CheckFieldFunc; | ||||
| }; | ||||
| 
 | ||||
| type CFBlob = CFBlobArray | CFBlobBuffer | CFBlobUint8; | ||||
| 
 | ||||
| interface CFBReadOpts { | ||||
| 	type?:string; | ||||
| }; | ||||
| 
 | ||||
| type CFBFileIndex = Array<CFBEntry>; | ||||
| 
 | ||||
| type CFBFindPath = (n:string)=>?CFBEntry; | ||||
| 
 | ||||
| type CFBContainer = { | ||||
| 	raw:{ | ||||
| 		header:any; | ||||
| 		sectors:Array<any>; | ||||
| 	}; | ||||
| 	FileIndex:CFBFileIndex; | ||||
| 	FullPathDir:CFBDirectory; | ||||
| 	FullPaths:Array<string>; | ||||
| 	find:CFBFindPath; | ||||
| } | ||||
| 
 | ||||
| type CFBEntry = { | ||||
| 	name: string; | ||||
| 	type: number; | ||||
| 	ct?: Date; | ||||
| 	mt?: Date; | ||||
| 	color: number; | ||||
| 	clsid: string; | ||||
| 	state: number; | ||||
| 	start: number; | ||||
| 	size: number; | ||||
| 	storage?: "fat" | "minifat"; | ||||
| 	L: number; | ||||
| 	R: number; | ||||
| 	C: number; | ||||
| 	content?: CFBlob; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // ----------------------------------------------------------------------------
 | ||||
| // Note: The following override is needed because Flow is missing Date#getYear
 | ||||
| // ----------------------------------------------------------------------------
 | ||||
|  | ||||
							
								
								
									
										17
									
								
								package.json
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										17
									
								
								package.json
									
									
									
									
									
								
							| @ -1,6 +1,6 @@ | ||||
| { | ||||
| 	"name": "xlsx", | ||||
| 	"version": "0.10.8", | ||||
| 	"version": "0.10.9", | ||||
| 	"author": "sheetjs", | ||||
| 	"description": "Excel (XLSB/XLSX/XLS/XML) ODS and other spreadsheet format (CSV/DIF/DBF/SYLK) parser and writer", | ||||
| 	"keywords": [ "excel", "xls", "xlsx", "xlsb", "xlsm", "ods", "csv", "dbf", "dif", "sylk", "office", "spreadsheet" ], | ||||
| @ -18,20 +18,19 @@ | ||||
| 	}, | ||||
| 	"dependencies": { | ||||
| 		"exit-on-epipe":"~1.0.1", | ||||
| 		"ssf":"~0.9.4", | ||||
| 		"codepage":"~1.9.0", | ||||
| 		"cfb":"~0.11.1", | ||||
| 		"crc-32":"~1.0.2", | ||||
| 		"adler-32":"~1.0.0", | ||||
| 		"ssf":"~0.10.0", | ||||
| 		"codepage":"~1.10.1", | ||||
| 		"cfb":"~0.12.0", | ||||
| 		"crc-32":"~1.1.0", | ||||
| 		"adler-32":"~1.1.0", | ||||
| 		"commander":"~2.11.0" | ||||
| 	}, | ||||
| 	"devDependencies": { | ||||
| 		"mocha":"~2.5.3", | ||||
| 		"blanket": "~1.2.3", | ||||
| 		"xlsjs":"*", | ||||
| 		"@sheetjs/uglify-js":"*", | ||||
| 		"@sheetjs/uglify-js":"~2.7.3", | ||||
| 		"@types/node":"^8.0.7", | ||||
| 		"@types/commander":"*", | ||||
| 		"@types/commander":"^2.9.0", | ||||
| 		"dtslint": "^0.1.2", | ||||
| 		"typescript": "2.2.0" | ||||
| 	}, | ||||
|  | ||||
							
								
								
									
										329
									
								
								xlsx.flow.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										329
									
								
								xlsx.flow.js
									
									
									
									
									
								
							| @ -6,7 +6,7 @@ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false */ | ||||
| var XLSX = {}; | ||||
| (function make_xlsx(XLSX){ | ||||
| XLSX.version = '0.10.8'; | ||||
| XLSX.version = '0.10.9'; | ||||
| var current_codepage = 1200; | ||||
| /*:: declare var cptable:any; */ | ||||
| /*global cptable:true */ | ||||
| @ -130,9 +130,9 @@ type WriteObjStrFactory = {from_sheet(ws:Worksheet, o:any, wb:?Workbook):string} | ||||
| */ | ||||
| /* ssf.js (C) 2013-present SheetJS -- http://sheetjs.com */ | ||||
| /*jshint -W041 */ | ||||
| var SSF = {}; | ||||
| var make_ssf = function make_ssf(SSF){ | ||||
| SSF.version = '0.9.4'; | ||||
| var SSF/*:SSFModule*/ = ({}/*:any*/); | ||||
| var make_ssf = function make_ssf(SSF/*:SSFModule*/){ | ||||
| SSF.version = '0.10.0'; | ||||
| function _strrev(x/*:string*/)/*:string*/ { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; } | ||||
| function fill(c/*:string*/,l/*:number*/)/*:string*/ { var o = ""; while(o.length < l) o+=c; return o; } | ||||
| function pad0(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;} | ||||
| @ -143,16 +143,9 @@ function pad0r2(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>= | ||||
| var p2_32 = Math.pow(2,32); | ||||
| function pad0r(v/*:any*/,d/*:number*/)/*:string*/{if(v>p2_32||v<-p2_32) return pad0r1(v,d); var i = Math.round(v); return pad0r2(i,d); } | ||||
| function isgeneral(s/*:string*/, i/*:?number*/)/*:boolean*/ { i = i || 0; return s.length >= 7 + i && (s.charCodeAt(i)|32) === 103 && (s.charCodeAt(i+1)|32) === 101 && (s.charCodeAt(i+2)|32) === 110 && (s.charCodeAt(i+3)|32) === 101 && (s.charCodeAt(i+4)|32) === 114 && (s.charCodeAt(i+5)|32) === 97 && (s.charCodeAt(i+6)|32) === 108; } | ||||
| /* Options */ | ||||
| var opts_fmt/*:Array<Array<any> >*/ = [ | ||||
| 	["date1904", 0], | ||||
| 	["output", ""], | ||||
| 	["WTF", false] | ||||
| ]; | ||||
| function fixopts(o){ | ||||
| 	for(var y = 0; y != opts_fmt.length; ++y) if(o[opts_fmt[y][0]]===undefined) o[opts_fmt[y][0]]=opts_fmt[y][1]; | ||||
| } | ||||
| SSF.opts = opts_fmt; | ||||
| /*:: | ||||
| type SSF_write_num = {(type:string, fmt:string, val:number):string}; | ||||
| */ | ||||
| var days/*:Array<Array<string> >*/ = [ | ||||
| 	['Sun', 'Sunday'], | ||||
| 	['Mon', 'Monday'], | ||||
| @ -231,7 +224,47 @@ function frac(x/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Array<number>*/ | ||||
| 	var q = Math.floor(sgn * P/Q); | ||||
| 	return [q, sgn*P - q*Q, Q]; | ||||
| } | ||||
| function general_fmt_int(v/*:number*/)/*:string*/ { return ""+v; } | ||||
| function parse_date_code(v/*:number*/,opts/*:?any*/,b2/*:?boolean*/) { | ||||
| 	if(v > 2958465 || v < 0) return null; | ||||
| 	var date = (v|0), time = Math.floor(86400 * (v - date)), dow=0; | ||||
| 	var dout=[]; | ||||
| 	var out={D:date, T:time, u:86400*(v-date)-time,y:0,m:0,d:0,H:0,M:0,S:0,q:0}; | ||||
| 	if(Math.abs(out.u) < 1e-6) out.u = 0; | ||||
| 	if(opts && opts.date1904) date += 1462; | ||||
| 	if(out.u > 0.9999) { | ||||
| 		out.u = 0; | ||||
| 		if(++time == 86400) { out.T = time = 0; ++date; ++out.D; } | ||||
| 	} | ||||
| 	if(date === 60) {dout = b2 ? [1317,10,29] : [1900,2,29]; dow=3;} | ||||
| 	else if(date === 0) {dout = b2 ? [1317,8,29] : [1900,1,0]; dow=6;} | ||||
| 	else { | ||||
| 		if(date > 60) --date; | ||||
| 		/* 1 = Jan 1 1900 in Gregorian */ | ||||
| 		var d = new Date(1900, 0, 1); | ||||
| 		d.setDate(d.getDate() + date - 1); | ||||
| 		dout = [d.getFullYear(), d.getMonth()+1,d.getDate()]; | ||||
| 		dow = d.getDay(); | ||||
| 		if(date < 60) dow = (dow + 6) % 7; | ||||
| 		if(b2) dow = fix_hijri(d, dout); | ||||
| 	} | ||||
| 	out.y = dout[0]; out.m = dout[1]; out.d = dout[2]; | ||||
| 	out.S = time % 60; time = Math.floor(time / 60); | ||||
| 	out.M = time % 60; time = Math.floor(time / 60); | ||||
| 	out.H = time; | ||||
| 	out.q = dow; | ||||
| 	return out; | ||||
| } | ||||
| SSF.parse_date_code = parse_date_code; | ||||
| var basedate = new Date(1899, 11, 31, 0, 0, 0); | ||||
| var dnthresh = basedate.getTime(); | ||||
| var base1904 = new Date(1900, 2, 1, 0, 0, 0); | ||||
| function datenum_local(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ { | ||||
| 	var epoch = v.getTime(); | ||||
| 	if(date1904) epoch -= 1461*24*60*60*1000; | ||||
| 	else if(v >= base1904) epoch += 24*60*60*1000; | ||||
| 	return (epoch - (dnthresh + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000)) / (24 * 60 * 60 * 1000); | ||||
| } | ||||
| function general_fmt_int(v/*:number*/)/*:string*/ { return v.toString(10); } | ||||
| SSF._general_int = general_fmt_int; | ||||
| var general_fmt_num = (function make_general_fmt_num() { | ||||
| var gnr1 = /\.(\d*[1-9])0+$/, gnr2 = /\.0*$/, gnr4 = /\.(\d*[1-9])0+/, gnr5 = /\.0*[Ee]/, gnr6 = /(E[+-])(\d)$/; | ||||
| @ -262,50 +295,20 @@ return function general_fmt_num(v/*:number*/)/*:string*/ { | ||||
| 	return gfn5(gfn4(o)); | ||||
| };})(); | ||||
| SSF._general_num = general_fmt_num; | ||||
| function general_fmt(v/*:any*/) { | ||||
| function general_fmt(v/*:any*/, opts/*:any*/) { | ||||
| 	switch(typeof v) { | ||||
| 		case 'string': return v; | ||||
| 		case 'boolean': return v ? "TRUE" : "FALSE"; | ||||
| 		case 'number': return (v|0) === v ? general_fmt_int(v/*, opts*/) : general_fmt_num(v/*, opts*/); | ||||
| 		case 'number': return (v|0) === v ? general_fmt_int(v) : general_fmt_num(v); | ||||
| 		case 'undefined': return ""; | ||||
| 		case 'object': if(v == null) return ""; | ||||
| 		case 'object': | ||||
| 			if(v == null) return ""; | ||||
| 			if(v instanceof Date) return format(14, datenum_local(v, opts && opts.date1904), opts); | ||||
| 	} | ||||
| 	throw new Error("unsupported value in General format: " + v); | ||||
| } | ||||
| SSF._general = general_fmt; | ||||
| function fix_hijri(/*date, o*/) { return 0; } | ||||
| function parse_date_code(v/*:number*/,opts/*:?any*/,b2/*:?boolean*/) { | ||||
| 	if(v > 2958465 || v < 0) return null; | ||||
| 	var date = (v|0), time = Math.floor(86400 * (v - date)), dow=0; | ||||
| 	var dout=[]; | ||||
| 	var out={D:date, T:time, u:86400*(v-date)-time,y:0,m:0,d:0,H:0,M:0,S:0,q:0}; | ||||
| 	if(Math.abs(out.u) < 1e-6) out.u = 0; | ||||
| 	fixopts(opts != null ? opts : (opts=[])); | ||||
| 	if(opts.date1904) date += 1462; | ||||
| 	if(out.u > 0.9999) { | ||||
| 		out.u = 0; | ||||
| 		if(++time == 86400) { out.T = time = 0; ++date; ++out.D; } | ||||
| 	} | ||||
| 	if(date === 60) {dout = b2 ? [1317,10,29] : [1900,2,29]; dow=3;} | ||||
| 	else if(date === 0) {dout = b2 ? [1317,8,29] : [1900,1,0]; dow=6;} | ||||
| 	else { | ||||
| 		if(date > 60) --date; | ||||
| 		/* 1 = Jan 1 1900 in Gregorian */ | ||||
| 		var d = new Date(1900, 0, 1); | ||||
| 		d.setDate(d.getDate() + date - 1); | ||||
| 		dout = [d.getFullYear(), d.getMonth()+1,d.getDate()]; | ||||
| 		dow = d.getDay(); | ||||
| 		if(date < 60) dow = (dow + 6) % 7; | ||||
| 		if(b2) dow = fix_hijri(d, dout); | ||||
| 	} | ||||
| 	out.y = dout[0]; out.m = dout[1]; out.d = dout[2]; | ||||
| 	out.S = time % 60; time = Math.floor(time / 60); | ||||
| 	out.M = time % 60; time = Math.floor(time / 60); | ||||
| 	out.H = time; | ||||
| 	out.q = dow; | ||||
| 	return out; | ||||
| } | ||||
| SSF.parse_date_code = parse_date_code; | ||||
| function fix_hijri(/*::date, o*/) { return 0; } | ||||
| /*jshint -W086 */ | ||||
| function write_date(type/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:string*/ { | ||||
| 	var o="", ss=0, tt=0, y = val.y, out, outl = 0; | ||||
| @ -347,23 +350,17 @@ function write_date(type/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:str | ||||
| 			default: throw 'bad minute format: ' + fmt; | ||||
| 		} break; | ||||
| 		case 115: /* 's' seconds */ | ||||
| 		if(val.u === 0) switch(fmt) { | ||||
| 			case 's': case 'ss': return pad0(val.S, fmt.length); | ||||
| 			case '.0': case '.00': case '.000': | ||||
| 		} | ||||
| 		switch(fmt) { | ||||
| 			case 's': case 'ss': case '.0': case '.00': case '.000': | ||||
| 				/*::if(!ss0) ss0 = 0; */ | ||||
| 				if(ss0 >= 2) tt = ss0 === 3 ? 1000 : 100; | ||||
| 				else tt = ss0 === 1 ? 10 : 1; | ||||
| 				ss = Math.round((tt)*(val.S + val.u)); | ||||
| 				if(ss >= 60*tt) ss = 0; | ||||
| 				if(fmt === 's') return ss === 0 ? "0" : ""+ss/tt; | ||||
| 				o = pad0(ss,2 + ss0); | ||||
| 				if(fmt === 'ss') return o.substr(0,2); | ||||
| 				return "." + o.substr(2,fmt.length-1); | ||||
| 			default: throw 'bad second format: ' + fmt; | ||||
| 		} | ||||
| 			if(fmt != 's' && fmt != 'ss' && fmt != '.0' && fmt != '.00' && fmt != '.000') throw 'bad second format: ' + fmt; | ||||
| 			if(val.u === 0 && (fmt == "s" || fmt == "ss")) return pad0(val.S, fmt.length); | ||||
| 			/*::if(!ss0) ss0 = 0; */ | ||||
| 			if(ss0 >= 2) tt = ss0 === 3 ? 1000 : 100; | ||||
| 			else tt = ss0 === 1 ? 10 : 1; | ||||
| 			ss = Math.round((tt)*(val.S + val.u)); | ||||
| 			if(ss >= 60*tt) ss = 0; | ||||
| 			if(fmt === 's') return ss === 0 ? "0" : ""+ss/tt; | ||||
| 			o = pad0(ss,2 + ss0); | ||||
| 			if(fmt === 'ss') return o.substr(0,2); | ||||
| 			return "." + o.substr(2,fmt.length-1); | ||||
| 		case 90: /* 'Z' absolute time */ | ||||
| 		switch(fmt) { | ||||
| 			case '[h]': case '[hh]': out = val.D*24+val.H; break; | ||||
| @ -378,12 +375,13 @@ function write_date(type/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:str | ||||
| } | ||||
| /*jshint +W086 */ | ||||
| function commaify(s/*:string*/)/*:string*/ { | ||||
| 	if(s.length <= 3) return s; | ||||
| 	var j = (s.length % 3), o = s.substr(0,j); | ||||
| 	for(; j!=s.length; j+=3) o+=(o.length > 0 ? "," : "") + s.substr(j,3); | ||||
| 	var w = 3; | ||||
| 	if(s.length <= w) return s; | ||||
| 	var j = (s.length % w), o = s.substr(0,j); | ||||
| 	for(; j!=s.length; j+=w) o+=(o.length > 0 ? "," : "") + s.substr(j,w); | ||||
| 	return o; | ||||
| } | ||||
| var write_num = (function make_write_num(){ | ||||
| var write_num/*:SSF_write_num*/ = (function make_write_num(){ | ||||
| var pct1 = /%/g; | ||||
| function write_num_pct(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string*/{ | ||||
| 	var sfmt = fmt.replace(pct1,""), mul = fmt.length - sfmt.length; | ||||
| @ -721,7 +719,7 @@ function fmt_is_date(fmt/*:string*/)/*:boolean*/ { | ||||
| } | ||||
| SSF.is_date = fmt_is_date; | ||||
| function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 	var out = [], o = "", i = 0, c = "", lst='t', q, dt, j, cc; | ||||
| 	var out = [], o = "", i = 0, c = "", lst='t', dt, j, cc; | ||||
| 	var hr='H'; | ||||
| 	/* Tokenize */ | ||||
| 	while(i < fmt.length) { | ||||
| @ -749,12 +747,12 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 			case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g': | ||||
| 				if(v < 0) return ""; | ||||
| 				if(dt==null) { dt=parse_date_code(v, opts); if(dt==null) return ""; } | ||||
| 				o = c; while(++i<fmt.length && fmt.charAt(i).toLowerCase() === c) o+=c; | ||||
| 				o = c; while(++i < fmt.length && fmt.charAt(i).toLowerCase() === c) o+=c; | ||||
| 				if(c === 'm' && lst.toLowerCase() === 'h') c = 'M'; | ||||
| 				if(c === 'h') c = hr; | ||||
| 				out[out.length] = {t:c, v:o}; lst = c; break; | ||||
| 			case 'A': case 'a': | ||||
| 				q={t:c, v:c}; | ||||
| 				var q={t:c, v:c}; | ||||
| 				if(dt==null) dt=parse_date_code(v, opts); | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;} | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; } | ||||
| @ -777,7 +775,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 			/* Numbers */ | ||||
| 			case '.': | ||||
| 				if(dt != null) { | ||||
| 					o = c; while((c=fmt.charAt(++i)) === "0") o += c; | ||||
| 					o = c; while(++i < fmt.length && (c=fmt.charAt(i)) === "0") o += c; | ||||
| 					out[out.length] = {t:'s', v:o}; break; | ||||
| 				} | ||||
| 				/* falls through */ | ||||
| @ -786,7 +784,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) { | ||||
| 				out[out.length] = {t:'n', v:o}; break; | ||||
| 			case '?': | ||||
| 				o = c; while(fmt.charAt(++i) === c) o+=c; | ||||
| 				q={t:c, v:o}; out[out.length] = q; lst = c; break; | ||||
| 				out[out.length] = {t:c, v:o}; lst = c; break; | ||||
| 			case '*': ++i; if(fmt.charAt(i) == ' ' || fmt.charAt(i) == '*') ++i; break; // **
 | ||||
| 			case '(': case ')': out[out.length] = {t:(flen===1?'t':c), v:c}; ++i; break; | ||||
| 			case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': | ||||
| @ -937,7 +935,7 @@ function chkcond(v, rr) { | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
| function choose_fmt(f/*:string*/, v) { | ||||
| function choose_fmt(f/*:string*/, v/*:any*/) { | ||||
| 	var fmt = split_fmt(f); | ||||
| 	var l = fmt.length, lat = fmt[l-1].indexOf("@"); | ||||
| 	if(l<4 && lat>-1) --l; | ||||
| @ -972,18 +970,38 @@ function format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) { | ||||
| 			break; | ||||
| 	} | ||||
| 	if(isgeneral(sfmt,0)) return general_fmt(v, o); | ||||
| 	if(v instanceof Date) v = datenum_local(v, o.date1904); | ||||
| 	var f = choose_fmt(sfmt, v); | ||||
| 	if(isgeneral(f[1])) return general_fmt(v, o); | ||||
| 	if(v === true) v = "TRUE"; else if(v === false) v = "FALSE"; | ||||
| 	else if(v === "" || v == null) return ""; | ||||
| 	return eval_fmt(f[1], v, o, f[0]); | ||||
| } | ||||
| function load_entry(fmt/*:string*/, idx/*:?number*/)/*:number*/ { | ||||
| 	if(typeof idx != 'number') { | ||||
| 		idx = +idx || -1; | ||||
| /*::if(typeof idx != 'number') return 0x188; */ | ||||
| 		for(var i = 0; i < 0x0188; ++i) { | ||||
| /*::if(typeof idx != 'number') return 0x188; */ | ||||
| 			if(table_fmt[i] == undefined) { if(idx < 0) idx = i; continue; } | ||||
| 			if(table_fmt[i] == fmt) { idx = i; break; } | ||||
| 		} | ||||
| /*::if(typeof idx != 'number') return 0x188; */ | ||||
| 		if(idx < 0) idx = 0x187; | ||||
| 	} | ||||
| /*::if(typeof idx != 'number') return 0x188; */ | ||||
| 	table_fmt[idx] = fmt; | ||||
| 	return idx; | ||||
| } | ||||
| SSF.load = load_entry; | ||||
| SSF._table = table_fmt; | ||||
| SSF.load = function load_entry(fmt/*:string*/, idx/*:number*/) { table_fmt[idx] = fmt; }; | ||||
| SSF.format = format; | ||||
| SSF.get_table = function get_table() { return table_fmt; }; | ||||
| SSF.load_table = function load_table(tbl/*:{[n:number]:string}*/) { for(var i=0; i!=0x0188; ++i) if(tbl[i] !== undefined) SSF.load(tbl[i], i); }; | ||||
| SSF.get_table = function get_table()/*:SSFTable*/ { return table_fmt; }; | ||||
| SSF.load_table = function load_table(tbl/*:SSFTable*/)/*:void*/ { | ||||
| 	for(var i=0; i!=0x0188; ++i) | ||||
| 		if(tbl[i] !== undefined) load_entry(tbl[i], i); | ||||
| }; | ||||
| SSF.init_table = init_table; | ||||
| SSF.format = format; | ||||
| }; | ||||
| make_ssf(SSF); | ||||
| /* map from xlml named formats to SSF TODO: localize */ | ||||
| @ -1053,20 +1071,25 @@ declare var chr1:any; | ||||
| /*jshint eqnull:true */ | ||||
| 
 | ||||
| /*:: | ||||
| declare var DO_NOT_EXPORT_CFB:any; | ||||
| type SectorEntry = any; | ||||
| declare var DO_NOT_EXPORT_CFB:?boolean; | ||||
| type SectorEntry = { | ||||
| 	name?:string; | ||||
| 	nodes?:Array<number>; | ||||
| 	data:RawBytes; | ||||
| }; | ||||
| type SectorList = { | ||||
| 	(k:string|number):SectorEntry; | ||||
| 	[k:string|number]:SectorEntry; | ||||
| 	name:?string; | ||||
| 	fat_addrs:any; | ||||
| 	fat_addrs:Array<number>; | ||||
| 	ssz:number; | ||||
| } | ||||
| type CFBFiles = {[n:string]:CFBEntry}; | ||||
| */ | ||||
| /* [MS-CFB] v20130118 */ | ||||
| var CFB = (function _CFB(){ | ||||
| var exports = {}; | ||||
| exports.version = '0.11.1'; | ||||
| function parse(file) { | ||||
| var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/; | ||||
| exports.version = '0.12.0'; | ||||
| function parse(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/ { | ||||
| var mver = 3; // major version
 | ||||
| var ssz = 512; // sector size
 | ||||
| var nmfs = 0; // number of mini FAT sectors
 | ||||
| @ -1075,10 +1098,10 @@ var dir_start = 0; // first directory sector location | ||||
| var minifat_start = 0; // first mini FAT sector location
 | ||||
| var difat_start = 0; // first mini FAT sector location
 | ||||
| 
 | ||||
| var fat_addrs = []; // locations of FAT sectors
 | ||||
| var fat_addrs/*:Array<number>*/ = []; // locations of FAT sectors
 | ||||
| 
 | ||||
| /* [MS-CFB] 2.2 Compound File Header */ | ||||
| var blob/*:any*/ = file.slice(0,512); | ||||
| var blob/*:CFBlob*/ = /*::(*/file.slice(0,512)/*:: :any)*/; | ||||
| prep_blob(blob, 0); | ||||
| 
 | ||||
| /* major version */ | ||||
| @ -1090,14 +1113,14 @@ switch(mver) { | ||||
| } | ||||
| 
 | ||||
| /* reprocess header */ | ||||
| if(ssz !== 512) { blob = file.slice(0,ssz); prep_blob(blob, 28 /* blob.l */); } | ||||
| if(ssz !== 512) { blob = /*::(*/file.slice(0,ssz)/*:: :any)*/; prep_blob(blob, 28 /* blob.l */); } | ||||
| /* Save header for final object */ | ||||
| var header = file.slice(0,ssz); | ||||
| var header/*:RawBytes*/ = file.slice(0,ssz); | ||||
| 
 | ||||
| check_shifts(blob, mver); | ||||
| 
 | ||||
| // Number of Directory Sectors
 | ||||
| var nds = blob.read_shift(4, 'i'); | ||||
| var nds/*:number*/ = blob.read_shift(4, 'i'); | ||||
| if(mver === 3 && nds !== 0) throw new Error('# Directory Sectors: Expected 0 saw ' + nds); | ||||
| 
 | ||||
| // Number of FAT Sectors
 | ||||
| @ -1126,14 +1149,14 @@ difat_start = blob.read_shift(4, 'i'); | ||||
| ndfs = blob.read_shift(4, 'i'); | ||||
| 
 | ||||
| // Grab FAT Sector Locations
 | ||||
| for(var q, j = 0; j < 109; ++j) { /* 109 = (512 - blob.l)>>>2; */ | ||||
| for(var q = -1, j = 0; j < 109; ++j) { /* 109 = (512 - blob.l)>>>2; */ | ||||
| 	q = blob.read_shift(4, 'i'); | ||||
| 	if(q<0) break; | ||||
| 	fat_addrs[j] = q; | ||||
| } | ||||
| 
 | ||||
| /** Break the file up into sectors */ | ||||
| var sectors = sectorify(file, ssz); | ||||
| var sectors/*:Array<RawBytes>*/ = sectorify(file, ssz); | ||||
| 
 | ||||
| sleuth_fat(difat_start, ndfs, sectors, ssz, fat_addrs); | ||||
| 
 | ||||
| @ -1147,13 +1170,12 @@ sector_list.fat_addrs = fat_addrs; | ||||
| sector_list.ssz = ssz; | ||||
| 
 | ||||
| /* [MS-CFB] 2.6.1 Compound File Directory Entry */ | ||||
| var files = {}, Paths/*:any*/ = [], FileIndex = [], FullPaths = [], FullPathDir = {}; | ||||
| var files/*:CFBFiles*/ = {}, Paths/*:Array<string>*/ = [], FileIndex/*:CFBFileIndex*/ = [], FullPaths/*:Array<string>*/ = [], FullPathDir = {}; | ||||
| read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex); | ||||
| 
 | ||||
| build_full_paths(FileIndex, FullPathDir, FullPaths, Paths); | ||||
| 
 | ||||
| var root_name = Paths.shift(); | ||||
| Paths.root = root_name; | ||||
| var root_name/*:string*/ = Paths.shift(); | ||||
| 
 | ||||
| /* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */ | ||||
| var find_path = make_find_path(FullPaths, Paths, FileIndex, files, root_name); | ||||
| @ -1168,7 +1190,7 @@ return { | ||||
| } // parse
 | ||||
| 
 | ||||
| /* [MS-CFB] 2.2 Compound File Header -- read up to major version */ | ||||
| function check_get_mver(blob) { | ||||
| function check_get_mver(blob/*:CFBlob*/)/*:[number, number]*/ { | ||||
| 	// header signature 8
 | ||||
| 	blob.chk(HEADER_SIGNATURE, 'Header Signature: '); | ||||
| 
 | ||||
| @ -1176,11 +1198,11 @@ function check_get_mver(blob) { | ||||
| 	blob.chk(HEADER_CLSID, 'CLSID: '); | ||||
| 
 | ||||
| 	// minor version 2
 | ||||
| 	var mver = blob.read_shift(2, 'u'); | ||||
| 	var mver/*:number*/ = blob.read_shift(2, 'u'); | ||||
| 
 | ||||
| 	return [blob.read_shift(2,'u'), mver]; | ||||
| } | ||||
| function check_shifts(blob, mver) { | ||||
| function check_shifts(blob/*:CFBlob*/, mver/*:number*/)/*:void*/ { | ||||
| 	var shift = 0x09; | ||||
| 
 | ||||
| 	// Byte Order
 | ||||
| @ -1202,18 +1224,18 @@ function check_shifts(blob, mver) { | ||||
| } | ||||
| 
 | ||||
| /** Break the file up into sectors */ | ||||
| function sectorify(file, ssz) { | ||||
| function sectorify(file/*:RawBytes*/, ssz/*:number*/)/*:Array<RawBytes>*/ { | ||||
| 	var nsectors = Math.ceil(file.length/ssz)-1; | ||||
| 	var sectors = new Array(nsectors); | ||||
| 	var sectors/*:Array<RawBytes>*/ = []; | ||||
| 	for(var i=1; i < nsectors; ++i) sectors[i-1] = file.slice(i*ssz,(i+1)*ssz); | ||||
| 	sectors[nsectors-1] = file.slice(nsectors*ssz); | ||||
| 	return sectors; | ||||
| } | ||||
| 
 | ||||
| /* [MS-CFB] 2.6.4 Red-Black Tree */ | ||||
| function build_full_paths(FI, FPD, FP, Paths) { | ||||
| function build_full_paths(FI/*:CFBFileIndex*/, FPD/*:CFBFullPathDir*/, FP/*:Array<string>*/, Paths/*:Array<string>*/)/*:void*/ { | ||||
| 	var i = 0, L = 0, R = 0, C = 0, j = 0, pl = Paths.length; | ||||
| 	var dad = new Array(pl), q = new Array(pl); | ||||
| 	var dad/*:Array<number>*/ = [], q/*:Array<number>*/ = []; | ||||
| 
 | ||||
| 	for(; i < pl; ++i) { dad[i]=q[i]=i; FP[i]=Paths[i]; } | ||||
| 
 | ||||
| @ -1252,17 +1274,17 @@ function build_full_paths(FI, FPD, FP, Paths) { | ||||
| } | ||||
| 
 | ||||
| /* [MS-CFB] 2.6.4 */ | ||||
| function make_find_path(FullPaths, Paths, FileIndex, files, root_name) { | ||||
| 	var UCFullPaths = new Array(FullPaths.length); | ||||
| 	var UCPaths = new Array(Paths.length), i; | ||||
| function make_find_path(FullPaths/*:Array<string>*/, Paths/*:Array<string>*/, FileIndex/*:CFBFileIndex*/, files/*:CFBFiles*/, root_name/*:string*/)/*:CFBFindPath*/ { | ||||
| 	var UCFullPaths/*:Array<string>*/ = []; | ||||
| 	var UCPaths/*:Array<string>*/ = [], i = 0; | ||||
| 	for(i = 0; i < FullPaths.length; ++i) UCFullPaths[i] = FullPaths[i].toUpperCase().replace(chr0,'').replace(chr1,'!'); | ||||
| 	for(i = 0; i < Paths.length; ++i) UCPaths[i] = Paths[i].toUpperCase().replace(chr0,'').replace(chr1,'!'); | ||||
| 	return function find_path(path/*:string*/) { | ||||
| 		var k; | ||||
| 	return function find_path(path/*:string*/)/*:?CFBEntry*/ { | ||||
| 		var k/*:boolean*/ = false; | ||||
| 		if(path.charCodeAt(0) === 47 /* "/" */) { k=true; path = root_name + path; } | ||||
| 		else k = path.indexOf("/") !== -1; | ||||
| 		var UCPath = path.toUpperCase().replace(chr0,'').replace(chr1,'!'); | ||||
| 		var w = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath); | ||||
| 		var UCPath/*:string*/ = path.toUpperCase().replace(chr0,'').replace(chr1,'!'); | ||||
| 		var w/*:number*/ = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath); | ||||
| 		if(w === -1) return null; | ||||
| 		return k === true ? FileIndex[w] : files[Paths[w]]; | ||||
| 	}; | ||||
| @ -1270,8 +1292,8 @@ function make_find_path(FullPaths, Paths, FileIndex, files, root_name) { | ||||
| 
 | ||||
| /** Chase down the rest of the DIFAT chain to build a comprehensive list | ||||
|     DIFAT chains by storing the next sector number as the last 32 bytes */ | ||||
| function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) { | ||||
| 	var q; | ||||
| function sleuth_fat(idx/*:number*/, cnt/*:number*/, sectors/*:Array<RawBytes>*/, ssz/*:number*/, fat_addrs)/*:void*/ { | ||||
| 	var q/*:number*/ = ENDOFCHAIN; | ||||
| 	if(idx === ENDOFCHAIN) { | ||||
| 		if(cnt !== 0) throw new Error("DIFAT chain shorter than expected"); | ||||
| 	} else if(idx !== -1 /*FREESECT*/) { | ||||
| @ -1286,13 +1308,11 @@ function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) { | ||||
| } | ||||
| 
 | ||||
| /** Follow the linked list of sectors for a given starting point */ | ||||
| function get_sector_list(sectors, start, fat_addrs, ssz, chkd) { | ||||
| function get_sector_list(sectors/*:Array<RawBytes>*/, start/*:number*/, fat_addrs/*:Array<number>*/, ssz/*:number*/, chkd/*:?Array<boolean>*/)/*:SectorEntry*/ { | ||||
| 	var sl = sectors.length; | ||||
| 	var buf, buf_chain; | ||||
| 	if(!chkd) chkd = new Array(sl); | ||||
| 	var modulus = ssz - 1, j, jj; | ||||
| 	buf = []; | ||||
| 	buf_chain = []; | ||||
| 	var buf/*:Array<number>*/ = [], buf_chain/*:Array<any>*/ = []; | ||||
| 	if(!chkd) chkd = []; | ||||
| 	var modulus = ssz - 1, j = 0, jj = 0; | ||||
| 	for(j=start; j>=0;) { | ||||
| 		chkd[j] = true; | ||||
| 		buf[buf.length] = j; | ||||
| @ -1307,44 +1327,43 @@ function get_sector_list(sectors, start, fat_addrs, ssz, chkd) { | ||||
| } | ||||
| 
 | ||||
| /** Chase down the sector linked lists */ | ||||
| function make_sector_list(sectors, dir_start, fat_addrs, ssz/*:number*/)/*:any*/ { | ||||
| 	var sl = sectors.length, sector_list = new Array(sl); | ||||
| 	var chkd = new Array(sl), buf, buf_chain; | ||||
| 	var modulus = ssz - 1, i, j, k, jj; | ||||
| function make_sector_list(sectors/*:Array<RawBytes>*/, dir_start/*:number*/, fat_addrs/*:Array<number>*/, ssz/*:number*/)/*:SectorList*/ { | ||||
| 	var sl = sectors.length, sector_list/*:SectorList*/ = ([]/*:any*/); | ||||
| 	var chkd/*:Array<boolean>*/ = [], buf/*:Array<number>*/ = [], buf_chain/*:Array<RawBytes>*/ = []; | ||||
| 	var modulus = ssz - 1, i=0, j=0, k=0, jj=0; | ||||
| 	for(i=0; i < sl; ++i) { | ||||
| 		buf = []; | ||||
| 		buf = ([]/*:Array<number>*/); | ||||
| 		k = (i + dir_start); if(k >= sl) k-=sl; | ||||
| 		if(chkd[k] === true) continue; | ||||
| 		if(chkd[k]) continue; | ||||
| 		buf_chain = []; | ||||
| 		for(j=k; j>=0;) { | ||||
| 			chkd[j] = true; | ||||
| 			buf[buf.length] = j; | ||||
| 			buf_chain.push(sectors[j]); | ||||
| 			var addr = fat_addrs[Math.floor(j*4/ssz)]; | ||||
| 			var addr/*:number*/ = fat_addrs[Math.floor(j*4/ssz)]; | ||||
| 			jj = ((j*4) & modulus); | ||||
| 			if(ssz < 4 + jj) throw new Error("FAT boundary crossed: " + j + " 4 "+ssz); | ||||
| 			if(!sectors[addr]) break; | ||||
| 			j = __readInt32LE(sectors[addr], jj); | ||||
| 		} | ||||
| 		sector_list[k] = {nodes: buf, data:__toBuffer([buf_chain])}; | ||||
| 		sector_list[k] = ({nodes: buf, data:__toBuffer([buf_chain])}/*:SectorEntry*/); | ||||
| 	} | ||||
| 	return sector_list; | ||||
| } | ||||
| 
 | ||||
| /* [MS-CFB] 2.6.1 Compound File Directory Entry */ | ||||
| function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex) { | ||||
| 	var blob; | ||||
| function read_directory(dir_start/*:number*/, sector_list/*:SectorList*/, sectors/*:Array<RawBytes>*/, Paths/*:Array<string>*/, nmfs, files, FileIndex) { | ||||
| 	var minifat_store = 0, pl = (Paths.length?2:0); | ||||
| 	var sector = sector_list[dir_start].data; | ||||
| 	var i = 0, namelen = 0, name, o, ctime, mtime; | ||||
| 	var i = 0, namelen = 0, name; | ||||
| 	for(; i < sector.length; i+= 128) { | ||||
| 		blob = sector.slice(i, i+128); | ||||
| 		var blob/*:CFBlob*/ = /*::(*/sector.slice(i, i+128)/*:: :any)*/; | ||||
| 		prep_blob(blob, 64); | ||||
| 		namelen = blob.read_shift(2); | ||||
| 		if(namelen === 0) continue; | ||||
| 		name = __utf16le(blob,0,namelen-pl); | ||||
| 		Paths.push(name); | ||||
| 		o = ({ | ||||
| 		var o/*:CFBEntry*/ = ({ | ||||
| 			name:  name, | ||||
| 			type:  blob.read_shift(1), | ||||
| 			color: blob.read_shift(1), | ||||
| @ -1352,16 +1371,14 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil | ||||
| 			R:     blob.read_shift(4, 'i'), | ||||
| 			C:     blob.read_shift(4, 'i'), | ||||
| 			clsid: blob.read_shift(16), | ||||
| 			state: blob.read_shift(4, 'i') | ||||
| 		}/*:any*/); | ||||
| 		ctime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2); | ||||
| 		if(ctime !== 0) { | ||||
| 			o.ctime = ctime; o.ct = read_date(blob, blob.l-8); | ||||
| 		} | ||||
| 		mtime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2); | ||||
| 		if(mtime !== 0) { | ||||
| 			o.mtime = mtime; o.mt = read_date(blob, blob.l-8); | ||||
| 		} | ||||
| 			state: blob.read_shift(4, 'i'), | ||||
| 			start: 0, | ||||
| 			size: 0 | ||||
| 		}); | ||||
| 		var ctime/*:number*/ = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2); | ||||
| 		if(ctime !== 0) o.ct = read_date(blob, blob.l-8); | ||||
| 		var mtime/*:number*/ = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2); | ||||
| 		if(mtime !== 0) o.mt = read_date(blob, blob.l-8); | ||||
| 		o.start = blob.read_shift(4, 'i'); | ||||
| 		o.size = blob.read_shift(4, 'i'); | ||||
| 		if(o.type === 5) { /* root */ | ||||
| @ -1372,12 +1389,12 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil | ||||
| 			o.storage = 'fat'; | ||||
| 			if(sector_list[o.start] === undefined) sector_list[o.start] = get_sector_list(sectors, o.start, sector_list.fat_addrs, sector_list.ssz); | ||||
| 			sector_list[o.start].name = o.name; | ||||
| 			o.content = sector_list[o.start].data.slice(0,o.size); | ||||
| 			o.content = (sector_list[o.start].data.slice(0,o.size)/*:any*/); | ||||
| 			prep_blob(o.content, 0); | ||||
| 		} else { | ||||
| 			o.storage = 'minifat'; | ||||
| 			if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN) { | ||||
| 				o.content = sector_list[minifat_store].data.slice(o.start*MSSZ,o.start*MSSZ+o.size); | ||||
| 				o.content = (sector_list[minifat_store].data.slice(o.start*MSSZ,o.start*MSSZ+o.size)/*:any*/); | ||||
| 				prep_blob(o.content, 0); | ||||
| 			} | ||||
| 		} | ||||
| @ -1386,23 +1403,23 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function read_date(blob, offset) { | ||||
| function read_date(blob/*:RawBytes|CFBlob*/, offset/*:number*/)/*:Date*/ { | ||||
| 	return new Date(( ( (__readUInt32LE(blob,offset+4)/1e7)*Math.pow(2,32)+__readUInt32LE(blob,offset)/1e7 ) - 11644473600)*1000); | ||||
| } | ||||
| 
 | ||||
| var fs; | ||||
| function readFileSync(filename/*:string*/, options/*:any*/) { | ||||
| 	if(fs === undefined) fs = require('fs'); | ||||
| var fs/*:: = require('fs'); */; | ||||
| function readFileSync(filename/*:string*/, options/*:CFBReadOpts*/) { | ||||
| 	if(fs == null) fs = require('fs'); | ||||
| 	return parse(fs.readFileSync(filename), options); | ||||
| } | ||||
| 
 | ||||
| function readSync(blob/*:any*/, options/*:any*/) { | ||||
| 	switch(options !== undefined && options.type !== undefined ? options.type : "base64") { | ||||
| 		case "file": return readFileSync(blob, options); | ||||
| 		case "base64": return parse(s2a(Base64.decode(blob)), options); | ||||
| 		case "binary": return parse(s2a(blob), options); | ||||
| function readSync(blob/*:RawBytes|string*/, options/*:CFBReadOpts*/) { | ||||
| 	switch(options && options.type || "base64") { | ||||
| 		case "file": /*:: if(typeof blob !== 'string') throw "Must pass a filename when type='file'"; */return readFileSync(blob, options); | ||||
| 		case "base64": /*:: if(typeof blob !== 'string') throw "Must pass a base64-encoded binary string when type='file'"; */return parse(s2a(Base64.decode(blob)), options); | ||||
| 		case "binary": /*:: if(typeof blob !== 'string') throw "Must pass a binary string when type='file'"; */return parse(s2a(blob), options); | ||||
| 	} | ||||
| 	return parse(blob); | ||||
| 	return parse(/*::typeof blob == 'string' ? new Buffer(blob, 'utf-8') : */blob, options); | ||||
| } | ||||
| 
 | ||||
| /** CFB Constants */ | ||||
|  | ||||
							
								
								
									
										235
									
								
								xlsx.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										235
									
								
								xlsx.js
									
									
									
									
									
								
							| @ -6,7 +6,7 @@ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false */ | ||||
| var XLSX = {}; | ||||
| (function make_xlsx(XLSX){ | ||||
| XLSX.version = '0.10.8'; | ||||
| XLSX.version = '0.10.9'; | ||||
| var current_codepage = 1200; | ||||
| /*global cptable:true */ | ||||
| if(typeof module !== "undefined" && typeof require !== 'undefined') { | ||||
| @ -110,9 +110,9 @@ var bconcat = function(bufs) { return [].concat.apply([], bufs); }; | ||||
| var chr0 = /\u0000/g, chr1 = /[\u0001-\u0006]/; | ||||
| /* ssf.js (C) 2013-present SheetJS -- http://sheetjs.com */ | ||||
| /*jshint -W041 */ | ||||
| var SSF = {}; | ||||
| var SSF = ({}); | ||||
| var make_ssf = function make_ssf(SSF){ | ||||
| SSF.version = '0.9.4'; | ||||
| SSF.version = '0.10.0'; | ||||
| function _strrev(x) { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; } | ||||
| function fill(c,l) { var o = ""; while(o.length < l) o+=c; return o; } | ||||
| function pad0(v,d){var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;} | ||||
| @ -123,16 +123,6 @@ function pad0r2(v,d){var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;} | ||||
| var p2_32 = Math.pow(2,32); | ||||
| function pad0r(v,d){if(v>p2_32||v<-p2_32) return pad0r1(v,d); var i = Math.round(v); return pad0r2(i,d); } | ||||
| function isgeneral(s, i) { i = i || 0; return s.length >= 7 + i && (s.charCodeAt(i)|32) === 103 && (s.charCodeAt(i+1)|32) === 101 && (s.charCodeAt(i+2)|32) === 110 && (s.charCodeAt(i+3)|32) === 101 && (s.charCodeAt(i+4)|32) === 114 && (s.charCodeAt(i+5)|32) === 97 && (s.charCodeAt(i+6)|32) === 108; } | ||||
| /* Options */ | ||||
| var opts_fmt = [ | ||||
| 	["date1904", 0], | ||||
| 	["output", ""], | ||||
| 	["WTF", false] | ||||
| ]; | ||||
| function fixopts(o){ | ||||
| 	for(var y = 0; y != opts_fmt.length; ++y) if(o[opts_fmt[y][0]]===undefined) o[opts_fmt[y][0]]=opts_fmt[y][1]; | ||||
| } | ||||
| SSF.opts = opts_fmt; | ||||
| var days = [ | ||||
| 	['Sun', 'Sunday'], | ||||
| 	['Mon', 'Monday'], | ||||
| @ -211,7 +201,47 @@ function frac(x, D, mixed) { | ||||
| 	var q = Math.floor(sgn * P/Q); | ||||
| 	return [q, sgn*P - q*Q, Q]; | ||||
| } | ||||
| function general_fmt_int(v) { return ""+v; } | ||||
| function parse_date_code(v,opts,b2) { | ||||
| 	if(v > 2958465 || v < 0) return null; | ||||
| 	var date = (v|0), time = Math.floor(86400 * (v - date)), dow=0; | ||||
| 	var dout=[]; | ||||
| 	var out={D:date, T:time, u:86400*(v-date)-time,y:0,m:0,d:0,H:0,M:0,S:0,q:0}; | ||||
| 	if(Math.abs(out.u) < 1e-6) out.u = 0; | ||||
| 	if(opts && opts.date1904) date += 1462; | ||||
| 	if(out.u > 0.9999) { | ||||
| 		out.u = 0; | ||||
| 		if(++time == 86400) { out.T = time = 0; ++date; ++out.D; } | ||||
| 	} | ||||
| 	if(date === 60) {dout = b2 ? [1317,10,29] : [1900,2,29]; dow=3;} | ||||
| 	else if(date === 0) {dout = b2 ? [1317,8,29] : [1900,1,0]; dow=6;} | ||||
| 	else { | ||||
| 		if(date > 60) --date; | ||||
| 		/* 1 = Jan 1 1900 in Gregorian */ | ||||
| 		var d = new Date(1900, 0, 1); | ||||
| 		d.setDate(d.getDate() + date - 1); | ||||
| 		dout = [d.getFullYear(), d.getMonth()+1,d.getDate()]; | ||||
| 		dow = d.getDay(); | ||||
| 		if(date < 60) dow = (dow + 6) % 7; | ||||
| 		if(b2) dow = fix_hijri(d, dout); | ||||
| 	} | ||||
| 	out.y = dout[0]; out.m = dout[1]; out.d = dout[2]; | ||||
| 	out.S = time % 60; time = Math.floor(time / 60); | ||||
| 	out.M = time % 60; time = Math.floor(time / 60); | ||||
| 	out.H = time; | ||||
| 	out.q = dow; | ||||
| 	return out; | ||||
| } | ||||
| SSF.parse_date_code = parse_date_code; | ||||
| var basedate = new Date(1899, 11, 31, 0, 0, 0); | ||||
| var dnthresh = basedate.getTime(); | ||||
| var base1904 = new Date(1900, 2, 1, 0, 0, 0); | ||||
| function datenum_local(v, date1904) { | ||||
| 	var epoch = v.getTime(); | ||||
| 	if(date1904) epoch -= 1461*24*60*60*1000; | ||||
| 	else if(v >= base1904) epoch += 24*60*60*1000; | ||||
| 	return (epoch - (dnthresh + (v.getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000)) / (24 * 60 * 60 * 1000); | ||||
| } | ||||
| function general_fmt_int(v) { return v.toString(10); } | ||||
| SSF._general_int = general_fmt_int; | ||||
| var general_fmt_num = (function make_general_fmt_num() { | ||||
| var gnr1 = /\.(\d*[1-9])0+$/, gnr2 = /\.0*$/, gnr4 = /\.(\d*[1-9])0+/, gnr5 = /\.0*[Ee]/, gnr6 = /(E[+-])(\d)$/; | ||||
| @ -242,50 +272,20 @@ return function general_fmt_num(v) { | ||||
| 	return gfn5(gfn4(o)); | ||||
| };})(); | ||||
| SSF._general_num = general_fmt_num; | ||||
| function general_fmt(v) { | ||||
| function general_fmt(v, opts) { | ||||
| 	switch(typeof v) { | ||||
| 		case 'string': return v; | ||||
| 		case 'boolean': return v ? "TRUE" : "FALSE"; | ||||
| 		case 'number': return (v|0) === v ? general_fmt_int(v/*, opts*/) : general_fmt_num(v/*, opts*/); | ||||
| 		case 'number': return (v|0) === v ? general_fmt_int(v) : general_fmt_num(v); | ||||
| 		case 'undefined': return ""; | ||||
| 		case 'object': if(v == null) return ""; | ||||
| 		case 'object': | ||||
| 			if(v == null) return ""; | ||||
| 			if(v instanceof Date) return format(14, datenum_local(v, opts && opts.date1904), opts); | ||||
| 	} | ||||
| 	throw new Error("unsupported value in General format: " + v); | ||||
| } | ||||
| SSF._general = general_fmt; | ||||
| function fix_hijri(/*date, o*/) { return 0; } | ||||
| function parse_date_code(v,opts,b2) { | ||||
| 	if(v > 2958465 || v < 0) return null; | ||||
| 	var date = (v|0), time = Math.floor(86400 * (v - date)), dow=0; | ||||
| 	var dout=[]; | ||||
| 	var out={D:date, T:time, u:86400*(v-date)-time,y:0,m:0,d:0,H:0,M:0,S:0,q:0}; | ||||
| 	if(Math.abs(out.u) < 1e-6) out.u = 0; | ||||
| 	fixopts(opts != null ? opts : (opts=[])); | ||||
| 	if(opts.date1904) date += 1462; | ||||
| 	if(out.u > 0.9999) { | ||||
| 		out.u = 0; | ||||
| 		if(++time == 86400) { out.T = time = 0; ++date; ++out.D; } | ||||
| 	} | ||||
| 	if(date === 60) {dout = b2 ? [1317,10,29] : [1900,2,29]; dow=3;} | ||||
| 	else if(date === 0) {dout = b2 ? [1317,8,29] : [1900,1,0]; dow=6;} | ||||
| 	else { | ||||
| 		if(date > 60) --date; | ||||
| 		/* 1 = Jan 1 1900 in Gregorian */ | ||||
| 		var d = new Date(1900, 0, 1); | ||||
| 		d.setDate(d.getDate() + date - 1); | ||||
| 		dout = [d.getFullYear(), d.getMonth()+1,d.getDate()]; | ||||
| 		dow = d.getDay(); | ||||
| 		if(date < 60) dow = (dow + 6) % 7; | ||||
| 		if(b2) dow = fix_hijri(d, dout); | ||||
| 	} | ||||
| 	out.y = dout[0]; out.m = dout[1]; out.d = dout[2]; | ||||
| 	out.S = time % 60; time = Math.floor(time / 60); | ||||
| 	out.M = time % 60; time = Math.floor(time / 60); | ||||
| 	out.H = time; | ||||
| 	out.q = dow; | ||||
| 	return out; | ||||
| } | ||||
| SSF.parse_date_code = parse_date_code; | ||||
| function fix_hijri() { return 0; } | ||||
| /*jshint -W086 */ | ||||
| function write_date(type, fmt, val, ss0) { | ||||
| 	var o="", ss=0, tt=0, y = val.y, out, outl = 0; | ||||
| @ -327,22 +327,16 @@ function write_date(type, fmt, val, ss0) { | ||||
| 			default: throw 'bad minute format: ' + fmt; | ||||
| 		} break; | ||||
| 		case 115: /* 's' seconds */ | ||||
| 		if(val.u === 0) switch(fmt) { | ||||
| 			case 's': case 'ss': return pad0(val.S, fmt.length); | ||||
| 			case '.0': case '.00': case '.000': | ||||
| 		} | ||||
| 		switch(fmt) { | ||||
| 			case 's': case 'ss': case '.0': case '.00': case '.000': | ||||
| 			if(fmt != 's' && fmt != 'ss' && fmt != '.0' && fmt != '.00' && fmt != '.000') throw 'bad second format: ' + fmt; | ||||
| 			if(val.u === 0 && (fmt == "s" || fmt == "ss")) return pad0(val.S, fmt.length); | ||||
| if(ss0 >= 2) tt = ss0 === 3 ? 1000 : 100; | ||||
| 				else tt = ss0 === 1 ? 10 : 1; | ||||
| 				ss = Math.round((tt)*(val.S + val.u)); | ||||
| 				if(ss >= 60*tt) ss = 0; | ||||
| 				if(fmt === 's') return ss === 0 ? "0" : ""+ss/tt; | ||||
| 				o = pad0(ss,2 + ss0); | ||||
| 				if(fmt === 'ss') return o.substr(0,2); | ||||
| 				return "." + o.substr(2,fmt.length-1); | ||||
| 			default: throw 'bad second format: ' + fmt; | ||||
| 		} | ||||
| 			else tt = ss0 === 1 ? 10 : 1; | ||||
| 			ss = Math.round((tt)*(val.S + val.u)); | ||||
| 			if(ss >= 60*tt) ss = 0; | ||||
| 			if(fmt === 's') return ss === 0 ? "0" : ""+ss/tt; | ||||
| 			o = pad0(ss,2 + ss0); | ||||
| 			if(fmt === 'ss') return o.substr(0,2); | ||||
| 			return "." + o.substr(2,fmt.length-1); | ||||
| 		case 90: /* 'Z' absolute time */ | ||||
| 		switch(fmt) { | ||||
| 			case '[h]': case '[hh]': out = val.D*24+val.H; break; | ||||
| @ -357,9 +351,10 @@ if(ss0 >= 2) tt = ss0 === 3 ? 1000 : 100; | ||||
| } | ||||
| /*jshint +W086 */ | ||||
| function commaify(s) { | ||||
| 	if(s.length <= 3) return s; | ||||
| 	var j = (s.length % 3), o = s.substr(0,j); | ||||
| 	for(; j!=s.length; j+=3) o+=(o.length > 0 ? "," : "") + s.substr(j,3); | ||||
| 	var w = 3; | ||||
| 	if(s.length <= w) return s; | ||||
| 	var j = (s.length % w), o = s.substr(0,j); | ||||
| 	for(; j!=s.length; j+=w) o+=(o.length > 0 ? "," : "") + s.substr(j,w); | ||||
| 	return o; | ||||
| } | ||||
| var write_num = (function make_write_num(){ | ||||
| @ -698,7 +693,7 @@ function fmt_is_date(fmt) { | ||||
| } | ||||
| SSF.is_date = fmt_is_date; | ||||
| function eval_fmt(fmt, v, opts, flen) { | ||||
| 	var out = [], o = "", i = 0, c = "", lst='t', q, dt, j, cc; | ||||
| 	var out = [], o = "", i = 0, c = "", lst='t', dt, j, cc; | ||||
| 	var hr='H'; | ||||
| 	/* Tokenize */ | ||||
| 	while(i < fmt.length) { | ||||
| @ -726,12 +721,12 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 			case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g': | ||||
| 				if(v < 0) return ""; | ||||
| 				if(dt==null) { dt=parse_date_code(v, opts); if(dt==null) return ""; } | ||||
| 				o = c; while(++i<fmt.length && fmt.charAt(i).toLowerCase() === c) o+=c; | ||||
| 				o = c; while(++i < fmt.length && fmt.charAt(i).toLowerCase() === c) o+=c; | ||||
| 				if(c === 'm' && lst.toLowerCase() === 'h') c = 'M'; | ||||
| 				if(c === 'h') c = hr; | ||||
| 				out[out.length] = {t:c, v:o}; lst = c; break; | ||||
| 			case 'A': case 'a': | ||||
| 				q={t:c, v:c}; | ||||
| 				var q={t:c, v:c}; | ||||
| 				if(dt==null) dt=parse_date_code(v, opts); | ||||
| 				if(fmt.substr(i, 3).toUpperCase() === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;} | ||||
| 				else if(fmt.substr(i,5).toUpperCase() === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; } | ||||
| @ -754,7 +749,7 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 			/* Numbers */ | ||||
| 			case '.': | ||||
| 				if(dt != null) { | ||||
| 					o = c; while((c=fmt.charAt(++i)) === "0") o += c; | ||||
| 					o = c; while(++i < fmt.length && (c=fmt.charAt(i)) === "0") o += c; | ||||
| 					out[out.length] = {t:'s', v:o}; break; | ||||
| 				} | ||||
| 				/* falls through */ | ||||
| @ -763,7 +758,7 @@ function eval_fmt(fmt, v, opts, flen) { | ||||
| 				out[out.length] = {t:'n', v:o}; break; | ||||
| 			case '?': | ||||
| 				o = c; while(fmt.charAt(++i) === c) o+=c; | ||||
| 				q={t:c, v:o}; out[out.length] = q; lst = c; break; | ||||
| 				out[out.length] = {t:c, v:o}; lst = c; break; | ||||
| 			case '*': ++i; if(fmt.charAt(i) == ' ' || fmt.charAt(i) == '*') ++i; break; // **
 | ||||
| 			case '(': case ')': out[out.length] = {t:(flen===1?'t':c), v:c}; ++i; break; | ||||
| 			case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': | ||||
| @ -946,18 +941,34 @@ function format(fmt,v,o) { | ||||
| 			break; | ||||
| 	} | ||||
| 	if(isgeneral(sfmt,0)) return general_fmt(v, o); | ||||
| 	if(v instanceof Date) v = datenum_local(v, o.date1904); | ||||
| 	var f = choose_fmt(sfmt, v); | ||||
| 	if(isgeneral(f[1])) return general_fmt(v, o); | ||||
| 	if(v === true) v = "TRUE"; else if(v === false) v = "FALSE"; | ||||
| 	else if(v === "" || v == null) return ""; | ||||
| 	return eval_fmt(f[1], v, o, f[0]); | ||||
| } | ||||
| function load_entry(fmt, idx) { | ||||
| 	if(typeof idx != 'number') { | ||||
| 		idx = +idx || -1; | ||||
| for(var i = 0; i < 0x0188; ++i) { | ||||
| if(table_fmt[i] == undefined) { if(idx < 0) idx = i; continue; } | ||||
| 			if(table_fmt[i] == fmt) { idx = i; break; } | ||||
| 		} | ||||
| if(idx < 0) idx = 0x187; | ||||
| 	} | ||||
| table_fmt[idx] = fmt; | ||||
| 	return idx; | ||||
| } | ||||
| SSF.load = load_entry; | ||||
| SSF._table = table_fmt; | ||||
| SSF.load = function load_entry(fmt, idx) { table_fmt[idx] = fmt; }; | ||||
| SSF.format = format; | ||||
| SSF.get_table = function get_table() { return table_fmt; }; | ||||
| SSF.load_table = function load_table(tbl) { for(var i=0; i!=0x0188; ++i) if(tbl[i] !== undefined) SSF.load(tbl[i], i); }; | ||||
| SSF.load_table = function load_table(tbl) { | ||||
| 	for(var i=0; i!=0x0188; ++i) | ||||
| 		if(tbl[i] !== undefined) load_entry(tbl[i], i); | ||||
| }; | ||||
| SSF.init_table = init_table; | ||||
| SSF.format = format; | ||||
| }; | ||||
| make_ssf(SSF); | ||||
| /* map from xlml named formats to SSF TODO: localize */ | ||||
| @ -1015,8 +1026,8 @@ var DO_NOT_EXPORT_CFB = true; | ||||
| /* [MS-CFB] v20130118 */ | ||||
| var CFB = (function _CFB(){ | ||||
| var exports = {}; | ||||
| exports.version = '0.11.1'; | ||||
| function parse(file) { | ||||
| exports.version = '0.12.0'; | ||||
| function parse(file, options) { | ||||
| var mver = 3; // major version
 | ||||
| var ssz = 512; // sector size
 | ||||
| var nmfs = 0; // number of mini FAT sectors
 | ||||
| @ -1076,7 +1087,7 @@ difat_start = blob.read_shift(4, 'i'); | ||||
| ndfs = blob.read_shift(4, 'i'); | ||||
| 
 | ||||
| // Grab FAT Sector Locations
 | ||||
| for(var q, j = 0; j < 109; ++j) { /* 109 = (512 - blob.l)>>>2; */ | ||||
| for(var q = -1, j = 0; j < 109; ++j) { /* 109 = (512 - blob.l)>>>2; */ | ||||
| 	q = blob.read_shift(4, 'i'); | ||||
| 	if(q<0) break; | ||||
| 	fat_addrs[j] = q; | ||||
| @ -1103,7 +1114,6 @@ read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex); | ||||
| build_full_paths(FileIndex, FullPathDir, FullPaths, Paths); | ||||
| 
 | ||||
| var root_name = Paths.shift(); | ||||
| Paths.root = root_name; | ||||
| 
 | ||||
| /* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */ | ||||
| var find_path = make_find_path(FullPaths, Paths, FileIndex, files, root_name); | ||||
| @ -1154,7 +1164,7 @@ function check_shifts(blob, mver) { | ||||
| /** Break the file up into sectors */ | ||||
| function sectorify(file, ssz) { | ||||
| 	var nsectors = Math.ceil(file.length/ssz)-1; | ||||
| 	var sectors = new Array(nsectors); | ||||
| 	var sectors = []; | ||||
| 	for(var i=1; i < nsectors; ++i) sectors[i-1] = file.slice(i*ssz,(i+1)*ssz); | ||||
| 	sectors[nsectors-1] = file.slice(nsectors*ssz); | ||||
| 	return sectors; | ||||
| @ -1163,7 +1173,7 @@ function sectorify(file, ssz) { | ||||
| /* [MS-CFB] 2.6.4 Red-Black Tree */ | ||||
| function build_full_paths(FI, FPD, FP, Paths) { | ||||
| 	var i = 0, L = 0, R = 0, C = 0, j = 0, pl = Paths.length; | ||||
| 	var dad = new Array(pl), q = new Array(pl); | ||||
| 	var dad = [], q = []; | ||||
| 
 | ||||
| 	for(; i < pl; ++i) { dad[i]=q[i]=i; FP[i]=Paths[i]; } | ||||
| 
 | ||||
| @ -1203,12 +1213,12 @@ function build_full_paths(FI, FPD, FP, Paths) { | ||||
| 
 | ||||
| /* [MS-CFB] 2.6.4 */ | ||||
| function make_find_path(FullPaths, Paths, FileIndex, files, root_name) { | ||||
| 	var UCFullPaths = new Array(FullPaths.length); | ||||
| 	var UCPaths = new Array(Paths.length), i; | ||||
| 	var UCFullPaths = []; | ||||
| 	var UCPaths = [], i = 0; | ||||
| 	for(i = 0; i < FullPaths.length; ++i) UCFullPaths[i] = FullPaths[i].toUpperCase().replace(chr0,'').replace(chr1,'!'); | ||||
| 	for(i = 0; i < Paths.length; ++i) UCPaths[i] = Paths[i].toUpperCase().replace(chr0,'').replace(chr1,'!'); | ||||
| 	return function find_path(path) { | ||||
| 		var k; | ||||
| 		var k = false; | ||||
| 		if(path.charCodeAt(0) === 47 /* "/" */) { k=true; path = root_name + path; } | ||||
| 		else k = path.indexOf("/") !== -1; | ||||
| 		var UCPath = path.toUpperCase().replace(chr0,'').replace(chr1,'!'); | ||||
| @ -1221,7 +1231,7 @@ function make_find_path(FullPaths, Paths, FileIndex, files, root_name) { | ||||
| /** Chase down the rest of the DIFAT chain to build a comprehensive list | ||||
|     DIFAT chains by storing the next sector number as the last 32 bytes */ | ||||
| function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) { | ||||
| 	var q; | ||||
| 	var q = ENDOFCHAIN; | ||||
| 	if(idx === ENDOFCHAIN) { | ||||
| 		if(cnt !== 0) throw new Error("DIFAT chain shorter than expected"); | ||||
| 	} else if(idx !== -1 /*FREESECT*/) { | ||||
| @ -1238,11 +1248,9 @@ function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) { | ||||
| /** Follow the linked list of sectors for a given starting point */ | ||||
| function get_sector_list(sectors, start, fat_addrs, ssz, chkd) { | ||||
| 	var sl = sectors.length; | ||||
| 	var buf, buf_chain; | ||||
| 	if(!chkd) chkd = new Array(sl); | ||||
| 	var modulus = ssz - 1, j, jj; | ||||
| 	buf = []; | ||||
| 	buf_chain = []; | ||||
| 	var buf = [], buf_chain = []; | ||||
| 	if(!chkd) chkd = []; | ||||
| 	var modulus = ssz - 1, j = 0, jj = 0; | ||||
| 	for(j=start; j>=0;) { | ||||
| 		chkd[j] = true; | ||||
| 		buf[buf.length] = j; | ||||
| @ -1258,13 +1266,13 @@ function get_sector_list(sectors, start, fat_addrs, ssz, chkd) { | ||||
| 
 | ||||
| /** Chase down the sector linked lists */ | ||||
| function make_sector_list(sectors, dir_start, fat_addrs, ssz) { | ||||
| 	var sl = sectors.length, sector_list = new Array(sl); | ||||
| 	var chkd = new Array(sl), buf, buf_chain; | ||||
| 	var modulus = ssz - 1, i, j, k, jj; | ||||
| 	var sl = sectors.length, sector_list = ([]); | ||||
| 	var chkd = [], buf = [], buf_chain = []; | ||||
| 	var modulus = ssz - 1, i=0, j=0, k=0, jj=0; | ||||
| 	for(i=0; i < sl; ++i) { | ||||
| 		buf = []; | ||||
| 		buf = ([]); | ||||
| 		k = (i + dir_start); if(k >= sl) k-=sl; | ||||
| 		if(chkd[k] === true) continue; | ||||
| 		if(chkd[k]) continue; | ||||
| 		buf_chain = []; | ||||
| 		for(j=k; j>=0;) { | ||||
| 			chkd[j] = true; | ||||
| @ -1276,25 +1284,24 @@ function make_sector_list(sectors, dir_start, fat_addrs, ssz) { | ||||
| 			if(!sectors[addr]) break; | ||||
| 			j = __readInt32LE(sectors[addr], jj); | ||||
| 		} | ||||
| 		sector_list[k] = {nodes: buf, data:__toBuffer([buf_chain])}; | ||||
| 		sector_list[k] = ({nodes: buf, data:__toBuffer([buf_chain])}); | ||||
| 	} | ||||
| 	return sector_list; | ||||
| } | ||||
| 
 | ||||
| /* [MS-CFB] 2.6.1 Compound File Directory Entry */ | ||||
| function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex) { | ||||
| 	var blob; | ||||
| 	var minifat_store = 0, pl = (Paths.length?2:0); | ||||
| 	var sector = sector_list[dir_start].data; | ||||
| 	var i = 0, namelen = 0, name, o, ctime, mtime; | ||||
| 	var i = 0, namelen = 0, name; | ||||
| 	for(; i < sector.length; i+= 128) { | ||||
| 		blob = sector.slice(i, i+128); | ||||
| 		var blob = sector.slice(i, i+128); | ||||
| 		prep_blob(blob, 64); | ||||
| 		namelen = blob.read_shift(2); | ||||
| 		if(namelen === 0) continue; | ||||
| 		name = __utf16le(blob,0,namelen-pl); | ||||
| 		Paths.push(name); | ||||
| 		o = ({ | ||||
| 		var o = ({ | ||||
| 			name:  name, | ||||
| 			type:  blob.read_shift(1), | ||||
| 			color: blob.read_shift(1), | ||||
| @ -1302,16 +1309,14 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil | ||||
| 			R:     blob.read_shift(4, 'i'), | ||||
| 			C:     blob.read_shift(4, 'i'), | ||||
| 			clsid: blob.read_shift(16), | ||||
| 			state: blob.read_shift(4, 'i') | ||||
| 			state: blob.read_shift(4, 'i'), | ||||
| 			start: 0, | ||||
| 			size: 0 | ||||
| 		}); | ||||
| 		ctime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2); | ||||
| 		if(ctime !== 0) { | ||||
| 			o.ctime = ctime; o.ct = read_date(blob, blob.l-8); | ||||
| 		} | ||||
| 		mtime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2); | ||||
| 		if(mtime !== 0) { | ||||
| 			o.mtime = mtime; o.mt = read_date(blob, blob.l-8); | ||||
| 		} | ||||
| 		var ctime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2); | ||||
| 		if(ctime !== 0) o.ct = read_date(blob, blob.l-8); | ||||
| 		var mtime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2); | ||||
| 		if(mtime !== 0) o.mt = read_date(blob, blob.l-8); | ||||
| 		o.start = blob.read_shift(4, 'i'); | ||||
| 		o.size = blob.read_shift(4, 'i'); | ||||
| 		if(o.type === 5) { /* root */ | ||||
| @ -1322,12 +1327,12 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil | ||||
| 			o.storage = 'fat'; | ||||
| 			if(sector_list[o.start] === undefined) sector_list[o.start] = get_sector_list(sectors, o.start, sector_list.fat_addrs, sector_list.ssz); | ||||
| 			sector_list[o.start].name = o.name; | ||||
| 			o.content = sector_list[o.start].data.slice(0,o.size); | ||||
| 			o.content = (sector_list[o.start].data.slice(0,o.size)); | ||||
| 			prep_blob(o.content, 0); | ||||
| 		} else { | ||||
| 			o.storage = 'minifat'; | ||||
| 			if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN) { | ||||
| 				o.content = sector_list[minifat_store].data.slice(o.start*MSSZ,o.start*MSSZ+o.size); | ||||
| 				o.content = (sector_list[minifat_store].data.slice(o.start*MSSZ,o.start*MSSZ+o.size)); | ||||
| 				prep_blob(o.content, 0); | ||||
| 			} | ||||
| 		} | ||||
| @ -1342,17 +1347,17 @@ function read_date(blob, offset) { | ||||
| 
 | ||||
| var fs; | ||||
| function readFileSync(filename, options) { | ||||
| 	if(fs === undefined) fs = require('fs'); | ||||
| 	if(fs == null) fs = require('fs'); | ||||
| 	return parse(fs.readFileSync(filename), options); | ||||
| } | ||||
| 
 | ||||
| function readSync(blob, options) { | ||||
| 	switch(options !== undefined && options.type !== undefined ? options.type : "base64") { | ||||
| 	switch(options && options.type || "base64") { | ||||
| 		case "file": return readFileSync(blob, options); | ||||
| 		case "base64": return parse(s2a(Base64.decode(blob)), options); | ||||
| 		case "binary": return parse(s2a(blob), options); | ||||
| 	} | ||||
| 	return parse(blob); | ||||
| 	return parse(blob, options); | ||||
| } | ||||
| 
 | ||||
| /** CFB Constants */ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user