forked from sheetjs/sheetjs
		
	version bump 0.12.12: ecosystem deprecations
- node 10 `Buffer` deprecation workaround (with dependency update) - Angular 6 global deprecation workaround (fixes #1088 h/t @cristhiank) - BIFF8 write standard and custom properties - TH elements in HTML string (fixes #1090 h/t @GigiSan) - planmaker export quirks
This commit is contained in:
		
							parent
							
								
									eb5fc87be4
								
							
						
					
					
						commit
						c0b4895881
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -10,6 +10,8 @@ tmp | ||||
| *.[cC][sS][vV] | ||||
| *.[dD][iIbB][fF] | ||||
| *.[pP][rR][nN] | ||||
| *.[pP][mM][dD]* | ||||
| *.[pP][dD][fF] | ||||
| *.[sS][lL][kK] | ||||
| *.socialcalc | ||||
| *.[xX][lL][sSwWcCaAtTmM] | ||||
|  | ||||
| @ -12,6 +12,8 @@ tmp | ||||
| *.[cC][sS][vV] | ||||
| *.[dD][iIbB][fF] | ||||
| *.[pP][rR][nN] | ||||
| *.[pP][mM][dD]* | ||||
| *.[pP][dD][fF] | ||||
| *.[sS][lL][kK] | ||||
| *.socialcalc | ||||
| *.[xX][lL][sSwWcCaAtTmM] | ||||
|  | ||||
							
								
								
									
										26
									
								
								bin/xlsx.njs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										26
									
								
								bin/xlsx.njs
									
									
									
									
									
								
							| @ -43,6 +43,7 @@ program | ||||
| 	.option('-t, --txt',  'emit TXT  to <sheetname> or <file>.txt (UTF-8 TSV)') | ||||
| 	.option('-r, --rtf',  'emit RTF  to <sheetname> or <file>.txt (Table RTF)') | ||||
| 	.option('-z, --dump', 'dump internal representation as JSON') | ||||
| 	.option('--props',    'dump workbook properties as CSV') | ||||
| 
 | ||||
| 	.option('-F, --field-sep <sep>', 'CSV field separator', ",") | ||||
| 	.option('-R, --row-sep <sep>', 'CSV row separator', "\n") | ||||
| @ -163,6 +164,10 @@ if(program.dump) { | ||||
| 	console.log(JSON.stringify(wb)); | ||||
| 	process.exit(0); | ||||
| } | ||||
| if(program.props) { | ||||
| 	dump_props(wb); | ||||
| 	process.exit(0); | ||||
| } | ||||
| 
 | ||||
| /* full workbook formats */ | ||||
| workbook_formats.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) { | ||||
| @ -255,3 +260,24 @@ switch(true) { | ||||
| 		} else doit(function(ws) { return X.utils.sheet_to_csv(ws,{FS:program.fieldSep, RS:program.rowSep}); }); | ||||
| 		break; | ||||
| } | ||||
| 
 | ||||
