styled-exceljs 0.21.1 → 0.21.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/xlsx.mjs CHANGED
@@ -3,7 +3,7 @@
3
3
  /*exported XLSX */
4
4
  /*global process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false */
5
5
  var XLSX = {};
6
- XLSX.version = '0.21.1';
6
+ XLSX.version = '0.21.3';
7
7
  var current_codepage = 1200, current_ansi = 1252;
8
8
  /*:: declare var cptable:any; */
9
9
  /*global cptable:true, window */
@@ -158,9 +158,9 @@ function Base64_decode(input) {
158
158
  var o = "";
159
159
  var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0;
160
160
  if (input.slice(0, 5) == "data:") {
161
- var i = input.slice(0, 1024).indexOf(";base64,");
162
- if (i > -1)
163
- input = input.slice(i + 8);
161
+ var sep = input.slice(0, 1024).indexOf(";base64,");
162
+ if (sep > -1)
163
+ input = input.slice(sep + 8);
164
164
  }
165
165
  input = input.replace(/[^\w\+\/\=]/g, "");
166
166
  for (var i = 0; i < input.length; ) {
@@ -3300,7 +3300,7 @@ function blobify(data) {
3300
3300
  }
3301
3301
  /* write or download file */
3302
3302
  function write_dl(fname/*:string*/, payload/*:any*/, enc/*:?string*/) {
3303
- /*global IE_SaveFile, Blob, navigator, saveAs, document, File, chrome */
3303
+ /*global IE_SaveFile, navigator, saveAs, document, chrome */
3304
3304
  if(typeof _fs !== 'undefined' && _fs.writeFileSync) return enc ? _fs.writeFileSync(fname, payload, enc) : _fs.writeFileSync(fname, payload);
3305
3305
  if(typeof Deno !== 'undefined') {
3306
3306
  /* in this spot, it's safe to assume typed arrays and TextEncoder/TextDecoder exist */
@@ -3953,6 +3953,19 @@ function escapexlml(text/*:string*/)/*:string*/{
3953
3953
  return s.replace(decregex, function(y) { return rencoding[y]; }).replace(htmlcharegex,function(s) { return "&#x" + (s.charCodeAt(0).toString(16)).toUpperCase() + ";"; });
3954
3954
  }
3955
3955
 
3956
+ /* Extract text from XML fragments in linear time. This is a parser helper,
3957
+ * not an HTML sanitizer: text is escaped separately at HTML output boundaries. */
3958
+ function strip_xml_tags(text/*:string*/)/*:string*/ {
3959
+ var str = String(text), out = [], inTag = false;
3960
+ for(var i = 0; i < str.length; ++i) {
3961
+ var cc = str.charCodeAt(i);
3962
+ if(!inTag && cc == 60 /* < */) inTag = true;
3963
+ else if(inTag && cc == 62 /* > */) inTag = false;
3964
+ else if(!inTag) out.push(str.charAt(i));
3965
+ }
3966
+ return out.join("");
3967
+ }
3968
+
3956
3969
  /* TODO: handle codepages */
3957
3970
  var xlml_fixstr/*:StringConv*/ = /*#__PURE__*/(function() {
3958
3971
  var entregex = /&#(\d+);/g;
@@ -4059,8 +4072,8 @@ var htmldecode/*:{(s:string):string}*/ = /*#__PURE__*/(function() {
4059
4072
  .replace(/[\t\n\r ]+/g, " ")
4060
4073
  // Replace <br> tags with new lines
4061
4074
  .replace(/<\s*[bB][rR]\s*\/?>/g,"\n")
4062
- // Strip HTML elements
4063
- .replace(/<[^<>]*>/g,"");
4075
+ ;
4076
+ o = strip_xml_tags(o);
4064
4077
  for(var i = 0; i < entities.length; ++i) o = o.replace(entities[i][0], entities[i][1]);
4065
4078
  return o;
4066
4079
  };
@@ -4638,9 +4651,25 @@ function format_cell(cell/*:Cell*/, v/*:any*/, o/*:any*/) {
4638
4651
  return safe_format_cell(cell, v);
4639
4652
  }
4640
4653
 
4654
+ /* Worksheet names are document-controlled. A normal object treats
4655
+ * "__proto__" as a setter, so all workbook sheet maps must use an own-property
4656
+ * preserving dictionary and all lookups must reject inherited properties. */
4657
+ function sheet_map_new() {
4658
+ return Object.create ? Object.create(null) : {};
4659
+ }
4660
+ function sheet_map_set(sheets, name/*:string*/, sheet/*:Worksheet*/) {
4661
+ if(name == "__proto__" && Object.defineProperty) Object.defineProperty(sheets, name, {
4662
+ value: sheet, configurable: true, enumerable: true, writable: true
4663
+ });
4664
+ else sheets[name] = sheet;
4665
+ }
4666
+ function sheet_map_get(sheets, name/*:string*/)/*:?Worksheet*/ {
4667
+ return sheets != null && Object.prototype.hasOwnProperty.call(sheets, name) ? sheets[name] : void 0;
4668
+ }
4669
+
4641
4670
  function sheet_to_workbook(sheet/*:Worksheet*/, opts)/*:Workbook*/ {
4642
4671
  var n = opts && opts.sheet ? opts.sheet : "Sheet1";
4643
- var sheets = {}; sheets[n] = sheet;
4672
+ var sheets = sheet_map_new(); sheet_map_set(sheets, n, sheet);
4644
4673
  return { SheetNames: [n], Sheets: sheets };
4645
4674
  }
4646
4675
 
@@ -6315,8 +6344,8 @@ function parse_TypedPropertyValue(blob, type/*:number*/, _opts)/*:any*/ {
6315
6344
  case 0x03 /*VT_I4*/: ret = blob.read_shift(4, 'i'); return ret;
6316
6345
  case 0x0B /*VT_BOOL*/: return blob.read_shift(4) !== 0x0;
6317
6346
  case 0x13 /*VT_UI4*/: ret = blob.read_shift(4); return ret;
6318
- case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
6319
- case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
6347
+ case 0x1E /*VT_LPSTR*/: blob.l += 4; return parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1");
6348
+ case 0x1F /*VT_LPWSTR*/: blob.l += 4; return parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1");
6320
6349
  case 0x40 /*VT_FILETIME*/: return parse_FILETIME(blob);
6321
6350
  case 0x41 /*VT_BLOB*/: return parse_BLOB(blob);
6322
6351
  case 0x47 /*VT_CF*/: return parse_ClipboardData(blob);
@@ -6827,7 +6856,6 @@ function parse_LongRGBA(blob/*::, length*/) { var r = blob.read_shift(1), g = bl
6827
6856
  /* 2.5.177 LongRGB */
6828
6857
  function parse_LongRGB(blob, length) { var x = parse_LongRGBA(blob, length); x[3] = 0; return x; }
6829
6858
 
6830
-
6831
6859
  /* [MS-XLS] 2.5.19 */
6832
6860
  function parse_XLSCell(blob, length, opts)/*:Cell*/ {
6833
6861
  var rw = blob.read_shift(2); // 0-indexed
@@ -8290,7 +8318,7 @@ function dbf_to_workbook(buf, opts)/*:Workbook*/ {
8290
8318
  o.bookType = "dbf";
8291
8319
  return o;
8292
8320
  } catch(e) { if(opts && opts.WTF) throw e; }
8293
- return ({SheetNames:[],Sheets:{}});
8321
+ return ({SheetNames:[],Sheets:sheet_map_new()});
8294
8322
  }
8295
8323
 
8296
8324
  var _RLEN = { 'B': 8, 'C': 250, 'L': 1, 'D': 8, '?': 0, '': 0 };
@@ -9186,7 +9214,7 @@ function read_wb_TABL(d, opts) {
9186
9214
  try {
9187
9215
  var out = DIF.to_workbook(d, o);
9188
9216
  if(!out || !out.Sheets) throw "DIF bad workbook";
9189
- var ws = out.Sheets[out.SheetNames[0]];
9217
+ var ws = sheet_map_get(out.Sheets, out.SheetNames[0]);
9190
9218
  if(!ws || !ws["!ref"]) throw "DIF empty worksheet";
9191
9219
  o.WTF = OLD_WTF;
9192
9220
  return out;
@@ -9242,7 +9270,7 @@ var WK_ = /*#__PURE__*/(function() {
9242
9270
  var o = opts || {};
9243
9271
  if(DENSE != null && o.dense == null) o.dense = DENSE;
9244
9272
  var s/*:Worksheet*/ = ({}/*:any*/), n = "Sheet1", next_n = "", sidx = 0;
9245
- var sheets = {}, snames = [], realnames = [], sdata = [];
9273
+ var sheets = sheet_map_new(), snames = [], realnames = [], sdata = [];
9246
9274
  if(o.dense) sdata = s["!data"] = [];
9247
9275
 
9248
9276
  var refguess = {s: {r:0, c:0}, e: {r:0, c:0} };
@@ -9287,7 +9315,7 @@ var WK_ = /*#__PURE__*/(function() {
9287
9315
  if(o.qpro) {
9288
9316
  if(val[3] > sidx) {
9289
9317
  s["!ref"] = encode_range(refguess);
9290
- sheets[n] = s;
9318
+ sheet_map_set(sheets, n, s);
9291
9319
  snames.push(n);
9292
9320
  s = ({}/*:any*/); if(o.dense) sdata = s["!data"] = [];
9293
9321
  refguess = {s: {r:0, c:0}, e: {r:0, c:0} };
@@ -9338,7 +9366,7 @@ var WK_ = /*#__PURE__*/(function() {
9338
9366
  case 0x28: /* FORMULA28 */
9339
9367
  if(val[3] > sidx) {
9340
9368
  s["!ref"] = encode_range(refguess);
9341
- sheets[n] = s;
9369
+ sheet_map_set(sheets, n, s);
9342
9370
  snames.push(n);
9343
9371
  s = ({}/*:any*/); if(o.dense) sdata = s["!data"] = [];
9344
9372
  refguess = {s: {r:0, c:0}, e: {r:0, c:0} };
@@ -9361,17 +9389,17 @@ var WK_ = /*#__PURE__*/(function() {
9361
9389
  }}, o);
9362
9390
  } else throw new Error("Unrecognized LOTUS BOF " + d[2]);
9363
9391
  s["!ref"] = encode_range(refguess);
9364
- sheets[next_n || n] = s;
9392
+ sheet_map_set(sheets, next_n || n, s);
9365
9393
  snames.push(next_n || n);
9366
9394
  if(!realnames.length) return { SheetNames: snames, Sheets: sheets };
9367
- var osheets = {}, rnames = [];
9395
+ var osheets = sheet_map_new(), rnames = [];
9368
9396
  /* TODO: verify no collisions */
9369
- for(var i = 0; i < realnames.length; ++i) if(sheets[snames[i]]) {
9397
+ for(var i = 0; i < realnames.length; ++i) if(sheet_map_get(sheets, snames[i])) {
9370
9398
  rnames.push(realnames[i] || snames[i]);
9371
- osheets[realnames[i]] = sheets[realnames[i]] || sheets[snames[i]];
9399
+ sheet_map_set(osheets, realnames[i] || snames[i], sheet_map_get(sheets, realnames[i]) || sheet_map_get(sheets, snames[i]));
9372
9400
  } else {
9373
9401
  rnames.push(realnames[i]);
9374
- osheets[realnames[i]] = ({ "!ref": "A1" });
9402
+ sheet_map_set(osheets, realnames[i], ({ "!ref": "A1" }));
9375
9403
  }
9376
9404
  return { SheetNames: rnames, Sheets: osheets };
9377
9405
  }
@@ -9425,11 +9453,11 @@ var WK_ = /*#__PURE__*/(function() {
9425
9453
 
9426
9454
  write_biff_rec(ba, 0x00, write_BOF_WK3(wb));
9427
9455
 
9428
- for(var i = 0, cnt = 0; i < wb.SheetNames.length; ++i) if((wb.Sheets[wb.SheetNames[i]] || {})["!ref"]) write_biff_rec(ba, 0x1b, write_XFORMAT_SHEETNAME(wb.SheetNames[i], cnt++));
9456
+ for(var i = 0, cnt = 0; i < wb.SheetNames.length; ++i) if((sheet_map_get(wb.Sheets, wb.SheetNames[i]) || {})["!ref"]) write_biff_rec(ba, 0x1b, write_XFORMAT_SHEETNAME(wb.SheetNames[i], cnt++));
9429
9457
 
9430
9458
  var wsidx = 0;
9431
9459
  for(i = 0; i < wb.SheetNames.length; ++i) {
9432
- var ws = wb.Sheets[wb.SheetNames[i]];
9460
+ var ws = sheet_map_get(wb.Sheets, wb.SheetNames[i]);
9433
9461
  if(!ws || !ws["!ref"]) continue;
9434
9462
  var range = safe_decode_range(ws["!ref"]);
9435
9463
  var dense = ws["!data"] != null;
@@ -9474,7 +9502,7 @@ var WK_ = /*#__PURE__*/(function() {
9474
9502
  var rows = 0, cols = 0, wscnt = 0;
9475
9503
  for(var i = 0; i < wb.SheetNames.length; ++i) {
9476
9504
  var name = wb.SheetNames[i];
9477
- var ws = wb.Sheets[name];
9505
+ var ws = sheet_map_get(wb.Sheets, name);
9478
9506
  if(!ws || !ws["!ref"]) continue;
9479
9507
  ++wscnt;
9480
9508
  var range = decode_range(ws["!ref"]);
@@ -10202,7 +10230,7 @@ var WK_ = /*#__PURE__*/(function() {
10202
10230
  var SST = [], sname = "", formulae = [];
10203
10231
  var range = {s:{r:-1,c:-1}, e:{r:-1,c:-1}};
10204
10232
  var cnt = 0, type = 0, C = 0, R = 0;
10205
- var wb = { SheetNames: [], Sheets: {} };
10233
+ var wb = { SheetNames: [], Sheets: sheet_map_new() };
10206
10234
  var FMTS = [];
10207
10235
  outer: while(d.l < d.length) {
10208
10236
  var RT = d.read_shift(2), length = d.read_shift(2);
@@ -10506,13 +10534,13 @@ var parse_rs = /*#__PURE__*/(function() {
10506
10534
 
10507
10535
  /* Parse a list of <r> tags */
10508
10536
  var rs_to_html = /*#__PURE__*/(function parse_rs_factory() {
10509
- var nlregex = /(\r\n|\n)/g;
10510
10537
  function parse_rpr2(font, intro, outro) {
10511
10538
  var style/*:Array<string>*/ = [];
10512
10539
 
10513
10540
  if(font.u) style.push("text-decoration: underline;");
10514
- if(font.uval) style.push("text-underline-style:" + font.uval + ";");
10515
- if(font.sz) style.push("font-size:" + font.sz + "pt;");
10541
+ if(font.uval && /^(?:single|double|single-accounting|double-accounting)$/.test(font.uval)) style.push("text-underline-style:" + font.uval + ";");
10542
+ var sz = +font.sz;
10543
+ if(isFinite(sz) && sz > 0) style.push("font-size:" + Math.min(sz, 409) + "pt;");
10516
10544
  if(font.outline) style.push("text-effect: outline;");
10517
10545
  if(font.shadow) style.push("text-shadow: auto;");
10518
10546
  intro.push('<span style="' + style.join("") + '">');
@@ -10537,7 +10565,7 @@ var rs_to_html = /*#__PURE__*/(function parse_rs_factory() {
10537
10565
 
10538
10566
  if(r.s) parse_rpr2(r.s, terms[0], terms[2]);
10539
10567
 
10540
- return terms[0].join("") + terms[1].replace(nlregex,'<br/>') + terms[2].join("");
10568
+ return terms[0].join("") + escapehtml(terms[1]) + terms[2].join("");
10541
10569
  }
10542
10570
 
10543
10571
  return function parse_rs(rs) {
@@ -11196,7 +11224,7 @@ function resolve_style_obj_color(obj, themes) {
11196
11224
 
11197
11225
  /* 18.3.1.13 width calculations */
11198
11226
  /* [MS-OI29500] 2.1.595 Column Width & Formatting */
11199
- var DEF_MDW = 6, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW;
11227
+ var DEF_MDW = 7, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW;
11200
11228
  function width2px(width) { return Math.floor(( width + (Math.round(128/MDW))/256 )* MDW ); }
11201
11229
  function px2char(px) { return (Math.floor((px - 5)/MDW * 100 + 0.5))/100; }
11202
11230
  function char2width(chr) { return (Math.round((chr * MDW + 5)/MDW*256))/256; }
@@ -11272,6 +11300,15 @@ function style_font_family(style) {
11272
11300
  var font = style && style.font || {};
11273
11301
  return font.name || "Calibri";
11274
11302
  }
11303
+ function css_string_escape(value/*:any*/, quote/*:string*/)/*:string*/ {
11304
+ var str = String(value), out = [];
11305
+ for(var i = 0; i < str.length; ++i) {
11306
+ var cc = str.charCodeAt(i), ch = str.charAt(i);
11307
+ if(ch == quote || ch == "\\" || cc < 32 || cc == 127 || ch == "<" || ch == ">" || ch == "&") out.push("\\" + cc.toString(16) + " ");
11308
+ else out.push(ch);
11309
+ }
11310
+ return out.join("");
11311
+ }
11275
11312
  function css_font_from_style(style) {
11276
11313
  var font = style && style.font || {};
11277
11314
  var parts = [];
@@ -11279,7 +11316,8 @@ function css_font_from_style(style) {
11279
11316
  if(font.bold) parts.push("bold");
11280
11317
  parts.push(style_font_size_pt(style) + "pt");
11281
11318
  var name = style_font_family(style);
11282
- if(/[,\s'"]/.test(name)) name = '"' + String(name).replace(/"/g, '\\"') + '"';
11319
+ if(/[,\s'"]/.test(name)) name = '"' + css_string_escape(name, '"') + '"';
11320
+ else name = css_string_escape(name, '"');
11283
11321
  parts.push(name);
11284
11322
  return parts.join(" ");
11285
11323
  }
@@ -13262,7 +13300,7 @@ function parse_drawing_anchor(data) {
13262
13300
  function parse_drawing_text(data) {
13263
13301
  var out = [];
13264
13302
  (data.match(/<a:t\b[^>]*>[\s\S]*?<\/a:t>/g)||[]).forEach(function(t) {
13265
- out.push(unescapexml(t.replace(/<[^>]*>/g, "")));
13303
+ out.push(unescapexml(strip_xml_tags(t)));
13266
13304
  });
13267
13305
  return out.join("");
13268
13306
  }
@@ -16643,7 +16681,25 @@ var mergecregex = /<(?:\w+:)?mergeCell ref=["'][A-Z0-9:]+['"]\s*[\/]?>/g;
16643
16681
  var hlinkregex = /<(?:\w+:)?hyperlink [^<>]*>/mg;
16644
16682
  var dimregex = /"(\w*:\w*)"/;
16645
16683
  var colregex = /<(?:\w+:)?col\b[^<>]*[\/]?>/g;
16646
- var afregex = /<(?:\w:)?autoFilter[^>]*([\/]|>([\s\S]*)<\/(?:\w:)?autoFilter)>/g;
16684
+ function match_ws_xml_autofilter(data/*:string*/)/*:?string*/ {
16685
+ var paired = str_match_xml_ns(data, "autoFilter");
16686
+ if(paired) return paired[0];
16687
+ var start = 0;
16688
+ while((start = data.indexOf("<", start)) != -1) {
16689
+ var end = data.indexOf(">", start + 1);
16690
+ if(end == -1) return null;
16691
+ var tag = data.slice(start + 1, end), p = 0;
16692
+ while(p < tag.length && tag.charCodeAt(p) <= 32) ++p;
16693
+ var nameEnd = p;
16694
+ while(nameEnd < tag.length && tag.charCodeAt(nameEnd) > 32 && tag.charAt(nameEnd) != "/") ++nameEnd;
16695
+ var name = tag.slice(p, nameEnd), colon = name.indexOf(":");
16696
+ if(colon != -1) name = name.slice(colon + 1);
16697
+ var tail = tag.slice(nameEnd).trim();
16698
+ if(name == "autoFilter" && tail.charAt(tail.length - 1) == "/") return data.slice(start, end + 1);
16699
+ start = end + 1;
16700
+ }
16701
+ return null;
16702
+ }
16647
16703
  var marginregex= /<(?:\w+:)?pageMargins[^<>]*\/>/g;
16648
16704
  var sheetprregex = /<(?:\w+:)?sheetPr\b[^<>]*?\/>/;
16649
16705
 
@@ -16692,8 +16748,8 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
16692
16748
  if(mtch) parse_ws_xml_data(mtch[1], s, opts, refguess, themes, styles, wb);
16693
16749
 
16694
16750
  /* 18.3.1.2 autoFilter CT_AutoFilter */
16695
- var afilter = data2.match(afregex);
16696
- if(afilter) s['!autofilter'] = parse_ws_xml_autofilter(afilter[0]);
16751
+ var afilter = match_ws_xml_autofilter(data2);
16752
+ if(afilter) s['!autofilter'] = parse_ws_xml_autofilter(afilter);
16697
16753
 
16698
16754
  /* 18.3.1.55 mergeCells CT_MergeCells */
16699
16755
  var merges/*:Array<Range>*/ = [];
@@ -16846,7 +16902,8 @@ function parse_ws_xml_cols(columns, cols) {
16846
16902
  var colm=parseInt(coll.min, 10)-1, colM=parseInt(coll.max,10)-1;
16847
16903
  if(coll.outlineLevel) coll.level = (+coll.outlineLevel || 0);
16848
16904
  delete coll.min; delete coll.max; coll.width = +coll.width;
16849
- if(!seencol && coll.width) { seencol = true; find_mdw_colw(coll.width); }
16905
+ /* OOXML widths share the workbook Normal-font MDW; do not infer a different scale per sheet. */
16906
+ if(!seencol && coll.width) { seencol = true; MDW = DEF_MDW; }
16850
16907
  process_col(coll);
16851
16908
  while(colm <= colM) columns[colm++] = dup(coll);
16852
16909
  }
@@ -17217,7 +17274,7 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
17217
17274
  'xmlns:r': XMLNS.r
17218
17275
  })];
17219
17276
  var s = wb.SheetNames[idx], sidx = 0, rdata = "";
17220
- var ws = wb.Sheets[s];
17277
+ var ws = sheet_map_get(wb.Sheets, s);
17221
17278
  if(ws == null) ws = {};
17222
17279
  var ref = ws['!ref'] || 'A1';
17223
17280
  var range = safe_decode_range(ref);
@@ -18017,7 +18074,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
18017
18074
  if(!opts.cellStyles) break;
18018
18075
  while(val.e >= val.s) {
18019
18076
  colinfo[val.e--] = { width: val.w/256, hidden: !!(val.flags & 0x01), level: val.level };
18020
- if(!seencol) { seencol = true; find_mdw_colw(val.w/256); }
18077
+ if(!seencol) { seencol = true; MDW = DEF_MDW; }
18021
18078
  process_col(colinfo[val.e+1]);
18022
18079
  }
18023
18080
  break;
@@ -18331,7 +18388,7 @@ function write_SHEETPROTECT(ba, ws) {
18331
18388
 
18332
18389
  function write_ws_bin(idx/*:number*/, opts, wb/*:Workbook*/, rels) {
18333
18390
  var ba = buf_array();
18334
- var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {};
18391
+ var s = wb.SheetNames[idx], ws = sheet_map_get(wb.Sheets, s) || {};
18335
18392
  var c/*:string*/ = s; try { if(wb && wb.Workbook) c = wb.Workbook.Sheets[idx].CodeName || c; } catch(e) {}
18336
18393
  var r = safe_decode_range(ws['!ref'] || "A1");
18337
18394
  if(r.e.c > 0x3FFF || r.e.r > 0xFFFFF) {
@@ -18399,7 +18456,7 @@ function parse_Cache(data/*:string*/)/*:[Array<number|string>, string, ?string]*
18399
18456
  /* 21.2.2.71 formatCode CT_Xstring */
18400
18457
  var nf = unescapexml((str_match_xml(data, "c:formatCode") || ["","General"])[1]);
18401
18458
 
18402
- (str_match_ng(data, "<c:f>", "</c:f>")||[]).forEach(function(F) { f = F.replace(/<[^<>]*>/g,""); });
18459
+ (str_match_ng(data, "<c:f>", "</c:f>")||[]).forEach(function(F) { f = strip_xml_tags(F); });
18403
18460
 
18404
18461
  return [col, nf, f];
18405
18462
  }
@@ -18416,7 +18473,7 @@ function parse_chart_cache(data) {
18416
18473
  return {values:s[0], formatCode:s[1], formula:s[2]};
18417
18474
  }
18418
18475
  var f = (str_match_ng(data, "<c:f>", "</c:f>")||[])[0];
18419
- return {values:[], formula:f ? f.replace(/<[^<>]*>/g,"") : void 0};
18476
+ return {values:[], formula:f ? strip_xml_tags(f) : void 0};
18420
18477
  }
18421
18478
 
18422
18479
  function parse_chart_tx(data) {
@@ -18448,7 +18505,7 @@ function parse_chart_title(data) {
18448
18505
  var title = str_match_xml_ns(data, "title");
18449
18506
  if(!title) return "";
18450
18507
  var out = [];
18451
- (title[0].match(/<a:t\b[^>]*>[\s\S]*?<\/a:t>/g)||[]).forEach(function(t) { out.push(unescapexml(t.replace(/<[^>]*>/g, ""))); });
18508
+ (title[0].match(/<a:t\b[^>]*>[\s\S]*?<\/a:t>/g)||[]).forEach(function(t) { out.push(unescapexml(strip_xml_tags(t))); });
18452
18509
  return out.join("");
18453
18510
  }
18454
18511
 
@@ -18753,9 +18810,13 @@ function check_wb(wb) {
18753
18810
  if(!wb.SheetNames.length) throw new Error("Workbook is empty");
18754
18811
  var Sheets = (wb.Workbook && wb.Workbook.Sheets) || [];
18755
18812
  check_wb_names(wb.SheetNames, Sheets, !!wb.vbaraw);
18756
- for(var i = 0; i < wb.SheetNames.length; ++i) check_ws(wb.Sheets[wb.SheetNames[i]], wb.SheetNames[i], i);
18813
+ for(var i = 0; i < wb.SheetNames.length; ++i) {
18814
+ var ws = sheet_map_get(wb.Sheets, wb.SheetNames[i]);
18815
+ if(!ws) throw new Error("Missing worksheet |" + wb.SheetNames[i] + "|");
18816
+ check_ws(ws, wb.SheetNames[i], i);
18817
+ }
18757
18818
  wb.SheetNames.forEach(function(n, i) {
18758
- var ws = wb.Sheets[n];
18819
+ var ws = sheet_map_get(wb.Sheets, n);
18759
18820
  if(!ws || !ws["!autofilter"]) return;
18760
18821
  var DN;
18761
18822
  if(!wb.Workbook) wb.Workbook = {};
@@ -19544,7 +19605,7 @@ function parse_xlml_data(xml, ss, data, cell/*:any*/, base, styles, csty, row, a
19544
19605
  break;
19545
19606
  case 'String':
19546
19607
  cell.t = 's'; cell.r = xlml_fixstr(unescapexml(xml));
19547
- cell.v = (xml.indexOf("<") > -1 ? unescapexml(ss||xml).replace(/<[^<>]*>/g, "") : cell.r); // todo: BR etc
19608
+ cell.v = (xml.indexOf("<") > -1 ? strip_xml_tags(unescapexml(ss||xml)) : cell.r); // todo: BR etc
19548
19609
  break;
19549
19610
  case 'DateTime':
19550
19611
  if(xml.slice(-1) != "Z") xml += "Z";
@@ -19639,7 +19700,7 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
19639
19700
  var Rn;
19640
19701
  var state = [], tmp;
19641
19702
  if(DENSE != null && opts.dense == null) opts.dense = DENSE;
19642
- var sheets = {}, sheetnames/*:Array<string>*/ = [], cursheet/*:Worksheet*/ = ({}), sheetname = ""; if(opts.dense) cursheet["!data"] = [];
19703
+ var sheets = sheet_map_new(), sheetnames/*:Array<string>*/ = [], cursheet/*:Worksheet*/ = ({}), sheetname = ""; if(opts.dense) cursheet["!data"] = [];
19643
19704
  var cell = ({}/*:any*/), row = {};// eslint-disable-line no-unused-vars
19644
19705
  var dtag = xlml_parsexmltag('<Data ss:Type="String">'), didx = 0;
19645
19706
  var c = 0, r = 0;
@@ -19746,7 +19807,7 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
19746
19807
  if(merges.length) cursheet["!merges"] = merges;
19747
19808
  if(cstys.length > 0) cursheet["!cols"] = cstys;
19748
19809
  if(rowinfo.length > 0) cursheet["!rows"] = rowinfo;
19749
- sheets[sheetname] = cursheet;
19810
+ sheet_map_set(sheets, sheetname, cursheet);
19750
19811
  } else {
19751
19812
  refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
19752
19813
  r = c = 0;
@@ -20651,7 +20712,7 @@ function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbo
20651
20712
  function write_ws_xlml(idx/*:number*/, opts, wb/*:Workbook*/)/*:string*/ {
20652
20713
  var o/*:Array<string>*/ = [];
20653
20714
  var s = wb.SheetNames[idx];
20654
- var ws = wb.Sheets[s];
20715
+ var ws = sheet_map_get(wb.Sheets, s);
20655
20716
 
20656
20717
  var t/*:string*/ = ws ? write_ws_xlml_names(ws, opts, idx, wb) : "";
20657
20718
  if(t.length > 0) o.push("<Names>" + t + "</Names>");
@@ -20885,7 +20946,7 @@ var parse_BIFFSurface = make_BIFFChartType("surfaceChart");
20885
20946
  // 2.3.2
20886
20947
  function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
20887
20948
  var wb = ({opts:{}}/*:any*/);
20888
- var Sheets = {};
20949
+ var Sheets = sheet_map_new();
20889
20950
  if(DENSE != null && options.dense == null) options.dense = DENSE;
20890
20951
  var out/*:Worksheet*/ = ({}/*:any*/); if(options.dense) out["!data"] = [];
20891
20952
  var Directory = {};
@@ -21328,7 +21389,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
21328
21389
  finalize_sheet_visuals(out);
21329
21390
  Workbook.Sheets.push(wsprops);
21330
21391
  }
21331
- if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out;
21392
+ if(cur_sheet === "") Preamble = out; else sheet_map_set(Sheets, cur_sheet, out);
21332
21393
  out = ({}/*:any*/); if(options.dense) out["!data"] = [];
21333
21394
  } break;
21334
21395
  case 0x0009: case 0x0209: case 0x0409: case 0x0809 /* BOF */: {
@@ -21570,7 +21631,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
21570
21631
  while(val.e >= val.s) {
21571
21632
  colinfo[val.e--] = { width: val.w/256, level: (val.level || 0), hidden: !!(val.flags & 1) };
21572
21633
  if(val.ixfe != null && XFs[val.ixfe]) colinfo[val.e+1].s = resolve_xls_style(XFs[val.ixfe], val.ixfe);
21573
- if(!seencol) { seencol = true; find_mdw_colw(val.w/256); }
21634
+ if(!seencol) { seencol = true; MDW = DEF_MDW; }
21574
21635
  process_col(colinfo[val.e+1]);
21575
21636
  }
21576
21637
  } break;
@@ -21628,10 +21689,13 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
21628
21689
  if(!wb.SheetNames.length && Preamble["!ref"]) {
21629
21690
  wb.SheetNames.push("Sheet1");
21630
21691
  /*jshint -W069 */
21631
- if(wb.Sheets) wb.Sheets["Sheet1"] = Preamble;
21692
+ if(wb.Sheets) sheet_map_set(wb.Sheets, "Sheet1", Preamble);
21632
21693
  /*jshint +W069 */
21633
21694
  } else wb.Preamble=Preamble;
21634
- if(wb.Sheets) FilterDatabases.forEach(function(r,i) { wb.Sheets[wb.SheetNames[i]]['!autofilter'] = r; });
21695
+ if(wb.Sheets) FilterDatabases.forEach(function(r,i) {
21696
+ var ws = sheet_map_get(wb.Sheets, wb.SheetNames[i]);
21697
+ if(ws) ws['!autofilter'] = r;
21698
+ });
21635
21699
  wb.Strings = sst;
21636
21700
  wb.SSF = dup(table_fmt);
21637
21701
  if(opts.enc) wb.Encryption = opts.enc;
@@ -23256,7 +23320,7 @@ function write_biff2_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
23256
23320
  o.cellXfs = [{numFmtId: 0}];
23257
23321
  o._BIFF2FmtTable/*:Array<string>*/ = ["General"]; o._Fonts = [];
23258
23322
  var body = buf_array();
23259
- write_ws_biff2(body, wb.Sheets[wb.SheetNames[idx]], idx, o, wb);
23323
+ write_ws_biff2(body, sheet_map_get(wb.Sheets, wb.SheetNames[idx]), idx, o, wb);
23260
23324
 
23261
23325
  o._BIFF2FmtTable.forEach(function(f) {
23262
23326
  if(o.biff <= 3) write_biff_rec(ba, 0x001E, write_BIFF2Format(f));
@@ -23667,7 +23731,7 @@ function write_ws_biff8_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:n
23667
23731
  /* [MS-XLS] 2.1.7.20.5 */
23668
23732
  function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
23669
23733
  var ba = buf_array();
23670
- var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {};
23734
+ var s = wb.SheetNames[idx], ws = sheet_map_get(wb.Sheets, s) || {};
23671
23735
  var _WB/*:WBWBProps*/ = ((wb||{}).Workbook||{}/*:any*/);
23672
23736
  var _sheet/*:WBWSProp*/ = ((_WB.Sheets||[])[idx]||{}/*:any*/);
23673
23737
  var dense = ws["!data"] != null;
@@ -23866,7 +23930,7 @@ function write_biff8_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
23866
23930
 
23867
23931
  function write_biff_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
23868
23932
  for(var i = 0; i <= wb.SheetNames.length; ++i) {
23869
- var ws = wb.Sheets[wb.SheetNames[i]];
23933
+ var ws = sheet_map_get(wb.Sheets, wb.SheetNames[i]);
23870
23934
  if(!ws || !ws["!ref"]) continue;
23871
23935
  var range = decode_range(ws["!ref"]);
23872
23936
  if(range.e.c > 255) { // note: 255 is IV
@@ -23948,15 +24012,66 @@ function html_to_sheet(str/*:string*/, _opts)/*:Workbook*/ {
23948
24012
  return ws;
23949
24013
  }
23950
24014
 
23951
- function cssesc(x) { return escapexml(String(x).replace(/"/g, "'")); }
23952
24015
  function css_color(color) {
23953
24016
  if(!color) return "";
23954
- if(color.rgb) return "#" + String(color.rgb).slice(-6);
24017
+ if(color.rgb && /^[0-9A-Fa-f]{6}(?:[0-9A-Fa-f]{2})?$/.test(String(color.rgb))) return "#" + String(color.rgb).slice(-6);
23955
24018
  return "";
23956
24019
  }
23957
24020
  function css_font_family(name) {
23958
24021
  if(!name) return "";
23959
- return "'" + cssesc(name).replace(/'/g, "\\'") + "'";
24022
+ return "'" + css_string_escape(name, "'") + "'";
24023
+ }
24024
+
24025
+ function html_attr_escape(value/*:any*/)/*:string*/ {
24026
+ return String(value).replace(/[&<>"']/g, function(ch) {
24027
+ return ch == "&" ? "&amp;" : ch == "<" ? "&lt;" : ch == ">" ? "&gt;" : ch == '"' ? "&quot;" : "&#39;";
24028
+ });
24029
+ }
24030
+ function html_writextag(tag/*:string*/, content/*:?string*/, attrs)/*:string*/ {
24031
+ var out = ["<", tag];
24032
+ if(attrs) keys(attrs).forEach(function(key) { out.push(" ", key, '="', html_attr_escape(attrs[key]), '"'); });
24033
+ if(content == null) { out.push("/>"); return out.join(""); }
24034
+ out.push(">", content, "</", tag, ">");
24035
+ return out.join("");
24036
+ }
24037
+ function safe_html_href(value/*:any*/)/*:?string*/ {
24038
+ var href = String(value == null ? "" : value).trim();
24039
+ if(!href || href.slice(0, 2) == "//") return null;
24040
+ var colon = href.indexOf(":"), prefix = colon == -1 ? "" : href.slice(0, colon), compact = "";
24041
+ for(var i = 0; i < prefix.length; ++i) if(prefix.charCodeAt(i) > 32 && prefix.charCodeAt(i) != 127) compact += prefix.charAt(i);
24042
+ if(colon != -1 && !/^(?:https?|mailto|tel)$/i.test(compact)) return null;
24043
+ return href;
24044
+ }
24045
+ function safe_html_image_src(value/*:any*/)/*:?string*/ {
24046
+ var src = String(value == null ? "" : value);
24047
+ return /^data:image\/[A-Za-z0-9.+-]+;base64,[A-Za-z0-9+/=\r\n]+$/.test(src) ? src : null;
24048
+ }
24049
+ function sanitize_cell_html(value/*:any*/)/*:string*/ {
24050
+ var html = String(value == null ? "" : value), out = [], pos = 0;
24051
+ while(pos < html.length) {
24052
+ var start = html.indexOf("<", pos);
24053
+ if(start == -1) { out.push(html.slice(pos)); break; }
24054
+ out.push(html.slice(pos, start));
24055
+ var end = html.indexOf(">", start + 1);
24056
+ if(end == -1) { out.push("&lt;", html.slice(start + 1)); break; }
24057
+ var raw = html.slice(start + 1, end).trim(), lower = raw.toLowerCase();
24058
+ if(/^(?:\/?(?:b|i|s|sup|sub)|br\s*\/?)$/.test(lower)) out.push("<", lower == "br" ? "br/" : lower, ">");
24059
+ else if(lower == "/span") out.push("</span>");
24060
+ else if(lower.slice(0, 12) == 'span style="' && raw.charAt(raw.length - 1) == '"') {
24061
+ var declarations = raw.slice(12, -1).split(";"), safe = [];
24062
+ declarations.forEach(function(decl) {
24063
+ var colon = decl.indexOf(":"), key = colon == -1 ? "" : decl.slice(0, colon).trim().toLowerCase(), val = colon == -1 ? "" : decl.slice(colon + 1).trim().toLowerCase();
24064
+ if(key == "text-decoration" && val == "underline") safe.push("text-decoration:underline");
24065
+ else if(key == "text-underline-style" && /^(?:single|double|single-accounting|double-accounting)$/.test(val)) safe.push("text-underline-style:" + val);
24066
+ else if(key == "font-size" && /^\d+(?:\.\d+)?pt$/.test(val)) safe.push("font-size:" + val);
24067
+ else if(key == "text-effect" && val == "outline") safe.push("text-effect:outline");
24068
+ else if(key == "text-shadow" && val == "auto") safe.push("text-shadow:auto");
24069
+ });
24070
+ out.push('<span style="', safe.join(";"), safe.length ? ";" : "", '">');
24071
+ } else out.push(html_attr_escape(html.slice(start, end + 1)));
24072
+ pos = end + 1;
24073
+ }
24074
+ return out.join("");
23960
24075
  }
23961
24076
  function html_border_style(style) {
23962
24077
  switch(style) {
@@ -23985,7 +24100,8 @@ function html_cell_style(cell/*:Cell*/, opts/*:Sheet2HTMLOpts*/) {
23985
24100
  var s = cell.s, css = [];
23986
24101
  var font = s.font || {};
23987
24102
  if(font.name) css.push("font-family:" + css_font_family(font.name));
23988
- if(font.sz) css.push("font-size:" + font.sz + "pt");
24103
+ var fontSize = +font.sz;
24104
+ if(isFinite(fontSize) && fontSize > 0) css.push("font-size:" + Math.min(fontSize, 409) + "pt");
23989
24105
  if(font.bold) css.push("font-weight:bold");
23990
24106
  if(font.italic) css.push("font-style:italic");
23991
24107
  var deco = [];
@@ -23998,8 +24114,9 @@ function html_cell_style(cell/*:Cell*/, opts/*:Sheet2HTMLOpts*/) {
23998
24114
  if(fill.patternType != "none" && fill.patternType != "gray125") fillColor = css_color(fill.fgColor) || css_color(fill.bgColor);
23999
24115
  if(fillColor) css.push("background-color:" + fillColor);
24000
24116
  var alignment = s.alignment || {};
24001
- if(alignment.horizontal) css.push("text-align:" + alignment.horizontal);
24002
- if(alignment.vertical) css.push("vertical-align:" + alignment.vertical);
24117
+ if(/^(?:left|right|center|justify|fill|distributed)$/.test(alignment.horizontal || "")) css.push("text-align:" + alignment.horizontal);
24118
+ var vertical = alignment.vertical == "center" ? "middle" : alignment.vertical;
24119
+ if(/^(?:top|middle|bottom|baseline)$/.test(vertical || "")) css.push("vertical-align:" + vertical);
24003
24120
  if(alignment.textRotation != null && alignment.textRotation !== 0) {
24004
24121
  var deg = alignment.textRotation == 255 ? 90 : alignment.textRotation > 90 ? 90 - alignment.textRotation : alignment.textRotation;
24005
24122
  css.push("transform:rotate(" + deg + "deg)");
@@ -24078,7 +24195,7 @@ function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HT
24078
24195
  }
24079
24196
  }
24080
24197
  /* TODO: html entities */
24081
- var w = (cell && cell.v != null) && (cell.h || escapehtml(cell.w || (format_cell(cell), cell.w) || "")) || "";
24198
+ var w = (cell && cell.v != null) && (cell.h ? sanitize_cell_html(cell.h) : escapehtml(cell.w || (format_cell(cell), cell.w) || "")) || "";
24082
24199
  sp = ({}/*:any*/);
24083
24200
  if(RS > 1) sp.rowspan = RS;
24084
24201
  if(CS > 1) sp.colspan = CS;
@@ -24086,17 +24203,18 @@ function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HT
24086
24203
  else if(cell) {
24087
24204
  sp["data-t"] = cell && cell.t || 'z';
24088
24205
  // note: data-v is unaffected by the timezone interpretation
24089
- if(cell.v != null) sp["data-v"] = escapehtml(cell.v instanceof Date ? cell.v.toISOString() : cell.v);
24206
+ if(cell.v != null) sp["data-v"] = cell.v instanceof Date ? cell.v.toISOString() : cell.v;
24090
24207
  if(cell.z != null) sp["data-z"] = cell.z;
24091
- if(cell.f != null) sp["data-f"] = escapehtml(cell.f);
24092
- if(cell.l && (cell.l.Target || "#").charAt(0) != "#" && (!o.sanitizeLinks || (cell.l.Target || "").slice(0, 11).toLowerCase() != 'javascript:')) w = '<a href="' + escapehtml(cell.l.Target) +'">' + w + '</a>';
24208
+ if(cell.f != null) sp["data-f"] = cell.f;
24209
+ var href = cell.l && safe_html_href(cell.l.Target);
24210
+ if(href) w = '<a href="' + html_attr_escape(href) +'">' + w + '</a>';
24093
24211
  }
24094
24212
  var cstyle = html_cell_style(stylecell, o);
24095
24213
  var lstyle = html_cell_layout_style(stylecell, o, C, CS, cols);
24096
24214
  if(lstyle) cstyle = cstyle ? cstyle + ";" + lstyle : lstyle;
24097
24215
  if(cstyle) sp.style = cstyle;
24098
24216
  sp.id = (o.id || "sjs") + "-" + coord;
24099
- oo.push(writextag('td', w, sp));
24217
+ oo.push(html_writextag('td', w, sp));
24100
24218
  }
24101
24219
  var rsp = ({}/*:any*/), rstyle = [];
24102
24220
  if(row) {
@@ -24104,7 +24222,7 @@ function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HT
24104
24222
  if(o.browserPixels) rstyle.push("height:" + html_row_height(row) + "px");
24105
24223
  }
24106
24224
  if(rstyle.length) rsp.style = rstyle.join(";");
24107
- return writextag('tr', oo.join(""), rsp);
24225
+ return html_writextag('tr', oo.join(""), rsp);
24108
24226
  }
24109
24227
 
24110
24228
  var HTML_BEGIN = '<html><head><meta charset="utf-8"/><title>SheetJS Table Export</title></head><body>';
@@ -24240,8 +24358,10 @@ function render_html_drawings(ws, opts) {
24240
24358
  var out = [], drawings = ws["!drawings"] || {}, charts = ws["!charts"] || [];
24241
24359
  if(opts && opts.drawings && drawings.images) drawings.images.forEach(function(img) {
24242
24360
  if(!img || !img.dataURI) return;
24361
+ var src = safe_html_image_src(img.dataURI);
24362
+ if(!src) return;
24243
24363
  var pos = html_anchor_pos(ws, img.anchor, opts);
24244
- out.push('<img class="sjs-drawing-image" src="' + img.dataURI + '" style="' + html_abs_style(pos) + '"/>');
24364
+ out.push('<img class="sjs-drawing-image" src="' + html_attr_escape(src) + '" style="' + html_abs_style(pos) + '"/>');
24245
24365
  });
24246
24366
  if(opts && opts.charts) charts.forEach(function(chart) {
24247
24367
  var pos = html_anchor_pos(ws, chart.anchor, opts);
@@ -24256,7 +24376,7 @@ function make_html_preamble(ws/*:Worksheet*/, R/*:Range*/, o/*:Sheet2HTMLOpts*/)
24256
24376
  if(o && o.id) tattr.id = o.id;
24257
24377
  if(o && (o.browserPixels || o.autoFit)) tstyle.push("border-collapse:collapse;table-layout:fixed");
24258
24378
  if(tstyle.length) tattr.style = tstyle.join(";");
24259
- var table = writextag("table", "", tattr).replace(/<\/table>$/, "");
24379
+ var table = html_writextag("table", "", tattr).replace(/<\/table>$/, "");
24260
24380
  var cols = o && o._htmlCols || ws["!cols"];
24261
24381
  if(o && (o.browserPixels || o.autoFit) && cols) {
24262
24382
  out.push("<colgroup>");
@@ -24264,7 +24384,7 @@ function make_html_preamble(ws/*:Worksheet*/, R/*:Range*/, o/*:Sheet2HTMLOpts*/)
24264
24384
  var col = cols[C], style = [];
24265
24385
  style.push("width:" + html_col_width(col) + "px");
24266
24386
  if(col && col.hidden) style.push("display:none");
24267
- out.push(writextag("col", null, {style:style.join(";")}));
24387
+ out.push(html_writextag("col", null, {style:style.join(";")}));
24268
24388
  }
24269
24389
  out.push("</colgroup>");
24270
24390
  }
@@ -24431,7 +24551,7 @@ function parse_text_p(text/*:string*//*::, tag*/)/*:Array<any>*/ {
24431
24551
  .replace(/<text:s text:c="(\d+)"\/>/g, function($$,$1) { return Array(parseInt($1,10)+1).join(" "); })
24432
24552
  .replace(/<text:tab[^<>]*\/>/g,"\t")
24433
24553
  .replace(/<text:line-break\/>/g,"\n");
24434
- var v = unescapexml(fixed.replace(/<[^<>]*>/g,""));
24554
+ var v = unescapexml(strip_xml_tags(fixed));
24435
24555
 
24436
24556
  return [v];
24437
24557
  }
@@ -24668,7 +24788,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
24668
24788
  var nfidx, NF = "", pidx = 0;
24669
24789
  var sheetag/*:: = {name:"", '名称':""}*/;
24670
24790
  var rowtag/*:: = {'行号':""}*/;
24671
- var Sheets = {}, SheetNames/*:Array<string>*/ = [];
24791
+ var Sheets = sheet_map_new(), SheetNames/*:Array<string>*/ = [];
24672
24792
  var ws = ({}/*:any*/); if(opts.dense) ws["!data"] = [];
24673
24793
  var Rn, q/*:: :any = ({t:"", v:null, z:null, w:"",c:[],}:any)*/;
24674
24794
  var ctag = ({value:""}/*:any*/), ctag2 = ({}/*:any*/);
@@ -24705,7 +24825,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
24705
24825
  sheetag.name = sheetag['名称'] || sheetag.name;
24706
24826
  if(typeof JSON !== 'undefined') JSON.stringify(sheetag);
24707
24827
  SheetNames.push(sheetag.name);
24708
- Sheets[sheetag.name] = ws;
24828
+ sheet_map_set(Sheets, sheetag.name, ws);
24709
24829
  WB.Sheets.push({
24710
24830
  /* TODO: CodeName */
24711
24831
  Hidden: (tstyles[sheetag["style-name"]] && tstyles[sheetag["style-name"]]["display"] ? (parsexmlbool(tstyles[sheetag["style-name"]]["display"]) ? 0 : 1) : 0)
@@ -25061,7 +25181,9 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
25061
25181
  if(Rn[1]==='/') break;
25062
25182
  try {
25063
25183
  _Ref = ods_to_csf_3D(parsexmltag(Rn[0])['target-range-address']);
25064
- Sheets[_Ref[0]]['!autofilter'] = { ref:_Ref[1] };
25184
+ if(Object.prototype.hasOwnProperty.call(Sheets, _Ref[0]) && Sheets[_Ref[0]]) {
25185
+ Sheets[_Ref[0]]['!autofilter'] = { ref:_Ref[1] };
25186
+ }
25065
25187
  } catch(e) {/* empty */}
25066
25188
  break;
25067
25189
 
@@ -25571,7 +25693,7 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
25571
25693
 
25572
25694
  /* column styles */
25573
25695
  var cidx = 0;
25574
- wb.SheetNames.map(function(n) { return wb.Sheets[n]; }).forEach(function(ws) {
25696
+ wb.SheetNames.map(function(n) { return sheet_map_get(wb.Sheets, n); }).forEach(function(ws) {
25575
25697
  if(!ws) return;
25576
25698
  if(ws["!cols"]) {
25577
25699
  for(var C = 0; C < ws["!cols"].length; ++C) if(ws["!cols"][C]) {
@@ -25590,7 +25712,7 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
25590
25712
 
25591
25713
  /* row styles */
25592
25714
  var ridx = 0;
25593
- wb.SheetNames.map(function(n) { return wb.Sheets[n]; }).forEach(function(ws) {
25715
+ wb.SheetNames.map(function(n) { return sheet_map_get(wb.Sheets, n); }).forEach(function(ws) {
25594
25716
  if(!ws) return;
25595
25717
  if(ws["!rows"]) {
25596
25718
  for(var R = 0; R < ws["!rows"].length; ++R) if(ws["!rows"][R]) {
@@ -25623,7 +25745,7 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
25623
25745
  /* number formats, table cells, text */
25624
25746
  var nfs = {};
25625
25747
  var nfi = 69;
25626
- wb.SheetNames.map(function(n) { return wb.Sheets[n]; }).forEach(function(ws) {
25748
+ wb.SheetNames.map(function(n) { return sheet_map_get(wb.Sheets, n); }).forEach(function(ws) {
25627
25749
  if(!ws) return;
25628
25750
  var dense = (ws["!data"] != null);
25629
25751
  if(!ws["!ref"]) return;
@@ -25706,7 +25828,7 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
25706
25828
  o.push(' <office:body>\n');
25707
25829
  o.push(' <office:spreadsheet>\n');
25708
25830
  if(((wb.Workbook||{}).WBProps||{}).date1904) o.push(' <table:calculation-settings table:case-sensitive="false" table:search-criteria-must-apply-to-whole-cell="true" table:use-wildcards="true" table:use-regular-expressions="false" table:automatic-find-labels="false">\n <table:null-date table:date-value="1904-01-01"/>\n </table:calculation-settings>\n');
25709
- for(var i = 0; i != wb.SheetNames.length; ++i) o.push(write_ws(wb.Sheets[wb.SheetNames[i]], wb, i, opts, nfs, ((wb.Workbook||{}).WBProps||{}).date1904));
25831
+ for(var i = 0; i != wb.SheetNames.length; ++i) o.push(write_ws(sheet_map_get(wb.Sheets, wb.SheetNames[i]), wb, i, opts, nfs, ((wb.Workbook||{}).WBProps||{}).date1904));
25710
25832
  if((wb.Workbook||{}).Names) o.push(write_names_ods(wb.Workbook.Names, wb.SheetNames, -1));
25711
25833
  o.push(' </office:spreadsheet>\n');
25712
25834
  o.push(' </office:body>\n');
@@ -25758,7 +25880,6 @@ function write_ods(wb/*:any*/, opts/*:any*/) {
25758
25880
 
25759
25881
  return zip;
25760
25882
  }
25761
-
25762
25883
  /*! sheetjs (C) 2013-present SheetJS -- http://sheetjs.com */
25763
25884
  var subarray = function() {
25764
25885
  try {
@@ -26216,7 +26337,8 @@ var numbers_lut_new = function() {
26216
26337
  function numbers_format_cell(cell, t, flags, ofmt, nfmt) {
26217
26338
  var _a, _b, _c, _d;
26218
26339
  var ctype = t & 255, ver = t >> 8;
26219
- var fmt = ver >= 5 ? nfmt : ofmt;
26340
+ /* Missing legacy/new format tables mean the default format. */
26341
+ var fmt = (ver >= 5 ? nfmt : ofmt) || [];
26220
26342
  dur:
26221
26343
  if (flags & (ver > 4 ? 8 : 4) && cell.t == "n" && ctype == 7) {
26222
26344
  var dstyle = ((_a = fmt[7]) == null ? void 0 : _a[0]) ? varint_to_i32(fmt[7][0].data) : -1;
@@ -27275,7 +27397,7 @@ function write_numbers_iwa(wb, opts) {
27275
27397
  docroot = numbers_iwa_find(cfb, deps, 1);
27276
27398
  sheetrefs = mappa(parse_shallow(docroot.messages[0].data)[1], parse_TSP_Reference);
27277
27399
  }
27278
- write_numbers_ws(cfb, deps, wb.Sheets[name], name, idx, sheetrefs[idx]);
27400
+ write_numbers_ws(cfb, deps, sheet_map_get(wb.Sheets, name), name, idx, sheetrefs[idx]);
27279
27401
  });
27280
27402
  return cfb;
27281
27403
  }
@@ -28131,6 +28253,7 @@ function drawing_mime(path) {
28131
28253
  case "bmp": return "image/bmp";
28132
28254
  case "svg": return "image/svg+xml";
28133
28255
  case "jpg": case "jpeg": return "image/jpeg";
28256
+ case "tif": case "tiff": return "image/tiff";
28134
28257
  default: return "application/octet-stream";
28135
28258
  }
28136
28259
  }
@@ -28146,7 +28269,9 @@ function parse_sheet_drawing(sheet, type, zip, path, idx, opts, wb) {
28146
28269
  if(!img || !img.target) return;
28147
28270
  var ipath = resolve_path(img.target, dfile);
28148
28271
  var ibin = getzipbin(zip, ipath, true);
28149
- if(ibin) img.dataURI = "data:" + drawing_mime(ipath) + ";base64," + Base64_encode_arr(ibin);
28272
+ var contentType = drawing_mime(ipath);
28273
+ if(ibin) img.dataURI = "data:" + contentType + ";base64," + Base64_encode_arr(ibin);
28274
+ img.contentType = contentType;
28150
28275
  img.path = ipath;
28151
28276
  });
28152
28277
  if(opts.charts && draw.charts && draw.charts.length) {
@@ -28190,7 +28315,7 @@ function safe_parse_sheet(zip, path/*:string*/, relsPath/*:string*/, sheet, idx/
28190
28315
  case 'dialog': _ws = parse_ds(data, path, idx, opts, sheetRels[sheet], wb, themes, styles); break;
28191
28316
  default: throw new Error("Unrecognized sheet type " + stype);
28192
28317
  }
28193
- sheets[sheet] = _ws;
28318
+ sheet_map_set(sheets, sheet, _ws);
28194
28319
 
28195
28320
  /* scan rels for comments and threaded comments */
28196
28321
  var comments = [], tcomments = [];
@@ -28313,7 +28438,7 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
28313
28438
  if(opts.bookSheets && typeof sheets !== 'undefined') out.SheetNames = sheets;
28314
28439
  if(opts.bookSheets ? out.SheetNames : opts.bookProps) return out;
28315
28440
  }
28316
- sheets = {};
28441
+ sheets = sheet_map_new();
28317
28442
 
28318
28443
  var deps = {};
28319
28444
  if(opts.bookDeps && dir.calcchain) deps=parse_cc(getzipdata(zip, strip_front_slash(dir.calcchain)),dir.calcchain,opts);
@@ -28516,7 +28641,7 @@ function write_zip_xlsb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
28516
28641
 
28517
28642
  for(rId=1;rId <= wb.SheetNames.length; ++rId) {
28518
28643
  var wsrels = {'!id':{}};
28519
- var ws = wb.Sheets[wb.SheetNames[rId-1]];
28644
+ var ws = sheet_map_get(wb.Sheets, wb.SheetNames[rId-1]);
28520
28645
  var _type = (ws || {})["!type"] || "sheet";
28521
28646
  switch(_type) {
28522
28647
  case "chart":
@@ -28672,7 +28797,7 @@ function write_zip_xlsx(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
28672
28797
 
28673
28798
  for(rId=1;rId <= wb.SheetNames.length; ++rId) {
28674
28799
  var wsrels = {'!id':{}};
28675
- var ws = wb.Sheets[wb.SheetNames[rId-1]];
28800
+ var ws = sheet_map_get(wb.Sheets, wb.SheetNames[rId-1]);
28676
28801
  var _type = (ws || {})["!type"] || "sheet";
28677
28802
  switch(_type) {
28678
28803
  case "chart":
@@ -28768,7 +28893,6 @@ function write_zip_xlsx(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
28768
28893
  delete opts.revssf; delete opts.ssf;
28769
28894
  return zip;
28770
28895
  }
28771
-
28772
28896
  function firstbyte(f/*:RawData*/,o/*:?TypeOpts*/)/*:Array<number>*/ {
28773
28897
  var x = "";
28774
28898
  switch((o||{}).type || "base64") {
@@ -29038,18 +29162,18 @@ function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
29038
29162
  case 'xml':
29039
29163
  case 'xlml': return write_string_type(write_xlml(wb, o), o);
29040
29164
  case 'slk':
29041
- case 'sylk': return write_string_type(SYLK.from_sheet(wb.Sheets[wb.SheetNames[idx]], o, wb), o);
29165
+ case 'sylk': return write_string_type(SYLK.from_sheet(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o, wb), o);
29042
29166
  case 'htm':
29043
- case 'html': return write_string_type(sheet_to_html(wb.Sheets[wb.SheetNames[idx]], o), o);
29044
- case 'txt': return write_stxt_type(sheet_to_txt(wb.Sheets[wb.SheetNames[idx]], o), o);
29045
- case 'csv': return write_string_type(sheet_to_csv(wb.Sheets[wb.SheetNames[idx]], o), o, "\ufeff");
29046
- case 'dif': return write_string_type(DIF.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
29047
- case 'dbf': return write_binary_type(DBF.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
29048
- case 'prn': return write_string_type(PRN.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
29049
- case 'rtf': return write_string_type(sheet_to_rtf(wb.Sheets[wb.SheetNames[idx]], o), o);
29050
- case 'eth': return write_string_type(ETH.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
29167
+ case 'html': return write_string_type(sheet_to_html(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o);
29168
+ case 'txt': return write_stxt_type(sheet_to_txt(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o);
29169
+ case 'csv': return write_string_type(sheet_to_csv(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o, "\ufeff");
29170
+ case 'dif': return write_string_type(DIF.from_sheet(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o);
29171
+ case 'dbf': return write_binary_type(DBF.from_sheet(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o);
29172
+ case 'prn': return write_string_type(PRN.from_sheet(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o);
29173
+ case 'rtf': return write_string_type(sheet_to_rtf(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o);
29174
+ case 'eth': return write_string_type(ETH.from_sheet(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o);
29051
29175
  case 'fods': return write_string_type(write_ods(wb, o), o);
29052
- case 'wk1': return write_binary_type(WK_.sheet_to_wk1(wb.Sheets[wb.SheetNames[idx]], o), o);
29176
+ case 'wk1': return write_binary_type(WK_.sheet_to_wk1(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o);
29053
29177
  case 'wk3': return write_binary_type(WK_.book_to_wk3(wb, o), o);
29054
29178
  case 'biff2': if(!o.biff) o.biff = 2; /* falls through */
29055
29179
  case 'biff3': if(!o.biff) o.biff = 3; /* falls through */
@@ -29315,6 +29439,7 @@ function sheet_add_json(_ws/*:?Worksheet*/, js/*:Array<any>*/, opts)/*:Worksheet
29315
29439
  var _origin/*:CellAddress*/ = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
29316
29440
  _R = _origin.r; _C = _origin.c;
29317
29441
  }
29442
+ if(!isFinite(_R) || _R !== Math.floor(_R) || _R < -1 || !isFinite(_C) || _C !== Math.floor(_C) || _C < 0) throw new Error("Invalid origin");
29318
29443
  }
29319
29444
  var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:_C, r:_R + js.length - 1 + offset}}/*:any*/);
29320
29445
  if(ws['!ref']) {
@@ -29406,7 +29531,7 @@ function wb_sheet_idx(wb/*:Workbook*/, sh/*:number|string*/) {
29406
29531
 
29407
29532
  /* simple blank or single-sheet workbook object */
29408
29533
  function book_new(ws/*:?Worksheet*/, wsname/*:?string*/)/*:Workbook*/ {
29409
- var wb = { SheetNames: [], Sheets: {} };
29534
+ var wb = { SheetNames: [], Sheets: sheet_map_new() };
29410
29535
  if(ws) book_append_sheet(wb, ws, wsname || "Sheet1");
29411
29536
  return wb;
29412
29537
  }
@@ -29426,7 +29551,7 @@ function book_append_sheet(wb/*:Workbook*/, ws/*:Worksheet*/, name/*:?string*/,
29426
29551
  if(wb.SheetNames.indexOf(name) >= 0) throw new Error("Worksheet with name |" + name + "| already exists!");
29427
29552
 
29428
29553
  wb.SheetNames.push(name);
29429
- wb.Sheets[name] = ws;
29554
+ sheet_map_set(wb.Sheets, name, ws);
29430
29555
  return name;
29431
29556
  }
29432
29557
 
@@ -29493,7 +29618,6 @@ function sheet_set_array_formula(ws/*:Worksheet*/, range, formula/*:string*/, dy
29493
29618
  ws["!ref"] = encode_range(wsr);
29494
29619
  return ws;
29495
29620
  }
29496
-
29497
29621
  var utils/*:any*/ = {
29498
29622
  encode_col: encode_col,
29499
29623
  encode_row: encode_row,
@@ -29650,7 +29774,7 @@ function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
29650
29774
  if ((rowinfo[R]||{}).hidden) {
29651
29775
  ++R;
29652
29776
  continue;
29653
- };
29777
+ }
29654
29778
  var row = make_json_row(sheet, r, R, cols, header, hdr, o);
29655
29779
  ++R;
29656
29780
  if((row.isempty === false) || (header === 1 ? o.blankrows !== false : !!o.blankrows)) {
@@ -29679,7 +29803,7 @@ function write_xlml_stream(wb/*:Workbook*/, o/*:?Sheet2XLMLOpts*/) {
29679
29803
 
29680
29804
  /* do one pass to determine styles since they must be added before tables */
29681
29805
  wb.SheetNames.forEach(function(n) {
29682
- var ws = wb.Sheets[n];
29806
+ var ws = sheet_map_get(wb.Sheets, n);
29683
29807
  if(!ws || !ws["!ref"]) return;
29684
29808
  var range = decode_range(ws["!ref"]);
29685
29809
  var dense = ws["!data"] != null;
@@ -29699,7 +29823,7 @@ function write_xlml_stream(wb/*:Workbook*/, o/*:?Sheet2XLMLOpts*/) {
29699
29823
  });
29700
29824
  var sty = write_sty_xlml(wb, opts);
29701
29825
 
29702
- var stage = 0, wsidx = 0, ws = wb.Sheets[wb.SheetNames[wsidx]], range = safe_decode_range(ws), R = -1, T = false;
29826
+ var stage = 0, wsidx = 0, ws = sheet_map_get(wb.Sheets, wb.SheetNames[wsidx]), range = safe_decode_range(ws), R = -1, T = false;
29703
29827
 
29704
29828
  var marr = [], mi = 0, dense = false, darr = [], addr = {r:0,c:0};
29705
29829
 
@@ -29739,7 +29863,7 @@ function write_xlml_stream(wb/*:Workbook*/, o/*:?Sheet2XLMLOpts*/) {
29739
29863
 
29740
29864
  stream.push("<Worksheet" + wxt_helper({ "ss:Name": escapexml(wb.SheetNames[wsidx])}) + ">");
29741
29865
 
29742
- ws = wb.Sheets[wb.SheetNames[wsidx]];
29866
+ ws = sheet_map_get(wb.Sheets, wb.SheetNames[wsidx]);
29743
29867
  if(!ws) { stream.push("</Worksheet>"); return void ++wsidx; }
29744
29868
 
29745
29869
  var names = write_ws_xlml_names(ws, opts, wsidx, wb);