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
@@ -236,6 +236,12 @@ function parseLiteFragment(xml, container, namespaces) {
236
236
  }
237
237
  if (lt < 0) break;
238
238
  const next = source2.charCodeAt(lt + 1);
239
+ if (next === 33) {
240
+ const after = skipCommentOrCdata(source2, lt, top);
241
+ if (after < 0) return void 0;
242
+ pos = after;
243
+ continue;
244
+ }
239
245
  if (next === 47) {
240
246
  const gt = source2.indexOf(">", lt);
241
247
  if (gt < 0 || stack2.length < 2 || source2.slice(lt + 2, gt).trimEnd() !== top.tagName)
@@ -256,6 +262,25 @@ function parseLiteFragment(xml, container, namespaces) {
256
262
  }
257
263
  return stack2.length === 1 ? root : void 0;
258
264
  }
265
+ var DECLARATIONS = /<!DOCTYPE|<!ENTITY/i;
266
+ function skipCommentOrCdata(source2, lt, parent) {
267
+ if (source2.startsWith("<!--", lt)) {
268
+ const end = source2.indexOf("-->", lt + 4);
269
+ if (end < 0) return -1;
270
+ const body = source2.slice(lt + 4, end);
271
+ if (body.includes("--") || body.endsWith("-") || DECLARATIONS.test(body)) return -1;
272
+ return end + 3;
273
+ }
274
+ if (source2.startsWith("<![CDATA[", lt)) {
275
+ const end = source2.indexOf("]]>", lt + 9);
276
+ if (end < 0) return -1;
277
+ const text8 = source2.slice(lt + 9, end);
278
+ if (DECLARATIONS.test(text8)) return -1;
279
+ parent.childNodes.push(text8);
280
+ return end + 3;
281
+ }
282
+ return -1;
283
+ }
259
284
  function startTag(source2, from, namespaces) {
260
285
  const n = source2.length;
261
286
  let i2 = from;
@@ -3522,7 +3547,10 @@ function writeTable(doc, table4, node3, base2, writeParagraph, replaceSlots2) {
3522
3547
  "Cannot change the structure of a merged, nested, or complex table. The original DOCX package remains unchanged."
3523
3548
  );
3524
3549
  const width = table4.rows[0]?.length ?? 0;
3525
- if (!width || table4.rows.some((row3) => row3.length !== width || row3.some((cell) => !cell.paragraphs.length)))
3550
+ const reshaped = structural || !base2;
3551
+ if (!width || table4.rows.some(
3552
+ (row3) => reshaped && row3.length !== width || row3.some((cell) => !cell.paragraphs.length)
3553
+ ))
3526
3554
  throw new Error("Tables must contain rectangular rows and at least one paragraph per cell.");
3527
3555
  const oldRows = flatRows(node3).map((entry3) => entry3.element);
3528
3556
  const sourceById = /* @__PURE__ */ new Map();
@@ -19354,13 +19382,13 @@ function rejectUnsafeRunSegmentation(paragraph2, base2, oldRuns) {
19354
19382
  `Cannot edit paragraph ${paragraph2.id}: changing run boundaries could drop unsupported run properties. The original DOCX package remains unchanged.`
19355
19383
  );
19356
19384
  }
