ooxml-core 1.14.0 → 1.16.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 (143) hide show
  1. package/dist/PptxHandler-3A7VEXVK.cjs +13 -0
  2. package/dist/PptxHandler-7POULDRL.mjs +4 -0
  3. package/dist/{PptxHandler-KNBFECUE.mjs → PptxHandler-M35YFCUC.mjs} +2 -2
  4. package/dist/PresentationBuilder-C7NPM7OQ.mjs +4 -0
  5. package/dist/{PresentationBuilder-II7C4A3R.cjs → PresentationBuilder-XVRTITYR.cjs} +6 -5
  6. package/dist/{PresentationBuilder-5DCCFHWJ.mjs → PresentationBuilder-Y6DJK6H2.mjs} +2 -2
  7. package/dist/automation/index.cjs +1198 -1095
  8. package/dist/automation/index.mjs +1198 -1095
  9. package/dist/chunk-5W2QL4SB.cjs +244 -0
  10. package/dist/{chunk-TQE7FFNT.cjs → chunk-AHRFBMLK.cjs} +4070 -2015
  11. package/dist/{chunk-2D4IFQ5M.mjs → chunk-B37EVUMG.mjs} +1 -1
  12. package/dist/{chunk-4WZLFUUA.mjs → chunk-C2Y6SZDN.mjs} +934 -200
  13. package/dist/chunk-CA7KCNL3.mjs +236 -0
  14. package/dist/{chunk-BSUIDT6K.cjs → chunk-DWRJ62KP.cjs} +1 -0
  15. package/dist/{chunk-TNNXOW2O.mjs → chunk-KOX5Y5E5.mjs} +1 -1
  16. package/dist/{chunk-54ASP65T.mjs → chunk-LM6VBPQJ.mjs} +416 -15
  17. package/dist/{chunk-PC4MTLG4.cjs → chunk-OA5V3JJC.cjs} +8 -8
  18. package/dist/{chunk-ORH32TO3.mjs → chunk-OKGQ2X7D.mjs} +3092 -1037
  19. package/dist/{chunk-X7MGZQ6C.cjs → chunk-UGWY72WC.cjs} +396 -254
  20. package/dist/{chunk-XGXIS4PN.mjs → chunk-WBCV52YV.mjs} +3077 -1027
  21. package/dist/{chunk-2EBMHIGJ.mjs → chunk-WEFFRYXN.mjs} +379 -242
  22. package/dist/{chunk-AXF2FC4D.mjs → chunk-WSRCLCMB.mjs} +1 -0
  23. package/dist/{chunk-LMMP67YN.mjs → chunk-XCJRUBGJ.mjs} +1 -1
  24. package/dist/geometry/index.cjs +259 -0
  25. package/dist/geometry/index.d.ts +1 -0
  26. package/dist/geometry/index.d.ts.map +1 -1
  27. package/dist/geometry/index.mjs +255 -1
  28. package/dist/geometry/shape-gallery-catalog.d.ts +32 -0
  29. package/dist/geometry/shape-gallery-catalog.d.ts.map +1 -0
  30. package/dist/index.cjs +371 -112
  31. package/dist/index.mjs +371 -112
  32. package/dist/pptx/automation/index.cjs +4523 -1957
  33. package/dist/pptx/automation/index.d.ts +4 -4
  34. package/dist/pptx/automation/index.mjs +5 -5
  35. package/dist/pptx/chunks/{elements-tK7xnWeS.d.ts → elements-iUzpAeqR.d.ts} +232 -2
  36. package/dist/pptx/chunks/elements-iUzpAeqR.d.ts.map +1 -0
  37. package/dist/pptx/chunks/{index-DS9Y4Ne3.d.ts → index-BWHNCVNC.d.ts} +1673 -1534
  38. package/dist/pptx/chunks/index-BWHNCVNC.d.ts.map +1 -0
  39. package/dist/pptx/chunks/{index-BSpNQuvz.d.ts → index-CiyTR6mm.d.ts} +201 -5
  40. package/dist/pptx/chunks/index-CiyTR6mm.d.ts.map +1 -0
  41. package/dist/pptx/chunks/{text-operations-BdD_UQ11.d.ts → text-operations-CfLVZ7DK.d.ts} +81 -3
  42. package/dist/pptx/chunks/text-operations-CfLVZ7DK.d.ts.map +1 -0
  43. package/dist/pptx/cli/index.cjs +4465 -1899
  44. package/dist/pptx/cli/index.d.ts +1 -1
  45. package/dist/pptx/cli/index.mjs +4 -4
  46. package/dist/pptx/converter/index.cjs +52 -1
  47. package/dist/pptx/converter/index.d.ts +1 -1
  48. package/dist/pptx/converter/index.mjs +2 -2
  49. package/dist/pptx/editor/render/collaboration-live-patch-target.cjs +4 -4
  50. package/dist/pptx/editor/render/collaboration-live-patch-target.mjs +2 -2
  51. package/dist/pptx/editor/render/collaboration-reconcile.cjs +7 -7
  52. package/dist/pptx/editor/render/collaboration-reconcile.mjs +2 -2
  53. package/dist/pptx/editor/render/collaboration-sync.cjs +14 -14
  54. package/dist/pptx/editor/render/collaboration-sync.d.ts.map +1 -1
  55. package/dist/pptx/editor/render/collaboration-sync.mjs +1 -1
  56. package/dist/pptx/editor/render/find-replace.cjs +15 -14
  57. package/dist/pptx/editor/render/find-replace.d.ts +2 -2
  58. package/dist/pptx/editor/render/find-replace.mjs +2 -1
  59. package/dist/pptx/editor/render/slide-operations.cjs +9 -8
  60. package/dist/pptx/editor/render/slide-operations.mjs +3 -2
  61. package/dist/pptx/editor/render/slide-size-rescale.cjs +3 -3
  62. package/dist/pptx/editor/render/slide-size-rescale.d.ts +1 -1
  63. package/dist/pptx/editor/render/slide-size-rescale.d.ts.map +1 -1
  64. package/dist/pptx/editor/render/slide-size-rescale.mjs +3 -3
  65. package/dist/pptx/editor/render/text-runs-style-patch.d.ts +1 -1
  66. package/dist/pptx/editor/render/text-style-scope.d.ts +1 -1
  67. package/dist/pptx/index.cjs +5656 -2290
  68. package/dist/pptx/index.d.ts +5 -5
  69. package/dist/pptx/index.mjs +5 -5
  70. package/dist/teams/ics.d.ts.map +1 -1
  71. package/dist/teams/index.cjs +631 -635
  72. package/dist/teams/index.d.ts +1 -0
  73. package/dist/teams/index.d.ts.map +1 -1
  74. package/dist/teams/index.mjs +616 -636
  75. package/dist/teams/meetings.d.ts +11 -1
  76. package/dist/teams/meetings.d.ts.map +1 -1
  77. package/dist/teams/recurrence-calendar.d.ts +41 -0
  78. package/dist/teams/recurrence-calendar.d.ts.map +1 -0
  79. package/dist/teams/recurrence.d.ts +1 -1
  80. package/dist/teams/recurrence.d.ts.map +1 -1
  81. package/dist/teams/server-session.d.ts +19 -0
  82. package/dist/teams/server-session.d.ts.map +1 -1
  83. package/dist/xlsx/edit/pivots.d.ts.map +1 -1
  84. package/dist/xlsx/index.cjs +1137 -1027
  85. package/dist/xlsx/index.mjs +1136 -1028
  86. package/dist/xlsx/load/index.cjs +593 -652
  87. package/dist/xlsx/load/index.mjs +593 -652
  88. package/dist/xlsx/model-pivots.d.ts +64 -4
  89. package/dist/xlsx/model-pivots.d.ts.map +1 -1
  90. package/dist/xlsx/pivot/aggregate.d.ts +6 -3
  91. package/dist/xlsx/pivot/aggregate.d.ts.map +1 -1
  92. package/dist/xlsx/pivot/axes.d.ts +5 -0
  93. package/dist/xlsx/pivot/axes.d.ts.map +1 -1
  94. package/dist/xlsx/pivot/captions-locales.d.ts +3 -0
  95. package/dist/xlsx/pivot/captions-locales.d.ts.map +1 -0
  96. package/dist/xlsx/pivot/captions-read.d.ts +14 -0
  97. package/dist/xlsx/pivot/captions-read.d.ts.map +1 -0
  98. package/dist/xlsx/pivot/captions.d.ts +26 -0
  99. package/dist/xlsx/pivot/captions.d.ts.map +1 -0
  100. package/dist/xlsx/pivot/columns.d.ts +9 -3
  101. package/dist/xlsx/pivot/columns.d.ts.map +1 -1
  102. package/dist/xlsx/pivot/data.d.ts +3 -2
  103. package/dist/xlsx/pivot/data.d.ts.map +1 -1
  104. package/dist/xlsx/pivot/date-axes.d.ts +1 -1
  105. package/dist/xlsx/pivot/date-axes.d.ts.map +1 -1
  106. package/dist/xlsx/pivot/date-group-read.d.ts.map +1 -1
  107. package/dist/xlsx/pivot/date-groups.d.ts +8 -3
  108. package/dist/xlsx/pivot/date-groups.d.ts.map +1 -1
  109. package/dist/xlsx/pivot/index.d.ts +2 -1
  110. package/dist/xlsx/pivot/index.d.ts.map +1 -1
  111. package/dist/xlsx/pivot/item-labels.d.ts +12 -0
  112. package/dist/xlsx/pivot/item-labels.d.ts.map +1 -0
  113. package/dist/xlsx/pivot/item-names-read.d.ts +8 -0
  114. package/dist/xlsx/pivot/item-names-read.d.ts.map +1 -0
  115. package/dist/xlsx/pivot/measures.d.ts +2 -8
  116. package/dist/xlsx/pivot/measures.d.ts.map +1 -1
  117. package/dist/xlsx/pivot/nested.d.ts +4 -2
  118. package/dist/xlsx/pivot/nested.d.ts.map +1 -1
  119. package/dist/xlsx/pivot/page-filter-admission.d.ts.map +1 -1
  120. package/dist/xlsx/pivot/page-filter.d.ts +1 -1
  121. package/dist/xlsx/pivot/page-filter.d.ts.map +1 -1
  122. package/dist/xlsx/pivot/read.d.ts.map +1 -1
  123. package/dist/xlsx/pivot/subtotals.d.ts +6 -1
  124. package/dist/xlsx/pivot/subtotals.d.ts.map +1 -1
  125. package/dist/xlsx/pivot/table-xml.d.ts.map +1 -1
  126. package/dist/xlsx/pivot/values-axis.d.ts +7 -4
  127. package/dist/xlsx/pivot/values-axis.d.ts.map +1 -1
  128. package/dist/xlsx/ui/commands/i18n/navigation.d.ts.map +1 -1
  129. package/dist/xlsx/ui/commands/i18n/pivots.d.ts.map +1 -1
  130. package/dist/xlsx/ui/index.cjs +1002 -1136
  131. package/dist/xlsx/ui/index.mjs +1002 -1136
  132. package/package.json +1 -1
  133. package/dist/PptxHandler-5YP75BPO.cjs +0 -12
  134. package/dist/PptxHandler-GT5Q66TG.mjs +0 -3
  135. package/dist/PresentationBuilder-CVM6LJ7L.mjs +0 -3
  136. package/dist/pptx/chunks/elements-tK7xnWeS.d.ts.map +0 -1
  137. package/dist/pptx/chunks/index-BSpNQuvz.d.ts.map +0 -1
  138. package/dist/pptx/chunks/index-DS9Y4Ne3.d.ts.map +0 -1
  139. package/dist/pptx/chunks/text-operations-BdD_UQ11.d.ts.map +0 -1
  140. package/dist/xlsx/pivot/hierarchy-first.d.ts +0 -21
  141. package/dist/xlsx/pivot/hierarchy-first.d.ts.map +0 -1
  142. package/dist/xlsx/pivot/hierarchy.d.ts +0 -8
  143. package/dist/xlsx/pivot/hierarchy.d.ts.map +0 -1
