ooxml-core 1.19.1 → 1.20.0

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.
Files changed (88) hide show
  1. package/README.md +12 -1
  2. package/dist/{PptxHandler-2V4PQL6O.mjs → PptxHandler-FYD7IYXT.mjs} +2 -2
  3. package/dist/PptxHandler-SITN3K3F.mjs +4 -0
  4. package/dist/{PptxHandler-6TNIQ7S5.cjs → PptxHandler-TEKISCJO.cjs} +3 -3
  5. package/dist/{PresentationBuilder-HQ6C7L4V.mjs → PresentationBuilder-EYI6Z2JP.mjs} +2 -2
  6. package/dist/{PresentationBuilder-G7MPEGXJ.mjs → PresentationBuilder-IMB4DVRN.mjs} +2 -2
  7. package/dist/{PresentationBuilder-RM52LCVN.cjs → PresentationBuilder-NCKASKXU.cjs} +5 -5
  8. package/dist/automation/index.cjs +424 -90
  9. package/dist/automation/index.mjs +423 -91
  10. package/dist/automation/xlsx-read.d.ts +56 -0
  11. package/dist/automation/xlsx-read.d.ts.map +1 -0
  12. package/dist/automation/xlsx.d.ts +105 -4
  13. package/dist/automation/xlsx.d.ts.map +1 -1
  14. package/dist/{chunk-M6GDBVQ7.mjs → chunk-GQYQQ3GA.mjs} +1 -1
  15. package/dist/{chunk-SLNQNVQM.mjs → chunk-LEV2SVMK.mjs} +1 -1
  16. package/dist/{chunk-JUABSM7C.mjs → chunk-LVM3IZJ2.mjs} +1 -1
  17. package/dist/{chunk-TJPUAUWL.mjs → chunk-MN27HKHM.mjs} +8 -194
  18. package/dist/{chunk-4FTUAD2B.mjs → chunk-MNXKRXFB.mjs} +715 -200
  19. package/dist/{chunk-R5FIHHGB.cjs → chunk-NXKATFM5.cjs} +1598 -1204
  20. package/dist/{chunk-ZJ2OKIJN.mjs → chunk-WXY5EDGT.mjs} +592 -198
  21. package/dist/docx/embedded.cjs +4 -1
  22. package/dist/docx/embedded.mjs +4 -1
  23. package/dist/docx/index.cjs +4 -1
  24. package/dist/docx/index.mjs +4 -1
  25. package/dist/docx/load/index.cjs +4 -1
  26. package/dist/docx/load/index.mjs +4 -1
  27. package/dist/docx/write-table.d.ts.map +1 -1
  28. package/dist/index.cjs +25 -0
  29. package/dist/index.mjs +25 -0
  30. package/dist/pptx/automation/index.cjs +887 -453
  31. package/dist/pptx/automation/index.d.ts +2 -2
  32. package/dist/pptx/automation/index.mjs +5 -5
  33. package/dist/pptx/chunks/{index-Bqm-jFG-.d.ts → index-CgFX0T7b.d.ts} +7573 -7508
  34. package/dist/pptx/chunks/index-CgFX0T7b.d.ts.map +1 -0
  35. package/dist/pptx/chunks/{index-B9x557hr.d.ts → index-qwVYoFn6.d.ts} +2 -2
  36. package/dist/pptx/chunks/{index-B9x557hr.d.ts.map → index-qwVYoFn6.d.ts.map} +1 -1
  37. package/dist/pptx/cli/index.cjs +654 -221
  38. package/dist/pptx/cli/index.mjs +4 -4
  39. package/dist/pptx/converter/index.d.ts +1 -1
  40. package/dist/pptx/converter/index.mjs +2 -2
  41. package/dist/pptx/editor/render/find-replace.cjs +14 -14
  42. package/dist/pptx/editor/render/find-replace.d.ts +1 -1
  43. package/dist/pptx/editor/render/find-replace.mjs +1 -1
  44. package/dist/pptx/editor/render/slide-operations.cjs +8 -8
  45. package/dist/pptx/editor/render/slide-operations.mjs +2 -2
  46. package/dist/pptx/index.cjs +991 -619
  47. package/dist/pptx/index.d.ts +3 -3
  48. package/dist/pptx/index.mjs +5 -5
  49. package/dist/visio/index.cjs +61 -7
  50. package/dist/visio/index.mjs +61 -7
  51. package/dist/visio/ui/contract.d.ts +2 -1
  52. package/dist/visio/ui/contract.d.ts.map +1 -1
  53. package/dist/visio/ui/index.cjs +62 -7
  54. package/dist/visio/ui/index.mjs +62 -7
  55. package/dist/xlsx/edit/dimensions.d.ts.map +1 -1
  56. package/dist/xlsx/edit/history-rows.d.ts +7 -0
  57. package/dist/xlsx/edit/history-rows.d.ts.map +1 -0
  58. package/dist/xlsx/edit/history.d.ts +11 -1
  59. package/dist/xlsx/edit/history.d.ts.map +1 -1
  60. package/dist/xlsx/edit/outline.d.ts.map +1 -1
  61. package/dist/xlsx/edit/row-autofit.d.ts.map +1 -1
  62. package/dist/xlsx/index.cjs +235 -54
  63. package/dist/xlsx/index.mjs +235 -54
  64. package/dist/xlsx/layout/merge-sweep.d.ts +36 -0
  65. package/dist/xlsx/layout/merge-sweep.d.ts.map +1 -0
  66. package/dist/xlsx/layout/metrics.d.ts +5 -0
  67. package/dist/xlsx/layout/metrics.d.ts.map +1 -1
  68. package/dist/xlsx/layout/row-autofit.d.ts +6 -0
  69. package/dist/xlsx/layout/row-autofit.d.ts.map +1 -1
  70. package/dist/xlsx/load/index.cjs +61 -7
  71. package/dist/xlsx/load/index.mjs +61 -7
  72. package/dist/xlsx/numfmt/format.d.ts +8 -0
  73. package/dist/xlsx/numfmt/format.d.ts.map +1 -1
  74. package/dist/xlsx/read/sheet-data-source.d.ts.map +1 -1
  75. package/dist/xlsx/ui/index.cjs +281 -55
  76. package/dist/xlsx/ui/index.d.ts +1 -0
  77. package/dist/xlsx/ui/index.d.ts.map +1 -1
  78. package/dist/xlsx/ui/index.mjs +281 -56
  79. package/dist/xlsx/ui/selection-format.d.ts +13 -0
  80. package/dist/xlsx/ui/selection-format.d.ts.map +1 -0
  81. package/dist/xml/index.cjs +25 -0
  82. package/dist/xml/index.mjs +25 -0
  83. package/dist/xml/lite.d.ts.map +1 -1
  84. package/package.json +2 -2
  85. package/dist/PptxHandler-HSPKEP5E.mjs +0 -4
  86. package/dist/pptx/chunks/index-Bqm-jFG-.d.ts.map +0 -1
  87. /package/dist/{chunk-NYTR4UZ5.cjs → chunk-3IENHIFD.cjs} +0 -0
  88. /package/dist/{chunk-XTSHZGSM.mjs → chunk-CC5UNZOO.mjs} +0 -0
@@ -242,6 +242,12 @@ function parseLiteFragment(xml, container, namespaces) {
242
242
  }