19357
- function writeParagraphImpl(doc, paragraph2, node3, base2, allocator, spans2) {
19358
- const continuation = spans2?.next.get(paragraph2.id);
19359
- const ranges = spans2 && {
19385
+ function writeParagraphImpl(doc, paragraph2, node3, base2, allocator, spans3) {
19386
+ const continuation = spans3?.next.get(paragraph2.id);
19387
+ const ranges = spans3 && {
19360
19388
  ...continuation ?? { before: /* @__PURE__ */ new Set(), after: /* @__PURE__ */ new Set() },
19361
- rangeIds: spans2.rangeIds
19389
+ rangeIds: spans3.rangeIds
19362
19390
  };
19363
- const sameRanges = continuationKey(continuation) === continuationKey(spans2?.original.get(paragraph2.id));
19391
+ const sameRanges = continuationKey(continuation) === continuationKey(spans3?.original.get(paragraph2.id));
19364
19392
  if (base2 && sameRanges && JSON.stringify(paragraph2) === JSON.stringify(base2)) return node3;
19365
19393
  const slots = collectInlineSlots(node3);
19366
19394
  if (!slots)
@@ -19421,7 +19449,7 @@ function writeParagraphImpl(doc, paragraph2, node3, base2, allocator, spans2) {
19421
19449
  children2(node3, "bookmarkEnd"),
19422
19450
  paragraph2.bookmarks ?? [],
19423
19451
  base2?.bookmarks ?? [],
19424
- () => spans2?.nextId() ?? "0"
19452
+ () => spans3?.nextId() ?? "0"
19425
19453
  );
19426
19454
  for (const bookmark of [...children2(node3, "bookmarkStart"), ...children2(node3, "bookmarkEnd")])
19427
19455
  node3.removeChild(bookmark);
@@ -19443,9 +19471,9 @@ function writeParagraphImpl(doc, paragraph2, node3, base2, allocator, spans2) {
19443
19471
  if (!pPr.childNodes.length) node3.removeChild(pPr);
19444
19472
  return node3;
19445
19473
  }
19446
- function createParagraph(doc, paragraph2, allocator, spans2) {
19474
+ function createParagraph(doc, paragraph2, allocator, spans3) {
19447
19475
  const node3 = makeW(doc, "p");
19448
- return writeParagraphImpl(doc, paragraph2, node3, void 0, allocator, spans2);
19476
+ return writeParagraphImpl(doc, paragraph2, node3, void 0, allocator, spans3);
19449
19477
  }
19450
19478
 
19451
19479
  // docx/docpr-ids.ts
@@ -19534,7 +19562,7 @@ var RelationshipAllocator = class {
19534
19562
 
19535
19563
  // docx/write.ts
19536
19564
  var twips2 = (pixels) => String(Math.round(pixels * 15));
19537
- function createTable(doc, table4, allocator, contentWidthTwips, spans2) {
19565
+ function createTable(doc, table4, allocator, contentWidthTwips, spans3) {
19538
19566
  const node3 = makeW(doc, "tbl");
19539
19567
  const { tblPr, tblGrid } = buildNewTableProperties(doc, table4, contentWidthTwips);
19540
19568
  node3.appendChild(tblPr);
@@ -19550,7 +19578,7 @@ function createTable(doc, table4, allocator, contentWidthTwips, spans2) {
19550
19578
  const tcPr = buildCellProperties(doc, cell);
19551
19579
  if (tcPr) tc.appendChild(tcPr);
19552
19580
  for (const paragraph2 of cell.paragraphs)
19553
- tc.appendChild(createParagraph(doc, paragraph2, allocator, spans2));
19581
+ tc.appendChild(createParagraph(doc, paragraph2, allocator, spans3));
19554
19582
  if (!cell.paragraphs.length) tc.appendChild(makeW(doc, "p"));
19555
19583
  tr.appendChild(tc);
19556
19584
  }
@@ -19578,13 +19606,13 @@ function baseMap(blocks) {
19578
19606
  }
19579
19607
  function applyBlocks(doc, container, blocks, original, allocator, contentWidthTwips, anchor = null) {
19580
19608
  const nextId3 = annotationIdAllocator(doc, blocks);
19581
- const spans2 = {
19609
+ const spans3 = {
19582
19610
  next: commentContinuations(blocks),
19583
19611
  original: commentContinuations(original),
19584
19612
  rangeIds: newMoveRangeIds(blocks, nextId3),
19585
19613
  nextId: nextId3
19586
19614
  };
19587
- const boundWriteParagraph = (writeDoc, paragraph2, node3, base2) => writeParagraphImpl(writeDoc, paragraph2, node3, base2, allocator, spans2);
19615
+ const boundWriteParagraph = (writeDoc, paragraph2, node3, base2) => writeParagraphImpl(writeDoc, paragraph2, node3, base2, allocator, spans3);
19588
19616
  const flat = flatBlocks(container);
19589
19617
  const oldNodes = flat.map((entry3) => entry3.element);
19590
19618
  const oldById = /* @__PURE__ */ new Map();
@@ -19598,7 +19626,7 @@ function applyBlocks(doc, container, blocks, original, allocator, contentWidthTw
19598
19626
  const base2 = bases.get(block.id);
19599
19627
  if (block.type === "paragraph")
19600
19628
  output.push(
19601
- old ? boundWriteParagraph(doc, block, old, base2?.type === "paragraph" ? base2 : void 0) : createParagraph(doc, block, allocator, spans2)
19629
+ old ? boundWriteParagraph(doc, block, old, base2?.type === "paragraph" ? base2 : void 0) : createParagraph(doc, block, allocator, spans3)
19602
19630
  );
19603
19631
  else
19604
19632
  output.push(
@@ -19609,7 +19637,7 @@ function applyBlocks(doc, container, blocks, original, allocator, contentWidthTw
19609
19637
  base2?.type === "table" ? base2 : void 0,
19610
19638
  boundWriteParagraph,
19611
19639
  replaceSlots
19612
- ) : createTable(doc, block, allocator, contentWidthTwips, spans2)
19640
+ ) : createTable(doc, block, allocator, contentWidthTwips, spans3)
19613
19641
  );
19614
19642
  }
19615
19643
  const nested = flat.some((entry3) => entry3.sdt) || blocks.some((block) => block.contentControl);
@@ -23713,6 +23741,37 @@ function formatValue(value3, format5, options2 = {}) {
23713
23741
  function isDateFormat(format5) {
23714
23742
  return compileFormat(format5).isDate;
23715
23743
  }
23744
+ var DAY_PARTS = /* @__PURE__ */ new Set([
23745
+ "y",
23746
+ "yyyy",
23747
+ "e",
23748
+ "g",
23749
+ "b",
23750
+ "bbbb",
23751
+ "m",
23752
+ "mm",
23753
+ "mmm",
23754
+ "mmmm",
23755
+ "mmmmm",
23756
+ "d",
23757
+ "dd",
23758
+ "ddd",
23759
+ "dddd"
23760
+ ]);
23761
+ function dateTimeParts(format5, value3) {
23762
+ const section3 = chooseSection(compileFormat(format5), value3)?.section;
23763
+ if (section3?.kind !== "date") return void 0;
23764
+ let date2 = false;
23765
+ let time = false;
23766
+ for (const token of section3.tokens) {
23767
+ if (token.t === "elapsed") return void 0;
23768
+ if (token.t === "date") {
23769
+ if (DAY_PARTS.has(token.part)) date2 = true;
23770
+ else time = true;
23771
+ } else if (token.t === "ampm" || token.t === "subsec") time = true;
23772
+ }
23773
+ return date2 || time ? { date: date2, time } : void 0;
23774
+ }
23716
23775
 
23717
23776
  // xlsx/numfmt/input-date.ts
23718
23777
  var MONTH_NAMES = [
@@ -29666,21 +29725,50 @@ function rootNamespaces(xml) {
29666
29725
  for (const match2 of (root[2] ?? "").matchAll(DECLARATION3)) out[match2[1] ?? ""] = match2[3] ?? "";
29667
29726
  return out;
29668
29727
  }
29728
+ var SPECIAL = /<[!?]/g;
29729
+ var SECTIONS = [
29730
+ ["<!--", "-->"],
29731
+ ["<![CDATA[", "]]>"],
29732
+ ["<?", "?>"]
29733
+ ];
29734
+ function blankComments(xml) {
29735
+ if (!xml.includes("<!--") && !xml.includes("<![CDATA[")) return xml;
29736
+ const pieces = [];
29737
+ let copied = 0;
29738
+ SPECIAL.lastIndex = 0;
29739
+ for (let match2 = SPECIAL.exec(xml); match2; match2 = SPECIAL.exec(xml)) {
29740
+ const at2 = match2.index;
29741
+ const section3 = SECTIONS.find(([open2]) => xml.startsWith(open2, at2));
29742
+ if (!section3) return void 0;
29743
+ const [open, close4] = section3;
29744
+ const end = xml.indexOf(close4, at2 + open.length);
29745
+ if (end < 0) return void 0;
29746
+ const after = end + close4.length;
29747
+ if (open !== "<?") {
29748
+ pieces.push(xml.slice(copied, at2), " ".repeat(after - at2));
29749
+ copied = after;
29750
+ }
29751
+ SPECIAL.lastIndex = after;
29752
+ }
29753
+ pieces.push(xml.slice(copied));
29754
+ return pieces.join("");
29755
+ }
29669
29756
  function splitSheetData(xml) {
29670
- if (xml.includes("<!--") || xml.includes("<![CDATA[")) return void 0;
29671
- const namespaces = rootNamespaces(xml);
29672
- const open = OPEN.exec(xml);
29757
+ const plain5 = blankComments(xml);
29758
+ if (plain5 === void 0) return void 0;
29759
+ const namespaces = rootNamespaces(plain5);
29760
+ const open = OPEN.exec(plain5);
29673
29761
  if (!namespaces || !open) return void 0;
29674
29762
  const prefix3 = (open[1] ?? "").slice(0, -1);
29675
29763
  const ns = namespaces[prefix3];
29676
29764
  if (prefix3 && ns === void 0) return void 0;
29677
29765
  const tagName2 = `${open[1] ?? ""}sheetData`;
29678
- const openEnd = xml.indexOf(">", open.index);
29766
+ const openEnd = plain5.indexOf(">", open.index);
29679
29767
  if (openEnd < 0) return void 0;
29680
- const attributes = xml.slice(open.index + tagName2.length + 1, openEnd);
29768
+ const attributes = plain5.slice(open.index + tagName2.length + 1, openEnd);
29681
29769
  if (attributes.trimEnd().endsWith("/") || attributes.includes("xmlns")) return void 0;
29682
- const close4 = xml.indexOf(`</${tagName2}`, openEnd);
29683
- if (close4 < 0 || OPEN.test(xml.slice(openEnd))) return void 0;
29770
+ const close4 = plain5.indexOf(`</${tagName2}`, openEnd);
29771
+ if (close4 < 0 || OPEN.test(plain5.slice(openEnd))) return void 0;
29684
29772
  const container = new LiteElement(tagName2, "sheetData", ns || null);
29685
29773
  const data = parseLiteFragment(xml.slice(openEnd + 1, close4), container, namespaces);
29686
29774
  if (!data) return void 0;
@@ -48154,9 +48242,9 @@ function toHtml(cells3, theme3) {
48154
48242
  for (let r = link.range.start.row; r <= link.range.end.row; r++)
48155
48243
  for (let c2 = link.range.start.col; c2 <= link.range.end.col; c2++) links.set(`${r},${c2}`, link);
48156
48244
  const covered = /* @__PURE__ */ new Set();
48157
- const spans2 = /* @__PURE__ */ new Map();
48245
+ const spans3 = /* @__PURE__ */ new Map();
48158
48246
  for (const m of cells3.merges) {
48159
- spans2.set(`${m.start.row},${m.start.col}`, m);
48247
+ spans3.set(`${m.start.row},${m.start.col}`, m);
48160
48248
  for (let r = m.start.row; r <= m.end.row; r++)
48161
48249
  for (let c2 = m.start.col; c2 <= m.end.col; c2++)
48162
48250
  if (r !== m.start.row || c2 !== m.start.col) covered.add(`${r},${c2}`);
@@ -48168,7 +48256,7 @@ function toHtml(cells3, theme3) {
48168
48256
  if (covered.has(`${r},${c2}`)) continue;
48169
48257
  const cell = cells3.data[r]?.[c2] ?? null;
48170
48258
  const attrs3 = [];
48171
- const span3 = spans2.get(`${r},${c2}`);
48259
+ const span3 = spans3.get(`${r},${c2}`);
48172
48260
  if (span3 && span3.end.row > span3.start.row)
48173
48261
  attrs3.push(`rowspan="${span3.end.row - span3.start.row + 1}"`);
48174
48262
  if (span3 && span3.end.col > span3.start.col)
@@ -49021,7 +49109,7 @@ function setColumnWidth(ctx, s, cols, width, measure2) {
49021
49109
  ctx.run(
49022
49110
  "Column width",
49023
49111
  "view",
49024
- [{ kind: "sheet", sheet: s }],
49112
+ [{ kind: "parts", sheet: s, parts: ["columns"] }],
49025
49113
  () => editColumns(sheet, cols, (info) => {
49026
49114
  const next = widths.get(info.min);
49027
49115
  if (next === void 0) {
@@ -49056,7 +49144,7 @@ function setRowHeight(ctx, s, rows, height) {
49056
49144
  ctx.run(
49057
49145
  "Row height",
49058
49146
  "view",
49059
- [{ kind: "sheet", sheet: s }],
49147
+ [{ kind: "rowInfo", sheet: s, rows }],
49060
49148
  () => {
49061
49149
  for (const row3 of rows) {
49062
49150
  const info = { ...sheet.rowInfo.get(row3) };
@@ -49086,7 +49174,9 @@ function setHidden(ctx, s, axis, indices, hidden) {
49086
49174
  ctx.run(
49087
49175
  `${hidden ? "Hide" : "Unhide"} ${noun}`,
49088
49176
  "view",
49089
- [{ kind: "sheet", sheet: s }],
49177
+ [
49178
+ axis === "col" ? { kind: "parts", sheet: s, parts: ["columns"] } : { kind: "rowInfo", sheet: s, rows: indices }
49179
+ ],
49090
49180
  () => {
49091
49181
  if (axis === "col") {
49092
49182
  editColumns(sheet, indices, (info) => {
@@ -49680,6 +49770,19 @@ function shiftEdgeCells(sheet, spec2, phase) {
49680
49770
  return out;
49681
49771
  }
49682
49772
 
49773
+ // xlsx/edit/history-rows.ts
49774
+ function captureRowInfo(sheet, rows) {
49775
+ return [...new Set(rows)].map((row3) => {
49776
+ const info = sheet.rowInfo.get(row3);
49777
+ return [row3, info && structuredClone(info)];
49778
+ });
49779
+ }
49780
+ function restoreRowInfo(sheet, entries) {
49781
+ for (const [row3, info] of entries)
49782
+ if (info) sheet.rowInfo.set(row3, structuredClone(info));
49783
+ else sheet.rowInfo.delete(row3);
49784
+ }
49785
+
49683
49786
  // xlsx/edit/history.ts
49684
49787
  var SETTING_KEYS = [
49685
49788
  "structureLocked",
@@ -49764,6 +49867,8 @@ function captureScope(workbook, scope, before) {
49764
49867
  if (!sheet) throw new RangeError(`No sheet at index ${scope.sheet}`);
49765
49868
  if (scope.kind === "sheet")
49766
49869
  return { kind: "sheet", sheet: scope.sheet, data: structuredClone(sheet) };
49870
+ if (scope.kind === "rowInfo")
49871
+ return { kind: "rowInfo", sheet: scope.sheet, rows: captureRowInfo(sheet, scope.rows) };
49767
49872
  if (scope.kind === "parts") {
49768
49873
  const data = {};
49769
49874
  for (const part of scope.parts) if (sheet[part] !== void 0) data[part] = sheet[part];
@@ -49815,6 +49920,7 @@ function restoreSnapshot(workbook, snapshot) {
49815
49920
  }
49816
49921
  const sheet = workbook.sheets[snapshot.sheet];
49817
49922
  if (!sheet) return;
49923
+ if (snapshot.kind === "rowInfo") return restoreRowInfo(sheet, snapshot.rows);
49818
49924
  if (snapshot.kind === "parts") {
49819
49925
  const target2 = sheet;
49820
49926
  const data = structuredClone(snapshot.data);
@@ -50531,16 +50637,27 @@ function columnOverrides(sheet, mdw, defaultPx) {
50531
50637
  }
50532
50638
  return out;
50533
50639
  }
50534
- function createGridMetrics(sheet, options2 = {}) {
50535
- const zoom = zoomPercent(options2.zoom ?? sheet.view.zoom);
50640
+ function pixelScale(zoom) {
50536
50641
  const factor = zoom / 100;
50537
- const mdw = options2.mdw ?? DEFAULT_MAX_DIGIT_WIDTH;
50538
- const scale2 = (px2) => px2 > 0 ? Math.max(1, Math.round(px2 * factor)) : 0;
50642
+ return (px2) => px2 > 0 ? Math.max(1, Math.round(px2 * factor)) : 0;
50643
+ }
50644
+ function columnAxis(sheet, mdw, scale2) {
50539
50645
  const defaultColPx = defaultColumnPixels(sheet.defaultColWidth, mdw);
50540
50646
  const colOverrides = [...columnOverrides(sheet, mdw, defaultColPx)].map(
50541
50647
  ([c2, px2]) => [c2, scale2(px2)]
50542
50648
  );
50543
- const cols = new AxisMetrics(scale2(defaultColPx), MAX_COL + 1, colOverrides);
50649
+ return new AxisMetrics(scale2(defaultColPx), MAX_COL + 1, colOverrides);
50650
+ }
50651
+ function createColumnWidths(sheet, options2 = {}) {
50652
+ const zoom = zoomPercent(options2.zoom ?? sheet.view.zoom);
50653
+ const cols = columnAxis(sheet, options2.mdw ?? DEFAULT_MAX_DIGIT_WIDTH, pixelScale(zoom));
50654
+ return (c2) => cols.size(c2);
50655
+ }
50656
+ function createGridMetrics(sheet, options2 = {}) {
50657
+ const zoom = zoomPercent(options2.zoom ?? sheet.view.zoom);
50658
+ const mdw = options2.mdw ?? DEFAULT_MAX_DIGIT_WIDTH;
50659
+ const scale2 = pixelScale(zoom);
50660
+ const cols = columnAxis(sheet, mdw, scale2);
50544
50661
  const defaultRowPx = pointsToPixels(sheet.defaultRowHeight);
50545
50662
  const rowOverrides = [];
50546
50663
  for (const [r, info] of sheet.rowInfo) {
@@ -52413,12 +52530,13 @@ function span2(from, to) {
52413
52530
  }
52414
52531
  function outlineRows(ctx, s, from, to, delta) {
52415
52532
  const sheet = sheetAt(ctx.workbook, s);
52533
+ const rows = span2(from, to);
52416
52534
  ctx.run(
52417
52535
  delta > 0 ? "Group rows" : "Ungroup rows",
52418
52536
  "structure",
52419
- [{ kind: "sheet", sheet: s }],
52537
+ [{ kind: "rowInfo", sheet: s, rows }],
52420
52538
  () => {
52421
- for (const row3 of span2(from, to)) {
52539
+ for (const row3 of rows) {
52422
52540
  const info = { ...sheet.rowInfo.get(row3) };
52423
52541
  const level2 = nextLevel(info.outlineLevel, delta);
52424
52542
  if (level2) info.outlineLevel = level2;
@@ -52438,7 +52556,7 @@ function outlineColumns(ctx, s, from, to, delta) {
52438
52556
  ctx.run(
52439
52557
  delta > 0 ? "Group columns" : "Ungroup columns",
52440
52558
  "structure",
52441
- [{ kind: "sheet", sheet: s }],
52559
+ [{ kind: "parts", sheet: s, parts: ["columns"] }],
52442
52560
  () => editColumns(sheet, span2(from, to), (info) => {
52443
52561
  const level2 = nextLevel(info.outlineLevel, delta);
52444
52562
  if (level2) info.outlineLevel = level2;
@@ -52461,7 +52579,7 @@ function setDefaultColumnWidth(ctx, s, width) {
52461
52579
  ctx.run(
52462
52580
  "Standard width",
52463
52581
  "format",
52464
- [{ kind: "sheet", sheet: s }],
52582
+ [{ kind: "parts", sheet: s, parts: ["defaultColWidth"] }],
52465
52583
  () => {
52466
52584
  if (width === void 0) Reflect.deleteProperty(sheet, "defaultColWidth");
52467
52585
  else sheet.defaultColWidth = width;
@@ -54840,6 +54958,87 @@ function cellView(workbook, sheetIndex2, row3, col, cf, options2 = {}) {
54840
54958
  return view;
54841
54959
  }
54842
54960
 
54961
+ // xlsx/layout/merge-sweep.ts
54962
+ var NONE = { merged: false, spanned: false };
54963
+ var SINGLE3 = { merged: true, spanned: false };
54964
+ var SPANNED = { merged: true, spanned: true };
54965
+ var spans2 = (merge2) => merge2.start.row !== merge2.end.row || merge2.start.col !== merge2.end.col;
54966
+ function firstRightOf(merges, col) {
54967
+ let lo = 0;
54968
+ let hi = merges.length;
54969
+ while (lo < hi) {
54970
+ const mid = lo + hi >> 1;
54971
+ if ((merges[mid]?.start.col ?? 0) <= col) lo = mid + 1;
54972
+ else hi = mid;
54973
+ }
54974
+ return lo;
54975
+ }
54976
+ var MergeSweep = class {
54977
+ /** The merges by first row; `next` is the first one the sweep has not reached. */
54978
+ byRow;
54979
+ next = 0;
54980
+ row = Number.NEGATIVE_INFINITY;
54981
+ /** The merges covering the current row, by first column. */
54982
+ active = [];
54983
+ /** The last row of the earliest-ending active merge. */
54984
+ firstEnd = Number.POSITIVE_INFINITY;
54985
+ overlapping = false;
54986
+ constructor(merges) {
54987
+ this.byRow = [...merges].sort((a2, b) => a2.start.row - b.start.row);
54988
+ }
54989
+ /** How many merges cover the current row, which is everything the sweep holds. */
54990
+ get size() {
54991
+ return this.active.length;
54992
+ }
54993
+ /** Moves to `row`, which must not be above the previous one. */
54994
+ moveTo(row3) {
54995
+ if (row3 < this.row) throw new RangeError(`Rows must not go up: ${row3} after ${this.row}`);
54996
+ this.row = row3;
54997
+ if (row3 > this.firstEnd) this.dropEnded(row3);
54998
+ for (; this.next < this.byRow.length; this.next++) {
54999
+ const merge2 = this.byRow[this.next];
55000
+ if (!merge2 || merge2.start.row > row3) break;
55001
+ if (merge2.end.row >= row3) this.add(merge2);
55002
+ }
55003
+ }
55004
+ /** How the merges cover column `col` of the current row. */
55005
+ at(col) {
55006
+ if (this.overlapping) {
55007
+ let merged = false;
55008
+ for (const merge3 of this.active) {
55009
+ if (col < merge3.start.col || col > merge3.end.col) continue;
55010
+ if (spans2(merge3)) return SPANNED;
55011
+ merged = true;
55012
+ }
55013
+ return merged ? SINGLE3 : NONE;
55014
+ }
55015
+ const merge2 = this.active[firstRightOf(this.active, col) - 1];
55016
+ if (!merge2 || col > merge2.end.col) return NONE;
55017
+ return spans2(merge2) ? SPANNED : SINGLE3;
55018
+ }
55019
+ add(merge2) {
55020
+ const at2 = firstRightOf(this.active, merge2.start.col);
55021
+ const before = this.active[at2 - 1];
55022
+ const after = this.active[at2];
55023
+ if (before && before.end.col >= merge2.start.col || after && merge2.end.col >= after.start.col)
55024
+ this.overlapping = true;
55025
+ this.active.splice(at2, 0, merge2);
55026
+ this.firstEnd = Math.min(this.firstEnd, merge2.end.row);
55027
+ }
55028
+ dropEnded(row3) {
55029
+ let kept = 0;
55030
+ let firstEnd = Number.POSITIVE_INFINITY;
55031
+ for (const merge2 of this.active) {
55032
+ if (merge2.end.row < row3) continue;
55033
+ this.active[kept++] = merge2;
55034
+ firstEnd = Math.min(firstEnd, merge2.end.row);
55035
+ }
55036
+ this.active.length = kept;
55037
+ this.firstEnd = firstEnd;
55038
+ if (!kept) this.overlapping = false;
55039
+ }
55040
+ };
55041
+
54843
55042
  // xlsx/layout/row-autofit.ts
54844
55043
  var LINE_HEIGHTS = [
54845
55044
  [6, 8.25],
@@ -54899,30 +55098,39 @@ function wrappedLineCount(text8, width, measure2) {
54899
55098
  }
54900
55099
  return lines2;
54901
55100
  }
54902
- function autoFitRowHeight(workbook, sheetIndex2, row3, measure2) {
55101
+ function fitRowHeights(workbook, sheetIndex2, rows, measure2) {
55102
+ const heights = /* @__PURE__ */ new Map();
54903
55103
  const sheet = workbook.sheets[sheetIndex2];
54904
- if (!sheet) return 15;
54905
- const cells3 = sheet.rows.get(row3);
54906
- if (!cells3?.size) return sheet.defaultRowHeight;
54907
- const metrics = createGridMetrics(sheet, { zoom: 100 });
54908
- let tallest = 0;
54909
- for (const col of cells3.keys()) {
54910
- const merged = sheet.merges.some(
54911
- (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)
54912
- );
54913
- if (merged) continue;
54914
- const view = cellView(workbook, sheetIndex2, row3, col);
54915
- if (!view.text) continue;
54916
- const fonts = view.rich?.length ? view.rich.map((run2) => run2.font) : [view.font];
54917
- const sizePt = Math.max(...fonts.map((f6) => f6.sizePx * 3 / 4));
54918
- let lines2 = 1;
54919
- if (view.wrap) {
54920
- const width = metrics.colWidth(col) - COLUMN_PADDING_PX - 1 - view.indentPx;
54921
- lines2 = wrappedLineCount(view.text, width, (text8) => measure2(text8, view.font));
55104
+ if (!sheet) return heights;
55105
+ const filled = [];
55106
+ for (const row3 of new Set(rows)) {
55107
+ if (sheet.rows.get(row3)?.size) filled.push(row3);
55108
+ else heights.set(row3, sheet.defaultRowHeight);
55109
+ }
55110
+ filled.sort((a2, b) => a2 - b);
55111
+ const merges = new MergeSweep(sheet.merges);
55112
+ let colWidth;
55113
+ for (const row3 of filled) {
55114
+ merges.moveTo(row3);
55115
+ let tallest = 0;
55116
+ for (const col of sheet.rows.get(row3)?.keys() ?? []) {
55117
+ const cover = merges.at(col);
55118
+ if (cover.spanned) continue;
55119
+ const view = cellView(workbook, sheetIndex2, row3, col, void 0, { merged: cover.merged });
55120
+ if (!view.text) continue;
55121
+ const fonts = view.rich?.length ? view.rich.map((run2) => run2.font) : [view.font];
55122
+ const sizePt = Math.max(...fonts.map((f6) => f6.sizePx * 3 / 4));
55123
+ let lines2 = 1;
55124
+ if (view.wrap) {
55125
+ colWidth ??= createColumnWidths(sheet, { zoom: 100 });
55126
+ const width = colWidth(col) - COLUMN_PADDING_PX - 1 - view.indentPx;
55127
+ lines2 = wrappedLineCount(view.text, width, (text8) => measure2(text8, view.font));
55128
+ }
55129
+ tallest = Math.max(tallest, lines2 * lineHeightPoints(sizePt));
54922
55130
  }
54923
- tallest = Math.max(tallest, lines2 * lineHeightPoints(sizePt));
55131
+ heights.set(row3, tallest > 0 ? tallest : sheet.defaultRowHeight);
54924
55132
  }
54925
- return tallest > 0 ? tallest : sheet.defaultRowHeight;
55133
+ return heights;
54926
55134
  }
54927
55135
  var approximateMeasure = (text8, font) => text8.length * font.sizePx * (font.bold ? 0.58 : 0.53);
54928
55136
 
@@ -54930,22 +55138,26 @@ var approximateMeasure = (text8, font) => text8.length * font.sizePx * (font.bol
54930
55138
  var MAX_HEIGHT2 = 409;
54931
55139
  function autoGrowRows(ctx, s, rows, measure2 = approximateMeasure) {
54932
55140
  const sheet = sheetAt(ctx.workbook, s);
54933
- const updates = [];
54934
- for (const row3 of new Set(rows)) {
55141
+ const candidates = [...new Set(rows)].filter((row3) => {
54935
55142
  const info = sheet.rowInfo.get(row3);
54936
- if (info?.customHeight || info?.hidden) continue;
54937
- const fit3 = Math.min(MAX_HEIGHT2, autoFitRowHeight(ctx.workbook, s, row3, measure2));
55143
+ return !info?.customHeight && !info?.hidden;
55144
+ });
55145
+ const fits = fitRowHeights(ctx.workbook, s, candidates, measure2);
55146
+ const updates = [];
55147
+ for (const row3 of candidates) {
55148
+ const fit3 = Math.min(MAX_HEIGHT2, fits.get(row3) ?? sheet.defaultRowHeight);
54938
55149
  const next = Math.abs(fit3 - sheet.defaultRowHeight) < 1e-9 ? void 0 : fit3;
54939
- const current = info?.height;
55150
+ const current = sheet.rowInfo.get(row3)?.height;
54940
55151
  if (current === next) continue;
54941
55152
  if (current !== void 0 && next !== void 0 && Math.abs(current - next) < 1e-9) continue;
54942
55153
  updates.push([row3, next]);
54943
55154
  }
54944
55155
  if (!updates.length) return [];
55156
+ const changed = updates.map(([row3]) => row3);
54945
55157
  ctx.run(
54946
55158
  "Row height",
54947
55159
  "view",
54948
- [{ kind: "sheet", sheet: s }],
55160
+ [{ kind: "rowInfo", sheet: s, rows: changed }],
54949
55161
  () => {
54950
55162
  for (const [row3, height] of updates) {
54951
55163
  const info = { ...sheet.rowInfo.get(row3) };
@@ -54957,7 +55169,7 @@ function autoGrowRows(ctx, s, rows, measure2 = approximateMeasure) {
54957
55169
  },
54958
55170
  { sheet: s, structural: true }
54959
55171
  );
54960
- return updates.map(([row3]) => row3);
55172
+ return changed;
54961
55173
  }
54962
55174
  var MAX_REFIT_ROWS = 1e4;
54963
55175
  function rowsToRefit(sheet, ranges) {
@@ -55713,11 +55925,84 @@ function createEditSession(workbook, options2 = {}) {
55713
55925
  };
55714
55926
  }
55715
55927
 
55928
+ // automation/xlsx-read.ts
55929
+ var INSPECT_LIST_LIMIT = 500;
55930
+ function sheetSummaries(workbook) {
55931
+ return workbook.sheets.map((sheet, index3) => {
55932
+ const used = usedRange(sheet);
55933
+ const omitted2 = sheet.tables.length - INSPECT_LIST_LIMIT;
55934
+ return {
55935
+ index: index3,
55936
+ name: sheet.name,
55937
+ state: sheet.state,
55938
+ usedRange: used ? formatRange(used) : null,
55939
+ rows: used ? used.end.row - used.start.row + 1 : 0,
55940
+ columns: used ? used.end.col - used.start.col + 1 : 0,
55941
+ tables: sheet.tables.slice(0, INSPECT_LIST_LIMIT).map((table4) => ({
55942
+ name: table4.displayName,
55943
+ range: formatRange(table4.range),
55944
+ headerRow: table4.headerRow,
55945
+ totalsRow: table4.totalsRow
55946
+ })),
55947
+ ...omitted2 > 0 ? { tablesOmitted: omitted2 } : {}
55948
+ };
55949
+ });
55950
+ }
55951
+ function definedNameList(workbook) {
55952
+ const visible = workbook.definedNames.filter((name3) => !name3.hidden);
55953
+ const definedNames = visible.slice(0, INSPECT_LIST_LIMIT).map((name3) => ({
55954
+ name: name3.name,
55955
+ refersTo: name3.formula,
55956
+ ...name3.localSheet === void 0 ? {} : { sheetIndex: name3.localSheet }
55957
+ }));
55958
+ const omitted2 = visible.length - INSPECT_LIST_LIMIT;
55959
+ return omitted2 > 0 ? { definedNames, definedNamesOmitted: omitted2 } : { definedNames };
55960
+ }
55961
+ function isoOf(serial, date1904, shows2) {
55962
+ if (!(serial >= 0) || serial > MAX_DATE_SERIAL + 1) return void 0;
55963
+ if (!date1904 && serial >= 60 && serial < 61) return void 0;
55964
+ const date2 = serialToDate(serial, date1904);
55965
+ if (date2.getUTCFullYear() > 9999) return void 0;
55966
+ const iso = date2.toISOString();
55967
+ const time = iso.slice(11, iso.endsWith(".000Z") ? 19 : 23);
55968
+ if (serial < 1 && (!date1904 || !shows2.date)) return time;
55969
+ return Number.isInteger(serial) && !shows2.time ? iso.slice(0, 10) : `${iso.slice(0, 10)}T${time}`;
55970
+ }
55971
+ function cellView2(workbook, cell) {
55972
+ const value3 = cell?.value ?? null;
55973
+ const text8 = displayText(workbook, cell);
55974
+ const view = cell?.formula ? { value: value3, formula: cell.formula, text: text8 } : { value: value3, text: text8 };
55975
+ const numFmt = styleAt(workbook, cell?.styleId).numFmt;
55976
+ if (numFmt === "General") return view;
55977
+ view.numberFormat = numFmt;
55978
+ const parts = typeof value3 === "number" ? dateTimeParts(numFmt, value3) : void 0;
55979
+ if (parts && typeof value3 === "number") {
55980
+ const iso = isoOf(value3, workbook.date1904, parts);
55981
+ if (iso) view.iso = iso;
55982
+ }
55983
+ return view;
55984
+ }
55985
+ var READ_LIMIT = 1e4;
55986
+ function rangeCells(workbook, sheet, range2) {
55987
+ const count2 = (range2.end.row - range2.start.row + 1) * (range2.end.col - range2.start.col + 1);
55988
+ if (count2 > READ_LIMIT) throw new Error(`Read at most ${READ_LIMIT} cells per request`);
55989
+ const cells3 = [];
55990
+ for (let row3 = range2.start.row; row3 <= range2.end.row; row3++)
55991
+ for (let col = range2.start.col; col <= range2.end.col; col++)
55992
+ cells3.push({
55993
+ address: formatAddress({ row: row3, col }),
55994
+ ...cellView2(workbook, getCell(sheet, row3, col))
55995
+ });
55996
+ return cells3;
55997
+ }
55998
+
55716
55999
  // automation/xlsx.ts
55717
56000
  async function inspectXlsx(bytes) {
55718
56001
  const workbook = await loadXlsx(bytes);
55719
56002
  return {
55720
- sheets: workbook.sheets.map((sheet, index3) => ({ index: index3, name: sheet.name })),
56003
+ sheets: sheetSummaries(workbook),
56004
+ activeSheet: workbook.activeSheet,
56005
+ ...definedNameList(workbook),
55721
56006
  properties: workbook.properties,
55722
56007
  warnings: workbook.warnings
55723
56008
  };
@@ -55740,19 +56025,7 @@ async function readXlsxRange(bytes, sheetIndex2, reference2) {
55740
56025
  const range2 = parseRange(reference2);
55741
56026
  if (!sheet || !range2 || range2.end.col > MAX_COL || range2.end.row > MAX_ROW)
55742
56027
  throw new Error("Invalid sheet or range");
55743
- const count2 = (range2.end.row - range2.start.row + 1) * (range2.end.col - range2.start.col + 1);
55744
- if (count2 > 1e4) throw new Error("Read at most 10000 cells per request");
55745
- const cells3 = [];
55746
- for (let row3 = range2.start.row; row3 <= range2.end.row; row3++)
55747
- for (let col = range2.start.col; col <= range2.end.col; col++) {
55748
- const cell = getCell(sheet, row3, col);
55749
- cells3.push({
55750
- address: formatAddress({ row: row3, col }),
55751
- value: cell?.value ?? null,
55752
- formula: cell?.formula
55753
- });
55754
- }
55755
- return { cells: cells3, warnings: workbook.warnings };
56028
+ return { cells: rangeCells(workbook, sheet, range2), warnings: workbook.warnings };
55756
56029
  }
55757
56030
  async function setXlsxCells(bytes, sheetIndex2, cells3) {
55758
56031
  const workbook = await loadXlsx(bytes);
@@ -55795,6 +56068,65 @@ async function readXlsxFilledCells(bytes, { maxCells = 5e3 } = {}) {
55795
56068
  warnings: workbook.warnings
55796
56069
  };
55797
56070
  }
56071
+ async function findXlsxCells(bytes, text8, options2 = {}) {
56072
+ if (!text8) throw new Error("The search text is empty");
56073
+ const max = options2.maxResults ?? 100;
56074
+ if (!Number.isSafeInteger(max) || max < 1 || max > 1e3)
56075
+ throw new Error("Return between 1 and 1000 matches per request");
56076
+ const workbook = await loadXlsx(bytes);
56077
+ const query = { text: text8, lookIn: options2.lookIn ?? "formulas" };
56078
+ const { sheetIndex: sheetIndex2 } = options2;
56079
+ if (sheetIndex2 !== void 0) {
56080
+ if (!Number.isSafeInteger(sheetIndex2) || !workbook.sheets[sheetIndex2])
56081
+ throw new Error("Invalid sheet");
56082
+ query.sheet = sheetIndex2;
56083
+ }
56084
+ if (options2.range !== void 0) {
56085
+ const range2 = parseRange(options2.range);
56086
+ if (sheetIndex2 === void 0) throw new Error("A range needs a sheetIndex");
56087
+ if (!range2) throw new Error("Invalid range");
56088
+ query.range = range2;
56089
+ }
56090
+ if (options2.matchCase) query.matchCase = true;
56091
+ if (options2.wholeCell) query.wholeCell = true;
56092
+ if (options2.wildcards === false) query.wildcards = false;
56093
+ const found = findAll(workbook, query);
56094
+ const matches2 = found.slice(0, max).map((match2) => {
56095
+ const sheet = workbook.sheets[match2.sheet];
56096
+ return {
56097
+ sheetIndex: match2.sheet,
56098
+ sheet: sheet?.name ?? "",
56099
+ address: formatAddress(match2),
56100
+ ...cellView2(workbook, sheet && getCell(sheet, match2.row, match2.col))
56101
+ };
56102
+ });
56103
+ return {
56104
+ matches: matches2,
56105
+ total: found.length,
56106
+ truncated: found.length > max,
56107
+ warnings: workbook.warnings
56108
+ };
56109
+ }
56110
+ async function readXlsxTable(bytes, name3) {
56111
+ const workbook = await loadXlsx(bytes);
56112
+ const wanted = name3.toLowerCase();
56113
+ for (const [sheetIndex2, sheet] of workbook.sheets.entries()) {
56114
+ const table4 = sheet.tables.find((t) => t.displayName.toLowerCase() === wanted);
56115
+ if (!table4) continue;
56116
+ return {
56117
+ sheetIndex: sheetIndex2,
56118
+ sheet: sheet.name,
56119
+ name: table4.displayName,
56120
+ range: formatRange(table4.range),
56121
+ headerRow: table4.headerRow,
56122
+ totalsRow: table4.totalsRow,
56123
+ columns: table4.columns.map((column2) => column2.name),
56124
+ cells: rangeCells(workbook, sheet, table4.range),
56125
+ warnings: workbook.warnings
56126
+ };
56127
+ }
56128
+ throw new Error(`No table named ${name3}`);
56129
+ }
55798
56130
 
55799
56131
  // visio/package-common.ts
55800
56132
  var VisioPackageError = class extends Error {
@@ -55878,7 +56210,7 @@ function inspectZip(bytes, limits, check3) {
55878
56210
  if (count2 > limits.maxEntries) fail2("LIMIT_ENTRIES", "Too many ZIP entries");
55879
56211
  if (centralStart + centralSize !== end) fail2("INVALID_ZIP", "Invalid central directory bounds");
55880
56212
  const entries = /* @__PURE__ */ new Map(), canonical2 = /* @__PURE__ */ new Set();
55881
- const spans2 = [];
56213
+ const spans3 = [];
55882
56214
  let offset2 = centralStart, total2 = 0;
55883
56215
  const extras = (start, length, name3) => {
55884
56216
  const stop = start + length;
@@ -55948,14 +56280,14 @@ function inspectZip(bytes, limits, check3) {
55948
56280
  dataEnd += 12;
55949
56281
  }
55950
56282
  if (dataEnd > centralStart) fail2("ZIP_MISMATCH", "ZIP entry overlaps the central directory");
55951
- spans2.push({ start: local, end: dataEnd });
56283
+ spans3.push({ start: local, end: dataEnd });
55952
56284
  entries.set(name3, { name: name3, compressed, size: size3, crc, directory });
55953
56285
  offset2 += 46 + nameLength + extraLength + commentLength;
55954
56286
  }
55955
56287
  if (offset2 !== end) fail2("INVALID_ZIP", "Central directory length or count mismatch");
55956
- spans2.sort((a2, b) => a2.start - b.start);
56288
+ spans3.sort((a2, b) => a2.start - b.start);
55957
56289
  let previousEnd = 0;
55958
- for (const span3 of spans2) {
56290
+ for (const span3 of spans3) {
55959
56291
  if (span3.start !== previousEnd)
55960
56292
  fail2("ZIP_MISMATCH", "Overlapping, prefixed, or unindexed ZIP records");
55961
56293
  previousEnd = span3.end;
@@ -68685,13 +69017,13 @@ function flattenCornerCurve(points) {
68685
69017
  return flattened ? [points[0], ...flattened] : void 0;
68686
69018
  }
68687
69019
  function connectorCurveMiddle(points) {
68688
- const spans2 = connectorCurveSpans(points);
69020
+ const spans3 = connectorCurveSpans(points);
68689
69021
  if (points.length === 5) {
68690
69022
  const flattened = flattenCornerCurve(points);
68691
69023
  if (flattened) return connectorPolylineMiddle(flattened);
68692
69024
  return mix(points[0], points.at(-1), 0.5);
68693
69025
  }
68694
- const row3 = [...spans2[0]];
69026
+ const row3 = [...spans3[0]];
68695
69027
  for (let count2 = row3.length - 1; count2 > 0; count2--)
68696
69028
  for (let i2 = 0; i2 < count2; i2++) row3[i2] = mix(row3[i2], row3[i2 + 1], 0.5);
68697
69029
  return row3[0];
@@ -79747,7 +80079,7 @@ function assertParentIndependent(facts, from, ids) {
79747
80079
 
79748
80080
  // visio/edit-group.ts
79749
80081
  var clean5 = (value3) => Math.abs(value3) < 1e-12 ? 0 : value3;
79750
- var NONE = /* @__PURE__ */ new Map();
80082
+ var NONE2 = /* @__PURE__ */ new Map();
79751
80083
  function topLevel2(root) {
79752
80084
  const containers = children3(root, "Shapes");
79753
80085
  if (containers.length !== 1)
@@ -79762,7 +80094,7 @@ function assertGroupable(shape2, document) {
79762
80094
  assertShapeLocks(shape2, document, ["LockGroup"]);
79763
80095
  assertUnlayeredShape(shape2, document);
79764
80096
  }
79765
- var transformOf = (shape2, instances = NONE) => {
80097
+ var transformOf = (shape2, instances = NONE2) => {
79766
80098
  const local = cells(instances.get(shape2)?.view ?? shape2);
79767
80099
  const width = numeric4(local.get("Width")), height = numeric4(local.get("Height"));
79768
80100
  return {
@@ -79784,7 +80116,7 @@ var transformOf = (shape2, instances = NONE) => {
79784
80116
  )
79785
80117
  };
79786
80118
  };
79787
- function visioShapeBounds(shapes, instances = NONE) {
80119
+ function visioShapeBounds(shapes, instances = NONE2) {
79788
80120
  let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
79789
80121
  for (const shape2 of shapes) {
79790
80122
  const box5 = transformOf(shape2, instances);
@@ -79804,7 +80136,7 @@ function visioShapeBounds(shapes, instances = NONE) {
79804
80136
  }
79805
80137
  return { minX, minY, maxX, maxY };
79806
80138
  }
79807
- function groupVisioShapes(root, document, edit, check3, instances = NONE) {
80139
+ function groupVisioShapes(root, document, edit, check3, instances = NONE2) {
79808
80140
  check3();
79809
80141
  const siblings = topLevel2(root);
79810
80142
  for (const node3 of Array.from(root.getElementsByTagName("*")))
@@ -79877,7 +80209,7 @@ function groupVisioShapes(root, document, edit, check3, instances = NONE) {
79877
80209
  }
79878
80210
  return true;
79879
80211
  }
79880
- function ungroupVisioShape(root, document, edit, check3, instances = NONE) {
80212
+ function ungroupVisioShape(root, document, edit, check3, instances = NONE2) {
79881
80213
  check3();
79882
80214
  const candidates = topLevel2(root).filter((shape2) => attribute3(shape2, "ID") === edit.shapeId);
79883
80215
  if (candidates.length !== 1 || attribute3(candidates[0], "Type") !== "Group")
@@ -82383,4 +82715,4 @@ async function createXlsxFromSheets(sheets) {
82383
82715
  return saveXlsx(workbook);
82384
82716
  }
82385
82717
 
82386
- export { createDocx, createDocxFromOutline, createXlsx, createXlsxFromSheets, editVsdx as editVisio, inspectDocx, inspectVisio, inspectXlsx, readXlsxFilledCells, readXlsxRange, setDocxRunText, setXlsxCells, suggestDocxRunText };
82718
+ export { createDocx, createDocxFromOutline, createXlsx, createXlsxFromSheets, editVsdx as editVisio, findXlsxCells, inspectDocx, inspectVisio, inspectXlsx, readXlsxFilledCells, readXlsxRange, readXlsxTable, setDocxRunText, setXlsxCells, suggestDocxRunText };