@@ -34,19 +34,19 @@ var TIME_PERIODS = [
34
34
  var MAX_ROW = 1048575;
35
35
  var MAX_COL = 16383;
36
36
  function columnLabel(col) {
37
- let label5 = "";
37
+ let label2 = "";
38
38
  let n2 = col + 1;
39
39
  while (n2 > 0) {
40
40
  const rem = (n2 - 1) % 26;
41
- label5 = String.fromCharCode(65 + rem) + label5;
41
+ label2 = String.fromCharCode(65 + rem) + label2;
42
42
  n2 = Math.floor((n2 - 1) / 26);
43
43
  }
44
- return label5;
44
+ return label2;
45
45
  }
46
- function columnIndex(label5) {
47
- if (!/^[A-Za-z]{1,3}$/.test(label5)) return -1;
46
+ function columnIndex(label2) {
47
+ if (!/^[A-Za-z]{1,3}$/.test(label2)) return -1;
48
48
  let n2 = 0;
49
- for (const ch of label5.toUpperCase()) n2 = n2 * 26 + (ch.charCodeAt(0) - 64);
49
+ for (const ch of label2.toUpperCase()) n2 = n2 * 26 + (ch.charCodeAt(0) - 64);
50
50
  return n2 - 1;
51
51
  }
52
52
  var formatAddress = (address2) => `${columnLabel(address2.col)}${address2.row + 1}`;
@@ -3897,14 +3897,14 @@ function unique(args, ctx) {
3897
3897
  const byCol = args.length > 1 && args[1] !== null && toBool(ctx.toScalar(args[1] ?? null));
3898
3898
  const once = args.length > 2 && args[2] !== null && toBool(ctx.toScalar(args[2] ?? null));
3899
3899
  if (byCol) m = transpose(m);
3900
- const keyOf2 = (row2) => JSON.stringify(
3900
+ const keyOf3 = (row2) => JSON.stringify(
3901
3901
  row2.map(
3902
3902
  (v) => isError(v) ? `#${v.error}` : typeof v === "string" ? `s${v.toLowerCase()}` : v
3903
3903
  )
3904
3904
  );
3905
3905
  const counts = /* @__PURE__ */ new Map();
3906
3906
  for (const row2 of m.data) {
3907
- const key = keyOf2(row2);
3907
+ const key = keyOf3(row2);
3908
3908
  const entry3 = counts.get(key);
3909
3909
  if (entry3) entry3.count++;
3910
3910
  else counts.set(key, { row: row2, count: 1 });
@@ -4195,24 +4195,24 @@ function tableOf(ctx, value2) {
4195
4195
  if (!head || records.length === 0) fail(ERR.VALUE);
4196
4196
  return { headers: head.map((v) => label(v).toLowerCase()), records };
4197
4197
  }
4198
- function fieldIndex(table2, field) {
4198
+ function fieldIndex(table3, field) {
4199
4199
  const value2 = scalar(field);
4200
4200
  if (isError(value2)) fail(value2);
4201
4201
  if (typeof value2 === "number") {
4202
4202
  const index4 = Math.trunc(value2) - 1;
4203
- if (index4 < 0 || index4 >= table2.headers.length) fail(ERR.VALUE);
4203
+ if (index4 < 0 || index4 >= table3.headers.length) fail(ERR.VALUE);
4204
4204
  return index4;
4205
4205
  }
4206
- const index3 = table2.headers.indexOf(label(value2).toLowerCase());
4206
+ const index3 = table3.headers.indexOf(label(value2).toLowerCase());
4207
4207
  if (index3 < 0) fail(ERR.VALUE);
4208
4208
  return index3;
4209
4209
  }
4210
- function recordFilter(table2, criteria) {
4210
+ function recordFilter(table3, criteria) {
4211
4211
  const [head, ...rows] = criteria;
4212
4212
  if (!head || rows.length === 0) fail(ERR.VALUE);
4213
4213
  const columns = head.map((name) => {
4214
4214
  if (name === null || name === "") return -1;
4215
- return table2.headers.indexOf(label(name).toLowerCase());
4215
+ return table3.headers.indexOf(label(name).toLowerCase());
4216
4216
  });
4217
4217
  const alternatives = rows.map(
4218
4218
  (row2) => row2.flatMap((cell, c2) => {
@@ -4226,10 +4226,10 @@ function recordFilter(table2, criteria) {
4226
4226
  return (record) => alternatives.some((tests) => tests.every((test) => test(record)));
4227
4227
  }
4228
4228
  function selected(ctx, args) {
4229
- const table2 = tableOf(ctx, args[0]);
4230
- const column2 = fieldIndex(table2, args[1]);
4231
- const matches2 = recordFilter(table2, ctx.toMatrix(args[2] ?? null).data);
4232
- return table2.records.filter(matches2).map((record) => record[column2] ?? null);
4229
+ const table3 = tableOf(ctx, args[0]);
4230
+ const column2 = fieldIndex(table3, args[1]);
4231
+ const matches2 = recordFilter(table3, ctx.toMatrix(args[2] ?? null).data);
4232
+ return table3.records.filter(matches2).map((record) => record[column2] ?? null);
4233
4233
  }
4234
4234
  var numbers = (values2) => {
4235
4235
  for (const v of values2) if (isError(v)) fail(v);
@@ -6528,30 +6528,30 @@ function findTable(host, name, sheet, row2, col) {
6528
6528
  if (name) {
6529
6529
  const lower3 = name.toLowerCase();
6530
6530
  for (let s = 0; s < sheets.length; s++) {
6531
- const table3 = sheets[s]?.tables.find(
6531
+ const table4 = sheets[s]?.tables.find(
6532
6532
  (t) => t.displayName.toLowerCase() === lower3 || t.name.toLowerCase() === lower3
6533
6533
  );
6534
- if (table3) return { table: table3, sheet: s };
6534
+ if (table4) return { table: table4, sheet: s };
6535
6535
  }
6536
6536
  return void 0;
6537
6537
  }
6538
- const table2 = sheets[sheet]?.tables.find(
6538
+ const table3 = sheets[sheet]?.tables.find(
6539
6539
  (t) => row2 >= t.range.start.row && row2 <= t.range.end.row && col >= t.range.start.col && col <= t.range.end.col
6540
6540
  );
6541
- return table2 ? { table: table2, sheet } : void 0;
6541
+ return table3 ? { table: table3, sheet } : void 0;
6542
6542
  }
6543
6543
  function resolveStructured(ref, frame) {
6544
6544
  const found = findTable(frame.host, ref.table, frame.sheet, frame.row, frame.col);
6545
6545
  if (!found) return ref.table ? ERR.NAME : ERR.REF;
6546
- const { table: table2, sheet } = found;
6547
- const range = normalizeRange(table2.range);
6548
- const headerRow = table2.headerRow ? range.start.row : -1;
6549
- const dataStart = range.start.row + (table2.headerRow ? 1 : 0);
6550
- const dataEnd = range.end.row - (table2.totalsRow ? 1 : 0);
6551
- const totalsRow = table2.totalsRow ? range.end.row : -1;
6546
+ const { table: table3, sheet } = found;
6547
+ const range = normalizeRange(table3.range);
6548
+ const headerRow = table3.headerRow ? range.start.row : -1;
6549
+ const dataStart = range.start.row + (table3.headerRow ? 1 : 0);
6550
+ const dataEnd = range.end.row - (table3.totalsRow ? 1 : 0);
6551
+ const totalsRow = table3.totalsRow ? range.end.row : -1;
6552
6552
  const columnOf = (name) => {
6553
6553
  const lower3 = name.toLowerCase();
6554
- const index3 = table2.columns.findIndex((c3) => c3.name.toLowerCase() === lower3);
6554
+ const index3 = table3.columns.findIndex((c3) => c3.name.toLowerCase() === lower3);
6555
6555
  return index3 < 0 ? -1 : range.start.col + index3;
6556
6556
  };
6557
6557
  let c1 = range.start.col;
@@ -7819,16 +7819,16 @@ function lookupArray(value2) {
7819
7819
  }
7820
7820
  function vhlookup(args, ctx, vertical) {
7821
7821
  const lookup2 = blankAsZero(args);
7822
- const table2 = lookupArray(args[1] ?? null);
7822
+ const table3 = lookupArray(args[1] ?? null);
7823
7823
  const index3 = int(args[2]);
7824
7824
  const approximate2 = args.length < 4 ? true : bool(args[3]);
7825
- const { rows, cols } = shape(table2);
7825
+ const { rows, cols } = shape(table3);
7826
7826
  if (index3 < 1) fail(ERR.VALUE);
7827
7827
  if (index3 > (vertical ? cols : rows)) fail(ERR.REF);
7828
- const keys = line(ctx, table2, vertical ? "col" : "row", 0);
7828
+ const keys = line(ctx, table3, vertical ? "col" : "row", 0);
7829
7829
  const at = approximate2 ? findAscending(keys, lookup2) : findExact(keys, lookup2, true);
7830
7830
  if (at < 0) fail(ERR.NA);
7831
- return vertical ? cellOf(table2, at, index3 - 1) : cellOf(table2, index3 - 1, at);
7831
+ return vertical ? cellOf(table3, at, index3 - 1) : cellOf(table3, index3 - 1, at);
7832
7832
  }
7833
7833
  function match(args, ctx) {
7834
7834
  const lookup2 = blankAsZero(args);
@@ -9329,10 +9329,10 @@ var REGRESSION_FUNCTIONS = [
9329
9329
  const lay = logs(layout(ctx, args));
9330
9330
  const fit2 = fitLeastSquares(lay.x, lay.y, withConst(args, 2));
9331
9331
  const stats = !omitted(args, 3) && bool(args[3]);
9332
- const table2 = coefficientTable(fit2, stats, Math.exp);
9333
- if (!stats) return table2;
9332
+ const table3 = coefficientTable(fit2, stats, Math.exp);
9333
+ if (!stats) return table3;
9334
9334
  const plain3 = coefficientTable(fit2, true, (v) => v).data;
9335
- return new Matrix([table2.data[0] ?? [], ...plain3.slice(1)]);
9335
+ return new Matrix([table3.data[0] ?? [], ...plain3.slice(1)]);
9336
9336
  },
9337
9337
  ARGS
9338
9338
  ),
@@ -11731,7 +11731,7 @@ var DEFAULT_XML_LIMITS = {
11731
11731
  maxNodes: 5e6
11732
11732
  };
11733
11733
  var MARKUP_RE = /<!--[\s\S]*?-->|<!\[CDATA\[[\s\S]*?\]\]>|<\?[\s\S]*?\?>|<(\/?)([^\s\/>]+)(?:\s+[^\s=\/>]+\s*=\s*(?:"[^"]*"|'[^']*'))*\s*(\/?)>/g;
11734
- function checkXmlLimits(xml, label5, limits = {}) {
11734
+ function checkXmlLimits(xml, label2, limits = {}) {
11735
11735
  const maxDepth = limits.maxDepth ?? DEFAULT_XML_LIMITS.maxDepth;
11736
11736
  const maxNodes = limits.maxNodes ?? DEFAULT_XML_LIMITS.maxNodes;
11737
11737
  let depth = 0;
@@ -11744,16 +11744,16 @@ function checkXmlLimits(xml, label5, limits = {}) {
11744
11744
  continue;
11745
11745
  }
11746
11746
  nodes++;
11747
- if (nodes > maxNodes) throw new Error(`${label5} XML exceeds the limit of ${maxNodes} elements`);
11747
+ if (nodes > maxNodes) throw new Error(`${label2} XML exceeds the limit of ${maxNodes} elements`);
11748
11748
  if (!selfClosing && ++depth > maxDepth)
11749
- throw new Error(`${label5} XML exceeds the nesting depth limit of ${maxDepth}`);
11749
+ throw new Error(`${label2} XML exceeds the nesting depth limit of ${maxDepth}`);
11750
11750
  }
11751
11751
  }
11752
11752
  function parseXml(xml, options = {}) {
11753
- const label5 = options.label ?? "OOXML";
11753
+ const label2 = options.label ?? "OOXML";
11754
11754
  if (/<!DOCTYPE|<!ENTITY/i.test(xml))
11755
- throw new Error(`${label5} XML with DTD or entity declarations is not supported`);
11756
- checkXmlLimits(xml, label5, options.limits);
11755
+ throw new Error(`${label2} XML with DTD or entity declarations is not supported`);
11756
+ checkXmlLimits(xml, label2, options.limits);
11757
11757
  let parseError = "";
11758
11758
  let parsed;
11759
11759
  try {
@@ -11764,12 +11764,12 @@ function parseXml(xml, options = {}) {
11764
11764
  }).parseFromString(xml, "application/xml");
11765
11765
  } catch (error) {
11766
11766
  throw new Error(
11767
- `Invalid ${label5} XML: ${error instanceof Error ? error.message : String(error)}`,
11767
+ `Invalid ${label2} XML: ${error instanceof Error ? error.message : String(error)}`,
11768
11768
  { cause: error }
11769
11769
  );
11770
11770
  }
11771
11771
  if (parseError || !parsed.documentElement)
11772
- throw new Error(`Invalid ${label5} XML: ${parseError || "missing root element"}`);
11772
+ throw new Error(`Invalid ${label2} XML: ${parseError || "missing root element"}`);
11773
11773
  return parsed;
11774
11774
  }
11775
11775
  var buildXml = (node2) => new XMLSerializer().serializeToString(node2);
@@ -11952,11 +11952,235 @@ var pivotRowFields = (pivot) => [
11952
11952
  ...pivot.secondRowField ? [pivot.secondRowField] : [],
11953
11953
  ...pivot.secondRowField ? pivot.moreRowFields ?? [] : []
11954
11954
  ];
11955
+ function pivotValuesIndex(pivot) {
11956
+ if (pivot.valuesAxis !== "rows") return -1;
11957
+ const count2 = pivotRowFields(pivot).length;
11958
+ const at = pivot.valuesPosition;
11959
+ if (typeof at === "number") return Math.min(Math.max(Math.trunc(at), 0), count2);
11960
+ return at === "first" ? 0 : at === "between" ? Math.min(1, count2) : count2;
11961
+ }
11955
11962
  var pivotColumnFields = (pivot) => [
11956
11963
  ...pivot.columnField ? [pivot.columnField] : [],
11957
11964
  ...pivot.columnField ? pivot.moreColumnFields ?? [] : []
11958
11965
  ];
11959
11966
 
11967
+ // i18n/locale.ts
11968
+ var SUPPORTED_OFFICE_LOCALES = ["en", "fr", "de", "es", "zh-CN"];
11969
+ var DEFAULT_REJECTED_SUBTAGS = ["hant", "tw", "hk", "mo"];
11970
+ function normalizeLocale(input, supported, fallback, options = {}) {
11971
+ const parts = (input ?? "").trim().toLowerCase().split(/[-_]/).filter(Boolean);
11972
+ const language = parts[0];
11973
+ if (!language) return fallback;
11974
+ const find3 = (tag) => supported.find((item) => item.toLowerCase() === tag);
11975
+ const exact = find3(parts.join("-"));
11976
+ if (exact) return exact;
11977
+ const base = find3(language);
11978
+ if (base) return base;
11979
+ const rejected = options.rejectedSubtags ?? DEFAULT_REJECTED_SUBTAGS;
11980
+ if (parts.slice(1).some((part) => rejected.includes(part))) return fallback;
11981
+ return supported.find((item) => item.toLowerCase().split("-")[0] === language && item.includes("-")) ?? fallback;
11982
+ }
11983
+ function normalizeOfficeLocale(input) {
11984
+ return normalizeLocale(input, SUPPORTED_OFFICE_LOCALES, "en");
11985
+ }
11986
+
11987
+ // xlsx/pivot/captions-locales.ts
11988
+ var table2 = (words2, prefix, rest, functions) => ({
11989
+ ...rest,
11990
+ functions,
11991
+ aggregates: Object.fromEntries(
11992
+ Object.keys(words2).map((fn) => [fn, prefix(words2[fn])])
11993
+ )
11994
+ });
11995
+ var GERMAN = {
11996
+ sum: "Summe",
11997
+ count: "Anzahl",
11998
+ average: "Mittelwert",
11999
+ max: "Max",
12000
+ min: "Min",
12001
+ product: "Produkt",
12002
+ countNums: "Anzahl (Zahlen)",
12003
+ stdDev: "Standardabweichung",
12004
+ stdDevp: "Standardabweichung (Grundgesamtheit)",
12005
+ var: "Varianz",
12006
+ varp: "Varianz (Grundgesamtheit)"
12007
+ };
12008
+ var SPANISH = {
12009
+ sum: "Suma",
12010
+ count: "Cuenta",
12011
+ average: "Promedio",
12012
+ max: "M\xE1x",
12013
+ min: "M\xEDn",
12014
+ product: "Producto",
12015
+ countNums: "Cuenta de n\xFAmeros",
12016
+ stdDev: "Desvest",
12017
+ stdDevp: "Desvestp",
12018
+ var: "Var",
12019
+ varp: "Varp"
12020
+ };
12021
+ var FRENCH = {
12022
+ sum: "Somme",
12023
+ count: "Nombre",
12024
+ average: "Moyenne",
12025
+ max: "Max",
12026
+ min: "Min",
12027
+ product: "Produit",
12028
+ countNums: "Nombre (nombres)",
12029
+ stdDev: "\xC9cartype",
12030
+ stdDevp: "\xC9cartypep",
12031
+ var: "Var",
12032
+ varp: "Varp"
12033
+ };
12034
+ var CHINESE = {
12035
+ sum: "\u6C42\u548C",
12036
+ count: "\u8BA1\u6570",
12037
+ average: "\u5E73\u5747\u503C",
12038
+ max: "\u6700\u5927\u503C",
12039
+ min: "\u6700\u5C0F\u503C",
12040
+ product: "\u4E58\u79EF",
12041
+ countNums: "\u6570\u503C\u8BA1\u6570",
12042
+ stdDev: "\u6807\u51C6\u504F\u5DEE",
12043
+ stdDevp: "\u603B\u4F53\u6807\u51C6\u504F\u5DEE",
12044
+ var: "\u65B9\u5DEE",
12045
+ varp: "\u603B\u4F53\u65B9\u5DEE"
12046
+ };
12047
+ var LOCALIZED_PIVOT_CAPTIONS = {
12048
+ de: table2(
12049
+ GERMAN,
12050
+ (word) => `${word} von {0}`,
12051
+ {
12052
+ rowLabels: "Zeilenbeschriftungen",
12053
+ columnLabels: "Spaltenbeschriftungen",
12054
+ grandTotal: "Gesamtergebnis",
12055
+ values: "Werte",
12056
+ all: "(Alle)",
12057
+ blank: "(leer)",
12058
+ subtotal: "{0} Ergebnis",
12059
+ measureTotal: "Gesamt {0}"
12060
+ },
12061
+ GERMAN
12062
+ ),
12063
+ es: table2(
12064
+ SPANISH,
12065
+ (word) => `${word} de {0}`,
12066
+ {
12067
+ rowLabels: "Etiquetas de fila",
12068
+ columnLabels: "Etiquetas de columna",
12069
+ grandTotal: "Total general",
12070
+ values: "Valores",
12071
+ all: "(Todas)",
12072
+ blank: "(en blanco)",
12073
+ subtotal: "{0} Total",
12074
+ measureTotal: "Total {0}"
12075
+ },
12076
+ SPANISH
12077
+ ),
12078
+ fr: table2(
12079
+ FRENCH,
12080
+ (word) => `${word} de {0}`,
12081
+ {
12082
+ rowLabels: "\xC9tiquettes de lignes",
12083
+ columnLabels: "\xC9tiquettes de colonnes",
12084
+ grandTotal: "Total g\xE9n\xE9ral",
12085
+ values: "Valeurs",
12086
+ all: "(Tous)",
12087
+ blank: "(vide)",
12088
+ subtotal: "{0} Total",
12089
+ measureTotal: "Total {0}"
12090
+ },
12091
+ FRENCH
12092
+ ),
12093
+ "zh-CN": table2(
12094
+ CHINESE,
12095
+ (word) => `${word}\u9879:{0}`,
12096
+ {
12097
+ rowLabels: "\u884C\u6807\u7B7E",
12098
+ columnLabels: "\u5217\u6807\u7B7E",
12099
+ grandTotal: "\u603B\u8BA1",
12100
+ values: "\u6570\u503C",
12101
+ all: "(\u5168\u90E8)",
12102
+ blank: "(\u7A7A\u767D)",
12103
+ subtotal: "{0} \u6C47\u603B",
12104
+ measureTotal: "\u603B\u8BA1 {0}"
12105
+ },
12106
+ CHINESE
12107
+ )
12108
+ };
12109
+
12110
+ // xlsx/pivot/captions.ts
12111
+ var FUNCTIONS = {
12112
+ sum: "Sum",
12113
+ count: "Count",
12114
+ average: "Average",
12115
+ max: "Max",
12116
+ min: "Min",
12117
+ product: "Product",
12118
+ countNums: "Count",
12119
+ stdDev: "StdDev",
12120
+ stdDevp: "StdDevp",
12121
+ var: "Var",
12122
+ varp: "Varp"
12123
+ };
12124
+ var aggregateNames = () => Object.fromEntries(
12125
+ Object.keys(FUNCTIONS).map((fn) => [
12126
+ fn,
12127
+ `${fn[0].toUpperCase()}${fn.slice(1)} of {0}`
12128
+ ])
12129
+ );
12130
+ var ENGLISH_PIVOT_CAPTIONS = {
12131
+ rowLabels: "Row Labels",
12132
+ columnLabels: "Column Labels",
12133
+ grandTotal: "Grand Total",
12134
+ values: "Values",
12135
+ all: "(All)",
12136
+ blank: "(blank)",
12137
+ subtotal: "{0} Total",
12138
+ measureTotal: "Total {0}",
12139
+ functions: FUNCTIONS,
12140
+ aggregates: aggregateNames()
12141
+ };
12142
+ var fillCaption = (template, ...args) => template.replace(/\{(\d)\}/g, (_match, at) => args[Number(at)] ?? "");
12143
+ function pivotCaptions(pivot) {
12144
+ const own = pivot.captions;
12145
+ if (!own) return ENGLISH_PIVOT_CAPTIONS;
12146
+ return {
12147
+ ...ENGLISH_PIVOT_CAPTIONS,
12148
+ ...Object.fromEntries(Object.entries(own).filter(([, value2]) => typeof value2 === "string")),
12149
+ functions: { ...ENGLISH_PIVOT_CAPTIONS.functions, ...own.functions },
12150
+ aggregates: { ...ENGLISH_PIVOT_CAPTIONS.aggregates, ...own.aggregates }
12151
+ };
12152
+ }
12153
+ var pivotMeasureName = (aggregate3, field, pivot = {}) => fillCaption(pivotCaptions(pivot).aggregates[aggregate3], field);
12154
+ function localizedPivotCaptions(locale) {
12155
+ const caps = LOCALIZED_PIVOT_CAPTIONS[normalizeOfficeLocale(locale)];
12156
+ return caps ? structuredClone(caps) : void 0;
12157
+ }
12158
+ function trimmedCaptions(caps) {
12159
+ const out = {};
12160
+ for (const key of [
12161
+ "rowLabels",
12162
+ "columnLabels",
12163
+ "grandTotal",
12164
+ "values",
12165
+ "all",
12166
+ "blank",
12167
+ "subtotal",
12168
+ "measureTotal"
12169
+ ])
12170
+ if (caps[key] !== ENGLISH_PIVOT_CAPTIONS[key]) out[key] = caps[key];
12171
+ for (const key of ["functions", "aggregates"]) {
12172
+ const changed = Object.keys(caps[key]).filter(
12173
+ (fn) => caps[key][fn] !== ENGLISH_PIVOT_CAPTIONS[key][fn]
12174
+ );
12175
+ if (changed.length) out[key] = Object.fromEntries(changed.map((fn) => [fn, caps[key][fn]]));
12176
+ }
12177
+ return Object.keys(out).length ? out : void 0;
12178
+ }
12179
+ function authoredCaptions(options) {
12180
+ const own = options.captions ?? localizedPivotCaptions(options.locale);
12181
+ return own && Object.keys(own).length ? structuredClone(own) : void 0;
12182
+ }
12183
+
11960
12184
  // xlsx/pivot/date-groups.ts
11961
12185
  var PIVOT_DATE_UNITS = [
11962
12186
  "seconds",
@@ -11981,7 +12205,7 @@ var LEAP_MONTHS = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
11981
12205
  var MAX_ITEMS = 1e4;
11982
12206
  var pad3 = (value2, width = 2) => String(value2).padStart(width, "0");
11983
12207
  var dateGroupUnits = (group) => PIVOT_DATE_UNITS.filter((unit) => group.by.includes(unit));
11984
- var dateGroupFieldName = (unit, field) => `${UNIT_TITLES[unit]} (${field})`;
12208
+ var dateGroupFieldName = (unit, field, group) => group?.localized?.[unit]?.name ?? `${UNIT_TITLES[unit]} (${field})`;
11985
12209
  var dateGroupDays = (group) => group.by.length === 1 && group.by[0] === "days" ? group.days ?? 1 : 1;
11986
12210
  function dateGroupRange(group, serials) {
11987
12211
  let min = Infinity;
@@ -12004,7 +12228,7 @@ var secondsOfDay = (serial) => Math.round((serial - Math.floor(serial)) * 86400)
12004
12228
  function dayBuckets(range, days) {
12005
12229
  return Math.max(1, Math.ceil((Math.floor(range.end) - Math.floor(range.start) + 1) / days));
12006
12230
  }
12007
- function dateUnitLabels(unit, range, days, date1904) {
12231
+ function englishDateUnitLabels(unit, range, days, date1904) {
12008
12232
  const labels = [`<${isoDay(range.start, date1904)}`];
12009
12233
  if (unit === "seconds" || unit === "minutes")
12010
12234
  for (let i2 = 0; i2 < 60; i2++) labels.push(`:${pad3(i2)}`);
@@ -12033,6 +12257,11 @@ function dateUnitLabels(unit, range, days, date1904) {
12033
12257
  labels.push(`>${isoDay(range.end, date1904)}`);
12034
12258
  return labels;
12035
12259
  }
12260
+ function dateUnitLabels(unit, range, days, date1904, group) {
12261
+ const english = englishDateUnitLabels(unit, range, days, date1904);
12262
+ const localized = group?.localized?.[unit]?.labels;
12263
+ return localized?.length === english.length ? localized : english;
12264
+ }
12036
12265
  function dateUnitIndex(unit, range, days, date1904, serial, count2) {
12037
12266
  if (serial < range.start) return 0;
12038
12267
  if (serial > range.end) return count2 - 1;
@@ -12056,7 +12285,7 @@ function derivedDateFields(pivot) {
12056
12285
  for (const group of pivot.dateGroups ?? [])
12057
12286
  for (const unit of dateGroupUnits(group))
12058
12287
  derived.push({
12059
- name: dateGroupFieldName(unit, group.field),
12288
+ name: dateGroupFieldName(unit, group.field, group),
12060
12289
  unit,
12061
12290
  group,
12062
12291
  index: databaseFields + derived.length
@@ -12067,7 +12296,7 @@ function countDerived(pivot) {
12067
12296
  let count2 = 0;
12068
12297
  for (const group of pivot.dateGroups ?? [])
12069
12298
  for (const unit of dateGroupUnits(group))
12070
- if (pivot.fields.includes(dateGroupFieldName(unit, group.field))) count2++;
12299
+ if (pivot.fields.includes(dateGroupFieldName(unit, group.field, group))) count2++;
12071
12300
  return count2;
12072
12301
  }
12073
12302
  var pivotAxisFieldNames = (pivot) => [
@@ -12087,7 +12316,7 @@ function derivedDateLabels(pivot, name) {
12087
12316
  if (!entry3) return void 0;
12088
12317
  const [group] = resolveDateGroups({ ...pivot, dateGroups: [entry3.group] });
12089
12318
  const range = { start: group.start, end: group.end };
12090
- return dateUnitLabels(entry3.unit, range, dateGroupDays(group), pivot.date1904 ?? false);
12319
+ return dateUnitLabels(entry3.unit, range, dateGroupDays(group), pivot.date1904 ?? false, group);
12091
12320
  }
12092
12321
  function validateDateGroups(pivot) {
12093
12322
  const groups = pivot.dateGroups;
@@ -12103,18 +12332,16 @@ function validateDateGroups(pivot) {
12103
12332
  seen.add(group.field);
12104
12333
  if (!(pivot.dateFields ?? []).includes(group.field))
12105
12334
  throw new Error("Only fields that contain dates can be grouped by date.");
12106
- if (pivot.pageFilter || pivot.dateFilter)
12107
- throw new Error("Date groups cannot be combined with report filters or timelines.");
12108
12335
  const serials = pivot.records.map((record) => record[index3]);
12109
12336
  if (!serials.length || serials.some((v) => typeof v !== "number" || !Number.isFinite(v)))
12110
12337
  throw new Error("Only fields that contain dates can be grouped by date.");
12111
12338
  const range = dateGroupRange(group, serials);
12112
12339
  if (range.start >= range.end) throw new Error("The date group must end after it starts.");
12113
12340
  for (const unit of dateGroupUnits(group)) {
12114
- const name = dateGroupFieldName(unit, group.field);
12341
+ const name = dateGroupFieldName(unit, group.field, group);
12115
12342
  if (pivot.fields.includes(name))
12116
12343
  throw new Error("A source field already has the name of a date group field.");
12117
- if (dateUnitLabels(unit, range, dateGroupDays(group), pivot.date1904 ?? false).length > MAX_ITEMS)
12344
+ if (dateUnitLabels(unit, range, dateGroupDays(group), pivot.date1904 ?? false, group).length > MAX_ITEMS)
12118
12345
  throw new Error("The date group has too many items.");
12119
12346
  }
12120
12347
  }
@@ -12128,7 +12355,7 @@ function expandDateGroups(pivot) {
12128
12355
  const tables = derived.map((entry3) => {
12129
12356
  const range = { start: entry3.group.start, end: entry3.group.end };
12130
12357
  const days = dateGroupDays(entry3.group);
12131
- const labels = dateUnitLabels(entry3.unit, range, days, date1904);
12358
+ const labels = dateUnitLabels(entry3.unit, range, days, date1904, entry3.group);
12132
12359
  return {
12133
12360
  base: pivot.fields.indexOf(entry3.group.field),
12134
12361
  labels,
@@ -12140,9 +12367,9 @@ function expandDateGroups(pivot) {
12140
12367
  fields: [...pivot.fields, ...derived.map((entry3) => entry3.name)],
12141
12368
  records: pivot.records.map((record) => [
12142
12369
  ...record,
12143
- ...tables.map((table2) => {
12144
- const value2 = record[table2.base];
12145
- return typeof value2 === "number" ? table2.labels[table2.index(value2)] : null;
12370
+ ...tables.map((table3) => {
12371
+ const value2 = record[table3.base];
12372
+ return typeof value2 === "number" ? table3.labels[table3.index(value2)] : null;
12146
12373
  })
12147
12374
  ])
12148
12375
  };
@@ -12285,6 +12512,11 @@ function fieldSubtotalFunctions(pivot, field) {
12285
12512
  if (entry3) return PIVOT_SUBTOTAL_ORDER.filter((fn) => entry3.functions.includes(fn));
12286
12513
  return field === pivot.rowField && pivot.subtotals === false ? [] : "auto";
12287
12514
  }
12515
+ function pivotSubtotalFields(pivot) {
12516
+ const rows = pivotRowFields(pivot);
12517
+ const columns = pivotColumnFields(pivot);
12518
+ return [...rows.length > 1 ? rows : [], ...columns.length > 1 ? columns : []];
12519
+ }
12288
12520
  function normalizedFieldSubtotals(entries) {
12289
12521
  return entries.map((entry3) => {
12290
12522
  if (!entry3 || !Array.isArray(entry3.functions) || entry3.functions.some((fn) => !PIVOT_SUBTOTAL_ORDER.includes(fn)))
@@ -12295,15 +12527,13 @@ function normalizedFieldSubtotals(entries) {
12295
12527
  };
12296
12528
  });
12297
12529
  }
12298
- function validateFieldSubtotals(pivot, rowFields) {
12530
+ function validateFieldSubtotals(pivot, axisFields) {
12299
12531
  const entries = pivot.fieldSubtotals;
12300
12532
  if (entries === void 0) return;
12301
12533
  if (!Array.isArray(entries)) throw new Error("Choose valid field subtotals.");
12302
- if (entries.length && pivot.valuesAxis === "rows")
12303
- throw new Error("Field subtotals require Values on columns.");
12304
12534
  const seen = /* @__PURE__ */ new Set();
12305
12535
  for (const entry3 of entries) {
12306
- if (!entry3 || typeof entry3 !== "object" || !rowFields.includes(entry3.field) || seen.has(entry3.field) || !Array.isArray(entry3.functions) || entry3.functions.some((fn) => !PIVOT_AGGREGATES.includes(fn)) || new Set(entry3.functions).size !== entry3.functions.length)
12536
+ if (!entry3 || typeof entry3 !== "object" || !axisFields.includes(entry3.field) || seen.has(entry3.field) || !Array.isArray(entry3.functions) || entry3.functions.some((fn) => !PIVOT_AGGREGATES.includes(fn)) || new Set(entry3.functions).size !== entry3.functions.length)
12307
12537
  throw new Error("Choose valid field subtotals.");
12308
12538
  seen.add(entry3.field);
12309
12539
  }
@@ -12382,6 +12612,17 @@ function pruneItemFilters(pivot) {
12382
12612
  return next.length ? next : void 0;
12383
12613
  }
12384
12614
 
12615
+ // xlsx/pivot/item-labels.ts
12616
+ var keyOf = (field, item) => `${field}\0${pivotValueKey(item)}`;
12617
+ function pivotItemLabeler(pivot) {
12618
+ const blank = pivotCaptions(pivot).blank;
12619
+ const names = pivot.itemNames?.length ? new Map(pivot.itemNames.map((entry3) => [keyOf(entry3.field, entry3.item), entry3.name])) : void 0;
12620
+ return (field, value2) => names?.get(keyOf(field, value2)) ?? (value2 === null || value2 === "" ? blank : pivotItemLabel(value2));
12621
+ }
12622
+ var pivotItemName = (pivot, field, item) => pivot.itemNames?.find(
12623
+ (entry3) => entry3.field === field && pivotValueKey(entry3.item) === pivotValueKey(item)
12624
+ )?.name;
12625
+
12385
12626
  // xlsx/pivot/page-filter.ts
12386
12627
  function validatePivotPageFilter(pivot) {
12387
12628
  const filter2 = pivot.pageFilter;
@@ -12393,23 +12634,24 @@ function validatePivotPageFilter(pivot) {
12393
12634
  pivot.columnField,
12394
12635
  pivot.valueField,
12395
12636
  ...extras.map((v) => v?.field)
12396
- ].includes(filter2.field) || pivot.valuesAxis === "rows")
12397
- throw new Error("Report filters require Values on columns and a separate source field.");
12637
+ ].includes(filter2.field))
12638
+ throw new Error("Report filters require a separate source field.");
12398
12639
  if (filter2.item !== void 0 && !(filter2.item === null || typeof filter2.item === "string" || typeof filter2.item === "boolean" || typeof filter2.item === "number" && Number.isFinite(filter2.item) || isCellError(filter2.item) && isErrorCode(filter2.item.error) && Object.keys(filter2.item).length === 1))
12399
12640
  throw new Error("Choose a cached literal report filter item.");
12400
12641
  }
12401
12642
  function pivotPageProjection(pivot) {
12402
- return applyPivotGroups(applyPivotItemFilters(pagedProjection(pivot)));
12643
+ const groups = pivot.dateGroups?.length ? { ...pivot, dateGroups: resolveDateGroups(pivot) } : pivot;
12644
+ return applyPivotGroups(applyPivotItemFilters(pagedProjection(groups)));
12403
12645
  }
12404
12646
  function pagedProjection(pivot) {
12405
12647
  const filter2 = pivot.pageFilter;
12406
12648
  if (!filter2) return pivot;
12407
12649
  const labels = /* @__PURE__ */ new Map();
12408
12650
  for (const item of pivotItems(pivot, filter2.field)) {
12409
- const label5 = String(pivotItemLabel(item)).toLowerCase(), key2 = pivotValueKey(item);
12410
- if (label5 === "(all)" || labels.has(label5) && labels.get(label5) !== key2)
12651
+ const label2 = String(pivotItemLabel(item)).toLowerCase(), key2 = pivotValueKey(item);
12652
+ if (label2 === "(all)" || labels.has(label2) && labels.get(label2) !== key2)
12411
12653
  throw new Error("Ambiguous report filter item captions are preserved.");
12412
- labels.set(label5, key2);
12654
+ labels.set(label2, key2);
12413
12655
  }
12414
12656
  if (filter2.item === void 0) return pivot;
12415
12657
  const index3 = pivot.fields.indexOf(filter2.field), key = pivotValueKey(filter2.item);
@@ -12427,7 +12669,7 @@ function prependPivotPage(grid, pivot) {
12427
12669
  values: [
12428
12670
  [
12429
12671
  pivot.pageFilter.field,
12430
- pivot.pageFilter.item === void 0 ? "(All)" : pivotItemLabel(pivot.pageFilter.item),
12672
+ pivot.pageFilter.item === void 0 ? pivotCaptions(pivot).all : pivotItemLabeler(pivot)(pivot.pageFilter.field, pivot.pageFilter.item),
12431
12673
  ...Array(width - 2).fill(null)
12432
12674
  ],
12433
12675
  Array(width).fill(null),
@@ -12551,13 +12793,9 @@ function validatePivotFields(pivot) {
12551
12793
  const columns = pivotColumnFields(pivot);
12552
12794
  if (pivot.moreColumnFields !== void 0 && (!Array.isArray(pivot.moreColumnFields) || pivot.moreColumnFields.length > 0 && !pivot.columnField || pivot.moreColumnFields.length > 62 || pivot.moreColumnFields.some((name) => typeof name !== "string")))
12553
12795
  throw new Error("Choose valid PivotTable column fields.");
12554
- if (pivot.valuesAxis === "rows" && rows.length > 2)
12555
- throw new Error("Values on rows support at most two row fields.");
12556
- if (pivot.valuesAxis === "rows" && columns.length > 1)
12557
- throw new Error("Values on rows support one column field.");
12558
12796
  if (pivot.pageFilter && columns.length > 1)
12559
12797
  throw new Error("Report filters support one column field.");
12560
- validateFieldSubtotals(pivot, rows);
12798
+ validateFieldSubtotals(pivot, [...rows, ...columns]);
12561
12799
  const axisNames = pivotAxisFieldNames(pivot);
12562
12800
  if ((pivot.dateGroups ?? []).some(
12563
12801
  (group) => [...rows, ...columns].some((name) => name === group.field)
@@ -12566,13 +12804,14 @@ function validatePivotFields(pivot) {
12566
12804
  const extras = pivot.additionalValues ?? [];
12567
12805
  if (pivot.valuesAxis !== void 0 && !["columns", "rows"].includes(pivot.valuesAxis))
12568
12806
  throw new Error("Choose a valid Values axis.");
12569
- if (pivot.valuesPosition !== void 0 && !["last", "between", "first"].includes(pivot.valuesPosition))
12807
+ const position = pivot.valuesPosition;
12808
+ if (position !== void 0 && !["last", "between", "first"].includes(position) && !(typeof position === "number" && Number.isInteger(position) && position >= 0))
12570
12809
  throw new Error("Choose a valid Values position.");
12571
- if ((pivot.valuesPosition === "between" || pivot.valuesPosition === "first") && (pivot.valuesAxis !== "rows" || !pivot.secondRowField))
12810
+ if (position !== void 0 && position !== "last" && (pivot.valuesAxis !== "rows" || position === "between" && !pivot.secondRowField || typeof position === "number" && position > rows.length))
12572
12811
  throw new Error("Values before or between fields require two row fields and Values on rows.");
12573
12812
  if (pivot.valuesAxis === "rows" && (!Array.isArray(extras) || !extras.length))
12574
12813
  throw new Error("Values on rows require multiple measures.");
12575
- if (extras.length > 0 && pivot.sourceXml && parseXml(pivot.sourceXml).documentElement.getAttribute("dataCaption") !== "Values")
12814
+ if (extras.length > 0 && pivot.sourceXml && parseXml(pivot.sourceXml).documentElement.getAttribute("dataCaption") !== pivotCaptions(pivot).values)
12576
12815
  throw new Error("This PivotTable uses unsupported Values header captions.");
12577
12816
  if (!Array.isArray(extras) || extras.length > 15 || extras.some(
12578
12817
  (measure) => !measure || !pivot.fields.includes(measure.field) || !PIVOT_AGGREGATES.includes(measure.aggregate) || typeof measure.caption !== "string" || !measure.caption.trim() || measure.caption.length > 255 || pivot.fields.some((field) => field.toLowerCase() === measure.caption.toLowerCase())
@@ -12585,8 +12824,47 @@ function validatePivotFields(pivot) {
12585
12824
  if (pivot.layout !== void 0 && !["tabular", "compact", "outline"].includes(pivot.layout) || pivot.subtotalPosition !== void 0 && !["top", "bottom"].includes(pivot.subtotalPosition) || !PIVOT_AGGREGATES.includes(pivot.aggregate) || !pivot.fields.includes(pivot.valueField) || [...rows, ...columns].some((field) => !axisNames.includes(field)) || (/* @__PURE__ */ new Set([...rows, ...columns])).size !== rows.length + columns.length || pivot.subtotals !== void 0 && typeof pivot.subtotals !== "boolean" || pivot.repeatLabels !== void 0 && typeof pivot.repeatLabels !== "boolean")
12586
12825
  throw new Error("Choose valid PivotTable fields; row and column fields must differ.");
12587
12826
  }
12588
- function pivotCaption(aggregate3, field) {
12589
- return `${aggregate3[0].toUpperCase()}${aggregate3.slice(1)} of ${field}`;
12827
+ function pivotCaption(aggregate3, field, pivot) {
12828
+ return pivotMeasureName(aggregate3, field, pivot);
12829
+ }
12830
+
12831
+ // xlsx/write/xml-out.ts
12832
+ var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n';
12833
+ var CONTROL = "\0-\b\v\f-" + String.fromCharCode(65534, 65535);
12834
+ var NEEDS_ESCAPE = new RegExp(`[${CONTROL}\r]|_x[0-9A-Fa-f]{4}_`);
12835
+ var ESCAPABLE = new RegExp(`[${CONTROL}\r]|_(?=x[0-9A-Fa-f]{4}_)`, "g");
12836
+ function encodeEscapes(text4) {
12837
+ if (!NEEDS_ESCAPE.test(text4)) return text4;
12838
+ return text4.replace(
12839
+ ESCAPABLE,
12840
+ (ch) => `_x${ch.charCodeAt(0).toString(16).toUpperCase().padStart(4, "0")}_`
12841
+ );
12842
+ }
12843
+ var INVALID_XML = new RegExp(`[${CONTROL}]`, "g");
12844
+ var escapeText = (text4) => text4.replace(INVALID_XML, "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
12845
+ var escapeAttr = (text4) => text4.replace(INVALID_XML, "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/\r/g, "&#13;").replace(/\n/g, "&#10;").replace(/\t/g, "&#9;");
12846
+ function attrs(values2) {
12847
+ let out = "";
12848
+ for (const [name, value2] of Object.entries(values2)) {
12849
+ if (value2 === void 0) continue;
12850
+ const text4 = typeof value2 === "boolean" ? value2 ? "1" : "0" : typeof value2 === "number" ? num2(value2) : value2;
12851
+ out += ` ${name}="${escapeAttr(text4)}"`;
12852
+ }
12853
+ return out;
12854
+ }
12855
+ var el = (name, values2 = {}, content2 = "") => content2 ? `<${name}${attrs(values2)}>${content2}</${name}>` : `<${name}${attrs(values2)}/>`;
12856
+ var num2 = (value2) => Object.is(value2, -0) ? "0" : String(value2);
12857
+ function tElement(text4, name = "t") {
12858
+ const encoded = escapeText(encodeEscapes(text4));
12859
+ const preserve = /^\s|\s$|\n|\t/.test(text4) ? ' xml:space="preserve"' : "";
12860
+ return `<${name}${preserve}>${encoded}</${name}>`;
12861
+ }
12862
+ var MAIN_NS = ' xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"';
12863
+ function inlineFragment(xml) {
12864
+ const end = xml.indexOf(">");
12865
+ if (end < 0) return xml;
12866
+ const head = xml.slice(0, end);
12867
+ return head.includes(MAIN_NS) ? head.replace(MAIN_NS, "") + xml.slice(end) : xml;
12590
12868
  }
12591
12869
 
12592
12870
  // xlsx/pivot/measures.ts
@@ -12594,7 +12872,7 @@ var pivotMeasures = (pivot) => [
12594
12872
  { field: pivot.valueField, aggregate: pivot.aggregate, caption: pivot.valueCaption },
12595
12873
  ...pivot.additionalValues ?? []
12596
12874
  ];
12597
- function normalizedPivotMeasures(values2) {
12875
+ function normalizedPivotMeasures(values2, pivot) {
12598
12876
  if (!Array.isArray(values2) || values2.length > 15)
12599
12877
  throw new Error("Choose between one and sixteen PivotTable value fields.");
12600
12878
  return values2.map((value2) => {
@@ -12606,7 +12884,7 @@ function normalizedPivotMeasures(values2) {
12606
12884
  return {
12607
12885
  field: value2.field,
12608
12886
  aggregate: aggregate3,
12609
- caption: value2.caption ?? `${aggregate3[0].toUpperCase()}${aggregate3.slice(1)} of ${value2.field}`
12887
+ caption: value2.caption ?? pivotMeasureName(aggregate3, value2.field, pivot)
12610
12888
  };
12611
12889
  });
12612
12890
  }
@@ -12638,329 +12916,16 @@ function aggregateValues(records, field, type) {
12638
12916
  return type === "average" ? sum3 / numbers3.length : sum3;
12639
12917
  }
12640
12918
  var pivotMeasureNumber = (pivot, records, measure) => aggregateValues(records, pivot.fields.indexOf(measure.field), measure.aggregate);
12641
- var pivotNumbers = (pivot, records) => pivotMeasures(pivot).map((measure) => pivotMeasureNumber(pivot, records, measure));
12642
- function pivotHeaderDimensions(pivot, columnItems, rowLabels) {
12643
- return {
12644
- rows: (pivot.columnField ? 2 : 1) + (pivot.pageFilter ? 2 : 0),
12645
- width: rowLabels + (pivot.columnField ? columnItems + 1 : 1)
12646
- };
12647
- }
12648
- function pivotHeaders(pivot, columns, labels, label5) {
12649
- const rowLabels = pivot.layout === "compact" ? ["Row Labels"] : pivot.valuesPosition === "first" ? ["Values", ...labels] : pivot.valuesPosition === "between" ? [labels[0], "Values", labels[1]] : [...labels, "Values"];
12650
- return pivot.columnField ? [
12651
- [
12652
- ...rowLabels.map(() => null),
12653
- pivot.layout === "compact" ? "Column Labels" : pivot.columnField,
12654
- ...columns.map(() => null)
12655
- ],
12656
- [...rowLabels, ...columns.map(label5), "Grand Total"]
12657
- ] : [[...rowLabels, null]];
12658
- }
12659
-
12660
- // xlsx/pivot/hierarchy-first.ts
12661
- function appendFirstPivotValues(pivot, context) {
12662
- const {
12663
- rowItems,
12664
- secondRowItems,
12665
- columnItems,
12666
- children: children2,
12667
- innerIndices,
12668
- groups,
12669
- details,
12670
- buckets,
12671
- width,
12672
- rowLabels,
12673
- top,
12674
- bottom,
12675
- append
12676
- } = context;
12677
- const compact3 = pivot.layout === "compact";
12678
- const tabular = !pivot.layout || pivot.layout === "tabular";
12679
- const blank = () => Array(width - rowLabels).fill(null);
12680
- pivotMeasures(pivot).forEach((measure, m) => {
12681
- const numbers3 = (keys, records) => [
12682
- ...columnItems.map(
12683
- (column2) => pivotMeasureNumber(
12684
- pivot,
12685
- buckets.get(JSON.stringify([...keys, pivotValueKey(column2)])) ?? [],
12686
- measure
12687
- )
12688
- ),
12689
- pivotMeasureNumber(pivot, records, measure)
12690
- ];
12691
- if (!tabular)
12692
- append([measure.caption, ...Array(rowLabels - 1).fill(null)], blank(), {
12693
- indices: [m],
12694
- measure: m
12695
- });
12696
- let first2 = true;
12697
- rowItems.forEach((outer, outerIndex) => {
12698
- const key = pivotValueKey(outer);
12699
- const group = groups.get(key) ?? [];
12700
- if (!tabular)
12701
- append(
12702
- compact3 ? [pivotItemLabel(outer)] : [null, pivotItemLabel(outer), null],
12703
- top ? numbers3([key], group) : blank(),
12704
- { indices: [m, outerIndex], measure: m },
12705
- compact3 ? 1 : 0
12706
- );
12707
- const innerKeys = [...children2.get(key)].sort(
12708
- (a2, b) => innerIndices.get(a2) - innerIndices.get(b)
12709
- );
12710
- innerKeys.forEach((innerKey, child3) => {
12711
- const innerIndex = innerIndices.get(innerKey);
12712
- append(
12713
- compact3 ? [pivotItemLabel(secondRowItems[innerIndex])] : [
12714
- tabular && first2 ? measure.caption : null,
12715
- pivot.repeatLabels || tabular && child3 === 0 ? pivotItemLabel(outer) : null,
12716
- pivotItemLabel(secondRowItems[innerIndex])
12717
- ],
12718
- numbers3([key, innerKey], details.get(JSON.stringify([key, innerKey]))),
12719
- { indices: [m, outerIndex, innerIndex], measure: m },
12720
- compact3 ? 2 : 0
12721
- );
12722
- first2 = false;
12723
- });
12724
- if (bottom)
12725
- append(
12726
- compact3 ? [`${String(pivotItemLabel(outer))} Total`] : [null, `${String(pivotItemLabel(outer))} Total`, null],
12727
- numbers3([key], group),
12728
- { indices: [m, outerIndex], measure: m, type: "default" },
12729
- compact3 ? 1 : 0
12730
- );
12731
- });
12732
- });
12733
- }
12734
-
12735
- // xlsx/pivot/hierarchy.ts
12736
- var label2 = pivotItemLabel;
12737
- function hierarchicalPivotGrid(pivot) {
12738
- const rowItems = pivotItems(pivot, pivot.rowField);
12739
- const secondRowItems = pivotItems(pivot, pivot.secondRowField);
12740
- const columnItems = pivot.columnField ? pivotItems(pivot, pivot.columnField) : [];
12741
- const outerField = pivot.fields.indexOf(pivot.rowField);
12742
- const innerField = pivot.fields.indexOf(pivot.secondRowField);
12743
- const columnField = pivot.columnField ? pivot.fields.indexOf(pivot.columnField) : -1;
12744
- const layout2 = pivot.layout ?? "tabular";
12745
- const compact3 = layout2 === "compact";
12746
- const firstValues = pivot.valuesPosition === "first";
12747
- const between = pivot.valuesPosition === "between";
12748
- const measures = pivotMeasures(pivot);
12749
- const top = firstValues && layout2 !== "tabular" && pivot.subtotals !== false && (pivot.subtotalPosition ?? "top") === "top";
12750
- const bottom = pivot.subtotals !== false && !top;
12751
- const rowLabelColumns = compact3 ? 1 : 3;
12752
- const groups = /* @__PURE__ */ new Map();
12753
- const details = /* @__PURE__ */ new Map();
12754
- const children2 = /* @__PURE__ */ new Map();
12755
- const innerIndices = new Map(secondRowItems.map((item, index3) => [pivotValueKey(item), index3]));
12756
- const buckets = /* @__PURE__ */ new Map();
12757
- const collect2 = (map, key, record) => {
12758
- const list = map.get(key);
12759
- if (list) list.push(record);
12760
- else map.set(key, [record]);
12761
- };
12762
- for (const record of pivot.records) {
12763
- const outer = pivotValueKey(record[outerField] ?? null);
12764
- const inner2 = pivotValueKey(record[innerField] ?? null);
12765
- collect2(groups, outer, record);
12766
- collect2(details, JSON.stringify([outer, inner2]), record);
12767
- if (!children2.has(outer)) children2.set(outer, /* @__PURE__ */ new Set());
12768
- children2.get(outer).add(inner2);
12769
- if (pivot.columnField) {
12770
- const column2 = pivotValueKey(record[columnField] ?? null);
12771
- for (const key of [[], [outer], [outer, inner2]])
12772
- collect2(buckets, JSON.stringify([...key, column2]), record);
12773
- }
12774
- }
12775
- const dimensions = pivotHeaderDimensions(pivot, columnItems.length, rowLabelColumns);
12776
- const rows = (details.size + rowItems.length * Number(bottom) + 1) * measures.length + rowItems.length * Number(layout2 !== "tabular") * (firstValues ? measures.length : 1) + (firstValues ? measures.length : between ? rowItems.length * measures.length : details.size) * Number(layout2 !== "tabular") + dimensions.rows;
12777
- if (rows * dimensions.width > 1e6) throw new Error("The PivotTable result is too large.");
12778
- const labels = compact3 ? ["Row Labels"] : [pivot.rowField, pivot.secondRowField];
12779
- const values2 = pivotHeaders(pivot, columnItems, labels, label2);
12780
- const firstDataRow = values2.length;
12781
- const indents = values2.map(() => 0);
12782
- const rowEntries = [];
12783
- const append = (labels2, numbers4, entry3, indent = 0) => {
12784
- values2.push([...labels2, ...numbers4]);
12785
- rowEntries.push(entry3);
12786
- indents.push(indent);
12787
- };
12788
- const bands = (keys, records) => [
12789
- ...columnItems.map(
12790
- (column2) => pivotNumbers(pivot, buckets.get(JSON.stringify([...keys, pivotValueKey(column2)])) ?? [])
12791
- ),
12792
- pivotNumbers(pivot, records)
12793
- ];
12794
- const numbers3 = (keys, records) => bands(keys, records).flat();
12795
- const appendMeasures = (labels2, keys, records, indices, type) => {
12796
- const values3 = bands(keys, records);
12797
- measures.forEach(
12798
- (measure, m) => append(
12799
- type ? [
12800
- `${type === "grand" ? "Total" : String(labels2[0])} ${measure.caption}`,
12801
- ...Array(rowLabelColumns - 1).fill(null)
12802
- ] : compact3 ? [measure.caption] : [
12803
- ...labels2.map(
12804
- (label5) => layout2 === "tabular" && m === 0 || pivot.repeatLabels ? label5 : null
12805
- ),
12806
- measure.caption
12807
- ],
12808
- values3.map((band) => band[m] ?? null),
12809
- { indices: type ? indices : [...indices, m], measure: m, ...type ? { type } : {} },
12810
- compact3 && !type ? 2 : 0
12811
- )
12812
- );
12813
- };
12814
- if (firstValues)
12815
- appendFirstPivotValues(pivot, {
12816
- rowItems,
12817
- secondRowItems,
12818
- columnItems,
12819
- children: children2,
12820
- innerIndices,
12821
- groups,
12822
- details,
12823
- buckets,
12824
- width: dimensions.width,
12825
- rowLabels: rowLabelColumns,
12826
- top,
12827
- bottom,
12828
- append
12829
- });
12830
- else
12831
- rowItems.forEach((outer, outerIndex) => {
12832
- const key = pivotValueKey(outer);
12833
- if (layout2 !== "tabular")
12834
- append(
12835
- [label2(outer), ...Array(rowLabelColumns - 1).fill(null)],
12836
- top ? numbers3([key], groups.get(key) ?? []) : Array(dimensions.width - rowLabelColumns).fill(null),
12837
- { indices: [outerIndex] }
12838
- );
12839
- let first2 = true;
12840
- const innerKeys = [...children2.get(key)].sort(
12841
- (a2, b) => innerIndices.get(a2) - innerIndices.get(b)
12842
- );
12843
- if (between)
12844
- measures.forEach((measure, m) => {
12845
- if (layout2 !== "tabular")
12846
- append(
12847
- compact3 ? [measure.caption] : [pivot.repeatLabels ? label2(outer) : null, measure.caption, null],
12848
- Array(dimensions.width - rowLabelColumns).fill(null),
12849
- { indices: [outerIndex, m], measure: m },
12850
- compact3 ? 1 : 0
12851
- );
12852
- innerKeys.forEach((innerKey, child3) => {
12853
- const innerIndex = innerIndices.get(innerKey);
12854
- const keys = [key, innerKey];
12855
- const records = details.get(JSON.stringify(keys));
12856
- append(
12857
- compact3 ? [label2(secondRowItems[innerIndex])] : [
12858
- pivot.repeatLabels || layout2 === "tabular" && m === 0 && child3 === 0 ? label2(outer) : null,
12859
- layout2 === "tabular" && child3 === 0 ? measure.caption : null,
12860
- label2(secondRowItems[innerIndex])
12861
- ],
12862
- [
12863
- ...columnItems.map(
12864
- (column2) => pivotMeasureNumber(
12865
- pivot,
12866
- buckets.get(JSON.stringify([...keys, pivotValueKey(column2)])) ?? [],
12867
- measure
12868
- )
12869
- ),
12870
- pivotMeasureNumber(pivot, records, measure)
12871
- ],
12872
- { indices: [outerIndex, m, innerIndex], measure: m },
12873
- compact3 ? 2 : 0
12874
- );
12875
- });
12876
- });
12877
- else
12878
- innerKeys.forEach((innerKey) => {
12879
- const innerIndex = innerIndices.get(innerKey);
12880
- const inner2 = secondRowItems[innerIndex];
12881
- const keys = [key, innerKey];
12882
- const records = details.get(JSON.stringify(keys));
12883
- if (!records) return;
12884
- if (layout2 !== "tabular")
12885
- append(
12886
- compact3 ? [label2(inner2)] : [pivot.repeatLabels ? label2(outer) : null, label2(inner2), null],
12887
- Array(dimensions.width - rowLabelColumns).fill(null),
12888
- { indices: [outerIndex, innerIndex] },
12889
- compact3 ? 1 : 0
12890
- );
12891
- appendMeasures(
12892
- [pivot.repeatLabels || first2 ? label2(outer) : null, label2(inner2)],
12893
- keys,
12894
- records,
12895
- [outerIndex, innerIndex]
12896
- );
12897
- first2 = false;
12898
- });
12899
- if (bottom)
12900
- appendMeasures([label2(outer)], [key], groups.get(key) ?? [], [outerIndex], "default");
12901
- });
12902
- appendMeasures([], [], pivot.records, [0], "grand");
12903
- return {
12904
- values: values2,
12905
- rowItems,
12906
- secondRowItems,
12907
- columnItems,
12908
- rowEntries,
12909
- firstDataRow,
12910
- rowLabelColumns,
12911
- indents,
12912
- firstHeaderRow: 1
12913
- };
12914
- }
12915
-
12916
- // xlsx/write/xml-out.ts
12917
- var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n';
12918
- var CONTROL = "\0-\b\v\f-" + String.fromCharCode(65534, 65535);
12919
- var NEEDS_ESCAPE = new RegExp(`[${CONTROL}\r]|_x[0-9A-Fa-f]{4}_`);
12920
- var ESCAPABLE = new RegExp(`[${CONTROL}\r]|_(?=x[0-9A-Fa-f]{4}_)`, "g");
12921
- function encodeEscapes(text4) {
12922
- if (!NEEDS_ESCAPE.test(text4)) return text4;
12923
- return text4.replace(
12924
- ESCAPABLE,
12925
- (ch) => `_x${ch.charCodeAt(0).toString(16).toUpperCase().padStart(4, "0")}_`
12926
- );
12927
- }
12928
- var INVALID_XML = new RegExp(`[${CONTROL}]`, "g");
12929
- var escapeText = (text4) => text4.replace(INVALID_XML, "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
12930
- var escapeAttr = (text4) => text4.replace(INVALID_XML, "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/\r/g, "&#13;").replace(/\n/g, "&#10;").replace(/\t/g, "&#9;");
12931
- function attrs(values2) {
12932
- let out = "";
12933
- for (const [name, value2] of Object.entries(values2)) {
12934
- if (value2 === void 0) continue;
12935
- const text4 = typeof value2 === "boolean" ? value2 ? "1" : "0" : typeof value2 === "number" ? num2(value2) : value2;
12936
- out += ` ${name}="${escapeAttr(text4)}"`;
12937
- }
12938
- return out;
12939
- }
12940
- var el = (name, values2 = {}, content2 = "") => content2 ? `<${name}${attrs(values2)}>${content2}</${name}>` : `<${name}${attrs(values2)}/>`;
12941
- var num2 = (value2) => Object.is(value2, -0) ? "0" : String(value2);
12942
- function tElement(text4, name = "t") {
12943
- const encoded = escapeText(encodeEscapes(text4));
12944
- const preserve = /^\s|\s$|\n|\t/.test(text4) ? ' xml:space="preserve"' : "";
12945
- return `<${name}${preserve}>${encoded}</${name}>`;
12946
- }
12947
- var MAIN_NS = ' xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"';
12948
- function inlineFragment(xml) {
12949
- const end = xml.indexOf(">");
12950
- if (end < 0) return xml;
12951
- const head = xml.slice(0, end);
12952
- return head.includes(MAIN_NS) ? head.replace(MAIN_NS, "") + xml.slice(end) : xml;
12953
- }
12954
12919
 
12955
12920
  // xlsx/pivot/columns.ts
12956
12921
  var SEPARATOR = "";
12957
- var label3 = pivotItemLabel;
12958
12922
  var columnKey = (keys, depth) => keys.slice(0, depth).join(SEPARATOR);
12959
12923
  var recordColumnKeys = (record, indices) => indices.map((index3) => pivotValueKey(record[index3] ?? null));
12960
12924
  function pivotColumnEntries(pivot) {
12961
12925
  const names = pivotColumnFields(pivot);
12962
12926
  const items = names.map((name) => pivotItems(pivot, name));
12963
12927
  const entries = [];
12928
+ const functions = names.map((name) => fieldSubtotalFunctions(pivot, name));
12964
12929
  if (names.length) {
12965
12930
  const order = items.map(
12966
12931
  (list) => new Map(list.map((item, index3) => [pivotValueKey(item), index3]))
@@ -12995,7 +12960,9 @@ function pivotColumnEntries(pivot) {
12995
12960
  if (level === names.length - 1) entries.push({ kind: "leaf", ...entry3 });
12996
12961
  else {
12997
12962
  visit2(child3[1], level + 1, here.path, here.values, here.keys);
12998
- entries.push({ kind: "subtotal", ...entry3 });
12963
+ const own = functions[level];
12964
+ if (own === "auto") entries.push({ kind: "subtotal", ...entry3 });
12965
+ else for (const fn of own) entries.push({ kind: "subtotal", ...entry3, fn });
12999
12966
  }
13000
12967
  }
13001
12968
  };
@@ -13004,26 +12971,31 @@ function pivotColumnEntries(pivot) {
13004
12971
  entries.push({ kind: "grand", path: [], key: "", values: [] });
13005
12972
  return { names, items, entries };
13006
12973
  }
13007
- function pivotColumnDimensions(pivot, columns, labelColumns) {
13008
- const measures = 1 + (pivot.additionalValues?.length ?? 0);
12974
+ function pivotColumnDimensions(pivot, columns, labelColumns, valuesOnRows = false) {
12975
+ const measures = valuesOnRows ? 1 : 1 + (pivot.additionalValues?.length ?? 0);
13009
12976
  const levels = columns.names.length;
13010
12977
  return {
13011
12978
  rows: (levels ? levels + 1 + Number(measures > 1) : 1) + (pivot.pageFilter ? 2 : 0),
13012
12979
  width: labelColumns + (levels ? columns.entries.length : 1) * measures
13013
12980
  };
13014
12981
  }
13015
- function pivotColumnHeaders(pivot, columns, rowLabels) {
13016
- const measures = pivotMeasures(pivot);
12982
+ function pivotColumnHeaders(pivot, columns, rowLabels, valuesOnRows = false) {
12983
+ const measures = valuesOnRows ? pivotMeasures(pivot).slice(0, 1) : pivotMeasures(pivot);
13017
12984
  const count2 = measures.length;
13018
12985
  const levels = columns.names.length;
13019
- if (!levels) return [[...rowLabels, ...measures.map((measure) => measure.caption)]];
12986
+ if (!levels)
12987
+ return [
12988
+ [...rowLabels, ...valuesOnRows ? [null] : measures.map((measure) => measure.caption)]
12989
+ ];
13020
12990
  const compact3 = pivot.layout === "compact";
13021
12991
  const labelColumns = rowLabels.length;
13022
12992
  const width = labelColumns + columns.entries.length * count2;
13023
12993
  const rows = levels + 1 + Number(count2 > 1);
13024
12994
  const grid = Array.from({ length: rows }, () => Array(width).fill(null));
13025
- if (count2 === 1) grid[0][0] = pivot.valueCaption;
13026
- const titles = compact3 ? ["Column Labels"] : [...columns.names, ...count2 > 1 ? ["Values"] : []];
12995
+ if (count2 === 1 && !valuesOnRows) grid[0][0] = pivot.valueCaption;
12996
+ const caps = pivotCaptions(pivot);
12997
+ const labelOf = pivotItemLabeler(pivot);
12998
+ const titles = compact3 ? [caps.columnLabels] : [...columns.names, ...count2 > 1 ? [caps.values] : []];
13027
12999
  titles.forEach((title, i2) => {
13028
13000
  grid[0][labelColumns + i2] = title;
13029
13001
  });
@@ -13036,16 +13008,17 @@ function pivotColumnHeaders(pivot, columns, rowLabels) {
13036
13008
  if (entry3.kind === "leaf") {
13037
13009
  entry3.path.forEach((_index, level) => {
13038
13010
  const continued = entry3.path.slice(0, level + 1).every((p, i2) => p === previous[i2]);
13039
- if (!continued) grid[1 + level][at] = label3(entry3.values[level]);
13011
+ if (!continued) grid[1 + level][at] = labelOf(columns.names[level], entry3.values[level]);
13040
13012
  });
13041
13013
  previous = entry3.path;
13042
13014
  if (count2 > 1) measures.forEach((measure, m) => grid[rows - 1][at + m] = measure.caption);
13043
13015
  return;
13044
13016
  }
13045
13017
  const row2 = entry3.kind === "grand" ? 1 : entry3.path.length;
13046
- const name = entry3.kind === "grand" ? "" : String(label3(entry3.values.at(-1)));
13018
+ const name = entry3.kind === "grand" ? "" : String(labelOf(columns.names[entry3.path.length - 1], entry3.values.at(-1)));
13047
13019
  measures.forEach((measure, m) => {
13048
- grid[row2][at + m] = count2 === 1 ? entry3.kind === "grand" ? "Grand Total" : `${name} Total` : entry3.kind === "grand" ? `Total ${measure.caption}` : `${name} ${measure.caption}`;
13020
+ const custom = entry3.fn ? caps.functions[entry3.fn] : void 0;
13021
+ grid[row2][at + m] = custom ? count2 === 1 ? `${name} ${custom}` : `${name} ${custom} of ${measure.field}` : count2 === 1 ? entry3.kind === "grand" ? caps.grandTotal : fillCaption(caps.subtotal, name) : entry3.kind === "grand" ? fillCaption(caps.measureTotal, measure.caption) : `${name} ${measure.caption}`;
13049
13022
  });
13050
13023
  });
13051
13024
  return grid;
@@ -13070,7 +13043,7 @@ function pivotColumnItemsXml(entries, measures, remap) {
13070
13043
  const prefix = sharedPrefix(path2, previous);
13071
13044
  const xs = path2.slice(prefix).map((index3) => `<x${attrs({ v: index3 || void 0 })}/>`);
13072
13045
  out.push(
13073
- `<i${attrs({ t: entry3.kind === "subtotal" ? "default" : void 0, r: prefix || void 0, i: m || void 0 })}>${xs.join("")}</i>`
13046
+ `<i${attrs({ t: entry3.kind === "subtotal" ? entry3.fn ? PIVOT_SUBTOTALS[entry3.fn].item : "default" : void 0, r: prefix || void 0, i: m || void 0 })}>${xs.join("")}</i>`
13074
13047
  );
13075
13048
  previous = path2;
13076
13049
  }
@@ -13078,7 +13051,6 @@ function pivotColumnItemsXml(entries, measures, remap) {
13078
13051
  }
13079
13052
 
13080
13053
  // xlsx/pivot/nested.ts
13081
- var label4 = pivotItemLabel;
13082
13054
  var MAX_CELLS = 1e6;
13083
13055
  var node = (index3, value2) => ({
13084
13056
  index: index3,
@@ -13090,6 +13062,10 @@ var node = (index3, value2) => ({
13090
13062
  function nestedPivotGrid(pivot) {
13091
13063
  const names = pivotRowFields(pivot);
13092
13064
  const depth = names.length;
13065
+ const valuesAt = pivotValuesIndex(pivot);
13066
+ const onRows = valuesAt >= 0;
13067
+ const levels = depth + (onRows ? 1 : 0);
13068
+ const fieldOf = (level) => !onRows || level < valuesAt ? level : level === valuesAt ? -1 : level - 1;
13093
13069
  const axisItems = names.map((name) => pivotItems(pivot, name));
13094
13070
  const itemIndices = axisItems.map(
13095
13071
  (items) => new Map(items.map((item, index3) => [pivotValueKey(item), index3]))
@@ -13101,125 +13077,170 @@ function nestedPivotGrid(pivot) {
13101
13077
  const compact3 = layout2 === "compact";
13102
13078
  const tabular = layout2 === "tabular";
13103
13079
  const above = !tabular && (pivot.subtotalPosition ?? "top") === "top";
13104
- const labelColumns = compact3 ? 1 : depth;
13080
+ const labelColumns = compact3 ? 1 : levels;
13105
13081
  const measures = pivotMeasures(pivot);
13082
+ const functions = names.map((name) => fieldSubtotalFunctions(pivot, name));
13083
+ const caps = pivotCaptions(pivot);
13084
+ const labelOf = pivotItemLabeler(pivot);
13106
13085
  const root = node(0, null);
13107
13086
  for (const record of pivot.records) {
13108
13087
  const keys = recordColumnKeys(record, columnFields);
13109
13088
  let current = root;
13110
- for (let level = -1; level < depth; level++) {
13111
- if (level >= 0) {
13112
- const value2 = record[fieldIndices[level]] ?? null;
13089
+ for (let field = -1; field < depth; field++) {
13090
+ if (field >= 0) {
13091
+ const value2 = record[fieldIndices[field]] ?? null;
13113
13092
  const key = pivotValueKey(value2);
13114
13093
  let child3 = current.children.get(key);
13115
13094
  if (!child3) {
13116
- child3 = node(itemIndices[level].get(key), value2);
13095
+ child3 = node(itemIndices[field].get(key), value2);
13117
13096
  current.children.set(key, child3);
13118
13097
  }
13119
13098
  current = child3;
13120
13099
  }
13121
13100
  current.records.push(record);
13122
- for (let width = 1; width <= keys.length; width++) {
13123
- const key = columnKey(keys, width);
13101
+ for (let width2 = 1; width2 <= keys.length; width2++) {
13102
+ const key = columnKey(keys, width2);
13124
13103
  const list = current.columns.get(key);
13125
13104
  if (list) list.push(record);
13126
13105
  else current.columns.set(key, [record]);
13127
13106
  }
13128
13107
  }
13129
13108
  }
13130
- const dimensions = pivotColumnDimensions(pivot, columns, labelColumns);
13131
- const functions = names.map((name) => fieldSubtotalFunctions(pivot, name));
13132
- let rows = 1;
13133
- const count2 = (parent, level) => {
13134
- for (const child3 of parent.children.values()) {
13135
- rows++;
13136
- if (level < depth - 1) {
13137
- const f6 = functions[level];
13138
- rows += f6 === "auto" ? 1 : f6.length;
13139
- count2(child3, level + 1);
13140
- }
13141
- }
13142
- };
13143
- count2(root, 0);
13144
- if ((rows + dimensions.rows) * dimensions.width > MAX_CELLS)
13145
- throw new Error("The PivotTable result is too large.");
13146
- const values2 = pivotColumnHeaders(pivot, columns, compact3 ? ["Row Labels"] : names);
13147
- const firstDataRow = values2.length;
13148
- const indents = values2.map(() => 0);
13109
+ const dimensions = pivotColumnDimensions(pivot, columns, labelColumns, onRows);
13110
+ const rowTitles = names.map((name) => name);
13111
+ if (onRows) rowTitles.splice(valuesAt, 0, caps.values);
13112
+ let values2 = [];
13113
+ let indents = [];
13149
13114
  const rowEntries = [];
13150
- const blanks = () => Array(dimensions.width - labelColumns).fill(null);
13151
- const bands = (group, run2) => columns.entries.flatMap(
13152
- (entry3) => run2(entry3.kind === "grand" ? group.records : group.columns.get(entry3.key) ?? [])
13153
- );
13154
- const numbers3 = (group) => bands(group, (records) => pivotNumbers(pivot, records));
13155
- const subtotalNumbers = (group, fn) => bands(
13156
- group,
13157
- (records) => measures.map((measure) => aggregateValues(records, pivot.fields.indexOf(measure.field), fn))
13158
- );
13159
- const labelCells = (path2, shown, text4) => {
13115
+ let counting = true;
13116
+ let rowCount = 0;
13117
+ const width = dimensions.width - labelColumns;
13118
+ const blanks = () => Array(width).fill(null);
13119
+ const cells = (group, rowFn, measure) => columns.entries.flatMap((entry3) => {
13120
+ const records = entry3.kind === "grand" ? group.records : group.columns.get(entry3.key) ?? [];
13121
+ const picked = measure === void 0 ? measures : [measures[measure]];
13122
+ if (rowFn && entry3.fn && rowFn !== entry3.fn) return picked.map(() => null);
13123
+ const fn = rowFn ?? entry3.fn;
13124
+ return picked.map(
13125
+ (one2) => fn ? aggregateValues(records, pivot.fields.indexOf(one2.field), fn) : pivotMeasureNumber(pivot, records, one2)
13126
+ );
13127
+ });
13128
+ const labelCells = (path2, shown, level, text4) => {
13160
13129
  if (compact3) return [text4];
13161
- const cells = Array(depth).fill(null);
13162
- path2.forEach((value2, level) => {
13163
- if (shown[level]) cells[level] = label4(value2);
13130
+ const row2 = Array(levels).fill(null);
13131
+ path2.labels.forEach((value2, at) => {
13132
+ if (shown[at]) row2[at] = value2;
13164
13133
  });
13165
- cells[path2.length] = text4;
13166
- return cells;
13134
+ row2[level] = text4;
13135
+ return row2;
13167
13136
  };
13168
- const push3 = (cells, numbersOnRow, entry3, indent) => {
13169
- values2.push([...cells, ...numbersOnRow]);
13137
+ const push3 = (indent, build3) => {
13138
+ if (counting) {
13139
+ if ((++rowCount + dimensions.rows) * dimensions.width > MAX_CELLS)
13140
+ throw new Error("The PivotTable result is too large.");
13141
+ return;
13142
+ }
13143
+ const [cells2, numbers3, entry3] = build3();
13144
+ values2.push([...cells2, ...numbers3]);
13170
13145
  rowEntries.push(entry3);
13171
13146
  indents.push(compact3 ? indent : 0);
13172
13147
  };
13173
- const emit = (parent, level, path2, indices, firsts) => {
13174
- const last = level === depth - 1;
13175
- const own = functions[level];
13176
- const children2 = [...parent.children.values()].sort((a2, b) => a2.index - b.index);
13148
+ const entryOf = (indices, measure, type) => ({
13149
+ indices,
13150
+ ...measure !== void 0 ? { measure } : {},
13151
+ ...type ? { type } : {}
13152
+ });
13153
+ const walk = (level, group, measure, path2) => {
13154
+ const field = fieldOf(level);
13155
+ const last = level === levels - 1;
13156
+ const repeated = Array.from(
13157
+ { length: level },
13158
+ (_v, k) => !!pivot.repeatLabels && fieldOf(k) >= 0
13159
+ );
13160
+ const leafShown = (firsts) => repeated.map((repeat, k) => repeat || tabular && firsts.slice(k + 1).every(Boolean));
13161
+ if (field < 0) {
13162
+ measures.forEach((one2, m) => {
13163
+ const here = {
13164
+ labels: [...path2.labels, one2.caption],
13165
+ indices: [...path2.indices, m],
13166
+ firsts: [...path2.firsts, m === 0]
13167
+ };
13168
+ if (last)
13169
+ return push3(level, () => [
13170
+ labelCells(path2, leafShown(here.firsts), level, one2.caption),
13171
+ cells(group, void 0, m),
13172
+ entryOf(here.indices, m)
13173
+ ]);
13174
+ if (!tabular)
13175
+ push3(level, () => [
13176
+ labelCells(path2, repeated, level, one2.caption),
13177
+ blanks(),
13178
+ entryOf(here.indices, m)
13179
+ ]);
13180
+ walk(level + 1, group, m, here);
13181
+ });
13182
+ return;
13183
+ }
13184
+ const own = functions[field];
13185
+ const valuesAbove = !onRows || valuesAt < level;
13186
+ const showsValue = above && own === "auto" && valuesAbove;
13187
+ const children2 = [...group.children.values()].sort((a2, b) => a2.index - b.index);
13177
13188
  children2.forEach((child3, position) => {
13178
- const here = [...path2, child3.value];
13179
- const at = [...indices, child3.index];
13180
- const firstHere = [...firsts, position === 0];
13181
- const repeated = Array(level).fill(!!pivot.repeatLabels);
13182
- if (last) {
13183
- const shown = repeated.map(
13184
- (repeat, k) => repeat || tabular && firstHere.slice(k + 1).every(Boolean)
13185
- );
13186
- push3(labelCells(path2, shown, label4(child3.value)), numbers3(child3), { indices: at }, level);
13187
- return;
13188
- }
13189
+ const here = {
13190
+ labels: [...path2.labels, labelOf(names[field], child3.value)],
13191
+ indices: [...path2.indices, child3.index],
13192
+ firsts: [...path2.firsts, position === 0]
13193
+ };
13194
+ const text4 = labelOf(names[field], child3.value);
13195
+ if (last)
13196
+ return push3(level, () => [
13197
+ labelCells(path2, leafShown(here.firsts), level, text4),
13198
+ cells(child3, void 0, measure),
13199
+ entryOf(here.indices, measure)
13200
+ ]);
13189
13201
  if (!tabular)
13190
- push3(
13191
- labelCells(path2, repeated, label4(child3.value)),
13192
- own === "auto" && above ? numbers3(child3) : blanks(),
13193
- { indices: at },
13194
- level
13195
- );
13196
- emit(child3, level + 1, here, at, firstHere);
13197
- const caption = String(label4(child3.value));
13202
+ push3(level, () => [
13203
+ labelCells(path2, repeated, level, text4),
13204
+ showsValue ? cells(child3, void 0, measure) : blanks(),
13205
+ entryOf(here.indices, measure)
13206
+ ]);
13207
+ walk(level + 1, child3, measure, here);
13208
+ if (field === depth - 1) return;
13209
+ const caption = String(text4);
13210
+ const subtotal = (title, fn, one2) => push3(level, () => [
13211
+ labelCells(path2, repeated, level, title),
13212
+ cells(child3, fn, one2),
13213
+ entryOf(here.indices, one2, fn ?? "default")
13214
+ ]);
13198
13215
  if (own === "auto") {
13199
- if (!above)
13200
- push3(
13201
- labelCells(path2, repeated, `${caption} Total`),
13202
- numbers3(child3),
13203
- { indices: at, type: "default" },
13204
- level
13205
- );
13216
+ if (showsValue) return;
13217
+ if (valuesAbove) subtotal(fillCaption(caps.subtotal, caption), void 0, measure);
13218
+ else measures.forEach((one2, m) => subtotal(`${caption} ${one2.caption}`, void 0, m));
13206
13219
  } else
13207
13220
  for (const fn of own)
13208
- push3(
13209
- labelCells(path2, repeated, `${caption} ${PIVOT_SUBTOTALS[fn].label}`),
13210
- subtotalNumbers(child3, fn),
13211
- { indices: at, type: fn },
13212
- level
13213
- );
13221
+ if (valuesAbove) subtotal(`${caption} ${caps.functions[fn]}`, fn, measure);
13222
+ else
13223
+ measures.forEach(
13224
+ (one2, m) => subtotal(`${caption} ${caps.functions[fn]} of ${one2.field}`, fn, m)
13225
+ );
13214
13226
  });
13215
13227
  };
13216
- emit(root, 0, [], [], []);
13217
- push3(
13218
- compact3 ? ["Grand Total"] : ["Grand Total", ...Array(depth - 1).fill(null)],
13219
- numbers3(root),
13220
- { indices: [0], type: "grand" },
13221
- 0
13222
- );
13228
+ const grand = (text4, measure) => push3(0, () => [
13229
+ compact3 ? [text4] : [text4, ...Array(levels - 1).fill(null)],
13230
+ cells(root, void 0, measure),
13231
+ entryOf([0], measure, "grand")
13232
+ ]);
13233
+ const build2 = () => {
13234
+ walk(0, root, void 0, { labels: [], indices: [], firsts: [] });
13235
+ if (onRows) measures.forEach((one2, m) => grand(fillCaption(caps.measureTotal, one2.caption), m));
13236
+ else grand(caps.grandTotal);
13237
+ };
13238
+ build2();
13239
+ counting = false;
13240
+ values2 = pivotColumnHeaders(pivot, columns, compact3 ? [caps.rowLabels] : rowTitles, onRows);
13241
+ const firstDataRow = values2.length;
13242
+ indents = values2.map(() => 0);
13243
+ build2();
13223
13244
  return {
13224
13245
  values: values2,
13225
13246
  rowItems: axisItems[0],
@@ -13231,105 +13252,15 @@ function nestedPivotGrid(pivot) {
13231
13252
  rowEntries,
13232
13253
  firstDataRow,
13233
13254
  rowLabelColumns: labelColumns,
13234
- indents
13255
+ indents,
13256
+ ...onRows ? { firstHeaderRow: 1 } : {}
13235
13257
  };
13236
13258
  }
13237
13259
 
13238
13260
  // xlsx/pivot/aggregate.ts
13239
13261
  function pivotGrid(pivot) {
13240
13262
  validatePivotFields(pivot);
13241
- return prependPivotPage(pivotDataGrid(pivotPageProjection(pivot)), pivot);
13242
- }
13243
- function pivotDataGrid(pivot) {
13244
- if (pivot.valuesAxis !== "rows") return nestedPivotGrid(pivot);
13245
- if (pivot.secondRowField) return hierarchicalPivotGrid(pivot);
13246
- const rowItems = pivotItems(pivot, pivot.rowField);
13247
- const columnItems = pivot.columnField ? pivotItems(pivot, pivot.columnField) : [];
13248
- const compact3 = pivot.layout === "compact";
13249
- const headings = pivot.layout !== void 0 && pivot.layout !== "tabular";
13250
- const dimensions = pivotHeaderDimensions(pivot, columnItems.length, compact3 ? 1 : 2);
13251
- const dataRows = (rowItems.length + 1) * (1 + (pivot.additionalValues?.length ?? 0)) + (headings ? rowItems.length : 0);
13252
- if ((dataRows + dimensions.rows) * dimensions.width > 1e6)
13253
- throw new Error("The PivotTable result is too large.");
13254
- const label5 = pivotItemLabel;
13255
- const values2 = pivotHeaders(pivot, columnItems, [compact3 ? "Row Labels" : pivot.rowField], label5);
13256
- const rowField = pivot.fields.indexOf(pivot.rowField);
13257
- const colField = pivot.columnField ? pivot.fields.indexOf(pivot.columnField) : -1;
13258
- const groups = /* @__PURE__ */ new Map();
13259
- const cells = /* @__PURE__ */ new Map();
13260
- const columns = /* @__PURE__ */ new Map();
13261
- const collect2 = (map, key, record) => {
13262
- const found = map.get(key);
13263
- if (found) found.push(record);
13264
- else map.set(key, [record]);
13265
- };
13266
- for (const record of pivot.records) {
13267
- const key = pivotValueKey(record[rowField] ?? null);
13268
- collect2(groups, key, record);
13269
- if (pivot.columnField) {
13270
- const col = pivotValueKey(record[colField] ?? null);
13271
- collect2(columns, col, record);
13272
- collect2(cells, JSON.stringify([key, col]), record);
13273
- }
13274
- }
13275
- const firstDataRow = values2.length;
13276
- const measures = pivotMeasures(pivot);
13277
- const rowEntries = [];
13278
- const indents = values2.map(() => 0);
13279
- const append = (caption, bands, index3, grand = false) => {
13280
- measures.forEach((measure, m) => {
13281
- values2.push([
13282
- ...compact3 ? [grand ? `Total ${measure.caption}` : measure.caption] : [
13283
- grand ? `Total ${measure.caption}` : pivot.repeatLabels || !headings && m === 0 ? caption : null,
13284
- grand ? null : measure.caption
13285
- ],
13286
- ...bands.map((band) => band[m] ?? null)
13287
- ]);
13288
- indents.push(compact3 && !grand ? 1 : 0);
13289
- rowEntries.push({
13290
- indices: grand ? [0] : [index3, m],
13291
- measure: m,
13292
- ...grand ? { type: "grand" } : {}
13293
- });
13294
- });
13295
- };
13296
- rowItems.forEach((item, index3) => {
13297
- const key = pivotValueKey(item);
13298
- if (headings) {
13299
- values2.push([label5(item), ...Array(dimensions.width - 1).fill(null)]);
13300
- rowEntries.push({ indices: [index3] });
13301
- indents.push(0);
13302
- }
13303
- append(
13304
- label5(item),
13305
- [
13306
- ...columnItems.map(
13307
- (col) => pivotNumbers(pivot, cells.get(JSON.stringify([key, pivotValueKey(col)])) ?? [])
13308
- ),
13309
- pivotNumbers(pivot, groups.get(key) ?? [])
13310
- ],
13311
- index3
13312
- );
13313
- });
13314
- append(
13315
- "Grand Total",
13316
- [
13317
- ...columnItems.map((col) => pivotNumbers(pivot, columns.get(pivotValueKey(col)) ?? [])),
13318
- pivotNumbers(pivot, pivot.records)
13319
- ],
13320
- 0,
13321
- true
13322
- );
13323
- return {
13324
- values: values2,
13325
- rowItems,
13326
- columnItems,
13327
- firstDataRow,
13328
- rowLabelColumns: compact3 ? 1 : 2,
13329
- indents,
13330
- firstHeaderRow: 1,
13331
- rowEntries
13332
- };
13263
+ return prependPivotPage(nestedPivotGrid(pivotPageProjection(pivot)), pivot);
13333
13264
  }
13334
13265
  function pivotTableAt(sheet, at) {
13335
13266
  return sheet.pivotTables?.find((pivot) => rangeContains(pivot.location, at));
@@ -13442,7 +13373,7 @@ function headerMode(args, i2, ctx, firstRow) {
13442
13373
  if (mode === 1 || mode === 3) return true;
13443
13374
  return fail(ERR.VALUE);
13444
13375
  }
13445
- var keyOf = (values2) => JSON.stringify(values2);
13376
+ var keyOf2 = (values2) => JSON.stringify(values2);
13446
13377
  var plain2 = (v) => v === void 0 || isError(v) ? null : v;
13447
13378
  function compareBy(keys, rows) {
13448
13379
  return (a2, b) => {
@@ -13482,12 +13413,12 @@ function groupby(args, ctx) {
13482
13413
  if (rows.length === 0) fail(ERR.CALC);
13483
13414
  const groups = /* @__PURE__ */ new Map();
13484
13415
  for (const r of rows) {
13485
- const key = keyOf(keysM.data[r]);
13416
+ const key = keyOf2(keysM.data[r]);
13486
13417
  const found = groups.get(key);
13487
13418
  if (found) found.push(r);
13488
13419
  else groups.set(key, [r]);
13489
13420
  }
13490
- const table2 = [...groups.values()].map((members) => {
13421
+ const table3 = [...groups.values()].map((members) => {
13491
13422
  const key = keysM.data[members[0]];
13492
13423
  const cells = Array.from(
13493
13424
  { length: vCols },
@@ -13499,8 +13430,8 @@ function groupby(args, ctx) {
13499
13430
  return [...key, ...cells];
13500
13431
  });
13501
13432
  for (const key of sort2) if (Math.abs(key) > kCols + vCols) fail(ERR.VALUE);
13502
- const order = table2.map((_, i2) => i2).sort(compareBy(sort2, table2));
13503
- const out = order.map((i2) => table2[i2]);
13433
+ const order = table3.map((_, i2) => i2).sort(compareBy(sort2, table3));
13434
+ const out = order.map((i2) => table3[i2]);
13504
13435
  if (depth !== 0) {
13505
13436
  const total2 = [
13506
13437
  "Total",
@@ -13549,8 +13480,8 @@ function pivotby(args, ctx) {
13549
13480
  const colKeys = /* @__PURE__ */ new Map();
13550
13481
  for (const r of used) {
13551
13482
  for (const [map, key] of [
13552
- [rowKeys, keyOf(rowsM.data[r])],
13553
- [colKeys, keyOf(colsM.data[r])]
13483
+ [rowKeys, keyOf2(rowsM.data[r])],
13484
+ [colKeys, keyOf2(colsM.data[r])]
13554
13485
  ]) {
13555
13486
  const found = map.get(key);
13556
13487
  if (found) found.push(r);
@@ -14283,8 +14214,8 @@ function resolveName(node2, frame) {
14283
14214
  const value2 = evaluateDefinedName(node2.name, sheet, node2.prefix !== void 0, frame);
14284
14215
  if (value2 !== void 0) return value2;
14285
14216
  if (!node2.prefix) {
14286
- const table2 = resolveStructured({ table: node2.name, specials: [] }, frame);
14287
- if (!(isError(table2) && table2.error === "#NAME?")) return table2;
14217
+ const table3 = resolveStructured({ table: node2.name, specials: [] }, frame);
14218
+ if (!(isError(table3) && table3.error === "#NAME?")) return table3;
14288
14219
  }
14289
14220
  return ERR.NAME;
14290
14221
  }
@@ -16182,8 +16113,8 @@ function deleteSheetInFormula(formula, sheetName, tableNames = []) {
16182
16113
  for (const token of tokens2) {
16183
16114
  const prefix = token.prefix;
16184
16115
  const onSheet = prefix !== void 0 && prefix.book === void 0 && prefix.sheet2 === void 0 && same2(prefix.sheet, sheetName);
16185
- const table2 = typeof token.value === "string" && tables.has(token.value.toLowerCase()) && (token.kind === "structured" || token.kind === "name" && !prefix);
16186
- if ((token.kind === "ref" || token.kind === "name") && onSheet || table2) {
16116
+ const table3 = typeof token.value === "string" && tables.has(token.value.toLowerCase()) && (token.kind === "structured" || token.kind === "name" && !prefix);
16117
+ if ((token.kind === "ref" || token.kind === "name") && onSheet || table3) {
16187
16118
  token.text = "#REF!";
16188
16119
  changed = true;
16189
16120
  }
@@ -16246,11 +16177,11 @@ function renameTableColumnInFormula(formula, tableName, oldName, newName, inside
16246
16177
  // xlsx/formula/structured-to-a1.ts
16247
16178
  var abs = (row2, col, rowAbs = true) => `$${columnLabel(col)}${rowAbs ? "$" : ""}${row2 + 1}`;
16248
16179
  function a1For(ref, t) {
16249
- const { table: table2 } = t;
16250
- const { start, end } = table2.range;
16180
+ const { table: table3 } = t;
16181
+ const { start, end } = table3.range;
16251
16182
  const index3 = (name) => {
16252
16183
  if (name === void 0) return void 0;
16253
- const i2 = table2.columns.findIndex((c3) => c3.name.toLowerCase() === name.toLowerCase());
16184
+ const i2 = table3.columns.findIndex((c3) => c3.name.toLowerCase() === name.toLowerCase());
16254
16185
  return i2 < 0 ? -1 : start.col + i2;
16255
16186
  };
16256
16187
  const c1 = index3(ref.column);
@@ -16258,10 +16189,10 @@ function a1For(ref, t) {
16258
16189
  if (c1 === -1 || c2 === -1) return "#REF!";
16259
16190
  const colLo = c1 ?? start.col;
16260
16191
  const colHi = c2 ?? end.col;
16261
- const headerRow = table2.headerRow ? start.row : void 0;
16262
- const totalsRow = table2.totalsRow ? end.row : void 0;
16263
- const dataLo = start.row + (table2.headerRow ? 1 : 0);
16264
- const dataHi = end.row - (table2.totalsRow ? 1 : 0);
16192
+ const headerRow = table3.headerRow ? start.row : void 0;
16193
+ const totalsRow = table3.totalsRow ? end.row : void 0;
16194
+ const dataLo = start.row + (table3.headerRow ? 1 : 0);
16195
+ const dataHi = end.row - (table3.totalsRow ? 1 : 0);
16265
16196
  const specials = new Set(ref.specials);
16266
16197
  let rowLo;
16267
16198
  let rowHi;
@@ -17400,14 +17331,14 @@ function descendants(root, local, ns) {
17400
17331
  var X14 = "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main";
17401
17332
  var LAYOUT = "http://schemas.microsoft.com/office/spreadsheetml/2016/pivotdefaultlayout";
17402
17333
  var TABLE = {
17403
- pivotTableDefinition: "name cacheId dataCaption dataOnRows dataPosition updatedVersion minRefreshableVersion createdVersion applyNumberFormats applyBorderFormats applyFontFormats applyPatternFormats applyAlignmentFormats applyWidthHeightFormats useAutoFormatting itemPrintTitles indent compact compactData outline outlineData multipleFieldFilters rowGrandTotals colGrandTotals",
17334
+ pivotTableDefinition: "name cacheId dataCaption grandTotalCaption rowHeaderCaption colHeaderCaption dataOnRows dataPosition updatedVersion minRefreshableVersion createdVersion applyNumberFormats applyBorderFormats applyFontFormats applyPatternFormats applyAlignmentFormats applyWidthHeightFormats useAutoFormatting itemPrintTitles indent compact compactData outline outlineData multipleFieldFilters rowGrandTotals colGrandTotals",
17404
17335
  location: "ref firstHeaderRow firstDataRow firstDataCol rowPageCount colPageCount",
17405
17336
  pageFields: "count",
17406
17337
  pageField: "fld item hier",
17407
17338
  pivotFields: "count",
17408
17339
  pivotField: "axis dataField compact outline showAll subtotalTop defaultSubtotal numFmtId sumSubtotal countASubtotal avgSubtotal maxSubtotal minSubtotal productSubtotal countSubtotal stdDevSubtotal stdDevPSubtotal varSubtotal varPSubtotal",
17409
17340
  items: "count",
17410
- item: "x t h",
17341
+ item: "x t h n",
17411
17342
  rowFields: "count",
17412
17343
  colFields: "count",
17413
17344
  field: "x",
@@ -17508,8 +17439,8 @@ function inspect(node2, profile, cache3) {
17508
17439
  }
17509
17440
  for (const child3 of elements(node2)) inspect(child3, profile, cache3);
17510
17441
  }
17511
- function assertPivotAdmission(table2, cache3) {
17512
- inspect(table2, TABLE, false);
17442
+ function assertPivotAdmission(table3, cache3) {
17443
+ inspect(table3, TABLE, false);
17513
17444
  inspect(cache3, CACHE, true);
17514
17445
  }
17515
17446
  function assertPivotRecords(records) {
@@ -17520,6 +17451,121 @@ function assertPivotRecords(records) {
17520
17451
  );
17521
17452
  }
17522
17453
 
17454
+ // xlsx/pivot/captions-read.ts
17455
+ var ATTRIBUTES = {
17456
+ rowHeaderCaption: "rowLabels",
17457
+ colHeaderCaption: "columnLabels",
17458
+ grandTotalCaption: "grandTotal",
17459
+ dataCaption: "values"
17460
+ };
17461
+ function readPivotCaptionAttributes(root) {
17462
+ const out = {};
17463
+ for (const [attribute2, key] of Object.entries(ATTRIBUTES)) {
17464
+ const text4 = att(root, attribute2);
17465
+ if (text4 !== void 0)
17466
+ out[key] = decodeEscapes(text4);
17467
+ }
17468
+ return out;
17469
+ }
17470
+ function aggregateCaptionsOf(pivot) {
17471
+ const out = {};
17472
+ for (const measure of [
17473
+ { field: pivot.valueField, aggregate: pivot.aggregate, caption: pivot.valueCaption },
17474
+ ...pivot.additionalValues ?? []
17475
+ ]) {
17476
+ const at = measure.caption.indexOf(measure.field);
17477
+ if (at < 0 || measure.caption === measure.field) continue;
17478
+ const template = `${measure.caption.slice(0, at)}{0}${measure.caption.slice(at + measure.field.length)}`;
17479
+ if (template !== ENGLISH_PIVOT_CAPTIONS.aggregates[measure.aggregate])
17480
+ out[measure.aggregate] = template;
17481
+ }
17482
+ return Object.keys(out).length ? out : void 0;
17483
+ }
17484
+ var MARK = "";
17485
+ var SENTINELS = {
17486
+ rowLabels: `${MARK}R`,
17487
+ columnLabels: `${MARK}C`,
17488
+ grandTotal: `${MARK}G`,
17489
+ values: `${MARK}V`,
17490
+ all: `${MARK}A`,
17491
+ blank: `${MARK}B`,
17492
+ subtotal: `{0}${MARK}S`,
17493
+ measureTotal: `${MARK}M{0}`,
17494
+ functions: Object.fromEntries(
17495
+ Object.keys(ENGLISH_PIVOT_CAPTIONS.functions).map((fn) => [fn, `${MARK}F${fn}`])
17496
+ ),
17497
+ aggregates: ENGLISH_PIVOT_CAPTIONS.aggregates
17498
+ };
17499
+ function templateOf2(cached, arg) {
17500
+ if (!arg || !cached.includes(arg)) return void 0;
17501
+ if (cached.startsWith(arg)) return `{0}${cached.slice(arg.length)}`;
17502
+ if (cached.endsWith(arg)) return `${cached.slice(0, -arg.length)}{0}`;
17503
+ const at = cached.indexOf(arg);
17504
+ return `${cached.slice(0, at)}{0}${cached.slice(at + arg.length)}`;
17505
+ }
17506
+ function inferPivotCaptions(pivot, sheet, named2) {
17507
+ const known = pivotCaptions({ captions: named2 });
17508
+ const probe = { ...SENTINELS };
17509
+ for (const key of Object.keys(named2))
17510
+ if (typeof named2[key] === "string")
17511
+ probe[key] = known[key];
17512
+ const grid = pivotGrid({ ...pivot, captions: probe });
17513
+ const found = /* @__PURE__ */ new Map();
17514
+ const set = (key, value2) => {
17515
+ if (value2 === void 0) return;
17516
+ const before = found.get(key);
17517
+ found.set(key, before === void 0 || before === value2 ? value2 : null);
17518
+ };
17519
+ grid.values.forEach(
17520
+ (line3, r) => line3.forEach((expected, c2) => {
17521
+ if (typeof expected !== "string" || !expected.includes(MARK)) return;
17522
+ const cached = getCell(
17523
+ sheet,
17524
+ pivot.location.start.row + r,
17525
+ pivot.location.start.col + c2
17526
+ )?.value;
17527
+ if (typeof cached !== "string") return;
17528
+ const kind = /\u0001([RCGVASMFB])(\w*)/.exec(expected);
17529
+ if (!kind) return;
17530
+ const at = kind.index;
17531
+ switch (kind[1]) {
17532
+ case "R":
17533
+ return set("rowLabels", cached);
17534
+ case "C":
17535
+ return set("columnLabels", cached);
17536
+ case "G":
17537
+ return set("grandTotal", cached);
17538
+ case "V":
17539
+ return set("values", cached);
17540
+ case "A":
17541
+ return set("all", cached);
17542
+ case "B":
17543
+ return set("blank", cached);
17544
+ case "S":
17545
+ return set("subtotal", templateOf2(cached, expected.slice(0, at)));
17546
+ case "M":
17547
+ return set("measureTotal", templateOf2(cached, expected.slice(at + 2)));
17548
+ case "F": {
17549
+ const item = expected.slice(0, at - 1);
17550
+ const of = / of (.*)$/.exec(expected.slice(at));
17551
+ const word = cached.slice(item.length + 1, of ? cached.length - of[0].length : void 0);
17552
+ if (cached.startsWith(`${item} `) && (!of || cached.endsWith(of[0])))
17553
+ set(`function:${kind[2]}`, word);
17554
+ }
17555
+ }
17556
+ })
17557
+ );
17558
+ const out = pivotCaptions({ captions: named2 });
17559
+ const functions = { ...out.functions };
17560
+ for (const [key, value2] of found) {
17561
+ if (value2 === null) continue;
17562
+ if (key.startsWith("function:")) functions[key.slice(9)] = value2;
17563
+ else out[key] = value2;
17564
+ }
17565
+ out.functions = functions;
17566
+ return trimmedCaptions(out);
17567
+ }
17568
+
17523
17569
  // xlsx/slicer/read-slicers.ts
17524
17570
  var TABLE_SLICER_URI = "{2F2917AC-EB37-4324-AD4E-5DD8C200BD13}";
17525
17571
  var X152 = "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main";
@@ -17595,12 +17641,12 @@ function parseSlicerCache(xml, partName) {
17595
17641
  if (data) return void 0;
17596
17642
  const list = byLocal(root, "extLst");
17597
17643
  const ext = list ? elements(list).find((node2) => node2.getAttribute("uri") === TABLE_SLICER_URI) : void 0;
17598
- const table2 = ext ? first(ext, "tableSlicerCache", X152) : void 0;
17599
- const tableId = numAttr(table2, "tableId");
17600
- const column2 = numAttr(table2, "column");
17601
- if (!table2 || tableId === void 0 || column2 === void 0) return void 0;
17644
+ const table3 = ext ? first(ext, "tableSlicerCache", X152) : void 0;
17645
+ const tableId = numAttr(table3, "tableId");
17646
+ const column2 = numAttr(table3, "column");
17647
+ if (!table3 || tableId === void 0 || column2 === void 0) return void 0;
17602
17648
  const cache3 = { ...common, source: { kind: "table", tableId, column: column2 } };
17603
- if (att(table2, "sortOrder") === "descending") cache3.sortOrder = "descending";
17649
+ if (att(table3, "sortOrder") === "descending") cache3.sortOrder = "descending";
17604
17650
  if (elements(root).some((node2) => node2.localName === "pivotTables")) return void 0;
17605
17651
  return cache3;
17606
17652
  }
@@ -17685,14 +17731,14 @@ function parseTimelineCache(xml, partName) {
17685
17731
  }
17686
17732
 
17687
17733
  // xlsx/slicer/table-filter.ts
17688
- function tableFilterBounds(table2) {
17734
+ function tableFilterBounds(table3) {
17689
17735
  return {
17690
- start: table2.range.start,
17691
- end: { ...table2.range.end, row: table2.range.end.row - (table2.totalsRow ? 1 : 0) }
17736
+ start: table3.range.start,
17737
+ end: { ...table3.range.end, row: table3.range.end.row - (table3.totalsRow ? 1 : 0) }
17692
17738
  };
17693
17739
  }
17694
- function tableAutoFilter(table2) {
17695
- const columns = table2.columns.flatMap(
17740
+ function tableAutoFilter(table3) {
17741
+ const columns = table3.columns.flatMap(
17696
17742
  (column2, offset2) => column2.filter ? [
17697
17743
  {
17698
17744
  offset: offset2,
@@ -17702,12 +17748,12 @@ function tableAutoFilter(table2) {
17702
17748
  ] : []
17703
17749
  );
17704
17750
  if (!columns.length) return void 0;
17705
- return { range: tableFilterBounds(table2), columns };
17751
+ return { range: tableFilterBounds(table3), columns };
17706
17752
  }
17707
- function applyTableFilter(workbook, sheet, table2) {
17708
- if (!table2.headerRow) return;
17709
- const bounds = tableFilterBounds(table2);
17710
- const filter2 = tableAutoFilter(table2);
17753
+ function applyTableFilter(workbook, sheet, table3) {
17754
+ if (!table3.headerRow) return;
17755
+ const bounds = tableFilterBounds(table3);
17756
+ const filter2 = tableAutoFilter(table3);
17711
17757
  for (let row2 = bounds.start.row + 1; row2 <= bounds.end.row; row2++) {
17712
17758
  const visible = !filter2 || rowMatchesFilter(workbook, sheet, row2, filter2);
17713
17759
  setRowFiltered(sheet, row2, !visible, !!filter2);
@@ -17715,8 +17761,8 @@ function applyTableFilter(workbook, sheet, table2) {
17715
17761
  }
17716
17762
  function readTableFilteredRows(workbook) {
17717
17763
  for (const sheet of workbook.sheets)
17718
- for (const table2 of sheet.tables) {
17719
- const filter2 = tableAutoFilter(table2);
17764
+ for (const table3 of sheet.tables) {
17765
+ const filter2 = tableAutoFilter(table3);
17720
17766
  if (!filter2) continue;
17721
17767
  for (let row2 = filter2.range.start.row + 1; row2 <= filter2.range.end.row; row2++) {
17722
17768
  const info = sheet.rowInfo.get(row2);
@@ -17835,9 +17881,9 @@ function settleSlicers(workbook, warn) {
17835
17881
  if (cache3.source.kind === "table") {
17836
17882
  const { tableId, column: column2 } = cache3.source;
17837
17883
  for (const sheet of workbook.sheets) {
17838
- const table2 = sheet.tables.find((entry3) => entry3.id === tableId);
17839
- if (table2)
17840
- return table2.headerRow && !table2.filterNotModeled && table2.columns.some((entry3) => entry3.sourceId === column2);
17884
+ const table3 = sheet.tables.find((entry3) => entry3.id === tableId);
17885
+ if (table3)
17886
+ return table3.headerRow && !table3.filterNotModeled && table3.columns.some((entry3) => entry3.sourceId === column2);
17841
17887
  }
17842
17888
  return false;
17843
17889
  }
@@ -18025,7 +18071,7 @@ function readFieldGroups(fields, names) {
18025
18071
  throw new Error("Unsupported pivot field group");
18026
18072
  const labels = children(list, "s", NS.x).map((node2) => decodeEscapes(att(node2, "v") ?? ""));
18027
18073
  const expected = numberGroupLabels({ start, end, by });
18028
- if (elements(list).length !== labels.length || labels.length !== expected.length || labels.some((label5, i2) => label5 !== expected[i2]))
18074
+ if (elements(list).length !== labels.length || labels.length !== expected.length || labels.some((label2, i2) => label2 !== expected[i2]))
18029
18075
  throw new Error("Unsupported pivot group items");
18030
18076
  groups.push({ field: names[index3] ?? "", start, end, by });
18031
18077
  });
@@ -18103,14 +18149,18 @@ function readDateGroups(fields, count2, names, dateFields, records, date1904) {
18103
18149
  const expected = dateGroupRange(group, serials);
18104
18150
  if (!close(expected.start, start) || !close(expected.end, end))
18105
18151
  throw unsupported("stale range");
18152
+ const localized = {};
18106
18153
  for (const entry3 of list) {
18107
- const labels = dateUnitLabels(entry3.unit, expected, dateGroupDays(group), date1904);
18154
+ const labels = englishDateUnitLabels(entry3.unit, expected, dateGroupDays(group), date1904);
18108
18155
  const node2 = first(first(entry3.node, "fieldGroup", NS.x), "groupItems", NS.x);
18109
18156
  const actual = children(node2, "s", NS.x).map((item) => decodeEscapes(att(item, "v") ?? ""));
18110
- if (att(entry3.node, "name") === void 0 || decodeEscapes(att(entry3.node, "name")) !== dateGroupFieldName(entry3.unit, field) || elements(node2).length !== actual.length || actual.length !== labels.length || actual.some((label5, i2) => label5 !== labels[i2]))
18157
+ const name = decodeEscapes(att(entry3.node, "name") ?? "");
18158
+ if (!name || elements(node2).length !== actual.length || actual.length !== labels.length || actual.some((label2) => !label2) || new Set(actual).size !== actual.length)
18111
18159
  throw unsupported("group items");
18160
+ if (name !== dateGroupFieldName(entry3.unit, field) || actual.some((l, i2) => l !== labels[i2]))
18161
+ localized[entry3.unit] = { name, labels: actual };
18112
18162
  }
18113
- groups.push(group);
18163
+ groups.push(Object.keys(localized).length ? { ...group, localized } : group);
18114
18164
  }
18115
18165
  return groups;
18116
18166
  }
@@ -18163,12 +18213,32 @@ function readItemFilters(fields, names, shared) {
18163
18213
  return filters.length ? filters : void 0;
18164
18214
  }
18165
18215
 
18216
+ // xlsx/pivot/item-names-read.ts
18217
+ function readItemNames(tableFields, names, shared) {
18218
+ const out = [];
18219
+ tableFields.forEach((field, index3) => {
18220
+ const list = first(field, "items", NS.x);
18221
+ if (!list || index3 >= names.length) return;
18222
+ for (const item of children(list, "item", NS.x)) {
18223
+ const name = att(item, "n");
18224
+ if (name === void 0) continue;
18225
+ const at = Number(att(item, "x"));
18226
+ const value2 = shared[index3]?.[at];
18227
+ if (att(item, "t") !== void 0 || !Number.isInteger(at) || value2 === void 0)
18228
+ throw new Error("Unsupported pivot item name");
18229
+ out.push({ field: names[index3], item: value2, name: decodeEscapes(name) });
18230
+ }
18231
+ });
18232
+ return out;
18233
+ }
18234
+
18166
18235
  // xlsx/pivot/values-axis.ts
18167
18236
  function remapPivotRowEntries(entries, axes2) {
18168
18237
  return entries.map(
18169
18238
  (entry3) => entry3.type === "grand" ? entry3 : {
18170
18239
  ...entry3,
18171
18240
  indices: entry3.indices.map((item, axis) => {
18241
+ if (axes2[axis] === null) return item;
18172
18242
  const index3 = axes2[axis]?.[item];
18173
18243
  if (index3 === void 0) throw new Error("Invalid report row axis item");
18174
18244
  return index3;
@@ -18187,7 +18257,7 @@ function pivotValueIndex(root, axis) {
18187
18257
  const position = root.getAttribute("dataPosition");
18188
18258
  if (position !== null && (!/^\d+$/.test(position.trim()) || Number(position) !== index3))
18189
18259
  throw new Error("Inconsistent Values axis position");
18190
- if (axis.length === 3 && index3 >= 0 && index3 < 2 && position === null)
18260
+ if (index3 >= 0 && index3 < axis.length - 1 && position === null)
18191
18261
  throw new Error("Missing leading or between-field Values position");
18192
18262
  return index3;
18193
18263
  }
@@ -18202,7 +18272,7 @@ function pivotValueAxisItems(measures) {
18202
18272
  function supportedPivotAxes(rows, columns, measures, valuesOnRows) {
18203
18273
  const index3 = pivotFieldIndex;
18204
18274
  if (valuesOnRows)
18205
- return measures > 1 && (rows.length === 2 || rows.length === 3) && (index3(rows[0]) >= 0 || rows.length === 3) && rows.filter((field) => index3(field) === -2).length === 1 && rows.filter((field) => index3(field) !== -2).every((field) => index3(field) >= 0) && columns.length <= 1 && (!columns.length || index3(columns[0]) >= 0);
18275
+ return measures > 1 && rows.length > 1 && rows.filter((field) => index3(field) === -2).length === 1 && rows.filter((field) => index3(field) !== -2).every((field) => index3(field) >= 0) && columns.every((field) => index3(field) >= 0);
18206
18276
  if (rows.some((field) => !Number.isInteger(index3(field)) || index3(field) < 0)) return false;
18207
18277
  if (measures > 1 && (!columns.length || index3(columns.at(-1)) !== -2)) return false;
18208
18278
  return (measures > 1 ? columns.slice(0, -1) : columns).every(
@@ -18264,6 +18334,9 @@ function assertPageAxisItems(root, pivot, shared, cache3, recordRoot) {
18264
18334
  literals(cache3);
18265
18335
  literals(recordRoot);
18266
18336
  const cacheFields = children(first(cache3, "cacheFields", NS.x), "cacheField", NS.x);
18337
+ const all2 = expandDateGroups(pivot).fields;
18338
+ const derived = all2.slice(pivot.fields.length).map((name) => groupLabelsOf(pivot, name) ?? []);
18339
+ const sharedAll = [...shared, ...derived];
18267
18340
  if (pivot.columnField) {
18268
18341
  const column2 = children(first(root, "pivotFields", NS.x), "pivotField", NS.x)[pivot.fields.indexOf(pivot.columnField)];
18269
18342
  const list = first(column2, "extLst", NS.x);
@@ -18282,13 +18355,13 @@ function assertPageAxisItems(root, pivot, shared, cache3, recordRoot) {
18282
18355
  ))
18283
18356
  throw new Error("Repeated report column labels are preserved");
18284
18357
  }
18285
- if (integer(first(cache3, "cacheFields", NS.x)?.getAttribute("count") ?? null) !== pivot.fields.length || integer(cache3.getAttribute("recordCount")) !== pivot.records.length || integer(recordRoot.getAttribute("count")) !== pivot.records.length)
18358
+ if (integer(first(cache3, "cacheFields", NS.x)?.getAttribute("count") ?? null) !== all2.length || integer(cache3.getAttribute("recordCount")) !== pivot.records.length || integer(recordRoot.getAttribute("count")) !== pivot.records.length)
18286
18359
  throw new Error("Inconsistent report cache counts");
18287
18360
  for (const name of [...pivotRowFields(pivot), pivot.columnField, pivot.pageFilter.field].filter(
18288
18361
  Boolean
18289
18362
  )) {
18290
- const field = pivot.fields.indexOf(name);
18291
- if (integer(first(cacheFields[field], "sharedItems", NS.x)?.getAttribute("count") ?? null) !== shared[field].length)
18363
+ const field = all2.indexOf(name);
18364
+ if (field < pivot.fields.length && integer(first(cacheFields[field], "sharedItems", NS.x)?.getAttribute("count") ?? null) !== shared[field].length)
18292
18365
  throw new Error("Inconsistent report shared-item counts");
18293
18366
  }
18294
18367
  for (const name of ["rowFields", "colFields"]) {
@@ -18298,7 +18371,7 @@ function assertPageAxisItems(root, pivot, shared, cache3, recordRoot) {
18298
18371
  }
18299
18372
  const projected = pivotPageProjection(pivot), fields = children(first(root, "pivotFields", NS.x), "pivotField", NS.x);
18300
18373
  const axisValues = (name, axis) => {
18301
- const f6 = pivot.fields.indexOf(name), node2 = fields[f6], list = first(node2, "items", NS.x), items = children(list, "item", NS.x), count2 = shared[f6].length;
18374
+ const f6 = all2.indexOf(name), node2 = fields[f6], list = first(node2, "items", NS.x), items = children(list, "item", NS.x), count2 = sharedAll[f6].length;
18302
18375
  if (node2.getAttribute("axis") !== axis) throw new Error("Inconsistent report axis field");
18303
18376
  const defaults = node2.getAttribute("defaultSubtotal") !== "0";
18304
18377
  if (!list || integer(list.getAttribute("count")) !== items.length || items.length !== count2 + Number(defaults))
@@ -18307,7 +18380,7 @@ function assertPageAxisItems(root, pivot, shared, cache3, recordRoot) {
18307
18380
  const i2 = integer(item.getAttribute("x"));
18308
18381
  if (item.hasAttribute("t") || !Number.isInteger(i2) || i2 >= count2)
18309
18382
  throw new Error("Invalid page-axis cache item");
18310
- return shared[f6][i2];
18383
+ return sharedAll[f6][i2];
18311
18384
  });
18312
18385
  if (new Set(data.map(pivotValueKey)).size !== count2 || defaults && (items.at(-1)?.getAttribute("t") !== "default" || items.at(-1)?.hasAttribute("x")))
18313
18386
  throw new Error("Invalid page-axis default item");
@@ -18322,7 +18395,10 @@ function assertPageAxisItems(root, pivot, shared, cache3, recordRoot) {
18322
18395
  };
18323
18396
  const rowAxes = pivotRowFields(pivot).map((name) => axisValues(name, "axisRow")), rowItems = read("rowItems");
18324
18397
  const grid = pivotGrid(pivot);
18325
- const entries = grid.rowEntries ? remapPivotRowEntries(grid.rowEntries, rowAxes) : [
18398
+ const valuesAt = pivotValuesIndex(pivot);
18399
+ const levelAxes = [...rowAxes];
18400
+ if (valuesAt >= 0) levelAxes.splice(valuesAt, 0, null);
18401
+ const entries = grid.rowEntries ? remapPivotRowEntries(grid.rowEntries, levelAxes) : [
18326
18402
  ...rowAxes[0].map((index3) => ({ indices: [index3] })),
18327
18403
  { indices: [0], type: "grand" }
18328
18404
  ];
@@ -18332,11 +18408,11 @@ function assertPageAxisItems(root, pivot, shared, cache3, recordRoot) {
18332
18408
  const expected2 = entries[i2];
18333
18409
  const xs = children(item, "x", NS.x).map((x) => integer(x.getAttribute("v"), 0)), prefix = integer(item.getAttribute("r"), 0);
18334
18410
  const type = expected2.type === void 0 || expected2.type === "default" || expected2.type === "grand" ? expected2.type : PIVOT_SUBTOTALS[expected2.type].item;
18335
- if (item.getAttribute("t") !== (type ?? null) || !Number.isInteger(prefix) || prefix < 0 || prefix > previousRow.length || prefix >= expected2.indices.length || expected2.type === "grand" && prefix !== 0 || integer(item.getAttribute("i"), 0) !== 0 || JSON.stringify([...previousRow.slice(0, prefix), ...xs]) !== JSON.stringify(expected2.indices))
18411
+ if (item.getAttribute("t") !== (type ?? null) || !Number.isInteger(prefix) || prefix < 0 || prefix > previousRow.length || prefix >= expected2.indices.length || expected2.type === "grand" && prefix !== 0 || integer(item.getAttribute("i"), 0) !== (expected2.measure ?? 0) || JSON.stringify([...previousRow.slice(0, prefix), ...xs]) !== JSON.stringify(expected2.indices))
18336
18412
  throw new Error("Unmodeled page row item");
18337
18413
  previousRow = expected2.type === "grand" ? [] : expected2.indices;
18338
18414
  });
18339
- const measures = 1 + (pivot.additionalValues?.length ?? 0), columns = pivot.columnField ? axisValues(pivot.columnField, "axisCol") : void 0, expected = [];
18415
+ const measures = valuesAt >= 0 ? 1 : 1 + (pivot.additionalValues?.length ?? 0), columns = pivot.columnField ? axisValues(pivot.columnField, "axisCol") : void 0, expected = [];
18340
18416
  if (columns)
18341
18417
  for (const col of columns)
18342
18418
  for (let m = 0; m < measures; m++) expected.push(measures > 1 ? [col, m] : [col]);
@@ -18378,6 +18454,10 @@ function value(node2, date1904 = false) {
18378
18454
  if (node2.localName === "e" && isErrorCode(v)) return { error: v };
18379
18455
  throw new Error("Unsupported pivot cache item");
18380
18456
  }
18457
+ var namedAggregates = (pivot) => {
18458
+ const aggregates = aggregateCaptionsOf(pivot);
18459
+ return aggregates ? { aggregates } : {};
18460
+ };
18381
18461
  function readOne(workbook, source2, part) {
18382
18462
  const xml = source2.text(part);
18383
18463
  const root = parseXml(xml).documentElement;
@@ -18443,7 +18523,7 @@ function readOne(workbook, source2, part) {
18443
18523
  "dataField",
18444
18524
  NS.x
18445
18525
  );
18446
- if (rowFields.length < 1 || rowsAxis && rowFields.length > 3 || dataFields.length < 1 || dataFields.length > 16 || !supportedPivotAxes(rowFields, colFields, dataFields.length, rowsAxis) || root.getAttribute("rowGrandTotals") === "0" || root.getAttribute("colGrandTotals") === "0")
18526
+ if (rowFields.length < 1 || dataFields.length < 1 || dataFields.length > 16 || !supportedPivotAxes(rowFields, colFields, dataFields.length, rowsAxis) || root.getAttribute("rowGrandTotals") === "0" || root.getAttribute("colGrandTotals") === "0")
18447
18527
  throw new Error("Unsupported pivot layout");
18448
18528
  const valueIndex = pivotValueIndex(root, rowsAxis ? rowFields : colFields);
18449
18529
  const measure = dataFields[0];
@@ -18513,8 +18593,8 @@ function readOne(workbook, source2, part) {
18513
18593
  const col = columnNames[0];
18514
18594
  const moreColumns = columnNames.slice(1);
18515
18595
  const columnDefinitions = columnDefs.map((field) => tableFields[Number(att(field, "x"))]);
18516
- if (fieldSubtotalsOf(columnDefinitions.slice(0, -1), columnNames.slice(0, -1)).length || columnNames.some((name) => !name))
18517
- throw new Error("Column subtotal settings are preserved");
18596
+ if (columnNames.some((name) => !name)) throw new Error("Invalid pivot column fields");
18597
+ const columnSubtotals = fieldSubtotalsOf(columnDefinitions, columnNames);
18518
18598
  const data = names[Number(att(measure, "fld"))];
18519
18599
  const location = parseRange(att(first(root, "location", NS.x), "ref") ?? "");
18520
18600
  if (!row2 || !data || !location || hasColumn && !col || realRows.length === 2 && !second)
@@ -18524,6 +18604,7 @@ function readOne(workbook, source2, part) {
18524
18604
  location.start.row -= 2;
18525
18605
  }
18526
18606
  const itemFilters = readItemFilters(tableFields, names, shared);
18607
+ const itemNames = readItemNames(tableFields, names, shared);
18527
18608
  const slicerCacheId = readSlicerCacheId(cache3);
18528
18609
  const fieldGroups = readFieldGroups(fields, names);
18529
18610
  const dateFields = readDateFields(fields, names);
@@ -18555,11 +18636,14 @@ function readOne(workbook, source2, part) {
18555
18636
  ]);
18556
18637
  if (dateFields.some((field) => onAxis.has(field)))
18557
18638
  throw new Error("Date fields used as rows, columns or values are preserved");
18558
- if ([...realRows, ...columnDefs].some((field) => pivotFieldIndex(field) >= databaseCount) && (pageFilter || dateFilter || itemFilters || slicerCacheId !== void 0))
18559
- throw new Error("Date groups with filters are preserved");
18639
+ const fieldSubtotals = [
18640
+ ...subtotalSettings.filter((entry4) => entry4.field !== row2 || entry4.functions.length),
18641
+ ...columnSubtotals
18642
+ ];
18560
18643
  const pivot = {
18561
18644
  ...pageFilter ? { pageFilter } : {},
18562
18645
  ...itemFilters ? { itemFilters } : {},
18646
+ ...itemNames.length ? { itemNames } : {},
18563
18647
  ...fieldGroups.length ? { fieldGroups } : {},
18564
18648
  ...dateFields.length ? { dateFields } : {},
18565
18649
  ...dateGroups.length ? { dateGroups } : {},
@@ -18571,13 +18655,11 @@ function readOne(workbook, source2, part) {
18571
18655
  rowField: row2,
18572
18656
  layout: layout2,
18573
18657
  ...rowsAxis ? { valuesAxis: "rows" } : {},
18574
- ...rowsAxis && realRows.length === 2 && valueIndex < 2 ? { valuesPosition: valueIndex === 0 ? "first" : "between" } : {},
18575
- subtotalPosition: att(outer, "subtotalTop") === "0" ? "bottom" : "top",
18576
- ...subtotalSettings.some((entry4) => entry4.field !== row2 || entry4.functions.length) ? {
18577
- fieldSubtotals: subtotalSettings.filter(
18578
- (entry4) => entry4.field !== row2 || entry4.functions.length
18579
- )
18658
+ ...rowsAxis && valueIndex < realRows.length ? {
18659
+ valuesPosition: valueIndex === 0 ? "first" : valueIndex === 1 && realRows.length === 2 ? "between" : valueIndex
18580
18660
  } : {},
18661
+ subtotalPosition: att(outer, "subtotalTop") === "0" ? "bottom" : "top",
18662
+ ...fieldSubtotals.length ? { fieldSubtotals } : {},
18581
18663
  ...more.length ? { moreRowFields: more } : {},
18582
18664
  ...second ? { secondRowField: second, subtotals: subtotal, repeatLabels: repeat[0] ?? false } : {
18583
18665
  ...subtotal ? {} : { subtotals: false },
@@ -18604,6 +18686,12 @@ function readOne(workbook, source2, part) {
18604
18686
  ...col ? { columnField: col } : {},
18605
18687
  ...moreColumns.length ? { moreColumnFields: moreColumns } : {}
18606
18688
  };
18689
+ const captions = trimmedCaptions(
18690
+ pivotCaptions({
18691
+ captions: { ...readPivotCaptionAttributes(root), ...namedAggregates(pivot) }
18692
+ })
18693
+ );
18694
+ if (captions) pivot.captions = captions;
18607
18695
  if (pageFilter && moreColumns.length) throw new Error("Report filters support one column field");
18608
18696
  assertPageAxisItems(root, pivot, shared, cache3, recordRoot);
18609
18697
  return pivot;
@@ -18631,6 +18719,12 @@ function readPivotTables(workbook, source2, warn, slicers) {
18631
18719
  if (slicers.blocked.has(pivotKey(sheet.sheetId, name)) || cache3 && (caches2.get(cache3) ?? 0) > 1)
18632
18720
  throw new Error("Shared pivot cache or unsupported slicer connection");
18633
18721
  const pivot = readOne(workbook, source2, part);
18722
+ const inferred = inferPivotCaptions(pivot, sheet, {
18723
+ ...readPivotCaptionAttributes(parseXml(pivot.sourceXml).documentElement),
18724
+ ...namedAggregates(pivot)
18725
+ });
18726
+ if (inferred) pivot.captions = inferred;
18727
+ else delete pivot.captions;
18634
18728
  const grid = pivotGrid(pivot);
18635
18729
  if (grid.values.length !== pivot.location.end.row - pivot.location.start.row + 1 || grid.values[0].length !== pivot.location.end.col - pivot.location.start.col + 1 || grid.values.some(
18636
18730
  (line3, r) => line3.some(
@@ -20390,8 +20484,8 @@ function parseDiagramDataModel(source2, part) {
20390
20484
  "CONNECTION_ENDPOINT_MISSING",
20391
20485
  `dgm:cxn ${attribute2} references missing point: ${id}.`
20392
20486
  );
20393
- const label5 = connectionLabel(connection, transitionText);
20394
- connections.push(label5 ? { ...connection, label: label5 } : connection);
20487
+ const label2 = connectionLabel(connection, transitionText);
20488
+ connections.push(label2 ? { ...connection, label: label2 } : connection);
20395
20489
  if ((!connection.type || connection.type === "parOf") && !parentById.has(connection.destId))
20396
20490
  parentById.set(connection.destId, connection.sourceId);
20397
20491
  }
@@ -20430,14 +20524,14 @@ function colorList(container) {
20430
20524
  }
20431
20525
  function parseDiagramColors(source2) {
20432
20526
  const root = rootOf2(source2);
20433
- const labels = children(root, "styleLbl", NS.dgm).map((label5) => ({
20434
- name: stringAttribute(label5, "name") ?? "",
20435
- fill: colorList(first(label5, "fillClrLst", NS.dgm)),
20436
- line: colorList(first(label5, "linClrLst", NS.dgm)),
20437
- effect: colorList(first(label5, "effectClrLst", NS.dgm)),
20438
- textLine: colorList(first(label5, "txLinClrLst", NS.dgm)),
20439
- textFill: colorList(first(label5, "txFillClrLst", NS.dgm)),
20440
- textEffect: colorList(first(label5, "txEffectClrLst", NS.dgm))
20527
+ const labels = children(root, "styleLbl", NS.dgm).map((label2) => ({
20528
+ name: stringAttribute(label2, "name") ?? "",
20529
+ fill: colorList(first(label2, "fillClrLst", NS.dgm)),
20530
+ line: colorList(first(label2, "linClrLst", NS.dgm)),
20531
+ effect: colorList(first(label2, "effectClrLst", NS.dgm)),
20532
+ textLine: colorList(first(label2, "txLinClrLst", NS.dgm)),
20533
+ textFill: colorList(first(label2, "txFillClrLst", NS.dgm)),
20534
+ textEffect: colorList(first(label2, "txEffectClrLst", NS.dgm))
20441
20535
  }));
20442
20536
  return { ...parseDefinitionHeader(root), labels };
20443
20537
  }
@@ -20470,16 +20564,16 @@ function parseStyleReferences(style2) {
20470
20564
  var hasContent = (element2) => Boolean(element2 && (element2.attributes.length > 0 || elements(element2).length > 0));
20471
20565
  function parseDiagramQuickStyle(source2) {
20472
20566
  const root = rootOf2(source2);
20473
- const labels = children(root, "styleLbl", NS.dgm).map((label5) => ({
20474
- name: stringAttribute(label5, "name") ?? "",
20475
- ...parseStyleReferences(first(label5, "style", NS.dgm)),
20476
- hasScene3d: Boolean(first(label5, "scene3d", NS.dgm)),
20477
- hasShape3d: hasContent(first(label5, "sp3d", NS.dgm))
20567
+ const labels = children(root, "styleLbl", NS.dgm).map((label2) => ({
20568
+ name: stringAttribute(label2, "name") ?? "",
20569
+ ...parseStyleReferences(first(label2, "style", NS.dgm)),
20570
+ hasScene3d: Boolean(first(label2, "scene3d", NS.dgm)),
20571
+ hasShape3d: hasContent(first(label2, "sp3d", NS.dgm))
20478
20572
  }));
20479
20573
  return {
20480
20574
  ...parseDefinitionHeader(root),
20481
20575
  labels,
20482
- has3d: labels.some((label5) => label5.hasShape3d)
20576
+ has3d: labels.some((label2) => label2.hasShape3d)
20483
20577
  };
20484
20578
  }
20485
20579
  function parseDiagramLayoutSummary(source2) {
@@ -21418,9 +21512,9 @@ var OFFICE_GRADIENT_PRESET_DATA = [
21418
21512
  ];
21419
21513
 
21420
21514
  // drawingml/gradient-presets.ts
21421
- OFFICE_GRADIENT_PRESET_DATA.map(([label5], index3) => ({
21515
+ OFFICE_GRADIENT_PRESET_DATA.map(([label2], index3) => ({
21422
21516
  id: index3 + 1,
21423
- label: label5
21517
+ label: label2
21424
21518
  }));
21425
21519
  function officeGradientPresetFill(id) {
21426
21520
  const data = Number.isInteger(id) && OFFICE_GRADIENT_PRESET_DATA[id - 1];
@@ -22669,10 +22763,10 @@ function parseDisplayUnits(context, element2) {
22669
22763
  if (!element2) return void 0;
22670
22764
  reportUnmodelled(context, element2, DISPLAY_UNITS);
22671
22765
  const labelElement = cChild(element2, "dispUnitsLbl");
22672
- let label5;
22766
+ let label2;
22673
22767
  if (labelElement) {
22674
22768
  reportUnmodelled(context, labelElement, DISPLAY_UNITS_LABEL);
22675
- label5 = assignDefined(
22769
+ label2 = assignDefined(
22676
22770
  {},
22677
22771
  {
22678
22772
  layout: manualLayout(labelElement),
@@ -22687,7 +22781,7 @@ function parseDisplayUnits(context, element2) {
22687
22781
  {
22688
22782
  builtInUnit: cVal(element2, "builtInUnit"),
22689
22783
  customUnit: cNumber(context, element2, "custUnit"),
22690
- label: label5,
22784
+ label: label2,
22691
22785
  extLst: extensionList(element2)
22692
22786
  }
22693
22787
  );
@@ -24071,14 +24165,14 @@ function readDataTable(f6) {
24071
24165
  const ref = parseRange(att(f6, "ref") ?? "");
24072
24166
  const r1 = att(f6, "r1");
24073
24167
  if (!ref || !r1) return void 0;
24074
- const table2 = { ref, r1 };
24168
+ const table3 = { ref, r1 };
24075
24169
  const r2 = att(f6, "r2");
24076
- if (r2) table2.r2 = r2;
24077
- if (boolAttr(f6, "dt2D")) table2.dt2D = true;
24078
- if (boolAttr(f6, "dtr")) table2.dtr = true;
24079
- if (boolAttr(f6, "del1")) table2.del1 = true;
24080
- if (boolAttr(f6, "del2")) table2.del2 = true;
24081
- return table2;
24170
+ if (r2) table3.r2 = r2;
24171
+ if (boolAttr(f6, "dt2D")) table3.dt2D = true;
24172
+ if (boolAttr(f6, "dtr")) table3.dtr = true;
24173
+ if (boolAttr(f6, "del1")) table3.del1 = true;
24174
+ if (boolAttr(f6, "del2")) table3.del2 = true;
24175
+ return table3;
24082
24176
  }
24083
24177
  function readFormula(ctx, f6, row2, col, cell, masters, dynamic, anchors, sheet) {
24084
24178
  const kind = att(f6, "t") ?? "normal";
@@ -24102,8 +24196,8 @@ function readFormula(ctx, f6, row2, col, cell, masters, dynamic, anchors, sheet)
24102
24196
  }
24103
24197
  if (kind === "dataTable") {
24104
24198
  delete cell.legacyFormula;
24105
- const table2 = readDataTable(f6);
24106
- if (table2) (sheet.dataTables ??= []).push(table2);
24199
+ const table3 = readDataTable(f6);
24200
+ if (table3) (sheet.dataTables ??= []).push(table3);
24107
24201
  else ctx.warn("A what-if data table formula could not be read; its cached values were kept.");
24108
24202
  return;
24109
24203
  }
@@ -24295,14 +24389,14 @@ function parseTable(xml, partName) {
24295
24389
  if (id !== void 0 && Number.isInteger(id) && id >= 0) column2.sourceId = id;
24296
24390
  const fn = att(node2, "totalsRowFunction");
24297
24391
  if (fn && fn !== "none") column2.totalsRowFunction = fn;
24298
- const label5 = att(node2, "totalsRowLabel");
24299
- if (label5 !== void 0) column2.totalsRowLabel = label5;
24392
+ const label2 = att(node2, "totalsRowLabel");
24393
+ if (label2 !== void 0) column2.totalsRowLabel = label2;
24300
24394
  const calculated = xFirst(node2, "calculatedColumnFormula");
24301
24395
  if (calculated) column2.calculatedColumnFormula = stripFuturePrefixes(xText(calculated));
24302
24396
  return column2;
24303
24397
  }
24304
24398
  );
24305
- const table2 = {
24399
+ const table3 = {
24306
24400
  id: numAttr(root, "id") ?? 1,
24307
24401
  name,
24308
24402
  displayName: att(root, "displayName") ?? name,
@@ -24312,26 +24406,26 @@ function parseTable(xml, partName) {
24312
24406
  columns,
24313
24407
  partName
24314
24408
  };
24315
- readColumnFilters(root, table2);
24409
+ readColumnFilters(root, table3);
24316
24410
  const info = xFirst(root, "tableStyleInfo");
24317
24411
  if (info) {
24318
24412
  const style2 = att(info, "name");
24319
- if (style2) table2.styleName = style2;
24320
- table2.showRowStripes = boolAttr(info, "showRowStripes", false);
24321
- table2.showColumnStripes = boolAttr(info, "showColumnStripes", false);
24322
- table2.showFirstColumn = boolAttr(info, "showFirstColumn", false);
24323
- table2.showLastColumn = boolAttr(info, "showLastColumn", false);
24413
+ if (style2) table3.styleName = style2;
24414
+ table3.showRowStripes = boolAttr(info, "showRowStripes", false);
24415
+ table3.showColumnStripes = boolAttr(info, "showColumnStripes", false);
24416
+ table3.showFirstColumn = boolAttr(info, "showFirstColumn", false);
24417
+ table3.showLastColumn = boolAttr(info, "showLastColumn", false);
24324
24418
  }
24325
- return table2;
24419
+ return table3;
24326
24420
  }
24327
- function readColumnFilters(root, table2) {
24421
+ function readColumnFilters(root, table3) {
24328
24422
  const filter2 = xFirst(root, "autoFilter");
24329
24423
  for (const node2 of filter2 ? xChildren(filter2, "filterColumn") : []) {
24330
- const column2 = table2.columns[numAttr(node2, "colId") ?? -1];
24424
+ const column2 = table3.columns[numAttr(node2, "colId") ?? -1];
24331
24425
  const filters = xChildren(node2, "filters");
24332
24426
  const simple = column2 && isValueListFilterColumn(node2);
24333
24427
  if (!simple) {
24334
- table2.filterNotModeled = true;
24428
+ table3.filterNotModeled = true;
24335
24429
  continue;
24336
24430
  }
24337
24431
  const values2 = xChildren(filters[0], "filter").map((child3) => att(child3, "val") ?? "");
@@ -24410,8 +24504,8 @@ function readTables(ctx, partName, node2, sheet) {
24410
24504
  const rel = rels.get(relAttr(part, "id") ?? "");
24411
24505
  const target = rel ? ctx.source.target(partName, rel) : void 0;
24412
24506
  const xml = target ? ctx.source.text(target) : void 0;
24413
- const table2 = target && xml ? parseTable(xml, target) : void 0;
24414
- if (table2) sheet.tables.push(table2);
24507
+ const table3 = target && xml ? parseTable(xml, target) : void 0;
24508
+ if (table3) sheet.tables.push(table3);
24415
24509
  else ctx.warn("A table part could not be read and was dropped.");
24416
24510
  }
24417
24511
  }
@@ -25275,10 +25369,10 @@ function titleXml(context, title) {
25275
25369
  function labelOptionsXml(context, options) {
25276
25370
  return numberFormatXml(options.numberFormat) + shapePropertiesXml(context, options.spPr) + textBodyXml(context, options.txPr) + valXml("dLblPos", options.position) + valXml("showLegendKey", options.showLegendKey) + valXml("showVal", options.showValue) + valXml("showCatName", options.showCategoryName) + valXml("showSerName", options.showSeriesName) + valXml("showPercent", options.showPercent) + valXml("showBubbleSize", options.showBubbleSize) + (options.separator === void 0 ? "" : textElement("separator", options.separator));
25277
25371
  }
25278
- function labelXml(context, label5) {
25372
+ function labelXml(context, label2) {
25279
25373
  return elementXml(
25280
25374
  "dLbl",
25281
- valXml("idx", label5.index) + valXml("delete", label5.deleted) + layoutXml(context, label5.layout) + chartTextXml(context, label5.tx, false) + labelOptionsXml(context, label5) + raw(context, label5.extLst)
25375
+ valXml("idx", label2.index) + valXml("delete", label2.deleted) + layoutXml(context, label2.layout) + chartTextXml(context, label2.tx, false) + labelOptionsXml(context, label2) + raw(context, label2.extLst)
25282
25376
  );
25283
25377
  }
25284
25378
  function dataLabelsXml(context, labels) {
@@ -25286,7 +25380,7 @@ function dataLabelsXml(context, labels) {
25286
25380
  const leaderLines = labels.leaderLines ? elementXml("leaderLines", shapePropertiesXml(context, labels.leaderLines.spPr)) : "";
25287
25381
  return elementXml(
25288
25382
  "dLbls",
25289
- labels.labels.map((label5) => labelXml(context, label5)).join("") + valXml("delete", labels.deleted) + labelOptionsXml(context, labels) + valXml("showLeaderLines", labels.showLeaderLines) + leaderLines + raw(context, labels.extLst)
25383
+ labels.labels.map((label2) => labelXml(context, label2)).join("") + valXml("delete", labels.deleted) + labelOptionsXml(context, labels) + valXml("showLeaderLines", labels.showLeaderLines) + leaderLines + raw(context, labels.extLst)
25290
25384
  );
25291
25385
  }
25292
25386
 
@@ -25298,21 +25392,21 @@ function surfaceXml(context, local, surface) {
25298
25392
  valXml("thickness", surface.thickness) + shapePropertiesXml(context, surface.spPr) + raw(context, surface.pictureOptionsXml) + raw(context, surface.extLst)
25299
25393
  );
25300
25394
  }
25301
- function dataTableXml(context, table2) {
25302
- if (!table2) return "";
25395
+ function dataTableXml(context, table3) {
25396
+ if (!table3) return "";
25303
25397
  return elementXml(
25304
25398
  "dTable",
25305
- valXml("showHorzBorder", table2.showHorizontalBorder) + valXml("showVertBorder", table2.showVerticalBorder) + valXml("showOutline", table2.showOutline) + valXml("showKeys", table2.showKeys) + shapePropertiesXml(context, table2.spPr) + textBodyXml(context, table2.txPr) + raw(context, table2.extLst)
25399
+ valXml("showHorzBorder", table3.showHorizontalBorder) + valXml("showVertBorder", table3.showVerticalBorder) + valXml("showOutline", table3.showOutline) + valXml("showKeys", table3.showKeys) + shapePropertiesXml(context, table3.spPr) + textBodyXml(context, table3.txPr) + raw(context, table3.extLst)
25306
25400
  );
25307
25401
  }
25308
25402
  function displayUnitsXml(context, units2) {
25309
25403
  if (!units2) return "";
25310
- const label5 = units2.label;
25404
+ const label2 = units2.label;
25311
25405
  return elementXml(
25312
25406
  "dispUnits",
25313
- valXml("custUnit", units2.customUnit) + (units2.customUnit === void 0 ? valXml("builtInUnit", units2.builtInUnit) : "") + (label5 ? elementXml(
25407
+ valXml("custUnit", units2.customUnit) + (units2.customUnit === void 0 ? valXml("builtInUnit", units2.builtInUnit) : "") + (label2 ? elementXml(
25314
25408
  "dispUnitsLbl",
25315
- layoutXml(context, label5.layout) + chartTextXml(context, label5.tx, false) + shapePropertiesXml(context, label5.spPr) + textBodyXml(context, label5.txPr)
25409
+ layoutXml(context, label2.layout) + chartTextXml(context, label2.tx, false) + shapePropertiesXml(context, label2.spPr) + textBodyXml(context, label2.txPr)
25316
25410
  ) : "") + raw(context, units2.extLst)
25317
25411
  );
25318
25412
  }
@@ -25337,11 +25431,11 @@ function axisXml(context, axis) {
25337
25431
  }
25338
25432
 
25339
25433
  // chart/write-analysis.ts
25340
- function trendlineLabelXml(context, label5) {
25341
- if (!label5) return "";
25434
+ function trendlineLabelXml(context, label2) {
25435
+ if (!label2) return "";
25342
25436
  return elementXml(
25343
25437
  "trendlineLbl",
25344
- layoutXml(context, label5.layout) + chartTextXml(context, label5.tx, false) + numberFormatXml(label5.numberFormat) + shapePropertiesXml(context, label5.spPr) + textBodyXml(context, label5.txPr) + raw(context, label5.extLst)
25438
+ layoutXml(context, label2.layout) + chartTextXml(context, label2.tx, false) + numberFormatXml(label2.numberFormat) + shapePropertiesXml(context, label2.spPr) + textBodyXml(context, label2.txPr) + raw(context, label2.extLst)
25345
25439
  );
25346
25440
  }
25347
25441
  function trendlineXml(context, trendline) {
@@ -28014,8 +28108,8 @@ function sheetDataXml(ctx, sheet) {
28014
28108
  ].sort((a2, b) => a2 - b);
28015
28109
  const spills = new SpillPlan(sheet);
28016
28110
  const tables = /* @__PURE__ */ new Map();
28017
- for (const table2 of sheet.dataTables ?? [])
28018
- tables.set(`${table2.ref.start.row}:${table2.ref.start.col}`, table2);
28111
+ for (const table3 of sheet.dataTables ?? [])
28112
+ tables.set(`${table3.ref.start.row}:${table3.ref.start.col}`, table3);
28019
28113
  let out = "";
28020
28114
  for (const row2 of rows) {
28021
28115
  const cells = sheet.rows.get(row2);
@@ -28414,29 +28508,29 @@ function setChildText(doc, parent, local, text4, before) {
28414
28508
  node2.textContent = text4;
28415
28509
  if (!existing) insertBefore(parent, node2, before);
28416
28510
  }
28417
- function tableFilterRange(table2) {
28511
+ function tableFilterRange(table3) {
28418
28512
  return {
28419
- start: table2.range.start,
28420
- end: { ...table2.range.end, row: table2.range.end.row - (table2.totalsRow ? 1 : 0) }
28513
+ start: table3.range.start,
28514
+ end: { ...table3.range.end, row: table3.range.end.row - (table3.totalsRow ? 1 : 0) }
28421
28515
  };
28422
28516
  }
28423
- function sourceColumnsForPatch(root, table2, names) {
28517
+ function sourceColumnsForPatch(root, table3, names) {
28424
28518
  const list = xKid(root, "tableColumns");
28425
28519
  const source2 = list ? xKids(list, "tableColumn") : [];
28426
28520
  const byId2 = new Map(source2.map((c2) => [Number(c2.getAttribute("id")), c2]));
28427
28521
  const byName = new Map(source2.map((c2) => [(c2.getAttribute("name") ?? "").toLowerCase(), c2]));
28428
- const tracked = table2.partName !== void 0 || table2.columns.some((c2) => c2.sourceId !== void 0);
28522
+ const tracked = table3.partName !== void 0 || table3.columns.some((c2) => c2.sourceId !== void 0);
28429
28523
  const used = /* @__PURE__ */ new Set();
28430
28524
  return names.map((name, index3) => {
28431
- const id = table2.columns[index3]?.sourceId;
28525
+ const id = table3.columns[index3]?.sourceId;
28432
28526
  const match2 = id !== void 0 ? byId2.get(id) : tracked ? void 0 : source2.length === names.length ? source2[index3] : byName.get(name.toLowerCase());
28433
28527
  if (!match2 || used.has(match2)) return void 0;
28434
28528
  used.add(match2);
28435
28529
  return match2;
28436
28530
  });
28437
28531
  }
28438
- function syncColumnFilters(doc, filter2, table2) {
28439
- table2.columns.forEach((column2, index3) => {
28532
+ function syncColumnFilters(doc, filter2, table3) {
28533
+ table3.columns.forEach((column2, index3) => {
28440
28534
  const node2 = xKids(filter2, "filterColumn").find(
28441
28535
  (n2) => Number(n2.getAttribute("colId")) === index3
28442
28536
  );
@@ -28458,29 +28552,29 @@ function syncColumnFilters(doc, filter2, table2) {
28458
28552
  }
28459
28553
  });
28460
28554
  }
28461
- function patchAutoFilter(doc, root, table2, before, names) {
28555
+ function patchAutoFilter(doc, root, table3, before, names) {
28462
28556
  const existing = xKid(root, "autoFilter");
28463
- if (!table2.headerRow) {
28557
+ if (!table3.headerRow) {
28464
28558
  if (existing) root.removeChild(existing);
28465
28559
  return;
28466
28560
  }
28467
28561
  const filter2 = existing ?? doc.createElementNS(NS.x, "autoFilter");
28468
- const range = tableFilterRange(table2);
28562
+ const range = tableFilterRange(table3);
28469
28563
  filter2.setAttribute("ref", formatRange(range));
28470
28564
  const list = xKid(root, "tableColumns");
28471
28565
  const original = list ? xKids(list, "tableColumn") : [];
28472
- const current = new Map(sourceColumnsForPatch(root, table2, names).map((c2, index3) => [c2, index3]));
28566
+ const current = new Map(sourceColumnsForPatch(root, table3, names).map((c2, index3) => [c2, index3]));
28473
28567
  for (const column2 of xKids(filter2, "filterColumn")) {
28474
28568
  const old = original[Number(column2.getAttribute("colId") ?? "0")];
28475
28569
  const index3 = old ? current.get(old) : void 0;
28476
28570
  if (index3 === void 0) filter2.removeChild(column2);
28477
28571
  else column2.setAttribute("colId", num2(index3));
28478
28572
  }
28479
- syncColumnFilters(doc, filter2, table2);
28573
+ syncColumnFilters(doc, filter2, table3);
28480
28574
  if (!existing) insertBefore(root, filter2, ["sortState", "tableColumns"]);
28481
28575
  const sort2 = xKid(filter2, "sortState") ?? xKid(root, "sortState");
28482
28576
  if (!sort2) return;
28483
- const moved = before.start.row !== table2.range.start.row || before.start.col !== table2.range.start.col || before.end.col !== table2.range.end.col;
28577
+ const moved = before.start.row !== table3.range.start.row || before.start.col !== table3.range.start.col || before.end.col !== table3.range.end.col;
28484
28578
  if (moved) {
28485
28579
  sort2.parentNode?.removeChild(sort2);
28486
28580
  return;
@@ -28502,7 +28596,7 @@ function patchAutoFilter(doc, root, table2, before, names) {
28502
28596
  }
28503
28597
  }
28504
28598
  var COLUMN_CHILD_ORDER = ["calculatedColumnFormula", "totalsRowFormula", "xmlColumnPr", "extLst"];
28505
- function patchColumns(doc, root, sheet, table2, names) {
28599
+ function patchColumns(doc, root, sheet, table3, names) {
28506
28600
  let list = xKid(root, "tableColumns");
28507
28601
  if (!list) {
28508
28602
  list = doc.createElementNS(NS.x, "tableColumns");
@@ -28510,7 +28604,7 @@ function patchColumns(doc, root, sheet, table2, names) {
28510
28604
  }
28511
28605
  const sourceColumns = xKids(list, "tableColumn");
28512
28606
  const ids = /* @__PURE__ */ new Set();
28513
- const picked = sourceColumnsForPatch(root, table2, names).map((match2) => {
28607
+ const picked = sourceColumnsForPatch(root, table3, names).map((match2) => {
28514
28608
  if (!match2) return void 0;
28515
28609
  const id = Number(match2.getAttribute("id"));
28516
28610
  if (Number.isInteger(id) && id >= 0 && !ids.has(id)) ids.add(id);
@@ -28519,15 +28613,15 @@ function patchColumns(doc, root, sheet, table2, names) {
28519
28613
  });
28520
28614
  for (const column2 of sourceColumns) list.removeChild(column2);
28521
28615
  let nextId = Math.max(0, ...ids) + 1;
28522
- const totalsRow = table2.range.end.row;
28616
+ const totalsRow = table3.range.end.row;
28523
28617
  names.forEach((name, index3) => {
28524
28618
  const column2 = picked[index3] ?? doc.createElementNS(NS.x, "tableColumn");
28525
28619
  if (!column2.getAttribute("id")) column2.setAttribute("id", num2(nextId++));
28526
28620
  column2.setAttribute("name", name);
28527
- const model = table2.columns[index3];
28528
- const fn = table2.totalsRow ? model?.totalsRowFunction : void 0;
28621
+ const model = table3.columns[index3];
28622
+ const fn = table3.totalsRow ? model?.totalsRowFunction : void 0;
28529
28623
  setOrRemove(column2, "totalsRowFunction", fn);
28530
- setOrRemove(column2, "totalsRowLabel", table2.totalsRow ? model?.totalsRowLabel : void 0);
28624
+ setOrRemove(column2, "totalsRowLabel", table3.totalsRow ? model?.totalsRowLabel : void 0);
28531
28625
  const calculated = model?.calculatedColumnFormula;
28532
28626
  setChildText(
28533
28627
  doc,
@@ -28538,7 +28632,7 @@ function patchColumns(doc, root, sheet, table2, names) {
28538
28632
  );
28539
28633
  if (fn !== "custom") setChildText(doc, column2, "totalsRowFormula", void 0, []);
28540
28634
  else {
28541
- const cellFormula = sheet.rows.get(totalsRow)?.get(table2.range.start.col + index3)?.formula;
28635
+ const cellFormula = sheet.rows.get(totalsRow)?.get(table3.range.start.col + index3)?.formula;
28542
28636
  if (cellFormula)
28543
28637
  setChildText(
28544
28638
  doc,
@@ -28552,19 +28646,19 @@ function patchColumns(doc, root, sheet, table2, names) {
28552
28646
  });
28553
28647
  list.setAttribute("count", num2(names.length));
28554
28648
  }
28555
- function patchStyleInfo(doc, root, table2) {
28649
+ function patchStyleInfo(doc, root, table3) {
28556
28650
  let info = xKid(root, "tableStyleInfo");
28557
28651
  if (!info) {
28558
28652
  info = doc.createElementNS(NS.x, "tableStyleInfo");
28559
28653
  insertBefore(root, info, ["extLst"]);
28560
28654
  }
28561
- setOrRemove(info, "name", table2.styleName);
28562
- info.setAttribute("showFirstColumn", flag(table2.showFirstColumn, false));
28563
- info.setAttribute("showLastColumn", flag(table2.showLastColumn, false));
28564
- info.setAttribute("showRowStripes", flag(table2.showRowStripes, true));
28565
- info.setAttribute("showColumnStripes", flag(table2.showColumnStripes, false));
28655
+ setOrRemove(info, "name", table3.styleName);
28656
+ info.setAttribute("showFirstColumn", flag(table3.showFirstColumn, false));
28657
+ info.setAttribute("showLastColumn", flag(table3.showLastColumn, false));
28658
+ info.setAttribute("showRowStripes", flag(table3.showRowStripes, true));
28659
+ info.setAttribute("showColumnStripes", flag(table3.showColumnStripes, false));
28566
28660
  }
28567
- function patchTableXml(sourceXml, sheet, table2, id, names) {
28661
+ function patchTableXml(sourceXml, sheet, table3, id, names) {
28568
28662
  let doc;
28569
28663
  try {
28570
28664
  doc = parseXml(sourceXml, { label: "XLSX table" });
@@ -28573,80 +28667,80 @@ function patchTableXml(sourceXml, sheet, table2, id, names) {
28573
28667
  }
28574
28668
  const root = doc.documentElement;
28575
28669
  if (root.localName !== "table") return void 0;
28576
- const before = parseRange(root.getAttribute("ref") ?? "") ?? table2.range;
28670
+ const before = parseRange(root.getAttribute("ref") ?? "") ?? table3.range;
28577
28671
  root.setAttribute("id", num2(id));
28578
- root.setAttribute("name", table2.name);
28579
- root.setAttribute("displayName", table2.displayName || table2.name);
28580
- root.setAttribute("ref", formatRange(table2.range));
28581
- setOrRemove(root, "headerRowCount", table2.headerRow ? void 0 : "0");
28582
- if (table2.totalsRow) {
28672
+ root.setAttribute("name", table3.name);
28673
+ root.setAttribute("displayName", table3.displayName || table3.name);
28674
+ root.setAttribute("ref", formatRange(table3.range));
28675
+ setOrRemove(root, "headerRowCount", table3.headerRow ? void 0 : "0");
28676
+ if (table3.totalsRow) {
28583
28677
  root.setAttribute("totalsRowCount", "1");
28584
28678
  root.removeAttribute("totalsRowShown");
28585
28679
  } else {
28586
28680
  root.removeAttribute("totalsRowCount");
28587
28681
  if (!root.hasAttribute("totalsRowShown")) root.setAttribute("totalsRowShown", "0");
28588
28682
  }
28589
- patchAutoFilter(doc, root, table2, before, names);
28590
- patchColumns(doc, root, sheet, table2, names);
28591
- patchStyleInfo(doc, root, table2);
28683
+ patchAutoFilter(doc, root, table3, before, names);
28684
+ patchColumns(doc, root, sheet, table3, names);
28685
+ patchStyleInfo(doc, root, table3);
28592
28686
  return buildXml(doc);
28593
28687
  }
28594
28688
 
28595
28689
  // xlsx/write/tables.ts
28596
28690
  var headerTextOf = (value2) => typeof value2 === "string" ? value2 : typeof value2 === "number" || typeof value2 === "boolean" ? String(value2).toUpperCase() : void 0;
28597
- function resolveTableColumns(sheet, table2) {
28691
+ function resolveTableColumns(sheet, table3) {
28598
28692
  const headerText = /* @__PURE__ */ new Map();
28599
28693
  const used = /* @__PURE__ */ new Set();
28600
- const width = table2.range.end.col - table2.range.start.col + 1;
28694
+ const width = table3.range.end.col - table3.range.start.col + 1;
28601
28695
  const names = [];
28602
28696
  for (let i2 = 0; i2 < width; i2++) {
28603
- const col = table2.range.start.col + i2;
28604
- const row2 = table2.range.start.row;
28605
- const fromCell = table2.headerRow ? headerTextOf(sheet.rows.get(row2)?.get(col)?.value) : void 0;
28606
- let name = (fromCell?.trim() ? fromCell : void 0) ?? table2.columns[i2]?.name ?? `Column${i2 + 1}`;
28697
+ const col = table3.range.start.col + i2;
28698
+ const row2 = table3.range.start.row;
28699
+ const fromCell = table3.headerRow ? headerTextOf(sheet.rows.get(row2)?.get(col)?.value) : void 0;
28700
+ let name = (fromCell?.trim() ? fromCell : void 0) ?? table3.columns[i2]?.name ?? `Column${i2 + 1}`;
28607
28701
  if (!name.trim()) name = `Column${i2 + 1}`;
28608
28702
  let unique3 = name;
28609
28703
  for (let n2 = 2; used.has(unique3.toLowerCase()); n2++) unique3 = `${name}${n2}`;
28610
28704
  used.add(unique3.toLowerCase());
28611
28705
  names.push(unique3);
28612
28706
  const cell = sheet.rows.get(row2)?.get(col);
28613
- if (table2.headerRow && (typeof cell?.value !== "string" || cell.value !== unique3))
28707
+ if (table3.headerRow && (typeof cell?.value !== "string" || cell.value !== unique3))
28614
28708
  headerText.set(`${row2}:${col}`, unique3);
28615
28709
  }
28616
28710
  return { names, headerText };
28617
28711
  }
28618
- function tableXml(table2, id, names) {
28619
- const range = formatRange(table2.range);
28620
- const filterEnd = { ...table2.range.end, row: table2.range.end.row - (table2.totalsRow ? 1 : 0) };
28621
- const criteria = table2.columns.map((column2, index3) => column2.filter ? filterColumnXml(index3, column2.filter) : "").join("");
28622
- const filterRef = formatRange({ start: table2.range.start, end: filterEnd });
28623
- const filter2 = table2.headerRow ? criteria ? `<autoFilter ref="${filterRef}">${criteria}</autoFilter>` : `<autoFilter ref="${filterRef}"/>` : "";
28712
+ function tableXml(table3, id, names) {
28713
+ const range = formatRange(table3.range);
28714
+ const filterEnd = { ...table3.range.end, row: table3.range.end.row - (table3.totalsRow ? 1 : 0) };
28715
+ const criteria = table3.columns.map((column2, index3) => column2.filter ? filterColumnXml(index3, column2.filter) : "").join("");
28716
+ const filterRef = formatRange({ start: table3.range.start, end: filterEnd });
28717
+ const filter2 = table3.headerRow ? criteria ? `<autoFilter ref="${filterRef}">${criteria}</autoFilter>` : `<autoFilter ref="${filterRef}"/>` : "";
28624
28718
  const columns = names.map((name, index3) => {
28625
- const column2 = table2.columns[index3];
28719
+ const column2 = table3.columns[index3];
28626
28720
  const calculated = column2?.calculatedColumnFormula ? `<calculatedColumnFormula>${escapeText(addFuturePrefixes(column2.calculatedColumnFormula))}</calculatedColumnFormula>` : "";
28627
28721
  const values2 = attrs({
28628
28722
  id: index3 + 1,
28629
28723
  name,
28630
- totalsRowFunction: table2.totalsRow ? column2?.totalsRowFunction : void 0,
28631
- totalsRowLabel: table2.totalsRow ? column2?.totalsRowLabel : void 0
28724
+ totalsRowFunction: table3.totalsRow ? column2?.totalsRowFunction : void 0,
28725
+ totalsRowLabel: table3.totalsRow ? column2?.totalsRowLabel : void 0
28632
28726
  });
28633
28727
  return calculated ? `<tableColumn${values2}>${calculated}</tableColumn>` : `<tableColumn${values2}/>`;
28634
28728
  }).join("");
28635
28729
  const style2 = attrs({
28636
- name: table2.styleName,
28637
- showFirstColumn: table2.showFirstColumn ?? false,
28638
- showLastColumn: table2.showLastColumn ?? false,
28639
- showRowStripes: table2.showRowStripes ?? true,
28640
- showColumnStripes: table2.showColumnStripes ?? false
28730
+ name: table3.styleName,
28731
+ showFirstColumn: table3.showFirstColumn ?? false,
28732
+ showLastColumn: table3.showLastColumn ?? false,
28733
+ showRowStripes: table3.showRowStripes ?? true,
28734
+ showColumnStripes: table3.showColumnStripes ?? false
28641
28735
  });
28642
28736
  const head = attrs({
28643
28737
  id,
28644
- name: table2.name,
28645
- displayName: table2.displayName || table2.name,
28738
+ name: table3.name,
28739
+ displayName: table3.displayName || table3.name,
28646
28740
  ref: range,
28647
- headerRowCount: table2.headerRow ? void 0 : 0,
28648
- totalsRowCount: table2.totalsRow ? 1 : void 0,
28649
- totalsRowShown: table2.totalsRow ? void 0 : false
28741
+ headerRowCount: table3.headerRow ? void 0 : 0,
28742
+ totalsRowCount: table3.totalsRow ? 1 : void 0,
28743
+ totalsRowShown: table3.totalsRow ? void 0 : false
28650
28744
  });
28651
28745
  return `${XML_HEADER}<table xmlns="${NS.x}"${head}>${filter2}<tableColumns count="${names.length}">${columns}</tableColumns><tableStyleInfo${style2}/></table>`;
28652
28746
  }
@@ -28660,24 +28754,24 @@ var SUBTOTAL_CODES = {
28660
28754
  sum: 109,
28661
28755
  var: 110
28662
28756
  };
28663
- function totalsRowFormulas(sheet, table2, names) {
28757
+ function totalsRowFormulas(sheet, table3, names) {
28664
28758
  const out = /* @__PURE__ */ new Map();
28665
- if (!table2.totalsRow) return out;
28666
- const row2 = table2.range.end.row;
28759
+ if (!table3.totalsRow) return out;
28760
+ const row2 = table3.range.end.row;
28667
28761
  names.forEach((name, index3) => {
28668
- const code = SUBTOTAL_CODES[table2.columns[index3]?.totalsRowFunction ?? ""];
28762
+ const code = SUBTOTAL_CODES[table3.columns[index3]?.totalsRowFunction ?? ""];
28669
28763
  if (code === void 0) return;
28670
- const col = table2.range.start.col + index3;
28764
+ const col = table3.range.start.col + index3;
28671
28765
  const escaped = name.replace(/['#[\]]/g, "'$&");
28672
- const formula = `SUBTOTAL(${code},${table2.displayName || table2.name}[${escaped}])`;
28766
+ const formula = `SUBTOTAL(${code},${table3.displayName || table3.name}[${escaped}])`;
28673
28767
  if (sheet.rows.get(row2)?.get(col)?.formula !== formula) out.set(`${row2}:${col}`, formula);
28674
28768
  });
28675
28769
  return out;
28676
28770
  }
28677
- function resolveTableNames(table2, before, index3) {
28678
- const display = table2.displayName || table2.name;
28771
+ function resolveTableNames(table3, before, index3) {
28772
+ const display = table3.displayName || table3.name;
28679
28773
  const displayName = before && before.displayName === display ? display : safeTableName(display, index3);
28680
- const name = before && before.name === table2.name ? table2.name : table2.name === display ? displayName : safeTableName(table2.name, index3);
28774
+ const name = before && before.name === table3.name ? table3.name : table3.name === display ? displayName : safeTableName(table3.name, index3);
28681
28775
  return { name, displayName };
28682
28776
  }
28683
28777
  function safeTableName(name, index3) {
@@ -28770,21 +28864,21 @@ function writeTables(ctx, sheet, partName, rels, headerText, formulas) {
28770
28864
  const sourceXml = original.partName ? source2?.text(original.partName) : void 0;
28771
28865
  const before = sourceXml && original.partName ? parseTable(sourceXml, original.partName) : void 0;
28772
28866
  const { name, displayName } = resolveTableNames(original, before, index3 + 1);
28773
- const table2 = name === original.name && displayName === original.displayName ? original : { ...original, name, displayName };
28774
- const { names, headerText: forced } = resolveTableColumns(sheet, table2);
28867
+ const table3 = name === original.name && displayName === original.displayName ? original : { ...original, name, displayName };
28868
+ const { names, headerText: forced } = resolveTableColumns(sheet, table3);
28775
28869
  for (const [key, text4] of forced) headerText.set(key, text4);
28776
- const totals = totalsRowFormulas(sheet, table2, names);
28870
+ const totals = totalsRowFormulas(sheet, table3, names);
28777
28871
  for (const [key, formula] of totals) formulas.set(key, formula);
28778
- let id = table2.id;
28779
- const unchanged = table2.partName && sourceXml && !writer.has(table2.partName) && !ctx.tableIds.has(id) && forced.size === 0 && totals.size === 0 && table2 === original && sameModel(before, table2);
28872
+ let id = table3.id;
28873
+ const unchanged = table3.partName && sourceXml && !writer.has(table3.partName) && !ctx.tableIds.has(id) && forced.size === 0 && totals.size === 0 && table3 === original && sameModel(before, table3);
28780
28874
  let part;
28781
- if (unchanged && table2.partName) {
28782
- part = table2.partName;
28875
+ if (unchanged && table3.partName) {
28876
+ part = table3.partName;
28783
28877
  writer.carry(part);
28784
28878
  } else {
28785
28879
  while (ctx.tableIds.has(id) || id < 1) id++;
28786
- part = table2.partName && !writer.has(table2.partName) ? table2.partName : writer.uniqueName((n2) => `xl/tables/table${n2}.xml`, ctx.reserved);
28787
- const xml = (sourceXml && patchTableXml(sourceXml, sheet, table2, id, names)) ?? tableXml(table2, id, names);
28880
+ part = table3.partName && !writer.has(table3.partName) ? table3.partName : writer.uniqueName((n2) => `xl/tables/table${n2}.xml`, ctx.reserved);
28881
+ const xml = (sourceXml && patchTableXml(sourceXml, sheet, table3, id, names)) ?? tableXml(table3, id, names);
28788
28882
  writer.add(part, xml, CONTENT_TYPES.table);
28789
28883
  }
28790
28884
  ctx.tableIds.add(id);
@@ -29227,15 +29321,15 @@ function derivedFields(pivot, date1904) {
29227
29321
  function derivedFieldXml(pivot, entry3, date1904) {
29228
29322
  const range = { start: entry3.group.start, end: entry3.group.end };
29229
29323
  const days = dateGroupDays(entry3.group);
29230
- const labels = dateUnitLabels(entry3.unit, range, days, date1904);
29324
+ const labels = dateUnitLabels(entry3.unit, range, days, date1904, entry3.group);
29231
29325
  const base = pivot.fields.indexOf(entry3.group.field);
29232
- return `<cacheField${attrs({ name: encodeEscapes(entry3.name), numFmtId: 0, databaseField: false })}><fieldGroup base="${base}"><rangePr${attrs({ autoStart: entry3.autoStart ? void 0 : false, autoEnd: entry3.autoEnd ? void 0 : false, groupBy: entry3.unit, startDate: serialToIso(range.start, date1904), endDate: serialToIso(range.end, date1904), groupInterval: days > 1 ? days : void 0 })}/><groupItems count="${labels.length}">${labels.map((label5) => `<s v="${escapeAttr(label5)}"/>`).join("")}</groupItems></fieldGroup></cacheField>`;
29326
+ return `<cacheField${attrs({ name: encodeEscapes(entry3.name), numFmtId: 0, databaseField: false })}><fieldGroup base="${base}"><rangePr${attrs({ autoStart: entry3.autoStart ? void 0 : false, autoEnd: entry3.autoEnd ? void 0 : false, groupBy: entry3.unit, startDate: serialToIso(range.start, date1904), endDate: serialToIso(range.end, date1904), groupInterval: days > 1 ? days : void 0 })}/><groupItems count="${labels.length}">${labels.map((label2) => `<s v="${escapeAttr(label2)}"/>`).join("")}</groupItems></fieldGroup></cacheField>`;
29233
29327
  }
29234
29328
  function groupXml2(pivot, name, index3) {
29235
29329
  const group = groupOf(pivot, name);
29236
29330
  if (!group) return "";
29237
29331
  const labels = numberGroupLabels(group);
29238
- return `<fieldGroup base="${index3}"><rangePr autoStart="0" autoEnd="0" startNum="${group.start}" endNum="${group.end}" groupInterval="${group.by}"/><groupItems count="${labels.length}">${labels.map((label5) => `<s v="${escapeAttr(label5)}"/>`).join("")}</groupItems></fieldGroup>`;
29332
+ return `<fieldGroup base="${index3}"><rangePr autoStart="0" autoEnd="0" startNum="${group.start}" endNum="${group.end}" groupInterval="${group.by}"/><groupItems count="${labels.length}">${labels.map((label2) => `<s v="${escapeAttr(label2)}"/>`).join("")}</groupItems></fieldGroup>`;
29239
29333
  }
29240
29334
  function slicerExt(pivot) {
29241
29335
  if (pivot.slicerCacheId === void 0) return "";
@@ -29256,8 +29350,6 @@ function pivotTableXml(source2, cacheId, cache3) {
29256
29350
  const pivot = expandDateGroups(source2);
29257
29351
  const rowNames = pivotRowFields(pivot);
29258
29352
  const rowIdx = rowNames.map((name) => pivot.fields.indexOf(name));
29259
- const row2 = rowIdx[0];
29260
- const second = rowIdx[1] ?? -1;
29261
29353
  const page = pivot.pageFilter ? pivot.fields.indexOf(pivot.pageFilter.field) : -1;
29262
29354
  const pageItems = page >= 0 ? pivotItems(pivot, pivot.pageFilter.field) : [];
29263
29355
  const filtered2 = filteredFields(pivot);
@@ -29285,7 +29377,10 @@ function pivotTableXml(source2, cacheId, cache3) {
29285
29377
  const columnIndicesFull = columnNames.map(
29286
29378
  (_name, k) => itemIndices(visibleColumns[k], columnItemsFull[k])
29287
29379
  );
29288
- const rowEntries = anyFull && grid.rowEntries ? remapPivotRowEntries(grid.rowEntries, rowIndicesFull) : grid.rowEntries;
29380
+ const valuesAt = pivotValuesIndex(pivot);
29381
+ const levelAxes = [...rowIndicesFull];
29382
+ if (valuesAt >= 0) levelAxes.splice(valuesAt, 0, null);
29383
+ const rowEntries = anyFull && grid.rowEntries ? remapPivotRowEntries(grid.rowEntries, levelAxes) : grid.rowEntries;
29289
29384
  const pageOffset = page >= 0 ? 2 : 0;
29290
29385
  const col = columnIdx[0] ?? -1;
29291
29386
  const measures = pivotMeasures(pivot);
@@ -29294,13 +29389,17 @@ function pivotTableXml(source2, cacheId, cache3) {
29294
29389
  const compact3 = pivot.layout === "compact";
29295
29390
  const outline = pivot.layout === "compact" || pivot.layout === "outline";
29296
29391
  const top = (pivot.subtotalPosition ?? (outline ? "top" : "bottom")) === "top";
29392
+ const named2 = (field, item) => {
29393
+ const text4 = pivotItemName(pivot, field, item);
29394
+ return text4 === void 0 ? "" : attrs({ n: encodeEscapes(text4) });
29395
+ };
29297
29396
  const fields = pivot.fields.map((name, index3) => {
29298
29397
  const isDate = pivot.dateFields?.includes(name) ?? false;
29299
29398
  const at = rowIdx.indexOf(index3);
29300
29399
  const colAt = columnIdx.indexOf(index3);
29301
29400
  const items2 = index3 === page ? pageItems : at >= 0 ? rowItemsFull[at] : colAt >= 0 ? columnItemsFull[colAt] : groupLabelsOf(pivot, name) ?? (filtered2.has(name) || isDate ? pivotItems(pivot, name) : void 0);
29302
29401
  const hidden = hiddenItemKeys(pivot, name);
29303
- const functions = at >= 0 ? fieldSubtotalFunctions(pivot, name) : "auto";
29402
+ const functions = at >= 0 || colAt >= 0 ? fieldSubtotalFunctions(pivot, name) : "auto";
29304
29403
  const automatic = functions === "auto";
29305
29404
  const custom = automatic ? [] : functions;
29306
29405
  const repeated = pivot.repeatLabels && at >= 0 ? `<extLst><ext uri="{2946ED86-A175-432a-8AC1-64E0C546D7DE}"><x14:pivotField xmlns:x14="${X143}" fillDownLabels="1"/></ext></extLst>` : "";
@@ -29308,37 +29407,27 @@ function pivotTableXml(source2, cacheId, cache3) {
29308
29407
  custom.map((fn) => [PIVOT_SUBTOTALS[fn].attr, true])
29309
29408
  );
29310
29409
  const entries = automatic ? '<item t="default"/>' : custom.map((fn) => `<item t="${PIVOT_SUBTOTALS[fn].item}"/>`).join("");
29311
- return `<pivotField${attrs({ axis: index3 === page ? "axisPage" : at >= 0 ? "axisRow" : colAt >= 0 ? "axisCol" : void 0, dataField: measures.some((measure) => pivot.fields.indexOf(measure.field) === index3) ? true : void 0, compact: compact3, outline, showAll: false, subtotalTop: at >= 0 ? top : void 0, numFmtId: isDate ? 14 : void 0, defaultSubtotal: automatic ? void 0 : false, ...flags })}>${items2 ? `<items count="${items2.length + (automatic ? 1 : custom.length)}">${items2.map((item) => `<item${hidden.has(pivotValueKey(item)) ? ' h="1"' : ""} x="${itemX(index3, item)}"/>`).join("")}${entries}</items>` : ""}${repeated}</pivotField>`;
29410
+ return `<pivotField${attrs({ axis: index3 === page ? "axisPage" : at >= 0 ? "axisRow" : colAt >= 0 ? "axisCol" : void 0, dataField: measures.some((measure) => pivot.fields.indexOf(measure.field) === index3) ? true : void 0, compact: compact3, outline, showAll: false, subtotalTop: at >= 0 ? top : void 0, numFmtId: isDate ? 14 : void 0, defaultSubtotal: automatic ? void 0 : false, ...flags })}>${items2 ? `<items count="${items2.length + (automatic ? 1 : custom.length)}">${items2.map((item) => `<item${hidden.has(pivotValueKey(item)) ? ' h="1"' : ""}${named2(name, item)} x="${itemX(index3, item)}"/>`).join("")}${entries}</items>` : ""}${repeated}</pivotField>`;
29312
29411
  }).join("");
29313
29412
  const items = (count2, indices) => Array.from({ length: count2 }, (_v, i2) => `<i><x v="${indices?.[i2] ?? i2}"/></i>`).join("") + '<i t="grand"><x/></i>';
29314
29413
  const header = grid.firstHeaderRow !== void 0 ? grid.firstHeaderRow - pageOffset : col >= 0 ? 1 : grid.firstDataRow - pageOffset - 1;
29315
- const rowIndices = rowsAxis && pivot.valuesPosition === "first" ? [-2, row2, second] : rowsAxis && pivot.valuesPosition === "between" ? [row2, -2, second] : [...rowIdx, ...rowsAxis ? [-2] : []];
29414
+ const rowIndices = [...rowIdx];
29415
+ if (valuesAt >= 0) rowIndices.splice(valuesAt, 0, -2);
29316
29416
  let previous = [];
29317
29417
  const rowItems = rowEntries?.map((entry3) => {
29318
29418
  let prefix = 0;
29319
29419
  const type = entry3.type === void 0 || entry3.type === "default" || entry3.type === "grand" ? entry3.type : PIVOT_SUBTOTALS[entry3.type].item;
29320
- if (rowsAxis) {
29321
- if (entry3.type === "default" && pivot.valuesPosition === "first") prefix = 1;
29322
- else if (!entry3.type)
29323
- while (prefix < entry3.indices.length - 1 && entry3.indices[prefix] === previous[prefix])
29324
- prefix++;
29325
- previous = entry3.type && !(entry3.type === "default" && pivot.valuesPosition === "first") ? [] : entry3.indices;
29326
- } else {
29327
- if (entry3.type !== "grand") prefix = sharedPrefix(entry3.indices, previous);
29328
- previous = entry3.type === "grand" ? [] : entry3.indices;
29329
- }
29420
+ if (entry3.type !== "grand") prefix = sharedPrefix(entry3.indices, previous);
29421
+ previous = entry3.type === "grand" ? [] : entry3.indices;
29330
29422
  return `<i${attrs({ t: type, r: prefix || void 0, i: entry3.measure || void 0 })}>${entry3.indices.slice(prefix).map((index3) => `<x${attrs({ v: index3 || void 0 })}/>`).join("")}</i>`;
29331
29423
  }).join("") ?? items(grid.rowItems.length, rowIndicesFull[0]);
29332
29424
  let body = `<location${attrs({ ref: formatRange({ ...pivot.location, start: { ...pivot.location.start, row: pivot.location.start.row + pageOffset } }), firstHeaderRow: header, firstDataRow: grid.firstDataRow - pageOffset, rowPageCount: page >= 0 ? 1 : void 0, colPageCount: page >= 0 ? 1 : void 0, firstDataCol: grid.rowLabelColumns ?? 1 })}/><pivotFields count="${pivot.fields.length}">${fields}</pivotFields><rowFields count="${rowIndices.length}">${rowIndices.map((index3) => `<field x="${index3}"/>`).join("")}</rowFields><rowItems count="${grid.rowEntries?.length ?? grid.rowItems.length + 1}">${rowItems}</rowItems>`;
29333
- if (!rowsAxis && col >= 0 && grid.columnEntries) {
29334
- const fieldsOnColumns = [...columnIdx, ...multiple ? [-2] : []];
29335
- body += `<colFields count="${fieldsOnColumns.length}">${fieldsOnColumns.map((index3) => `<field x="${index3}"/>`).join("")}</colFields>${pivotColumnItemsXml(grid.columnEntries, measures.length, (level, index3) => columnIndicesFull[level][index3])}`;
29425
+ if (col >= 0 && grid.columnEntries) {
29426
+ const fieldsOnColumns = [...columnIdx, ...multiple && !rowsAxis ? [-2] : []];
29427
+ body += `<colFields count="${fieldsOnColumns.length}">${fieldsOnColumns.map((index3) => `<field x="${index3}"/>`).join("")}</colFields>${pivotColumnItemsXml(grid.columnEntries, rowsAxis ? 1 : measures.length, (level, index3) => columnIndicesFull[level][index3])}`;
29336
29428
  } else if (multiple && !rowsAxis)
29337
29429
  body += `<colFields count="1"><field x="-2"/></colFields>${pivotValueAxisItems(measures.length)}`;
29338
- else if (col >= 0)
29339
- body += `<colFields count="1"><field x="${col}"/></colFields><colItems count="${grid.columnItems.length + 1}">${items(grid.columnItems.length, columnIndicesFull[0])}</colItems>`;
29340
- else
29341
- body += rowsAxis ? '<colItems count="1"><i/></colItems>' : page >= 0 ? '<colItems count="1"><i/></colItems>' : '<colItems count="1"><i><x/></i></colItems>';
29430
+ else body += '<colItems count="1"><i/></colItems>';
29342
29431
  if (page >= 0)
29343
29432
  body += `<pageFields count="1"><pageField${attrs({ fld: page, hier: -1, item: pivot.pageFilter.item !== void 0 ? pageItems.findIndex((item) => pivotValueKey(item) === pivotValueKey(pivot.pageFilter.item)) : void 0 })}/></pageFields>`;
29344
29433
  body += `<dataFields count="${measures.length}">${measures.map((measure) => `<dataField${attrs({ name: encodeEscapes(measure.caption), fld: pivot.fields.indexOf(measure.field), subtotal: measure.aggregate, baseField: 0, baseItem: 0 })}/>`).join("")}</dataFields>`;
@@ -29348,9 +29437,17 @@ function pivotTableXml(source2, cacheId, cache3) {
29348
29437
  const root = doc.documentElement;
29349
29438
  root.setAttribute("name", pivot.name);
29350
29439
  root.setAttribute("cacheId", String(cacheId));
29440
+ const caps = pivotCaptions(pivot);
29441
+ root.setAttribute("dataCaption", caps.values);
29442
+ for (const [attribute2, key] of [
29443
+ ["rowHeaderCaption", "rowLabels"],
29444
+ ["colHeaderCaption", "columnLabels"],
29445
+ ["grandTotalCaption", "grandTotal"]
29446
+ ])
29447
+ if (caps[key] !== ENGLISH_PIVOT_CAPTIONS[key] || root.hasAttribute(attribute2))
29448
+ root.setAttribute(attribute2, caps[key]);
29351
29449
  root.setAttribute("dataOnRows", rowsAxis ? "1" : "0");
29352
- if (rowsAxis && (pivot.valuesPosition === "between" || pivot.valuesPosition === "first"))
29353
- root.setAttribute("dataPosition", pivot.valuesPosition === "first" ? "0" : "1");
29450
+ if (rowsAxis && valuesAt < rowIdx.length) root.setAttribute("dataPosition", String(valuesAt));
29354
29451
  else root.removeAttribute("dataPosition");
29355
29452
  root.setAttribute("compact", compact3 ? "1" : "0");
29356
29453
  root.setAttribute("compactData", compact3 ? "1" : "0");
@@ -29416,7 +29513,8 @@ function pivotTableXml(source2, cacheId, cache3) {
29416
29513
  }
29417
29514
  function dateFilterXml(pivot, filter2) {
29418
29515
  const x15 = "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main";
29419
- return `<filters count="1"><filter${attrs({ fld: pivot.fields.indexOf(filter2.field), type: "dateBetween", evalOrder: -1, id: 1, name: filter2.field })}><autoFilter ref="A1"><filterColumn colId="0"><customFilters and="1"><customFilter operator="greaterThanOrEqual" val="${Math.floor(filter2.start)}"/><customFilter operator="lessThanOrEqual" val="${Math.floor(filter2.end)}"/></customFilters></filterColumn></autoFilter><extLst><ext uri="{0605FD5F-26C8-4aeb-8148-2DB25E43C511}" xmlns:x15="${x15}"><x15:pivotFilter useWholeDay="1"/></ext></extLst></filter></filters>`;
29516
+ const id = Number(/<filter [^>]*\bid="(\d+)"/.exec(pivot.sourceXml ?? "")?.[1] ?? 1);
29517
+ return `<filters count="1"><filter${attrs({ fld: pivot.fields.indexOf(filter2.field), type: "dateBetween", evalOrder: -1, id, name: filter2.field })}><autoFilter ref="A1"><filterColumn colId="0"><customFilters and="1"><customFilter operator="greaterThanOrEqual" val="${Math.floor(filter2.start)}"/><customFilter operator="lessThanOrEqual" val="${Math.floor(filter2.end)}"/></customFilters></filterColumn></autoFilter><extLst><ext uri="{0605FD5F-26C8-4aeb-8148-2DB25E43C511}" xmlns:x15="${x15}"><x15:pivotFilter useWholeDay="1"/></ext></extLst></filter></filters>`;
29420
29518
  }
29421
29519
 
29422
29520
  // xlsx/pivot/write.ts
@@ -29471,7 +29569,7 @@ var PivotWritePlan = class {
29471
29569
  this.tableParts.set(pivot, pivot.partName);
29472
29570
  continue;
29473
29571
  }
29474
- const table2 = pivot.partName ?? writer.uniqueName((n2) => `xl/pivotTables/pivotTable${n2}.xml`, reserved);
29572
+ const table3 = pivot.partName ?? writer.uniqueName((n2) => `xl/pivotTables/pivotTable${n2}.xml`, reserved);
29475
29573
  const definition = writer.uniqueName(
29476
29574
  (n2) => `xl/pivotCache/pivotCacheDefinition${n2}.xml`,
29477
29575
  reserved
@@ -29493,24 +29591,24 @@ var PivotWritePlan = class {
29493
29591
  TYPES2.definition
29494
29592
  );
29495
29593
  writer.rels(definition, cacheRels);
29496
- writer.add(table2, pivotTableXml(pivot, cacheId, cache3), TYPES2.table);
29594
+ writer.add(table3, pivotTableXml(pivot, cacheId, cache3), TYPES2.table);
29497
29595
  const tableRels = new RelationshipSet();
29498
- tableRels.add(RELATIONSHIP_TYPES.pivotCacheDefinition, relativeTarget(table2, definition));
29499
- writer.rels(table2, tableRels);
29596
+ tableRels.add(RELATIONSHIP_TYPES.pivotCacheDefinition, relativeTarget(table3, definition));
29597
+ writer.rels(table3, tableRels);
29500
29598
  const rid2 = bookRels.add(
29501
29599
  RELATIONSHIP_TYPES.pivotCacheDefinition,
29502
29600
  relativeTarget(bookPart, definition)
29503
29601
  );
29504
29602
  entries.push(`<pivotCache cacheId="${cacheId++}" r:id="${rid2}"/>`);
29505
- this.tableParts.set(pivot, table2);
29603
+ this.tableParts.set(pivot, table3);
29506
29604
  }
29507
29605
  this.cachesXml = owns ? entries.length ? `<pivotCaches>${entries.join("")}</pivotCaches>` : "" : void 0;
29508
29606
  }
29509
29607
  writeSheet(writer, sheet, part, rels) {
29510
29608
  for (const pivot of sheet.pivotTables ?? []) {
29511
- const table2 = this.tableParts.get(pivot);
29512
- writer.carry(table2);
29513
- rels.add(RELATIONSHIP_TYPES.pivotTable, relativeTarget(part, table2));
29609
+ const table3 = this.tableParts.get(pivot);
29610
+ writer.carry(table3);
29611
+ rels.add(RELATIONSHIP_TYPES.pivotTable, relativeTarget(part, table3));
29514
29612
  }
29515
29613
  }
29516
29614
  };
@@ -29680,9 +29778,9 @@ function slicerTarget(workbook, cache3) {
29680
29778
  const source2 = cache3.source;
29681
29779
  for (const [sheetIndex2, sheet] of workbook.sheets.entries()) {
29682
29780
  if (source2.kind === "table") {
29683
- const table2 = sheet.tables.find((entry3) => entry3.id === source2.tableId);
29684
- const offset2 = table2?.columns.findIndex((column2) => column2.sourceId === source2.column) ?? -1;
29685
- if (table2 && offset2 >= 0) return { kind: "table", sheet, sheetIndex: sheetIndex2, table: table2, offset: offset2 };
29781
+ const table3 = sheet.tables.find((entry3) => entry3.id === source2.tableId);
29782
+ const offset2 = table3?.columns.findIndex((column2) => column2.sourceId === source2.column) ?? -1;
29783
+ if (table3 && offset2 >= 0) return { kind: "table", sheet, sheetIndex: sheetIndex2, table: table3, offset: offset2 };
29686
29784
  } else {
29687
29785
  const first2 = source2.pivots[0];
29688
29786
  const pivot = first2 && sheet.sheetId === first2.tabId ? sheet.pivotTables?.find((entry3) => entry3.name === first2.name) : void 0;
@@ -29693,11 +29791,11 @@ function slicerTarget(workbook, cache3) {
29693
29791
  }
29694
29792
  var stateOf = (selected2, hasData) => selected2 ? hasData ? "selected" : "selectedNoData" : hasData ? "unselected" : "unselectedNoData";
29695
29793
  function tableItems(workbook, target) {
29696
- const { sheet, table: table2, offset: offset2 } = target;
29697
- const bounds = tableFilterBounds(table2);
29698
- const column2 = table2.columns[offset2];
29794
+ const { sheet, table: table3, offset: offset2 } = target;
29795
+ const bounds = tableFilterBounds(table3);
29796
+ const column2 = table3.columns[offset2];
29699
29797
  const col = bounds.start.col + offset2;
29700
- const filter2 = tableAutoFilter(table2);
29798
+ const filter2 = tableAutoFilter(table3);
29701
29799
  const others = filter2 && {
29702
29800
  ...filter2,
29703
29801
  columns: (filter2.columns ?? []).filter((entry3) => entry3.offset !== offset2)
@@ -29783,22 +29881,22 @@ function timelinePeriods(level, boundsStart, boundsEnd, locale = "en") {
29783
29881
  const year = d.getUTCFullYear();
29784
29882
  const month = d.getUTCMonth();
29785
29883
  let next;
29786
- let label5;
29884
+ let label2;
29787
29885
  let group;
29788
29886
  if (level === 0) {
29789
29887
  next = Date.UTC(year + 1, 0, 1);
29790
- label5 = group = String(year);
29888
+ label2 = group = String(year);
29791
29889
  } else if (level === 1) {
29792
29890
  next = Date.UTC(year, month + 3, 1);
29793
- label5 = `Q${Math.floor(month / 3) + 1}`;
29891
+ label2 = `Q${Math.floor(month / 3) + 1}`;
29794
29892
  group = String(year);
29795
29893
  } else if (level === 2) {
29796
29894
  next = Date.UTC(year, month + 1, 1);
29797
- label5 = monthName(cursor, locale);
29895
+ label2 = monthName(cursor, locale);
29798
29896
  group = String(year);
29799
29897
  } else {
29800
29898
  next = cursor;
29801
- label5 = "";
29899
+ label2 = "";
29802
29900
  group = "";
29803
29901
  }
29804
29902
  if (level === 3) {
@@ -29817,7 +29915,7 @@ function timelinePeriods(level, boundsStart, boundsEnd, locale = "en") {
29817
29915
  continue;
29818
29916
  }
29819
29917
  if (next > start)
29820
- out.push({ index: out.length, label: label5, group, first: ymd(cursor), last: ymd(next - DAY) });
29918
+ out.push({ index: out.length, label: label2, group, first: ymd(cursor), last: ymd(next - DAY) });
29821
29919
  cursor = next;
29822
29920
  }
29823
29921
  return out;
@@ -30075,12 +30173,12 @@ function slicerCacheXml(cache3, facts) {
30075
30173
  ext.setAttribute("xmlns:x15", X153);
30076
30174
  list.appendChild(ext);
30077
30175
  }
30078
- let table2 = first(ext, "tableSlicerCache", X153);
30079
- if (!table2) table2 = ext.appendChild(make2(X153, "x15:tableSlicerCache"));
30080
- table2.setAttribute("tableId", String(source2.tableId));
30081
- table2.setAttribute("column", String(source2.column));
30082
- if (cache3.sortOrder === "descending") table2.setAttribute("sortOrder", "descending");
30083
- else table2.removeAttribute("sortOrder");
30176
+ let table3 = first(ext, "tableSlicerCache", X153);
30177
+ if (!table3) table3 = ext.appendChild(make2(X153, "x15:tableSlicerCache"));
30178
+ table3.setAttribute("tableId", String(source2.tableId));
30179
+ table3.setAttribute("column", String(source2.column));
30180
+ if (cache3.sortOrder === "descending") table3.setAttribute("sortOrder", "descending");
30181
+ else table3.removeAttribute("sortOrder");
30084
30182
  return XML_HEADER + buildXml(root);
30085
30183
  }
30086
30184
 
@@ -30633,12 +30731,12 @@ function rewriteSheetFormulas(sheet, rewrite2, formulaCells) {
30633
30731
  }
30634
30732
  {
30635
30733
  const name = sheet.name;
30636
- for (const table2 of sheet.tables)
30637
- for (const [index3, column2] of table2.columns.entries())
30734
+ for (const table3 of sheet.tables)
30735
+ for (const [index3, column2] of table3.columns.entries())
30638
30736
  if (column2.calculatedColumnFormula !== void 0)
30639
30737
  column2.calculatedColumnFormula = safe(rewrite2, column2.calculatedColumnFormula, name, {
30640
- row: table2.range.start.row + (table2.headerRow ? 1 : 0),
30641
- col: table2.range.start.col + index3
30738
+ row: table3.range.start.row + (table3.headerRow ? 1 : 0),
30739
+ col: table3.range.start.col + index3
30642
30740
  });
30643
30741
  if (formulaCells) {
30644
30742
  for (const at of formulaCells) {
@@ -30703,14 +30801,14 @@ function tableHeaderAt(sheet, row2, col) {
30703
30801
  );
30704
30802
  }
30705
30803
  function syncTableHeader(ctx, sheet, row2, col, formulaCells) {
30706
- const table2 = tableHeaderAt(sheet, row2, col);
30707
- if (!table2) return;
30708
- const column2 = table2.columns[col - table2.range.start.col];
30804
+ const table3 = tableHeaderAt(sheet, row2, col);
30805
+ if (!table3) return;
30806
+ const column2 = table3.columns[col - table3.range.start.col];
30709
30807
  if (!column2) return;
30710
30808
  const text4 = displayText(ctx.workbook, getCell(sheet, row2, col)).trim();
30711
30809
  if (!text4 || column2.name === text4) return;
30712
30810
  const oldName = column2.name;
30713
- const others = table2.columns.filter((entry3) => entry3 !== column2).map((entry3) => entry3.name);
30811
+ const others = table3.columns.filter((entry3) => entry3 !== column2).map((entry3) => entry3.name);
30714
30812
  const newName = uniqueHeaders([...others, text4]).at(-1);
30715
30813
  column2.name = newName;
30716
30814
  if (newName !== text4) writeValue(sheet, row2, col, newName);
@@ -30720,10 +30818,10 @@ function syncTableHeader(ctx, sheet, row2, col, formulaCells) {
30720
30818
  ctx.workbook,
30721
30819
  (formula, formulaSheet, at) => renameTableColumnInFormula(
30722
30820
  formula,
30723
- table2.name,
30821
+ table3.name,
30724
30822
  oldName,
30725
30823
  newName,
30726
- formulaSheet === sheet.name && !!at && rangeContains(table2.range, at)
30824
+ formulaSheet === sheet.name && !!at && rangeContains(table3.range, at)
30727
30825
  ),
30728
30826
  cells
30729
30827
  );
@@ -31847,11 +31945,11 @@ function uniqueColumnName(columns) {
31847
31945
  const taken = new Set(columns.map((c2) => c2.name.toLowerCase()));
31848
31946
  for (let n2 = 1; ; n2++) if (!taken.has(`column${n2}`)) return `Column${n2}`;
31849
31947
  }
31850
- function shiftTable(sheet, table2, shift2, moveRange) {
31851
- const old = table2.range;
31948
+ function shiftTable(sheet, table3, shift2, moveRange) {
31949
+ const old = table3.range;
31852
31950
  const range = moveRange(old);
31853
31951
  if (!range) return [];
31854
- const next = { ...table2, range, columns: [...table2.columns] };
31952
+ const next = { ...table3, range, columns: [...table3.columns] };
31855
31953
  const widened = range.end.col - range.start.col !== old.end.col - old.start.col;
31856
31954
  if (shift2.axis === "col" && widened) {
31857
31955
  if (shift2.count > 0) {
@@ -32327,8 +32425,8 @@ function cellText(inner2) {
32327
32425
  ).replace(/ /g, " ").trim();
32328
32426
  }
32329
32427
  function parseHtmlTable(html, base) {
32330
- const table2 = /<table\b[^>]*>([\s\S]*?)<\/table>/i.exec(html)?.[1];
32331
- if (table2 === void 0) return void 0;
32428
+ const table3 = /<table\b[^>]*>([\s\S]*?)<\/table>/i.exec(html)?.[1];
32429
+ if (table3 === void 0) return void 0;
32332
32430
  const classes = /* @__PURE__ */ new Map();
32333
32431
  for (const block of html.matchAll(/<style\b[^>]*>([\s\S]*?)<\/style>/gi))
32334
32432
  for (const rule of removeAll(block[1] ?? "", ["<!--", "-->"]).matchAll(
@@ -32341,7 +32439,7 @@ function parseHtmlTable(html, base) {
32341
32439
  const hyperlinks = [];
32342
32440
  let r = 0;
32343
32441
  let spanned = 0;
32344
- for (const tr of table2.matchAll(/<tr\b[^>]*>([\s\S]*?)(?=<tr\b|<\/tbody|<\/table|$)/gi)) {
32442
+ for (const tr of table3.matchAll(/<tr\b[^>]*>([\s\S]*?)(?=<tr\b|<\/tbody|<\/table|$)/gi)) {
32345
32443
  const row2 = grid[r] ??= [];
32346
32444
  let c2 = 0;
32347
32445
  for (const td of (tr[1] ?? "").matchAll(
@@ -33193,9 +33291,9 @@ function filterColumn(ctx, s, col, values2) {
33193
33291
  }
33194
33292
  function sortByColumn(ctx, s, col, descending) {
33195
33293
  const sheet = sheetAt(ctx.workbook, s);
33196
- const table2 = sheet.tables.find((t) => col >= t.range.start.col && col <= t.range.end.col);
33294
+ const table3 = sheet.tables.find((t) => col >= t.range.start.col && col <= t.range.end.col);
33197
33295
  const filter2 = sheet.autoFilter;
33198
- const target = table2 ? { range: table2.range, header: table2.headerRow, totals: table2.totalsRow } : filter2 && rangeContains(filter2.range, { row: filter2.range.start.row, col }) ? { range: filter2.range, header: true, totals: false } : void 0;
33296
+ const target = table3 ? { range: table3.range, header: table3.headerRow, totals: table3.totalsRow } : filter2 && rangeContains(filter2.range, { row: filter2.range.start.row, col }) ? { range: filter2.range, header: true, totals: false } : void 0;
33199
33297
  if (!target) throw new Error("The column is not inside a table or an auto-filter range.");
33200
33298
  const range = target.totals ? { start: target.range.start, end: { ...target.range.end, row: target.range.end.row - 1 } } : target.range;
33201
33299
  ctx.run(
@@ -33212,13 +33310,13 @@ var DATA_TABLE_PART_ERROR = "Cannot change part of a data table.";
33212
33310
  function dataTableAt(sheet, row2, col) {
33213
33311
  return sheet.dataTables?.find((t) => rangeContains(t.ref, { row: row2, col }));
33214
33312
  }
33215
- function dataTableFormula(table2) {
33216
- if (table2.dt2D) return `TABLE(${table2.r1},${table2.r2 ?? ""})`;
33217
- return table2.dtr ? `TABLE(${table2.r1},)` : `TABLE(,${table2.r1})`;
33313
+ function dataTableFormula(table3) {
33314
+ if (table3.dt2D) return `TABLE(${table3.r1},${table3.r2 ?? ""})`;
33315
+ return table3.dtr ? `TABLE(${table3.r1},)` : `TABLE(,${table3.r1})`;
33218
33316
  }
33219
33317
  function dataTableFormulaText(sheet, row2, col) {
33220
- const table2 = dataTableAt(sheet, row2, col);
33221
- return table2 ? `{=${dataTableFormula(table2)}}` : void 0;
33318
+ const table3 = dataTableAt(sheet, row2, col);
33319
+ return table3 ? `{=${dataTableFormula(table3)}}` : void 0;
33222
33320
  }
33223
33321
  function cutsDataTable(sheet, range) {
33224
33322
  const r = normalizeRange(range);
@@ -33266,12 +33364,12 @@ function restore(sheet, saved) {
33266
33364
  Object.assign(cell, saved.fields);
33267
33365
  }
33268
33366
  var valueAt = (sheet, row2, col) => getCell(sheet, row2, col)?.value ?? null;
33269
- function computeDataTable(workbook, calc, sheetIndex2, table2) {
33367
+ function computeDataTable(workbook, calc, sheetIndex2, table3) {
33270
33368
  const sheet = sheetAt(workbook, sheetIndex2);
33271
- const { ref } = table2;
33272
- const first2 = parseInputCell(sheet, table2.r1);
33273
- const second = table2.dt2D && table2.r2 ? parseInputCell(sheet, table2.r2) : void 0;
33274
- if (!first2 || table2.dt2D && !second || table2.del1 || table2.del2) return [];
33369
+ const { ref } = table3;
33370
+ const first2 = parseInputCell(sheet, table3.r1);
33371
+ const second = table3.dt2D && table3.r2 ? parseInputCell(sheet, table3.r2) : void 0;
33372
+ if (!first2 || table3.dt2D && !second || table3.del1 || table3.del2) return [];
33275
33373
  const inputs = [first2, ...second ? [second] : []];
33276
33374
  const saved = inputs.map((p) => save(sheet, p.row, p.col));
33277
33375
  const top = ref.start.row - 1;
@@ -33290,11 +33388,11 @@ function computeDataTable(workbook, calc, sheetIndex2, table2) {
33290
33388
  for (let row2 = ref.start.row; row2 <= ref.end.row; row2++) {
33291
33389
  for (let col = ref.start.col; col <= ref.end.col; col++) {
33292
33390
  let formulaAt;
33293
- if (table2.dt2D) {
33391
+ if (table3.dt2D) {
33294
33392
  set(first2, valueAt(sheet, top, col));
33295
33393
  if (second) set(second, valueAt(sheet, row2, left2));
33296
33394
  formulaAt = { row: top, col: left2 };
33297
- } else if (table2.dtr) {
33395
+ } else if (table3.dtr) {
33298
33396
  set(first2, valueAt(sheet, top, col));
33299
33397
  formulaAt = { row: row2, col: left2 };
33300
33398
  } else {
@@ -33319,8 +33417,8 @@ function computeDataTable(workbook, calc, sheetIndex2, table2) {
33319
33417
  function refreshDataTables(workbook, calc) {
33320
33418
  const changed = [];
33321
33419
  workbook.sheets.forEach((sheet, index3) => {
33322
- for (const table2 of sheet.dataTables ?? [])
33323
- changed.push(...computeDataTable(workbook, calc, index3, table2));
33420
+ for (const table3 of sheet.dataTables ?? [])
33421
+ changed.push(...computeDataTable(workbook, calc, index3, table3));
33324
33422
  });
33325
33423
  if (changed.length) calc.recalculateFrom(changed);
33326
33424
  }
@@ -33344,17 +33442,17 @@ function resolve2(sheet, request) {
33344
33442
  const ref = cellRange(range.start.row + 1, range.start.col + 1, range.end.row, range.end.col);
33345
33443
  if ([row2, col].some((p) => p && rangeContains(ref, p))) return { problem: "input-inside" };
33346
33444
  const name = (p) => formatAddress(p);
33347
- const table2 = { ref, r1: "" };
33445
+ const table3 = { ref, r1: "" };
33348
33446
  if (row2 && col) {
33349
- table2.dt2D = true;
33350
- table2.dtr = true;
33351
- table2.r1 = name(row2);
33352
- table2.r2 = name(col);
33447
+ table3.dt2D = true;
33448
+ table3.dtr = true;
33449
+ table3.r1 = name(row2);
33450
+ table3.r2 = name(col);
33353
33451
  } else if (row2) {
33354
- table2.dtr = true;
33355
- table2.r1 = name(row2);
33356
- } else if (col) table2.r1 = name(col);
33357
- return { table: table2 };
33452
+ table3.dtr = true;
33453
+ table3.r1 = name(row2);
33454
+ } else if (col) table3.r1 = name(col);
33455
+ return { table: table3 };
33358
33456
  }
33359
33457
  function checkDataTable(workbook, sheetIndex2, request) {
33360
33458
  const result2 = resolve2(sheetAt(workbook, sheetIndex2), request);
@@ -33364,7 +33462,7 @@ function createDataTable(ctx, s, request) {
33364
33462
  const sheet = sheetAt(ctx.workbook, s);
33365
33463
  const result2 = resolve2(sheet, request);
33366
33464
  if ("problem" in result2) throw new Error(MESSAGES[result2.problem]);
33367
- const { table: table2 } = result2;
33465
+ const { table: table3 } = result2;
33368
33466
  const range = normalizeRange(request.range);
33369
33467
  ctx.run(
33370
33468
  "Data Table",
@@ -33375,16 +33473,16 @@ function createDataTable(ctx, s, request) {
33375
33473
  ],
33376
33474
  () => {
33377
33475
  sheet.dataTables = (sheet.dataTables ?? []).filter((t) => !rangesIntersect(t.ref, range));
33378
- sheet.dataTables.push(table2);
33379
- for (let row2 = table2.ref.start.row; row2 <= table2.ref.end.row; row2++)
33380
- for (let col = table2.ref.start.col; col <= table2.ref.end.col; col++) {
33476
+ sheet.dataTables.push(table3);
33477
+ for (let row2 = table3.ref.start.row; row2 <= table3.ref.end.row; row2++)
33478
+ for (let col = table3.ref.start.col; col <= table3.ref.end.col; col++) {
33381
33479
  const cell = ensureCell(sheet, row2, col);
33382
33480
  delete cell.formula;
33383
33481
  delete cell.arrayRange;
33384
33482
  delete cell.legacyFormula;
33385
33483
  delete cell.dynamicArray;
33386
33484
  }
33387
- computeDataTable(ctx.workbook, ctx.calc, s, table2);
33485
+ computeDataTable(ctx.workbook, ctx.calc, s, table3);
33388
33486
  },
33389
33487
  { sheet: s, ranges: [range] }
33390
33488
  );
@@ -34663,7 +34761,7 @@ function pictureAnchorAt(cell, width, height, maxWidth = 640) {
34663
34761
  }
34664
34762
 
34665
34763
  // xlsx/pivot/date-axes.ts
34666
- var dateGroupAxisNames = (group) => dateGroupUnits(group).reverse().map((unit) => dateGroupFieldName(unit, group.field));
34764
+ var dateGroupAxisNames = (group) => dateGroupUnits(group).reverse().map((unit) => dateGroupFieldName(unit, group.field, group));
34667
34765
  function replace(list, names, replacement) {
34668
34766
  const at = list.findIndex((name) => names.includes(name));
34669
34767
  if (at < 0) return list;
@@ -34699,7 +34797,9 @@ function reconcileDateAxes(next, previous) {
34699
34797
  if (columns.length > 1) next.moreColumnFields = columns.slice(1);
34700
34798
  else delete next.moreColumnFields;
34701
34799
  if (next.fieldSubtotals) {
34702
- const kept = next.fieldSubtotals.filter((entry3) => rows.includes(entry3.field));
34800
+ const kept = next.fieldSubtotals.filter(
34801
+ (entry3) => rows.includes(entry3.field) || columns.includes(entry3.field)
34802
+ );
34703
34803
  if (kept.length) next.fieldSubtotals = kept;
34704
34804
  else delete next.fieldSubtotals;
34705
34805
  }
@@ -34741,7 +34841,7 @@ function plan(ctx, s, pivot, old) {
34741
34841
  if (![start.row, start.col].every(Number.isInteger) || start.row < 0 || start.col < 0 || location.end.row > MAX_ROW || location.end.col > MAX_COL)
34742
34842
  throw new Error("The PivotTable result does not fit on the worksheet.");
34743
34843
  const source2 = sparklineDataRange(ctx.workbook, s, pivot.source);
34744
- if (source2.sheet === s && rangesIntersect(source2.range, location) || sheet.merges.some((range) => rangesIntersect(range, location)) || sheet.tables.some((table2) => rangesIntersect(table2.range, location)) || sheet.pivotTables?.some((other) => other !== old && rangesIntersect(other.location, location)))
34844
+ if (source2.sheet === s && rangesIntersect(source2.range, location) || sheet.merges.some((range) => rangesIntersect(range, location)) || sheet.tables.some((table3) => rangesIntersect(table3.range, location)) || sheet.pivotTables?.some((other) => other !== old && rangesIntersect(other.location, location)))
34745
34845
  throw new Error("The PivotTable would overlap source data, another table or merged cells.");
34746
34846
  let occupied = false;
34747
34847
  forEachCellInRange(sheet, location, (cell, row2, col) => {
@@ -34751,12 +34851,12 @@ function plan(ctx, s, pivot, old) {
34751
34851
  if (occupied) throw new Error("The PivotTable would overwrite existing cell content.");
34752
34852
  return { grid, location };
34753
34853
  }
34754
- function writePivot(ctx, s, pivot, old, label5, inside2) {
34854
+ function writePivot(ctx, s, pivot, old, label2, inside2) {
34755
34855
  const sheet = sheetAt(ctx.workbook, s);
34756
34856
  const { grid, location } = plan(ctx, s, pivot, old);
34757
34857
  const ranges = [...old ? [old.location] : [], location];
34758
34858
  ctx.run(
34759
- label5 ?? (old ? "Refresh PivotTable" : "Create PivotTable"),
34859
+ label2 ?? (old ? "Refresh PivotTable" : "Create PivotTable"),
34760
34860
  "annotations",
34761
34861
  [
34762
34862
  { kind: "parts", sheet: s, parts: ["pivotTables"] },
@@ -34813,8 +34913,10 @@ function createPivotTable(ctx, s, destination, options) {
34813
34913
  const name = options.name ?? uniqueName(ctx);
34814
34914
  checkName2(ctx, name);
34815
34915
  const aggregate3 = options.aggregate ?? "sum";
34916
+ const captions = authoredCaptions(options);
34816
34917
  const pivot = {
34817
34918
  ...data,
34919
+ ...captions ? { captions } : {},
34818
34920
  name,
34819
34921
  rowField: options.rowField,
34820
34922
  layout: options.layout ?? "tabular",
@@ -34828,12 +34930,12 @@ function createPivotTable(ctx, s, destination, options) {
34828
34930
  ...options.repeatLabels !== void 0 ? { repeatLabels: options.repeatLabels } : {},
34829
34931
  valueField: options.valueField,
34830
34932
  aggregate: aggregate3,
34831
- valueCaption: pivotCaption(aggregate3, options.valueField),
34933
+ valueCaption: pivotCaption(aggregate3, options.valueField, { captions }),
34832
34934
  ...options.pageFilter !== void 0 ? { pageFilter: structuredClone(options.pageFilter) } : {},
34833
34935
  ...options.fieldGroups?.length ? { fieldGroups: structuredClone(options.fieldGroups) } : {},
34834
34936
  ...options.valuesAxis !== void 0 ? { valuesAxis: options.valuesAxis } : {},
34835
34937
  ...options.valuesPosition !== void 0 ? { valuesPosition: options.valuesPosition } : {},
34836
- ...options.additionalValues ? { additionalValues: normalizedPivotMeasures(options.additionalValues) } : {},
34938
+ ...options.additionalValues ? { additionalValues: normalizedPivotMeasures(options.additionalValues, { captions }) } : {},
34837
34939
  location: { start: { ...destination }, end: { ...destination } },
34838
34940
  ...options.columnField ? { columnField: options.columnField } : {},
34839
34941
  ...options.columnField && options.moreColumnFields?.length ? { moreColumnFields: [...options.moreColumnFields] } : {}
@@ -34856,7 +34958,7 @@ function refreshPivotTable(ctx, s, name, patch3 = {}) {
34856
34958
  rowField: patch3.rowField ?? old.rowField,
34857
34959
  valueField,
34858
34960
  aggregate: aggregate3,
34859
- valueCaption: aggregate3 === old.aggregate && valueField === old.valueField ? old.valueCaption : pivotCaption(aggregate3, valueField)
34961
+ valueCaption: aggregate3 === old.aggregate && valueField === old.valueField ? old.valueCaption : pivotCaption(aggregate3, valueField, old)
34860
34962
  };
34861
34963
  if (patch3.columnField !== void 0) {
34862
34964
  if (patch3.columnField) next.columnField = patch3.columnField;
@@ -34906,7 +35008,7 @@ function refreshPivotTable(ctx, s, name, patch3 = {}) {
34906
35008
  else if (patch3.valuesAxis === "columns" || patch3.secondRowField === "")
34907
35009
  delete next.valuesPosition;
34908
35010
  if (patch3.additionalValues !== void 0) {
34909
- const measures = normalizedPivotMeasures(patch3.additionalValues);
35011
+ const measures = normalizedPivotMeasures(patch3.additionalValues, old);
34910
35012
  if (measures.length) next.additionalValues = measures;
34911
35013
  else delete next.additionalValues;
34912
35014
  }
@@ -34915,6 +35017,12 @@ function refreshPivotTable(ctx, s, name, patch3 = {}) {
34915
35017
  else delete next.dateFields;
34916
35018
  roundDateRecords(next, dates, ctx.workbook.date1904);
34917
35019
  if (next.dateFilter && !dates.includes(next.dateFilter.field)) delete next.dateFilter;
35020
+ if (patch3.fieldSubtotals === void 0 && next.fieldSubtotals) {
35021
+ const onAxes = [...pivotRowFields(next), ...pivotColumnFields(next)];
35022
+ const left2 = next.fieldSubtotals.filter((entry3) => onAxes.includes(entry3.field));
35023
+ if (left2.length) next.fieldSubtotals = left2;
35024
+ else delete next.fieldSubtotals;
35025
+ }
34918
35026
  const kept = pruneItemFilters(next);
34919
35027
  if (kept) next.itemFilters = kept;
34920
35028
  else delete next.itemFilters;
@@ -35370,10 +35478,10 @@ function validatePatch(group, patch3) {
35370
35478
  delete next.manualMax;
35371
35479
  validateSettings(next);
35372
35480
  }
35373
- function save2(ctx, s, next, label5, ranges) {
35481
+ function save2(ctx, s, next, label2, ranges) {
35374
35482
  const sheet = sheetAt(ctx.workbook, s);
35375
35483
  ctx.run(
35376
- label5,
35484
+ label2,
35377
35485
  "annotations",
35378
35486
  [{ kind: "parts", sheet: s, parts: ["preserved"] }],
35379
35487
  () => sheet.preserved.set("extLst", next),
@@ -35491,20 +35599,20 @@ function setSlicerSelection(ctx, cacheName, keys) {
35491
35599
  const target = slicerTarget(ctx.workbook, cache3);
35492
35600
  if (!target) throw new Error("The slicer has no data source.");
35493
35601
  if (target.kind === "table") {
35494
- const { sheet, table: table2, offset: offset2 } = target;
35602
+ const { sheet, table: table3, offset: offset2 } = target;
35495
35603
  ctx.run(
35496
35604
  keys === null ? "Clear slicer filter" : "Filter slicer",
35497
35605
  "view",
35498
35606
  [{ kind: "sheet", sheet: target.sheetIndex }],
35499
35607
  () => {
35500
- const column2 = table2.columns[offset2];
35608
+ const column2 = table3.columns[offset2];
35501
35609
  if (keys === null) delete column2.filter;
35502
35610
  else
35503
35611
  column2.filter = {
35504
35612
  values: keys.filter((key) => key !== ""),
35505
35613
  ...keys.includes("") ? { blank: true } : {}
35506
35614
  };
35507
- applyTableFilter(ctx.workbook, sheet, table2);
35615
+ applyTableFilter(ctx.workbook, sheet, table3);
35508
35616
  },
35509
35617
  { sheet: target.sheetIndex, structural: true }
35510
35618
  );
@@ -35575,17 +35683,17 @@ function unique2(base, taken) {
35575
35683
  function insertSlicer(ctx, s, ref) {
35576
35684
  const { workbook } = ctx;
35577
35685
  const sheet = sheetAt(workbook, s);
35578
- let table2;
35686
+ let table3;
35579
35687
  let pivot;
35580
35688
  let field;
35581
35689
  if (ref.kind === "table") {
35582
- table2 = sheet.tables.find(
35690
+ table3 = sheet.tables.find(
35583
35691
  (entry3) => entry3.name === ref.table || entry3.displayName === ref.table
35584
35692
  );
35585
- if (!table2?.headerRow || table2.filterNotModeled)
35693
+ if (!table3?.headerRow || table3.filterNotModeled)
35586
35694
  throw new Error("Choose a table with a header row and value filters.");
35587
35695
  field = ref.column;
35588
- if (!table2.columns.some((column2) => column2.name === field))
35696
+ if (!table3.columns.some((column2) => column2.name === field))
35589
35697
  throw new Error("Choose a column of the table.");
35590
35698
  } else {
35591
35699
  pivot = sheet.pivotTables?.find((entry3) => entry3.name === ref.pivot);
@@ -35605,7 +35713,7 @@ function insertSlicer(ctx, s, ref) {
35605
35713
  (c2) => names.has(c2.toLowerCase())
35606
35714
  ).replace(/ /g, "_");
35607
35715
  const metrics = createGridMetrics(sheet, { zoom: 100 });
35608
- const anchorCell = table2 ? { row: table2.range.start.row, col: table2.range.end.col + 2 } : { row: pivot.location.start.row, col: pivot.location.end.col + 2 };
35716
+ const anchorCell = table3 ? { row: table3.range.start.row, col: table3.range.end.col + 2 } : { row: pivot.location.start.row, col: pivot.location.end.col + 2 };
35609
35717
  const x = Math.max(metrics.colLeft(anchorCell.col), frameBounds(sheet) + 10);
35610
35718
  const box2 = { x, y: metrics.rowTop(anchorCell.row), ...SLICER_BOX };
35611
35719
  const anchor = pixelBoxToAnchor(sheet, box2, metrics, "twoCell");
@@ -35622,13 +35730,13 @@ function insertSlicer(ctx, s, ref) {
35622
35730
  () => {
35623
35731
  const book = cloneBook(workbook);
35624
35732
  let source2;
35625
- if (table2) {
35626
- if (table2.columns.some((column2) => column2.sourceId === void 0))
35627
- table2.columns.forEach((column2, index3) => column2.sourceId ??= index3 + 1);
35733
+ if (table3) {
35734
+ if (table3.columns.some((column2) => column2.sourceId === void 0))
35735
+ table3.columns.forEach((column2, index3) => column2.sourceId ??= index3 + 1);
35628
35736
  source2 = {
35629
35737
  kind: "table",
35630
- tableId: table2.id,
35631
- column: table2.columns.find((column2) => column2.name === field).sourceId
35738
+ tableId: table3.id,
35739
+ column: table3.columns.find((column2) => column2.name === field).sourceId
35632
35740
  };
35633
35741
  } else {
35634
35742
  const target = pivot;
@@ -36115,9 +36223,9 @@ var SUBTOTAL = {
36115
36223
  var: 110
36116
36224
  };
36117
36225
  var escapeColumn = (name) => name.replace(/['#[\]]/g, "'$&");
36118
- function applyTotalsRow(sheet, table2) {
36119
- const row2 = table2.range.end.row;
36120
- const { columns } = table2;
36226
+ function applyTotalsRow(sheet, table3) {
36227
+ const row2 = table3.range.end.row;
36228
+ const { columns } = table3;
36121
36229
  if (!columns.some((c2) => c2.totalsRowFunction || c2.totalsRowLabel)) {
36122
36230
  const first2 = columns[0];
36123
36231
  const last = columns[columns.length - 1];
@@ -36125,12 +36233,12 @@ function applyTotalsRow(sheet, table2) {
36125
36233
  if (last) last.totalsRowFunction = "sum";
36126
36234
  }
36127
36235
  columns.forEach((column2, i2) => {
36128
- const col = table2.range.start.col + i2;
36236
+ const col = table3.range.start.col + i2;
36129
36237
  const code = SUBTOTAL[column2.totalsRowFunction ?? ""];
36130
36238
  if (code !== void 0) {
36131
36239
  const cell = ensureCell(sheet, row2, col);
36132
36240
  clearContents(cell);
36133
- cell.formula = `SUBTOTAL(${code},${table2.name}[${escapeColumn(column2.name)}])`;
36241
+ cell.formula = `SUBTOTAL(${code},${table3.name}[${escapeColumn(column2.name)}])`;
36134
36242
  } else if (column2.totalsRowLabel && column2.totalsRowFunction !== "custom")
36135
36243
  writeValue(sheet, row2, col, column2.totalsRowLabel);
36136
36244
  });
@@ -36154,8 +36262,8 @@ function validateTableName(workbook, name, self) {
36154
36262
  ) || workbook.definedNames.some((n2) => n2.name.toLowerCase() === lower3);
36155
36263
  return taken ? "That name is already used by another table or name." : void 0;
36156
36264
  }
36157
- function renameTableIn(workbook, table2, name) {
36158
- const old = table2.name;
36265
+ function renameTableIn(workbook, table3, name) {
36266
+ const old = table3.name;
36159
36267
  if (old === name) return;
36160
36268
  const rename = (f6) => renameTableInFormula(f6, old, name);
36161
36269
  rewriteFormulas(workbook, rename);
@@ -36164,73 +36272,73 @@ function renameTableIn(workbook, table2, name) {
36164
36272
  for (const column2 of t.columns)
36165
36273
  if (column2.calculatedColumnFormula)
36166
36274
  column2.calculatedColumnFormula = rename(column2.calculatedColumnFormula);
36167
- table2.name = name;
36168
- table2.displayName = name;
36275
+ table3.name = name;
36276
+ table3.displayName = name;
36169
36277
  }
36170
36278
  var byId = (sheet, id) => {
36171
- const table2 = sheet.tables.find((t) => t.id === id);
36172
- if (!table2) throw new Error("The table disappeared during the edit.");
36173
- return table2;
36279
+ const table3 = sheet.tables.find((t) => t.id === id);
36280
+ if (!table3) throw new Error("The table disappeared during the edit.");
36281
+ return table3;
36174
36282
  };
36175
- function insertBandRow(workbook, sheet, table2, row2) {
36283
+ function insertBandRow(workbook, sheet, table3, row2) {
36176
36284
  const shift2 = { axis: "row", at: row2, count: 1 };
36177
- const band = { lo: table2.range.start.col, hi: table2.range.end.col };
36285
+ const band = { lo: table3.range.start.col, hi: table3.range.end.col };
36178
36286
  assertInsertFits(sheet, shift2, band);
36179
36287
  rewriteFormulas(workbook, (f6, fs) => shiftFormulaInBand(f6, fs, sheet.name, shift2, band));
36180
36288
  shiftSheetContent(sheet, shift2, band);
36181
36289
  }
36182
36290
  function setHeaderRow(workbook, sheet, id, on) {
36183
- let table2 = byId(sheet, id);
36184
- if (table2.headerRow === on) return;
36185
- const { start, end } = table2.range;
36291
+ let table3 = byId(sheet, id);
36292
+ if (table3.headerRow === on) return;
36293
+ const { start, end } = table3.range;
36186
36294
  if (!on) {
36187
36295
  if (start.row === end.row) throw new Error("A table needs at least one row.");
36188
36296
  clearRow(sheet, start.row, start.col, end.col);
36189
- table2.range = { start: { row: start.row + 1, col: start.col }, end };
36190
- table2.headerRow = false;
36297
+ table3.range = { start: { row: start.row + 1, col: start.col }, end };
36298
+ table3.headerRow = false;
36191
36299
  return;
36192
36300
  }
36193
36301
  if (start.row === 0 || !rowIsEmpty(sheet, start.row - 1, start.col, end.col)) {
36194
- insertBandRow(workbook, sheet, table2, start.row);
36195
- table2 = byId(sheet, id);
36196
- }
36197
- const top = table2.range.start.row - 1;
36198
- const left2 = table2.range.start.col;
36199
- table2.range = { start: { row: top, col: left2 }, end: table2.range.end };
36200
- table2.headerRow = true;
36201
- uniqueHeaders(table2.columns.map((c2) => c2.name)).forEach((name, i2) => {
36202
- const column2 = table2.columns[i2];
36302
+ insertBandRow(workbook, sheet, table3, start.row);
36303
+ table3 = byId(sheet, id);
36304
+ }
36305
+ const top = table3.range.start.row - 1;
36306
+ const left2 = table3.range.start.col;
36307
+ table3.range = { start: { row: top, col: left2 }, end: table3.range.end };
36308
+ table3.headerRow = true;
36309
+ uniqueHeaders(table3.columns.map((c2) => c2.name)).forEach((name, i2) => {
36310
+ const column2 = table3.columns[i2];
36203
36311
  if (column2) column2.name = name;
36204
36312
  writeValue(sheet, top, left2 + i2, name);
36205
36313
  });
36206
36314
  }
36207
36315
  function setTotalsRow(workbook, sheet, id, on) {
36208
- let table2 = byId(sheet, id);
36209
- if (table2.totalsRow === on) return;
36210
- const { start, end } = table2.range;
36316
+ let table3 = byId(sheet, id);
36317
+ if (table3.totalsRow === on) return;
36318
+ const { start, end } = table3.range;
36211
36319
  if (!on) {
36212
36320
  clearRow(sheet, end.row, start.col, end.col);
36213
- table2.range = { start, end: { row: end.row - 1, col: end.col } };
36214
- table2.totalsRow = false;
36321
+ table3.range = { start, end: { row: end.row - 1, col: end.col } };
36322
+ table3.totalsRow = false;
36215
36323
  return;
36216
36324
  }
36217
36325
  if (end.row === MAX_ROW) throw new RangeError("The insert area extends beyond the sheet.");
36218
36326
  if (!rowIsEmpty(sheet, end.row + 1, start.col, end.col)) {
36219
- insertBandRow(workbook, sheet, table2, end.row + 1);
36220
- table2 = byId(sheet, id);
36327
+ insertBandRow(workbook, sheet, table3, end.row + 1);
36328
+ table3 = byId(sheet, id);
36221
36329
  }
36222
- table2.range = { start: table2.range.start, end: { row: table2.range.end.row + 1, col: end.col } };
36223
- table2.totalsRow = true;
36224
- applyTotalsRow(sheet, table2);
36330
+ table3.range = { start: table3.range.start, end: { row: table3.range.end.row + 1, col: end.col } };
36331
+ table3.totalsRow = true;
36332
+ applyTotalsRow(sheet, table3);
36225
36333
  }
36226
- function resizedColumns(workbook, sheet, table2, range) {
36334
+ function resizedColumns(workbook, sheet, table3, range) {
36227
36335
  const width = range.end.col - range.start.col + 1;
36228
- const oldAt = (col) => col >= table2.range.start.col && col <= table2.range.end.col ? table2.columns[col - table2.range.start.col] : void 0;
36336
+ const oldAt = (col) => col >= table3.range.start.col && col <= table3.range.end.col ? table3.columns[col - table3.range.start.col] : void 0;
36229
36337
  const texts = Array.from({ length: width }, (_v, i2) => {
36230
36338
  const col = range.start.col + i2;
36231
36339
  const old = oldAt(col);
36232
36340
  if (old) return old.name;
36233
- return table2.headerRow ? displayText(workbook, getCell(sheet, range.start.row, col)) : "";
36341
+ return table3.headerRow ? displayText(workbook, getCell(sheet, range.start.row, col)) : "";
36234
36342
  });
36235
36343
  return uniqueHeaders(texts).map((name, i2) => {
36236
36344
  const old = oldAt(range.start.col + i2);
@@ -36238,30 +36346,30 @@ function resizedColumns(workbook, sheet, table2, range) {
36238
36346
  });
36239
36347
  }
36240
36348
  function resizeTableIn(workbook, sheet, id, range) {
36241
- const table2 = byId(sheet, id);
36349
+ const table3 = byId(sheet, id);
36242
36350
  const r = normalizeRange(range);
36243
- if (table2.headerRow && r.start.row !== table2.range.start.row)
36351
+ if (table3.headerRow && r.start.row !== table3.range.start.row)
36244
36352
  throw new Error("The table headers must remain in the same row.");
36245
- if (!rangesIntersect(r, table2.range)) throw new Error("The new range must overlap the table.");
36246
- if (r.end.row - r.start.row + 1 < (table2.headerRow ? 2 : 1) + (table2.totalsRow ? 1 : 0))
36353
+ if (!rangesIntersect(r, table3.range)) throw new Error("The new range must overlap the table.");
36354
+ if (r.end.row - r.start.row + 1 < (table3.headerRow ? 2 : 1) + (table3.totalsRow ? 1 : 0))
36247
36355
  throw new Error("The table range is too small.");
36248
- if (sheet.tables.some((t) => t !== table2 && rangesIntersect(t.range, r)))
36356
+ if (sheet.tables.some((t) => t !== table3 && rangesIntersect(t.range, r)))
36249
36357
  throw new Error("A table cannot overlap another table.");
36250
36358
  if (sheet.pivotTables?.some((pivot) => rangesIntersect(pivot.location, r)))
36251
36359
  throw new Error("A table cannot overlap a PivotTable.");
36252
36360
  if (sheet.merges.some((m) => rangesIntersect(m, r)))
36253
36361
  throw new Error("A table cannot contain merged cells.");
36254
- const oldEnd = table2.range.end.row;
36255
- table2.columns = resizedColumns(workbook, sheet, table2, r);
36256
- table2.range = r;
36257
- if (table2.headerRow)
36258
- table2.columns.forEach((column2, i2) => {
36362
+ const oldEnd = table3.range.end.row;
36363
+ table3.columns = resizedColumns(workbook, sheet, table3, r);
36364
+ table3.range = r;
36365
+ if (table3.headerRow)
36366
+ table3.columns.forEach((column2, i2) => {
36259
36367
  const cell = getCell(sheet, r.start.row, r.start.col + i2);
36260
36368
  if (cell?.value !== column2.name) writeValue(sheet, r.start.row, r.start.col + i2, column2.name);
36261
36369
  });
36262
- if (table2.totalsRow) {
36370
+ if (table3.totalsRow) {
36263
36371
  if (oldEnd !== r.end.row) clearRow(sheet, oldEnd, r.start.col, r.end.col);
36264
- applyTotalsRow(sheet, table2);
36372
+ applyTotalsRow(sheet, table3);
36265
36373
  }
36266
36374
  }
36267
36375
  var STYLE_KEYS = [
@@ -36289,20 +36397,20 @@ function updateTable(ctx, s, ref, patch3) {
36289
36397
  "structure",
36290
36398
  [scope],
36291
36399
  () => {
36292
- const table2 = byId(sheet, id);
36293
- if (renaming) renameTableIn(workbook, table2, name);
36400
+ const table3 = byId(sheet, id);
36401
+ if (renaming) renameTableIn(workbook, table3, name);
36294
36402
  for (const key of STYLE_KEYS) {
36295
36403
  if (!(key in patch3)) continue;
36296
36404
  const value2 = patch3[key];
36297
- if (value2 === void 0) delete table2[key];
36298
- else table2[key] = value2;
36405
+ if (value2 === void 0) delete table3[key];
36406
+ else table3[key] = value2;
36299
36407
  }
36300
36408
  if (patch3.columns) {
36301
- const width = table2.range.end.col - table2.range.start.col + 1;
36409
+ const width = table3.range.end.col - table3.range.start.col + 1;
36302
36410
  if (patch3.columns.length !== width) throw new Error("Give one column per table column.");
36303
- const before = table2.columns;
36304
- table2.columns = structuredClone(patch3.columns);
36305
- for (const [index3, column2] of table2.columns.entries()) {
36411
+ const before = table3.columns;
36412
+ table3.columns = structuredClone(patch3.columns);
36413
+ for (const [index3, column2] of table3.columns.entries()) {
36306
36414
  const sourceId = before[index3]?.sourceId;
36307
36415
  if (column2.sourceId === void 0 && sourceId !== void 0) column2.sourceId = sourceId;
36308
36416
  const filter2 = before[index3]?.filter;
@@ -36311,7 +36419,7 @@ function updateTable(ctx, s, ref, patch3) {
36311
36419
  }
36312
36420
  if (patch3.headerRow !== void 0) setHeaderRow(workbook, sheet, id, patch3.headerRow);
36313
36421
  if (patch3.totalsRow !== void 0) setTotalsRow(workbook, sheet, id, patch3.totalsRow);
36314
- else if (patch3.columns && table2.totalsRow) applyTotalsRow(sheet, byId(sheet, id));
36422
+ else if (patch3.columns && table3.totalsRow) applyTotalsRow(sheet, byId(sheet, id));
36315
36423
  if (patch3.range) resizeTableIn(workbook, sheet, id, patch3.range);
36316
36424
  },
36317
36425
  { sheet: s, ranges: [current.range], structural: true }
@@ -36331,13 +36439,13 @@ function resizeTable(ctx, s, ref, range) {
36331
36439
  function convertTableToRange(ctx, s, ref) {
36332
36440
  const { workbook } = ctx;
36333
36441
  const sheet = sheetAt(workbook, s);
36334
- const table2 = sheet.tables[tableIndex(sheet, ref)];
36442
+ const table3 = sheet.tables[tableIndex(sheet, ref)];
36335
36443
  ctx.run(
36336
36444
  "Convert to range",
36337
36445
  "structure",
36338
36446
  [{ kind: "workbook" }],
36339
36447
  () => {
36340
- const live = byId(sheet, table2.id);
36448
+ const live = byId(sheet, table3.id);
36341
36449
  const base = { table: live, tableSheet: sheet.name };
36342
36450
  const { start, end } = live.range;
36343
36451
  for (const ws of workbook.sheets)
@@ -36362,7 +36470,7 @@ function convertTableToRange(ctx, s, ref) {
36362
36470
  });
36363
36471
  sheet.tables = sheet.tables.filter((t) => t.id !== live.id);
36364
36472
  },
36365
- { sheet: s, ranges: [table2.range], structural: true }
36473
+ { sheet: s, ranges: [table3.range], structural: true }
36366
36474
  );
36367
36475
  }
36368
36476
 
@@ -39313,7 +39421,7 @@ function createTable(ctx, s, range, hasHeader, styleName = "TableStyleMedium2")
39313
39421
  });
39314
39422
  const name = nextTableName(workbook);
39315
39423
  const id = Math.max(0, ...workbook.sheets.flatMap((ws) => ws.tables.map((t) => t.id))) + 1;
39316
- const table2 = {
39424
+ const table3 = {
39317
39425
  id,
39318
39426
  name,
39319
39427
  displayName: name,
@@ -39327,8 +39435,8 @@ function createTable(ctx, s, range, hasHeader, styleName = "TableStyleMedium2")
39327
39435
  showFirstColumn: false,
39328
39436
  showLastColumn: false
39329
39437
  };
39330
- sheet.tables.push(table2);
39331
- return table2;
39438
+ sheet.tables.push(table3);
39439
+ return table3;
39332
39440
  },
39333
39441
  { sheet: s, ranges: [r], structural: !hasHeader }
39334
39442
  );
@@ -39546,8 +39654,8 @@ function createEditSession(workbook, options = {}) {
39546
39654
  if (!workbook.warnings.includes(message)) workbook.warnings.push(message);
39547
39655
  }
39548
39656
  };
39549
- const begin = (label5, kind, info) => {
39550
- const step2 = { label: label5, entries: [], structural: info.structural ?? false };
39657
+ const begin = (label2, kind, info) => {
39658
+ const step2 = { label: label2, entries: [], structural: info.structural ?? false };
39551
39659
  if (info.calc) step2.calc = info.calc;
39552
39660
  return { step: step2, kind, sheet: info.sheet, ranges: [...info.ranges ?? []] };
39553
39661
  };
@@ -39571,7 +39679,7 @@ function createEditSession(workbook, options = {}) {
39571
39679
  }
39572
39680
  current.step.entries.length = from;
39573
39681
  };
39574
- const run2 = (label5, kind, scopes, fn, info = {}) => {
39682
+ const run2 = (label2, kind, scopes, fn, info = {}) => {
39575
39683
  if (kind === "cells") {
39576
39684
  for (const scope of scopes)
39577
39685
  if (scope.kind === "cells" && workbook.sheets[scope.sheet]?.pivotTables?.some(
@@ -39588,7 +39696,7 @@ function createEditSession(workbook, options = {}) {
39588
39696
  }))
39589
39697
  throw new Error(DATA_TABLE_PART_ERROR);
39590
39698
  const outer = !open;
39591
- const current = open ?? begin(label5, kind, info);
39699
+ const current = open ?? begin(label2, kind, info);
39592
39700
  if (!outer) {
39593
39701
  delete current.step.calc;
39594
39702
  if (info.structural) current.step.structural = true;
@@ -39719,9 +39827,9 @@ function createEditSession(workbook, options = {}) {
39719
39827
  removeConditionalFormat: (s, index3) => removeConditionalFormat(ctx, s, index3),
39720
39828
  setConditionalRulePriority: (s, f6, r, priority) => setConditionalRulePriority(ctx, s, f6, r, priority),
39721
39829
  moveConditionalRule: (s, f6, r, direction) => moveConditionalRule(ctx, s, f6, r, direction),
39722
- updateTable: (s, table2, patch3) => updateTable(ctx, s, table2, patch3),
39723
- resizeTable: (s, table2, range) => resizeTable(ctx, s, table2, range),
39724
- convertTableToRange: (s, table2) => convertTableToRange(ctx, s, table2),
39830
+ updateTable: (s, table3, patch3) => updateTable(ctx, s, table3, patch3),
39831
+ resizeTable: (s, table3, range) => resizeTable(ctx, s, table3, range),
39832
+ convertTableToRange: (s, table3) => convertTableToRange(ctx, s, table3),
39725
39833
  applyCellStyle: (s, ranges, name) => applyCellStyle(ctx, s, ranges, name),
39726
39834
  setPageSetup: (s, patch3) => setPageSetup(ctx, s, patch3),
39727
39835
  setPageBreak: (s, axis, before, present2) => setPageBreak(ctx, s, axis, before, present2),
@@ -39758,12 +39866,12 @@ function createEditSession(workbook, options = {}) {
39758
39866
  validate: (s, r, c2, value2) => validateCellInput(workbook, s, r, c2, value2, {
39759
39867
  evaluate: (formula, at) => calc.evaluate(formula, at)
39760
39868
  }),
39761
- batch(label5, fn) {
39869
+ batch(label2, fn) {
39762
39870
  if (open) {
39763
39871
  fn();
39764
39872
  return;
39765
39873
  }
39766
- const current = begin(label5, "batch", {});
39874
+ const current = begin(label2, "batch", {});
39767
39875
  open = current;
39768
39876
  try {
39769
39877
  fn();
@@ -40697,16 +40805,16 @@ function normalizeLevels(levels, pointCount) {
40697
40805
  return levels.map((level) => {
40698
40806
  let previous = "";
40699
40807
  return Array.from({ length: pointCount }, (_, index3) => {
40700
- const label5 = level[index3]?.trim() ?? "";
40701
- if (label5) previous = label5;
40702
- return label5 || previous;
40808
+ const label2 = level[index3]?.trim() ?? "";
40809
+ if (label2) previous = label2;
40810
+ return label2 || previous;
40703
40811
  });
40704
40812
  });
40705
40813
  }
40706
- function findOrAddParent(children2, label5, colorIndex, parentLabelLayout) {
40707
- const existing = children2.find((child3) => child3.children && child3.label === label5);
40814
+ function findOrAddParent(children2, label2, colorIndex, parentLabelLayout) {
40815
+ const existing = children2.find((child3) => child3.children && child3.label === label2);
40708
40816
  if (existing?.children) return existing;
40709
- const parent = { label: label5, weight: 0, children: [], colorIndex, parentLabelLayout };
40817
+ const parent = { label: label2, weight: 0, children: [], colorIndex, parentLabelLayout };
40710
40818
  children2.push(parent);
40711
40819
  return parent;
40712
40820
  }
@@ -40718,8 +40826,8 @@ function buildSeriesHierarchy(series, seriesIndex, categoryLabels, categoryLevel
40718
40826
  for (let pointIndex = 0; pointIndex < pointCount; pointIndex++) {
40719
40827
  let children2 = roots;
40720
40828
  for (let levelIndex = levels.length - 1; levelIndex >= 1; levelIndex--) {
40721
- const label5 = levels[levelIndex]?.[pointIndex] || `Group ${levelIndex}`;
40722
- children2 = findOrAddParent(children2, label5, pointIndex, layout2).children;
40829
+ const label2 = levels[levelIndex]?.[pointIndex] || `Group ${levelIndex}`;
40830
+ children2 = findOrAddParent(children2, label2, pointIndex, layout2).children;
40723
40831
  }
40724
40832
  children2.push({
40725
40833
  label: levels[0]?.[pointIndex] || categoryLabels[pointIndex] || String(pointIndex + 1),
@@ -40763,7 +40871,7 @@ function hierarchyBranchLabels(series, categoryLabels, categoryLevels2) {
40763
40871
  const pointCount = series[0]?.values.length ?? categoryLabels.length;
40764
40872
  const topLevel = normalizeLevels(categoryLevels2, pointCount).at(-1) ?? [];
40765
40873
  const seen = [];
40766
- for (const label5 of topLevel) if (!seen.includes(label5)) seen.push(label5);
40874
+ for (const label2 of topLevel) if (!seen.includes(label2)) seen.push(label2);
40767
40875
  return seen;
40768
40876
  }
40769
40877
  return [...categoryLabels];
@@ -41178,7 +41286,7 @@ function liveLevels(ref, evaluateRef) {
41178
41286
  const flat = columns > 1 ? resolveRef(ref, evaluateRef)?.map(toText2) : void 0;
41179
41287
  if (!flat || flat.length % columns !== 0) return void 0;
41180
41288
  const levels = Array.from({ length: columns }, () => []);
41181
- flat.forEach((label5, i2) => levels[columns - 1 - i2 % columns]?.push(label5));
41289
+ flat.forEach((label2, i2) => levels[columns - 1 - i2 % columns]?.push(label2));
41182
41290
  return levels;
41183
41291
  }
41184
41292
  function hierarchyView(chart, model, evaluateRef) {
@@ -41364,12 +41472,12 @@ function groupRowsByCategory(rawCategories) {
41364
41472
  const uniqueCategories = [];
41365
41473
  const rowIndexesByCategory = /* @__PURE__ */ new Map();
41366
41474
  rawCategories.forEach((rawLabel, rowIndex) => {
41367
- const label5 = rawLabel ?? "";
41368
- let rows = rowIndexesByCategory.get(label5);
41475
+ const label2 = rawLabel ?? "";
41476
+ let rows = rowIndexesByCategory.get(label2);
41369
41477
  if (!rows) {
41370
41478
  rows = [];
41371
- rowIndexesByCategory.set(label5, rows);
41372
- uniqueCategories.push(label5);
41479
+ rowIndexesByCategory.set(label2, rows);
41480
+ uniqueCategories.push(label2);
41373
41481
  }
41374
41482
  rows.push(rowIndex);
41375
41483
  });
@@ -41458,11 +41566,11 @@ function computeHistogramBins(values2, options, format = String) {
41458
41566
  }
41459
41567
  function aggregateByCategory(values2, rawCategories) {
41460
41568
  const { uniqueCategories, rowIndexesByCategory } = groupRowsByCategory(rawCategories);
41461
- return uniqueCategories.map((label5) => {
41462
- const rows = rowIndexesByCategory.get(label5) ?? [];
41569
+ return uniqueCategories.map((label2) => {
41570
+ const rows = rowIndexesByCategory.get(label2) ?? [];
41463
41571
  return {
41464
41572
  value: rows.reduce((sum3, row2) => sum3 + (values2[row2] ?? 0), 0),
41465
- label: label5,
41573
+ label: label2,
41466
41574
  sourceIndices: rows
41467
41575
  };
41468
41576
  });
@@ -42266,17 +42374,17 @@ function cartesianAxes(model, area, out) {
42266
42374
  out.push(chartAreaRect(model, "plotArea", plot2));
42267
42375
  scale2.ticks.forEach((t, i2) => {
42268
42376
  const p = value2(t);
42269
- const label5 = labels[i2] ?? "";
42377
+ const label2 = labels[i2] ?? "";
42270
42378
  if (horizontal) {
42271
42379
  out.push(line2(p, plot2.y, p, plot2.y + plot2.h, grid.color, grid.width));
42272
42380
  if (valueLabels)
42273
42381
  out.push(
42274
- text3(p, plot2.y + plot2.h + valueSize + 2, label5, { anchor: "middle", ...valueAttrs })
42382
+ text3(p, plot2.y + plot2.h + valueSize + 2, label2, { anchor: "middle", ...valueAttrs })
42275
42383
  );
42276
42384
  } else {
42277
42385
  out.push(line2(plot2.x, p, plot2.x + plot2.w, p, grid.color, grid.width));
42278
42386
  if (valueLabels)
42279
- out.push(text3(plot2.x - 4, p + valueSize * 0.3, label5, { anchor: "end", ...valueAttrs }));
42387
+ out.push(text3(plot2.x - 4, p + valueSize * 0.3, label2, { anchor: "end", ...valueAttrs }));
42280
42388
  }
42281
42389
  });
42282
42390
  const zero = value2(Math.min(Math.max(0, scale2.min), scale2.max));
@@ -42894,10 +43002,10 @@ function sunburstSvg(model, area) {
42894
43002
  );
42895
43003
  const flatLabels = levels.length > 1 || model.series.length !== 1 ? void 0 : model.categories;
42896
43004
  for (const arc of model.hierarchy?.labels === false ? [] : arcs) {
42897
- const label5 = arc.label ?? (arc.pointIndex === void 0 ? void 0 : flatLabels?.[arc.pointIndex]);
42898
- if (!label5) continue;
43005
+ const label2 = arc.label ?? (arc.pointIndex === void 0 ? void 0 : flatLabels?.[arc.pointIndex]);
43006
+ if (!label2) continue;
42899
43007
  out.push(
42900
- `<text x="${n(arc.labelX)}" y="${n(arc.labelY)}" font-size="10" fill="#FFFFFF" text-anchor="middle" dominant-baseline="central" transform="rotate(${n(arc.labelRotation)}, ${n(arc.labelX)}, ${n(arc.labelY)})">${esc(label5)}</text>`
43008
+ `<text x="${n(arc.labelX)}" y="${n(arc.labelY)}" font-size="10" fill="#FFFFFF" text-anchor="middle" dominant-baseline="central" transform="rotate(${n(arc.labelRotation)}, ${n(arc.labelX)}, ${n(arc.labelY)})">${esc(label2)}</text>`
42901
43009
  );
42902
43010
  }
42903
43011
  return out.join("");
@@ -42968,7 +43076,7 @@ function chartLegendSvg(model, area, frame, options) {
42968
43076
  const baselineOffset = font ? (font.ascent - font.descent) / 2 : size * 0.35;
42969
43077
  entries.forEach((entry3, i2) => {
42970
43078
  const available = horizontal ? chartTextWidth(entry3.label, attrs2, options) : Math.max(0, rowWidth - size / 2 - keySize - keyGap);
42971
- const label5 = fitChartText(entry3.label, available, attrs2, options);
43079
+ const label2 = fitChartText(entry3.label, available, attrs2, options);
42972
43080
  const contentWidth = Math.min(
42973
43081
  horizontal ? widths[i2] ?? 0 : Math.max(...widths),
42974
43082
  rowWidth - size / 2
@@ -42976,7 +43084,7 @@ function chartLegendSvg(model, area, frame, options) {
42976
43084
  const x = horizontal ? horizontalX : manual.x + Math.max(size / 4, (rowWidth - contentWidth) / 2);
42977
43085
  const centerY = manual.y + (horizontal ? 0 : i2 * rowHeight) + rowHeight / 2;
42978
43086
  markup.push(rect(x, centerY - keySize / 2, keySize, keySize, entry3.color));
42979
- markup.push(text3(x + keySize + keyGap, centerY + baselineOffset, label5, attrs2));
43087
+ markup.push(text3(x + keySize + keyGap, centerY + baselineOffset, label2, attrs2));
42980
43088
  if (horizontal) horizontalX += (widths[i2] ?? 0) + horizontalGap;
42981
43089
  });
42982
43090
  return {
@@ -42988,15 +43096,15 @@ function chartLegendSvg(model, area, frame, options) {
42988
43096
  function legendEntries(model) {
42989
43097
  if (model.type === "pie" || model.type === "doughnut") {
42990
43098
  const first2 = model.series[0];
42991
- return model.categories.map((label5, i2) => ({
42992
- label: label5,
43099
+ return model.categories.map((label2, i2) => ({
43100
+ label: label2,
42993
43101
  color: first2?.pointColors?.[i2] ?? first2?.color ?? "#4472C4"
42994
43102
  }));
42995
43103
  }
42996
43104
  if ((model.type === "treemap" || model.type === "sunburst") && model.hierarchy) {
42997
43105
  const first2 = model.series[0];
42998
- return model.hierarchy.branches.map((label5, i2) => ({
42999
- label: label5,
43106
+ return model.hierarchy.branches.map((label2, i2) => ({
43107
+ label: label2,
43000
43108
  color: first2?.pointColors?.[i2 % Math.max(1, first2.pointColors.length)] ?? first2?.color ?? "#4472C4"
43001
43109
  }));
43002
43110
  }
@@ -43289,8 +43397,8 @@ function renderChartSvg(model, width, height, options = {}) {
43289
43397
  } else if (model.title) {
43290
43398
  const attrs2 = chartTextAttributes(model, "title", 14);
43291
43399
  const size = attrs2.size ?? 14;
43292
- const label5 = fitChartText(model.title, w - 16, attrs2, options);
43293
- const titleWidth = Math.min(w - 16, chartTextWidth(label5, attrs2, options) + 8);
43400
+ const label2 = fitChartText(model.title, w - 16, attrs2, options);
43401
+ const titleWidth = Math.min(w - 16, chartTextWidth(label2, attrs2, options) + 8);
43294
43402
  const font = chartFontMetrics(attrs2, options);
43295
43403
  const titleHeight = Math.max(24, font ? font.ascent + font.descent + 4 : size * 1.4 + 4);
43296
43404
  out.push(
@@ -43302,7 +43410,7 @@ function renderChartSvg(model, width, height, options = {}) {
43302
43410
  })
43303
43411
  );
43304
43412
  out.push(
43305
- text3(w / 2, 8 + size, label5, {
43413
+ text3(w / 2, 8 + size, label2, {
43306
43414
  anchor: "middle",
43307
43415
  fill: "#404040",
43308
43416
  ...attrs2
@@ -44258,4 +44366,4 @@ function slicerStyleLabel(name) {
44258
44366
  return { family: match2?.[1] ?? "Light", index: Number(match2?.[2] ?? 1) };
44259
44367
  }
44260
44368
 
44261
- export { AxisMetrics, BORDER_STYLES, BUILTIN_CELL_STYLES, BUILTIN_NUMBER_FORMATS, CHART_FILL_PARTS, CIRCULAR_REFERENCE_WARNING, COLUMN_PADDING_PX, DATA_TABLE_PART_ERROR, DEFAULT_ANCHOR_EXTENT_EMU, DEFAULT_BASE_COL_WIDTH, DEFAULT_COL_WIDTH, DEFAULT_GOAL_ITERATIONS, DEFAULT_GOAL_MAX_CHANGE, DEFAULT_MAX_DIGIT_WIDTH, DEFAULT_ROW_HEIGHT, DEFAULT_SLICER_STYLE, DEFAULT_THEME, DEFAULT_VALIDATION_MESSAGE, ERROR_CODES, FORMAT_PRESETS, FUNCTION_CATALOG, FormulaError, IMAGE_EXTENSIONS, INDENT_PX_PER_LEVEL, INDEXED_COLORS, MAX_COL, MAX_DATE_SERIAL, MAX_OUTLINE_LEVEL, MAX_ROW, MAX_SCENARIO_CELLS, MIN_TWO_CELL_PIXELS, OVERFLOW_TEXT, PAGE_VIEW_GAP, PERCENT_SCALE, PIVOT_AGGREGATES, PIVOT_DATE_UNITS, PIVOT_SUBTOTALS, PIVOT_SUBTOTAL_ORDER, PRINT_MARGINS, PRINT_PAPER_INCHES, PRINT_TITLES_NAME, REFERENCE_COLORS, SLICER_DEFAULT_ROW_HEIGHT, SLICER_METRICS, SLICER_STYLE_NAMES, THEME_SLOTS, TIMELINE_LEVELS, TIMELINE_METRICS, TIMELINE_PERIOD_WIDTH, TIME_PERIODS, acceptsReference, activeParam, addFuturePrefixes, anchorKind, anchorToPixelBox, applyBuiltinStyle, applyStylePatch, applyTint, approximateMeasure, autoFitColumnWidth, autoFitRowHeight, autoGrowRows, autoSeriesColor, bordersView, boundsOfSerialRange, builtinCellStyle, builtinFormatId, calcModeOf, callAtCaret, categoryTotals, cellError, cellInputText, cellKey, cellView, cellsFromText, charactersToColumnWidth, charactersToPixels, chartBarSpacing, chartColorPalettePatch, chartColorScheme, chartDrawingColor, chartElementFill, chartElementFillPatch, chartElementGradientPatch, chartElementSolidFillPatch, chartElementTransparency, chartElementTransparencyPatch, chartGradientStopTransparency, chartSeriesFillPatch, chartSeriesGradientPatch, chartSeriesSolidColor, chartSeriesSolidFillPatch, chartSeriesTransparency, chartSeriesTransparencyPatch, chartView, chartWithElementFills, checkDataTable, checkGoalSeek, closeParens, coloredReferences, columnIndex, columnLabel, columnWidthToPixels, compareCellValues, compareValues, composeHeaderFooter, createCalcEngine, createConditionalFormatEvaluator, createEditSession, createGridMetrics, createPrintMergeIndex, createRefEvaluator, createWorkbook, createWorksheet, currentRegion, cutsDataTable, dataTableAt, dataTableFormula, dataTableFormulaText, dataTableMessage, dateGroupAxisNames, dateGroupDays, dateGroupFieldName, dateGroupRange, dateGroupUnits, dateToSerial, dateUnitLabels, defaultCellStyle, defaultColumnPixels, defaultDateGroup, defaultFieldGroup, deleteCell, deleteSheetInFormula, detectSeries, displayText, edgeView, effectiveStyleId, emuToPixels, expandCells, fieldSubtotalFunctions, fillView, fontView, forEachCell, forEachCellInRange, formatAddress, formatAxisValue, formatGeneral, formatPrintTitleSpan, formatRange, formatRefSpec, formatSelectionStat, formatValue, formulaBarText, functionMatches, generalAlignment, getCell, getCellAt, getValue, goalSeekMessage, goalSeekSettings, groupOf, hasSparklineAt, headerFooterKey, hls240ToRgb, inTimePeriod, insideString, internStyle, isCellError, isDateFormat, isEmptyCell, isErrorCode, isFormulaText, isOverflowTarget, isSpilledCell, keyToAddress, layoutRemoteSelections, legacyPasswordHash, lineHeightPoints, listValidationOptions, loadXlsx, mergeAt, mergeFont, mergeView, mergeWouldDiscard, mixColors, modernPasswordHash, modulateLuminance, moveReferencesInFormula, nameAtCaret, navigate, needsArrayEvaluation, newMediaPart, nextSheetId, nextSheetName, niceScale, normalizeRange, numberGroupLabel, numberGroupLabels, numberInputText, numberToText, overflowExtent, pageBreakPreview, pageHeaderFooter, pageOfCell, pageViewCellRect, pageViewHit, pageViewLayout, paginateWorksheet, parseAddress, parseCellInput, parseFormula, parseHeaderFooter, parseHex, parseHtmlTable, parseInputCell, parseNumberText, parsePrintTitleSpan, parseR1C1Range, parseRange, parseTsv, patchHeaderFooterSection, patchStyle, percentile, periodsInSelection, pictureAnchorAt, pivotAxisChoices, pivotGrid, pivotGroupableDateFields, pivotGroupableFields, isoToSerial as pivotIsoToSerial, pivotItemLabel as pivotPageItemLabel, pivotPageItems, pivotRowFields, serialToIso as pivotSerialToIso, pivotSourceData, pivotTableAt, pixelBoxToAnchor, pixelSizeToExtent, pixelsToCharacters, pixelsToColumnWidth, pixelsToEmu, pixelsToPoints, planBreakDrag, pointsToPixels, presetEdges, previewScenario, printRange, printTitles, printTitlesFormula, putCell, queryPattern, quoteSheetName, rangeContains, rangeSize, rangesIntersect, readSparklineGroup, readSparklineGroups, readSparklineValues, referenceSpans, referenceTarget, referencedRanges, refreshDataTables, renameSheetInFormula, renameTableInFormula, renderChartSvg, renderHeaderFooter, renderHeaderFooterRuns, replaceText, resizePrintArea, resizedFrameAnchor, resolveColor, resolvePasteOptions, resolveSparklineRange, rgbToHls240, rotationDegrees, rowsToRefit, sameChartColor, saveXlsx, scaleColor, scenarioAddresses, scenarioMessage, scenariosOf, selectedKeys, selectedSparklineGroups, selectionAfterClick, selectionLabel, selectionOfPeriods, selectionStats, serialToDate, sheetByName, sheetPageBreaks, sheetSparklineGroups, shiftFormula, shiftRange, shiftSpan, slicerFiltered, slicerGeometry, slicerHit, slicerItems, slicerStyleColors, slicerStyleLabel, slicerStylePreview, slicerTarget, solveGoal, sparklineScale, sparklineValues, sparklineView, sparklineViewAt, spillAnchorOf, splice, splitHeaderFooter, stepDecimals, stripFuturePrefixes, structuredToA1, styleAt, styleKey, subtractRange, syntaxParams, themeColor, timePeriodFormula, timelineGeometry, timelinePeriods, timelineTarget, timelineView, toHexColor, toHtml, toIsoDate, toTsv, toggleAbsolute, tokenize, translateFormula, translateReferences, uniqueHeaders, usedRange, validateCellInput, validateDefinedName, validateSheetName, validateTableName, validationAt, verifySheetPassword, verifySheetPasswordAsync, verifyWorkbookPassword, visibleCells, wrappedLineCount, zoomPercent };
44369
+ export { AxisMetrics, BORDER_STYLES, BUILTIN_CELL_STYLES, BUILTIN_NUMBER_FORMATS, CHART_FILL_PARTS, CIRCULAR_REFERENCE_WARNING, COLUMN_PADDING_PX, DATA_TABLE_PART_ERROR, DEFAULT_ANCHOR_EXTENT_EMU, DEFAULT_BASE_COL_WIDTH, DEFAULT_COL_WIDTH, DEFAULT_GOAL_ITERATIONS, DEFAULT_GOAL_MAX_CHANGE, DEFAULT_MAX_DIGIT_WIDTH, DEFAULT_ROW_HEIGHT, DEFAULT_SLICER_STYLE, DEFAULT_THEME, DEFAULT_VALIDATION_MESSAGE, ERROR_CODES, FORMAT_PRESETS, FUNCTION_CATALOG, FormulaError, IMAGE_EXTENSIONS, INDENT_PX_PER_LEVEL, INDEXED_COLORS, MAX_COL, MAX_DATE_SERIAL, MAX_OUTLINE_LEVEL, MAX_ROW, MAX_SCENARIO_CELLS, MIN_TWO_CELL_PIXELS, OVERFLOW_TEXT, PAGE_VIEW_GAP, PERCENT_SCALE, PIVOT_AGGREGATES, PIVOT_DATE_UNITS, PIVOT_SUBTOTALS, PIVOT_SUBTOTAL_ORDER, PRINT_MARGINS, PRINT_PAPER_INCHES, PRINT_TITLES_NAME, REFERENCE_COLORS, SLICER_DEFAULT_ROW_HEIGHT, SLICER_METRICS, SLICER_STYLE_NAMES, THEME_SLOTS, TIMELINE_LEVELS, TIMELINE_METRICS, TIMELINE_PERIOD_WIDTH, TIME_PERIODS, acceptsReference, activeParam, addFuturePrefixes, anchorKind, anchorToPixelBox, applyBuiltinStyle, applyStylePatch, applyTint, approximateMeasure, autoFitColumnWidth, autoFitRowHeight, autoGrowRows, autoSeriesColor, bordersView, boundsOfSerialRange, builtinCellStyle, builtinFormatId, calcModeOf, callAtCaret, categoryTotals, cellError, cellInputText, cellKey, cellView, cellsFromText, charactersToColumnWidth, charactersToPixels, chartBarSpacing, chartColorPalettePatch, chartColorScheme, chartDrawingColor, chartElementFill, chartElementFillPatch, chartElementGradientPatch, chartElementSolidFillPatch, chartElementTransparency, chartElementTransparencyPatch, chartGradientStopTransparency, chartSeriesFillPatch, chartSeriesGradientPatch, chartSeriesSolidColor, chartSeriesSolidFillPatch, chartSeriesTransparency, chartSeriesTransparencyPatch, chartView, chartWithElementFills, checkDataTable, checkGoalSeek, closeParens, coloredReferences, columnIndex, columnLabel, columnWidthToPixels, compareCellValues, compareValues, composeHeaderFooter, createCalcEngine, createConditionalFormatEvaluator, createEditSession, createGridMetrics, createPrintMergeIndex, createRefEvaluator, createWorkbook, createWorksheet, currentRegion, cutsDataTable, dataTableAt, dataTableFormula, dataTableFormulaText, dataTableMessage, dateGroupAxisNames, dateGroupDays, dateGroupFieldName, dateGroupRange, dateGroupUnits, dateToSerial, dateUnitLabels, defaultCellStyle, defaultColumnPixels, defaultDateGroup, defaultFieldGroup, deleteCell, deleteSheetInFormula, detectSeries, displayText, edgeView, effectiveStyleId, emuToPixels, expandCells, fieldSubtotalFunctions, fillView, fontView, forEachCell, forEachCellInRange, formatAddress, formatAxisValue, formatGeneral, formatPrintTitleSpan, formatRange, formatRefSpec, formatSelectionStat, formatValue, formulaBarText, functionMatches, generalAlignment, getCell, getCellAt, getValue, goalSeekMessage, goalSeekSettings, groupOf, hasSparklineAt, headerFooterKey, hls240ToRgb, inTimePeriod, insideString, internStyle, isCellError, isDateFormat, isEmptyCell, isErrorCode, isFormulaText, isOverflowTarget, isSpilledCell, keyToAddress, layoutRemoteSelections, legacyPasswordHash, lineHeightPoints, listValidationOptions, loadXlsx, mergeAt, mergeFont, mergeView, mergeWouldDiscard, mixColors, modernPasswordHash, modulateLuminance, moveReferencesInFormula, nameAtCaret, navigate, needsArrayEvaluation, newMediaPart, nextSheetId, nextSheetName, niceScale, normalizeRange, numberGroupLabel, numberGroupLabels, numberInputText, numberToText, overflowExtent, pageBreakPreview, pageHeaderFooter, pageOfCell, pageViewCellRect, pageViewHit, pageViewLayout, paginateWorksheet, parseAddress, parseCellInput, parseFormula, parseHeaderFooter, parseHex, parseHtmlTable, parseInputCell, parseNumberText, parsePrintTitleSpan, parseR1C1Range, parseRange, parseTsv, patchHeaderFooterSection, patchStyle, percentile, periodsInSelection, pictureAnchorAt, pivotAxisChoices, pivotGrid, pivotGroupableDateFields, pivotGroupableFields, isoToSerial as pivotIsoToSerial, pivotItemLabel as pivotPageItemLabel, pivotPageItems, pivotRowFields, serialToIso as pivotSerialToIso, pivotSourceData, pivotSubtotalFields, pivotTableAt, pivotValuesIndex, pixelBoxToAnchor, pixelSizeToExtent, pixelsToCharacters, pixelsToColumnWidth, pixelsToEmu, pixelsToPoints, planBreakDrag, pointsToPixels, presetEdges, previewScenario, printRange, printTitles, printTitlesFormula, putCell, queryPattern, quoteSheetName, rangeContains, rangeSize, rangesIntersect, readSparklineGroup, readSparklineGroups, readSparklineValues, referenceSpans, referenceTarget, referencedRanges, refreshDataTables, renameSheetInFormula, renameTableInFormula, renderChartSvg, renderHeaderFooter, renderHeaderFooterRuns, replaceText, resizePrintArea, resizedFrameAnchor, resolveColor, resolvePasteOptions, resolveSparklineRange, rgbToHls240, rotationDegrees, rowsToRefit, sameChartColor, saveXlsx, scaleColor, scenarioAddresses, scenarioMessage, scenariosOf, selectedKeys, selectedSparklineGroups, selectionAfterClick, selectionLabel, selectionOfPeriods, selectionStats, serialToDate, sheetByName, sheetPageBreaks, sheetSparklineGroups, shiftFormula, shiftRange, shiftSpan, slicerFiltered, slicerGeometry, slicerHit, slicerItems, slicerStyleColors, slicerStyleLabel, slicerStylePreview, slicerTarget, solveGoal, sparklineScale, sparklineValues, sparklineView, sparklineViewAt, spillAnchorOf, splice, splitHeaderFooter, stepDecimals, stripFuturePrefixes, structuredToA1, styleAt, styleKey, subtractRange, syntaxParams, themeColor, timePeriodFormula, timelineGeometry, timelinePeriods, timelineTarget, timelineView, toHexColor, toHtml, toIsoDate, toTsv, toggleAbsolute, tokenize, translateFormula, translateReferences, uniqueHeaders, usedRange, validateCellInput, validateDefinedName, validateSheetName, validateTableName, validationAt, verifySheetPassword, verifySheetPasswordAsync, verifyWorkbookPassword, visibleCells, wrappedLineCount, zoomPercent };