243
243
  if (lt < 0) break;
244
244
  const next = source2.charCodeAt(lt + 1);
245
+ if (next === 33) {
246
+ const after = skipCommentOrCdata(source2, lt, top);
247
+ if (after < 0) return void 0;
248
+ pos = after;
249
+ continue;
250
+ }
245
251
  if (next === 47) {
246
252
  const gt = source2.indexOf(">", lt);
247
253
  if (gt < 0 || stack2.length < 2 || source2.slice(lt + 2, gt).trimEnd() !== top.tagName)
@@ -262,6 +268,25 @@ function parseLiteFragment(xml, container, namespaces) {
262
268
  }
263
269
  return stack2.length === 1 ? root : void 0;
264
270
  }
271
+ var DECLARATIONS = /<!DOCTYPE|<!ENTITY/i;
272
+ function skipCommentOrCdata(source2, lt, parent) {
273
+ if (source2.startsWith("<!--", lt)) {
274
+ const end = source2.indexOf("-->", lt + 4);
275
+ if (end < 0) return -1;
276
+ const body = source2.slice(lt + 4, end);
277
+ if (body.includes("--") || body.endsWith("-") || DECLARATIONS.test(body)) return -1;
278
+ return end + 3;
279
+ }
280
+ if (source2.startsWith("<![CDATA[", lt)) {
281
+ const end = source2.indexOf("]]>", lt + 9);
282
+ if (end < 0) return -1;
283
+ const text8 = source2.slice(lt + 9, end);
284
+ if (DECLARATIONS.test(text8)) return -1;
285
+ parent.childNodes.push(text8);
286
+ return end + 3;
287
+ }
288
+ return -1;
289
+ }
265
290
  function startTag(source2, from, namespaces) {
266
291
  const n = source2.length;
267
292
  let i2 = from;
@@ -3528,7 +3553,10 @@ function writeTable(doc, table4, node3, base2, writeParagraph, replaceSlots2) {
3528
3553
  "Cannot change the structure of a merged, nested, or complex table. The original DOCX package remains unchanged."
3529
3554
  );
3530
3555
  const width = table4.rows[0]?.length ?? 0;
3531
- if (!width || table4.rows.some((row3) => row3.length !== width || row3.some((cell) => !cell.paragraphs.length)))
3556
+ const reshaped = structural || !base2;
3557
+ if (!width || table4.rows.some(
3558
+ (row3) => reshaped && row3.length !== width || row3.some((cell) => !cell.paragraphs.length)
3559
+ ))
3532
3560
  throw new Error("Tables must contain rectangular rows and at least one paragraph per cell.");
3533
3561
  const oldRows = flatRows(node3).map((entry3) => entry3.element);
3534
3562
  const sourceById = /* @__PURE__ */ new Map();
@@ -19360,13 +19388,13 @@ function rejectUnsafeRunSegmentation(paragraph2, base2, oldRuns) {
19360
19388
  `Cannot edit paragraph ${paragraph2.id}: changing run boundaries could drop unsupported run properties. The original DOCX package remains unchanged.`
19361
19389
  );
19362
19390
  }
