| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | /* [MS-OLEDS] 2.3.8 CompObjStream */ | 
					
						
							| 
									
										
										
										
											2017-09-30 06:18:11 +00:00
										 |  |  | function parse_compobj(obj/*:CFBEntry*/) { | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	var v = {}; | 
					
						
							|  |  |  | 	var o = obj.content; | 
					
						
							| 
									
										
										
										
											2017-09-30 06:18:11 +00:00
										 |  |  | 	/*:: if(o == null) return; */ | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* [MS-OLEDS] 2.3.7 CompObjHeader -- All fields MUST be ignored */ | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	o.l = 28; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	v.AnsiUserType = o.read_shift(0, "lpstr-ansi"); | 
					
						
							|  |  |  | 	v.AnsiClipboardFormat = parse_ClipboardFormatOrAnsiString(o); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(o.length - o.l <= 4) return v; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var m/*:number*/ = o.read_shift(4); | 
					
						
							|  |  |  | 	if(m == 0 || m > 40) return v; | 
					
						
							|  |  |  | 	o.l-=4; v.Reserved1 = o.read_shift(0, "lpstr-ansi"); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	if(o.length - o.l <= 4) return v; | 
					
						
							|  |  |  | 	m = o.read_shift(4); | 
					
						
							|  |  |  | 	if(m !== 0x71b239f4) return v; | 
					
						
							|  |  |  | 	v.UnicodeClipboardFormat = parse_ClipboardFormatOrUnicodeString(o); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	m = o.read_shift(4); | 
					
						
							|  |  |  | 	if(m == 0 || m > 40) return v; | 
					
						
							|  |  |  | 	o.l-=4; v.Reserved2 = o.read_shift(0, "lpwstr"); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-26 08:35:28 +00:00
										 |  |  | /* | 
					
						
							|  |  |  | 	Continue logic for: | 
					
						
							|  |  |  | 	- 2.4.58 Continue | 
					
						
							|  |  |  | 	- 2.4.59 ContinueBigName | 
					
						
							|  |  |  | 	- 2.4.60 ContinueFrt | 
					
						
							|  |  |  | 	- 2.4.61 ContinueFrt11 | 
					
						
							|  |  |  | 	- 2.4.62 ContinueFrt12 | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | function slurp(R, blob, length/*:number*/, opts)/*:any*/ { | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	var l = length; | 
					
						
							|  |  |  | 	var bufs = []; | 
					
						
							|  |  |  | 	var d = blob.slice(blob.l,blob.l+l); | 
					
						
							| 
									
										
										
										
											2021-05-13 19:02:31 +00:00
										 |  |  | 	if(opts && opts.enc && opts.enc.insitu && d.length > 0) switch(R.n) { | 
					
						
							|  |  |  | 	case 'BOF': case 'FilePass': case 'FileLock': case 'InterfaceHdr': case 'RRDInfo': case 'RRDHead': case 'UsrExcl': case 'EOF': | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 'BoundSheet8': | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	default: | 
					
						
							| 
									
										
										
										
											2017-10-17 00:14:32 +00:00
										 |  |  | 		opts.enc.insitu(d); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	bufs.push(d); | 
					
						
							|  |  |  | 	blob.l += l; | 
					
						
							|  |  |  | 	var next = (XLSRecordEnum[__readUInt16LE(blob,blob.l)]); | 
					
						
							| 
									
										
										
										
											2017-07-26 08:35:28 +00:00
										 |  |  | 	var start = 0; | 
					
						
							|  |  |  | 	while(next != null && next.n.slice(0,8) === 'Continue') { | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 		l = __readUInt16LE(blob,blob.l+2); | 
					
						
							| 
									
										
										
										
											2017-07-26 08:35:28 +00:00
										 |  |  | 		start = blob.l + 4; | 
					
						
							|  |  |  | 		if(next.n == 'ContinueFrt') start += 4; | 
					
						
							| 
									
										
										
										
											2021-05-13 19:02:31 +00:00
										 |  |  | 		else if(next.n.slice(0,11) == 'ContinueFrt') { | 
					
						
							|  |  |  | 			start += 12; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		d = blob.slice(start,blob.l+4+l); | 
					
						
							|  |  |  | 		bufs.push(d); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 		blob.l += 4+l; | 
					
						
							|  |  |  | 		next = (XLSRecordEnum[__readUInt16LE(blob, blob.l)]); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 	var b = (bconcat(bufs)/*:any*/); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	prep_blob(b, 0); | 
					
						
							|  |  |  | 	var ll = 0; b.lens = []; | 
					
						
							|  |  |  | 	for(var j = 0; j < bufs.length; ++j) { b.lens.push(ll); ll += bufs[j].length; } | 
					
						
							| 
									
										
										
										
											2021-05-13 19:02:31 +00:00
										 |  |  | 	if(b.length < length) throw "XLS Record " + (R && R.n || "??") + " Truncated: " + b.length + " < " + length; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	return R.f(b, b.length, opts); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-12 18:02:43 +00:00
										 |  |  | function safe_format_xf(p/*:any*/, opts/*:ParseOpts*/, date1904/*:?boolean*/) { | 
					
						
							| 
									
										
										
										
											2017-03-15 08:19:02 +00:00
										 |  |  | 	if(p.t === 'z') return; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	if(!p.XF) return; | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 	var fmtid = 0; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	try { | 
					
						
							| 
									
										
										
										
											2017-07-27 20:07:51 +00:00
										 |  |  | 		fmtid = p.z || p.XF.numFmtId || 0; | 
					
						
							| 
									
										
										
										
											2017-04-21 22:02:02 +00:00
										 |  |  | 		if(opts.cellNF) p.z = SSF._table[fmtid]; | 
					
						
							| 
									
										
										
										
											2017-04-26 02:27:12 +00:00
										 |  |  | 	} catch(e) { if(opts.WTF) throw e; } | 
					
						
							|  |  |  | 	if(!opts || opts.cellText !== false) try { | 
					
						
							|  |  |  | 		if(p.t === 'e') { p.w = p.w || BErr[p.v]; } | 
					
						
							| 
									
										
										
										
											2017-07-27 20:07:51 +00:00
										 |  |  | 		else if(fmtid === 0 || fmtid == "General") { | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 			if(p.t === 'n') { | 
					
						
							|  |  |  | 				if((p.v|0) === p.v) p.w = SSF._general_int(p.v); | 
					
						
							|  |  |  | 				else p.w = SSF._general_num(p.v); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else p.w = SSF._general(p.v); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-09-20 06:38:41 +00:00
										 |  |  | 		else p.w = SSF.format(fmtid,p.v, {date1904:!!date1904, dateNF: opts && opts.dateNF}); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	} catch(e) { if(opts.WTF) throw e; } | 
					
						
							| 
									
										
										
										
											2017-10-18 03:05:05 +00:00
										 |  |  | 	if(opts.cellDates && fmtid && p.t == 'n' && SSF.is_date(SSF._table[fmtid] || String(fmtid))) { | 
					
						
							|  |  |  | 		var _d = SSF.parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); } | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | function make_cell(val, ixfe, t)/*:Cell*/ { | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 	return ({v:val, ixfe:ixfe, t:t}/*:any*/); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 2.3.2
 | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | 
					
						
							|  |  |  | 	var wb = ({opts:{}}/*:any*/); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	var Sheets = {}; | 
					
						
							| 
									
										
										
										
											2017-04-09 04:03:19 +00:00
										 |  |  | 	if(DENSE != null && options.dense == null) options.dense = DENSE; | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 	var out/*:Worksheet*/ = ((options.dense ? [] : {})/*:any*/); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	var Directory = {}; | 
					
						
							| 
									
										
										
										
											2017-03-25 01:36:40 +00:00
										 |  |  | 	var range/*:Range*/ = ({}/*:any*/); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	var last_formula = null; | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	var sst/*:SST*/ = ([]/*:any*/); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	var cur_sheet = ""; | 
					
						
							|  |  |  | 	var Preamble = {}; | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	var lastcell, last_cell = "", cc/*:Cell*/, cmnt, rngC, rngR; | 
					
						
							| 
									
										
										
										
											2018-01-09 07:36:02 +00:00
										 |  |  | 	var sharedf = {}; | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	var arrayf/*:Array<[Range, string]>*/ = []; | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 	var temp_val/*:Cell*/; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	var country; | 
					
						
							|  |  |  | 	var XFs = []; /* XF records */ | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	var palette/*:Array<[number, number, number]>*/ = []; | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	var Workbook/*:WBWBProps*/ = ({ Sheets:[], WBProps:{date1904:false}, Views:[{}] }/*:any*/), wsprops = {}; | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 	var get_rgb = function getrgb(icv/*:number*/)/*:[number, number, number]*/ { | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 		if(icv < 8) return XLSIcv[icv]; | 
					
						
							|  |  |  | 		if(icv < 64) return palette[icv-8] || XLSIcv[icv]; | 
					
						
							|  |  |  | 		return XLSIcv[icv]; | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2017-03-20 09:02:25 +00:00
										 |  |  | 	var process_cell_style = function pcs(cell, line/*:any*/, options) { | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 		var xfd = line.XF.data; | 
					
						
							| 
									
										
										
										
											2017-03-20 09:02:25 +00:00
										 |  |  | 		if(!xfd || !xfd.patternType || !options || !options.cellStyles) return; | 
					
						
							| 
									
										
										
										
											2017-03-12 18:02:43 +00:00
										 |  |  | 		line.s = ({}/*:any*/); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 		line.s.patternType = xfd.patternType; | 
					
						
							|  |  |  | 		var t; | 
					
						
							|  |  |  | 		if((t = rgb2Hex(get_rgb(xfd.icvFore)))) { line.s.fgColor = {rgb:t}; } | 
					
						
							|  |  |  | 		if((t = rgb2Hex(get_rgb(xfd.icvBack)))) { line.s.bgColor = {rgb:t}; } | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2017-03-12 18:02:43 +00:00
										 |  |  | 	var addcell = function addcell(cell/*:any*/, line/*:any*/, options/*:any*/) { | 
					
						
							| 
									
										
										
										
											2017-03-20 09:02:25 +00:00
										 |  |  | 		if(file_depth > 1) return; | 
					
						
							| 
									
										
										
										
											2021-10-27 06:26:17 +00:00
										 |  |  | 		if(options.sheetRows && cell.r >= options.sheetRows) return; | 
					
						
							| 
									
										
										
										
											2017-03-20 09:02:25 +00:00
										 |  |  | 		if(options.cellStyles && line.XF && line.XF.data) process_cell_style(cell, line, options); | 
					
						
							| 
									
										
										
										
											2017-08-18 18:10:18 +00:00
										 |  |  | 		delete line.ixfe; delete line.XF; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 		lastcell = cell; | 
					
						
							|  |  |  | 		last_cell = encode_cell(cell); | 
					
						
							| 
									
										
										
										
											2018-11-13 20:25:51 +00:00
										 |  |  | 		if(!range || !range.s || !range.e) range = {s:{r:0,c:0},e:{r:0,c:0}}; | 
					
						
							|  |  |  | 		if(cell.r < range.s.r) range.s.r = cell.r; | 
					
						
							|  |  |  | 		if(cell.c < range.s.c) range.s.c = cell.c; | 
					
						
							|  |  |  | 		if(cell.r + 1 > range.e.r) range.e.r = cell.r + 1; | 
					
						
							|  |  |  | 		if(cell.c + 1 > range.e.c) range.e.c = cell.c + 1; | 
					
						
							| 
									
										
										
										
											2017-03-18 00:45:06 +00:00
										 |  |  | 		if(options.cellFormula && line.f) { | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 			for(var afi = 0; afi < arrayf.length; ++afi) { | 
					
						
							| 
									
										
										
										
											2018-01-09 07:36:02 +00:00
										 |  |  | 				if(arrayf[afi][0].s.c > cell.c || arrayf[afi][0].s.r > cell.r) continue; | 
					
						
							|  |  |  | 				if(arrayf[afi][0].e.c < cell.c || arrayf[afi][0].e.r < cell.r) continue; | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 				line.F = encode_range(arrayf[afi][0]); | 
					
						
							| 
									
										
										
										
											2018-01-09 07:36:02 +00:00
										 |  |  | 				if(arrayf[afi][0].s.c != cell.c || arrayf[afi][0].s.r != cell.r) delete line.f; | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 				if(line.f) line.f = "" + stringify_formula(arrayf[afi][1], range, cell, supbooks, opts); | 
					
						
							| 
									
										
										
										
											2017-03-18 00:45:06 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-04-06 06:39:48 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2017-04-08 06:55:35 +00:00
										 |  |  | 			if(options.dense) { | 
					
						
							|  |  |  | 				if(!out[cell.r]) out[cell.r] = []; | 
					
						
							|  |  |  | 				out[cell.r][cell.c] = line; | 
					
						
							|  |  |  | 			} else out[last_cell] = line; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 	var opts = ({ | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 		enc: false, // encrypted
 | 
					
						
							|  |  |  | 		sbcch: 0, // cch in the preceding SupBook
 | 
					
						
							|  |  |  | 		snames: [], // sheetnames
 | 
					
						
							| 
									
										
										
										
											2018-01-09 07:36:02 +00:00
										 |  |  | 		sharedf: sharedf, // shared formulae by address
 | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 		arrayf: arrayf, // array formulae array
 | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 		rrtabid: [], // RRTabId
 | 
					
						
							|  |  |  | 		lastuser: "", // Last User from WriteAccess
 | 
					
						
							|  |  |  | 		biff: 8, // BIFF version
 | 
					
						
							|  |  |  | 		codepage: 0, // CP from CodePage record
 | 
					
						
							|  |  |  | 		winlocked: 0, // fLockWn from WinProtect
 | 
					
						
							| 
									
										
										
										
											2017-03-20 09:02:25 +00:00
										 |  |  | 		cellStyles: !!options && !!options.cellStyles, | 
					
						
							| 
									
										
										
										
											2017-03-18 23:25:50 +00:00
										 |  |  | 		WTF: !!options && !!options.wtf | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 	}/*:any*/); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	if(options.password) opts.password = options.password; | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	var themes; | 
					
						
							|  |  |  | 	var merges/*:Array<Range>*/ = []; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	var objects = []; | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	var colinfo/*:Array<ColInfo>*/ = [], rowinfo/*:Array<RowInfo>*/ = []; | 
					
						
							| 
									
										
										
										
											2018-01-23 09:07:51 +00:00
										 |  |  | 	// eslint-disable-next-line no-unused-vars
 | 
					
						
							| 
									
										
										
										
											2017-03-20 09:02:25 +00:00
										 |  |  | 	var defwidth = 0, defheight = 0; // twips / MDW respectively
 | 
					
						
							|  |  |  | 	var seencol = false; | 
					
						
							| 
									
										
										
										
											2017-04-11 22:15:36 +00:00
										 |  |  | 	var supbooks = ([]/*:any*/); // 1-indexed, will hold extern names
 | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	supbooks.SheetNames = opts.snames; | 
					
						
							|  |  |  | 	supbooks.sharedf = opts.sharedf; | 
					
						
							|  |  |  | 	supbooks.arrayf = opts.arrayf; | 
					
						
							| 
									
										
										
										
											2017-04-11 22:15:36 +00:00
										 |  |  | 	supbooks.names = []; | 
					
						
							|  |  |  | 	supbooks.XTI = []; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	var last_Rn = ''; | 
					
						
							|  |  |  | 	var file_depth = 0; /* TODO: make a real stack */ | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	var BIFF2Fmt = 0, BIFF2FmtTable/*:Array<string>*/ = []; | 
					
						
							| 
									
										
										
										
											2017-04-10 05:10:54 +00:00
										 |  |  | 	var FilterDatabases = []; /* TODO: sort out supbooks and process elsewhere */ | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 	var last_lbl/*:?DefinedName*/; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* explicit override for some broken writers */ | 
					
						
							|  |  |  | 	opts.codepage = 1200; | 
					
						
							|  |  |  | 	set_cp(1200); | 
					
						
							| 
									
										
										
										
											2017-12-09 07:17:25 +00:00
										 |  |  | 	var seen_codepage = false; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	while(blob.l < blob.length - 1) { | 
					
						
							|  |  |  | 		var s = blob.l; | 
					
						
							|  |  |  | 		var RecordType = blob.read_shift(2); | 
					
						
							|  |  |  | 		if(RecordType === 0 && last_Rn === 'EOF') break; | 
					
						
							| 
									
										
										
										
											2018-01-23 09:07:51 +00:00
										 |  |  | 		var length = (blob.l === blob.length ? 0 : blob.read_shift(2)); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 		var R = XLSRecordEnum[RecordType]; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 		//console.log(RecordType.toString(16), RecordType, R, blob.l, length, blob.length);
 | 
					
						
							| 
									
										
										
										
											2017-03-05 00:56:31 +00:00
										 |  |  | 		//if(!R) console.log(blob.slice(blob.l, blob.l + length));
 | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 		if(R && R.f) { | 
					
						
							|  |  |  | 			if(options.bookSheets) { | 
					
						
							|  |  |  | 				if(last_Rn === 'BoundSheet8' && R.n !== 'BoundSheet8') break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			last_Rn = R.n; | 
					
						
							|  |  |  | 			if(R.r === 2 || R.r == 12) { | 
					
						
							|  |  |  | 				var rt = blob.read_shift(2); length -= 2; | 
					
						
							| 
									
										
										
										
											2018-02-21 07:01:34 +00:00
										 |  |  | 				if(!opts.enc && rt !== RecordType && (((rt&0xFF)<<8)|(rt>>8)) !== RecordType) throw new Error("rt mismatch: " + rt + "!=" + RecordType); | 
					
						
							| 
									
										
										
										
											2021-09-26 22:51:19 +00:00
										 |  |  | 				if(R.r == 12){ | 
					
						
							|  |  |  | 					blob.l += 10; length -= 10; | 
					
						
							|  |  |  | 				} // skip FRT
 | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			//console.error(R,blob.l,length,blob.length);
 | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 			var val/*:any*/ = ({}/*:any*/); | 
					
						
							|  |  |  | 			if(R.n === 'EOF') val = /*::(*/R.f(blob, length, opts)/*:: :any)*/; | 
					
						
							|  |  |  | 			else val = /*::(*/slurp(R, blob, length, opts)/*:: :any)*/; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 			var Rn = R.n; | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 			/*:: val = (val:any); */ | 
					
						
							| 
									
										
										
										
											2018-01-09 07:36:02 +00:00
										 |  |  | 			if(file_depth == 0 && Rn != 'BOF') continue; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 			/* nested switch statements to workaround V8 128 limit */ | 
					
						
							|  |  |  | 			switch(Rn) { | 
					
						
							|  |  |  | 				/* Workbook Options */ | 
					
						
							| 
									
										
										
										
											2017-06-01 21:22:11 +00:00
										 |  |  | 				case 'Date1904': | 
					
						
							|  |  |  | 					/*:: if(!Workbook.WBProps) Workbook.WBProps = {}; */ | 
					
						
							|  |  |  | 					wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				case 'WriteProtect': wb.opts.WriteProtect = true; break; | 
					
						
							|  |  |  | 				case 'FilePass': | 
					
						
							|  |  |  | 					if(!opts.enc) blob.l = 0; | 
					
						
							|  |  |  | 					opts.enc = val; | 
					
						
							|  |  |  | 					if(!options.password) throw new Error("File is password-protected"); | 
					
						
							| 
									
										
										
										
											2017-05-11 07:29:59 +00:00
										 |  |  | 					if(val.valid == null) throw new Error("Encryption scheme unsupported"); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 					if(!val.valid) throw new Error("Password is incorrect"); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				case 'WriteAccess': opts.lastuser = val; break; | 
					
						
							|  |  |  | 				case 'FileSharing': break; //TODO
 | 
					
						
							|  |  |  | 				case 'CodePage': | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 					var cpval = Number(val); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 					/* overrides based on test cases */ | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 					switch(cpval) { | 
					
						
							|  |  |  | 						case 0x5212: cpval =  1200; break; | 
					
						
							|  |  |  | 						case 0x8000: cpval = 10000; break; | 
					
						
							|  |  |  | 						case 0x8001: cpval =  1252; break; | 
					
						
							| 
									
										
										
										
											2017-08-18 18:10:18 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 					set_cp(opts.codepage = cpval); | 
					
						
							| 
									
										
										
										
											2017-12-09 07:17:25 +00:00
										 |  |  | 					seen_codepage = true; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 					break; | 
					
						
							|  |  |  | 				case 'RRTabId': opts.rrtabid = val; break; | 
					
						
							|  |  |  | 				case 'WinProtect': opts.winlocked = val; break; | 
					
						
							|  |  |  | 				case 'Template': break; // TODO
 | 
					
						
							|  |  |  | 				case 'BookBool': break; // TODO
 | 
					
						
							| 
									
										
										
										
											2017-05-11 07:29:59 +00:00
										 |  |  | 				case 'UsesELFs': break; | 
					
						
							| 
									
										
										
										
											2017-03-10 08:39:51 +00:00
										 |  |  | 				case 'MTRSettings': break; | 
					
						
							| 
									
										
										
										
											2018-01-09 07:36:02 +00:00
										 |  |  | 				case 'RefreshAll': | 
					
						
							|  |  |  | 				case 'CalcCount': | 
					
						
							|  |  |  | 				case 'CalcDelta': | 
					
						
							|  |  |  | 				case 'CalcIter': | 
					
						
							|  |  |  | 				case 'CalcMode': | 
					
						
							|  |  |  | 				case 'CalcPrecision': | 
					
						
							|  |  |  | 				case 'CalcSaveRecalc': | 
					
						
							|  |  |  | 					wb.opts[Rn] = val; break; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				case 'CalcRefMode': opts.CalcRefMode = val; break; // TODO: implement R1C1
 | 
					
						
							|  |  |  | 				case 'Uncalced': break; | 
					
						
							|  |  |  | 				case 'ForceFullCalculation': wb.opts.FullCalc = val; break; | 
					
						
							| 
									
										
										
										
											2017-11-20 01:51:14 +00:00
										 |  |  | 				case 'WsBool': | 
					
						
							|  |  |  | 					if(val.fDialog) out["!type"] = "dialog"; | 
					
						
							| 
									
										
										
										
											2021-09-22 06:45:08 +00:00
										 |  |  | 					if(!val.fBelow) (out["!outline"] || (out["!outline"] = {})).above = true; | 
					
						
							|  |  |  | 					if(!val.fRight) (out["!outline"] || (out["!outline"] = {})).left = true; | 
					
						
							| 
									
										
										
										
											2017-11-20 01:51:14 +00:00
										 |  |  | 					break; // TODO
 | 
					
						
							| 
									
										
										
										
											2019-04-01 14:25:15 +00:00
										 |  |  | 				case 'XF': | 
					
						
							|  |  |  | 					XFs.push(val); break; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				case 'ExtSST': break; // TODO
 | 
					
						
							|  |  |  | 				case 'BookExt': break; // TODO
 | 
					
						
							|  |  |  | 				case 'RichTextStream': break; | 
					
						
							|  |  |  | 				case 'BkHim': break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 22:15:36 +00:00
										 |  |  | 				case 'SupBook': | 
					
						
							|  |  |  | 					supbooks.push([val]); | 
					
						
							|  |  |  | 					supbooks[supbooks.length-1].XTI = []; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				case 'ExternName': | 
					
						
							|  |  |  | 					supbooks[supbooks.length-1].push(val); | 
					
						
							|  |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				case 'Index': break; // TODO
 | 
					
						
							| 
									
										
										
										
											2017-04-10 05:10:54 +00:00
										 |  |  | 				case 'Lbl': | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 					last_lbl = ({ | 
					
						
							| 
									
										
										
										
											2017-04-11 22:15:36 +00:00
										 |  |  | 						Name: val.Name, | 
					
						
							|  |  |  | 						Ref: stringify_formula(val.rgce,range,null,supbooks,opts) | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 					}/*:DefinedName*/); | 
					
						
							| 
									
										
										
										
											2017-04-11 22:15:36 +00:00
										 |  |  | 					if(val.itab > 0) last_lbl.Sheet = val.itab - 1; | 
					
						
							|  |  |  | 					supbooks.names.push(last_lbl); | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 					if(!supbooks[0]) { supbooks[0] = []; supbooks[0].XTI = []; } | 
					
						
							| 
									
										
										
										
											2017-04-11 22:15:36 +00:00
										 |  |  | 					supbooks[supbooks.length-1].push(val); | 
					
						
							| 
									
										
										
										
											2017-06-10 01:47:42 +00:00
										 |  |  | 					if(val.Name == "_xlnm._FilterDatabase" && val.itab > 0) | 
					
						
							| 
									
										
										
										
											2017-04-10 05:10:54 +00:00
										 |  |  | 						if(val.rgce && val.rgce[0] && val.rgce[0][0] && val.rgce[0][0][0] == 'PtgArea3d') | 
					
						
							|  |  |  | 							FilterDatabases[val.itab - 1] = { ref: encode_range(val.rgce[0][0][1][2]) }; | 
					
						
							|  |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2017-07-26 08:35:28 +00:00
										 |  |  | 				case 'ExternCount': opts.ExternCount = val; break; | 
					
						
							| 
									
										
										
										
											2017-04-11 22:15:36 +00:00
										 |  |  | 				case 'ExternSheet': | 
					
						
							|  |  |  | 					if(supbooks.length == 0) { supbooks[0] = []; supbooks[0].XTI = []; } | 
					
						
							|  |  |  | 					supbooks[supbooks.length - 1].XTI = supbooks[supbooks.length - 1].XTI.concat(val); supbooks.XTI = supbooks.XTI.concat(val); break; | 
					
						
							|  |  |  | 				case 'NameCmt': | 
					
						
							|  |  |  | 					/* TODO: search for correct name */ | 
					
						
							|  |  |  | 					if(opts.biff < 8) break; | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 					if(last_lbl != null) last_lbl.Comment = val[1]; | 
					
						
							| 
									
										
										
										
											2017-04-11 22:15:36 +00:00
										 |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				case 'Protect': out["!protect"] = val; break; /* for sheet or book */ | 
					
						
							|  |  |  | 				case 'Password': if(val !== 0 && opts.WTF) console.error("Password verifier: " + val); break; | 
					
						
							|  |  |  | 				case 'Prot4Rev': case 'Prot4RevPass': break; /*TODO: Revision Control*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				case 'BoundSheet8': { | 
					
						
							|  |  |  | 					Directory[val.pos] = val; | 
					
						
							|  |  |  | 					opts.snames.push(val.name); | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'EOF': { | 
					
						
							|  |  |  | 					if(--file_depth) break; | 
					
						
							|  |  |  | 					if(range.e) { | 
					
						
							|  |  |  | 						if(range.e.r > 0 && range.e.c > 0) { | 
					
						
							|  |  |  | 							range.e.r--; range.e.c--; | 
					
						
							|  |  |  | 							out["!ref"] = encode_range(range); | 
					
						
							| 
									
										
										
										
											2018-04-06 06:39:48 +00:00
										 |  |  | 							if(options.sheetRows && options.sheetRows <= range.e.r) { | 
					
						
							|  |  |  | 								var tmpri = range.e.r; | 
					
						
							|  |  |  | 								range.e.r = options.sheetRows - 1; | 
					
						
							|  |  |  | 								out["!fullref"] = out["!ref"]; | 
					
						
							|  |  |  | 								out["!ref"] = encode_range(range); | 
					
						
							|  |  |  | 								range.e.r = tmpri; | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 							range.e.r++; range.e.c++; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 						if(merges.length > 0) out["!merges"] = merges; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 						if(objects.length > 0) out["!objects"] = objects; | 
					
						
							| 
									
										
										
										
											2017-03-20 09:02:25 +00:00
										 |  |  | 						if(colinfo.length > 0) out["!cols"] = colinfo; | 
					
						
							|  |  |  | 						if(rowinfo.length > 0) out["!rows"] = rowinfo; | 
					
						
							| 
									
										
										
										
											2017-03-31 18:46:42 +00:00
										 |  |  | 						Workbook.Sheets.push(wsprops); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out; | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 					out = ((options.dense ? [] : {})/*:any*/); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'BOF': { | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 					if(opts.biff === 8) opts.biff = { | 
					
						
							|  |  |  | 						/*::[*/0x0009/*::]*/:2, | 
					
						
							|  |  |  | 						/*::[*/0x0209/*::]*/:3, | 
					
						
							|  |  |  | 						/*::[*/0x0409/*::]*/:4 | 
					
						
							|  |  |  | 					}[RecordType] || { | 
					
						
							| 
									
										
										
										
											2018-02-21 07:01:34 +00:00
										 |  |  | 						/*::[*/0x0200/*::]*/:2, | 
					
						
							|  |  |  | 						/*::[*/0x0300/*::]*/:3, | 
					
						
							|  |  |  | 						/*::[*/0x0400/*::]*/:4, | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 						/*::[*/0x0500/*::]*/:5, | 
					
						
							|  |  |  | 						/*::[*/0x0600/*::]*/:8, | 
					
						
							|  |  |  | 						/*::[*/0x0002/*::]*/:2, | 
					
						
							|  |  |  | 						/*::[*/0x0007/*::]*/:2 | 
					
						
							|  |  |  | 					}[val.BIFFVer] || 8; | 
					
						
							| 
									
										
										
										
											2021-09-26 22:51:19 +00:00
										 |  |  | 					opts.biffguess = val.BIFFVer == 0; | 
					
						
							|  |  |  | 					if(val.BIFFVer == 0 && val.dt == 0x1000) { opts.biff = 5; seen_codepage = true; set_cp(opts.codepage = 28591); } | 
					
						
							| 
									
										
										
										
											2018-08-15 19:22:47 +00:00
										 |  |  | 					if(opts.biff == 8 && val.BIFFVer == 0 && val.dt == 16) opts.biff = 2; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 					if(file_depth++) break; | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 					out = ((options.dense ? [] : {})/*:any*/); | 
					
						
							| 
									
										
										
										
											2017-03-31 18:46:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 07:17:25 +00:00
										 |  |  | 					if(opts.biff < 8 && !seen_codepage) { seen_codepage = true; set_cp(opts.codepage = options.codepage || 1252); } | 
					
						
							| 
									
										
										
										
											2021-09-26 22:51:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					if(opts.biff < 5 || val.BIFFVer == 0 && val.dt == 0x1000) { | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 						if(cur_sheet === "") cur_sheet = "Sheet1"; | 
					
						
							|  |  |  | 						range = {s:{r:0,c:0},e:{r:0,c:0}}; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 						/* fake BoundSheet8 */ | 
					
						
							|  |  |  | 						var fakebs8 = {pos: blob.l - length, name:cur_sheet}; | 
					
						
							|  |  |  | 						Directory[fakebs8.pos] = fakebs8; | 
					
						
							|  |  |  | 						opts.snames.push(cur_sheet); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					else cur_sheet = (Directory[s] || {name:""}).name; | 
					
						
							| 
									
										
										
										
											2017-03-27 21:35:15 +00:00
										 |  |  | 					if(val.dt == 0x20) out["!type"] = "chart"; | 
					
						
							| 
									
										
										
										
											2017-11-20 01:51:14 +00:00
										 |  |  | 					if(val.dt == 0x40) out["!type"] = "macro"; | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 					merges = []; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 					objects = []; | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 					opts.arrayf = arrayf = []; | 
					
						
							| 
									
										
										
										
											2017-03-20 09:02:25 +00:00
										 |  |  | 					colinfo = []; rowinfo = []; | 
					
						
							|  |  |  | 					defwidth = defheight = 0; | 
					
						
							|  |  |  | 					seencol = false; | 
					
						
							| 
									
										
										
										
											2017-03-31 18:46:42 +00:00
										 |  |  | 					wsprops = {Hidden:(Directory[s]||{hs:0}).hs, name:cur_sheet }; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				} break; | 
					
						
							| 
									
										
										
										
											2017-03-18 00:45:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 				case 'Number': case 'BIFF2NUM': case 'BIFF2INT': { | 
					
						
							| 
									
										
										
										
											2017-04-08 06:55:35 +00:00
										 |  |  | 					if(out["!type"] == "chart") if(options.dense ? (out[val.r]||[])[val.c]: out[encode_cell({c:val.c, r:val.r})]) ++val.c; | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 					temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe]||{}, v:val.val, t:'n'}/*:any*/); | 
					
						
							| 
									
										
										
										
											2021-09-26 22:51:19 +00:00
										 |  |  | 					if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F]; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 					safe_format_xf(temp_val, options, wb.opts.Date1904); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 					addcell({c:val.c, r:val.r}, temp_val, options); | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'BoolErr': { | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 					temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t}/*:any*/); | 
					
						
							| 
									
										
										
										
											2021-09-26 22:51:19 +00:00
										 |  |  | 					if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F]; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 					safe_format_xf(temp_val, options, wb.opts.Date1904); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 					addcell({c:val.c, r:val.r}, temp_val, options); | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'RK': { | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 					temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'}/*:any*/); | 
					
						
							| 
									
										
										
										
											2021-09-26 22:51:19 +00:00
										 |  |  | 					if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F]; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 					safe_format_xf(temp_val, options, wb.opts.Date1904); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 					addcell({c:val.c, r:val.r}, temp_val, options); | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'MulRk': { | 
					
						
							|  |  |  | 					for(var j = val.c; j <= val.C; ++j) { | 
					
						
							|  |  |  | 						var ixfe = val.rkrec[j-val.c][0]; | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 						temp_val= ({ixfe:ixfe, XF:XFs[ixfe], v:val.rkrec[j-val.c][1], t:'n'}/*:any*/); | 
					
						
							| 
									
										
										
										
											2021-09-26 22:51:19 +00:00
										 |  |  | 						if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F]; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 						safe_format_xf(temp_val, options, wb.opts.Date1904); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 						addcell({c:j, r:val.r}, temp_val, options); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'Formula': { | 
					
						
							| 
									
										
										
										
											2017-03-18 00:45:06 +00:00
										 |  |  | 					if(val.val == 'String') { last_formula = val; break; } | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 					temp_val = make_cell(val.val, val.cell.ixfe, val.tt); | 
					
						
							| 
									
										
										
										
											2017-03-18 00:45:06 +00:00
										 |  |  | 					temp_val.XF = XFs[temp_val.ixfe]; | 
					
						
							|  |  |  | 					if(options.cellFormula) { | 
					
						
							|  |  |  | 						var _f = val.formula; | 
					
						
							|  |  |  | 						if(_f && _f[0] && _f[0][0] && _f[0][0][0] == 'PtgExp') { | 
					
						
							|  |  |  | 							var _fr = _f[0][0][1][0], _fc = _f[0][0][1][1]; | 
					
						
							|  |  |  | 							var _fe = encode_cell({r:_fr, c:_fc}); | 
					
						
							| 
									
										
										
										
											2018-01-09 07:36:02 +00:00
										 |  |  | 							if(sharedf[_fe]) temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts); | 
					
						
							| 
									
										
										
										
											2017-04-08 06:55:35 +00:00
										 |  |  | 							else temp_val.F = ((options.dense ? (out[_fr]||[])[_fc]: out[_fe]) || {}).F; | 
					
						
							| 
									
										
										
										
											2017-03-18 00:45:06 +00:00
										 |  |  | 						} else temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2021-09-26 22:51:19 +00:00
										 |  |  | 					if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F]; | 
					
						
							| 
									
										
										
										
											2017-03-18 00:45:06 +00:00
										 |  |  | 					safe_format_xf(temp_val, options, wb.opts.Date1904); | 
					
						
							|  |  |  | 					addcell(val.cell, temp_val, options); | 
					
						
							|  |  |  | 					last_formula = val; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'String': { | 
					
						
							| 
									
										
										
										
											2017-03-18 00:45:06 +00:00
										 |  |  | 					if(last_formula) { /* technically always true */ | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 						last_formula.val = val; | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 						temp_val = make_cell(val, last_formula.cell.ixfe, 's'); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 						temp_val.XF = XFs[temp_val.ixfe]; | 
					
						
							| 
									
										
										
										
											2017-03-18 00:45:06 +00:00
										 |  |  | 						if(options.cellFormula) { | 
					
						
							|  |  |  | 							temp_val.f = ""+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2021-09-26 22:51:19 +00:00
										 |  |  | 						if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F]; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 						safe_format_xf(temp_val, options, wb.opts.Date1904); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 						addcell(last_formula.cell, temp_val, options); | 
					
						
							|  |  |  | 						last_formula = null; | 
					
						
							| 
									
										
										
										
											2017-03-18 00:45:06 +00:00
										 |  |  | 					} else throw new Error("String record expects Formula"); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'Array': { | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 					arrayf.push(val); | 
					
						
							| 
									
										
										
										
											2017-03-18 00:45:06 +00:00
										 |  |  | 					var _arraystart = encode_cell(val[0].s); | 
					
						
							| 
									
										
										
										
											2017-04-08 06:55:35 +00:00
										 |  |  | 					cc = options.dense ? (out[val[0].s.r]||[])[val[0].s.c] : out[_arraystart]; | 
					
						
							|  |  |  | 					if(options.cellFormula && cc) { | 
					
						
							| 
									
										
										
										
											2017-03-12 18:02:43 +00:00
										 |  |  | 						if(!last_formula) break; /* technically unreachable */ | 
					
						
							| 
									
										
										
										
											2017-04-08 06:55:35 +00:00
										 |  |  | 						if(!_arraystart || !cc) break; | 
					
						
							|  |  |  | 						cc.f = ""+stringify_formula(val[1], range, val[0], supbooks, opts); | 
					
						
							|  |  |  | 						cc.F = encode_range(val[0]); | 
					
						
							| 
									
										
										
										
											2017-02-19 20:36:32 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'ShrFmla': { | 
					
						
							| 
									
										
										
										
											2017-02-19 20:36:32 +00:00
										 |  |  | 					if(!options.cellFormula) break; | 
					
						
							|  |  |  | 					if(last_cell) { | 
					
						
							|  |  |  | 						/* TODO: capture range */ | 
					
						
							| 
									
										
										
										
											2017-03-12 18:02:43 +00:00
										 |  |  | 						if(!last_formula) break; /* technically unreachable */ | 
					
						
							| 
									
										
										
										
											2018-01-09 07:36:02 +00:00
										 |  |  | 						sharedf[encode_cell(last_formula.cell)]= val[0]; | 
					
						
							| 
									
										
										
										
											2017-04-08 06:55:35 +00:00
										 |  |  | 						cc = options.dense ? (out[last_formula.cell.r]||[])[last_formula.cell.c] : out[encode_cell(last_formula.cell)]; | 
					
						
							|  |  |  | 						(cc||{}).f = ""+stringify_formula(val[0], range, lastcell, supbooks, opts); | 
					
						
							| 
									
										
										
										
											2017-02-19 20:36:32 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'LabelSst': | 
					
						
							|  |  |  | 					temp_val=make_cell(sst[val.isst].t, val.ixfe, 's'); | 
					
						
							| 
									
										
										
										
											2019-11-15 01:46:49 +00:00
										 |  |  | 					if(sst[val.isst].h) temp_val.h = sst[val.isst].h; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 					temp_val.XF = XFs[temp_val.ixfe]; | 
					
						
							| 
									
										
										
										
											2021-09-26 22:51:19 +00:00
										 |  |  | 					if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F]; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 					safe_format_xf(temp_val, options, wb.opts.Date1904); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 					addcell({c:val.c, r:val.r}, temp_val, options); | 
					
						
							|  |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2017-03-15 08:19:02 +00:00
										 |  |  | 				case 'Blank': if(options.sheetStubs) { | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 					temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'}/*:any*/); | 
					
						
							| 
									
										
										
										
											2021-09-26 22:51:19 +00:00
										 |  |  | 					if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F]; | 
					
						
							| 
									
										
										
										
											2017-03-15 08:19:02 +00:00
										 |  |  | 					safe_format_xf(temp_val, options, wb.opts.Date1904); | 
					
						
							|  |  |  | 					addcell({c:val.c, r:val.r}, temp_val, options); | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'MulBlank': if(options.sheetStubs) { | 
					
						
							|  |  |  | 					for(var _j = val.c; _j <= val.C; ++_j) { | 
					
						
							|  |  |  | 						var _ixfe = val.ixfe[_j-val.c]; | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 						temp_val= ({ixfe:_ixfe, XF:XFs[_ixfe], t:'z'}/*:any*/); | 
					
						
							| 
									
										
										
										
											2021-09-26 22:51:19 +00:00
										 |  |  | 						if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F]; | 
					
						
							| 
									
										
										
										
											2017-03-15 08:19:02 +00:00
										 |  |  | 						safe_format_xf(temp_val, options, wb.opts.Date1904); | 
					
						
							|  |  |  | 						addcell({c:_j, r:val.r}, temp_val, options); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} break; | 
					
						
							| 
									
										
										
										
											2017-02-19 20:36:32 +00:00
										 |  |  | 				case 'RString': | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				case 'Label': case 'BIFF2STR': | 
					
						
							|  |  |  | 					temp_val=make_cell(val.val, val.ixfe, 's'); | 
					
						
							|  |  |  | 					temp_val.XF = XFs[temp_val.ixfe]; | 
					
						
							| 
									
										
										
										
											2021-09-26 22:51:19 +00:00
										 |  |  | 					if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F]; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 					safe_format_xf(temp_val, options, wb.opts.Date1904); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 					addcell({c:val.c, r:val.r}, temp_val, options); | 
					
						
							|  |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2017-03-18 00:45:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				case 'Dimensions': { | 
					
						
							|  |  |  | 					if(file_depth === 1) range = val; /* TODO: stack */ | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'SST': { | 
					
						
							|  |  |  | 					sst = val; | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'Format': { /* val = [id, fmt] */ | 
					
						
							| 
									
										
										
										
											2017-12-01 05:48:10 +00:00
										 |  |  | 					if(opts.biff == 4) { | 
					
						
							|  |  |  | 						BIFF2FmtTable[BIFF2Fmt++] = val[1]; | 
					
						
							|  |  |  | 						for(var b4idx = 0; b4idx < BIFF2Fmt + 163; ++b4idx) if(SSF._table[b4idx] == val[1]) break; | 
					
						
							|  |  |  | 						if(b4idx >= 163) SSF.load(val[1], BIFF2Fmt + 163); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else SSF.load(val[1], val[0]); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				} break; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 				case 'BIFF2FORMAT': { | 
					
						
							| 
									
										
										
										
											2017-05-09 18:07:57 +00:00
										 |  |  | 					BIFF2FmtTable[BIFF2Fmt++] = val; | 
					
						
							|  |  |  | 					for(var b2idx = 0; b2idx < BIFF2Fmt + 163; ++b2idx) if(SSF._table[b2idx] == val) break; | 
					
						
							|  |  |  | 					if(b2idx >= 163) SSF.load(val, BIFF2Fmt + 163); | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 				} break; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 				case 'MergeCells': merges = merges.concat(val); break; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				case 'Obj': objects[val.cmo[0]] = opts.lastobj = val; break; | 
					
						
							|  |  |  | 				case 'TxO': opts.lastobj.TxO = val; break; | 
					
						
							| 
									
										
										
										
											2017-05-09 18:07:57 +00:00
										 |  |  | 				case 'ImData': opts.lastobj.ImData = val; break; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				case 'HLink': { | 
					
						
							|  |  |  | 					for(rngR = val[0].s.r; rngR <= val[0].e.r; ++rngR) | 
					
						
							| 
									
										
										
										
											2017-04-08 06:55:35 +00:00
										 |  |  | 						for(rngC = val[0].s.c; rngC <= val[0].e.c; ++rngC) { | 
					
						
							|  |  |  | 							cc = options.dense ? (out[rngR]||[])[rngC] : out[encode_cell({c:rngC,r:rngR})]; | 
					
						
							|  |  |  | 							if(cc) cc.l = val[1]; | 
					
						
							| 
									
										
										
										
											2017-05-09 18:07:57 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'HLinkTooltip': { | 
					
						
							|  |  |  | 					for(rngR = val[0].s.r; rngR <= val[0].e.r; ++rngR) | 
					
						
							| 
									
										
										
										
											2017-04-08 06:55:35 +00:00
										 |  |  | 						for(rngC = val[0].s.c; rngC <= val[0].e.c; ++rngC) { | 
					
						
							|  |  |  | 							cc = options.dense ? (out[rngR]||[])[rngC] : out[encode_cell({c:rngC,r:rngR})]; | 
					
						
							| 
									
										
										
										
											2018-02-21 07:01:34 +00:00
										 |  |  | 							if(cc && cc.l) cc.l.Tooltip = val[1]; | 
					
						
							| 
									
										
										
										
											2017-04-08 06:55:35 +00:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Comments */ | 
					
						
							|  |  |  | 				case 'Note': { | 
					
						
							|  |  |  | 					if(opts.biff <= 5 && opts.biff >= 2) break; /* TODO: BIFF5 */ | 
					
						
							| 
									
										
										
										
											2017-04-08 06:55:35 +00:00
										 |  |  | 					cc = options.dense ? (out[val[0].r]||[])[val[0].c] : out[encode_cell(val[0])]; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 					var noteobj = objects[val[2]]; | 
					
						
							| 
									
										
										
										
											2019-08-03 22:37:04 +00:00
										 |  |  | 					if(!cc) { | 
					
						
							|  |  |  | 						if(options.dense) { | 
					
						
							|  |  |  | 							if(!out[val[0].r]) out[val[0].r] = []; | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 							cc = out[val[0].r][val[0].c] = ({t:"z"}/*:any*/); | 
					
						
							| 
									
										
										
										
											2019-08-03 22:37:04 +00:00
										 |  |  | 						} else { | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 							cc = out[encode_cell(val[0])] = ({t:"z"}/*:any*/); | 
					
						
							| 
									
										
										
										
											2019-08-03 22:37:04 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						range.e.r = Math.max(range.e.r, val[0].r); | 
					
						
							|  |  |  | 						range.s.r = Math.min(range.s.r, val[0].r); | 
					
						
							|  |  |  | 						range.e.c = Math.max(range.e.c, val[0].c); | 
					
						
							|  |  |  | 						range.s.c = Math.min(range.s.c, val[0].c); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 					if(!cc.c) cc.c = []; | 
					
						
							|  |  |  | 					cmnt = {a:val[1],t:noteobj.TxO.t}; | 
					
						
							|  |  |  | 					cc.c.push(cmnt); | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				default: switch(R.n) { /* nested */ | 
					
						
							|  |  |  | 				case 'ClrtClient': break; | 
					
						
							|  |  |  | 				case 'XFExt': update_xfext(XFs[val.ixfe], val.ext); break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-20 09:02:25 +00:00
										 |  |  | 				case 'DefColWidth': defwidth = val; break; | 
					
						
							|  |  |  | 				case 'DefaultRowHeight': defheight = val[1]; break; // TODO: flags
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				case 'ColInfo': { | 
					
						
							|  |  |  | 					if(!opts.cellStyles) break; | 
					
						
							|  |  |  | 					while(val.e >= val.s) { | 
					
						
							| 
									
										
										
										
											2021-09-20 06:38:41 +00:00
										 |  |  | 						colinfo[val.e--] = { width: val.w/256, level: (val.level || 0), hidden: !!(val.flags & 1) }; | 
					
						
							| 
									
										
										
										
											2017-03-20 09:02:25 +00:00
										 |  |  | 						if(!seencol) { seencol = true; find_mdw_colw(val.w/256); } | 
					
						
							|  |  |  | 						process_col(colinfo[val.e+1]); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} break; | 
					
						
							| 
									
										
										
										
											2017-04-28 07:28:03 +00:00
										 |  |  | 				case 'Row': { | 
					
						
							|  |  |  | 					var rowobj = {}; | 
					
						
							| 
									
										
										
										
											2017-07-09 17:37:45 +00:00
										 |  |  | 					if(val.level != null) { rowinfo[val.r] = rowobj; rowobj.level = val.level; } | 
					
						
							| 
									
										
										
										
											2017-04-28 07:28:03 +00:00
										 |  |  | 					if(val.hidden) { rowinfo[val.r] = rowobj; rowobj.hidden = true; } | 
					
						
							|  |  |  | 					if(val.hpt) { | 
					
						
							|  |  |  | 						rowinfo[val.r] = rowobj; | 
					
						
							|  |  |  | 						rowobj.hpt = val.hpt; rowobj.hpx = pt2px(val.hpt); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} break; | 
					
						
							| 
									
										
										
										
											2017-03-20 09:02:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-13 01:29:38 +00:00
										 |  |  | 				case 'LeftMargin': | 
					
						
							|  |  |  | 				case 'RightMargin': | 
					
						
							|  |  |  | 				case 'TopMargin': | 
					
						
							|  |  |  | 				case 'BottomMargin': | 
					
						
							|  |  |  | 					if(!out['!margins']) default_margins(out['!margins'] = {}); | 
					
						
							| 
									
										
										
										
											2017-05-13 18:21:22 +00:00
										 |  |  | 					out['!margins'][Rn.slice(0,-6).toLowerCase()] = val; | 
					
						
							| 
									
										
										
										
											2017-04-13 01:29:38 +00:00
										 |  |  | 					break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-16 23:40:52 +00:00
										 |  |  | 				case 'Selection': break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-13 01:29:38 +00:00
										 |  |  | 				case 'Setup': // TODO
 | 
					
						
							|  |  |  | 					if(!out['!margins']) default_margins(out['!margins'] = {}); | 
					
						
							|  |  |  | 					out['!margins'].header = val.header; | 
					
						
							|  |  |  | 					out['!margins'].footer = val.footer; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 				case 'Window2': // TODO
 | 
					
						
							|  |  |  | 					// $FlowIgnore
 | 
					
						
							|  |  |  | 					if(val.RTL) Workbook.Views[0].RTL = true; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				case 'Header': break; // TODO
 | 
					
						
							|  |  |  | 				case 'Footer': break; // TODO
 | 
					
						
							|  |  |  | 				case 'HCenter': break; // TODO
 | 
					
						
							|  |  |  | 				case 'VCenter': break; // TODO
 | 
					
						
							|  |  |  | 				case 'Pls': break; // TODO
 | 
					
						
							|  |  |  | 				case 'GCW': break; | 
					
						
							|  |  |  | 				case 'LHRecord': break; | 
					
						
							|  |  |  | 				case 'DBCell': break; // TODO
 | 
					
						
							|  |  |  | 				case 'EntExU2': break; // TODO
 | 
					
						
							|  |  |  | 				case 'SxView': break; // TODO
 | 
					
						
							|  |  |  | 				case 'Sxvd': break; // TODO
 | 
					
						
							|  |  |  | 				case 'SXVI': break; // TODO
 | 
					
						
							|  |  |  | 				case 'SXVDEx': break; // TODO
 | 
					
						
							|  |  |  | 				case 'SxIvd': break; // TODO
 | 
					
						
							| 
									
										
										
										
											2017-07-26 08:35:28 +00:00
										 |  |  | 				case 'SXString': break; // TODO
 | 
					
						
							|  |  |  | 				case 'Sync': break; | 
					
						
							|  |  |  | 				case 'Addin': break; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				case 'SXDI': break; // TODO
 | 
					
						
							|  |  |  | 				case 'SXLI': break; // TODO
 | 
					
						
							|  |  |  | 				case 'SXEx': break; // TODO
 | 
					
						
							|  |  |  | 				case 'QsiSXTag': break; // TODO
 | 
					
						
							|  |  |  | 				case 'Feat': break; | 
					
						
							|  |  |  | 				case 'FeatHdr': case 'FeatHdr11': break; | 
					
						
							|  |  |  | 				case 'Feature11': case 'Feature12': case 'List12': break; | 
					
						
							|  |  |  | 				case 'Country': country = val; break; | 
					
						
							|  |  |  | 				case 'RecalcId': break; | 
					
						
							| 
									
										
										
										
											2017-03-20 09:02:25 +00:00
										 |  |  | 				case 'DxGCol': break; // TODO: htmlify
 | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				case 'Fbi': case 'Fbi2': case 'GelFrame': break; | 
					
						
							|  |  |  | 				case 'Font': break; // TODO
 | 
					
						
							|  |  |  | 				case 'XFCRC': break; // TODO
 | 
					
						
							|  |  |  | 				case 'Style': break; // TODO
 | 
					
						
							|  |  |  | 				case 'StyleExt': break; // TODO
 | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 				case 'Palette': palette = val; break; | 
					
						
							|  |  |  | 				case 'Theme': themes = val; break; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				/* Protection */ | 
					
						
							|  |  |  | 				case 'ScenarioProtect': break; | 
					
						
							|  |  |  | 				case 'ObjProtect': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Conditional Formatting */ | 
					
						
							|  |  |  | 				case 'CondFmt12': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Table */ | 
					
						
							|  |  |  | 				case 'Table': break; // TODO
 | 
					
						
							|  |  |  | 				case 'TableStyles': break; // TODO
 | 
					
						
							|  |  |  | 				case 'TableStyle': break; // TODO
 | 
					
						
							|  |  |  | 				case 'TableStyleElement': break; // TODO
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* PivotTable */ | 
					
						
							|  |  |  | 				case 'SXStreamID': break; // TODO
 | 
					
						
							|  |  |  | 				case 'SXVS': break; // TODO
 | 
					
						
							|  |  |  | 				case 'DConRef': break; // TODO
 | 
					
						
							|  |  |  | 				case 'SXAddl': break; // TODO
 | 
					
						
							|  |  |  | 				case 'DConBin': break; // TODO
 | 
					
						
							|  |  |  | 				case 'DConName': break; // TODO
 | 
					
						
							|  |  |  | 				case 'SXPI': break; // TODO
 | 
					
						
							|  |  |  | 				case 'SxFormat': break; // TODO
 | 
					
						
							|  |  |  | 				case 'SxSelect': break; // TODO
 | 
					
						
							|  |  |  | 				case 'SxRule': break; // TODO
 | 
					
						
							|  |  |  | 				case 'SxFilt': break; // TODO
 | 
					
						
							|  |  |  | 				case 'SxItm': break; // TODO
 | 
					
						
							|  |  |  | 				case 'SxDXF': break; // TODO
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Scenario Manager */ | 
					
						
							|  |  |  | 				case 'ScenMan': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Data Consolidation */ | 
					
						
							|  |  |  | 				case 'DCon': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Watched Cell */ | 
					
						
							|  |  |  | 				case 'CellWatch': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Print Settings */ | 
					
						
							|  |  |  | 				case 'PrintRowCol': break; | 
					
						
							|  |  |  | 				case 'PrintGrid': break; | 
					
						
							|  |  |  | 				case 'PrintSize': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				case 'XCT': break; | 
					
						
							|  |  |  | 				case 'CRN': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				case 'Scl': { | 
					
						
							|  |  |  | 					//console.log("Zoom Level:", val[0]/val[1],val);
 | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'SheetExt': { | 
					
						
							| 
									
										
										
										
											2017-05-09 18:07:57 +00:00
										 |  |  | 					/* empty */ | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'SheetExtOptional': { | 
					
						
							| 
									
										
										
										
											2017-05-09 18:07:57 +00:00
										 |  |  | 					/* empty */ | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* VBA */ | 
					
						
							|  |  |  | 				case 'ObNoMacros': { | 
					
						
							| 
									
										
										
										
											2017-05-09 18:07:57 +00:00
										 |  |  | 					/* empty */ | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'ObProj': { | 
					
						
							| 
									
										
										
										
											2017-05-09 18:07:57 +00:00
										 |  |  | 					/* empty */ | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'CodeName': { | 
					
						
							| 
									
										
										
										
											2017-10-27 16:25:54 +00:00
										 |  |  | 					/*:: if(!Workbook.WBProps) Workbook.WBProps = {}; */ | 
					
						
							| 
									
										
										
										
											2017-11-20 01:51:14 +00:00
										 |  |  | 					if(!cur_sheet) Workbook.WBProps.CodeName = val || "ThisWorkbook"; | 
					
						
							|  |  |  | 					else wsprops.CodeName = val || wsprops.name; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case 'GUIDTypeLib': { | 
					
						
							| 
									
										
										
										
											2017-05-09 18:07:57 +00:00
										 |  |  | 					/* empty */ | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				case 'WOpt': break; // TODO: WTF?
 | 
					
						
							|  |  |  | 				case 'PhoneticInfo': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				case 'OleObjectSize': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Differential Formatting */ | 
					
						
							|  |  |  | 				case 'DXF': case 'DXFN': case 'DXFN12': case 'DXFN12List': case 'DXFN12NoCB': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Data Validation */ | 
					
						
							|  |  |  | 				case 'Dv': case 'DVal': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Data Series */ | 
					
						
							|  |  |  | 				case 'BRAI': case 'Series': case 'SeriesText': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Data Connection */ | 
					
						
							|  |  |  | 				case 'DConn': break; | 
					
						
							|  |  |  | 				case 'DbOrParamQry': break; | 
					
						
							|  |  |  | 				case 'DBQueryExt': break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-26 08:35:28 +00:00
										 |  |  | 				case 'OleDbConn': break; | 
					
						
							|  |  |  | 				case 'ExtString': break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				/* Formatting */ | 
					
						
							|  |  |  | 				case 'IFmtRecord': break; | 
					
						
							|  |  |  | 				case 'CondFmt': case 'CF': case 'CF12': case 'CFEx': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Explicitly Ignored */ | 
					
						
							|  |  |  | 				case 'Excel9File': break; | 
					
						
							|  |  |  | 				case 'Units': break; | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 				case 'InterfaceHdr': case 'Mms': case 'InterfaceEnd': case 'DSF': break; | 
					
						
							|  |  |  | 				case 'BuiltInFnGroupCount': /* 2.4.30 0x0E or 0x10 but excel 2011 generates 0x11? */ break; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				/* View Stuff */ | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 				case 'Window1': case 'HideObj': case 'GridSet': case 'Guts': | 
					
						
							| 
									
										
										
										
											2019-11-01 03:09:14 +00:00
										 |  |  | 				case 'UserBView': case 'UserSViewBegin': case 'UserSViewEnd': break; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				case 'Pane': break; | 
					
						
							|  |  |  | 				default: switch(R.n) { /* nested */ | 
					
						
							|  |  |  | 				/* Chart */ | 
					
						
							|  |  |  | 				case 'Dat': | 
					
						
							|  |  |  | 				case 'Begin': case 'End': | 
					
						
							|  |  |  | 				case 'StartBlock': case 'EndBlock': | 
					
						
							|  |  |  | 				case 'Frame': case 'Area': | 
					
						
							|  |  |  | 				case 'Axis': case 'AxisLine': case 'Tick': break; | 
					
						
							|  |  |  | 				case 'AxesUsed': | 
					
						
							|  |  |  | 				case 'CrtLayout12': case 'CrtLayout12A': case 'CrtLink': case 'CrtLine': case 'CrtMlFrt': case 'CrtMlFrtContinue': break; | 
					
						
							|  |  |  | 				case 'LineFormat': case 'AreaFormat': | 
					
						
							|  |  |  | 				case 'Chart': case 'Chart3d': case 'Chart3DBarShape': case 'ChartFormat': case 'ChartFrtInfo': break; | 
					
						
							|  |  |  | 				case 'PlotArea': case 'PlotGrowth': break; | 
					
						
							|  |  |  | 				case 'SeriesList': case 'SerParent': case 'SerAuxTrend': break; | 
					
						
							|  |  |  | 				case 'DataFormat': case 'SerToCrt': case 'FontX': break; | 
					
						
							|  |  |  | 				case 'CatSerRange': case 'AxcExt': case 'SerFmt': break; | 
					
						
							|  |  |  | 				case 'ShtProps': break; | 
					
						
							|  |  |  | 				case 'DefaultText': case 'Text': case 'CatLab': break; | 
					
						
							|  |  |  | 				case 'DataLabExtContents': break; | 
					
						
							|  |  |  | 				case 'Legend': case 'LegendException': break; | 
					
						
							|  |  |  | 				case 'Pie': case 'Scatter': break; | 
					
						
							|  |  |  | 				case 'PieFormat': case 'MarkerFormat': break; | 
					
						
							|  |  |  | 				case 'StartObject': case 'EndObject': break; | 
					
						
							|  |  |  | 				case 'AlRuns': case 'ObjectLink': break; | 
					
						
							|  |  |  | 				case 'SIIndex': break; | 
					
						
							|  |  |  | 				case 'AttachedLabel': case 'YMult': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Chart Group */ | 
					
						
							|  |  |  | 				case 'Line': case 'Bar': break; | 
					
						
							|  |  |  | 				case 'Surf': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Axis Group */ | 
					
						
							|  |  |  | 				case 'AxisParent': break; | 
					
						
							|  |  |  | 				case 'Pos': break; | 
					
						
							|  |  |  | 				case 'ValueRange': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Pivot Chart */ | 
					
						
							|  |  |  | 				case 'SXViewEx9': break; // TODO
 | 
					
						
							|  |  |  | 				case 'SXViewLink': break; | 
					
						
							|  |  |  | 				case 'PivotChartBits': break; | 
					
						
							|  |  |  | 				case 'SBaseRef': break; | 
					
						
							|  |  |  | 				case 'TextPropsStream': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Chart Misc */ | 
					
						
							|  |  |  | 				case 'LnExt': break; | 
					
						
							|  |  |  | 				case 'MkrExt': break; | 
					
						
							|  |  |  | 				case 'CrtCoopt': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Query Table */ | 
					
						
							|  |  |  | 				case 'Qsi': case 'Qsif': case 'Qsir': case 'QsiSXTag': break; | 
					
						
							|  |  |  | 				case 'TxtQry': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Filter */ | 
					
						
							|  |  |  | 				case 'FilterMode': break; | 
					
						
							|  |  |  | 				case 'AutoFilter': case 'AutoFilterInfo': break; | 
					
						
							|  |  |  | 				case 'AutoFilter12': break; | 
					
						
							|  |  |  | 				case 'DropDownObjIds': break; | 
					
						
							|  |  |  | 				case 'Sort': break; | 
					
						
							|  |  |  | 				case 'SortData': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Drawing */ | 
					
						
							|  |  |  | 				case 'ShapePropsStream': break; | 
					
						
							|  |  |  | 				case 'MsoDrawing': case 'MsoDrawingGroup': case 'MsoDrawingSelection': break; | 
					
						
							|  |  |  | 				/* Pub Stuff */ | 
					
						
							| 
									
										
										
										
											2017-05-09 18:07:57 +00:00
										 |  |  | 				case 'WebPub': case 'AutoWebPub': break; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				/* Print Stuff */ | 
					
						
							|  |  |  | 				case 'HeaderFooter': case 'HFPicture': case 'PLV': | 
					
						
							| 
									
										
										
										
											2017-05-09 18:07:57 +00:00
										 |  |  | 				case 'HorizontalPageBreaks': case 'VerticalPageBreaks': break; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				/* Behavioral */ | 
					
						
							|  |  |  | 				case 'Backup': case 'CompressPictures': case 'Compat12': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Should not Happen */ | 
					
						
							|  |  |  | 				case 'Continue': case 'ContinueFrt12': break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Future Records */ | 
					
						
							|  |  |  | 				case 'FrtFontList': case 'FrtWrapper': break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 				default: switch(R.n) { /* nested */ | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				/* BIFF5 records */ | 
					
						
							|  |  |  | 				case 'TabIdConf': case 'Radar': case 'RadarArea': case 'DropBar': case 'Intl': case 'CoordList': case 'SerAuxErrBar': break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 				/* BIFF2-4 records */ | 
					
						
							| 
									
										
										
										
											2017-02-19 20:36:32 +00:00
										 |  |  | 				case 'BIFF2FONTCLR': case 'BIFF2FMTCNT': case 'BIFF2FONTXTRA': break; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 				case 'BIFF2XF': case 'BIFF3XF': case 'BIFF4XF': break; | 
					
						
							| 
									
										
										
										
											2021-09-26 22:51:19 +00:00
										 |  |  | 				case 'BIFF2XFINDEX': break; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | 				case 'BIFF4FMTCNT': case 'BIFF2ROW': case 'BIFF2WINDOW2': break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				/* Miscellaneous */ | 
					
						
							|  |  |  | 				case 'SCENARIO': case 'DConBin': case 'PicF': case 'DataLabExt': | 
					
						
							|  |  |  | 				case 'Lel': case 'BopPop': case 'BopPopCustom': case 'RealTimeData': | 
					
						
							|  |  |  | 				case 'Name': break; | 
					
						
							| 
									
										
										
										
											2017-07-26 08:35:28 +00:00
										 |  |  | 				case 'LHNGraph': case 'FnGroupName': case 'AddMenu': case 'LPr': break; | 
					
						
							|  |  |  | 				case 'ListObj': case 'ListField': break; | 
					
						
							|  |  |  | 				case 'RRSort': break; | 
					
						
							|  |  |  | 				case 'BigName': break; | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 				case 'ToolbarHdr': case 'ToolbarEnd': break; | 
					
						
							|  |  |  | 				case 'DDEObjName': break; | 
					
						
							|  |  |  | 				case 'FRTArchId$': break; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 				default: if(options.WTF) throw 'Unrecognized Record ' + R.n; | 
					
						
							|  |  |  | 			}}}} | 
					
						
							|  |  |  | 		} else blob.l += length; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-01-23 09:07:51 +00:00
										 |  |  | 	wb.SheetNames=keys(Directory).sort(function(a,b) { return Number(a) - Number(b); }).map(function(x){return Directory[x].name;}); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	if(!options.bookSheets) wb.Sheets=Sheets; | 
					
						
							| 
									
										
										
										
											2021-09-16 23:40:52 +00:00
										 |  |  | 	if(!wb.SheetNames.length && Preamble["!ref"]) { | 
					
						
							|  |  |  | 		wb.SheetNames.push("Sheet1"); | 
					
						
							| 
									
										
										
										
											2021-12-29 09:16:02 +00:00
										 |  |  | 		/*jshint -W069 */ | 
					
						
							| 
									
										
										
										
											2021-09-16 23:40:52 +00:00
										 |  |  | 		if(wb.Sheets) wb.Sheets["Sheet1"] = Preamble; | 
					
						
							| 
									
										
										
										
											2021-12-29 09:16:02 +00:00
										 |  |  | 		/*jshint +W069 */ | 
					
						
							| 
									
										
										
										
											2021-09-16 23:40:52 +00:00
										 |  |  | 	} else wb.Preamble=Preamble; | 
					
						
							| 
									
										
										
										
											2017-04-10 05:10:54 +00:00
										 |  |  | 	if(wb.Sheets) FilterDatabases.forEach(function(r,i) { wb.Sheets[wb.SheetNames[i]]['!autofilter'] = r; }); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	wb.Strings = sst; | 
					
						
							|  |  |  | 	wb.SSF = SSF.get_table(); | 
					
						
							|  |  |  | 	if(opts.enc) wb.Encryption = opts.enc; | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	if(themes) wb.Themes = themes; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	wb.Metadata = {}; | 
					
						
							|  |  |  | 	if(country !== undefined) wb.Metadata.Country = country; | 
					
						
							| 
									
										
										
										
											2017-04-11 22:15:36 +00:00
										 |  |  | 	if(supbooks.names.length > 0) Workbook.Names = supbooks.names; | 
					
						
							| 
									
										
										
										
											2017-03-31 18:46:42 +00:00
										 |  |  | 	wb.Workbook = Workbook; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	return wb; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-05 06:34:37 +00:00
										 |  |  | /* TODO: split props*/ | 
					
						
							|  |  |  | var PSCLSID = { | 
					
						
							|  |  |  | 	SI: "e0859ff2f94f6810ab9108002b27b3d9", | 
					
						
							|  |  |  | 	DSI: "02d5cdd59c2e1b10939708002b2cf9ae", | 
					
						
							|  |  |  | 	UDI: "05d5cdd59c2e1b10939708002b2cf9ae" | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | function parse_xls_props(cfb/*:CFBContainer*/, props, o) { | 
					
						
							| 
									
										
										
										
											2017-04-30 16:27:03 +00:00
										 |  |  | 	/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */ | 
					
						
							| 
									
										
										
										
											2022-01-25 07:52:05 +00:00
										 |  |  | 	var DSI = CFB.find(cfb, '/!DocumentSummaryInformation'); | 
					
						
							| 
									
										
										
										
											2018-02-14 20:06:35 +00:00
										 |  |  | 	if(DSI && DSI.size > 0) try { | 
					
						
							| 
									
										
										
										
											2018-05-05 06:34:37 +00:00
										 |  |  | 		var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, PSCLSID.DSI); | 
					
						
							| 
									
										
										
										
											2017-09-30 06:18:11 +00:00
										 |  |  | 		for(var d in DocSummary) props[d] = DocSummary[d]; | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	} catch(e) {if(o.WTF) throw e;/* empty */} | 
					
						
							| 
									
										
										
										
											2017-04-30 16:27:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/ | 
					
						
							| 
									
										
										
										
											2022-01-25 07:52:05 +00:00
										 |  |  | 	var SI = CFB.find(cfb, '/!SummaryInformation'); | 
					
						
							| 
									
										
										
										
											2018-02-14 20:06:35 +00:00
										 |  |  | 	if(SI && SI.size > 0) try { | 
					
						
							| 
									
										
										
										
											2018-05-05 06:34:37 +00:00
										 |  |  | 		var Summary = parse_PropertySetStream(SI, SummaryPIDSI, PSCLSID.SI); | 
					
						
							| 
									
										
										
										
											2017-09-30 06:18:11 +00:00
										 |  |  | 		for(var s in Summary) if(props[s] == null) props[s] = Summary[s]; | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	} catch(e) {if(o.WTF) throw e;/* empty */} | 
					
						
							| 
									
										
										
										
											2018-05-05 06:34:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(props.HeadingPairs && props.TitlesOfParts) { | 
					
						
							|  |  |  | 		load_props_pairs(props.HeadingPairs, props.TitlesOfParts, props, o); | 
					
						
							|  |  |  | 		delete props.HeadingPairs; delete props.TitlesOfParts; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | function write_xls_props(wb/*:Workbook*/, cfb/*:CFBContainer*/) { | 
					
						
							|  |  |  | 	var DSEntries = [], SEntries = [], CEntries = []; | 
					
						
							|  |  |  | 	var i = 0, Keys; | 
					
						
							|  |  |  | 	if(wb.Props) { | 
					
						
							|  |  |  | 		Keys = keys(wb.Props); | 
					
						
							| 
									
										
										
										
											2018-05-20 01:34:59 +00:00
										 |  |  | 		// $FlowIgnore
 | 
					
						
							| 
									
										
										
										
											2020-03-15 07:42:05 +00:00
										 |  |  | 		for(i = 0; i < Keys.length; ++i) (Object.prototype.hasOwnProperty.call(DocSummaryRE, Keys[i]) ? DSEntries : Object.prototype.hasOwnProperty.call(SummaryRE, Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Props[Keys[i]]]); | 
					
						
							| 
									
										
										
										
											2018-05-05 06:34:37 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if(wb.Custprops) { | 
					
						
							|  |  |  | 		Keys = keys(wb.Custprops); | 
					
						
							| 
									
										
										
										
											2018-05-20 01:34:59 +00:00
										 |  |  | 		// $FlowIgnore
 | 
					
						
							| 
									
										
										
										
											2020-03-15 07:42:05 +00:00
										 |  |  | 		for(i = 0; i < Keys.length; ++i) if(!Object.prototype.hasOwnProperty.call((wb.Props||{}), Keys[i])) (Object.prototype.hasOwnProperty.call(DocSummaryRE, Keys[i]) ? DSEntries : Object.prototype.hasOwnProperty.call(SummaryRE, Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Custprops[Keys[i]]]); | 
					
						
							| 
									
										
										
										
											2018-05-05 06:34:37 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	var CEntries2 = []; | 
					
						
							|  |  |  | 	for(i = 0; i < CEntries.length; ++i) { | 
					
						
							|  |  |  | 		if(XLSPSSkip.indexOf(CEntries[i][0]) > -1) continue; | 
					
						
							|  |  |  | 		if(CEntries[i][1] == null) continue; | 
					
						
							|  |  |  | 		CEntries2.push(CEntries[i]); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(SEntries.length) CFB.utils.cfb_add(cfb, "/\u0005SummaryInformation", write_PropertySetStream(SEntries, PSCLSID.SI, SummaryRE, SummaryPIDSI)); | 
					
						
							|  |  |  | 	if(DSEntries.length || CEntries2.length) CFB.utils.cfb_add(cfb, "/\u0005DocumentSummaryInformation", write_PropertySetStream(DSEntries, PSCLSID.DSI, DocSummaryRE, DocSummaryPIDDSI, CEntries2.length ? CEntries2 : null, PSCLSID.UDI)); | 
					
						
							| 
									
										
										
										
											2017-04-30 16:27:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-12 18:02:43 +00:00
										 |  |  | function parse_xlscfb(cfb/*:any*/, options/*:?ParseOpts*/)/*:Workbook*/ { | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | if(!options) options = {}; | 
					
						
							|  |  |  | fix_read_opts(options); | 
					
						
							|  |  |  | reset_cp(); | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | if(options.codepage) set_ansi(options.codepage); | 
					
						
							| 
									
										
										
										
											2018-01-23 09:07:51 +00:00
										 |  |  | var CompObj/*:?CFBEntry*/, WB/*:?any*/; | 
					
						
							| 
									
										
										
										
											2017-02-10 19:23:01 +00:00
										 |  |  | if(cfb.FullPaths) { | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 	if(CFB.find(cfb, '/encryption')) throw new Error("File is password-protected"); | 
					
						
							| 
									
										
										
										
											2017-08-09 22:38:23 +00:00
										 |  |  | 	CompObj = CFB.find(cfb, '!CompObj'); | 
					
						
							| 
									
										
										
										
											2017-09-30 06:18:11 +00:00
										 |  |  | 	WB = CFB.find(cfb, '/Workbook') || CFB.find(cfb, '/Book'); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | } else { | 
					
						
							| 
									
										
										
										
											2017-08-19 23:06:34 +00:00
										 |  |  | 	switch(options.type) { | 
					
						
							|  |  |  | 		case 'base64': cfb = s2a(Base64.decode(cfb)); break; | 
					
						
							|  |  |  | 		case 'binary': cfb = s2a(cfb); break; | 
					
						
							|  |  |  | 		case 'buffer': break; | 
					
						
							|  |  |  | 		case 'array': if(!Array.isArray(cfb)) cfb = Array.prototype.slice.call(cfb); break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	prep_blob(cfb, 0); | 
					
						
							| 
									
										
										
										
											2017-08-09 22:38:23 +00:00
										 |  |  | 	WB = ({content: cfb}/*:any*/); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-01-23 09:07:51 +00:00
										 |  |  | var /*::CompObjP, */WorkbookP/*:: :Workbook = XLSX.utils.book_new(); */; | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-09 22:38:23 +00:00
										 |  |  | var _data/*:?any*/; | 
					
						
							| 
									
										
										
										
											2018-01-23 09:07:51 +00:00
										 |  |  | if(CompObj) /*::CompObjP = */parse_compobj(CompObj); | 
					
						
							| 
									
										
										
										
											2017-03-12 18:02:43 +00:00
										 |  |  | if(options.bookProps && !options.bookSheets) WorkbookP = ({}/*:any*/); | 
					
						
							| 
									
										
										
										
											2017-09-30 06:18:11 +00:00
										 |  |  | else/*:: if(cfb instanceof CFBContainer) */ { | 
					
						
							|  |  |  | 	var T = has_buf ? 'buffer' : 'array'; | 
					
						
							| 
									
										
										
										
											2017-08-09 22:38:23 +00:00
										 |  |  | 	if(WB && WB.content) WorkbookP = parse_workbook(WB.content, options); | 
					
						
							| 
									
										
										
										
											2017-04-04 16:09:41 +00:00
										 |  |  | 	/* Quattro Pro 7-8 */ | 
					
						
							| 
									
										
										
										
											2017-09-30 06:18:11 +00:00
										 |  |  | 	else if((_data=CFB.find(cfb, 'PerfectOffice_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options)); | 
					
						
							| 
									
										
										
										
											2017-04-04 16:09:41 +00:00
										 |  |  | 	/* Quattro Pro 9 */ | 
					
						
							| 
									
										
										
										
											2017-09-30 06:18:11 +00:00
										 |  |  | 	else if((_data=CFB.find(cfb, 'NativeContent_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options)); | 
					
						
							| 
									
										
										
										
											2021-12-29 09:16:02 +00:00
										 |  |  | 	/* Works 4 for Mac */ | 
					
						
							|  |  |  | 	else if((_data=CFB.find(cfb, 'MN0')) && _data.content) throw new Error("Unsupported Works 4 for Mac file"); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | 	else throw new Error("Cannot find Workbook stream"); | 
					
						
							| 
									
										
										
										
											2017-11-15 18:14:02 +00:00
										 |  |  | 	if(options.bookVBA && cfb.FullPaths && CFB.find(cfb, '/_VBA_PROJECT_CUR/VBA/dir')) WorkbookP.vbaraw = make_vba_xls(cfb); | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var props = {}; | 
					
						
							| 
									
										
										
										
											2018-05-05 06:34:37 +00:00
										 |  |  | if(cfb.FullPaths) parse_xls_props(/*::((*/cfb/*:: :any):CFBContainer)*/, props, options); | 
					
						
							| 
									
										
										
										
											2017-09-30 06:18:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */ | 
					
						
							|  |  |  | if(options.bookFiles) WorkbookP.cfb = cfb; | 
					
						
							| 
									
										
										
										
											2017-03-12 18:02:43 +00:00
										 |  |  | /*WorkbookP.CompObjP = CompObjP; // TODO: storage? */ | 
					
						
							| 
									
										
										
										
											2015-04-02 20:32:22 +00:00
										 |  |  | return WorkbookP; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | function write_xlscfb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:CFBContainer*/ { | 
					
						
							|  |  |  | 	var o = opts || {}; | 
					
						
							|  |  |  | 	var cfb = CFB.utils.cfb_new({root:"R"}); | 
					
						
							|  |  |  | 	var wbpath = "/Workbook"; | 
					
						
							|  |  |  | 	switch(o.bookType || "xls") { | 
					
						
							|  |  |  | 		case "xls": o.bookType = "biff8"; | 
					
						
							|  |  |  | 		/* falls through */ | 
					
						
							| 
									
										
										
										
											2017-12-30 05:40:35 +00:00
										 |  |  | 		case "xla": if(!o.bookType) o.bookType = "xla"; | 
					
						
							|  |  |  | 		/* falls through */ | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 		case "biff8": wbpath = "/Workbook"; o.biff = 8; break; | 
					
						
							|  |  |  | 		case "biff5": wbpath = "/Book"; o.biff = 5; break; | 
					
						
							|  |  |  | 		default: throw new Error("invalid type " + o.bookType + " for XLS CFB"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	CFB.utils.cfb_add(cfb, wbpath, write_biff_buf(wb, o)); | 
					
						
							| 
									
										
										
										
											2018-05-05 06:34:37 +00:00
										 |  |  | 	if(o.biff == 8 && (wb.Props || wb.Custprops)) write_xls_props(wb, cfb); | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	// TODO: SI, DSI, CO
 | 
					
						
							| 
									
										
										
										
											2017-10-27 16:25:54 +00:00
										 |  |  | 	if(o.biff == 8 && wb.vbaraw) fill_vba_xls(cfb, CFB.read(wb.vbaraw, {type: typeof wb.vbaraw == "string" ? "binary" : "buffer"})); | 
					
						
							| 
									
										
										
										
											2017-09-22 22:18:51 +00:00
										 |  |  | 	return cfb; | 
					
						
							|  |  |  | } |