| function dump_props(wb) { | ||||
| 	var propaoa = []; | ||||
| 	if(Object.assign && Object.entries) propaoa = Object.entries(Object.assign({}, wb.Props, wb.Custprops)); | ||||
| 	else { | ||||
| 		var Keys, pi; | ||||
| 		if(wb.Props) { | ||||
| 			Keys = Object.keys(wb.Props); | ||||
| 			for(pi = 0; pi < Keys.length; ++pi) { | ||||
| 				if(Keys.hasOwnProperty(Keys[pi])) propaoa.push([Keys[pi], Keys[Keys[pi]]]); | ||||
| 			} | ||||
| 		} | ||||
| 		if(wb.Custprops) { | ||||
| 			Keys = Object.keys(wb.Custprops); | ||||
| 			for(pi = 0; pi < Keys.length; ++pi) { | ||||
| 				if(Keys.hasOwnProperty(Keys[pi])) propaoa.push([Keys[pi], Keys[Keys[pi]]]); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	console.log(X.utils.sheet_to_csv(X.utils.aoa_to_sheet(propaoa))); | ||||
| } | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| XLSX.version = '0.12.11'; | ||||
| XLSX.version = '0.12.12'; | ||||
|  | ||||
| @ -1,8 +1,11 @@ | ||||
| var current_codepage = 1200, current_ansi = 1252; | ||||
| /*:: declare var cptable:any; */ | ||||
| /*global cptable:true */ | ||||
| /*global cptable:true, window */ | ||||
| if(typeof module !== "undefined" && typeof require !== 'undefined') { | ||||
| 	if(typeof cptable === 'undefined') global.cptable = require('./dist/cpexcel.js'); | ||||
| 	if(typeof cptable === 'undefined') { | ||||
| 		if(typeof global !== 'undefined') global.cptable = require('./dist/cpexcel.js'); | ||||
| 		else if(typeof window !== 'undefined') window.cptable = require('./dist/cpexcel.js'); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| var VALID_ANSI = [ 874, 932, 936, 949, 950 ]; | ||||
|  | ||||
| @ -1,16 +1,22 @@ | ||||
| var has_buf = (typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && process.versions.node); | ||||
| 
 | ||||
| if(typeof Buffer !== 'undefined') { | ||||
| 	// $FlowIgnore
 | ||||
| 	if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); }; | ||||
| 	// $FlowIgnore
 | ||||
| 	if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); }; | ||||
| } | ||||
| 
 | ||||
| function new_raw_buf(len/*:number*/) { | ||||
| 	/* jshint -W056 */ | ||||
| 	// $FlowIgnore
 | ||||
| 	return new (has_buf ? Buffer : Array)(len); | ||||
| 	return has_buf ? Buffer.alloc(len) : new Array(len); | ||||
| 	/* jshint +W056 */ | ||||
| } | ||||
| 
 | ||||
| function s2a(s/*:string*/)/*:any*/ { | ||||
| 	if(has_buf) return new Buffer(s, "binary"); | ||||
| var s2a = function s2a(s/*:string*/)/*:any*/ { | ||||
| 	if(has_buf) return Buffer.from(s, "binary"); | ||||
| 	return s.split("").map(function(x/*:string*/)/*:number*/{ return x.charCodeAt(0) & 0xff; }); | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| function s2ab(s/*:string*/)/*:any*/ { | ||||
| 	if(typeof ArrayBuffer === 'undefined') return s2a(s); | ||||
|  | ||||
| @ -38,7 +38,7 @@ type CFBFiles = {[n:string]:CFBEntry}; | ||||
| /* [MS-CFB] v20171201 */ | ||||
| var CFB = (function _CFB(){ | ||||
| var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/; | ||||
| exports.version = '1.0.6'; | ||||
| exports.version = '1.0.7'; | ||||
| /* [MS-CFB] 2.6.4 */ | ||||
| function namecmp(l/*:string*/, r/*:string*/)/*:number*/ { | ||||
| 	var L = l.split("/"), R = r.split("/"); | ||||
|  | ||||
| @ -135,7 +135,7 @@ var utf8write/*:StringConv*/ = function(orig/*:string*/)/*:string*/ { | ||||
| 
 | ||||
| if(has_buf) { | ||||
| 	var utf8readb = function utf8readb(data) { | ||||
| 		var out = new Buffer(2*data.length), w, i, j = 1, k = 0, ww=0, c; | ||||
| 		var out = Buffer.alloc(2*data.length), w, i, j = 1, k = 0, ww=0, c; | ||||
| 		for(i = 0; i < data.length; i+=j) { | ||||
| 			j = 1; | ||||
| 			if((c=data.charCodeAt(i)) < 128) w = c; | ||||
| @ -153,10 +153,10 @@ if(has_buf) { | ||||
| 	var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3"; | ||||
| 	if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb; | ||||
| 	// $FlowIgnore
 | ||||
| 	var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); }; | ||||
| 	var utf8readc = function utf8readc(data) { return Buffer.from(data, 'binary').toString('utf8'); }; | ||||
| 	if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc; | ||||
| 
 | ||||
| 	utf8write = function(data) { return new Buffer(data, 'utf8').toString("binary"); }; | ||||
| 	utf8write = function(data) { return Buffer.from(data, 'utf8').toString("binary"); }; | ||||
| } | ||||
| 
 | ||||
| // matches <foo>...</foo> extracts content
 | ||||
|  | ||||
| @ -51,15 +51,15 @@ var DocSummaryPIDDSI = { | ||||
| 	/*::[*/0x08/*::]*/: { n: 'NoteCount', t: VT_I4 }, | ||||
| 	/*::[*/0x09/*::]*/: { n: 'HiddenCount', t: VT_I4 }, | ||||
| 	/*::[*/0x0a/*::]*/: { n: 'MultimediaClipCount', t: VT_I4 }, | ||||
| 	/*::[*/0x0b/*::]*/: { n: 'Scale', t: VT_BOOL }, | ||||
| 	/*::[*/0x0c/*::]*/: { n: 'HeadingPair', t: VT_VECTOR | VT_VARIANT }, | ||||
| 	/*::[*/0x0d/*::]*/: { n: 'DocParts', t: VT_VECTOR | VT_LPSTR }, | ||||
| 	/*::[*/0x0b/*::]*/: { n: 'ScaleCrop', t: VT_BOOL }, | ||||
| 	/*::[*/0x0c/*::]*/: { n: 'HeadingPairs', t: VT_VECTOR | VT_VARIANT }, | ||||
| 	/*::[*/0x0d/*::]*/: { n: 'TitlesOfParts', t: VT_VECTOR | VT_LPSTR }, | ||||
| 	/*::[*/0x0e/*::]*/: { n: 'Manager', t: VT_STRING }, | ||||
| 	/*::[*/0x0f/*::]*/: { n: 'Company', t: VT_STRING }, | ||||
| 	/*::[*/0x10/*::]*/: { n: 'LinksDirty', t: VT_BOOL }, | ||||
| 	/*::[*/0x10/*::]*/: { n: 'LinksUpToDate', t: VT_BOOL }, | ||||
| 	/*::[*/0x11/*::]*/: { n: 'CharacterCount', t: VT_I4 }, | ||||
| 	/*::[*/0x13/*::]*/: { n: 'SharedDoc', t: VT_BOOL }, | ||||
| 	/*::[*/0x16/*::]*/: { n: 'HLinksChanged', t: VT_BOOL }, | ||||
| 	/*::[*/0x16/*::]*/: { n: 'HyperlinksChanged', t: VT_BOOL }, | ||||
| 	/*::[*/0x17/*::]*/: { n: 'AppVersion', t: VT_I4, p: 'version' }, | ||||
| 	/*::[*/0x18/*::]*/: { n: 'DigSig', t: VT_BLOB }, | ||||
| 	/*::[*/0x1A/*::]*/: { n: 'ContentType', t: VT_STRING }, | ||||
| @ -88,8 +88,8 @@ var SummaryPIDSI = { | ||||
| 	/*::[*/0x0F/*::]*/: { n: 'WordCount', t: VT_I4 }, | ||||
| 	/*::[*/0x10/*::]*/: { n: 'CharCount', t: VT_I4 }, | ||||
| 	/*::[*/0x11/*::]*/: { n: 'Thumbnail', t: VT_CF }, | ||||
| 	/*::[*/0x12/*::]*/: { n: 'ApplicationName', t: VT_STRING }, | ||||
| 	/*::[*/0x13/*::]*/: { n: 'DocumentSecurity', t: VT_I4 }, | ||||
| 	/*::[*/0x12/*::]*/: { n: 'Application', t: VT_STRING }, | ||||
| 	/*::[*/0x13/*::]*/: { n: 'DocSecurity', t: VT_I4 }, | ||||
| 	/*::[*/0xFF/*::]*/: {} | ||||
| }; | ||||
| 
 | ||||
| @ -105,6 +105,9 @@ var SpecialProperties = { | ||||
| 	DocSummaryPIDDSI[y] = SummaryPIDSI[y] = SpecialProperties[y]; | ||||
| })(); | ||||
| 
 | ||||
| var DocSummaryRE = evert_key(DocSummaryPIDDSI, "n"); | ||||
| var SummaryRE = evert_key(SummaryPIDSI, "n"); | ||||
| 
 | ||||
| /* [MS-XLS] 2.4.63 Country/Region codes */ | ||||
| var CountryEnum = { | ||||
| 	/*::[*/0x0001/*::]*/: "US", // United States
 | ||||
|  | ||||
| @ -17,6 +17,56 @@ var EXT_PROPS/*:Array<Array<string> >*/ = [ | ||||
| XMLNS.EXT_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"; | ||||
| RELS.EXT_PROPS  = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties'; | ||||
| 
 | ||||
| var PseudoPropsPairs = [ | ||||
| 	"Worksheets",  "SheetNames", | ||||
| 	"NamedRanges", "DefinedNames", | ||||
| 	"Chartsheets", "ChartNames" | ||||
| ]; | ||||
| function load_props_pairs(HP/*:string|Array<Array<any>>*/, TOP, props, opts) { | ||||
| 	var v = []; | ||||
| 	if(typeof HP == "string") v = parseVector(HP, opts); | ||||
| 	else for(var j = 0; j < HP.length; ++j) v = v.concat(HP[j].map(function(hp) { return {v:hp}; })); | ||||
| 	var parts = (typeof TOP == "string") ? parseVector(TOP, opts).map(function (x) { return x.v; }) : TOP; | ||||
| 	var idx = 0, len = 0; | ||||
| 	if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) { | ||||
| 		len = +(v[i+1].v); | ||||
| 		switch(v[i].v) { | ||||
| 			case "Worksheets": | ||||
| 			case "工作表": | ||||
| 			case "Листы": | ||||
| 			case "أوراق العمل": | ||||
| 			case "ワークシート": | ||||
| 			case "גליונות עבודה": | ||||
| 			case "Arbeitsblätter": | ||||
| 			case "Çalışma Sayfaları": | ||||
| 			case "Feuilles de calcul": | ||||
| 			case "Fogli di lavoro": | ||||
| 			case "Folhas de cálculo": | ||||
| 			case "Planilhas": | ||||
| 			case "Regneark": | ||||
| 			case "Werkbladen": | ||||
| 				props.Worksheets = len; | ||||
| 				props.SheetNames = parts.slice(idx, idx + len); | ||||
| 				break; | ||||
| 
 | ||||
| 			case "Named Ranges": | ||||
| 			case "名前付き一覧": | ||||
| 			case "Benannte Bereiche": | ||||
| 			case "Navngivne områder": | ||||
| 				props.NamedRanges = len; | ||||
| 				props.DefinedNames = parts.slice(idx, idx + len); | ||||
| 				break; | ||||
| 
 | ||||
| 			case "Charts": | ||||
| 			case "Diagramme": | ||||
| 				props.Chartsheets = len; | ||||
| 				props.ChartNames = parts.slice(idx, idx + len); | ||||
| 				break; | ||||
| 		} | ||||
| 		idx += len; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function parse_ext_props(data, p, opts) { | ||||
| 	var q = {}; if(!p) p = {}; | ||||
| 	data = utf8read(data); | ||||
| @ -32,48 +82,7 @@ function parse_ext_props(data, p, opts) { | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	if(q.HeadingPairs && q.TitlesOfParts) { | ||||
| 		var v = parseVector(q.HeadingPairs, opts); | ||||
| 		var parts = parseVector(q.TitlesOfParts, opts).map(function (x) { return x.v; }); | ||||
| 		var idx = 0, len = 0; | ||||
| 		if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) { | ||||
| 			len = +(v[i+1].v); | ||||
| 			switch(v[i].v) { | ||||
| 				case "Worksheets": | ||||
| 				case "工作表": | ||||
| 				case "Листы": | ||||
| 				case "أوراق العمل": | ||||
| 				case "ワークシート": | ||||
| 				case "גליונות עבודה": | ||||
| 				case "Arbeitsblätter": | ||||
| 				case "Çalışma Sayfaları": | ||||
| 				case "Feuilles de calcul": | ||||
| 				case "Fogli di lavoro": | ||||
| 				case "Folhas de cálculo": | ||||
| 				case "Planilhas": | ||||
| 				case "Regneark": | ||||
| 				case "Werkbladen": | ||||
| 					p.Worksheets = len; | ||||
| 					p.SheetNames = parts.slice(idx, idx + len); | ||||
| 					break; | ||||
| 
 | ||||
| 				case "Named Ranges": | ||||
| 				case "名前付き一覧": | ||||
| 				case "Benannte Bereiche": | ||||
| 				case "Navngivne områder": | ||||
| 					p.NamedRanges = len; | ||||
| 					p.DefinedNames = parts.slice(idx, idx + len); | ||||
| 					break; | ||||
| 
 | ||||
| 				case "Charts": | ||||
| 				case "Diagramme": | ||||
| 					p.Chartsheets = len; | ||||
| 					p.ChartNames = parts.slice(idx, idx + len); | ||||
| 					break; | ||||
| 			} | ||||
| 			idx += len; | ||||
| 		} | ||||
| 	} | ||||
| 	if(q.HeadingPairs && q.TitlesOfParts) load_props_pairs(q.HeadingPairs, q.TitlesOfParts, p, opts); | ||||
| 
 | ||||
| 	return p; | ||||
| } | ||||
|  | ||||
| @ -5,6 +5,15 @@ function parse_FILETIME(blob) { | ||||
| 	var dwLowDateTime = blob.read_shift(4), dwHighDateTime = blob.read_shift(4); | ||||
| 	return new Date(((dwHighDateTime/1e7*Math.pow(2,32) + dwLowDateTime/1e7) - 11644473600)*1000).toISOString().replace(/\.000/,""); | ||||
| } | ||||
| function write_FILETIME(time/*:string|Date*/) { | ||||
| 	var date = (typeof time == "string") ? new Date(Date.parse(time)) : time; | ||||
| 	var t = date.getTime() / 1000 + 11644473600; | ||||
| 	var l = t % Math.pow(2,32), h = (t - l) / Math.pow(2,32); | ||||
| 	l *= 1e7; h *= 1e7; | ||||
| 	var w = (l / Math.pow(2,32)) | 0; | ||||
| 	if(w > 0) { l = l % Math.pow(2,32); h += w; } | ||||
| 	var o = new_buf(8); o.write_shift(4, l); o.write_shift(4, h); return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-OSHARED] 2.3.3.1.4 Lpstr */ | ||||
| function parse_lpstr(blob, type, pad/*:?number*/) { | ||||
| @ -74,6 +83,7 @@ function parse_dictionary(blob,CodePage) { | ||||
| 		var pid = blob.read_shift(4); | ||||
| 		var len = blob.read_shift(4); | ||||
| 		dict[pid] = blob.read_shift(len, (CodePage === 0x4B0 ?'utf16le':'utf8')).replace(chr0,'').replace(chr1,'!'); | ||||
| 		if(CodePage === 0x4B0 && (len % 2)) blob.l += 2; | ||||
| 	} | ||||
| 	if(blob.l & 3) blob.l = (blob.l>>2+1)<<2; | ||||
| 	return dict; | ||||
| @ -121,6 +131,25 @@ function parse_TypedPropertyValue(blob, type/*:number*/, _opts)/*:any*/ { | ||||
| 		default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + t); | ||||
| 	} | ||||
| } | ||||
| function write_TypedPropertyValue(type/*:number*/, value) { | ||||
| 	var o = new_buf(4), p = new_buf(4); | ||||
| 	o.write_shift(4, type == 0x50 ? 0x1F : type); | ||||
| 	switch(type) { | ||||
| 		case 0x03 /*VT_I4*/: p.write_shift(-4, value); break; | ||||
| 		case 0x05 /*VT_I4*/: p = new_buf(8); p.write_shift(8, value, 'f'); break; | ||||
| 		case 0x0B /*VT_BOOL*/: p.write_shift(4, value ? 0x01 : 0x00); break; | ||||
| 		case 0x40 /*VT_FILETIME*/: p = write_FILETIME(value); break; | ||||
| 		case 0x1F /*VT_LPWSTR*/: | ||||
| 		case 0x50 /*VT_STRING*/: | ||||
| 			p = new_buf(4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2)); | ||||
| 			p.write_shift(4, value.length + 1); | ||||
| 			p.write_shift(0, value, "dbcs"); | ||||
| 			while(p.l != p.length) p.write_shift(1, 0); | ||||
| 			break; | ||||
| 		default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + value); | ||||
| 	} | ||||
| 	return bconcat([o, p]); | ||||
| } | ||||
| 
 | ||||
| /* [MS-OLEPS] 2.20 PropertySet */ | ||||
| function parse_PropertySet(blob, PIDSI) { | ||||
| @ -151,7 +180,7 @@ function parse_PropertySet(blob, PIDSI) { | ||||
| 		if(PIDSI) { | ||||
| 			var piddsi = PIDSI[Props[i][0]]; | ||||
| 			PropH[piddsi.n] = parse_TypedPropertyValue(blob, piddsi.t, {raw:true}); | ||||
| 			if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + String(PropH[piddsi.n] & 0xFFFF); | ||||
| 			if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + ("0000" + String(PropH[piddsi.n] & 0xFFFF)).slice(-4); | ||||
| 			if(piddsi.n == "CodePage") switch(PropH[piddsi.n]) { | ||||
| 				case 0: PropH[piddsi.n] = 1252; | ||||
| 					/* falls through */ | ||||
| @ -196,8 +225,8 @@ function parse_PropertySet(blob, PIDSI) { | ||||
| 				/* [MS-OSHARED] 2.3.3.2.3.1.2 + PROPVARIANT */ | ||||
| 				switch(blob[blob.l]) { | ||||
| 					case 0x41 /*VT_BLOB*/: blob.l += 4; val = parse_BLOB(blob); break; | ||||
| 					case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break; | ||||
| 					case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break; | ||||
| 					case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break; | ||||
| 					case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break; | ||||
| 					case 0x03 /*VT_I4*/: blob.l += 4; val = blob.read_shift(4, 'i'); break; | ||||
| 					case 0x13 /*VT_UI4*/: blob.l += 4; val = blob.read_shift(4); break; | ||||
| 					case 0x05 /*VT_R8*/: blob.l += 4; val = blob.read_shift(8, 'f'); break; | ||||
| @ -212,6 +241,79 @@ function parse_PropertySet(blob, PIDSI) { | ||||
| 	blob.l = start_addr + size; /* step ahead to skip padding */ | ||||
| 	return PropH; | ||||
| } | ||||
| var XLSPSSkip = [ "CodePage", "Thumbnail", "_PID_LINKBASE", "_PID_HLINKS", "SystemIdentifier", "FMTID" ].concat(PseudoPropsPairs); | ||||
| function guess_property_type(val/*:any*/)/*:number*/ { | ||||
| 	switch(typeof val) { | ||||
| 		case "boolean": return 0x0B; | ||||
| 		case "number": return ((val|0)==val) ? 0x03 : 0x05; | ||||
| 		case "string": return 0x1F; | ||||
| 		case "object": if(val instanceof Date) return 0x40; break; | ||||
| 	} | ||||
| 	return -1; | ||||
| } | ||||
| function write_PropertySet(entries, RE, PIDSI) { | ||||
| 	var hdr = new_buf(8), piao = [], prop = []; | ||||
| 	var sz = 8, i = 0; | ||||
| 
 | ||||
| 	var pr = new_buf(8), pio = new_buf(8); | ||||
| 	pr.write_shift(4, 0x0002); | ||||
| 	pr.write_shift(4, 0x04B0); | ||||
| 	pio.write_shift(4, 0x0001); | ||||
| 	prop.push(pr); piao.push(pio); | ||||
| 	sz += 8 + pr.length; | ||||
| 
 | ||||
| 	if(!RE) { | ||||
| 		pio = new_buf(8); | ||||
| 		pio.write_shift(4, 0); | ||||
| 		piao.unshift(pio); | ||||
| 
 | ||||
| 		var bufs = [new_buf(4)]; | ||||
| 		bufs[0].write_shift(4, entries.length); | ||||
| 		for(i = 0; i < entries.length; ++i) { | ||||
| 			var value = entries[i][0]; | ||||
| 			pr = new_buf(4 + 4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2)); | ||||
| 			pr.write_shift(4, i+2); | ||||
| 			pr.write_shift(4, value.length + 1); | ||||
| 			pr.write_shift(0, value, "dbcs"); | ||||
| 			while(pr.l != pr.length) pr.write_shift(1, 0); | ||||
| 			bufs.push(pr); | ||||
| 		} | ||||
| 		pr = bconcat(bufs); | ||||
| 		prop.unshift(pr); | ||||
| 		sz += 8 + pr.length; | ||||
| 	} | ||||
| 
 | ||||
| 	for(i = 0; i < entries.length; ++i) { | ||||
| 		if(RE && !RE[entries[i][0]]) continue; | ||||
| 		if(XLSPSSkip.indexOf(entries[i][0]) > -1) continue; | ||||
| 		if(entries[i][1] == null) continue; | ||||
| 
 | ||||
| 		var val = entries[i][1], idx = 0; | ||||
| 		if(RE) { | ||||
| 			idx = +RE[entries[i][0]]; | ||||
| 			var pinfo = PIDSI[idx]; | ||||
| 			if(pinfo.p == "version" && typeof val == "string") val = (+((val = val.split("."))[0])<<16) + (+val[1]||0); | ||||
| 			pr = write_TypedPropertyValue(pinfo.t, val); | ||||
| 		} else { | ||||
| 			var T = guess_property_type(val); | ||||
| 			if(T == -1) { T = 0x1F; val = String(val); } | ||||
| 			pr = write_TypedPropertyValue(T, val); | ||||
| 		} | ||||
| 		prop.push(pr); | ||||
| 
 | ||||
| 		pio = new_buf(8); | ||||
| 		pio.write_shift(4, !RE ? 2+i : idx); | ||||
| 		piao.push(pio); | ||||
| 
 | ||||
| 		sz += 8 + pr.length; | ||||
| 	} | ||||
| 
 | ||||
| 	var w = 8 * (prop.length + 1); | ||||
| 	for(i = 0; i < prop.length; ++i) { piao[i].write_shift(4, w); w += prop[i].length; } | ||||
| 	hdr.write_shift(4, sz); | ||||
| 	hdr.write_shift(4, prop.length); | ||||
| 	return bconcat([hdr].concat(piao).concat(prop)); | ||||
| } | ||||
| 
 | ||||
| /* [MS-OLEPS] 2.21 PropertySetStream */ | ||||
| function parse_PropertySetStream(file, PIDSI, clsid) { | ||||
| @ -248,7 +350,27 @@ function parse_PropertySetStream(file, PIDSI, clsid) { | ||||
| 	rval.FMTID = [FMTID0, FMTID1]; // TODO: verify FMTID0/1
 | ||||
| 	return rval; | ||||
| } | ||||
| function write_PropertySetStream(entries, clsid, RE, PIDSI, entries2/*:?any*/, clsid2/*:?any*/) { | ||||
| 	var hdr = new_buf(entries2 ? 68 : 48); | ||||
| 	var bufs = [hdr]; | ||||
| 	hdr.write_shift(2, 0xFFFE); | ||||
| 	hdr.write_shift(2, 0x0000); /* TODO: type 1 props */ | ||||
| 	hdr.write_shift(4, 0x32363237); | ||||
| 	hdr.write_shift(16, CFB.utils.consts.HEADER_CLSID, "hex"); | ||||
| 	hdr.write_shift(4, (entries2 ? 2 : 1)); | ||||
| 	hdr.write_shift(16, clsid, "hex"); | ||||
| 	hdr.write_shift(4, (entries2 ? 68 : 48)); | ||||
| 	var ps0 = write_PropertySet(entries, RE, PIDSI); | ||||
| 	bufs.push(ps0); | ||||
| 
 | ||||
| 	if(entries2) { | ||||
| 		var ps1 = write_PropertySet(entries2, null, null); | ||||
| 		hdr.write_shift(16, clsid2, "hex"); | ||||
| 		hdr.write_shift(4, 68 + ps0.length); | ||||
| 		bufs.push(ps1); | ||||
| 	} | ||||
| 	return bconcat(bufs); | ||||
| } | ||||
| 
 | ||||
| function parsenoop2(blob, length) { blob.read_shift(length); return null; } | ||||
| function writezeroes(n, o) { if(!o) o=new_buf(n); for(var j=0; j<n; ++j) o.write_shift(1, 0); return o; } | ||||
|  | ||||
| @ -330,6 +330,7 @@ var SYLK = (function() { | ||||
| 					formats.push(rstr.slice(3).replace(/;;/g, ";")); | ||||
| 				break; | ||||
| 			case 'C': | ||||
| 			var C_seen_K = false; | ||||
| 			for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) { | ||||
| 				case 'X': C = parseInt(record[rj].slice(1))-1; break; | ||||
| 				case 'Y': | ||||
| @ -347,15 +348,16 @@ var SYLK = (function() { | ||||
| 					} else if(!isNaN(fuzzydate(val).getDate())) { | ||||
| 						val = parseDate(val); | ||||
| 					} | ||||
| 					arr[R][C] = val; | ||||
| 					next_cell_format = null; | ||||
| 					C_seen_K = true; | ||||
| 					break; | ||||
| 				case 'E': | ||||
| 					var formula = rc_to_a1(record[rj].slice(1), {r:R,c:C}); | ||||
| 					arr[R][C] = [arr[R][C], formula]; | ||||
| 					break; | ||||
| 				default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr); | ||||
| 			} break; | ||||
| 			} | ||||
| 			if(C_seen_K) { arr[R][C] = val; next_cell_format = null; } | ||||
| 			break; | ||||
| 			case 'F': | ||||
| 			var F_seen = 0; | ||||
| 			for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) { | ||||
| @ -366,6 +368,7 @@ var SYLK = (function() { | ||||
| 					break; | ||||
| 				case 'M': Mval = parseInt(record[rj].slice(1)) / 20; break; | ||||
| 				case 'F': break; /* ??? */ | ||||
| 				case 'G': break; /* hide grid */ | ||||
| 				case 'P': | ||||
| 					next_cell_format = formats[parseInt(record[rj].slice(1))]; | ||||
| 					break; | ||||
|  | ||||
| @ -2,6 +2,7 @@ | ||||
| function parse_borders(t, styles, themes, opts) { | ||||
| 	styles.Borders = []; | ||||
| 	var border = {}/*, sub_border = {}*/; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x); | ||||
| 		switch (y[0]) { | ||||
| @ -60,7 +61,13 @@ function parse_borders(t, styles, themes, opts) { | ||||
| 			case '<color': case '<color>': break; | ||||
| 			case '<color/>': case '</color>': break; | ||||
| 
 | ||||
| 			default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in borders'); | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in borders'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -69,6 +76,7 @@ function parse_borders(t, styles, themes, opts) { | ||||
| function parse_fills(t, styles, themes, opts) { | ||||
| 	styles.Fills = []; | ||||
| 	var fill = {}; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x); | ||||
| 		switch(y[0]) { | ||||
| @ -119,7 +127,13 @@ function parse_fills(t, styles, themes, opts) { | ||||
| 			case '<color': case '<color/>': break; | ||||
| 			case '</color>': break; | ||||
| 
 | ||||
| 			default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills'); | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in fills'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -128,6 +142,7 @@ function parse_fills(t, styles, themes, opts) { | ||||
| function parse_fonts(t, styles, themes, opts) { | ||||
| 	styles.Fonts = []; | ||||
| 	var font = {}; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x); | ||||
| 		switch (y[0]) { | ||||
| @ -228,7 +243,13 @@ function parse_fonts(t, styles, themes, opts) { | ||||
| 				break; | ||||
| 			case '<color/>': case '</color>': break; | ||||
| 
 | ||||
| 			default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fonts'); | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in fonts'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -278,6 +299,7 @@ var cellXF_bool = [ "applyAlignment", "applyBorder", "applyFill", "applyFont", " | ||||
| function parse_cellXfs(t, styles, opts) { | ||||
| 	styles.CellXf = []; | ||||
| 	var xf; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x), i = 0; | ||||
| 		switch(y[0]) { | ||||
| @ -313,9 +335,12 @@ function parse_cellXfs(t, styles, opts) { | ||||
| 			case '<protection': case '</protection>': case '<protection/>': break; | ||||
| 
 | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '</extLst>': break; | ||||
| 			case '<ext': break; | ||||
| 			default: if(opts.WTF) throw new Error('unrecognized ' + y[0] + ' in cellXfs'); | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in cellXfs'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
|  | ||||
| @ -284,6 +284,7 @@ function parse_SerAr(blob, biff/*:number*/) { | ||||
| 		case 0x04: /* SerBool -- boolean */ | ||||
| 			val[1] = parsebool(blob, 1) ? 'TRUE' : 'FALSE'; | ||||
| 			if(biff != 12) blob.l += 7; break; | ||||
| 		case 0x25: /* appears to be an alias */ | ||||
| 		case 0x10: /* SerErr -- error */ | ||||
| 			val[1] = BErr[blob[blob.l]]; | ||||
| 			blob.l += ((biff == 12) ? 4 : 8); break; | ||||
| @ -293,7 +294,7 @@ function parse_SerAr(blob, biff/*:number*/) { | ||||
| 			val[1] = parse_Xnum(blob, 8); break; | ||||
| 		case 0x02: /* SerStr -- XLUnicodeString (<256 chars) */ | ||||
| 			val[1] = parse_XLUnicodeString2(blob, 0, {biff:biff > 0 && biff < 8 ? 2 : biff}); break; | ||||
| 		default: throw "Bad SerAr: " + val[0]; /* Unreachable */ | ||||
| 		default: throw new Error("Bad SerAr: " + val[0]); /* Unreachable */ | ||||
| 	} | ||||
| 	return val; | ||||
| } | ||||
|  | ||||
| @ -842,21 +842,51 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 	return wb; | ||||
| } | ||||
| 
 | ||||
| /* TODO: WTF */ | ||||
| function parse_props(cfb/*:CFBContainer*/, props, o) { | ||||
| /* TODO: split props*/ | ||||
| var PSCLSID = { | ||||
| 	SI: "e0859ff2f94f6810ab9108002b27b3d9", | ||||
| 	DSI: "02d5cdd59c2e1b10939708002b2cf9ae", | ||||
| 	UDI: "05d5cdd59c2e1b10939708002b2cf9ae" | ||||
| }; | ||||
| function parse_xls_props(cfb/*:CFBContainer*/, props, o) { | ||||
| 	/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */ | ||||
| 	var DSI = CFB.find(cfb, '!DocumentSummaryInformation'); | ||||
| 	if(DSI && DSI.size > 0) try { | ||||
| 		var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, "02d5cdd59c2e1b10939708002b2cf9ae"); | ||||
| 		var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, PSCLSID.DSI); | ||||
| 		for(var d in DocSummary) props[d] = DocSummary[d]; | ||||
| 	} catch(e) {if(o.WTF) throw e;/* empty */} | ||||
| 
 | ||||
| 	/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/ | ||||
| 	var SI = CFB.find(cfb, '!SummaryInformation'); | ||||
| 	if(SI && SI.size > 0) try { | ||||
| 		var Summary = parse_PropertySetStream(SI, SummaryPIDSI, "e0859ff2f94f6810ab9108002b27b3d9"); | ||||
| 		var Summary = parse_PropertySetStream(SI, SummaryPIDSI, PSCLSID.SI); | ||||
| 		for(var s in Summary) if(props[s] == null) props[s] = Summary[s]; | ||||
| 	} catch(e) {if(o.WTF) throw e;/* empty */} | ||||
| 
 | ||||
| 	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); | ||||
| 		for(i = 0; i < Keys.length; ++i) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Props[Keys[i]]]); | ||||
| 	} | ||||
| 	if(wb.Custprops) { | ||||
| 		Keys = keys(wb.Custprops); | ||||
| 		for(i = 0; i < Keys.length; ++i) if(!wb.Props.hasOwnProperty(Keys[i])) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Custprops[Keys[i]]]); | ||||
| 	} | ||||
| 	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)); | ||||
| } | ||||
| 
 | ||||
| function parse_xlscfb(cfb/*:any*/, options/*:?ParseOpts*/)/*:Workbook*/ { | ||||
| @ -896,7 +926,7 @@ else/*:: if(cfb instanceof CFBContainer) */ { | ||||
| } | ||||
| 
 | ||||
| var props = {}; | ||||
| if(cfb.FullPaths) parse_props(/*::((*/cfb/*:: :any):CFBContainer)*/, props, options); | ||||
| if(cfb.FullPaths) parse_xls_props(/*::((*/cfb/*:: :any):CFBContainer)*/, props, options); | ||||
| 
 | ||||
| WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */ | ||||
| if(options.bookFiles) WorkbookP.cfb = cfb; | ||||
| @ -919,6 +949,7 @@ function write_xlscfb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:CFBContainer*/ { | ||||
| 		default: throw new Error("invalid type " + o.bookType + " for XLS CFB"); | ||||
| 	} | ||||
| 	CFB.utils.cfb_add(cfb, wbpath, write_biff_buf(wb, o)); | ||||
| 	if(o.biff == 8 && (wb.Props || wb.Custprops)) write_xls_props(wb, cfb); | ||||
| 	// TODO: SI, DSI, CO
 | ||||
| 	if(o.biff == 8 && wb.vbaraw) fill_vba_xls(cfb, CFB.read(wb.vbaraw, {type: typeof wb.vbaraw == "string" ? "binary" : "buffer"})); | ||||
| 	return cfb; | ||||
|  | ||||
| @ -120,7 +120,7 @@ function write_FEAT(ba, ws) { | ||||
| 	o.write_shift(4, 0x868); o.write_shift(4, 0); o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 3); o.write_shift(1, 0); o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 1); o.write_shift(4, 4); o.write_shift(2, 0); | ||||
| 	write_Ref8U(safe_decode_range(ws['!ref']), o); | ||||
| 	write_Ref8U(safe_decode_range(ws['!ref']||"A1"), o); | ||||
| 	o.write_shift(4, 4); | ||||
| 	write_biff_rec(ba, "Feat", o); | ||||
| } | ||||
|  | ||||
| @ -16,11 +16,11 @@ var HTML_ = (function() { | ||||
| 			var row = rows[i].trim(); | ||||
| 			var hd = row.slice(0,3).toLowerCase(); | ||||
| 			if(hd == "<tr") { ++R; if(opts.sheetRows && opts.sheetRows <= R) { --R; break; } C = 0; continue; } | ||||
| 			if(hd != "<td") continue; | ||||
| 			var cells = row.split(/<\/td>/i); | ||||
| 			if(hd != "<td" && hd != "<th") continue; | ||||
| 			var cells = row.split(/<\/t[dh]>/i); | ||||
| 			for(j = 0; j < cells.length; ++j) { | ||||
| 				var cell = cells[j].trim(); | ||||
| 				if(cell.slice(0,3).toLowerCase() != "<td") continue; | ||||
| 				if(!cell.match(/<t[dh]/i)) continue; | ||||
| 				var m = cell, cc = 0; | ||||
| 				/* TODO: parse styles etc */ | ||||
| 				while(m.charAt(0) == "<" && (cc = m.indexOf(">")) > -1) m = m.slice(cc+1); | ||||
| @ -155,7 +155,7 @@ function parse_dom_table(table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ { | ||||
| 			C += CS; | ||||
| 		} | ||||
| 	} | ||||
| 	ws['!merges'] = merges; | ||||
| 	if(merges.length) ws['!merges'] = merges; | ||||
| 	ws['!ref'] = encode_range(range); | ||||
| 	if(sheetRows < rows.length) ws['!fullref'] = encode_range((range.e.r = rows.length-1,range)); | ||||
| 	return ws; | ||||
|  | ||||
| @ -70,7 +70,7 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ { | ||||
| 	var styles = ({}/*:any*/); | ||||
| 	if(!opts.bookSheets && !opts.bookProps) { | ||||
| 		strs = []; | ||||
| 		if(dir.sst) strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts); | ||||
| 		if(dir.sst) try { strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts); } catch(e) { if(opts.WTF) throw e; } | ||||
| 
 | ||||
| 		if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipstr(zip, dir.themes[0].replace(/^\//,''), true)||"",dir.themes[0], opts); | ||||
| 
 | ||||
|  | ||||
| @ -38,7 +38,7 @@ function write_string_type(out/*:string*/, opts/*:WriteOpts*/, bom/*:?string*/)/ | ||||
| 		case "string": return out; | ||||
| 		case "file": return write_dl(opts.file, o, 'utf8'); | ||||
| 		case "buffer": { | ||||
| 			if(has_buf) return new Buffer(o, 'utf8'); | ||||
| 			if(has_buf) return Buffer.from(o, 'utf8'); | ||||
| 			else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); }); | ||||
| 		} | ||||
| 	} | ||||
| @ -52,7 +52,7 @@ function write_stxt_type(out/*:string*/, opts/*:WriteOpts*/)/*:any*/ { | ||||
| 		case "string": return out; /* override in sheet_to_txt */ | ||||
| 		case "file": return write_dl(opts.file, out, 'binary'); | ||||
| 		case "buffer": { | ||||
| 			if(has_buf) return new Buffer(out, 'binary'); | ||||
| 			if(has_buf) return Buffer.from(out, 'binary'); | ||||
| 			else return out.split("").map(function(c) { return c.charCodeAt(0); }); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										41
									
								
								dist/cpexcel.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										41
									
								
								dist/cpexcel.js
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -1,6 +1,6 @@ | ||||
| /* cpexcel.js (C) 2013-present SheetJS -- http://sheetjs.com */ | ||||
| /*jshint -W100 */ | ||||
| var cptable = {version:"1.12.0"}; | ||||
| var cptable = {version:"1.13.0"}; | ||||
| cptable[437] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })(); | ||||
| cptable[620] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàąçêëèïîćÄĄĘęłôöĆûùŚÖܢ٥śƒŹŻóÓńŃźż¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })(); | ||||
| cptable[737] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })(); | ||||
| @ -1018,9 +1018,14 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE | ||||
| 
 | ||||
|   var has_buf = (typeof Buffer !== 'undefined'); | ||||
|   if(has_buf) { | ||||
|     var mdl = 1024, mdb = new Buffer(mdl); | ||||
|     // $FlowIgnore
 | ||||
|     if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); }; | ||||
|     // $FlowIgnore
 | ||||
|     if(!Buffer.allocUnsafe) Buffer.allocUnsafe = function(n) { return new Buffer(n); }; | ||||
| 
 | ||||
|     var mdl = 1024, mdb = Buffer.allocUnsafe(mdl); | ||||
|     var make_EE = function make_EE(E){ | ||||
|       var EE = new Buffer(65536); | ||||
|       var EE = Buffer.allocUnsafe(65536); | ||||
|       for(var i = 0; i < 65536;++i) EE[i] = 0; | ||||
|       var keys = Object.keys(E), len = keys.length; | ||||
|       for(var ee = 0, e = keys[ee]; ee < len; ++ee) { | ||||
| @ -1035,10 +1040,10 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE | ||||
|         var len = data.length; | ||||
|         var out, i=0, j=0, D=0, w=0; | ||||
|         if(typeof data === 'string') { | ||||
|           out = new Buffer(len); | ||||
|           out = Buffer.allocUnsafe(len); | ||||
|           for(i = 0; i < len; ++i) out[i] = EE[data.charCodeAt(i)]; | ||||
|         } else if(Buffer.isBuffer(data)) { | ||||
|           out = new Buffer(2*len); | ||||
|           out = Buffer.allocUnsafe(2*len); | ||||
|           j = 0; | ||||
|           for(i = 0; i < len; ++i) { | ||||
|             D = data[i]; | ||||
| @ -1053,7 +1058,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE | ||||
|           } | ||||
|           out = out.slice(0,j); | ||||
|         } else { | ||||
|           out = new Buffer(len); | ||||
|           out = Buffer.allocUnsafe(len); | ||||
|           for(i = 0; i < len; ++i) out[i] = EE[data[i].charCodeAt(0)]; | ||||
|         } | ||||
|         if(!ofmt || ofmt === 'buf') return out; | ||||
| @ -1063,7 +1068,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE | ||||
|     }; | ||||
|     var sbcs_decode = function make_sbcs_decode(cp) { | ||||
|       var D = cpt[cp].dec; | ||||
|       var DD = new Buffer(131072), d=0, c=""; | ||||
|       var DD = Buffer.allocUnsafe(131072), d=0, c=""; | ||||
|       for(d=0;d<D.length;++d) { | ||||
|         if(!(c=D[d])) continue; | ||||
|         var w = c.charCodeAt(0); | ||||
| @ -1071,7 +1076,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE | ||||
|       } | ||||
|       return function sbcs_d(data) { | ||||
|         var len = data.length, i=0, j=0; | ||||
|         if(2 * len > mdl) { mdl = 2 * len; mdb = new Buffer(mdl); } | ||||
|         if(2 * len > mdl) { mdl = 2 * len; mdb = Buffer.allocUnsafe(mdl); } | ||||
|         if(Buffer.isBuffer(data)) { | ||||
|           for(i = 0; i < len; i++) { | ||||
|             j = 2*data[i]; | ||||
| @ -1093,7 +1098,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE | ||||
|     }; | ||||
|     var dbcs_encode = function make_dbcs_encode(cp) { | ||||
|       var E = cpt[cp].enc; | ||||
|       var EE = new Buffer(131072); | ||||
|       var EE = Buffer.allocUnsafe(131072); | ||||
|       for(var i = 0; i < 131072; ++i) EE[i] = 0; | ||||
|       var keys = Object.keys(E); | ||||
|       for(var ee = 0, e = keys[ee]; ee < keys.length; ++ee) { | ||||
| @ -1102,7 +1107,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE | ||||
|         EE[2*f] = E[e] & 255; EE[2*f+1] = E[e]>>8; | ||||
|       } | ||||
|       return function dbcs_e(data, ofmt) { | ||||
|         var len = data.length, out = new Buffer(2*len), i=0, j=0, jj=0, k=0, D=0; | ||||
|         var len = data.length, out = Buffer.allocUnsafe(2*len), i=0, j=0, jj=0, k=0, D=0; | ||||
|         if(typeof data === 'string') { | ||||
|           for(i = k = 0; i < len; ++i) { | ||||
|             j = data.charCodeAt(i)*2; | ||||
| @ -1136,7 +1141,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE | ||||
|     }; | ||||
|     var dbcs_decode = function make_dbcs_decode(cp) { | ||||
|       var D = cpt[cp].dec; | ||||
|       var DD = new Buffer(131072), d=0, c, w=0, j=0, i=0; | ||||
|       var DD = Buffer.allocUnsafe(131072), d=0, c, w=0, j=0, i=0; | ||||
|       for(i = 0; i < 65536; ++i) { DD[2*i] = 0xFF; DD[2*i+1] = 0xFD;} | ||||
|       for(d = 0; d < D.length; ++d) { | ||||
|         if(!(c=D[d])) continue; | ||||
| @ -1145,7 +1150,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE | ||||
|         DD[j] = w&255; DD[j+1] = w>>8; | ||||
|       } | ||||
|       return function dbcs_d(data) { | ||||
|         var len = data.length, out = new Buffer(2*len), i=0, j=0, k=0; | ||||
|         var len = data.length, out = Buffer.allocUnsafe(2*len), i=0, j=0, k=0; | ||||
|         if(Buffer.isBuffer(data)) { | ||||
|           for(i = 0; i < len; i++) { | ||||
|             j = 2*data[i]; | ||||
| @ -1171,7 +1176,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE | ||||
|     magic_decode[65001] = function utf8_d(data) { | ||||
|       if(typeof data === "string") return utf8_d(data.split("").map(cca)); | ||||
|       var len = data.length, w = 0, ww = 0; | ||||
|       if(4 * len > mdl) { mdl = 4 * len; mdb = new Buffer(mdl); } | ||||
|       if(4 * len > mdl) { mdl = 4 * len; mdb = Buffer.allocUnsafe(mdl); } | ||||
|       var i = 0; | ||||
|       if(len >= 3 && data[0] == 0xEF) if(data[1] == 0xBB && data[2] == 0xBF) i = 3; | ||||
|       for(var j = 1, k = 0, D = 0; i < len; i+=j) { | ||||
| @ -1196,7 +1201,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE | ||||
|       } | ||||
|       var len = data.length, w = 0, ww = 0, j = 0; | ||||
|       var direct = typeof data === "string"; | ||||
|       if(4 * len > mdl) { mdl = 4 * len; mdb = new Buffer(mdl); } | ||||
|       if(4 * len > mdl) { mdl = 4 * len; mdb = Buffer.allocUnsafe(mdl); } | ||||
|       for(var i = 0; i < len; ++i) { | ||||
|         w = direct ? data.charCodeAt(i) : data[i].charCodeAt(0); | ||||
|         if(w <= 0x007F) mdb[j++] = w; | ||||
| @ -1275,7 +1280,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE | ||||
|     if(cpecache[cp]) { last_enc = cpecache[last_cp=cp]; return last_enc(data, ofmt); } | ||||
|     if(has_buf && Buffer.isBuffer(data)) data = data.toString('utf8'); | ||||
|     var len = data.length; | ||||
|     var out = has_buf ? new Buffer(4*len) : [], w=0, i=0, j = 0, ww=0; | ||||
|     var out = has_buf ? Buffer.allocUnsafe(4*len) : [], w=0, i=0, j = 0, ww=0; | ||||
|     var C = cpt[cp], E, M = ""; | ||||
|     var isstr = typeof data === 'string'; | ||||
|     if(C && (E=C.enc)) for(i = 0; i < len; ++i, ++j) { | ||||
| @ -1287,7 +1292,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE | ||||
|     } | ||||
|     else if((M=magic[cp])) switch(M) { | ||||
|       case "utf8": | ||||
|         if(has_buf && isstr) { out = new Buffer(data, M); j = out.length; break; } | ||||
|         if(has_buf && isstr) { out = Buffer.from(data, M); j = out.length; break; } | ||||
|         for(i = 0; i < len; ++i, ++j) { | ||||
|           w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0); | ||||
|           if(w <= 0x007F) out[j] = w; | ||||
| @ -1309,7 +1314,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE | ||||
|         } | ||||
|         break; | ||||
|       case "ascii": | ||||
|         if(has_buf && typeof data === "string") { out = new Buffer(data, M); j = out.length; break; } | ||||
|         if(has_buf && typeof data === "string") { out = Buffer.from(data, M); j = out.length; break; } | ||||
|         for(i = 0; i < len; ++i, ++j) { | ||||
|           w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0); | ||||
|           if(w <= 0x007F) out[j] = w; | ||||
| @ -1317,7 +1322,7 @@ if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODE | ||||
|         } | ||||
|         break; | ||||
|       case "utf16le": | ||||
|         if(has_buf && typeof data === "string") { out = new Buffer(data, M); j = out.length; break; } | ||||
|         if(has_buf && typeof data === "string") { out = Buffer.from(data, M); j = out.length; break; } | ||||
|         for(i = 0; i < len; ++i) { | ||||
|           w = isstr ? data.charCodeAt(i) : data[i].charCodeAt(0); | ||||
|           out[j++] = w&255; | ||||
|  | ||||
							
								
								
									
										8
									
								
								dist/jszip.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										8
									
								
								dist/jszip.js
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -600,8 +600,14 @@ module.exports = function(data, options) { | ||||
| },{"./base64":1,"./zipEntries":22}],11:[function(_dereq_,module,exports){ | ||||
| (function (Buffer){ | ||||
| 'use strict'; | ||||
| if(typeof Buffer !== 'undefined') { | ||||
| 	// $FlowIgnore
 | ||||
| 	if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); }; | ||||
| 	// $FlowIgnore
 | ||||
| 	if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); }; | ||||
| } | ||||
| module.exports = function(data, encoding){ | ||||
|     return new Buffer(data, encoding); | ||||
|     return typeof data == 'number' ? Buffer.alloc(data) : Buffer.from(data, encoding); | ||||
| }; | ||||
| module.exports.test = function(b){ | ||||
|     return Buffer.isBuffer(b); | ||||
|  | ||||
							
								
								
									
										30
									
								
								dist/xlsx.core.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										30
									
								
								dist/xlsx.core.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.core.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.core.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										385
									
								
								dist/xlsx.extendscript.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										385
									
								
								dist/xlsx.extendscript.js
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -752,8 +752,14 @@ module.exports = function(data, options) { | ||||
| },{"./base64":1,"./zipEntries":22}],11:[function(_dereq_,module,exports){ | ||||
| (function (Buffer){ | ||||
| 'use strict'; | ||||
| if(typeof Buffer !== 'undefined') { | ||||
| 	// $FlowIgnore
 | ||||
| 	if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); }; | ||||
| 	// $FlowIgnore
 | ||||
| 	if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); }; | ||||
| } | ||||
| module.exports = function(data, encoding){ | ||||
|     return new Buffer(data, encoding); | ||||
|     return typeof data == 'number' ? Buffer.alloc(data) : Buffer.from(data, encoding); | ||||
| }; | ||||
| module.exports.test = function(b){ | ||||
|     return Buffer.isBuffer(b); | ||||
| @ -9147,11 +9153,14 @@ module.exports = ZStream; | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */ | ||||
| var XLSX = {}; | ||||
| (function make_xlsx(XLSX){ | ||||
| XLSX.version = '0.12.11'; | ||||
| XLSX.version = '0.12.12'; | ||||
| var current_codepage = 1200, current_ansi = 1252; | ||||
| /*global cptable:true */ | ||||
| /*global cptable:true, window */ | ||||
| if(typeof module !== "undefined" && typeof require !== 'undefined') { | ||||
| 	if(typeof cptable === 'undefined') global.cptable = undefined; | ||||
| 	if(typeof cptable === 'undefined') { | ||||
| 		if(typeof global !== 'undefined') global.cptable = undefined; | ||||
| 		else if(typeof window !== 'undefined') window.cptable = undefined; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| var VALID_ANSI = [ 874, 932, 936, 949, 950 ]; | ||||
| @ -9267,17 +9276,23 @@ var Base64 = (function make_b64(){ | ||||
| })(); | ||||
| var has_buf = (typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && process.versions.node); | ||||
| 
 | ||||
| if(typeof Buffer !== 'undefined') { | ||||
| 	// $FlowIgnore
 | ||||
| 	if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); }; | ||||
| 	// $FlowIgnore
 | ||||
| 	if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); }; | ||||
| } | ||||
| 
 | ||||
| function new_raw_buf(len) { | ||||
| 	/* jshint -W056 */ | ||||
| 	// $FlowIgnore
 | ||||
| 	return new (has_buf ? Buffer : Array)(len); | ||||
| 	return has_buf ? Buffer.alloc(len) : new Array(len); | ||||
| 	/* jshint +W056 */ | ||||
| } | ||||
| 
 | ||||
| function s2a(s) { | ||||
| 	if(has_buf) return new Buffer(s, "binary"); | ||||
| var s2a = function s2a(s) { | ||||
| 	if(has_buf) return Buffer.from(s, "binary"); | ||||
| 	return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; }); | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| function s2ab(s) { | ||||
| 	if(typeof ArrayBuffer === 'undefined') return s2a(s); | ||||
| @ -10267,7 +10282,7 @@ var DO_NOT_EXPORT_CFB = true; | ||||
| /* [MS-CFB] v20171201 */ | ||||
| var CFB = (function _CFB(){ | ||||
| var exports = {}; | ||||
| exports.version = '1.0.6'; | ||||
| exports.version = '1.0.7'; | ||||
| /* [MS-CFB] 2.6.4 */ | ||||
| function namecmp(l, r) { | ||||
| 	var L = l.split("/"), R = r.split("/"); | ||||
| @ -11390,7 +11405,7 @@ var utf8write = function(orig) { | ||||
| 
 | ||||
| if(has_buf) { | ||||
| 	var utf8readb = function utf8readb(data) { | ||||
| 		var out = new Buffer(2*data.length), w, i, j = 1, k = 0, ww=0, c; | ||||
| 		var out = Buffer.alloc(2*data.length), w, i, j = 1, k = 0, ww=0, c; | ||||
| 		for(i = 0; i < data.length; i+=j) { | ||||
| 			j = 1; | ||||
| 			if((c=data.charCodeAt(i)) < 128) w = c; | ||||
| @ -11408,10 +11423,10 @@ if(has_buf) { | ||||
| 	var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3"; | ||||
| 	if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb; | ||||
| 	// $FlowIgnore
 | ||||
| 	var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); }; | ||||
| 	var utf8readc = function utf8readc(data) { return Buffer.from(data, 'binary').toString('utf8'); }; | ||||
| 	if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc; | ||||
| 
 | ||||
| 	utf8write = function(data) { return new Buffer(data, 'utf8').toString("binary"); }; | ||||
| 	utf8write = function(data) { return Buffer.from(data, 'utf8').toString("binary"); }; | ||||
| } | ||||
| 
 | ||||
| // matches <foo>...</foo> extracts content
 | ||||
| @ -12350,15 +12365,15 @@ var DocSummaryPIDDSI = { | ||||
| 0x08: { n: 'NoteCount', t: VT_I4 }, | ||||
| 0x09: { n: 'HiddenCount', t: VT_I4 }, | ||||
| 0x0a: { n: 'MultimediaClipCount', t: VT_I4 }, | ||||
| 0x0b: { n: 'Scale', t: VT_BOOL }, | ||||
| 0x0c: { n: 'HeadingPair', t: VT_VECTOR | VT_VARIANT }, | ||||
| 0x0d: { n: 'DocParts', t: VT_VECTOR | VT_LPSTR }, | ||||
| 0x0b: { n: 'ScaleCrop', t: VT_BOOL }, | ||||
| 0x0c: { n: 'HeadingPairs', t: VT_VECTOR | VT_VARIANT }, | ||||
| 0x0d: { n: 'TitlesOfParts', t: VT_VECTOR | VT_LPSTR }, | ||||
| 0x0e: { n: 'Manager', t: VT_STRING }, | ||||
| 0x0f: { n: 'Company', t: VT_STRING }, | ||||
| 0x10: { n: 'LinksDirty', t: VT_BOOL }, | ||||
| 0x10: { n: 'LinksUpToDate', t: VT_BOOL }, | ||||
| 0x11: { n: 'CharacterCount', t: VT_I4 }, | ||||
| 0x13: { n: 'SharedDoc', t: VT_BOOL }, | ||||
| 0x16: { n: 'HLinksChanged', t: VT_BOOL }, | ||||
| 0x16: { n: 'HyperlinksChanged', t: VT_BOOL }, | ||||
| 0x17: { n: 'AppVersion', t: VT_I4, p: 'version' }, | ||||
| 0x18: { n: 'DigSig', t: VT_BLOB }, | ||||
| 0x1A: { n: 'ContentType', t: VT_STRING }, | ||||
| @ -12387,8 +12402,8 @@ var SummaryPIDSI = { | ||||
| 0x0F: { n: 'WordCount', t: VT_I4 }, | ||||
| 0x10: { n: 'CharCount', t: VT_I4 }, | ||||
| 0x11: { n: 'Thumbnail', t: VT_CF }, | ||||
| 0x12: { n: 'ApplicationName', t: VT_STRING }, | ||||
| 0x13: { n: 'DocumentSecurity', t: VT_I4 }, | ||||
| 0x12: { n: 'Application', t: VT_STRING }, | ||||
| 0x13: { n: 'DocSecurity', t: VT_I4 }, | ||||
| 0xFF: {} | ||||
| }; | ||||
| 
 | ||||
| @ -12404,6 +12419,9 @@ var SpecialProperties = { | ||||
| 	DocSummaryPIDDSI[y] = SummaryPIDSI[y] = SpecialProperties[y]; | ||||
| })(); | ||||
| 
 | ||||
| var DocSummaryRE = evert_key(DocSummaryPIDDSI, "n"); | ||||
| var SummaryRE = evert_key(SummaryPIDSI, "n"); | ||||
| 
 | ||||
| /* [MS-XLS] 2.4.63 Country/Region codes */ | ||||
| var CountryEnum = { | ||||
| 0x0001: "US", // United States
 | ||||
| @ -13100,6 +13118,56 @@ var EXT_PROPS = [ | ||||
| XMLNS.EXT_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"; | ||||
| RELS.EXT_PROPS  = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties'; | ||||
| 
 | ||||
| var PseudoPropsPairs = [ | ||||
| 	"Worksheets",  "SheetNames", | ||||
| 	"NamedRanges", "DefinedNames", | ||||
| 	"Chartsheets", "ChartNames" | ||||
| ]; | ||||
| function load_props_pairs(HP, TOP, props, opts) { | ||||
| 	var v = []; | ||||
| 	if(typeof HP == "string") v = parseVector(HP, opts); | ||||
| 	else for(var j = 0; j < HP.length; ++j) v = v.concat(HP[j].map(function(hp) { return {v:hp}; })); | ||||
| 	var parts = (typeof TOP == "string") ? parseVector(TOP, opts).map(function (x) { return x.v; }) : TOP; | ||||
| 	var idx = 0, len = 0; | ||||
| 	if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) { | ||||
| 		len = +(v[i+1].v); | ||||
| 		switch(v[i].v) { | ||||
| 			case "Worksheets": | ||||
| 			case "工作表": | ||||
| 			case "Листы": | ||||
| 			case "أوراق العمل": | ||||
| 			case "ワークシート": | ||||
| 			case "גליונות עבודה": | ||||
| 			case "Arbeitsblätter": | ||||
| 			case "Çalışma Sayfaları": | ||||
| 			case "Feuilles de calcul": | ||||
| 			case "Fogli di lavoro": | ||||
| 			case "Folhas de cálculo": | ||||
| 			case "Planilhas": | ||||
| 			case "Regneark": | ||||
| 			case "Werkbladen": | ||||
| 				props.Worksheets = len; | ||||
| 				props.SheetNames = parts.slice(idx, idx + len); | ||||
| 				break; | ||||
| 
 | ||||
| 			case "Named Ranges": | ||||
| 			case "名前付き一覧": | ||||
| 			case "Benannte Bereiche": | ||||
| 			case "Navngivne områder": | ||||
| 				props.NamedRanges = len; | ||||
| 				props.DefinedNames = parts.slice(idx, idx + len); | ||||
| 				break; | ||||
| 
 | ||||
| 			case "Charts": | ||||
| 			case "Diagramme": | ||||
| 				props.Chartsheets = len; | ||||
| 				props.ChartNames = parts.slice(idx, idx + len); | ||||
| 				break; | ||||
| 		} | ||||
| 		idx += len; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function parse_ext_props(data, p, opts) { | ||||
| 	var q = {}; if(!p) p = {}; | ||||
| 	data = utf8read(data); | ||||
| @ -13115,48 +13183,7 @@ function parse_ext_props(data, p, opts) { | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	if(q.HeadingPairs && q.TitlesOfParts) { | ||||
| 		var v = parseVector(q.HeadingPairs, opts); | ||||
| 		var parts = parseVector(q.TitlesOfParts, opts).map(function (x) { return x.v; }); | ||||
| 		var idx = 0, len = 0; | ||||
| 		if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) { | ||||
| 			len = +(v[i+1].v); | ||||
| 			switch(v[i].v) { | ||||
| 				case "Worksheets": | ||||
| 				case "工作表": | ||||
| 				case "Листы": | ||||
| 				case "أوراق العمل": | ||||
| 				case "ワークシート": | ||||
| 				case "גליונות עבודה": | ||||
| 				case "Arbeitsblätter": | ||||
| 				case "Çalışma Sayfaları": | ||||
| 				case "Feuilles de calcul": | ||||
| 				case "Fogli di lavoro": | ||||
| 				case "Folhas de cálculo": | ||||
| 				case "Planilhas": | ||||
| 				case "Regneark": | ||||
| 				case "Werkbladen": | ||||
| 					p.Worksheets = len; | ||||
| 					p.SheetNames = parts.slice(idx, idx + len); | ||||
| 					break; | ||||
| 
 | ||||
| 				case "Named Ranges": | ||||
| 				case "名前付き一覧": | ||||
| 				case "Benannte Bereiche": | ||||
| 				case "Navngivne områder": | ||||
| 					p.NamedRanges = len; | ||||
| 					p.DefinedNames = parts.slice(idx, idx + len); | ||||
| 					break; | ||||
| 
 | ||||
| 				case "Charts": | ||||
| 				case "Diagramme": | ||||
| 					p.Chartsheets = len; | ||||
| 					p.ChartNames = parts.slice(idx, idx + len); | ||||
| 					break; | ||||
| 			} | ||||
| 			idx += len; | ||||
| 		} | ||||
| 	} | ||||
| 	if(q.HeadingPairs && q.TitlesOfParts) load_props_pairs(q.HeadingPairs, q.TitlesOfParts, p, opts); | ||||
| 
 | ||||
| 	return p; | ||||
| } | ||||
| @ -13353,6 +13380,15 @@ function parse_FILETIME(blob) { | ||||
| 	var dwLowDateTime = blob.read_shift(4), dwHighDateTime = blob.read_shift(4); | ||||
| 	return new Date(((dwHighDateTime/1e7*Math.pow(2,32) + dwLowDateTime/1e7) - 11644473600)*1000).toISOString().replace(/\.000/,""); | ||||
| } | ||||
| function write_FILETIME(time) { | ||||
| 	var date = (typeof time == "string") ? new Date(Date.parse(time)) : time; | ||||
| 	var t = date.getTime() / 1000 + 11644473600; | ||||
| 	var l = t % Math.pow(2,32), h = (t - l) / Math.pow(2,32); | ||||
| 	l *= 1e7; h *= 1e7; | ||||
| 	var w = (l / Math.pow(2,32)) | 0; | ||||
| 	if(w > 0) { l = l % Math.pow(2,32); h += w; } | ||||
| 	var o = new_buf(8); o.write_shift(4, l); o.write_shift(4, h); return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-OSHARED] 2.3.3.1.4 Lpstr */ | ||||
| function parse_lpstr(blob, type, pad) { | ||||
| @ -13422,6 +13458,7 @@ function parse_dictionary(blob,CodePage) { | ||||
| 		var pid = blob.read_shift(4); | ||||
| 		var len = blob.read_shift(4); | ||||
| 		dict[pid] = blob.read_shift(len, (CodePage === 0x4B0 ?'utf16le':'utf8')).replace(chr0,'').replace(chr1,'!'); | ||||
| 		if(CodePage === 0x4B0 && (len % 2)) blob.l += 2; | ||||
| 	} | ||||
| 	if(blob.l & 3) blob.l = (blob.l>>2+1)<<2; | ||||
| 	return dict; | ||||
| @ -13469,6 +13506,25 @@ function parse_TypedPropertyValue(blob, type, _opts) { | ||||
| 		default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + t); | ||||
| 	} | ||||
| } | ||||
| function write_TypedPropertyValue(type, value) { | ||||
| 	var o = new_buf(4), p = new_buf(4); | ||||
| 	o.write_shift(4, type == 0x50 ? 0x1F : type); | ||||
| 	switch(type) { | ||||
| 		case 0x03 /*VT_I4*/: p.write_shift(-4, value); break; | ||||
| 		case 0x05 /*VT_I4*/: p = new_buf(8); p.write_shift(8, value, 'f'); break; | ||||
| 		case 0x0B /*VT_BOOL*/: p.write_shift(4, value ? 0x01 : 0x00); break; | ||||
| 		case 0x40 /*VT_FILETIME*/: p = write_FILETIME(value); break; | ||||
| 		case 0x1F /*VT_LPWSTR*/: | ||||
| 		case 0x50 /*VT_STRING*/: | ||||
| 			p = new_buf(4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2)); | ||||
| 			p.write_shift(4, value.length + 1); | ||||
| 			p.write_shift(0, value, "dbcs"); | ||||
| 			while(p.l != p.length) p.write_shift(1, 0); | ||||
| 			break; | ||||
| 		default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + value); | ||||
| 	} | ||||
| 	return bconcat([o, p]); | ||||
| } | ||||
| 
 | ||||
| /* [MS-OLEPS] 2.20 PropertySet */ | ||||
| function parse_PropertySet(blob, PIDSI) { | ||||
| @ -13499,7 +13555,7 @@ function parse_PropertySet(blob, PIDSI) { | ||||
| 		if(PIDSI) { | ||||
| 			var piddsi = PIDSI[Props[i][0]]; | ||||
| 			PropH[piddsi.n] = parse_TypedPropertyValue(blob, piddsi.t, {raw:true}); | ||||
| 			if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + String(PropH[piddsi.n] & 0xFFFF); | ||||
| 			if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + ("0000" + String(PropH[piddsi.n] & 0xFFFF)).slice(-4); | ||||
| 			if(piddsi.n == "CodePage") switch(PropH[piddsi.n]) { | ||||
| 				case 0: PropH[piddsi.n] = 1252; | ||||
| 					/* falls through */ | ||||
| @ -13544,8 +13600,8 @@ function parse_PropertySet(blob, PIDSI) { | ||||
| 				/* [MS-OSHARED] 2.3.3.2.3.1.2 + PROPVARIANT */ | ||||
| 				switch(blob[blob.l]) { | ||||
| 					case 0x41 /*VT_BLOB*/: blob.l += 4; val = parse_BLOB(blob); break; | ||||
| 					case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break; | ||||
| 					case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break; | ||||
| 					case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break; | ||||
| 					case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break; | ||||
| 					case 0x03 /*VT_I4*/: blob.l += 4; val = blob.read_shift(4, 'i'); break; | ||||
| 					case 0x13 /*VT_UI4*/: blob.l += 4; val = blob.read_shift(4); break; | ||||
| 					case 0x05 /*VT_R8*/: blob.l += 4; val = blob.read_shift(8, 'f'); break; | ||||
| @ -13560,6 +13616,79 @@ function parse_PropertySet(blob, PIDSI) { | ||||
| 	blob.l = start_addr + size; /* step ahead to skip padding */ | ||||
| 	return PropH; | ||||
| } | ||||
| var XLSPSSkip = [ "CodePage", "Thumbnail", "_PID_LINKBASE", "_PID_HLINKS", "SystemIdentifier", "FMTID" ].concat(PseudoPropsPairs); | ||||
| function guess_property_type(val) { | ||||
| 	switch(typeof val) { | ||||
| 		case "boolean": return 0x0B; | ||||
| 		case "number": return ((val|0)==val) ? 0x03 : 0x05; | ||||
| 		case "string": return 0x1F; | ||||
| 		case "object": if(val instanceof Date) return 0x40; break; | ||||
| 	} | ||||
| 	return -1; | ||||
| } | ||||
| function write_PropertySet(entries, RE, PIDSI) { | ||||
| 	var hdr = new_buf(8), piao = [], prop = []; | ||||
| 	var sz = 8, i = 0; | ||||
| 
 | ||||
| 	var pr = new_buf(8), pio = new_buf(8); | ||||
| 	pr.write_shift(4, 0x0002); | ||||
| 	pr.write_shift(4, 0x04B0); | ||||
| 	pio.write_shift(4, 0x0001); | ||||
| 	prop.push(pr); piao.push(pio); | ||||
| 	sz += 8 + pr.length; | ||||
| 
 | ||||
| 	if(!RE) { | ||||
| 		pio = new_buf(8); | ||||
| 		pio.write_shift(4, 0); | ||||
| 		piao.unshift(pio); | ||||
| 
 | ||||
| 		var bufs = [new_buf(4)]; | ||||
| 		bufs[0].write_shift(4, entries.length); | ||||
| 		for(i = 0; i < entries.length; ++i) { | ||||
| 			var value = entries[i][0]; | ||||
| 			pr = new_buf(4 + 4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2)); | ||||
| 			pr.write_shift(4, i+2); | ||||
| 			pr.write_shift(4, value.length + 1); | ||||
| 			pr.write_shift(0, value, "dbcs"); | ||||
| 			while(pr.l != pr.length) pr.write_shift(1, 0); | ||||
| 			bufs.push(pr); | ||||
| 		} | ||||
| 		pr = bconcat(bufs); | ||||
| 		prop.unshift(pr); | ||||
| 		sz += 8 + pr.length; | ||||
| 	} | ||||
| 
 | ||||
| 	for(i = 0; i < entries.length; ++i) { | ||||
| 		if(RE && !RE[entries[i][0]]) continue; | ||||
| 		if(XLSPSSkip.indexOf(entries[i][0]) > -1) continue; | ||||
| 		if(entries[i][1] == null) continue; | ||||
| 
 | ||||
| 		var val = entries[i][1], idx = 0; | ||||
| 		if(RE) { | ||||
| 			idx = +RE[entries[i][0]]; | ||||
| 			var pinfo = PIDSI[idx]; | ||||
| 			if(pinfo.p == "version" && typeof val == "string") val = (+((val = val.split("."))[0])<<16) + (+val[1]||0); | ||||
| 			pr = write_TypedPropertyValue(pinfo.t, val); | ||||
| 		} else { | ||||
| 			var T = guess_property_type(val); | ||||
| 			if(T == -1) { T = 0x1F; val = String(val); } | ||||
| 			pr = write_TypedPropertyValue(T, val); | ||||
| 		} | ||||
| 		prop.push(pr); | ||||
| 
 | ||||
| 		pio = new_buf(8); | ||||
| 		pio.write_shift(4, !RE ? 2+i : idx); | ||||
| 		piao.push(pio); | ||||
| 
 | ||||
| 		sz += 8 + pr.length; | ||||
| 	} | ||||
| 
 | ||||
| 	var w = 8 * (prop.length + 1); | ||||
| 	for(i = 0; i < prop.length; ++i) { piao[i].write_shift(4, w); w += prop[i].length; } | ||||
| 	hdr.write_shift(4, sz); | ||||
| 	hdr.write_shift(4, prop.length); | ||||
| 	return bconcat([hdr].concat(piao).concat(prop)); | ||||
| } | ||||
| 
 | ||||
| /* [MS-OLEPS] 2.21 PropertySetStream */ | ||||
| function parse_PropertySetStream(file, PIDSI, clsid) { | ||||
| @ -13596,7 +13725,27 @@ function parse_PropertySetStream(file, PIDSI, clsid) { | ||||
| 	rval.FMTID = [FMTID0, FMTID1]; // TODO: verify FMTID0/1
 | ||||
| 	return rval; | ||||
| } | ||||
| function write_PropertySetStream(entries, clsid, RE, PIDSI, entries2, clsid2) { | ||||
| 	var hdr = new_buf(entries2 ? 68 : 48); | ||||
| 	var bufs = [hdr]; | ||||
| 	hdr.write_shift(2, 0xFFFE); | ||||
| 	hdr.write_shift(2, 0x0000); /* TODO: type 1 props */ | ||||
| 	hdr.write_shift(4, 0x32363237); | ||||
| 	hdr.write_shift(16, CFB.utils.consts.HEADER_CLSID, "hex"); | ||||
| 	hdr.write_shift(4, (entries2 ? 2 : 1)); | ||||
| 	hdr.write_shift(16, clsid, "hex"); | ||||
| 	hdr.write_shift(4, (entries2 ? 68 : 48)); | ||||
| 	var ps0 = write_PropertySet(entries, RE, PIDSI); | ||||
| 	bufs.push(ps0); | ||||
| 
 | ||||
| 	if(entries2) { | ||||
| 		var ps1 = write_PropertySet(entries2, null, null); | ||||
| 		hdr.write_shift(16, clsid2, "hex"); | ||||
| 		hdr.write_shift(4, 68 + ps0.length); | ||||
| 		bufs.push(ps1); | ||||
| 	} | ||||
| 	return bconcat(bufs); | ||||
| } | ||||
| 
 | ||||
| function parsenoop2(blob, length) { blob.read_shift(length); return null; } | ||||
| function writezeroes(n, o) { if(!o) o=new_buf(n); for(var j=0; j<n; ++j) o.write_shift(1, 0); return o; } | ||||
| @ -15211,6 +15360,7 @@ var SYLK = (function() { | ||||
| 					formats.push(rstr.slice(3).replace(/;;/g, ";")); | ||||
| 				break; | ||||
| 			case 'C': | ||||
| 			var C_seen_K = false; | ||||
| 			for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) { | ||||
| 				case 'X': C = parseInt(record[rj].slice(1))-1; break; | ||||
| 				case 'Y': | ||||
| @ -15228,15 +15378,16 @@ var SYLK = (function() { | ||||
| 					} else if(!isNaN(fuzzydate(val).getDate())) { | ||||
| 						val = parseDate(val); | ||||
| 					} | ||||
| 					arr[R][C] = val; | ||||
| 					next_cell_format = null; | ||||
| 					C_seen_K = true; | ||||
| 					break; | ||||
| 				case 'E': | ||||
| 					var formula = rc_to_a1(record[rj].slice(1), {r:R,c:C}); | ||||
| 					arr[R][C] = [arr[R][C], formula]; | ||||
| 					break; | ||||
| 				default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr); | ||||
| 			} break; | ||||
| 			} | ||||
| 			if(C_seen_K) { arr[R][C] = val; next_cell_format = null; } | ||||
| 			break; | ||||
| 			case 'F': | ||||
| 			var F_seen = 0; | ||||
| 			for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) { | ||||
| @ -15247,6 +15398,7 @@ var SYLK = (function() { | ||||
| 					break; | ||||
| 				case 'M': Mval = parseInt(record[rj].slice(1)) / 20; break; | ||||
| 				case 'F': break; /* ??? */ | ||||
| 				case 'G': break; /* hide grid */ | ||||
| 				case 'P': | ||||
| 					next_cell_format = formats[parseInt(record[rj].slice(1))]; | ||||
| 					break; | ||||
| @ -16844,6 +16996,7 @@ var XLMLPatternTypeMap = { | ||||
| function parse_borders(t, styles, themes, opts) { | ||||
| 	styles.Borders = []; | ||||
| 	var border = {}/*, sub_border = {}*/; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x); | ||||
| 		switch (y[0]) { | ||||
| @ -16902,7 +17055,13 @@ function parse_borders(t, styles, themes, opts) { | ||||
| 			case '<color': case '<color>': break; | ||||
| 			case '<color/>': case '</color>': break; | ||||
| 
 | ||||
| 			default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in borders'); | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in borders'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -16911,6 +17070,7 @@ function parse_borders(t, styles, themes, opts) { | ||||
| function parse_fills(t, styles, themes, opts) { | ||||
| 	styles.Fills = []; | ||||
| 	var fill = {}; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x); | ||||
| 		switch(y[0]) { | ||||
| @ -16961,7 +17121,13 @@ function parse_fills(t, styles, themes, opts) { | ||||
| 			case '<color': case '<color/>': break; | ||||
| 			case '</color>': break; | ||||
| 
 | ||||
| 			default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills'); | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in fills'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -16970,6 +17136,7 @@ function parse_fills(t, styles, themes, opts) { | ||||
| function parse_fonts(t, styles, themes, opts) { | ||||
| 	styles.Fonts = []; | ||||
| 	var font = {}; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x); | ||||
| 		switch (y[0]) { | ||||
| @ -17070,7 +17237,13 @@ function parse_fonts(t, styles, themes, opts) { | ||||
| 				break; | ||||
| 			case '<color/>': case '</color>': break; | ||||
| 
 | ||||
| 			default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fonts'); | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in fonts'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -17120,6 +17293,7 @@ var cellXF_bool = [ "applyAlignment", "applyBorder", "applyFill", "applyFont", " | ||||
| function parse_cellXfs(t, styles, opts) { | ||||
| 	styles.CellXf = []; | ||||
| 	var xf; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x), i = 0; | ||||
| 		switch(y[0]) { | ||||
| @ -17155,9 +17329,12 @@ function parse_cellXfs(t, styles, opts) { | ||||
| 			case '<protection': case '</protection>': case '<protection/>': break; | ||||
| 
 | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '</extLst>': break; | ||||
| 			case '<ext': break; | ||||
| 			default: if(opts.WTF) throw new Error('unrecognized ' + y[0] + ' in cellXfs'); | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in cellXfs'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -18728,6 +18905,7 @@ function parse_SerAr(blob, biff) { | ||||
| 		case 0x04: /* SerBool -- boolean */ | ||||
| 			val[1] = parsebool(blob, 1) ? 'TRUE' : 'FALSE'; | ||||
| 			if(biff != 12) blob.l += 7; break; | ||||
| 		case 0x25: /* appears to be an alias */ | ||||
| 		case 0x10: /* SerErr -- error */ | ||||
| 			val[1] = BErr[blob[blob.l]]; | ||||
| 			blob.l += ((biff == 12) ? 4 : 8); break; | ||||
| @ -18737,7 +18915,7 @@ function parse_SerAr(blob, biff) { | ||||
| 			val[1] = parse_Xnum(blob, 8); break; | ||||
| 		case 0x02: /* SerStr -- XLUnicodeString (<256 chars) */ | ||||
| 			val[1] = parse_XLUnicodeString2(blob, 0, {biff:biff > 0 && biff < 8 ? 2 : biff}); break; | ||||
| 		default: throw "Bad SerAr: " + val[0]; /* Unreachable */ | ||||
| 		default: throw new Error("Bad SerAr: " + val[0]); /* Unreachable */ | ||||
| 	} | ||||
| 	return val; | ||||
| } | ||||
| @ -25307,21 +25485,51 @@ if(!cur_sheet) Workbook.WBProps.CodeName = val || "ThisWorkbook"; | ||||
| 	return wb; | ||||
| } | ||||
| 
 | ||||
| /* TODO: WTF */ | ||||
| function parse_props(cfb, props, o) { | ||||
| /* TODO: split props*/ | ||||
| var PSCLSID = { | ||||
| 	SI: "e0859ff2f94f6810ab9108002b27b3d9", | ||||
| 	DSI: "02d5cdd59c2e1b10939708002b2cf9ae", | ||||
| 	UDI: "05d5cdd59c2e1b10939708002b2cf9ae" | ||||
| }; | ||||
| function parse_xls_props(cfb, props, o) { | ||||
| 	/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */ | ||||
| 	var DSI = CFB.find(cfb, '!DocumentSummaryInformation'); | ||||
| 	if(DSI && DSI.size > 0) try { | ||||
| 		var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, "02d5cdd59c2e1b10939708002b2cf9ae"); | ||||
| 		var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, PSCLSID.DSI); | ||||
| 		for(var d in DocSummary) props[d] = DocSummary[d]; | ||||
| 	} catch(e) {if(o.WTF) throw e;/* empty */} | ||||
| 
 | ||||
| 	/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/ | ||||
| 	var SI = CFB.find(cfb, '!SummaryInformation'); | ||||
| 	if(SI && SI.size > 0) try { | ||||
| 		var Summary = parse_PropertySetStream(SI, SummaryPIDSI, "e0859ff2f94f6810ab9108002b27b3d9"); | ||||
| 		var Summary = parse_PropertySetStream(SI, SummaryPIDSI, PSCLSID.SI); | ||||
| 		for(var s in Summary) if(props[s] == null) props[s] = Summary[s]; | ||||
| 	} catch(e) {if(o.WTF) throw e;/* empty */} | ||||
| 
 | ||||
| 	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, cfb) { | ||||
| 	var DSEntries = [], SEntries = [], CEntries = []; | ||||
| 	var i = 0, Keys; | ||||
| 	if(wb.Props) { | ||||
| 		Keys = keys(wb.Props); | ||||
| 		for(i = 0; i < Keys.length; ++i) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Props[Keys[i]]]); | ||||
| 	} | ||||
| 	if(wb.Custprops) { | ||||
| 		Keys = keys(wb.Custprops); | ||||
| 		for(i = 0; i < Keys.length; ++i) if(!wb.Props.hasOwnProperty(Keys[i])) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Custprops[Keys[i]]]); | ||||
| 	} | ||||
| 	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)); | ||||
| } | ||||
| 
 | ||||
| function parse_xlscfb(cfb, options) { | ||||
| @ -25361,7 +25569,7 @@ else { | ||||
| } | ||||
| 
 | ||||
| var props = {}; | ||||
| if(cfb.FullPaths) parse_props(cfb, props, options); | ||||
| if(cfb.FullPaths) parse_xls_props(cfb, props, options); | ||||
| 
 | ||||
| WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */ | ||||
| if(options.bookFiles) WorkbookP.cfb = cfb; | ||||
| @ -25384,6 +25592,7 @@ function write_xlscfb(wb, opts) { | ||||
| 		default: throw new Error("invalid type " + o.bookType + " for XLS CFB"); | ||||
| 	} | ||||
| 	CFB.utils.cfb_add(cfb, wbpath, write_biff_buf(wb, o)); | ||||
| 	if(o.biff == 8 && (wb.Props || wb.Custprops)) write_xls_props(wb, cfb); | ||||
| 	// TODO: SI, DSI, CO
 | ||||
| 	if(o.biff == 8 && wb.vbaraw) fill_vba_xls(cfb, CFB.read(wb.vbaraw, {type: typeof wb.vbaraw == "string" ? "binary" : "buffer"})); | ||||
| 	return cfb; | ||||
| @ -26772,7 +26981,7 @@ function write_FEAT(ba, ws) { | ||||
| 	o.write_shift(4, 0x868); o.write_shift(4, 0); o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 3); o.write_shift(1, 0); o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 1); o.write_shift(4, 4); o.write_shift(2, 0); | ||||
| 	write_Ref8U(safe_decode_range(ws['!ref']), o); | ||||
| 	write_Ref8U(safe_decode_range(ws['!ref']||"A1"), o); | ||||
| 	o.write_shift(4, 4); | ||||
| 	write_biff_rec(ba, "Feat", o); | ||||
| } | ||||
| @ -26995,11 +27204,11 @@ var HTML_ = (function() { | ||||
| 			var row = rows[i].trim(); | ||||
| 			var hd = row.slice(0,3).toLowerCase(); | ||||
| 			if(hd == "<tr") { ++R; if(opts.sheetRows && opts.sheetRows <= R) { --R; break; } C = 0; continue; } | ||||
| 			if(hd != "<td") continue; | ||||
| 			var cells = row.split(/<\/td>/i); | ||||
| 			if(hd != "<td" && hd != "<th") continue; | ||||
| 			var cells = row.split(/<\/t[dh]>/i); | ||||
| 			for(j = 0; j < cells.length; ++j) { | ||||
| 				var cell = cells[j].trim(); | ||||
| 				if(cell.slice(0,3).toLowerCase() != "<td") continue; | ||||
| 				if(!cell.match(/<t[dh]/i)) continue; | ||||
| 				var m = cell, cc = 0; | ||||
| 				/* TODO: parse styles etc */ | ||||
| 				while(m.charAt(0) == "<" && (cc = m.indexOf(">")) > -1) m = m.slice(cc+1); | ||||
| @ -27134,7 +27343,7 @@ function parse_dom_table(table, _opts) { | ||||
| 			C += CS; | ||||
| 		} | ||||
| 	} | ||||
| 	ws['!merges'] = merges; | ||||
| 	if(merges.length) ws['!merges'] = merges; | ||||
| 	ws['!ref'] = encode_range(range); | ||||
| 	if(sheetRows < rows.length) ws['!fullref'] = encode_range((range.e.r = rows.length-1,range)); | ||||
| 	return ws; | ||||
| @ -28062,7 +28271,7 @@ function parse_zip(zip, opts) { | ||||
| 	var styles = ({}); | ||||
| 	if(!opts.bookSheets && !opts.bookProps) { | ||||
| 		strs = []; | ||||
| 		if(dir.sst) strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts); | ||||
| 		if(dir.sst) try { strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts); } catch(e) { if(opts.WTF) throw e; } | ||||
| 
 | ||||
| 		if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipstr(zip, dir.themes[0].replace(/^\//,''), true)||"",dir.themes[0], opts); | ||||
| 
 | ||||
| @ -28488,7 +28697,7 @@ function write_string_type(out, opts, bom) { | ||||
| 		case "string": return out; | ||||
| 		case "file": return write_dl(opts.file, o, 'utf8'); | ||||
| 		case "buffer": { | ||||
| 			if(has_buf) return new Buffer(o, 'utf8'); | ||||
| 			if(has_buf) return Buffer.from(o, 'utf8'); | ||||
| 			else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); }); | ||||
| 		} | ||||
| 	} | ||||
| @ -28502,7 +28711,7 @@ function write_stxt_type(out, opts) { | ||||
| 		case "string": return out; /* override in sheet_to_txt */ | ||||
| 		case "file": return write_dl(opts.file, out, 'binary'); | ||||
| 		case "buffer": { | ||||
| 			if(has_buf) return new Buffer(out, 'binary'); | ||||
| 			if(has_buf) return Buffer.from(out, 'binary'); | ||||
| 			else return out.split("").map(function(c) { return c.charCodeAt(0); }); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										42
									
								
								dist/xlsx.full.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										42
									
								
								dist/xlsx.full.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.full.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.full.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										377
									
								
								dist/xlsx.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										377
									
								
								dist/xlsx.js
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -4,11 +4,14 @@ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */ | ||||
| var XLSX = {}; | ||||
| (function make_xlsx(XLSX){ | ||||
| XLSX.version = '0.12.11'; | ||||
| XLSX.version = '0.12.12'; | ||||
| var current_codepage = 1200, current_ansi = 1252; | ||||
| /*global cptable:true */ | ||||
| /*global cptable:true, window */ | ||||
| if(typeof module !== "undefined" && typeof require !== 'undefined') { | ||||
| 	if(typeof cptable === 'undefined') global.cptable = undefined; | ||||
| 	if(typeof cptable === 'undefined') { | ||||
| 		if(typeof global !== 'undefined') global.cptable = undefined; | ||||
| 		else if(typeof window !== 'undefined') window.cptable = undefined; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| var VALID_ANSI = [ 874, 932, 936, 949, 950 ]; | ||||
| @ -124,17 +127,23 @@ var Base64 = (function make_b64(){ | ||||
| })(); | ||||
| var has_buf = (typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && process.versions.node); | ||||
| 
 | ||||
| if(typeof Buffer !== 'undefined') { | ||||
| 	// $FlowIgnore
 | ||||
| 	if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); }; | ||||
| 	// $FlowIgnore
 | ||||
| 	if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); }; | ||||
| } | ||||
| 
 | ||||
| function new_raw_buf(len) { | ||||
| 	/* jshint -W056 */ | ||||
| 	// $FlowIgnore
 | ||||
| 	return new (has_buf ? Buffer : Array)(len); | ||||
| 	return has_buf ? Buffer.alloc(len) : new Array(len); | ||||
| 	/* jshint +W056 */ | ||||
| } | ||||
| 
 | ||||
| function s2a(s) { | ||||
| 	if(has_buf) return new Buffer(s, "binary"); | ||||
| var s2a = function s2a(s) { | ||||
| 	if(has_buf) return Buffer.from(s, "binary"); | ||||
| 	return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; }); | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| function s2ab(s) { | ||||
| 	if(typeof ArrayBuffer === 'undefined') return s2a(s); | ||||
| @ -1124,7 +1133,7 @@ var DO_NOT_EXPORT_CFB = true; | ||||
| /* [MS-CFB] v20171201 */ | ||||
| var CFB = (function _CFB(){ | ||||
| var exports = {}; | ||||
| exports.version = '1.0.6'; | ||||
| exports.version = '1.0.7'; | ||||
| /* [MS-CFB] 2.6.4 */ | ||||
| function namecmp(l, r) { | ||||
| 	var L = l.split("/"), R = r.split("/"); | ||||
| @ -2247,7 +2256,7 @@ var utf8write = function(orig) { | ||||
| 
 | ||||
| if(has_buf) { | ||||
| 	var utf8readb = function utf8readb(data) { | ||||
| 		var out = new Buffer(2*data.length), w, i, j = 1, k = 0, ww=0, c; | ||||
| 		var out = Buffer.alloc(2*data.length), w, i, j = 1, k = 0, ww=0, c; | ||||
| 		for(i = 0; i < data.length; i+=j) { | ||||
| 			j = 1; | ||||
| 			if((c=data.charCodeAt(i)) < 128) w = c; | ||||
| @ -2265,10 +2274,10 @@ if(has_buf) { | ||||
| 	var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3"; | ||||
| 	if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb; | ||||
| 	// $FlowIgnore
 | ||||
| 	var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); }; | ||||
| 	var utf8readc = function utf8readc(data) { return Buffer.from(data, 'binary').toString('utf8'); }; | ||||
| 	if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc; | ||||
| 
 | ||||
| 	utf8write = function(data) { return new Buffer(data, 'utf8').toString("binary"); }; | ||||
| 	utf8write = function(data) { return Buffer.from(data, 'utf8').toString("binary"); }; | ||||
| } | ||||
| 
 | ||||
| // matches <foo>...</foo> extracts content
 | ||||
| @ -3207,15 +3216,15 @@ var DocSummaryPIDDSI = { | ||||
| 0x08: { n: 'NoteCount', t: VT_I4 }, | ||||
| 0x09: { n: 'HiddenCount', t: VT_I4 }, | ||||
| 0x0a: { n: 'MultimediaClipCount', t: VT_I4 }, | ||||
| 0x0b: { n: 'Scale', t: VT_BOOL }, | ||||
| 0x0c: { n: 'HeadingPair', t: VT_VECTOR | VT_VARIANT }, | ||||
| 0x0d: { n: 'DocParts', t: VT_VECTOR | VT_LPSTR }, | ||||
| 0x0b: { n: 'ScaleCrop', t: VT_BOOL }, | ||||
| 0x0c: { n: 'HeadingPairs', t: VT_VECTOR | VT_VARIANT }, | ||||
| 0x0d: { n: 'TitlesOfParts', t: VT_VECTOR | VT_LPSTR }, | ||||
| 0x0e: { n: 'Manager', t: VT_STRING }, | ||||
| 0x0f: { n: 'Company', t: VT_STRING }, | ||||
| 0x10: { n: 'LinksDirty', t: VT_BOOL }, | ||||
| 0x10: { n: 'LinksUpToDate', t: VT_BOOL }, | ||||
| 0x11: { n: 'CharacterCount', t: VT_I4 }, | ||||
| 0x13: { n: 'SharedDoc', t: VT_BOOL }, | ||||
| 0x16: { n: 'HLinksChanged', t: VT_BOOL }, | ||||
| 0x16: { n: 'HyperlinksChanged', t: VT_BOOL }, | ||||
| 0x17: { n: 'AppVersion', t: VT_I4, p: 'version' }, | ||||
| 0x18: { n: 'DigSig', t: VT_BLOB }, | ||||
| 0x1A: { n: 'ContentType', t: VT_STRING }, | ||||
| @ -3244,8 +3253,8 @@ var SummaryPIDSI = { | ||||
| 0x0F: { n: 'WordCount', t: VT_I4 }, | ||||
| 0x10: { n: 'CharCount', t: VT_I4 }, | ||||
| 0x11: { n: 'Thumbnail', t: VT_CF }, | ||||
| 0x12: { n: 'ApplicationName', t: VT_STRING }, | ||||
| 0x13: { n: 'DocumentSecurity', t: VT_I4 }, | ||||
| 0x12: { n: 'Application', t: VT_STRING }, | ||||
| 0x13: { n: 'DocSecurity', t: VT_I4 }, | ||||
| 0xFF: {} | ||||
| }; | ||||
| 
 | ||||
| @ -3261,6 +3270,9 @@ var SpecialProperties = { | ||||
| 	DocSummaryPIDDSI[y] = SummaryPIDSI[y] = SpecialProperties[y]; | ||||
| })(); | ||||
| 
 | ||||
| var DocSummaryRE = evert_key(DocSummaryPIDDSI, "n"); | ||||
| var SummaryRE = evert_key(SummaryPIDSI, "n"); | ||||
| 
 | ||||
| /* [MS-XLS] 2.4.63 Country/Region codes */ | ||||
| var CountryEnum = { | ||||
| 0x0001: "US", // United States
 | ||||
| @ -3957,6 +3969,56 @@ var EXT_PROPS = [ | ||||
| XMLNS.EXT_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"; | ||||
| RELS.EXT_PROPS  = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties'; | ||||
| 
 | ||||
| var PseudoPropsPairs = [ | ||||
| 	"Worksheets",  "SheetNames", | ||||
| 	"NamedRanges", "DefinedNames", | ||||
| 	"Chartsheets", "ChartNames" | ||||
| ]; | ||||
| function load_props_pairs(HP, TOP, props, opts) { | ||||
| 	var v = []; | ||||
| 	if(typeof HP == "string") v = parseVector(HP, opts); | ||||
| 	else for(var j = 0; j < HP.length; ++j) v = v.concat(HP[j].map(function(hp) { return {v:hp}; })); | ||||
| 	var parts = (typeof TOP == "string") ? parseVector(TOP, opts).map(function (x) { return x.v; }) : TOP; | ||||
| 	var idx = 0, len = 0; | ||||
| 	if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) { | ||||
| 		len = +(v[i+1].v); | ||||
| 		switch(v[i].v) { | ||||
| 			case "Worksheets": | ||||
| 			case "工作表": | ||||
| 			case "Листы": | ||||
| 			case "أوراق العمل": | ||||
| 			case "ワークシート": | ||||
| 			case "גליונות עבודה": | ||||
| 			case "Arbeitsblätter": | ||||
| 			case "Çalışma Sayfaları": | ||||
| 			case "Feuilles de calcul": | ||||
| 			case "Fogli di lavoro": | ||||
| 			case "Folhas de cálculo": | ||||
| 			case "Planilhas": | ||||
| 			case "Regneark": | ||||
| 			case "Werkbladen": | ||||
| 				props.Worksheets = len; | ||||
| 				props.SheetNames = parts.slice(idx, idx + len); | ||||
| 				break; | ||||
| 
 | ||||
| 			case "Named Ranges": | ||||
| 			case "名前付き一覧": | ||||
| 			case "Benannte Bereiche": | ||||
| 			case "Navngivne områder": | ||||
| 				props.NamedRanges = len; | ||||
| 				props.DefinedNames = parts.slice(idx, idx + len); | ||||
| 				break; | ||||
| 
 | ||||
| 			case "Charts": | ||||
| 			case "Diagramme": | ||||
| 				props.Chartsheets = len; | ||||
| 				props.ChartNames = parts.slice(idx, idx + len); | ||||
| 				break; | ||||
| 		} | ||||
| 		idx += len; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function parse_ext_props(data, p, opts) { | ||||
| 	var q = {}; if(!p) p = {}; | ||||
| 	data = utf8read(data); | ||||
| @ -3972,48 +4034,7 @@ function parse_ext_props(data, p, opts) { | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	if(q.HeadingPairs && q.TitlesOfParts) { | ||||
| 		var v = parseVector(q.HeadingPairs, opts); | ||||
| 		var parts = parseVector(q.TitlesOfParts, opts).map(function (x) { return x.v; }); | ||||
| 		var idx = 0, len = 0; | ||||
| 		if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) { | ||||
| 			len = +(v[i+1].v); | ||||
| 			switch(v[i].v) { | ||||
| 				case "Worksheets": | ||||
| 				case "工作表": | ||||
| 				case "Листы": | ||||
| 				case "أوراق العمل": | ||||
| 				case "ワークシート": | ||||
| 				case "גליונות עבודה": | ||||
| 				case "Arbeitsblätter": | ||||
| 				case "Çalışma Sayfaları": | ||||
| 				case "Feuilles de calcul": | ||||
| 				case "Fogli di lavoro": | ||||
| 				case "Folhas de cálculo": | ||||
| 				case "Planilhas": | ||||
| 				case "Regneark": | ||||
| 				case "Werkbladen": | ||||
| 					p.Worksheets = len; | ||||
| 					p.SheetNames = parts.slice(idx, idx + len); | ||||
| 					break; | ||||
| 
 | ||||
| 				case "Named Ranges": | ||||
| 				case "名前付き一覧": | ||||
| 				case "Benannte Bereiche": | ||||
| 				case "Navngivne områder": | ||||
| 					p.NamedRanges = len; | ||||
| 					p.DefinedNames = parts.slice(idx, idx + len); | ||||
| 					break; | ||||
| 
 | ||||
| 				case "Charts": | ||||
| 				case "Diagramme": | ||||
| 					p.Chartsheets = len; | ||||
| 					p.ChartNames = parts.slice(idx, idx + len); | ||||
| 					break; | ||||
| 			} | ||||
| 			idx += len; | ||||
| 		} | ||||
| 	} | ||||
| 	if(q.HeadingPairs && q.TitlesOfParts) load_props_pairs(q.HeadingPairs, q.TitlesOfParts, p, opts); | ||||
| 
 | ||||
| 	return p; | ||||
| } | ||||
| @ -4210,6 +4231,15 @@ function parse_FILETIME(blob) { | ||||
| 	var dwLowDateTime = blob.read_shift(4), dwHighDateTime = blob.read_shift(4); | ||||
| 	return new Date(((dwHighDateTime/1e7*Math.pow(2,32) + dwLowDateTime/1e7) - 11644473600)*1000).toISOString().replace(/\.000/,""); | ||||
| } | ||||
| function write_FILETIME(time) { | ||||
| 	var date = (typeof time == "string") ? new Date(Date.parse(time)) : time; | ||||
| 	var t = date.getTime() / 1000 + 11644473600; | ||||
| 	var l = t % Math.pow(2,32), h = (t - l) / Math.pow(2,32); | ||||
| 	l *= 1e7; h *= 1e7; | ||||
| 	var w = (l / Math.pow(2,32)) | 0; | ||||
| 	if(w > 0) { l = l % Math.pow(2,32); h += w; } | ||||
| 	var o = new_buf(8); o.write_shift(4, l); o.write_shift(4, h); return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-OSHARED] 2.3.3.1.4 Lpstr */ | ||||
| function parse_lpstr(blob, type, pad) { | ||||
| @ -4279,6 +4309,7 @@ function parse_dictionary(blob,CodePage) { | ||||
| 		var pid = blob.read_shift(4); | ||||
| 		var len = blob.read_shift(4); | ||||
| 		dict[pid] = blob.read_shift(len, (CodePage === 0x4B0 ?'utf16le':'utf8')).replace(chr0,'').replace(chr1,'!'); | ||||
| 		if(CodePage === 0x4B0 && (len % 2)) blob.l += 2; | ||||
| 	} | ||||
| 	if(blob.l & 3) blob.l = (blob.l>>2+1)<<2; | ||||
| 	return dict; | ||||
| @ -4326,6 +4357,25 @@ function parse_TypedPropertyValue(blob, type, _opts) { | ||||
| 		default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + t); | ||||
| 	} | ||||
| } | ||||
| function write_TypedPropertyValue(type, value) { | ||||
| 	var o = new_buf(4), p = new_buf(4); | ||||
| 	o.write_shift(4, type == 0x50 ? 0x1F : type); | ||||
| 	switch(type) { | ||||
| 		case 0x03 /*VT_I4*/: p.write_shift(-4, value); break; | ||||
| 		case 0x05 /*VT_I4*/: p = new_buf(8); p.write_shift(8, value, 'f'); break; | ||||
| 		case 0x0B /*VT_BOOL*/: p.write_shift(4, value ? 0x01 : 0x00); break; | ||||
| 		case 0x40 /*VT_FILETIME*/: p = write_FILETIME(value); break; | ||||
| 		case 0x1F /*VT_LPWSTR*/: | ||||
| 		case 0x50 /*VT_STRING*/: | ||||
| 			p = new_buf(4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2)); | ||||
| 			p.write_shift(4, value.length + 1); | ||||
| 			p.write_shift(0, value, "dbcs"); | ||||
| 			while(p.l != p.length) p.write_shift(1, 0); | ||||
| 			break; | ||||
| 		default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + value); | ||||
| 	} | ||||
| 	return bconcat([o, p]); | ||||
| } | ||||
| 
 | ||||
| /* [MS-OLEPS] 2.20 PropertySet */ | ||||
| function parse_PropertySet(blob, PIDSI) { | ||||
| @ -4356,7 +4406,7 @@ function parse_PropertySet(blob, PIDSI) { | ||||
| 		if(PIDSI) { | ||||
| 			var piddsi = PIDSI[Props[i][0]]; | ||||
| 			PropH[piddsi.n] = parse_TypedPropertyValue(blob, piddsi.t, {raw:true}); | ||||
| 			if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + String(PropH[piddsi.n] & 0xFFFF); | ||||
| 			if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + ("0000" + String(PropH[piddsi.n] & 0xFFFF)).slice(-4); | ||||
| 			if(piddsi.n == "CodePage") switch(PropH[piddsi.n]) { | ||||
| 				case 0: PropH[piddsi.n] = 1252; | ||||
| 					/* falls through */ | ||||
| @ -4401,8 +4451,8 @@ function parse_PropertySet(blob, PIDSI) { | ||||
| 				/* [MS-OSHARED] 2.3.3.2.3.1.2 + PROPVARIANT */ | ||||
| 				switch(blob[blob.l]) { | ||||
| 					case 0x41 /*VT_BLOB*/: blob.l += 4; val = parse_BLOB(blob); break; | ||||
| 					case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break; | ||||
| 					case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break; | ||||
| 					case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break; | ||||
| 					case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break; | ||||
| 					case 0x03 /*VT_I4*/: blob.l += 4; val = blob.read_shift(4, 'i'); break; | ||||
| 					case 0x13 /*VT_UI4*/: blob.l += 4; val = blob.read_shift(4); break; | ||||
| 					case 0x05 /*VT_R8*/: blob.l += 4; val = blob.read_shift(8, 'f'); break; | ||||
| @ -4417,6 +4467,79 @@ function parse_PropertySet(blob, PIDSI) { | ||||
| 	blob.l = start_addr + size; /* step ahead to skip padding */ | ||||
| 	return PropH; | ||||
| } | ||||
| var XLSPSSkip = [ "CodePage", "Thumbnail", "_PID_LINKBASE", "_PID_HLINKS", "SystemIdentifier", "FMTID" ].concat(PseudoPropsPairs); | ||||
| function guess_property_type(val) { | ||||
| 	switch(typeof val) { | ||||
| 		case "boolean": return 0x0B; | ||||
| 		case "number": return ((val|0)==val) ? 0x03 : 0x05; | ||||
| 		case "string": return 0x1F; | ||||
| 		case "object": if(val instanceof Date) return 0x40; break; | ||||
| 	} | ||||
| 	return -1; | ||||
| } | ||||
| function write_PropertySet(entries, RE, PIDSI) { | ||||
| 	var hdr = new_buf(8), piao = [], prop = []; | ||||
| 	var sz = 8, i = 0; | ||||
| 
 | ||||
| 	var pr = new_buf(8), pio = new_buf(8); | ||||
| 	pr.write_shift(4, 0x0002); | ||||
| 	pr.write_shift(4, 0x04B0); | ||||
| 	pio.write_shift(4, 0x0001); | ||||
| 	prop.push(pr); piao.push(pio); | ||||
| 	sz += 8 + pr.length; | ||||
| 
 | ||||
| 	if(!RE) { | ||||
| 		pio = new_buf(8); | ||||
| 		pio.write_shift(4, 0); | ||||
| 		piao.unshift(pio); | ||||
| 
 | ||||
| 		var bufs = [new_buf(4)]; | ||||
| 		bufs[0].write_shift(4, entries.length); | ||||
| 		for(i = 0; i < entries.length; ++i) { | ||||
| 			var value = entries[i][0]; | ||||
| 			pr = new_buf(4 + 4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2)); | ||||
| 			pr.write_shift(4, i+2); | ||||
| 			pr.write_shift(4, value.length + 1); | ||||
| 			pr.write_shift(0, value, "dbcs"); | ||||
| 			while(pr.l != pr.length) pr.write_shift(1, 0); | ||||
| 			bufs.push(pr); | ||||
| 		} | ||||
| 		pr = bconcat(bufs); | ||||
| 		prop.unshift(pr); | ||||
| 		sz += 8 + pr.length; | ||||
| 	} | ||||
| 
 | ||||
| 	for(i = 0; i < entries.length; ++i) { | ||||
| 		if(RE && !RE[entries[i][0]]) continue; | ||||
| 		if(XLSPSSkip.indexOf(entries[i][0]) > -1) continue; | ||||
| 		if(entries[i][1] == null) continue; | ||||
| 
 | ||||
| 		var val = entries[i][1], idx = 0; | ||||
| 		if(RE) { | ||||
| 			idx = +RE[entries[i][0]]; | ||||
| 			var pinfo = PIDSI[idx]; | ||||
| 			if(pinfo.p == "version" && typeof val == "string") val = (+((val = val.split("."))[0])<<16) + (+val[1]||0); | ||||
| 			pr = write_TypedPropertyValue(pinfo.t, val); | ||||
| 		} else { | ||||
| 			var T = guess_property_type(val); | ||||
| 			if(T == -1) { T = 0x1F; val = String(val); } | ||||
| 			pr = write_TypedPropertyValue(T, val); | ||||
| 		} | ||||
| 		prop.push(pr); | ||||
| 
 | ||||
| 		pio = new_buf(8); | ||||
| 		pio.write_shift(4, !RE ? 2+i : idx); | ||||
| 		piao.push(pio); | ||||
| 
 | ||||
| 		sz += 8 + pr.length; | ||||
| 	} | ||||
| 
 | ||||
| 	var w = 8 * (prop.length + 1); | ||||
| 	for(i = 0; i < prop.length; ++i) { piao[i].write_shift(4, w); w += prop[i].length; } | ||||
| 	hdr.write_shift(4, sz); | ||||
| 	hdr.write_shift(4, prop.length); | ||||
| 	return bconcat([hdr].concat(piao).concat(prop)); | ||||
| } | ||||
| 
 | ||||
| /* [MS-OLEPS] 2.21 PropertySetStream */ | ||||
| function parse_PropertySetStream(file, PIDSI, clsid) { | ||||
| @ -4453,7 +4576,27 @@ function parse_PropertySetStream(file, PIDSI, clsid) { | ||||
| 	rval.FMTID = [FMTID0, FMTID1]; // TODO: verify FMTID0/1
 | ||||
| 	return rval; | ||||
| } | ||||
| function write_PropertySetStream(entries, clsid, RE, PIDSI, entries2, clsid2) { | ||||
| 	var hdr = new_buf(entries2 ? 68 : 48); | ||||
| 	var bufs = [hdr]; | ||||
| 	hdr.write_shift(2, 0xFFFE); | ||||
| 	hdr.write_shift(2, 0x0000); /* TODO: type 1 props */ | ||||
| 	hdr.write_shift(4, 0x32363237); | ||||
| 	hdr.write_shift(16, CFB.utils.consts.HEADER_CLSID, "hex"); | ||||
| 	hdr.write_shift(4, (entries2 ? 2 : 1)); | ||||
| 	hdr.write_shift(16, clsid, "hex"); | ||||
| 	hdr.write_shift(4, (entries2 ? 68 : 48)); | ||||
| 	var ps0 = write_PropertySet(entries, RE, PIDSI); | ||||
| 	bufs.push(ps0); | ||||
| 
 | ||||
| 	if(entries2) { | ||||
| 		var ps1 = write_PropertySet(entries2, null, null); | ||||
| 		hdr.write_shift(16, clsid2, "hex"); | ||||
| 		hdr.write_shift(4, 68 + ps0.length); | ||||
| 		bufs.push(ps1); | ||||
| 	} | ||||
| 	return bconcat(bufs); | ||||
| } | ||||
| 
 | ||||
| function parsenoop2(blob, length) { blob.read_shift(length); return null; } | ||||
| function writezeroes(n, o) { if(!o) o=new_buf(n); for(var j=0; j<n; ++j) o.write_shift(1, 0); return o; } | ||||
| @ -6068,6 +6211,7 @@ var SYLK = (function() { | ||||
| 					formats.push(rstr.slice(3).replace(/;;/g, ";")); | ||||
| 				break; | ||||
| 			case 'C': | ||||
| 			var C_seen_K = false; | ||||
| 			for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) { | ||||
| 				case 'X': C = parseInt(record[rj].slice(1))-1; break; | ||||
| 				case 'Y': | ||||
| @ -6085,15 +6229,16 @@ var SYLK = (function() { | ||||
| 					} else if(!isNaN(fuzzydate(val).getDate())) { | ||||
| 						val = parseDate(val); | ||||
| 					} | ||||
| 					arr[R][C] = val; | ||||
| 					next_cell_format = null; | ||||
| 					C_seen_K = true; | ||||
| 					break; | ||||
| 				case 'E': | ||||
| 					var formula = rc_to_a1(record[rj].slice(1), {r:R,c:C}); | ||||
| 					arr[R][C] = [arr[R][C], formula]; | ||||
| 					break; | ||||
| 				default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr); | ||||
| 			} break; | ||||
| 			} | ||||
| 			if(C_seen_K) { arr[R][C] = val; next_cell_format = null; } | ||||
| 			break; | ||||
| 			case 'F': | ||||
| 			var F_seen = 0; | ||||
| 			for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) { | ||||
| @ -6104,6 +6249,7 @@ var SYLK = (function() { | ||||
| 					break; | ||||
| 				case 'M': Mval = parseInt(record[rj].slice(1)) / 20; break; | ||||
| 				case 'F': break; /* ??? */ | ||||
| 				case 'G': break; /* hide grid */ | ||||
| 				case 'P': | ||||
| 					next_cell_format = formats[parseInt(record[rj].slice(1))]; | ||||
| 					break; | ||||
| @ -7701,6 +7847,7 @@ var XLMLPatternTypeMap = { | ||||
| function parse_borders(t, styles, themes, opts) { | ||||
| 	styles.Borders = []; | ||||
| 	var border = {}/*, sub_border = {}*/; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x); | ||||
| 		switch (y[0]) { | ||||
| @ -7759,7 +7906,13 @@ function parse_borders(t, styles, themes, opts) { | ||||
| 			case '<color': case '<color>': break; | ||||
| 			case '<color/>': case '</color>': break; | ||||
| 
 | ||||
| 			default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in borders'); | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in borders'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -7768,6 +7921,7 @@ function parse_borders(t, styles, themes, opts) { | ||||
| function parse_fills(t, styles, themes, opts) { | ||||
| 	styles.Fills = []; | ||||
| 	var fill = {}; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x); | ||||
| 		switch(y[0]) { | ||||
| @ -7818,7 +7972,13 @@ function parse_fills(t, styles, themes, opts) { | ||||
| 			case '<color': case '<color/>': break; | ||||
| 			case '</color>': break; | ||||
| 
 | ||||
| 			default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills'); | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in fills'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -7827,6 +7987,7 @@ function parse_fills(t, styles, themes, opts) { | ||||
| function parse_fonts(t, styles, themes, opts) { | ||||
| 	styles.Fonts = []; | ||||
| 	var font = {}; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x); | ||||
| 		switch (y[0]) { | ||||
| @ -7927,7 +8088,13 @@ function parse_fonts(t, styles, themes, opts) { | ||||
| 				break; | ||||
| 			case '<color/>': case '</color>': break; | ||||
| 
 | ||||
| 			default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fonts'); | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in fonts'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -7977,6 +8144,7 @@ var cellXF_bool = [ "applyAlignment", "applyBorder", "applyFill", "applyFont", " | ||||
| function parse_cellXfs(t, styles, opts) { | ||||
| 	styles.CellXf = []; | ||||
| 	var xf; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x), i = 0; | ||||
| 		switch(y[0]) { | ||||
| @ -8012,9 +8180,12 @@ function parse_cellXfs(t, styles, opts) { | ||||
| 			case '<protection': case '</protection>': case '<protection/>': break; | ||||
| 
 | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '</extLst>': break; | ||||
| 			case '<ext': break; | ||||
| 			default: if(opts.WTF) throw new Error('unrecognized ' + y[0] + ' in cellXfs'); | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in cellXfs'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -9585,6 +9756,7 @@ function parse_SerAr(blob, biff) { | ||||
| 		case 0x04: /* SerBool -- boolean */ | ||||
| 			val[1] = parsebool(blob, 1) ? 'TRUE' : 'FALSE'; | ||||
| 			if(biff != 12) blob.l += 7; break; | ||||
| 		case 0x25: /* appears to be an alias */ | ||||
| 		case 0x10: /* SerErr -- error */ | ||||
| 			val[1] = BErr[blob[blob.l]]; | ||||
| 			blob.l += ((biff == 12) ? 4 : 8); break; | ||||
| @ -9594,7 +9766,7 @@ function parse_SerAr(blob, biff) { | ||||
| 			val[1] = parse_Xnum(blob, 8); break; | ||||
| 		case 0x02: /* SerStr -- XLUnicodeString (<256 chars) */ | ||||
| 			val[1] = parse_XLUnicodeString2(blob, 0, {biff:biff > 0 && biff < 8 ? 2 : biff}); break; | ||||
| 		default: throw "Bad SerAr: " + val[0]; /* Unreachable */ | ||||
| 		default: throw new Error("Bad SerAr: " + val[0]); /* Unreachable */ | ||||
| 	} | ||||
| 	return val; | ||||
| } | ||||
| @ -16164,21 +16336,51 @@ if(!cur_sheet) Workbook.WBProps.CodeName = val || "ThisWorkbook"; | ||||
| 	return wb; | ||||
| } | ||||
| 
 | ||||
| /* TODO: WTF */ | ||||
| function parse_props(cfb, props, o) { | ||||
| /* TODO: split props*/ | ||||
| var PSCLSID = { | ||||
| 	SI: "e0859ff2f94f6810ab9108002b27b3d9", | ||||
| 	DSI: "02d5cdd59c2e1b10939708002b2cf9ae", | ||||
| 	UDI: "05d5cdd59c2e1b10939708002b2cf9ae" | ||||
| }; | ||||
| function parse_xls_props(cfb, props, o) { | ||||
| 	/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */ | ||||
| 	var DSI = CFB.find(cfb, '!DocumentSummaryInformation'); | ||||
| 	if(DSI && DSI.size > 0) try { | ||||
| 		var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, "02d5cdd59c2e1b10939708002b2cf9ae"); | ||||
| 		var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, PSCLSID.DSI); | ||||
| 		for(var d in DocSummary) props[d] = DocSummary[d]; | ||||
| 	} catch(e) {if(o.WTF) throw e;/* empty */} | ||||
| 
 | ||||
| 	/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/ | ||||
| 	var SI = CFB.find(cfb, '!SummaryInformation'); | ||||
| 	if(SI && SI.size > 0) try { | ||||
| 		var Summary = parse_PropertySetStream(SI, SummaryPIDSI, "e0859ff2f94f6810ab9108002b27b3d9"); | ||||
| 		var Summary = parse_PropertySetStream(SI, SummaryPIDSI, PSCLSID.SI); | ||||
| 		for(var s in Summary) if(props[s] == null) props[s] = Summary[s]; | ||||
| 	} catch(e) {if(o.WTF) throw e;/* empty */} | ||||
| 
 | ||||
| 	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, cfb) { | ||||
| 	var DSEntries = [], SEntries = [], CEntries = []; | ||||
| 	var i = 0, Keys; | ||||
| 	if(wb.Props) { | ||||
| 		Keys = keys(wb.Props); | ||||
| 		for(i = 0; i < Keys.length; ++i) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Props[Keys[i]]]); | ||||
| 	} | ||||
| 	if(wb.Custprops) { | ||||
| 		Keys = keys(wb.Custprops); | ||||
| 		for(i = 0; i < Keys.length; ++i) if(!wb.Props.hasOwnProperty(Keys[i])) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Custprops[Keys[i]]]); | ||||
| 	} | ||||
| 	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)); | ||||
| } | ||||
| 
 | ||||
| function parse_xlscfb(cfb, options) { | ||||
| @ -16218,7 +16420,7 @@ else { | ||||
| } | ||||
| 
 | ||||
| var props = {}; | ||||
| if(cfb.FullPaths) parse_props(cfb, props, options); | ||||
| if(cfb.FullPaths) parse_xls_props(cfb, props, options); | ||||
| 
 | ||||
| WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */ | ||||
| if(options.bookFiles) WorkbookP.cfb = cfb; | ||||
| @ -16241,6 +16443,7 @@ function write_xlscfb(wb, opts) { | ||||
| 		default: throw new Error("invalid type " + o.bookType + " for XLS CFB"); | ||||
| 	} | ||||
| 	CFB.utils.cfb_add(cfb, wbpath, write_biff_buf(wb, o)); | ||||
| 	if(o.biff == 8 && (wb.Props || wb.Custprops)) write_xls_props(wb, cfb); | ||||
| 	// TODO: SI, DSI, CO
 | ||||
| 	if(o.biff == 8 && wb.vbaraw) fill_vba_xls(cfb, CFB.read(wb.vbaraw, {type: typeof wb.vbaraw == "string" ? "binary" : "buffer"})); | ||||
| 	return cfb; | ||||
| @ -17629,7 +17832,7 @@ function write_FEAT(ba, ws) { | ||||
| 	o.write_shift(4, 0x868); o.write_shift(4, 0); o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 3); o.write_shift(1, 0); o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 1); o.write_shift(4, 4); o.write_shift(2, 0); | ||||
| 	write_Ref8U(safe_decode_range(ws['!ref']), o); | ||||
| 	write_Ref8U(safe_decode_range(ws['!ref']||"A1"), o); | ||||
| 	o.write_shift(4, 4); | ||||
| 	write_biff_rec(ba, "Feat", o); | ||||
| } | ||||
| @ -17852,11 +18055,11 @@ var HTML_ = (function() { | ||||
| 			var row = rows[i].trim(); | ||||
| 			var hd = row.slice(0,3).toLowerCase(); | ||||
| 			if(hd == "<tr") { ++R; if(opts.sheetRows && opts.sheetRows <= R) { --R; break; } C = 0; continue; } | ||||
| 			if(hd != "<td") continue; | ||||
| 			var cells = row.split(/<\/td>/i); | ||||
| 			if(hd != "<td" && hd != "<th") continue; | ||||
| 			var cells = row.split(/<\/t[dh]>/i); | ||||
| 			for(j = 0; j < cells.length; ++j) { | ||||
| 				var cell = cells[j].trim(); | ||||
| 				if(cell.slice(0,3).toLowerCase() != "<td") continue; | ||||
| 				if(!cell.match(/<t[dh]/i)) continue; | ||||
| 				var m = cell, cc = 0; | ||||
| 				/* TODO: parse styles etc */ | ||||
| 				while(m.charAt(0) == "<" && (cc = m.indexOf(">")) > -1) m = m.slice(cc+1); | ||||
| @ -17991,7 +18194,7 @@ function parse_dom_table(table, _opts) { | ||||
| 			C += CS; | ||||
| 		} | ||||
| 	} | ||||
| 	ws['!merges'] = merges; | ||||
| 	if(merges.length) ws['!merges'] = merges; | ||||
| 	ws['!ref'] = encode_range(range); | ||||
| 	if(sheetRows < rows.length) ws['!fullref'] = encode_range((range.e.r = rows.length-1,range)); | ||||
| 	return ws; | ||||
| @ -18919,7 +19122,7 @@ function parse_zip(zip, opts) { | ||||
| 	var styles = ({}); | ||||
| 	if(!opts.bookSheets && !opts.bookProps) { | ||||
| 		strs = []; | ||||
| 		if(dir.sst) strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts); | ||||
| 		if(dir.sst) try { strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts); } catch(e) { if(opts.WTF) throw e; } | ||||
| 
 | ||||
| 		if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipstr(zip, dir.themes[0].replace(/^\//,''), true)||"",dir.themes[0], opts); | ||||
| 
 | ||||
| @ -19345,7 +19548,7 @@ function write_string_type(out, opts, bom) { | ||||
| 		case "string": return out; | ||||
| 		case "file": return write_dl(opts.file, o, 'utf8'); | ||||
| 		case "buffer": { | ||||
| 			if(has_buf) return new Buffer(o, 'utf8'); | ||||
| 			if(has_buf) return Buffer.from(o, 'utf8'); | ||||
| 			else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); }); | ||||
| 		} | ||||
| 	} | ||||
| @ -19359,7 +19562,7 @@ function write_stxt_type(out, opts) { | ||||
| 		case "string": return out; /* override in sheet_to_txt */ | ||||
| 		case "file": return write_dl(opts.file, out, 'binary'); | ||||
| 		case "buffer": { | ||||
| 			if(has_buf) return new Buffer(out, 'binary'); | ||||
| 			if(has_buf) return Buffer.from(out, 'binary'); | ||||
| 			else return out.split("").map(function(c) { return c.charCodeAt(0); }); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										26
									
								
								dist/xlsx.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										26
									
								
								dist/xlsx.min.js
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/xlsx.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/xlsx.min.map
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										8
									
								
								jszip.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										8
									
								
								jszip.js
									
									
									
									
									
								
							| @ -600,8 +600,14 @@ module.exports = function(data, options) { | ||||
| },{"./base64":1,"./zipEntries":22}],11:[function(_dereq_,module,exports){ | ||||
| (function (Buffer){ | ||||
| 'use strict'; | ||||
| if(typeof Buffer !== 'undefined') { | ||||
| 	// $FlowIgnore
 | ||||
| 	if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); }; | ||||
| 	// $FlowIgnore
 | ||||
| 	if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); }; | ||||
| } | ||||
| module.exports = function(data, encoding){ | ||||
|     return new Buffer(data, encoding); | ||||
|     return typeof data == 'number' ? Buffer.alloc(data) : Buffer.from(data, encoding); | ||||
| }; | ||||
| module.exports.test = function(b){ | ||||
|     return Buffer.isBuffer(b); | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| { | ||||
| 	"name": "xlsx", | ||||
| 	"version": "0.12.11", | ||||
| 	"version": "0.12.12", | ||||
| 	"author": "sheetjs", | ||||
| 	"description": "SheetJS Spreadsheet data parser and writer", | ||||
| 	"keywords": [ | ||||
| @ -31,9 +31,9 @@ | ||||
| 	}, | ||||
| 	"dependencies": { | ||||
| 		"adler-32": "~1.2.0", | ||||
| 		"cfb": "~1.0.6", | ||||
| 		"codepage": "~1.12.1", | ||||
| 		"commander": "~2.14.1", | ||||
| 		"cfb": "~1.0.7", | ||||
| 		"codepage": "~1.13.0", | ||||
| 		"commander": "~2.15.1", | ||||
| 		"crc-32": "~1.2.0", | ||||
| 		"exit-on-epipe": "~1.0.1", | ||||
| 		"ssf": "~0.10.2" | ||||
|  | ||||
							
								
								
									
										21
									
								
								test.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										21
									
								
								test.js
									
									
									
									
									
								
							| @ -1347,6 +1347,14 @@ describe('write features', function() { | ||||
| 		wb.Sheets.Sheet1['!ref'] =  "A" + X.utils.encode_row(C.r - 5) + ":" + X.utils.encode_cell({r:C.r+1, c:0}); | ||||
| 		assert.throws(function() { X.write(wb, wopts); }); | ||||
| 	}); }); }); | ||||
| 	it('single worksheet formats', function() { | ||||
| 		var wb = X.utils.book_new(); | ||||
| 		X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2],[3,4]]), "Sheet1"); | ||||
| 		X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[5,6],[7,8]]), "Sheet2"); | ||||
| 		assert.equal(X.write(wb, {type:"string", bookType:"csv", sheet:"Sheet1"}), "1,2\n3,4\n"); | ||||
| 		assert.equal(X.write(wb, {type:"string", bookType:"csv", sheet:"Sheet2"}), "5,6\n7,8\n"); | ||||
| 		assert.throws(function() { X.write(wb, {type:"string", bookType:"csv", sheet:"Sheet3"}); }); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| function seq(end/*:number*/, start/*:?number*/)/*:Array<number>*/ { | ||||
| @ -1386,6 +1394,7 @@ describe('roundtrip features', function() { | ||||
| 	if(typeof before != 'undefined') before(bef); | ||||
| 	else it('before', bef); | ||||
| 	describe('should preserve core properties', function() { [ | ||||
| 		['xls', paths.cpxls], | ||||
| 		['xlml', paths.cpxml], | ||||
| 		['xlsx', paths.cpxlsx], | ||||
| 		['xlsb', paths.cpxlsb] | ||||
| @ -1399,6 +1408,7 @@ describe('roundtrip features', function() { | ||||
| 	}); }); | ||||
| 
 | ||||
| 	describe('should preserve custom properties', function() { [ | ||||
| 		['xls', paths.cpxls], | ||||
| 		['xlml', paths.cpxml], | ||||
| 		['xlsx', paths.cpxlsx], | ||||
| 		['xlsb', paths.cpxlsb] | ||||
| @ -2065,6 +2075,17 @@ describe('HTML', function() { | ||||
| 		}); | ||||
| 		if(domtest) it('DOM', function() { chk(X.utils.table_to_sheet(get_dom_element(html))); }); | ||||
| 	}); | ||||
| 	describe('TH/THEAD/TBODY/TFOOT elements', function() { | ||||
| 		var html = "<table><thead><tr><th>A</th><th>B</th></tr></thead><tbody><tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr></tbody><tfoot><tr><th>4</th><th>6</th></tr></tfoot></table>"; | ||||
| 		it('HTML string', function() { | ||||
| 			var ws = X.read(html, {type:'string'}).Sheets.Sheet1; | ||||
| 			assert.equal(X.utils.sheet_to_csv(ws),  "A,B\n1,2\n3,4\n4,6\n"); | ||||
| 		}); | ||||
| 		if(domtest) it('DOM', function() { | ||||
| 			var ws = X.utils.table_to_sheet(get_dom_element(html)); | ||||
| 			assert.equal(X.utils.sheet_to_csv(ws),  "A,B\n1,2\n3,4\n4,6\n"); | ||||
| 		}); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| describe('js -> file -> js', function() { | ||||
|  | ||||
							
								
								
									
										21
									
								
								tests/core.js
									
									
									
										generated
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										21
									
								
								tests/core.js
									
									
									
										generated
									
									
									
								
							| @ -1347,6 +1347,14 @@ describe('write features', function() { | ||||
| 		wb.Sheets.Sheet1['!ref'] =  "A" + X.utils.encode_row(C.r - 5) + ":" + X.utils.encode_cell({r:C.r+1, c:0}); | ||||
| 		assert.throws(function() { X.write(wb, wopts); }); | ||||
| 	}); }); }); | ||||
| 	it('single worksheet formats', function() { | ||||
| 		var wb = X.utils.book_new(); | ||||
| 		X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2],[3,4]]), "Sheet1"); | ||||
| 		X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[5,6],[7,8]]), "Sheet2"); | ||||
| 		assert.equal(X.write(wb, {type:"string", bookType:"csv", sheet:"Sheet1"}), "1,2\n3,4\n"); | ||||
| 		assert.equal(X.write(wb, {type:"string", bookType:"csv", sheet:"Sheet2"}), "5,6\n7,8\n"); | ||||
| 		assert.throws(function() { X.write(wb, {type:"string", bookType:"csv", sheet:"Sheet3"}); }); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| function seq(end/*:number*/, start/*:?number*/)/*:Array<number>*/ { | ||||
| @ -1386,6 +1394,7 @@ describe('roundtrip features', function() { | ||||
| 	if(typeof before != 'undefined') before(bef); | ||||
| 	else it('before', bef); | ||||
| 	describe('should preserve core properties', function() { [ | ||||
| 		['xls', paths.cpxls], | ||||
| 		['xlml', paths.cpxml], | ||||
| 		['xlsx', paths.cpxlsx], | ||||
| 		['xlsb', paths.cpxlsb] | ||||
| @ -1399,6 +1408,7 @@ describe('roundtrip features', function() { | ||||
| 	}); }); | ||||
| 
 | ||||
| 	describe('should preserve custom properties', function() { [ | ||||
| 		['xls', paths.cpxls], | ||||
| 		['xlml', paths.cpxml], | ||||
| 		['xlsx', paths.cpxlsx], | ||||
| 		['xlsb', paths.cpxlsb] | ||||
| @ -2065,6 +2075,17 @@ describe('HTML', function() { | ||||
| 		}); | ||||
| 		if(domtest) it('DOM', function() { chk(X.utils.table_to_sheet(get_dom_element(html))); }); | ||||
| 	}); | ||||
| 	describe('TH/THEAD/TBODY/TFOOT elements', function() { | ||||
| 		var html = "<table><thead><tr><th>A</th><th>B</th></tr></thead><tbody><tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr></tbody><tfoot><tr><th>4</th><th>6</th></tr></tfoot></table>"; | ||||
| 		it('HTML string', function() { | ||||
| 			var ws = X.read(html, {type:'string'}).Sheets.Sheet1; | ||||
| 			assert.equal(X.utils.sheet_to_csv(ws),  "A,B\n1,2\n3,4\n4,6\n"); | ||||
| 		}); | ||||
| 		if(domtest) it('DOM', function() { | ||||
| 			var ws = X.utils.table_to_sheet(get_dom_element(html)); | ||||
| 			assert.equal(X.utils.sheet_to_csv(ws),  "A,B\n1,2\n3,4\n4,6\n"); | ||||
| 		}); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| describe('js -> file -> js', function() { | ||||
|  | ||||
| @ -41,6 +41,8 @@ program | ||||
| 	.option('-E, --eth',  'emit ETH  to <sheetname> or <file>.eth (Ethercalc)') | ||||
| 	.option('-t, --txt',  'emit TXT  to <sheetname> or <file>.txt (UTF-8 TSV)') | ||||
| 	.option('-r, --rtf',  'emit RTF  to <sheetname> or <file>.txt (Table RTF)') | ||||
| 	.option('-z, --dump', 'dump internal representation as JSON') | ||||
| 	.option('--props',    'dump workbook properties as CSV') | ||||
| 
 | ||||
| 	.option('-F, --field-sep <sep>', 'CSV field separator', ",") | ||||
| 	.option('-R, --row-sep <sep>', 'CSV row separator', "\n") | ||||
| @ -96,7 +98,8 @@ if(!fs.existsSync(filename)) { | ||||
| 	process.exit(2); | ||||
| } | ||||
| 
 | ||||
| let opts: X.ParsingOptions = {}, wb: X.WorkBook; | ||||
| const opts: X.ParsingOptions = {}; | ||||
| let wb: X.WorkBook; | ||||
| if(program.listSheets) opts.bookSheets = true; | ||||
| if(program.sheetRows) opts.sheetRows = program.sheetRows; | ||||
| if(program.password) opts.password = program.password; | ||||
| @ -118,7 +121,7 @@ if(seen) { | ||||
| } else if(program.formulae) opts.cellFormula = true; | ||||
| else opts.cellFormula = false; | ||||
| 
 | ||||
| let wopts: X.WritingOptions = ({WTF:opts.WTF, bookSST:program.sst}/*:any*/); | ||||
| const wopts: X.WritingOptions = ({WTF:opts.WTF, bookSST:program.sst}/*:any*/); | ||||
| if(program.compress) wopts.compression = true; | ||||
| 
 | ||||
| if(program.all) { | ||||
| @ -153,6 +156,14 @@ if(program.listSheets) { | ||||
| 	console.log((wb.SheetNames||[]).join("\n")); | ||||
| 	process.exit(0); | ||||
| } | ||||
| if(program.dump) { | ||||
| 	console.log(JSON.stringify(wb)); | ||||
| 	process.exit(0); | ||||
| } | ||||
| if(program.props) { | ||||
| 	dump_props(wb); | ||||
| 	process.exit(0); | ||||
| } | ||||
| 
 | ||||
| /* full workbook formats */ | ||||
| workbook_formats.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) { | ||||
| @ -214,7 +225,7 @@ else if(program.rawJs) oo = JSON.stringify(X.utils.sheet_to_json(ws,{raw:true})) | ||||
| else if(program.arrays) oo = JSON.stringify(X.utils.sheet_to_json(ws,{raw:true, header:1})); | ||||
| else { | ||||
| 	strm = true; | ||||
| 	let stream: NodeJS.ReadableStream = X.stream.to_csv(ws, {FS:program.fieldSep, RS:program.rowSep}); | ||||
| 	const stream: NodeJS.ReadableStream = X.stream.to_csv(ws, {FS:program.fieldSep, RS:program.rowSep}); | ||||
| 	if(program.output) stream.pipe(fs.createWriteStream(program.output)); | ||||
| 	else stream.pipe(process.stdout); | ||||
| } | ||||
| @ -225,3 +236,9 @@ if(!strm) { | ||||
| } | ||||
| /*::   } */ | ||||
| /*:: } */ | ||||
| 
 | ||||
| function dump_props(wb: X.WorkBook) { | ||||
| 	let propaoa: any[][] = []; | ||||
| 	propaoa = (<any>Object).entries({...wb.Props, ...wb.Custprops}); | ||||
| 	console.log(X.utils.sheet_to_csv(X.utils.aoa_to_sheet(propaoa))); | ||||
| } | ||||
|  | ||||
| @ -5,7 +5,7 @@ const version: string = XLSX.version; | ||||
| 
 | ||||
| const SSF = XLSX.SSF; | ||||
| 
 | ||||
| let read_opts: XLSX.ParsingOptions = { | ||||
| const read_opts: XLSX.ParsingOptions = { | ||||
| 	type: "buffer", | ||||
| 	raw: false, | ||||
| 	cellFormula: false, | ||||
| @ -26,7 +26,7 @@ let read_opts: XLSX.ParsingOptions = { | ||||
| 	WTF: false | ||||
| }; | ||||
| 
 | ||||
| let write_opts: XLSX.WritingOptions = { | ||||
| const write_opts: XLSX.WritingOptions = { | ||||
| 	type: "buffer", | ||||
| 	cellDates: false, | ||||
| 	bookSST: false, | ||||
|  | ||||
							
								
								
									
										8
									
								
								types/index.d.ts
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										8
									
								
								types/index.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -234,12 +234,12 @@ export interface WorkBook { | ||||
|     /** Ordered list of the sheet names in the workbook */ | ||||
|     SheetNames: string[]; | ||||
| 
 | ||||
|     /** | ||||
|      * an object storing the standard properties. wb.Custprops stores custom properties. | ||||
|      * Since the XLS standard properties deviate from the XLSX standard, XLS parsing stores core properties in both places. | ||||
|      */ | ||||
|     /** Standard workbook Properties */ | ||||
|     Props?: FullProperties; | ||||
| 
 | ||||
|     /** Custom workbook Properties */ | ||||
|     Custprops?: object; | ||||
| 
 | ||||
|     Workbook?: WBProps; | ||||
| 
 | ||||
|     vbaraw?: any; | ||||
|  | ||||
| @ -6,6 +6,7 @@ | ||||
| 		"only-arrow-functions": false, | ||||
| 		"no-consecutive-blank-lines": false, | ||||
| 		"prefer-conditional-expression": false, | ||||
| 		"one-variable-per-declaration": false | ||||
| 		"one-variable-per-declaration": false, | ||||
| 		"prefer-template": false | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| /* vim: set ts=2 ft=javascript: */ | ||||
| 
 | ||||
| /* original data */ | ||||
| let data: any[][] = [ | ||||
| const data: any[][] = [ | ||||
| 	[1, 2, 3], | ||||
| 	[true, false, null, "sheetjs"], | ||||
| 	["foo    bar", "baz", new Date("2014-02-19T14:30Z"), "0.3"], | ||||
| @ -13,7 +13,7 @@ let data: any[][] = [ | ||||
| 
 | ||||
| const ws_name = "SheetJS"; | ||||
| 
 | ||||
| let wscols: XLSX.ColInfo[] = [ | ||||
| const wscols: XLSX.ColInfo[] = [ | ||||
| 	{wch: 6}, // "characters"
 | ||||
| 	{wpx: 50}, // "pixels"
 | ||||
| 	, | ||||
| @ -21,7 +21,7 @@ let wscols: XLSX.ColInfo[] = [ | ||||
| ]; | ||||
| 
 | ||||
| /* At 96 PPI, 1 pt = 1 px */ | ||||
| let wsrows: XLSX.RowInfo[] = [ | ||||
| const wsrows: XLSX.RowInfo[] = [ | ||||
| 	{hpt: 12}, // "points"
 | ||||
| 	{hpx: 16}, // "pixels"
 | ||||
| 	, | ||||
| @ -47,7 +47,7 @@ let wb: XLSX.WorkBook = { SheetNames: <string[]>[], Sheets: {} }; | ||||
| wb = XLSX.utils.book_new(); | ||||
| 
 | ||||
| /* convert an array of arrays in JS to a CSF spreadsheet */ | ||||
| let ws: XLSX.WorkSheet = XLSX.utils.aoa_to_sheet(data, {cellDates:true}); | ||||
| const ws: XLSX.WorkSheet = XLSX.utils.aoa_to_sheet(data, {cellDates:true}); | ||||
| 
 | ||||
| /* TEST: add worksheet to workbook */ | ||||
| wb.SheetNames.push(ws_name); | ||||
| @ -177,7 +177,7 @@ const filenames: Array<[string]|[string, XLSX.WritingOptions]> = [ | ||||
| 
 | ||||
| filenames.forEach((r) => { | ||||
| 		/* write file */ | ||||
| 		XLSX.writeFile(wb, r[0], r[1]); | ||||
| 		XLSX.writeFile(wb, r[0], <XLSX.WritingOptions>r[1]); | ||||
| 		/* test by reading back files */ | ||||
| 		XLSX.readFile(r[0]); | ||||
| }); | ||||
|  | ||||
| @ -58,10 +58,10 @@ const wb_5: XLSX.WorkBook = XLSX.read(XLSX.write(newwb, {type: "array", bookType | ||||
| const wb_6: XLSX.WorkBook = XLSX.read(XLSX.write(newwb, {type: "string", bookType: "xlsx" }), {type: "string"}); | ||||
| 
 | ||||
| function get_header_row(sheet: XLSX.WorkSheet) { | ||||
|     let headers: string[] = []; | ||||
|     const headers: string[] = []; | ||||
|     const range = XLSX.utils.decode_range(sheet['!ref']); | ||||
|     let C: number = 0, R: number = range.s.r; | ||||
|     for(C = range.s.c; C <= range.e.c; ++C) { | ||||
|     const R: number = range.s.r; | ||||
|     for(let C = range.s.c; C <= range.e.c; ++C) { | ||||
|         const cell: XLSX.CellObject = sheet[XLSX.utils.encode_cell({c:C, r:R})]; | ||||
|         let hdr = "UNKNOWN " + C; | ||||
|         if(cell && cell.t) hdr = XLSX.utils.format_cell(cell); | ||||
|  | ||||
							
								
								
									
										377
									
								
								xlsx.flow.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										377
									
								
								xlsx.flow.js
									
									
									
									
									
								
							| @ -4,12 +4,15 @@ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */ | ||||
| var XLSX = {}; | ||||
| (function make_xlsx(XLSX){ | ||||
| XLSX.version = '0.12.11'; | ||||
| XLSX.version = '0.12.12'; | ||||
| var current_codepage = 1200, current_ansi = 1252; | ||||
| /*:: declare var cptable:any; */ | ||||
| /*global cptable:true */ | ||||
| /*global cptable:true, window */ | ||||
| if(typeof module !== "undefined" && typeof require !== 'undefined') { | ||||
| 	if(typeof cptable === 'undefined') global.cptable = require('./dist/cpexcel.js'); | ||||
| 	if(typeof cptable === 'undefined') { | ||||
| 		if(typeof global !== 'undefined') global.cptable = require('./dist/cpexcel.js'); | ||||
| 		else if(typeof window !== 'undefined') window.cptable = require('./dist/cpexcel.js'); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| var VALID_ANSI = [ 874, 932, 936, 949, 950 ]; | ||||
| @ -125,17 +128,23 @@ var Base64 = (function make_b64(){ | ||||
| })(); | ||||
| var has_buf = (typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && process.versions.node); | ||||
| 
 | ||||
| if(typeof Buffer !== 'undefined') { | ||||
| 	// $FlowIgnore
 | ||||
| 	if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); }; | ||||
| 	// $FlowIgnore
 | ||||
| 	if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); }; | ||||
| } | ||||
| 
 | ||||
| function new_raw_buf(len/*:number*/) { | ||||
| 	/* jshint -W056 */ | ||||
| 	// $FlowIgnore
 | ||||
| 	return new (has_buf ? Buffer : Array)(len); | ||||
| 	return has_buf ? Buffer.alloc(len) : new Array(len); | ||||
| 	/* jshint +W056 */ | ||||
| } | ||||
| 
 | ||||
| function s2a(s/*:string*/)/*:any*/ { | ||||
| 	if(has_buf) return new Buffer(s, "binary"); | ||||
| var s2a = function s2a(s/*:string*/)/*:any*/ { | ||||
| 	if(has_buf) return Buffer.from(s, "binary"); | ||||
| 	return s.split("").map(function(x/*:string*/)/*:number*/{ return x.charCodeAt(0) & 0xff; }); | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| function s2ab(s/*:string*/)/*:any*/ { | ||||
| 	if(typeof ArrayBuffer === 'undefined') return s2a(s); | ||||
| @ -1188,7 +1197,7 @@ type CFBFiles = {[n:string]:CFBEntry}; | ||||
| /* [MS-CFB] v20171201 */ | ||||
| var CFB = (function _CFB(){ | ||||
| var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/; | ||||
| exports.version = '1.0.6'; | ||||
| exports.version = '1.0.7'; | ||||
| /* [MS-CFB] 2.6.4 */ | ||||
| function namecmp(l/*:string*/, r/*:string*/)/*:number*/ { | ||||
| 	var L = l.split("/"), R = r.split("/"); | ||||
| @ -2325,7 +2334,7 @@ var utf8write/*:StringConv*/ = function(orig/*:string*/)/*:string*/ { | ||||
| 
 | ||||
| if(has_buf) { | ||||
| 	var utf8readb = function utf8readb(data) { | ||||
| 		var out = new Buffer(2*data.length), w, i, j = 1, k = 0, ww=0, c; | ||||
| 		var out = Buffer.alloc(2*data.length), w, i, j = 1, k = 0, ww=0, c; | ||||
| 		for(i = 0; i < data.length; i+=j) { | ||||
| 			j = 1; | ||||
| 			if((c=data.charCodeAt(i)) < 128) w = c; | ||||
| @ -2343,10 +2352,10 @@ if(has_buf) { | ||||
| 	var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3"; | ||||
| 	if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb; | ||||
| 	// $FlowIgnore
 | ||||
| 	var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); }; | ||||
| 	var utf8readc = function utf8readc(data) { return Buffer.from(data, 'binary').toString('utf8'); }; | ||||
| 	if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc; | ||||
| 
 | ||||
| 	utf8write = function(data) { return new Buffer(data, 'utf8').toString("binary"); }; | ||||
| 	utf8write = function(data) { return Buffer.from(data, 'utf8').toString("binary"); }; | ||||
| } | ||||
| 
 | ||||
| // matches <foo>...</foo> extracts content
 | ||||
| @ -3296,15 +3305,15 @@ var DocSummaryPIDDSI = { | ||||
| 	/*::[*/0x08/*::]*/: { n: 'NoteCount', t: VT_I4 }, | ||||
| 	/*::[*/0x09/*::]*/: { n: 'HiddenCount', t: VT_I4 }, | ||||
| 	/*::[*/0x0a/*::]*/: { n: 'MultimediaClipCount', t: VT_I4 }, | ||||
| 	/*::[*/0x0b/*::]*/: { n: 'Scale', t: VT_BOOL }, | ||||
| 	/*::[*/0x0c/*::]*/: { n: 'HeadingPair', t: VT_VECTOR | VT_VARIANT }, | ||||
| 	/*::[*/0x0d/*::]*/: { n: 'DocParts', t: VT_VECTOR | VT_LPSTR }, | ||||
| 	/*::[*/0x0b/*::]*/: { n: 'ScaleCrop', t: VT_BOOL }, | ||||
| 	/*::[*/0x0c/*::]*/: { n: 'HeadingPairs', t: VT_VECTOR | VT_VARIANT }, | ||||
| 	/*::[*/0x0d/*::]*/: { n: 'TitlesOfParts', t: VT_VECTOR | VT_LPSTR }, | ||||
| 	/*::[*/0x0e/*::]*/: { n: 'Manager', t: VT_STRING }, | ||||
| 	/*::[*/0x0f/*::]*/: { n: 'Company', t: VT_STRING }, | ||||
| 	/*::[*/0x10/*::]*/: { n: 'LinksDirty', t: VT_BOOL }, | ||||
| 	/*::[*/0x10/*::]*/: { n: 'LinksUpToDate', t: VT_BOOL }, | ||||
| 	/*::[*/0x11/*::]*/: { n: 'CharacterCount', t: VT_I4 }, | ||||
| 	/*::[*/0x13/*::]*/: { n: 'SharedDoc', t: VT_BOOL }, | ||||
| 	/*::[*/0x16/*::]*/: { n: 'HLinksChanged', t: VT_BOOL }, | ||||
| 	/*::[*/0x16/*::]*/: { n: 'HyperlinksChanged', t: VT_BOOL }, | ||||
| 	/*::[*/0x17/*::]*/: { n: 'AppVersion', t: VT_I4, p: 'version' }, | ||||
| 	/*::[*/0x18/*::]*/: { n: 'DigSig', t: VT_BLOB }, | ||||
| 	/*::[*/0x1A/*::]*/: { n: 'ContentType', t: VT_STRING }, | ||||
| @ -3333,8 +3342,8 @@ var SummaryPIDSI = { | ||||
| 	/*::[*/0x0F/*::]*/: { n: 'WordCount', t: VT_I4 }, | ||||
| 	/*::[*/0x10/*::]*/: { n: 'CharCount', t: VT_I4 }, | ||||
| 	/*::[*/0x11/*::]*/: { n: 'Thumbnail', t: VT_CF }, | ||||
| 	/*::[*/0x12/*::]*/: { n: 'ApplicationName', t: VT_STRING }, | ||||
| 	/*::[*/0x13/*::]*/: { n: 'DocumentSecurity', t: VT_I4 }, | ||||
| 	/*::[*/0x12/*::]*/: { n: 'Application', t: VT_STRING }, | ||||
| 	/*::[*/0x13/*::]*/: { n: 'DocSecurity', t: VT_I4 }, | ||||
| 	/*::[*/0xFF/*::]*/: {} | ||||
| }; | ||||
| 
 | ||||
| @ -3350,6 +3359,9 @@ var SpecialProperties = { | ||||
| 	DocSummaryPIDDSI[y] = SummaryPIDSI[y] = SpecialProperties[y]; | ||||
| })(); | ||||
| 
 | ||||
| var DocSummaryRE = evert_key(DocSummaryPIDDSI, "n"); | ||||
| var SummaryRE = evert_key(SummaryPIDSI, "n"); | ||||
| 
 | ||||
| /* [MS-XLS] 2.4.63 Country/Region codes */ | ||||
| var CountryEnum = { | ||||
| 	/*::[*/0x0001/*::]*/: "US", // United States
 | ||||
| @ -4046,6 +4058,56 @@ var EXT_PROPS/*:Array<Array<string> >*/ = [ | ||||
| XMLNS.EXT_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"; | ||||
| RELS.EXT_PROPS  = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties'; | ||||
| 
 | ||||
| var PseudoPropsPairs = [ | ||||
| 	"Worksheets",  "SheetNames", | ||||
| 	"NamedRanges", "DefinedNames", | ||||
| 	"Chartsheets", "ChartNames" | ||||
| ]; | ||||
| function load_props_pairs(HP/*:string|Array<Array<any>>*/, TOP, props, opts) { | ||||
| 	var v = []; | ||||
| 	if(typeof HP == "string") v = parseVector(HP, opts); | ||||
| 	else for(var j = 0; j < HP.length; ++j) v = v.concat(HP[j].map(function(hp) { return {v:hp}; })); | ||||
| 	var parts = (typeof TOP == "string") ? parseVector(TOP, opts).map(function (x) { return x.v; }) : TOP; | ||||
| 	var idx = 0, len = 0; | ||||
| 	if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) { | ||||
| 		len = +(v[i+1].v); | ||||
| 		switch(v[i].v) { | ||||
| 			case "Worksheets": | ||||
| 			case "工作表": | ||||
| 			case "Листы": | ||||
| 			case "أوراق العمل": | ||||
| 			case "ワークシート": | ||||
| 			case "גליונות עבודה": | ||||
| 			case "Arbeitsblätter": | ||||
| 			case "Çalışma Sayfaları": | ||||
| 			case "Feuilles de calcul": | ||||
| 			case "Fogli di lavoro": | ||||
| 			case "Folhas de cálculo": | ||||
| 			case "Planilhas": | ||||
| 			case "Regneark": | ||||
| 			case "Werkbladen": | ||||
| 				props.Worksheets = len; | ||||
| 				props.SheetNames = parts.slice(idx, idx + len); | ||||
| 				break; | ||||
| 
 | ||||
| 			case "Named Ranges": | ||||
| 			case "名前付き一覧": | ||||
| 			case "Benannte Bereiche": | ||||
| 			case "Navngivne områder": | ||||
| 				props.NamedRanges = len; | ||||
| 				props.DefinedNames = parts.slice(idx, idx + len); | ||||
| 				break; | ||||
| 
 | ||||
| 			case "Charts": | ||||
| 			case "Diagramme": | ||||
| 				props.Chartsheets = len; | ||||
| 				props.ChartNames = parts.slice(idx, idx + len); | ||||
| 				break; | ||||
| 		} | ||||
| 		idx += len; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function parse_ext_props(data, p, opts) { | ||||
| 	var q = {}; if(!p) p = {}; | ||||
| 	data = utf8read(data); | ||||
| @ -4061,48 +4123,7 @@ function parse_ext_props(data, p, opts) { | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	if(q.HeadingPairs && q.TitlesOfParts) { | ||||
| 		var v = parseVector(q.HeadingPairs, opts); | ||||
| 		var parts = parseVector(q.TitlesOfParts, opts).map(function (x) { return x.v; }); | ||||
| 		var idx = 0, len = 0; | ||||
| 		if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) { | ||||
| 			len = +(v[i+1].v); | ||||
| 			switch(v[i].v) { | ||||
| 				case "Worksheets": | ||||
| 				case "工作表": | ||||
| 				case "Листы": | ||||
| 				case "أوراق العمل": | ||||
| 				case "ワークシート": | ||||
| 				case "גליונות עבודה": | ||||
| 				case "Arbeitsblätter": | ||||
| 				case "Çalışma Sayfaları": | ||||
| 				case "Feuilles de calcul": | ||||
| 				case "Fogli di lavoro": | ||||
| 				case "Folhas de cálculo": | ||||
| 				case "Planilhas": | ||||
| 				case "Regneark": | ||||
| 				case "Werkbladen": | ||||
| 					p.Worksheets = len; | ||||
| 					p.SheetNames = parts.slice(idx, idx + len); | ||||
| 					break; | ||||
| 
 | ||||
| 				case "Named Ranges": | ||||
| 				case "名前付き一覧": | ||||
| 				case "Benannte Bereiche": | ||||
| 				case "Navngivne områder": | ||||
| 					p.NamedRanges = len; | ||||
| 					p.DefinedNames = parts.slice(idx, idx + len); | ||||
| 					break; | ||||
| 
 | ||||
| 				case "Charts": | ||||
| 				case "Diagramme": | ||||
| 					p.Chartsheets = len; | ||||
| 					p.ChartNames = parts.slice(idx, idx + len); | ||||
| 					break; | ||||
| 			} | ||||
| 			idx += len; | ||||
| 		} | ||||
| 	} | ||||
| 	if(q.HeadingPairs && q.TitlesOfParts) load_props_pairs(q.HeadingPairs, q.TitlesOfParts, p, opts); | ||||
| 
 | ||||
| 	return p; | ||||
| } | ||||
| @ -4301,6 +4322,15 @@ function parse_FILETIME(blob) { | ||||
| 	var dwLowDateTime = blob.read_shift(4), dwHighDateTime = blob.read_shift(4); | ||||
| 	return new Date(((dwHighDateTime/1e7*Math.pow(2,32) + dwLowDateTime/1e7) - 11644473600)*1000).toISOString().replace(/\.000/,""); | ||||
| } | ||||
| function write_FILETIME(time/*:string|Date*/) { | ||||
| 	var date = (typeof time == "string") ? new Date(Date.parse(time)) : time; | ||||
| 	var t = date.getTime() / 1000 + 11644473600; | ||||
| 	var l = t % Math.pow(2,32), h = (t - l) / Math.pow(2,32); | ||||
| 	l *= 1e7; h *= 1e7; | ||||
| 	var w = (l / Math.pow(2,32)) | 0; | ||||
| 	if(w > 0) { l = l % Math.pow(2,32); h += w; } | ||||
| 	var o = new_buf(8); o.write_shift(4, l); o.write_shift(4, h); return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-OSHARED] 2.3.3.1.4 Lpstr */ | ||||
| function parse_lpstr(blob, type, pad/*:?number*/) { | ||||
| @ -4370,6 +4400,7 @@ function parse_dictionary(blob,CodePage) { | ||||
| 		var pid = blob.read_shift(4); | ||||
| 		var len = blob.read_shift(4); | ||||
| 		dict[pid] = blob.read_shift(len, (CodePage === 0x4B0 ?'utf16le':'utf8')).replace(chr0,'').replace(chr1,'!'); | ||||
| 		if(CodePage === 0x4B0 && (len % 2)) blob.l += 2; | ||||
| 	} | ||||
| 	if(blob.l & 3) blob.l = (blob.l>>2+1)<<2; | ||||
| 	return dict; | ||||
| @ -4417,6 +4448,25 @@ function parse_TypedPropertyValue(blob, type/*:number*/, _opts)/*:any*/ { | ||||
| 		default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + t); | ||||
| 	} | ||||
| } | ||||
| function write_TypedPropertyValue(type/*:number*/, value) { | ||||
| 	var o = new_buf(4), p = new_buf(4); | ||||
| 	o.write_shift(4, type == 0x50 ? 0x1F : type); | ||||
| 	switch(type) { | ||||
| 		case 0x03 /*VT_I4*/: p.write_shift(-4, value); break; | ||||
| 		case 0x05 /*VT_I4*/: p = new_buf(8); p.write_shift(8, value, 'f'); break; | ||||
| 		case 0x0B /*VT_BOOL*/: p.write_shift(4, value ? 0x01 : 0x00); break; | ||||
| 		case 0x40 /*VT_FILETIME*/: p = write_FILETIME(value); break; | ||||
| 		case 0x1F /*VT_LPWSTR*/: | ||||
| 		case 0x50 /*VT_STRING*/: | ||||
| 			p = new_buf(4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2)); | ||||
| 			p.write_shift(4, value.length + 1); | ||||
| 			p.write_shift(0, value, "dbcs"); | ||||
| 			while(p.l != p.length) p.write_shift(1, 0); | ||||
| 			break; | ||||
| 		default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + value); | ||||
| 	} | ||||
| 	return bconcat([o, p]); | ||||
| } | ||||
| 
 | ||||
| /* [MS-OLEPS] 2.20 PropertySet */ | ||||
| function parse_PropertySet(blob, PIDSI) { | ||||
| @ -4447,7 +4497,7 @@ function parse_PropertySet(blob, PIDSI) { | ||||
| 		if(PIDSI) { | ||||
| 			var piddsi = PIDSI[Props[i][0]]; | ||||
| 			PropH[piddsi.n] = parse_TypedPropertyValue(blob, piddsi.t, {raw:true}); | ||||
| 			if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + String(PropH[piddsi.n] & 0xFFFF); | ||||
| 			if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + ("0000" + String(PropH[piddsi.n] & 0xFFFF)).slice(-4); | ||||
| 			if(piddsi.n == "CodePage") switch(PropH[piddsi.n]) { | ||||
| 				case 0: PropH[piddsi.n] = 1252; | ||||
| 					/* falls through */ | ||||
| @ -4492,8 +4542,8 @@ function parse_PropertySet(blob, PIDSI) { | ||||
| 				/* [MS-OSHARED] 2.3.3.2.3.1.2 + PROPVARIANT */ | ||||
| 				switch(blob[blob.l]) { | ||||
| 					case 0x41 /*VT_BLOB*/: blob.l += 4; val = parse_BLOB(blob); break; | ||||
| 					case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break; | ||||
| 					case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break; | ||||
| 					case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break; | ||||
| 					case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break; | ||||
| 					case 0x03 /*VT_I4*/: blob.l += 4; val = blob.read_shift(4, 'i'); break; | ||||
| 					case 0x13 /*VT_UI4*/: blob.l += 4; val = blob.read_shift(4); break; | ||||
| 					case 0x05 /*VT_R8*/: blob.l += 4; val = blob.read_shift(8, 'f'); break; | ||||
| @ -4508,6 +4558,79 @@ function parse_PropertySet(blob, PIDSI) { | ||||
| 	blob.l = start_addr + size; /* step ahead to skip padding */ | ||||
| 	return PropH; | ||||
| } | ||||
| var XLSPSSkip = [ "CodePage", "Thumbnail", "_PID_LINKBASE", "_PID_HLINKS", "SystemIdentifier", "FMTID" ].concat(PseudoPropsPairs); | ||||
| function guess_property_type(val/*:any*/)/*:number*/ { | ||||
| 	switch(typeof val) { | ||||
| 		case "boolean": return 0x0B; | ||||
| 		case "number": return ((val|0)==val) ? 0x03 : 0x05; | ||||
| 		case "string": return 0x1F; | ||||
| 		case "object": if(val instanceof Date) return 0x40; break; | ||||
| 	} | ||||
| 	return -1; | ||||
| } | ||||
| function write_PropertySet(entries, RE, PIDSI) { | ||||
| 	var hdr = new_buf(8), piao = [], prop = []; | ||||
| 	var sz = 8, i = 0; | ||||
| 
 | ||||
| 	var pr = new_buf(8), pio = new_buf(8); | ||||
| 	pr.write_shift(4, 0x0002); | ||||
| 	pr.write_shift(4, 0x04B0); | ||||
| 	pio.write_shift(4, 0x0001); | ||||
| 	prop.push(pr); piao.push(pio); | ||||
| 	sz += 8 + pr.length; | ||||
| 
 | ||||
| 	if(!RE) { | ||||
| 		pio = new_buf(8); | ||||
| 		pio.write_shift(4, 0); | ||||
| 		piao.unshift(pio); | ||||
| 
 | ||||
| 		var bufs = [new_buf(4)]; | ||||
| 		bufs[0].write_shift(4, entries.length); | ||||
| 		for(i = 0; i < entries.length; ++i) { | ||||
| 			var value = entries[i][0]; | ||||
| 			pr = new_buf(4 + 4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2)); | ||||
| 			pr.write_shift(4, i+2); | ||||
| 			pr.write_shift(4, value.length + 1); | ||||
| 			pr.write_shift(0, value, "dbcs"); | ||||
| 			while(pr.l != pr.length) pr.write_shift(1, 0); | ||||
| 			bufs.push(pr); | ||||
| 		} | ||||
| 		pr = bconcat(bufs); | ||||
| 		prop.unshift(pr); | ||||
| 		sz += 8 + pr.length; | ||||
| 	} | ||||
| 
 | ||||
| 	for(i = 0; i < entries.length; ++i) { | ||||
| 		if(RE && !RE[entries[i][0]]) continue; | ||||
| 		if(XLSPSSkip.indexOf(entries[i][0]) > -1) continue; | ||||
| 		if(entries[i][1] == null) continue; | ||||
| 
 | ||||
| 		var val = entries[i][1], idx = 0; | ||||
| 		if(RE) { | ||||
| 			idx = +RE[entries[i][0]]; | ||||
| 			var pinfo = PIDSI[idx]; | ||||
| 			if(pinfo.p == "version" && typeof val == "string") val = (+((val = val.split("."))[0])<<16) + (+val[1]||0); | ||||
| 			pr = write_TypedPropertyValue(pinfo.t, val); | ||||
| 		} else { | ||||
| 			var T = guess_property_type(val); | ||||
| 			if(T == -1) { T = 0x1F; val = String(val); } | ||||
| 			pr = write_TypedPropertyValue(T, val); | ||||
| 		} | ||||
| 		prop.push(pr); | ||||
| 
 | ||||
| 		pio = new_buf(8); | ||||
| 		pio.write_shift(4, !RE ? 2+i : idx); | ||||
| 		piao.push(pio); | ||||
| 
 | ||||
| 		sz += 8 + pr.length; | ||||
| 	} | ||||
| 
 | ||||
| 	var w = 8 * (prop.length + 1); | ||||
| 	for(i = 0; i < prop.length; ++i) { piao[i].write_shift(4, w); w += prop[i].length; } | ||||
| 	hdr.write_shift(4, sz); | ||||
| 	hdr.write_shift(4, prop.length); | ||||
| 	return bconcat([hdr].concat(piao).concat(prop)); | ||||
| } | ||||
| 
 | ||||
| /* [MS-OLEPS] 2.21 PropertySetStream */ | ||||
| function parse_PropertySetStream(file, PIDSI, clsid) { | ||||
| @ -4544,7 +4667,27 @@ function parse_PropertySetStream(file, PIDSI, clsid) { | ||||
| 	rval.FMTID = [FMTID0, FMTID1]; // TODO: verify FMTID0/1
 | ||||
| 	return rval; | ||||
| } | ||||
| function write_PropertySetStream(entries, clsid, RE, PIDSI, entries2/*:?any*/, clsid2/*:?any*/) { | ||||
| 	var hdr = new_buf(entries2 ? 68 : 48); | ||||
| 	var bufs = [hdr]; | ||||
| 	hdr.write_shift(2, 0xFFFE); | ||||
| 	hdr.write_shift(2, 0x0000); /* TODO: type 1 props */ | ||||
| 	hdr.write_shift(4, 0x32363237); | ||||
| 	hdr.write_shift(16, CFB.utils.consts.HEADER_CLSID, "hex"); | ||||
| 	hdr.write_shift(4, (entries2 ? 2 : 1)); | ||||
| 	hdr.write_shift(16, clsid, "hex"); | ||||
| 	hdr.write_shift(4, (entries2 ? 68 : 48)); | ||||
| 	var ps0 = write_PropertySet(entries, RE, PIDSI); | ||||
| 	bufs.push(ps0); | ||||
| 
 | ||||
| 	if(entries2) { | ||||
| 		var ps1 = write_PropertySet(entries2, null, null); | ||||
| 		hdr.write_shift(16, clsid2, "hex"); | ||||
| 		hdr.write_shift(4, 68 + ps0.length); | ||||
| 		bufs.push(ps1); | ||||
| 	} | ||||
| 	return bconcat(bufs); | ||||
| } | ||||
| 
 | ||||
| function parsenoop2(blob, length) { blob.read_shift(length); return null; } | ||||
| function writezeroes(n, o) { if(!o) o=new_buf(n); for(var j=0; j<n; ++j) o.write_shift(1, 0); return o; } | ||||
| @ -6160,6 +6303,7 @@ var SYLK = (function() { | ||||
| 					formats.push(rstr.slice(3).replace(/;;/g, ";")); | ||||
| 				break; | ||||
| 			case 'C': | ||||
| 			var C_seen_K = false; | ||||
| 			for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) { | ||||
| 				case 'X': C = parseInt(record[rj].slice(1))-1; break; | ||||
| 				case 'Y': | ||||
| @ -6177,15 +6321,16 @@ var SYLK = (function() { | ||||
| 					} else if(!isNaN(fuzzydate(val).getDate())) { | ||||
| 						val = parseDate(val); | ||||
| 					} | ||||
| 					arr[R][C] = val; | ||||
| 					next_cell_format = null; | ||||
| 					C_seen_K = true; | ||||
| 					break; | ||||
| 				case 'E': | ||||
| 					var formula = rc_to_a1(record[rj].slice(1), {r:R,c:C}); | ||||
| 					arr[R][C] = [arr[R][C], formula]; | ||||
| 					break; | ||||
| 				default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr); | ||||
| 			} break; | ||||
| 			} | ||||
| 			if(C_seen_K) { arr[R][C] = val; next_cell_format = null; } | ||||
| 			break; | ||||
| 			case 'F': | ||||
| 			var F_seen = 0; | ||||
| 			for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) { | ||||
| @ -6196,6 +6341,7 @@ var SYLK = (function() { | ||||
| 					break; | ||||
| 				case 'M': Mval = parseInt(record[rj].slice(1)) / 20; break; | ||||
| 				case 'F': break; /* ??? */ | ||||
| 				case 'G': break; /* hide grid */ | ||||
| 				case 'P': | ||||
| 					next_cell_format = formats[parseInt(record[rj].slice(1))]; | ||||
| 					break; | ||||
| @ -7794,6 +7940,7 @@ var XLMLPatternTypeMap = { | ||||
| function parse_borders(t, styles, themes, opts) { | ||||
| 	styles.Borders = []; | ||||
| 	var border = {}/*, sub_border = {}*/; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x); | ||||
| 		switch (y[0]) { | ||||
| @ -7852,7 +7999,13 @@ function parse_borders(t, styles, themes, opts) { | ||||
| 			case '<color': case '<color>': break; | ||||
| 			case '<color/>': case '</color>': break; | ||||
| 
 | ||||
| 			default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in borders'); | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in borders'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -7861,6 +8014,7 @@ function parse_borders(t, styles, themes, opts) { | ||||
| function parse_fills(t, styles, themes, opts) { | ||||
| 	styles.Fills = []; | ||||
| 	var fill = {}; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x); | ||||
| 		switch(y[0]) { | ||||
| @ -7911,7 +8065,13 @@ function parse_fills(t, styles, themes, opts) { | ||||
| 			case '<color': case '<color/>': break; | ||||
| 			case '</color>': break; | ||||
| 
 | ||||
| 			default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills'); | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in fills'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -7920,6 +8080,7 @@ function parse_fills(t, styles, themes, opts) { | ||||
| function parse_fonts(t, styles, themes, opts) { | ||||
| 	styles.Fonts = []; | ||||
| 	var font = {}; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x); | ||||
| 		switch (y[0]) { | ||||
| @ -8020,7 +8181,13 @@ function parse_fonts(t, styles, themes, opts) { | ||||
| 				break; | ||||
| 			case '<color/>': case '</color>': break; | ||||
| 
 | ||||
| 			default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fonts'); | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in fonts'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -8070,6 +8237,7 @@ var cellXF_bool = [ "applyAlignment", "applyBorder", "applyFill", "applyFont", " | ||||
| function parse_cellXfs(t, styles, opts) { | ||||
| 	styles.CellXf = []; | ||||
| 	var xf; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x), i = 0; | ||||
| 		switch(y[0]) { | ||||
| @ -8105,9 +8273,12 @@ function parse_cellXfs(t, styles, opts) { | ||||
| 			case '<protection': case '</protection>': case '<protection/>': break; | ||||
| 
 | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '</extLst>': break; | ||||
| 			case '<ext': break; | ||||
| 			default: if(opts.WTF) throw new Error('unrecognized ' + y[0] + ' in cellXfs'); | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in cellXfs'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -9680,6 +9851,7 @@ function parse_SerAr(blob, biff/*:number*/) { | ||||
| 		case 0x04: /* SerBool -- boolean */ | ||||
| 			val[1] = parsebool(blob, 1) ? 'TRUE' : 'FALSE'; | ||||
| 			if(biff != 12) blob.l += 7; break; | ||||
| 		case 0x25: /* appears to be an alias */ | ||||
| 		case 0x10: /* SerErr -- error */ | ||||
| 			val[1] = BErr[blob[blob.l]]; | ||||
| 			blob.l += ((biff == 12) ? 4 : 8); break; | ||||
| @ -9689,7 +9861,7 @@ function parse_SerAr(blob, biff/*:number*/) { | ||||
| 			val[1] = parse_Xnum(blob, 8); break; | ||||
| 		case 0x02: /* SerStr -- XLUnicodeString (<256 chars) */ | ||||
| 			val[1] = parse_XLUnicodeString2(blob, 0, {biff:biff > 0 && biff < 8 ? 2 : biff}); break; | ||||
| 		default: throw "Bad SerAr: " + val[0]; /* Unreachable */ | ||||
| 		default: throw new Error("Bad SerAr: " + val[0]); /* Unreachable */ | ||||
| 	} | ||||
| 	return val; | ||||
| } | ||||
| @ -16274,21 +16446,51 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { | ||||
| 	return wb; | ||||
| } | ||||
| 
 | ||||
| /* TODO: WTF */ | ||||
| function parse_props(cfb/*:CFBContainer*/, props, o) { | ||||
| /* TODO: split props*/ | ||||
| var PSCLSID = { | ||||
| 	SI: "e0859ff2f94f6810ab9108002b27b3d9", | ||||
| 	DSI: "02d5cdd59c2e1b10939708002b2cf9ae", | ||||
| 	UDI: "05d5cdd59c2e1b10939708002b2cf9ae" | ||||
| }; | ||||
| function parse_xls_props(cfb/*:CFBContainer*/, props, o) { | ||||
| 	/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */ | ||||
| 	var DSI = CFB.find(cfb, '!DocumentSummaryInformation'); | ||||
| 	if(DSI && DSI.size > 0) try { | ||||
| 		var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, "02d5cdd59c2e1b10939708002b2cf9ae"); | ||||
| 		var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, PSCLSID.DSI); | ||||
| 		for(var d in DocSummary) props[d] = DocSummary[d]; | ||||
| 	} catch(e) {if(o.WTF) throw e;/* empty */} | ||||
| 
 | ||||
| 	/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/ | ||||
| 	var SI = CFB.find(cfb, '!SummaryInformation'); | ||||
| 	if(SI && SI.size > 0) try { | ||||
| 		var Summary = parse_PropertySetStream(SI, SummaryPIDSI, "e0859ff2f94f6810ab9108002b27b3d9"); | ||||
| 		var Summary = parse_PropertySetStream(SI, SummaryPIDSI, PSCLSID.SI); | ||||
| 		for(var s in Summary) if(props[s] == null) props[s] = Summary[s]; | ||||
| 	} catch(e) {if(o.WTF) throw e;/* empty */} | ||||
| 
 | ||||
| 	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); | ||||
| 		for(i = 0; i < Keys.length; ++i) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Props[Keys[i]]]); | ||||
| 	} | ||||
| 	if(wb.Custprops) { | ||||
| 		Keys = keys(wb.Custprops); | ||||
| 		for(i = 0; i < Keys.length; ++i) if(!wb.Props.hasOwnProperty(Keys[i])) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Custprops[Keys[i]]]); | ||||
| 	} | ||||
| 	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)); | ||||
| } | ||||
| 
 | ||||
| function parse_xlscfb(cfb/*:any*/, options/*:?ParseOpts*/)/*:Workbook*/ { | ||||
| @ -16328,7 +16530,7 @@ else/*:: if(cfb instanceof CFBContainer) */ { | ||||
| } | ||||
| 
 | ||||
| var props = {}; | ||||
| if(cfb.FullPaths) parse_props(/*::((*/cfb/*:: :any):CFBContainer)*/, props, options); | ||||
| if(cfb.FullPaths) parse_xls_props(/*::((*/cfb/*:: :any):CFBContainer)*/, props, options); | ||||
| 
 | ||||
| WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */ | ||||
| if(options.bookFiles) WorkbookP.cfb = cfb; | ||||
| @ -16351,6 +16553,7 @@ function write_xlscfb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:CFBContainer*/ { | ||||
| 		default: throw new Error("invalid type " + o.bookType + " for XLS CFB"); | ||||
| 	} | ||||
| 	CFB.utils.cfb_add(cfb, wbpath, write_biff_buf(wb, o)); | ||||
| 	if(o.biff == 8 && (wb.Props || wb.Custprops)) write_xls_props(wb, cfb); | ||||
| 	// TODO: SI, DSI, CO
 | ||||
| 	if(o.biff == 8 && wb.vbaraw) fill_vba_xls(cfb, CFB.read(wb.vbaraw, {type: typeof wb.vbaraw == "string" ? "binary" : "buffer"})); | ||||
| 	return cfb; | ||||
| @ -17740,7 +17943,7 @@ function write_FEAT(ba, ws) { | ||||
| 	o.write_shift(4, 0x868); o.write_shift(4, 0); o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 3); o.write_shift(1, 0); o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 1); o.write_shift(4, 4); o.write_shift(2, 0); | ||||
| 	write_Ref8U(safe_decode_range(ws['!ref']), o); | ||||
| 	write_Ref8U(safe_decode_range(ws['!ref']||"A1"), o); | ||||
| 	o.write_shift(4, 4); | ||||
| 	write_biff_rec(ba, "Feat", o); | ||||
| } | ||||
| @ -17963,11 +18166,11 @@ var HTML_ = (function() { | ||||
| 			var row = rows[i].trim(); | ||||
| 			var hd = row.slice(0,3).toLowerCase(); | ||||
| 			if(hd == "<tr") { ++R; if(opts.sheetRows && opts.sheetRows <= R) { --R; break; } C = 0; continue; } | ||||
| 			if(hd != "<td") continue; | ||||
| 			var cells = row.split(/<\/td>/i); | ||||
| 			if(hd != "<td" && hd != "<th") continue; | ||||
| 			var cells = row.split(/<\/t[dh]>/i); | ||||
| 			for(j = 0; j < cells.length; ++j) { | ||||
| 				var cell = cells[j].trim(); | ||||
| 				if(cell.slice(0,3).toLowerCase() != "<td") continue; | ||||
| 				if(!cell.match(/<t[dh]/i)) continue; | ||||
| 				var m = cell, cc = 0; | ||||
| 				/* TODO: parse styles etc */ | ||||
| 				while(m.charAt(0) == "<" && (cc = m.indexOf(">")) > -1) m = m.slice(cc+1); | ||||
| @ -18102,7 +18305,7 @@ function parse_dom_table(table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ { | ||||
| 			C += CS; | ||||
| 		} | ||||
| 	} | ||||
| 	ws['!merges'] = merges; | ||||
| 	if(merges.length) ws['!merges'] = merges; | ||||
| 	ws['!ref'] = encode_range(range); | ||||
| 	if(sheetRows < rows.length) ws['!fullref'] = encode_range((range.e.r = rows.length-1,range)); | ||||
| 	return ws; | ||||
| @ -19031,7 +19234,7 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ { | ||||
| 	var styles = ({}/*:any*/); | ||||
| 	if(!opts.bookSheets && !opts.bookProps) { | ||||
| 		strs = []; | ||||
| 		if(dir.sst) strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts); | ||||
| 		if(dir.sst) try { strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts); } catch(e) { if(opts.WTF) throw e; } | ||||
| 
 | ||||
| 		if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipstr(zip, dir.themes[0].replace(/^\//,''), true)||"",dir.themes[0], opts); | ||||
| 
 | ||||
| @ -19462,7 +19665,7 @@ function write_string_type(out/*:string*/, opts/*:WriteOpts*/, bom/*:?string*/)/ | ||||
| 		case "string": return out; | ||||
| 		case "file": return write_dl(opts.file, o, 'utf8'); | ||||
| 		case "buffer": { | ||||
| 			if(has_buf) return new Buffer(o, 'utf8'); | ||||
| 			if(has_buf) return Buffer.from(o, 'utf8'); | ||||
| 			else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); }); | ||||
| 		} | ||||
| 	} | ||||
| @ -19476,7 +19679,7 @@ function write_stxt_type(out/*:string*/, opts/*:WriteOpts*/)/*:any*/ { | ||||
| 		case "string": return out; /* override in sheet_to_txt */ | ||||
| 		case "file": return write_dl(opts.file, out, 'binary'); | ||||
| 		case "buffer": { | ||||
| 			if(has_buf) return new Buffer(out, 'binary'); | ||||
| 			if(has_buf) return Buffer.from(out, 'binary'); | ||||
| 			else return out.split("").map(function(c) { return c.charCodeAt(0); }); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										377
									
								
								xlsx.js
									
									
									
										generated
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										377
									
								
								xlsx.js
									
									
									
										generated
									
									
									
								
							| @ -4,11 +4,14 @@ | ||||
| /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */ | ||||
| var XLSX = {}; | ||||
| (function make_xlsx(XLSX){ | ||||
| XLSX.version = '0.12.11'; | ||||
| XLSX.version = '0.12.12'; | ||||
| var current_codepage = 1200, current_ansi = 1252; | ||||
| /*global cptable:true */ | ||||
| /*global cptable:true, window */ | ||||
| if(typeof module !== "undefined" && typeof require !== 'undefined') { | ||||
| 	if(typeof cptable === 'undefined') global.cptable = require('./dist/cpexcel.js'); | ||||
| 	if(typeof cptable === 'undefined') { | ||||
| 		if(typeof global !== 'undefined') global.cptable = require('./dist/cpexcel.js'); | ||||
| 		else if(typeof window !== 'undefined') window.cptable = require('./dist/cpexcel.js'); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| var VALID_ANSI = [ 874, 932, 936, 949, 950 ]; | ||||
| @ -124,17 +127,23 @@ var Base64 = (function make_b64(){ | ||||
| })(); | ||||
| var has_buf = (typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && process.versions.node); | ||||
| 
 | ||||
| if(typeof Buffer !== 'undefined') { | ||||
| 	// $FlowIgnore
 | ||||
| 	if(!Buffer.from) Buffer.from = function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); }; | ||||
| 	// $FlowIgnore
 | ||||
| 	if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); }; | ||||
| } | ||||
| 
 | ||||
| function new_raw_buf(len) { | ||||
| 	/* jshint -W056 */ | ||||
| 	// $FlowIgnore
 | ||||
| 	return new (has_buf ? Buffer : Array)(len); | ||||
| 	return has_buf ? Buffer.alloc(len) : new Array(len); | ||||
| 	/* jshint +W056 */ | ||||
| } | ||||
| 
 | ||||
| function s2a(s) { | ||||
| 	if(has_buf) return new Buffer(s, "binary"); | ||||
| var s2a = function s2a(s) { | ||||
| 	if(has_buf) return Buffer.from(s, "binary"); | ||||
| 	return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; }); | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| function s2ab(s) { | ||||
| 	if(typeof ArrayBuffer === 'undefined') return s2a(s); | ||||
| @ -1124,7 +1133,7 @@ var DO_NOT_EXPORT_CFB = true; | ||||
| /* [MS-CFB] v20171201 */ | ||||
| var CFB = (function _CFB(){ | ||||
| var exports = {}; | ||||
| exports.version = '1.0.6'; | ||||
| exports.version = '1.0.7'; | ||||
| /* [MS-CFB] 2.6.4 */ | ||||
| function namecmp(l, r) { | ||||
| 	var L = l.split("/"), R = r.split("/"); | ||||
| @ -2247,7 +2256,7 @@ var utf8write = function(orig) { | ||||
| 
 | ||||
| if(has_buf) { | ||||
| 	var utf8readb = function utf8readb(data) { | ||||
| 		var out = new Buffer(2*data.length), w, i, j = 1, k = 0, ww=0, c; | ||||
| 		var out = Buffer.alloc(2*data.length), w, i, j = 1, k = 0, ww=0, c; | ||||
| 		for(i = 0; i < data.length; i+=j) { | ||||
| 			j = 1; | ||||
| 			if((c=data.charCodeAt(i)) < 128) w = c; | ||||
| @ -2265,10 +2274,10 @@ if(has_buf) { | ||||
| 	var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3"; | ||||
| 	if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb; | ||||
| 	// $FlowIgnore
 | ||||
| 	var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); }; | ||||
| 	var utf8readc = function utf8readc(data) { return Buffer.from(data, 'binary').toString('utf8'); }; | ||||
| 	if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc; | ||||
| 
 | ||||
| 	utf8write = function(data) { return new Buffer(data, 'utf8').toString("binary"); }; | ||||
| 	utf8write = function(data) { return Buffer.from(data, 'utf8').toString("binary"); }; | ||||
| } | ||||
| 
 | ||||
| // matches <foo>...</foo> extracts content
 | ||||
| @ -3207,15 +3216,15 @@ var DocSummaryPIDDSI = { | ||||
| 0x08: { n: 'NoteCount', t: VT_I4 }, | ||||
| 0x09: { n: 'HiddenCount', t: VT_I4 }, | ||||
| 0x0a: { n: 'MultimediaClipCount', t: VT_I4 }, | ||||
| 0x0b: { n: 'Scale', t: VT_BOOL }, | ||||
| 0x0c: { n: 'HeadingPair', t: VT_VECTOR | VT_VARIANT }, | ||||
| 0x0d: { n: 'DocParts', t: VT_VECTOR | VT_LPSTR }, | ||||
| 0x0b: { n: 'ScaleCrop', t: VT_BOOL }, | ||||
| 0x0c: { n: 'HeadingPairs', t: VT_VECTOR | VT_VARIANT }, | ||||
| 0x0d: { n: 'TitlesOfParts', t: VT_VECTOR | VT_LPSTR }, | ||||
| 0x0e: { n: 'Manager', t: VT_STRING }, | ||||
| 0x0f: { n: 'Company', t: VT_STRING }, | ||||
| 0x10: { n: 'LinksDirty', t: VT_BOOL }, | ||||
| 0x10: { n: 'LinksUpToDate', t: VT_BOOL }, | ||||
| 0x11: { n: 'CharacterCount', t: VT_I4 }, | ||||
| 0x13: { n: 'SharedDoc', t: VT_BOOL }, | ||||
| 0x16: { n: 'HLinksChanged', t: VT_BOOL }, | ||||
| 0x16: { n: 'HyperlinksChanged', t: VT_BOOL }, | ||||
| 0x17: { n: 'AppVersion', t: VT_I4, p: 'version' }, | ||||
| 0x18: { n: 'DigSig', t: VT_BLOB }, | ||||
| 0x1A: { n: 'ContentType', t: VT_STRING }, | ||||
| @ -3244,8 +3253,8 @@ var SummaryPIDSI = { | ||||
| 0x0F: { n: 'WordCount', t: VT_I4 }, | ||||
| 0x10: { n: 'CharCount', t: VT_I4 }, | ||||
| 0x11: { n: 'Thumbnail', t: VT_CF }, | ||||
| 0x12: { n: 'ApplicationName', t: VT_STRING }, | ||||
| 0x13: { n: 'DocumentSecurity', t: VT_I4 }, | ||||
| 0x12: { n: 'Application', t: VT_STRING }, | ||||
| 0x13: { n: 'DocSecurity', t: VT_I4 }, | ||||
| 0xFF: {} | ||||
| }; | ||||
| 
 | ||||
| @ -3261,6 +3270,9 @@ var SpecialProperties = { | ||||
| 	DocSummaryPIDDSI[y] = SummaryPIDSI[y] = SpecialProperties[y]; | ||||
| })(); | ||||
| 
 | ||||
| var DocSummaryRE = evert_key(DocSummaryPIDDSI, "n"); | ||||
| var SummaryRE = evert_key(SummaryPIDSI, "n"); | ||||
| 
 | ||||
| /* [MS-XLS] 2.4.63 Country/Region codes */ | ||||
| var CountryEnum = { | ||||
| 0x0001: "US", // United States
 | ||||
| @ -3957,6 +3969,56 @@ var EXT_PROPS = [ | ||||
| XMLNS.EXT_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"; | ||||
| RELS.EXT_PROPS  = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties'; | ||||
| 
 | ||||
| var PseudoPropsPairs = [ | ||||
| 	"Worksheets",  "SheetNames", | ||||
| 	"NamedRanges", "DefinedNames", | ||||
| 	"Chartsheets", "ChartNames" | ||||
| ]; | ||||
| function load_props_pairs(HP, TOP, props, opts) { | ||||
| 	var v = []; | ||||
| 	if(typeof HP == "string") v = parseVector(HP, opts); | ||||
| 	else for(var j = 0; j < HP.length; ++j) v = v.concat(HP[j].map(function(hp) { return {v:hp}; })); | ||||
| 	var parts = (typeof TOP == "string") ? parseVector(TOP, opts).map(function (x) { return x.v; }) : TOP; | ||||
| 	var idx = 0, len = 0; | ||||
| 	if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) { | ||||
| 		len = +(v[i+1].v); | ||||
| 		switch(v[i].v) { | ||||
| 			case "Worksheets": | ||||
| 			case "工作表": | ||||
| 			case "Листы": | ||||
| 			case "أوراق العمل": | ||||
| 			case "ワークシート": | ||||
| 			case "גליונות עבודה": | ||||
| 			case "Arbeitsblätter": | ||||
| 			case "Çalışma Sayfaları": | ||||
| 			case "Feuilles de calcul": | ||||
| 			case "Fogli di lavoro": | ||||
| 			case "Folhas de cálculo": | ||||
| 			case "Planilhas": | ||||
| 			case "Regneark": | ||||
| 			case "Werkbladen": | ||||
| 				props.Worksheets = len; | ||||
| 				props.SheetNames = parts.slice(idx, idx + len); | ||||
| 				break; | ||||
| 
 | ||||
| 			case "Named Ranges": | ||||
| 			case "名前付き一覧": | ||||
| 			case "Benannte Bereiche": | ||||
| 			case "Navngivne områder": | ||||
| 				props.NamedRanges = len; | ||||
| 				props.DefinedNames = parts.slice(idx, idx + len); | ||||
| 				break; | ||||
| 
 | ||||
| 			case "Charts": | ||||
| 			case "Diagramme": | ||||
| 				props.Chartsheets = len; | ||||
| 				props.ChartNames = parts.slice(idx, idx + len); | ||||
| 				break; | ||||
| 		} | ||||
| 		idx += len; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function parse_ext_props(data, p, opts) { | ||||
| 	var q = {}; if(!p) p = {}; | ||||
| 	data = utf8read(data); | ||||
| @ -3972,48 +4034,7 @@ function parse_ext_props(data, p, opts) { | ||||
| 		} | ||||
| 	}); | ||||
| 
 | ||||
| 	if(q.HeadingPairs && q.TitlesOfParts) { | ||||
| 		var v = parseVector(q.HeadingPairs, opts); | ||||
| 		var parts = parseVector(q.TitlesOfParts, opts).map(function (x) { return x.v; }); | ||||
| 		var idx = 0, len = 0; | ||||
| 		if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) { | ||||
| 			len = +(v[i+1].v); | ||||
| 			switch(v[i].v) { | ||||
| 				case "Worksheets": | ||||
| 				case "工作表": | ||||
| 				case "Листы": | ||||
| 				case "أوراق العمل": | ||||
| 				case "ワークシート": | ||||
| 				case "גליונות עבודה": | ||||
| 				case "Arbeitsblätter": | ||||
| 				case "Çalışma Sayfaları": | ||||
| 				case "Feuilles de calcul": | ||||
| 				case "Fogli di lavoro": | ||||
| 				case "Folhas de cálculo": | ||||
| 				case "Planilhas": | ||||
| 				case "Regneark": | ||||
| 				case "Werkbladen": | ||||
| 					p.Worksheets = len; | ||||
| 					p.SheetNames = parts.slice(idx, idx + len); | ||||
| 					break; | ||||
| 
 | ||||
| 				case "Named Ranges": | ||||
| 				case "名前付き一覧": | ||||
| 				case "Benannte Bereiche": | ||||
| 				case "Navngivne områder": | ||||
| 					p.NamedRanges = len; | ||||
| 					p.DefinedNames = parts.slice(idx, idx + len); | ||||
| 					break; | ||||
| 
 | ||||
| 				case "Charts": | ||||
| 				case "Diagramme": | ||||
| 					p.Chartsheets = len; | ||||
| 					p.ChartNames = parts.slice(idx, idx + len); | ||||
| 					break; | ||||
| 			} | ||||
| 			idx += len; | ||||
| 		} | ||||
| 	} | ||||
| 	if(q.HeadingPairs && q.TitlesOfParts) load_props_pairs(q.HeadingPairs, q.TitlesOfParts, p, opts); | ||||
| 
 | ||||
| 	return p; | ||||
| } | ||||
| @ -4210,6 +4231,15 @@ function parse_FILETIME(blob) { | ||||
| 	var dwLowDateTime = blob.read_shift(4), dwHighDateTime = blob.read_shift(4); | ||||
| 	return new Date(((dwHighDateTime/1e7*Math.pow(2,32) + dwLowDateTime/1e7) - 11644473600)*1000).toISOString().replace(/\.000/,""); | ||||
| } | ||||
| function write_FILETIME(time) { | ||||
| 	var date = (typeof time == "string") ? new Date(Date.parse(time)) : time; | ||||
| 	var t = date.getTime() / 1000 + 11644473600; | ||||
| 	var l = t % Math.pow(2,32), h = (t - l) / Math.pow(2,32); | ||||
| 	l *= 1e7; h *= 1e7; | ||||
| 	var w = (l / Math.pow(2,32)) | 0; | ||||
| 	if(w > 0) { l = l % Math.pow(2,32); h += w; } | ||||
| 	var o = new_buf(8); o.write_shift(4, l); o.write_shift(4, h); return o; | ||||
| } | ||||
| 
 | ||||
| /* [MS-OSHARED] 2.3.3.1.4 Lpstr */ | ||||
| function parse_lpstr(blob, type, pad) { | ||||
| @ -4279,6 +4309,7 @@ function parse_dictionary(blob,CodePage) { | ||||
| 		var pid = blob.read_shift(4); | ||||
| 		var len = blob.read_shift(4); | ||||
| 		dict[pid] = blob.read_shift(len, (CodePage === 0x4B0 ?'utf16le':'utf8')).replace(chr0,'').replace(chr1,'!'); | ||||
| 		if(CodePage === 0x4B0 && (len % 2)) blob.l += 2; | ||||
| 	} | ||||
| 	if(blob.l & 3) blob.l = (blob.l>>2+1)<<2; | ||||
| 	return dict; | ||||
| @ -4326,6 +4357,25 @@ function parse_TypedPropertyValue(blob, type, _opts) { | ||||
| 		default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + t); | ||||
| 	} | ||||
| } | ||||
| function write_TypedPropertyValue(type, value) { | ||||
| 	var o = new_buf(4), p = new_buf(4); | ||||
| 	o.write_shift(4, type == 0x50 ? 0x1F : type); | ||||
| 	switch(type) { | ||||
| 		case 0x03 /*VT_I4*/: p.write_shift(-4, value); break; | ||||
| 		case 0x05 /*VT_I4*/: p = new_buf(8); p.write_shift(8, value, 'f'); break; | ||||
| 		case 0x0B /*VT_BOOL*/: p.write_shift(4, value ? 0x01 : 0x00); break; | ||||
| 		case 0x40 /*VT_FILETIME*/: p = write_FILETIME(value); break; | ||||
| 		case 0x1F /*VT_LPWSTR*/: | ||||
| 		case 0x50 /*VT_STRING*/: | ||||
| 			p = new_buf(4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2)); | ||||
| 			p.write_shift(4, value.length + 1); | ||||
| 			p.write_shift(0, value, "dbcs"); | ||||
| 			while(p.l != p.length) p.write_shift(1, 0); | ||||
| 			break; | ||||
| 		default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + value); | ||||
| 	} | ||||
| 	return bconcat([o, p]); | ||||
| } | ||||
| 
 | ||||
| /* [MS-OLEPS] 2.20 PropertySet */ | ||||
| function parse_PropertySet(blob, PIDSI) { | ||||
| @ -4356,7 +4406,7 @@ function parse_PropertySet(blob, PIDSI) { | ||||
| 		if(PIDSI) { | ||||
| 			var piddsi = PIDSI[Props[i][0]]; | ||||
| 			PropH[piddsi.n] = parse_TypedPropertyValue(blob, piddsi.t, {raw:true}); | ||||
| 			if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + String(PropH[piddsi.n] & 0xFFFF); | ||||
| 			if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + ("0000" + String(PropH[piddsi.n] & 0xFFFF)).slice(-4); | ||||
| 			if(piddsi.n == "CodePage") switch(PropH[piddsi.n]) { | ||||
| 				case 0: PropH[piddsi.n] = 1252; | ||||
| 					/* falls through */ | ||||
| @ -4401,8 +4451,8 @@ function parse_PropertySet(blob, PIDSI) { | ||||
| 				/* [MS-OSHARED] 2.3.3.2.3.1.2 + PROPVARIANT */ | ||||
| 				switch(blob[blob.l]) { | ||||
| 					case 0x41 /*VT_BLOB*/: blob.l += 4; val = parse_BLOB(blob); break; | ||||
| 					case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break; | ||||
| 					case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break; | ||||
| 					case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break; | ||||
| 					case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break; | ||||
| 					case 0x03 /*VT_I4*/: blob.l += 4; val = blob.read_shift(4, 'i'); break; | ||||
| 					case 0x13 /*VT_UI4*/: blob.l += 4; val = blob.read_shift(4); break; | ||||
| 					case 0x05 /*VT_R8*/: blob.l += 4; val = blob.read_shift(8, 'f'); break; | ||||
| @ -4417,6 +4467,79 @@ function parse_PropertySet(blob, PIDSI) { | ||||
| 	blob.l = start_addr + size; /* step ahead to skip padding */ | ||||
| 	return PropH; | ||||
| } | ||||
| var XLSPSSkip = [ "CodePage", "Thumbnail", "_PID_LINKBASE", "_PID_HLINKS", "SystemIdentifier", "FMTID" ].concat(PseudoPropsPairs); | ||||
| function guess_property_type(val) { | ||||
| 	switch(typeof val) { | ||||
| 		case "boolean": return 0x0B; | ||||
| 		case "number": return ((val|0)==val) ? 0x03 : 0x05; | ||||
| 		case "string": return 0x1F; | ||||
| 		case "object": if(val instanceof Date) return 0x40; break; | ||||
| 	} | ||||
| 	return -1; | ||||
| } | ||||
| function write_PropertySet(entries, RE, PIDSI) { | ||||
| 	var hdr = new_buf(8), piao = [], prop = []; | ||||
| 	var sz = 8, i = 0; | ||||
| 
 | ||||
| 	var pr = new_buf(8), pio = new_buf(8); | ||||
| 	pr.write_shift(4, 0x0002); | ||||
| 	pr.write_shift(4, 0x04B0); | ||||
| 	pio.write_shift(4, 0x0001); | ||||
| 	prop.push(pr); piao.push(pio); | ||||
| 	sz += 8 + pr.length; | ||||
| 
 | ||||
| 	if(!RE) { | ||||
| 		pio = new_buf(8); | ||||
| 		pio.write_shift(4, 0); | ||||
| 		piao.unshift(pio); | ||||
| 
 | ||||
| 		var bufs = [new_buf(4)]; | ||||
| 		bufs[0].write_shift(4, entries.length); | ||||
| 		for(i = 0; i < entries.length; ++i) { | ||||
| 			var value = entries[i][0]; | ||||
| 			pr = new_buf(4 + 4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2)); | ||||
| 			pr.write_shift(4, i+2); | ||||
| 			pr.write_shift(4, value.length + 1); | ||||
| 			pr.write_shift(0, value, "dbcs"); | ||||
| 			while(pr.l != pr.length) pr.write_shift(1, 0); | ||||
| 			bufs.push(pr); | ||||
| 		} | ||||
| 		pr = bconcat(bufs); | ||||
| 		prop.unshift(pr); | ||||
| 		sz += 8 + pr.length; | ||||
| 	} | ||||
| 
 | ||||
| 	for(i = 0; i < entries.length; ++i) { | ||||
| 		if(RE && !RE[entries[i][0]]) continue; | ||||
| 		if(XLSPSSkip.indexOf(entries[i][0]) > -1) continue; | ||||
| 		if(entries[i][1] == null) continue; | ||||
| 
 | ||||
| 		var val = entries[i][1], idx = 0; | ||||
| 		if(RE) { | ||||
| 			idx = +RE[entries[i][0]]; | ||||
| 			var pinfo = PIDSI[idx]; | ||||
| 			if(pinfo.p == "version" && typeof val == "string") val = (+((val = val.split("."))[0])<<16) + (+val[1]||0); | ||||
| 			pr = write_TypedPropertyValue(pinfo.t, val); | ||||
| 		} else { | ||||
| 			var T = guess_property_type(val); | ||||
| 			if(T == -1) { T = 0x1F; val = String(val); } | ||||
| 			pr = write_TypedPropertyValue(T, val); | ||||
| 		} | ||||
| 		prop.push(pr); | ||||
| 
 | ||||
| 		pio = new_buf(8); | ||||
| 		pio.write_shift(4, !RE ? 2+i : idx); | ||||
| 		piao.push(pio); | ||||
| 
 | ||||
| 		sz += 8 + pr.length; | ||||
| 	} | ||||
| 
 | ||||
| 	var w = 8 * (prop.length + 1); | ||||
| 	for(i = 0; i < prop.length; ++i) { piao[i].write_shift(4, w); w += prop[i].length; } | ||||
| 	hdr.write_shift(4, sz); | ||||
| 	hdr.write_shift(4, prop.length); | ||||
| 	return bconcat([hdr].concat(piao).concat(prop)); | ||||
| } | ||||
| 
 | ||||
| /* [MS-OLEPS] 2.21 PropertySetStream */ | ||||
| function parse_PropertySetStream(file, PIDSI, clsid) { | ||||
| @ -4453,7 +4576,27 @@ function parse_PropertySetStream(file, PIDSI, clsid) { | ||||
| 	rval.FMTID = [FMTID0, FMTID1]; // TODO: verify FMTID0/1
 | ||||
| 	return rval; | ||||
| } | ||||
| function write_PropertySetStream(entries, clsid, RE, PIDSI, entries2, clsid2) { | ||||
| 	var hdr = new_buf(entries2 ? 68 : 48); | ||||
| 	var bufs = [hdr]; | ||||
| 	hdr.write_shift(2, 0xFFFE); | ||||
| 	hdr.write_shift(2, 0x0000); /* TODO: type 1 props */ | ||||
| 	hdr.write_shift(4, 0x32363237); | ||||
| 	hdr.write_shift(16, CFB.utils.consts.HEADER_CLSID, "hex"); | ||||
| 	hdr.write_shift(4, (entries2 ? 2 : 1)); | ||||
| 	hdr.write_shift(16, clsid, "hex"); | ||||
| 	hdr.write_shift(4, (entries2 ? 68 : 48)); | ||||
| 	var ps0 = write_PropertySet(entries, RE, PIDSI); | ||||
| 	bufs.push(ps0); | ||||
| 
 | ||||
| 	if(entries2) { | ||||
| 		var ps1 = write_PropertySet(entries2, null, null); | ||||
| 		hdr.write_shift(16, clsid2, "hex"); | ||||
| 		hdr.write_shift(4, 68 + ps0.length); | ||||
| 		bufs.push(ps1); | ||||
| 	} | ||||
| 	return bconcat(bufs); | ||||
| } | ||||
| 
 | ||||
| function parsenoop2(blob, length) { blob.read_shift(length); return null; } | ||||
| function writezeroes(n, o) { if(!o) o=new_buf(n); for(var j=0; j<n; ++j) o.write_shift(1, 0); return o; } | ||||
| @ -6068,6 +6211,7 @@ var SYLK = (function() { | ||||
| 					formats.push(rstr.slice(3).replace(/;;/g, ";")); | ||||
| 				break; | ||||
| 			case 'C': | ||||
| 			var C_seen_K = false; | ||||
| 			for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) { | ||||
| 				case 'X': C = parseInt(record[rj].slice(1))-1; break; | ||||
| 				case 'Y': | ||||
| @ -6085,15 +6229,16 @@ var SYLK = (function() { | ||||
| 					} else if(!isNaN(fuzzydate(val).getDate())) { | ||||
| 						val = parseDate(val); | ||||
| 					} | ||||
| 					arr[R][C] = val; | ||||
| 					next_cell_format = null; | ||||
| 					C_seen_K = true; | ||||
| 					break; | ||||
| 				case 'E': | ||||
| 					var formula = rc_to_a1(record[rj].slice(1), {r:R,c:C}); | ||||
| 					arr[R][C] = [arr[R][C], formula]; | ||||
| 					break; | ||||
| 				default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr); | ||||
| 			} break; | ||||
| 			} | ||||
| 			if(C_seen_K) { arr[R][C] = val; next_cell_format = null; } | ||||
| 			break; | ||||
| 			case 'F': | ||||
| 			var F_seen = 0; | ||||
| 			for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) { | ||||
| @ -6104,6 +6249,7 @@ var SYLK = (function() { | ||||
| 					break; | ||||
| 				case 'M': Mval = parseInt(record[rj].slice(1)) / 20; break; | ||||
| 				case 'F': break; /* ??? */ | ||||
| 				case 'G': break; /* hide grid */ | ||||
| 				case 'P': | ||||
| 					next_cell_format = formats[parseInt(record[rj].slice(1))]; | ||||
| 					break; | ||||
| @ -7701,6 +7847,7 @@ var XLMLPatternTypeMap = { | ||||
| function parse_borders(t, styles, themes, opts) { | ||||
| 	styles.Borders = []; | ||||
| 	var border = {}/*, sub_border = {}*/; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x); | ||||
| 		switch (y[0]) { | ||||
| @ -7759,7 +7906,13 @@ function parse_borders(t, styles, themes, opts) { | ||||
| 			case '<color': case '<color>': break; | ||||
| 			case '<color/>': case '</color>': break; | ||||
| 
 | ||||
| 			default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in borders'); | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in borders'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -7768,6 +7921,7 @@ function parse_borders(t, styles, themes, opts) { | ||||
| function parse_fills(t, styles, themes, opts) { | ||||
| 	styles.Fills = []; | ||||
| 	var fill = {}; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x); | ||||
| 		switch(y[0]) { | ||||
| @ -7818,7 +7972,13 @@ function parse_fills(t, styles, themes, opts) { | ||||
| 			case '<color': case '<color/>': break; | ||||
| 			case '</color>': break; | ||||
| 
 | ||||
| 			default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills'); | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in fills'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -7827,6 +7987,7 @@ function parse_fills(t, styles, themes, opts) { | ||||
| function parse_fonts(t, styles, themes, opts) { | ||||
| 	styles.Fonts = []; | ||||
| 	var font = {}; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x); | ||||
| 		switch (y[0]) { | ||||
| @ -7927,7 +8088,13 @@ function parse_fonts(t, styles, themes, opts) { | ||||
| 				break; | ||||
| 			case '<color/>': case '</color>': break; | ||||
| 
 | ||||
| 			default: if(opts && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fonts'); | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in fonts'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -7977,6 +8144,7 @@ var cellXF_bool = [ "applyAlignment", "applyBorder", "applyFill", "applyFont", " | ||||
| function parse_cellXfs(t, styles, opts) { | ||||
| 	styles.CellXf = []; | ||||
| 	var xf; | ||||
| 	var pass = false; | ||||
| 	t[0].match(tagregex).forEach(function(x) { | ||||
| 		var y = parsexmltag(x), i = 0; | ||||
| 		switch(y[0]) { | ||||
| @ -8012,9 +8180,12 @@ function parse_cellXfs(t, styles, opts) { | ||||
| 			case '<protection': case '</protection>': case '<protection/>': break; | ||||
| 
 | ||||
| 			/* 18.2.10 extLst CT_ExtensionList ? */ | ||||
| 			case '<extLst': case '</extLst>': break; | ||||
| 			case '<ext': break; | ||||
| 			default: if(opts.WTF) throw new Error('unrecognized ' + y[0] + ' in cellXfs'); | ||||
| 			case '<extLst': case '<extLst>': case '</extLst>': break; | ||||
| 			case '<ext': pass = true; break; | ||||
| 			case '</ext>': pass = false; break; | ||||
| 			default: if(opts && opts.WTF) { | ||||
| 				if(!pass) throw new Error('unrecognized ' + y[0] + ' in cellXfs'); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| } | ||||
| @ -9585,6 +9756,7 @@ function parse_SerAr(blob, biff) { | ||||
| 		case 0x04: /* SerBool -- boolean */ | ||||
| 			val[1] = parsebool(blob, 1) ? 'TRUE' : 'FALSE'; | ||||
| 			if(biff != 12) blob.l += 7; break; | ||||
| 		case 0x25: /* appears to be an alias */ | ||||
| 		case 0x10: /* SerErr -- error */ | ||||
| 			val[1] = BErr[blob[blob.l]]; | ||||
| 			blob.l += ((biff == 12) ? 4 : 8); break; | ||||
| @ -9594,7 +9766,7 @@ function parse_SerAr(blob, biff) { | ||||
| 			val[1] = parse_Xnum(blob, 8); break; | ||||
| 		case 0x02: /* SerStr -- XLUnicodeString (<256 chars) */ | ||||
| 			val[1] = parse_XLUnicodeString2(blob, 0, {biff:biff > 0 && biff < 8 ? 2 : biff}); break; | ||||
| 		default: throw "Bad SerAr: " + val[0]; /* Unreachable */ | ||||
| 		default: throw new Error("Bad SerAr: " + val[0]); /* Unreachable */ | ||||
| 	} | ||||
| 	return val; | ||||
| } | ||||
| @ -16164,21 +16336,51 @@ if(!cur_sheet) Workbook.WBProps.CodeName = val || "ThisWorkbook"; | ||||
| 	return wb; | ||||
| } | ||||
| 
 | ||||
| /* TODO: WTF */ | ||||
| function parse_props(cfb, props, o) { | ||||
| /* TODO: split props*/ | ||||
| var PSCLSID = { | ||||
| 	SI: "e0859ff2f94f6810ab9108002b27b3d9", | ||||
| 	DSI: "02d5cdd59c2e1b10939708002b2cf9ae", | ||||
| 	UDI: "05d5cdd59c2e1b10939708002b2cf9ae" | ||||
| }; | ||||
| function parse_xls_props(cfb, props, o) { | ||||
| 	/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */ | ||||
| 	var DSI = CFB.find(cfb, '!DocumentSummaryInformation'); | ||||
| 	if(DSI && DSI.size > 0) try { | ||||
| 		var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, "02d5cdd59c2e1b10939708002b2cf9ae"); | ||||
| 		var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, PSCLSID.DSI); | ||||
| 		for(var d in DocSummary) props[d] = DocSummary[d]; | ||||
| 	} catch(e) {if(o.WTF) throw e;/* empty */} | ||||
| 
 | ||||
| 	/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/ | ||||
| 	var SI = CFB.find(cfb, '!SummaryInformation'); | ||||
| 	if(SI && SI.size > 0) try { | ||||
| 		var Summary = parse_PropertySetStream(SI, SummaryPIDSI, "e0859ff2f94f6810ab9108002b27b3d9"); | ||||
| 		var Summary = parse_PropertySetStream(SI, SummaryPIDSI, PSCLSID.SI); | ||||
| 		for(var s in Summary) if(props[s] == null) props[s] = Summary[s]; | ||||
| 	} catch(e) {if(o.WTF) throw e;/* empty */} | ||||
| 
 | ||||
| 	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, cfb) { | ||||
| 	var DSEntries = [], SEntries = [], CEntries = []; | ||||
| 	var i = 0, Keys; | ||||
| 	if(wb.Props) { | ||||
| 		Keys = keys(wb.Props); | ||||
| 		for(i = 0; i < Keys.length; ++i) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Props[Keys[i]]]); | ||||
| 	} | ||||
| 	if(wb.Custprops) { | ||||
| 		Keys = keys(wb.Custprops); | ||||
| 		for(i = 0; i < Keys.length; ++i) if(!wb.Props.hasOwnProperty(Keys[i])) (DocSummaryRE.hasOwnProperty(Keys[i]) ? DSEntries : SummaryRE.hasOwnProperty(Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Custprops[Keys[i]]]); | ||||
| 	} | ||||
| 	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)); | ||||
| } | ||||
| 
 | ||||
| function parse_xlscfb(cfb, options) { | ||||
| @ -16218,7 +16420,7 @@ else { | ||||
| } | ||||
| 
 | ||||
| var props = {}; | ||||
| if(cfb.FullPaths) parse_props(cfb, props, options); | ||||
| if(cfb.FullPaths) parse_xls_props(cfb, props, options); | ||||
| 
 | ||||
| WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */ | ||||
| if(options.bookFiles) WorkbookP.cfb = cfb; | ||||
| @ -16241,6 +16443,7 @@ function write_xlscfb(wb, opts) { | ||||
| 		default: throw new Error("invalid type " + o.bookType + " for XLS CFB"); | ||||
| 	} | ||||
| 	CFB.utils.cfb_add(cfb, wbpath, write_biff_buf(wb, o)); | ||||
| 	if(o.biff == 8 && (wb.Props || wb.Custprops)) write_xls_props(wb, cfb); | ||||
| 	// TODO: SI, DSI, CO
 | ||||
| 	if(o.biff == 8 && wb.vbaraw) fill_vba_xls(cfb, CFB.read(wb.vbaraw, {type: typeof wb.vbaraw == "string" ? "binary" : "buffer"})); | ||||
| 	return cfb; | ||||
| @ -17629,7 +17832,7 @@ function write_FEAT(ba, ws) { | ||||
| 	o.write_shift(4, 0x868); o.write_shift(4, 0); o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 3); o.write_shift(1, 0); o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 1); o.write_shift(4, 4); o.write_shift(2, 0); | ||||
| 	write_Ref8U(safe_decode_range(ws['!ref']), o); | ||||
| 	write_Ref8U(safe_decode_range(ws['!ref']||"A1"), o); | ||||
| 	o.write_shift(4, 4); | ||||
| 	write_biff_rec(ba, "Feat", o); | ||||
| } | ||||
| @ -17852,11 +18055,11 @@ var HTML_ = (function() { | ||||
| 			var row = rows[i].trim(); | ||||
| 			var hd = row.slice(0,3).toLowerCase(); | ||||
| 			if(hd == "<tr") { ++R; if(opts.sheetRows && opts.sheetRows <= R) { --R; break; } C = 0; continue; } | ||||
| 			if(hd != "<td") continue; | ||||
| 			var cells = row.split(/<\/td>/i); | ||||
| 			if(hd != "<td" && hd != "<th") continue; | ||||
| 			var cells = row.split(/<\/t[dh]>/i); | ||||
| 			for(j = 0; j < cells.length; ++j) { | ||||
| 				var cell = cells[j].trim(); | ||||
| 				if(cell.slice(0,3).toLowerCase() != "<td") continue; | ||||
| 				if(!cell.match(/<t[dh]/i)) continue; | ||||
| 				var m = cell, cc = 0; | ||||
| 				/* TODO: parse styles etc */ | ||||
| 				while(m.charAt(0) == "<" && (cc = m.indexOf(">")) > -1) m = m.slice(cc+1); | ||||
| @ -17991,7 +18194,7 @@ function parse_dom_table(table, _opts) { | ||||
| 			C += CS; | ||||
| 		} | ||||
| 	} | ||||
| 	ws['!merges'] = merges; | ||||
| 	if(merges.length) ws['!merges'] = merges; | ||||
| 	ws['!ref'] = encode_range(range); | ||||
| 	if(sheetRows < rows.length) ws['!fullref'] = encode_range((range.e.r = rows.length-1,range)); | ||||
| 	return ws; | ||||
| @ -18919,7 +19122,7 @@ function parse_zip(zip, opts) { | ||||
| 	var styles = ({}); | ||||
| 	if(!opts.bookSheets && !opts.bookProps) { | ||||
| 		strs = []; | ||||
| 		if(dir.sst) strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts); | ||||
| 		if(dir.sst) try { strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts); } catch(e) { if(opts.WTF) throw e; } | ||||
| 
 | ||||
| 		if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipstr(zip, dir.themes[0].replace(/^\//,''), true)||"",dir.themes[0], opts); | ||||
| 
 | ||||
| @ -19345,7 +19548,7 @@ function write_string_type(out, opts, bom) { | ||||
| 		case "string": return out; | ||||
| 		case "file": return write_dl(opts.file, o, 'utf8'); | ||||
| 		case "buffer": { | ||||
| 			if(has_buf) return new Buffer(o, 'utf8'); | ||||
| 			if(has_buf) return Buffer.from(o, 'utf8'); | ||||
| 			else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); }); | ||||
| 		} | ||||
| 	} | ||||
| @ -19359,7 +19562,7 @@ function write_stxt_type(out, opts) { | ||||
| 		case "string": return out; /* override in sheet_to_txt */ | ||||
| 		case "file": return write_dl(opts.file, out, 'binary'); | ||||
| 		case "buffer": { | ||||
| 			if(has_buf) return new Buffer(out, 'binary'); | ||||
| 			if(has_buf) return Buffer.from(out, 'binary'); | ||||
| 			else return out.split("").map(function(c) { return c.charCodeAt(0); }); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user