19363
- function writeParagraphImpl(doc, paragraph2, node3, base2, allocator, spans2) {
19364
- const continuation = spans2?.next.get(paragraph2.id);
19365
- const ranges = spans2 && {
19391
+ function writeParagraphImpl(doc, paragraph2, node3, base2, allocator, spans3) {
19392
+ const continuation = spans3?.next.get(paragraph2.id);
19393
+ const ranges = spans3 && {
19366
19394
  ...continuation ?? { before: /* @__PURE__ */ new Set(), after: /* @__PURE__ */ new Set() },
19367
- rangeIds: spans2.rangeIds
19395
+ rangeIds: spans3.rangeIds
19368
19396
  };
19369
- const sameRanges = continuationKey(continuation) === continuationKey(spans2?.original.get(paragraph2.id));
19397
+ const sameRanges = continuationKey(continuation) === continuationKey(spans3?.original.get(paragraph2.id));
19370
19398
  if (base2 && sameRanges && JSON.stringify(paragraph2) === JSON.stringify(base2)) return node3;
19371
19399
  const slots = collectInlineSlots(node3);
19372
19400
  if (!slots)
@@ -19427,7 +19455,7 @@ function writeParagraphImpl(doc, paragraph2, node3, base2, allocator, spans2) {
19427
19455
  children2(node3, "bookmarkEnd"),
19428
19456
  paragraph2.bookmarks ?? [],
19429
19457
  base2?.bookmarks ?? [],
19430
- () => spans2?.nextId() ?? "0"
19458
+ () => spans3?.nextId() ?? "0"
19431
19459
  );
19432
19460
  for (const bookmark of [...children2(node3, "bookmarkStart"), ...children2(node3, "bookmarkEnd")])
19433
19461
  node3.removeChild(bookmark);
@@ -19449,9 +19477,9 @@ function writeParagraphImpl(doc, paragraph2, node3, base2, allocator, spans2) {
19449
19477
  if (!pPr.childNodes.length) node3.removeChild(pPr);
19450
19478
  return node3;
19451
19479
  }
19452
- function createParagraph(doc, paragraph2, allocator, spans2) {
19480
+ function createParagraph(doc, paragraph2, allocator, spans3) {
19453
19481
  const node3 = makeW(doc, "p");
19454
- return writeParagraphImpl(doc, paragraph2, node3, void 0, allocator, spans2);
19482
+ return writeParagraphImpl(doc, paragraph2, node3, void 0, allocator, spans3);
19455
19483
  }
19456
19484
 
19457
19485
  // docx/docpr-ids.ts
@@ -19540,7 +19568,7 @@ var RelationshipAllocator = class {
19540
19568
 
19541
19569
  // docx/write.ts
19542
19570
  var twips2 = (pixels) => String(Math.round(pixels * 15));
19543
- function createTable(doc, table4, allocator, contentWidthTwips, spans2) {
19571
+ function createTable(doc, table4, allocator, contentWidthTwips, spans3) {
19544
19572
  const node3 = makeW(doc, "tbl");
19545
19573
  const { tblPr, tblGrid } = buildNewTableProperties(doc, table4, contentWidthTwips);
19546
19574
  node3.appendChild(tblPr);
@@ -19556,7 +19584,7 @@ function createTable(doc, table4, allocator, contentWidthTwips, spans2) {
19556
19584
  const tcPr = buildCellProperties(doc, cell);
19557
19585
  if (tcPr) tc.appendChild(tcPr);
19558
19586
  for (const paragraph2 of cell.paragraphs)
19559
- tc.appendChild(createParagraph(doc, paragraph2, allocator, spans2));
19587
+ tc.appendChild(createParagraph(doc, paragraph2, allocator, spans3));
19560
19588
  if (!cell.paragraphs.length) tc.appendChild(makeW(doc, "p"));
19561
19589
  tr.appendChild(tc);
19562
19590
  }
@@ -19584,13 +19612,13 @@ function baseMap(blocks) {
19584
19612
  }
19585
19613
  function applyBlocks(doc, container, blocks, original, allocator, contentWidthTwips, anchor = null) {
19586
19614
  const nextId3 = annotationIdAllocator(doc, blocks);
19587
- const spans2 = {
19615
+ const spans3 = {
19588
19616
  next: commentContinuations(blocks),
19589
19617
  original: commentContinuations(original),
19590
19618
  rangeIds: newMoveRangeIds(blocks, nextId3),
19591
19619
  nextId: nextId3
19592
19620
  };
19593
- const boundWriteParagraph = (writeDoc, paragraph2, node3, base2) => writeParagraphImpl(writeDoc, paragraph2, node3, base2, allocator, spans2);
19621
+ const boundWriteParagraph = (writeDoc, paragraph2, node3, base2) => writeParagraphImpl(writeDoc, paragraph2, node3, base2, allocator, spans3);
19594
19622
  const flat = flatBlocks(container);
19595
19623
  const oldNodes = flat.map((entry3) => entry3.element);
19596
19624
  const oldById = /* @__PURE__ */ new Map();
@@ -19604,7 +19632,7 @@ function applyBlocks(doc, container, blocks, original, allocator, contentWidthTw
19604
19632
  const base2 = bases.get(block.id);
19605
19633
  if (block.type === "paragraph")
19606
19634
  output.push(
19607
- old ? boundWriteParagraph(doc, block, old, base2?.type === "paragraph" ? base2 : void 0) : createParagraph(doc, block, allocator, spans2)
19635
+ old ? boundWriteParagraph(doc, block, old, base2?.type === "paragraph" ? base2 : void 0) : createParagraph(doc, block, allocator, spans3)
19608
19636
  );
19609
19637
  else
19610
19638
  output.push(
@@ -19615,7 +19643,7 @@ function applyBlocks(doc, container, blocks, original, allocator, contentWidthTw
19615
19643
  base2?.type === "table" ? base2 : void 0,
19616
19644
  boundWriteParagraph,
19617
19645
  replaceSlots
19618
- ) : createTable(doc, block, allocator, contentWidthTwips, spans2)
19646
+ ) : createTable(doc, block, allocator, contentWidthTwips, spans3)
19619
19647
  );
19620
19648
  }
19621
19649
  const nested = flat.some((entry3) => entry3.sdt) || blocks.some((block) => block.contentControl);
@@ -23719,6 +23747,37 @@ function formatValue(value3, format5, options2 = {}) {
23719
23747
  function isDateFormat(format5) {
23720
23748
  return compileFormat(format5).isDate;
23721
23749
  }
23750
+ var DAY_PARTS = /* @__PURE__ */ new Set([
23751
+ "y",
23752
+ "yyyy",
23753
+ "e",
23754
+ "g",
23755
+ "b",
23756
+ "bbbb",
23757
+ "m",
23758
+ "mm",
23759
+ "mmm",
23760
+ "mmmm",
23761
+ "mmmmm",
23762
+ "d",
23763
+ "dd",
23764
+ "ddd",
23765
+ "dddd"
23766
+ ]);
23767
+ function dateTimeParts(format5, value3) {
23768
+ const section3 = chooseSection(compileFormat(format5), value3)?.section;
23769
+ if (section3?.kind !== "date") return void 0;
23770
+ let date2 = false;
23771
+ let time = false;
23772
+ for (const token of section3.tokens) {
23773
+ if (token.t === "elapsed") return void 0;
23774
+ if (token.t === "date") {
23775
+ if (DAY_PARTS.has(token.part)) date2 = true;
23776
+ else time = true;
23777
+ } else if (token.t === "ampm" || token.t === "subsec") time = true;
23778
+ }
23779
+ return date2 || time ? { date: date2, time } : void 0;
23780
+ }
23722
23781
 
23723
23782
  // xlsx/numfmt/input-date.ts
23724
23783
  var MONTH_NAMES = [
@@ -29672,21 +29731,50 @@ function rootNamespaces(xml) {
29672
29731
  for (const match2 of (root[2] ?? "").matchAll(DECLARATION3)) out[match2[1] ?? ""] = match2[3] ?? "";
29673
29732
  return out;
29674
29733
  }
29734
+ var SPECIAL = /<[!?]/g;
29735
+ var SECTIONS = [
29736
+ ["<!--", "-->"],
29737
+ ["<![CDATA[", "]]>"],
29738
+ ["<?", "?>"]
29739
+ ];
29740
+ function blankComments(xml) {
29741
+ if (!xml.includes("<!--") && !xml.includes("<![CDATA[")) return xml;
29742
+ const pieces = [];
29743
+ let copied = 0;
29744
+ SPECIAL.lastIndex = 0;
29745
+ for (let match2 = SPECIAL.exec(xml); match2; match2 = SPECIAL.exec(xml)) {
29746
+ const at2 = match2.index;
29747
+ const section3 = SECTIONS.find(([open2]) => xml.startsWith(open2, at2));
29748
+ if (!section3) return void 0;
29749
+ const [open, close4] = section3;
29750
+ const end = xml.indexOf(close4, at2 + open.length);
29751
+ if (end < 0) return void 0;
29752
+ const after = end + close4.length;
29753
+ if (open !== "<?") {
29754
+ pieces.push(xml.slice(copied, at2), " ".repeat(after - at2));
29755
+ copied = after;
29756
+ }
29757
+ SPECIAL.lastIndex = after;
29758
+ }
29759
+ pieces.push(xml.slice(copied));
29760
+ return pieces.join("");
29761
+ }
29675
29762
  function splitSheetData(xml) {
29676
- if (xml.includes("<!--") || xml.includes("<![CDATA[")) return void 0;
29677
- const namespaces = rootNamespaces(xml);
29678
- const open = OPEN.exec(xml);
29763
+ const plain5 = blankComments(xml);
29764
+ if (plain5 === void 0) return void 0;
29765
+ const namespaces = rootNamespaces(plain5);
29766
+ const open = OPEN.exec(plain5);
29679
29767
  if (!namespaces || !open) return void 0;
29680
29768
  const prefix3 = (open[1] ?? "").slice(0, -1);
29681
29769
  const ns = namespaces[prefix3];
29682
29770
  if (prefix3 && ns === void 0) return void 0;
29683
29771
  const tagName2 = `${open[1] ?? ""}sheetData`;
29684
- const openEnd = xml.indexOf(">", open.index);
29772
+ const openEnd = plain5.indexOf(">", open.index);
29685
29773
  if (openEnd < 0) return void 0;
29686
- const attributes = xml.slice(open.index + tagName2.length + 1, openEnd);
29774
+ const attributes = plain5.slice(open.index + tagName2.length + 1, openEnd);
29687
29775
  if (attributes.trimEnd().endsWith("/") || attributes.includes("xmlns")) return void 0;
29688
- const close4 = xml.indexOf(`</${tagName2}`, openEnd);
29689
- if (close4 < 0 || OPEN.test(xml.slice(openEnd))) return void 0;
29776
+ const close4 = plain5.indexOf(`</${tagName2}`, openEnd);
29777
+ if (close4 < 0 || OPEN.test(plain5.slice(openEnd))) return void 0;
29690
29778
  const container = new LiteElement(tagName2, "sheetData", ns || null);
29691
29779
  const data = parseLiteFragment(xml.slice(openEnd + 1, close4), container, namespaces);
29692
29780
  if (!data) return void 0;
@@ -48160,9 +48248,9 @@ function toHtml(cells3, theme3) {
48160
48248
  for (let r = link.range.start.row; r <= link.range.end.row; r++)
48161
48249
  for (let c2 = link.range.start.col; c2 <= link.range.end.col; c2++) links.set(`${r},${c2}`, link);
48162
48250
  const covered = /* @__PURE__ */ new Set();
48163
- const spans2 = /* @__PURE__ */ new Map();
48251
+ const spans3 = /* @__PURE__ */ new Map();
48164
48252
  for (const m of cells3.merges) {
48165
- spans2.set(`${m.start.row},${m.start.col}`, m);
48253
+ spans3.set(`${m.start.row},${m.start.col}`, m);
48166
48254
  for (let r = m.start.row; r <= m.end.row; r++)
48167
48255
  for (let c2 = m.start.col; c2 <= m.end.col; c2++)
48168
48256
  if (r !== m.start.row || c2 !== m.start.col) covered.add(`${r},${c2}`);
@@ -48174,7 +48262,7 @@ function toHtml(cells3, theme3) {
48174
48262
  if (covered.has(`${r},${c2}`)) continue;
48175
48263
  const cell = cells3.data[r]?.[c2] ?? null;
48176
48264
  const attrs3 = [];
48177
- const span3 = spans2.get(`${r},${c2}`);
48265
+ const span3 = spans3.get(`${r},${c2}`);
48178
48266
  if (span3 && span3.end.row > span3.start.row)
48179
48267
  attrs3.push(`rowspan="${span3.end.row - span3.start.row + 1}"`);
48180
48268
  if (span3 && span3.end.col > span3.start.col)
@@ -49027,7 +49115,7 @@ function setColumnWidth(ctx, s, cols, width, measure2) {
49027
49115
  ctx.run(
49028
49116
  "Column width",
49029
49117
  "view",
49030
- [{ kind: "sheet", sheet: s }],
49118
+ [{ kind: "parts", sheet: s, parts: ["columns"] }],
49031
49119
  () => editColumns(sheet, cols, (info) => {
49032
49120
  const next = widths.get(info.min);
49033
49121
  if (next === void 0) {
@@ -49062,7 +49150,7 @@ function setRowHeight(ctx, s, rows, height) {
49062
49150
  ctx.run(
49063
49151
  "Row height",
49064
49152
  "view",
49065
- [{ kind: "sheet", sheet: s }],
49153
+ [{ kind: "rowInfo", sheet: s, rows }],
49066
49154
  () => {
49067
49155
  for (const row3 of rows) {
49068
49156
  const info = { ...sheet.rowInfo.get(row3) };
@@ -49092,7 +49180,9 @@ function setHidden(ctx, s, axis, indices, hidden) {
49092
49180
  ctx.run(
49093
49181
  `${hidden ? "Hide" : "Unhide"} ${noun}`,
49094
49182
  "view",
49095
- [{ kind: "sheet", sheet: s }],
49183
+ [
49184
+ axis === "col" ? { kind: "parts", sheet: s, parts: ["columns"] } : { kind: "rowInfo", sheet: s, rows: indices }
49185
+ ],
49096
49186
  () => {
49097
49187
  if (axis === "col") {
49098
49188
  editColumns(sheet, indices, (info) => {
@@ -49686,6 +49776,19 @@ function shiftEdgeCells(sheet, spec2, phase) {
49686
49776
  return out;
49687
49777
  }
49688
49778
 
49779
+ // xlsx/edit/history-rows.ts
49780
+ function captureRowInfo(sheet, rows) {
49781
+ return [...new Set(rows)].map((row3) => {
49782
+ const info = sheet.rowInfo.get(row3);
49783
+ return [row3, info && structuredClone(info)];
49784
+ });
49785
+ }
49786
+ function restoreRowInfo(sheet, entries) {
49787
+ for (const [row3, info] of entries)
49788
+ if (info) sheet.rowInfo.set(row3, structuredClone(info));
49789
+ else sheet.rowInfo.delete(row3);
49790
+ }
49791
+
49689
49792
  // xlsx/edit/history.ts
49690
49793
  var SETTING_KEYS = [
49691
49794
  "structureLocked",
@@ -49770,6 +49873,8 @@ function captureScope(workbook, scope, before) {
49770
49873
  if (!sheet) throw new RangeError(`No sheet at index ${scope.sheet}`);
49771
49874
  if (scope.kind === "sheet")
49772
49875
  return { kind: "sheet", sheet: scope.sheet, data: structuredClone(sheet) };
49876
+ if (scope.kind === "rowInfo")
49877
+ return { kind: "rowInfo", sheet: scope.sheet, rows: captureRowInfo(sheet, scope.rows) };
49773
49878
  if (scope.kind === "parts") {
49774
49879
  const data = {};
49775
49880
  for (const part of scope.parts) if (sheet[part] !== void 0) data[part] = sheet[part];
@@ -49821,6 +49926,7 @@ function restoreSnapshot(workbook, snapshot) {
49821
49926
  }
49822
49927
  const sheet = workbook.sheets[snapshot.sheet];
49823
49928
  if (!sheet) return;
49929
+ if (snapshot.kind === "rowInfo") return restoreRowInfo(sheet, snapshot.rows);
49824
49930
  if (snapshot.kind === "parts") {
49825
49931
  const target2 = sheet;
49826
49932
  const data = structuredClone(snapshot.data);
@@ -50537,16 +50643,27 @@ function columnOverrides(sheet, mdw, defaultPx) {
50537
50643
  }
50538
50644
  return out;
50539
50645
  }
50540
- function createGridMetrics(sheet, options2 = {}) {
50541
- const zoom = zoomPercent(options2.zoom ?? sheet.view.zoom);
50646
+ function pixelScale(zoom) {
50542
50647
  const factor = zoom / 100;
50543
- const mdw = options2.mdw ?? DEFAULT_MAX_DIGIT_WIDTH;
50544
- const scale2 = (px2) => px2 > 0 ? Math.max(1, Math.round(px2 * factor)) : 0;
50648
+ return (px2) => px2 > 0 ? Math.max(1, Math.round(px2 * factor)) : 0;
50649
+ }
50650
+ function columnAxis(sheet, mdw, scale2) {
50545
50651
  const defaultColPx = defaultColumnPixels(sheet.defaultColWidth, mdw);
50546
50652
  const colOverrides = [...columnOverrides(sheet, mdw, defaultColPx)].map(
50547
50653
  ([c2, px2]) => [c2, scale2(px2)]
50548
50654
  );
50549
- const cols = new AxisMetrics(scale2(defaultColPx), MAX_COL + 1, colOverrides);
50655
+ return new AxisMetrics(scale2(defaultColPx), MAX_COL + 1, colOverrides);
50656
+ }
50657
+ function createColumnWidths(sheet, options2 = {}) {
50658
+ const zoom = zoomPercent(options2.zoom ?? sheet.view.zoom);
50659
+ const cols = columnAxis(sheet, options2.mdw ?? DEFAULT_MAX_DIGIT_WIDTH, pixelScale(zoom));
50660
+ return (c2) => cols.size(c2);
50661
+ }
50662
+ function createGridMetrics(sheet, options2 = {}) {
50663
+ const zoom = zoomPercent(options2.zoom ?? sheet.view.zoom);
50664
+ const mdw = options2.mdw ?? DEFAULT_MAX_DIGIT_WIDTH;
50665
+ const scale2 = pixelScale(zoom);
50666
+ const cols = columnAxis(sheet, mdw, scale2);
50550
50667
  const defaultRowPx = pointsToPixels(sheet.defaultRowHeight);
50551
50668
  const rowOverrides = [];
50552
50669
  for (const [r, info] of sheet.rowInfo) {
@@ -52419,12 +52536,13 @@ function span2(from, to) {
52419
52536
  }
52420
52537
  function outlineRows(ctx, s, from, to, delta) {
52421
52538
  const sheet = sheetAt(ctx.workbook, s);
52539
+ const rows = span2(from, to);
52422
52540
  ctx.run(
52423
52541
  delta > 0 ? "Group rows" : "Ungroup rows",
52424
52542
  "structure",
52425
- [{ kind: "sheet", sheet: s }],
52543
+ [{ kind: "rowInfo", sheet: s, rows }],
52426
52544
  () => {
52427
- for (const row3 of span2(from, to)) {
52545
+ for (const row3 of rows) {
52428
52546
  const info = { ...sheet.rowInfo.get(row3) };
52429
52547
  const level2 = nextLevel(info.outlineLevel, delta);
52430
52548
  if (level2) info.outlineLevel = level2;
@@ -52444,7 +52562,7 @@ function outlineColumns(ctx, s, from, to, delta) {
52444
52562
  ctx.run(
52445
52563
  delta > 0 ? "Group columns" : "Ungroup columns",
52446
52564
  "structure",
52447
- [{ kind: "sheet", sheet: s }],
52565
+ [{ kind: "parts", sheet: s, parts: ["columns"] }],
52448
52566
  () => editColumns(sheet, span2(from, to), (info) => {
52449
52567
  const level2 = nextLevel(info.outlineLevel, delta);
52450
52568
  if (level2) info.outlineLevel = level2;
@@ -52467,7 +52585,7 @@ function setDefaultColumnWidth(ctx, s, width) {
52467
52585
  ctx.run(
52468
52586
  "Standard width",
52469
52587
  "format",
52470
- [{ kind: "sheet", sheet: s }],
52588
+ [{ kind: "parts", sheet: s, parts: ["defaultColWidth"] }],
52471
52589
  () => {
52472
52590
  if (width === void 0) Reflect.deleteProperty(sheet, "defaultColWidth");
52473
52591
  else sheet.defaultColWidth = width;
@@ -54846,6 +54964,87 @@ function cellView(workbook, sheetIndex2, row3, col, cf, options2 = {}) {
54846
54964
  return view;
54847
54965
  }
54848
54966
 
54967
+ // xlsx/layout/merge-sweep.ts
54968
+ var NONE = { merged: false, spanned: false };
54969
+ var SINGLE3 = { merged: true, spanned: false };
54970
+ var SPANNED = { merged: true, spanned: true };
54971
+ var spans2 = (merge2) => merge2.start.row !== merge2.end.row || merge2.start.col !== merge2.end.col;
54972
+ function firstRightOf(merges, col) {
54973
+ let lo = 0;
54974
+ let hi = merges.length;
54975
+ while (lo < hi) {
54976
+ const mid = lo + hi >> 1;
54977
+ if ((merges[mid]?.start.col ?? 0) <= col) lo = mid + 1;
54978
+ else hi = mid;
54979
+ }
54980
+ return lo;
54981
+ }
54982
+ var MergeSweep = class {
54983
+ /** The merges by first row; `next` is the first one the sweep has not reached. */
54984
+ byRow;
54985
+ next = 0;
54986
+ row = Number.NEGATIVE_INFINITY;
54987
+ /** The merges covering the current row, by first column. */
54988
+ active = [];
54989
+ /** The last row of the earliest-ending active merge. */
54990
+ firstEnd = Number.POSITIVE_INFINITY;
54991
+ overlapping = false;
54992
+ constructor(merges) {
54993
+ this.byRow = [...merges].sort((a2, b) => a2.start.row - b.start.row);
54994
+ }
54995
+ /** How many merges cover the current row, which is everything the sweep holds. */
54996
+ get size() {
54997
+ return this.active.length;
54998
+ }
54999
+ /** Moves to `row`, which must not be above the previous one. */
55000
+ moveTo(row3) {
55001
+ if (row3 < this.row) throw new RangeError(`Rows must not go up: ${row3} after ${this.row}`);
55002
+ this.row = row3;
55003
+ if (row3 > this.firstEnd) this.dropEnded(row3);
55004
+ for (; this.next < this.byRow.length; this.next++) {
55005
+ const merge2 = this.byRow[this.next];
55006
+ if (!merge2 || merge2.start.row > row3) break;
55007
+ if (merge2.end.row >= row3) this.add(merge2);
55008
+ }
55009
+ }
55010
+ /** How the merges cover column `col` of the current row. */
55011
+ at(col) {
55012
+ if (this.overlapping) {
55013
+ let merged = false;
55014
+ for (const merge3 of this.active) {
55015
+ if (col < merge3.start.col || col > merge3.end.col) continue;
55016
+ if (spans2(merge3)) return SPANNED;
55017
+ merged = true;
55018
+ }
55019
+ return merged ? SINGLE3 : NONE;
55020
+ }
55021
+ const merge2 = this.active[firstRightOf(this.active, col) - 1];
55022
+ if (!merge2 || col > merge2.end.col) return NONE;
55023
+ return spans2(merge2) ? SPANNED : SINGLE3;
55024
+ }
55025
+ add(merge2) {
55026
+ const at2 = firstRightOf(this.active, merge2.start.col);
55027
+ const before = this.active[at2 - 1];
55028
+ const after = this.active[at2];
55029
+ if (before && before.end.col >= merge2.start.col || after && merge2.end.col >= after.start.col)
55030
+ this.overlapping = true;
55031
+ this.active.splice(at2, 0, merge2);
55032
+ this.firstEnd = Math.min(this.firstEnd, merge2.end.row);
55033
+ }
55034
+ dropEnded(row3) {
55035
+ let kept = 0;
55036
+ let firstEnd = Number.POSITIVE_INFINITY;
55037
+ for (const merge2 of this.active) {
55038
+ if (merge2.end.row < row3) continue;
55039
+ this.active[kept++] = merge2;
55040
+ firstEnd = Math.min(firstEnd, merge2.end.row);
55041
+ }
55042
+ this.active.length = kept;
55043
+ this.firstEnd = firstEnd;
55044
+ if (!kept) this.overlapping = false;
55045
+ }
55046
+ };
55047
+
54849
55048
  // xlsx/layout/row-autofit.ts
54850
55049
  var LINE_HEIGHTS = [
54851
55050
  [6, 8.25],
@@ -54905,30 +55104,39 @@ function wrappedLineCount(text8, width, measure2) {
54905
55104
  }
54906
55105
  return lines2;
54907
55106
  }
54908
- function autoFitRowHeight(workbook, sheetIndex2, row3, measure2) {
55107
+ function fitRowHeights(workbook, sheetIndex2, rows, measure2) {
55108
+ const heights = /* @__PURE__ */ new Map();
54909
55109
  const sheet = workbook.sheets[sheetIndex2];
54910
- if (!sheet) return 15;
54911
- const cells3 = sheet.rows.get(row3);
54912
- if (!cells3?.size) return sheet.defaultRowHeight;
54913
- const metrics = createGridMetrics(sheet, { zoom: 100 });
54914
- let tallest = 0;
54915
- for (const col of cells3.keys()) {
54916
- const merged = sheet.merges.some(
54917
- (m) => row3 >= m.start.row && row3 <= m.end.row && col >= m.start.col && col <= m.end.col && (m.start.row !== m.end.row || m.start.col !== m.end.col)
54918
- );
54919
- if (merged) continue;
54920
- const view = cellView(workbook, sheetIndex2, row3, col);
54921
- if (!view.text) continue;
54922
- const fonts = view.rich?.length ? view.rich.map((run2) => run2.font) : [view.font];
54923
- const sizePt = Math.max(...fonts.map((f6) => f6.sizePx * 3 / 4));
54924
- let lines2 = 1;
54925
- if (view.wrap) {
54926
- const width = metrics.colWidth(col) - COLUMN_PADDING_PX - 1 - view.indentPx;
54927
- lines2 = wrappedLineCount(view.text, width, (text8) => measure2(text8, view.font));
55110
+ if (!sheet) return heights;
55111
+ const filled = [];
55112
+ for (const row3 of new Set(rows)) {
55113
+ if (sheet.rows.get(row3)?.size) filled.push(row3);
55114
+ else heights.set(row3, sheet.defaultRowHeight);
55115
+ }
55116
+ filled.sort((a2, b) => a2 - b);
55117
+ const merges = new MergeSweep(sheet.merges);
55118
+ let colWidth;
55119
+ for (const row3 of filled) {
55120
+ merges.moveTo(row3);
55121
+ let tallest = 0;
55122
+ for (const col of sheet.rows.get(row3)?.keys() ?? []) {
55123
+ const cover = merges.at(col);
55124
+ if (cover.spanned) continue;
55125
+ const view = cellView(workbook, sheetIndex2, row3, col, void 0, { merged: cover.merged });
55126
+ if (!view.text) continue;
55127
+ const fonts = view.rich?.length ? view.rich.map((run2) => run2.font) : [view.font];
55128
+ const sizePt = Math.max(...fonts.map((f6) => f6.sizePx * 3 / 4));
55129
+ let lines2 = 1;
55130
+ if (view.wrap) {
55131
+ colWidth ??= createColumnWidths(sheet, { zoom: 100 });
55132
+ const width = colWidth(col) - COLUMN_PADDING_PX - 1 - view.indentPx;
55133
+ lines2 = wrappedLineCount(view.text, width, (text8) => measure2(text8, view.font));
55134
+ }
55135
+ tallest = Math.max(tallest, lines2 * lineHeightPoints(sizePt));
54928
55136
  }
54929
- tallest = Math.max(tallest, lines2 * lineHeightPoints(sizePt));
55137
+ heights.set(row3, tallest > 0 ? tallest : sheet.defaultRowHeight);
54930
55138
  }
54931
- return tallest > 0 ? tallest : sheet.defaultRowHeight;
55139
+ return heights;
54932
55140
  }
54933
55141
  var approximateMeasure = (text8, font) => text8.length * font.sizePx * (font.bold ? 0.58 : 0.53);
54934
55142
 
@@ -54936,22 +55144,26 @@ var approximateMeasure = (text8, font) => text8.length * font.sizePx * (font.bol
54936
55144
  var MAX_HEIGHT2 = 409;
54937
55145
  function autoGrowRows(ctx, s, rows, measure2 = approximateMeasure) {
54938
55146
  const sheet = sheetAt(ctx.workbook, s);
54939
- const updates = [];
54940
- for (const row3 of new Set(rows)) {
55147
+ const candidates = [...new Set(rows)].filter((row3) => {
54941
55148
  const info = sheet.rowInfo.get(row3);
54942
- if (info?.customHeight || info?.hidden) continue;
54943
- const fit3 = Math.min(MAX_HEIGHT2, autoFitRowHeight(ctx.workbook, s, row3, measure2));
55149
+ return !info?.customHeight && !info?.hidden;
55150
+ });
55151
+ const fits = fitRowHeights(ctx.workbook, s, candidates, measure2);
55152
+ const updates = [];
55153
+ for (const row3 of candidates) {
55154
+ const fit3 = Math.min(MAX_HEIGHT2, fits.get(row3) ?? sheet.defaultRowHeight);
54944
55155
  const next = Math.abs(fit3 - sheet.defaultRowHeight) < 1e-9 ? void 0 : fit3;
54945
- const current = info?.height;
55156
+ const current = sheet.rowInfo.get(row3)?.height;
54946
55157
  if (current === next) continue;
54947
55158
  if (current !== void 0 && next !== void 0 && Math.abs(current - next) < 1e-9) continue;
54948
55159
  updates.push([row3, next]);
54949
55160
  }
54950
55161
  if (!updates.length) return [];
55162
+ const changed = updates.map(([row3]) => row3);
54951
55163
  ctx.run(
54952
55164
  "Row height",
54953
55165
  "view",
54954
- [{ kind: "sheet", sheet: s }],
55166
+ [{ kind: "rowInfo", sheet: s, rows: changed }],
54955
55167
  () => {
54956
55168
  for (const [row3, height] of updates) {
54957
55169
  const info = { ...sheet.rowInfo.get(row3) };
@@ -54963,7 +55175,7 @@ function autoGrowRows(ctx, s, rows, measure2 = approximateMeasure) {
54963
55175
  },
54964
55176
  { sheet: s, structural: true }
54965
55177
  );
54966
- return updates.map(([row3]) => row3);
55178
+ return changed;
54967
55179
  }
54968
55180
  var MAX_REFIT_ROWS = 1e4;
54969
55181
  function rowsToRefit(sheet, ranges) {
@@ -55719,11 +55931,84 @@ function createEditSession(workbook, options2 = {}) {
55719
55931
  };
55720
55932
  }
55721
55933
 
55934
+ // automation/xlsx-read.ts
55935
+ var INSPECT_LIST_LIMIT = 500;
55936
+ function sheetSummaries(workbook) {
55937
+ return workbook.sheets.map((sheet, index3) => {
55938
+ const used = usedRange(sheet);
55939
+ const omitted2 = sheet.tables.length - INSPECT_LIST_LIMIT;
55940
+ return {
55941
+ index: index3,
55942
+ name: sheet.name,
55943
+ state: sheet.state,
55944
+ usedRange: used ? formatRange(used) : null,
55945
+ rows: used ? used.end.row - used.start.row + 1 : 0,
55946
+ columns: used ? used.end.col - used.start.col + 1 : 0,
55947
+ tables: sheet.tables.slice(0, INSPECT_LIST_LIMIT).map((table4) => ({
55948
+ name: table4.displayName,
55949
+ range: formatRange(table4.range),
55950
+ headerRow: table4.headerRow,
55951
+ totalsRow: table4.totalsRow
55952
+ })),
55953
+ ...omitted2 > 0 ? { tablesOmitted: omitted2 } : {}
55954
+ };
55955
+ });
55956
+ }
55957
+ function definedNameList(workbook) {
55958
+ const visible = workbook.definedNames.filter((name3) => !name3.hidden);
55959
+ const definedNames = visible.slice(0, INSPECT_LIST_LIMIT).map((name3) => ({
55960
+ name: name3.name,
55961
+ refersTo: name3.formula,
55962
+ ...name3.localSheet === void 0 ? {} : { sheetIndex: name3.localSheet }
55963
+ }));
55964
+ const omitted2 = visible.length - INSPECT_LIST_LIMIT;
55965
+ return omitted2 > 0 ? { definedNames, definedNamesOmitted: omitted2 } : { definedNames };
55966
+ }
55967
+ function isoOf(serial, date1904, shows2) {
55968
+ if (!(serial >= 0) || serial > MAX_DATE_SERIAL + 1) return void 0;
55969
+ if (!date1904 && serial >= 60 && serial < 61) return void 0;
55970
+ const date2 = serialToDate(serial, date1904);
55971
+ if (date2.getUTCFullYear() > 9999) return void 0;
55972
+ const iso = date2.toISOString();
55973
+ const time = iso.slice(11, iso.endsWith(".000Z") ? 19 : 23);
55974
+ if (serial < 1 && (!date1904 || !shows2.date)) return time;
55975
+ return Number.isInteger(serial) && !shows2.time ? iso.slice(0, 10) : `${iso.slice(0, 10)}T${time}`;
55976
+ }
55977
+ function cellView2(workbook, cell) {
55978
+ const value3 = cell?.value ?? null;
55979
+ const text8 = displayText(workbook, cell);
55980
+ const view = cell?.formula ? { value: value3, formula: cell.formula, text: text8 } : { value: value3, text: text8 };
55981
+ const numFmt = styleAt(workbook, cell?.styleId).numFmt;
55982
+ if (numFmt === "General") return view;
55983
+ view.numberFormat = numFmt;
55984
+ const parts = typeof value3 === "number" ? dateTimeParts(numFmt, value3) : void 0;
55985
+ if (parts && typeof value3 === "number") {
55986
+ const iso = isoOf(value3, workbook.date1904, parts);
55987
+ if (iso) view.iso = iso;
55988
+ }
55989
+ return view;
55990
+ }
55991
+ var READ_LIMIT = 1e4;
55992
+ function rangeCells(workbook, sheet, range2) {
55993
+ const count2 = (range2.end.row - range2.start.row + 1) * (range2.end.col - range2.start.col + 1);
55994
+ if (count2 > READ_LIMIT) throw new Error(`Read at most ${READ_LIMIT} cells per request`);
55995
+ const cells3 = [];
55996
+ for (let row3 = range2.start.row; row3 <= range2.end.row; row3++)
55997
+ for (let col = range2.start.col; col <= range2.end.col; col++)
55998
+ cells3.push({
55999
+ address: formatAddress({ row: row3, col }),
56000
+ ...cellView2(workbook, getCell(sheet, row3, col))
56001
+ });
56002
+ return cells3;
56003
+ }
56004
+
55722
56005
  // automation/xlsx.ts
55723
56006
  async function inspectXlsx(bytes) {
55724
56007
  const workbook = await loadXlsx(bytes);
55725
56008
  return {
55726
- sheets: workbook.sheets.map((sheet, index3) => ({ index: index3, name: sheet.name })),
56009
+ sheets: sheetSummaries(workbook),
56010
+ activeSheet: workbook.activeSheet,
56011
+ ...definedNameList(workbook),
55727
56012
  properties: workbook.properties,
55728
56013
  warnings: workbook.warnings
55729
56014
  };
@@ -55746,19 +56031,7 @@ async function readXlsxRange(bytes, sheetIndex2, reference2) {
55746
56031
  const range2 = parseRange(reference2);
55747
56032
  if (!sheet || !range2 || range2.end.col > MAX_COL || range2.end.row > MAX_ROW)
55748
56033
  throw new Error("Invalid sheet or range");
55749
- const count2 = (range2.end.row - range2.start.row + 1) * (range2.end.col - range2.start.col + 1);
55750
- if (count2 > 1e4) throw new Error("Read at most 10000 cells per request");
55751
- const cells3 = [];
55752
- for (let row3 = range2.start.row; row3 <= range2.end.row; row3++)
55753
- for (let col = range2.start.col; col <= range2.end.col; col++) {
55754
- const cell = getCell(sheet, row3, col);
55755
- cells3.push({
55756
- address: formatAddress({ row: row3, col }),
55757
- value: cell?.value ?? null,
55758
- formula: cell?.formula
55759
- });
55760
- }
55761
- return { cells: cells3, warnings: workbook.warnings };
56034
+ return { cells: rangeCells(workbook, sheet, range2), warnings: workbook.warnings };
55762
56035
  }
55763
56036
  async function setXlsxCells(bytes, sheetIndex2, cells3) {
55764
56037
  const workbook = await loadXlsx(bytes);
@@ -55801,6 +56074,65 @@ async function readXlsxFilledCells(bytes, { maxCells = 5e3 } = {}) {
55801
56074
  warnings: workbook.warnings
55802
56075
  };
55803
56076
  }
56077
+ async function findXlsxCells(bytes, text8, options2 = {}) {
56078
+ if (!text8) throw new Error("The search text is empty");
56079
+ const max = options2.maxResults ?? 100;
56080
+ if (!Number.isSafeInteger(max) || max < 1 || max > 1e3)
56081
+ throw new Error("Return between 1 and 1000 matches per request");
56082
+ const workbook = await loadXlsx(bytes);
56083
+ const query = { text: text8, lookIn: options2.lookIn ?? "formulas" };
56084
+ const { sheetIndex: sheetIndex2 } = options2;
56085
+ if (sheetIndex2 !== void 0) {
56086
+ if (!Number.isSafeInteger(sheetIndex2) || !workbook.sheets[sheetIndex2])
56087
+ throw new Error("Invalid sheet");
56088
+ query.sheet = sheetIndex2;
56089
+ }
56090
+ if (options2.range !== void 0) {
56091
+ const range2 = parseRange(options2.range);
56092
+ if (sheetIndex2 === void 0) throw new Error("A range needs a sheetIndex");
56093
+ if (!range2) throw new Error("Invalid range");
56094
+ query.range = range2;
56095
+ }
56096
+ if (options2.matchCase) query.matchCase = true;
56097
+ if (options2.wholeCell) query.wholeCell = true;
56098
+ if (options2.wildcards === false) query.wildcards = false;
56099
+ const found = findAll(workbook, query);
56100
+ const matches2 = found.slice(0, max).map((match2) => {
56101
+ const sheet = workbook.sheets[match2.sheet];
56102
+ return {
56103
+ sheetIndex: match2.sheet,
56104
+ sheet: sheet?.name ?? "",
56105
+ address: formatAddress(match2),
56106
+ ...cellView2(workbook, sheet && getCell(sheet, match2.row, match2.col))
56107
+ };
56108
+ });
56109
+ return {
56110
+ matches: matches2,
56111
+ total: found.length,
56112
+ truncated: found.length > max,
56113
+ warnings: workbook.warnings
56114
+ };
56115
+ }
56116
+ async function readXlsxTable(bytes, name3) {
56117
+ const workbook = await loadXlsx(bytes);
56118
+ const wanted = name3.toLowerCase();
56119
+ for (const [sheetIndex2, sheet] of workbook.sheets.entries()) {
56120
+ const table4 = sheet.tables.find((t) => t.displayName.toLowerCase() === wanted);
56121
+ if (!table4) continue;
56122
+ return {
56123
+ sheetIndex: sheetIndex2,
56124
+ sheet: sheet.name,
56125
+ name: table4.displayName,
56126
+ range: formatRange(table4.range),
56127
+ headerRow: table4.headerRow,
56128
+ totalsRow: table4.totalsRow,
56129
+ columns: table4.columns.map((column2) => column2.name),
56130
+ cells: rangeCells(workbook, sheet, table4.range),
56131
+ warnings: workbook.warnings
56132
+ };
56133
+ }
56134
+ throw new Error(`No table named ${name3}`);
56135
+ }
55804
56136
 
55805
56137
  // visio/package-common.ts
55806
56138
  var VisioPackageError = class extends Error {
@@ -55884,7 +56216,7 @@ function inspectZip(bytes, limits, check3) {
55884
56216
  if (count2 > limits.maxEntries) fail2("LIMIT_ENTRIES", "Too many ZIP entries");
55885
56217
  if (centralStart + centralSize !== end) fail2("INVALID_ZIP", "Invalid central directory bounds");
55886
56218
  const entries = /* @__PURE__ */ new Map(), canonical2 = /* @__PURE__ */ new Set();
55887
- const spans2 = [];
56219
+ const spans3 = [];
55888
56220
  let offset2 = centralStart, total2 = 0;
55889
56221
  const extras = (start, length, name3) => {
55890
56222
  const stop = start + length;
@@ -55954,14 +56286,14 @@ function inspectZip(bytes, limits, check3) {
55954
56286
  dataEnd += 12;
55955
56287
  }
55956
56288
  if (dataEnd > centralStart) fail2("ZIP_MISMATCH", "ZIP entry overlaps the central directory");
55957
- spans2.push({ start: local, end: dataEnd });
56289
+ spans3.push({ start: local, end: dataEnd });
55958
56290
  entries.set(name3, { name: name3, compressed, size: size3, crc, directory });
55959
56291
  offset2 += 46 + nameLength + extraLength + commentLength;
55960
56292
  }
55961
56293
  if (offset2 !== end) fail2("INVALID_ZIP", "Central directory length or count mismatch");
55962
- spans2.sort((a2, b) => a2.start - b.start);
56294
+ spans3.sort((a2, b) => a2.start - b.start);
55963
56295
  let previousEnd = 0;
55964
- for (const span3 of spans2) {
56296
+ for (const span3 of spans3) {
55965
56297
  if (span3.start !== previousEnd)
55966
56298
  fail2("ZIP_MISMATCH", "Overlapping, prefixed, or unindexed ZIP records");
55967
56299
  previousEnd = span3.end;
@@ -68691,13 +69023,13 @@ function flattenCornerCurve(points) {
68691
69023
  return flattened ? [points[0], ...flattened] : void 0;
68692
69024
  }
68693
69025
  function connectorCurveMiddle(points) {
68694
- const spans2 = connectorCurveSpans(points);
69026
+ const spans3 = connectorCurveSpans(points);
68695
69027
  if (points.length === 5) {
68696
69028
  const flattened = flattenCornerCurve(points);
68697
69029
  if (flattened) return connectorPolylineMiddle(flattened);
68698
69030
  return mix(points[0], points.at(-1), 0.5);
68699
69031
  }
68700
- const row3 = [...spans2[0]];
69032
+ const row3 = [...spans3[0]];
68701
69033
  for (let count2 = row3.length - 1; count2 > 0; count2--)
68702
69034
  for (let i2 = 0; i2 < count2; i2++) row3[i2] = mix(row3[i2], row3[i2 + 1], 0.5);
68703
69035
  return row3[0];
@@ -79753,7 +80085,7 @@ function assertParentIndependent(facts, from, ids) {
79753
80085
 
79754
80086
  // visio/edit-group.ts
79755
80087
  var clean5 = (value3) => Math.abs(value3) < 1e-12 ? 0 : value3;
79756
- var NONE = /* @__PURE__ */ new Map();
80088
+ var NONE2 = /* @__PURE__ */ new Map();
79757
80089
  function topLevel2(root) {
79758
80090
  const containers = children3(root, "Shapes");
79759
80091
  if (containers.length !== 1)
@@ -79768,7 +80100,7 @@ function assertGroupable(shape2, document) {
79768
80100
  assertShapeLocks(shape2, document, ["LockGroup"]);
79769
80101
  assertUnlayeredShape(shape2, document);
79770
80102
  }
79771
- var transformOf = (shape2, instances = NONE) => {
80103
+ var transformOf = (shape2, instances = NONE2) => {
79772
80104
  const local = cells(instances.get(shape2)?.view ?? shape2);
79773
80105
  const width = numeric4(local.get("Width")), height = numeric4(local.get("Height"));
79774
80106
  return {
@@ -79790,7 +80122,7 @@ var transformOf = (shape2, instances = NONE) => {
79790
80122
  )
79791
80123
  };
79792
80124
  };
79793
- function visioShapeBounds(shapes, instances = NONE) {
80125
+ function visioShapeBounds(shapes, instances = NONE2) {
79794
80126
  let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
79795
80127
  for (const shape2 of shapes) {
79796
80128
  const box5 = transformOf(shape2, instances);
@@ -79810,7 +80142,7 @@ function visioShapeBounds(shapes, instances = NONE) {
79810
80142
  }
79811
80143
  return { minX, minY, maxX, maxY };
79812
80144
  }
79813
- function groupVisioShapes(root, document, edit, check3, instances = NONE) {
80145
+ function groupVisioShapes(root, document, edit, check3, instances = NONE2) {
79814
80146
  check3();
79815
80147
  const siblings = topLevel2(root);
79816
80148
  for (const node3 of Array.from(root.getElementsByTagName("*")))
@@ -79883,7 +80215,7 @@ function groupVisioShapes(root, document, edit, check3, instances = NONE) {
79883
80215
  }
79884
80216
  return true;
79885
80217
  }
79886
- function ungroupVisioShape(root, document, edit, check3, instances = NONE) {
80218
+ function ungroupVisioShape(root, document, edit, check3, instances = NONE2) {
79887
80219
  check3();
79888
80220
  const candidates = topLevel2(root).filter((shape2) => attribute3(shape2, "ID") === edit.shapeId);
79889
80221
  if (candidates.length !== 1 || attribute3(candidates[0], "Type") !== "Group")
@@ -82394,11 +82726,13 @@ exports.createDocxFromOutline = createDocxFromOutline;
82394
82726
  exports.createXlsx = createXlsx;
82395
82727
  exports.createXlsxFromSheets = createXlsxFromSheets;
82396
82728
  exports.editVisio = editVsdx;
82729
+ exports.findXlsxCells = findXlsxCells;
82397
82730
  exports.inspectDocx = inspectDocx;
82398
82731
  exports.inspectVisio = inspectVisio;
82399
82732
  exports.inspectXlsx = inspectXlsx;
82400
82733
  exports.readXlsxFilledCells = readXlsxFilledCells;
82401
82734
  exports.readXlsxRange = readXlsxRange;
82735
+ exports.readXlsxTable = readXlsxTable;
82402
82736
  exports.setDocxRunText = setDocxRunText;
82403
82737
  exports.setXlsxCells = setXlsxCells;
82404
82738
  exports.suggestDocxRunText = suggestDocxRunText;