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
@@ -309,7 +309,7 @@ function parseOle2(buffer, options = {}) {
309
309
  fatEntries.push(fatView.getUint32(i2 * 4, true));
310
310
  }
311
311
  }
312
- function followChain(table2, start, label5, needed) {
312
+ function followChain(table2, start, label2, needed) {
313
313
  const ids = [];
314
314
  const visited = /* @__PURE__ */ new Set();
315
315
  let current = start;
@@ -317,26 +317,26 @@ function parseOle2(buffer, options = {}) {
317
317
  if (!strict && needed !== void 0 && ids.length >= needed)
318
318
  return ids;
319
319
  if (visited.has(current)) {
320
- throw new Ole2ParseError(`Circular reference in ${label5} chain at sector ${current}`);
320
+ throw new Ole2ParseError(`Circular reference in ${label2} chain at sector ${current}`);
321
321
  }
322
322
  visited.add(current);
323
323
  ids.push(current);
324
324
  if (table2[current] === void 0)
325
- throw new Ole2ParseError(`Missing ${label5} chain entry`);
325
+ throw new Ole2ParseError(`Missing ${label2} chain entry`);
326
326
  current = table2[current];
327
327
  }
328
328
  if (current !== ENDOFCHAIN) {
329
329
  if (strict || needed === void 0 || ids.length < needed) {
330
- throw new Ole2ParseError(`Invalid ${label5} chain terminator`);
330
+ throw new Ole2ParseError(`Invalid ${label2} chain terminator`);
331
331
  }
332
- warnings.push({ code: "chain-terminator", message: `Accepted ${label5} chain ending in 0x${current.toString(16)}` });
332
+ warnings.push({ code: "chain-terminator", message: `Accepted ${label2} chain ending in 0x${current.toString(16)}` });
333
333
  }
334
334
  return ids;
335
335
  }
336
- function readMetadataChain(startSector, label5) {
336
+ function readMetadataChain(startSector, label2) {
337
337
  if (startSector > MAXREGSECT)
338
338
  return new Uint8Array(0);
339
- const ids = followChain(fatEntries, startSector, label5 === "directory" ? "FAT" : label5);
339
+ const ids = followChain(fatEntries, startSector, label2 === "directory" ? "FAT" : label2);
340
340
  const result2 = new Uint8Array(ids.length * sectorSize);
341
341
  ids.forEach((id, i2) => result2.set(readSector(id), i2 * sectorSize));
342
342
  return result2;
@@ -3249,7 +3249,7 @@ var DEFAULT_XML_LIMITS = {
3249
3249
  maxNodes: 5e6
3250
3250
  };
3251
3251
  var MARKUP_RE = /<!--[\s\S]*?-->|<!\[CDATA\[[\s\S]*?\]\]>|<\?[\s\S]*?\?>|<(\/?)([^\s\/>]+)(?:\s+[^\s=\/>]+\s*=\s*(?:"[^"]*"|'[^']*'))*\s*(\/?)>/g;
3252
- function checkXmlLimits(xml, label5, limits = {}) {
3252
+ function checkXmlLimits(xml, label2, limits = {}) {
3253
3253
  const maxDepth = limits.maxDepth ?? DEFAULT_XML_LIMITS.maxDepth;
3254
3254
  const maxNodes = limits.maxNodes ?? DEFAULT_XML_LIMITS.maxNodes;
3255
3255
  let depth = 0;
@@ -3262,16 +3262,16 @@ function checkXmlLimits(xml, label5, limits = {}) {
3262
3262
  continue;
3263
3263
  }
3264
3264
  nodes++;
3265
- if (nodes > maxNodes) throw new Error(`${label5} XML exceeds the limit of ${maxNodes} elements`);
3265
+ if (nodes > maxNodes) throw new Error(`${label2} XML exceeds the limit of ${maxNodes} elements`);
3266
3266
  if (!selfClosing && ++depth > maxDepth)
3267
- throw new Error(`${label5} XML exceeds the nesting depth limit of ${maxDepth}`);
3267
+ throw new Error(`${label2} XML exceeds the nesting depth limit of ${maxDepth}`);
3268
3268
  }
3269
3269
  }
3270
3270
  function parseXml(xml, options = {}) {
3271
- const label5 = options.label ?? "OOXML";
3271
+ const label2 = options.label ?? "OOXML";
3272
3272
  if (/<!DOCTYPE|<!ENTITY/i.test(xml))
3273
- throw new Error(`${label5} XML with DTD or entity declarations is not supported`);
3274
- checkXmlLimits(xml, label5, options.limits);
3273
+ throw new Error(`${label2} XML with DTD or entity declarations is not supported`);
3274
+ checkXmlLimits(xml, label2, options.limits);
3275
3275
  let parseError = "";
3276
3276
  let parsed;
3277
3277
  try {
@@ -3282,12 +3282,12 @@ function parseXml(xml, options = {}) {
3282
3282
  }).parseFromString(xml, "application/xml");
3283
3283
  } catch (error) {
3284
3284
  throw new Error(
3285
- `Invalid ${label5} XML: ${error instanceof Error ? error.message : String(error)}`,
3285
+ `Invalid ${label2} XML: ${error instanceof Error ? error.message : String(error)}`,
3286
3286
  { cause: error }
3287
3287
  );
3288
3288
  }
3289
3289
  if (parseError || !parsed.documentElement)
3290
- throw new Error(`Invalid ${label5} XML: ${parseError || "missing root element"}`);
3290
+ throw new Error(`Invalid ${label2} XML: ${parseError || "missing root element"}`);
3291
3291
  return parsed;
3292
3292
  }
3293
3293
  var buildXml = (node2) => new XMLSerializer().serializeToString(node2);
@@ -4397,19 +4397,19 @@ var DIGITAL_SIGNATURE_ORIGIN_REL_TYPE = "http://schemas.openxmlformats.org/packa
4397
4397
  var MAX_ROW = 1048575;
4398
4398
  var MAX_COL = 16383;
4399
4399
  function columnLabel(col) {
4400
- let label5 = "";
4400
+ let label2 = "";
4401
4401
  let n = col + 1;
4402
4402
  while (n > 0) {
4403
4403
  const rem = (n - 1) % 26;
4404
- label5 = String.fromCharCode(65 + rem) + label5;
4404
+ label2 = String.fromCharCode(65 + rem) + label2;
4405
4405
  n = Math.floor((n - 1) / 26);
4406
4406
  }
4407
- return label5;
4407
+ return label2;
4408
4408
  }
4409
- function columnIndex(label5) {
4410
- if (!/^[A-Za-z]{1,3}$/.test(label5)) return -1;
4409
+ function columnIndex(label2) {
4410
+ if (!/^[A-Za-z]{1,3}$/.test(label2)) return -1;
4411
4411
  let n = 0;
4412
- for (const ch of label5.toUpperCase()) n = n * 26 + (ch.charCodeAt(0) - 64);
4412
+ for (const ch of label2.toUpperCase()) n = n * 26 + (ch.charCodeAt(0) - 64);
4413
4413
  return n - 1;
4414
4414
  }
4415
4415
  var formatAddress = (address2) => `${columnLabel(address2.col)}${address2.row + 1}`;
@@ -6719,11 +6719,83 @@ var pivotRowFields = (pivot) => [
6719
6719
  ...pivot.secondRowField ? [pivot.secondRowField] : [],
6720
6720
  ...pivot.secondRowField ? pivot.moreRowFields ?? [] : []
6721
6721
  ];
6722
+ function pivotValuesIndex(pivot) {
6723
+ if (pivot.valuesAxis !== "rows") return -1;
6724
+ const count2 = pivotRowFields(pivot).length;
6725
+ const at = pivot.valuesPosition;
6726
+ if (typeof at === "number") return Math.min(Math.max(Math.trunc(at), 0), count2);
6727
+ return at === "first" ? 0 : at === "between" ? Math.min(1, count2) : count2;
6728
+ }
6722
6729
  var pivotColumnFields = (pivot) => [
6723
6730
  ...pivot.columnField ? [pivot.columnField] : [],
6724
6731
  ...pivot.columnField ? pivot.moreColumnFields ?? [] : []
6725
6732
  ];
6726
6733
 
6734
+ // xlsx/pivot/captions.ts
6735
+ var FUNCTIONS = {
6736
+ sum: "Sum",
6737
+ count: "Count",
6738
+ average: "Average",
6739
+ max: "Max",
6740
+ min: "Min",
6741
+ product: "Product",
6742
+ countNums: "Count",
6743
+ stdDev: "StdDev",
6744
+ stdDevp: "StdDevp",
6745
+ var: "Var",
6746
+ varp: "Varp"
6747
+ };
6748
+ var aggregateNames = () => Object.fromEntries(
6749
+ Object.keys(FUNCTIONS).map((fn) => [
6750
+ fn,
6751
+ `${fn[0].toUpperCase()}${fn.slice(1)} of {0}`
6752
+ ])
6753
+ );
6754
+ var ENGLISH_PIVOT_CAPTIONS = {
6755
+ rowLabels: "Row Labels",
6756
+ columnLabels: "Column Labels",
6757
+ grandTotal: "Grand Total",
6758
+ values: "Values",
6759
+ all: "(All)",
6760
+ blank: "(blank)",
6761
+ subtotal: "{0} Total",
6762
+ measureTotal: "Total {0}",
6763
+ functions: FUNCTIONS,
6764
+ aggregates: aggregateNames()
6765
+ };
6766
+ var fillCaption = (template, ...args) => template.replace(/\{(\d)\}/g, (_match, at) => args[Number(at)] ?? "");
6767
+ function pivotCaptions(pivot) {
6768
+ const own = pivot.captions;
6769
+ if (!own) return ENGLISH_PIVOT_CAPTIONS;
6770
+ return {
6771
+ ...ENGLISH_PIVOT_CAPTIONS,
6772
+ ...Object.fromEntries(Object.entries(own).filter(([, value2]) => typeof value2 === "string")),
6773
+ functions: { ...ENGLISH_PIVOT_CAPTIONS.functions, ...own.functions },
6774
+ aggregates: { ...ENGLISH_PIVOT_CAPTIONS.aggregates, ...own.aggregates }
6775
+ };
6776
+ }
6777
+ function trimmedCaptions(caps) {
6778
+ const out = {};
6779
+ for (const key of [
6780
+ "rowLabels",
6781
+ "columnLabels",
6782
+ "grandTotal",
6783
+ "values",
6784
+ "all",
6785
+ "blank",
6786
+ "subtotal",
6787
+ "measureTotal"
6788
+ ])
6789
+ if (caps[key] !== ENGLISH_PIVOT_CAPTIONS[key]) out[key] = caps[key];
6790
+ for (const key of ["functions", "aggregates"]) {
6791
+ const changed = Object.keys(caps[key]).filter(
6792
+ (fn) => caps[key][fn] !== ENGLISH_PIVOT_CAPTIONS[key][fn]
6793
+ );
6794
+ if (changed.length) out[key] = Object.fromEntries(changed.map((fn) => [fn, caps[key][fn]]));
6795
+ }
6796
+ return Object.keys(out).length ? out : void 0;
6797
+ }
6798
+
6727
6799
  // xlsx/formula/date-serial.ts
6728
6800
  var DAY_MS = 864e5;
6729
6801
  var EPOCH_19002 = Date.UTC(1899, 11, 30);
@@ -6811,7 +6883,7 @@ var LEAP_MONTHS = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
6811
6883
  var MAX_ITEMS = 1e4;
6812
6884
  var pad4 = (value2, width = 2) => String(value2).padStart(width, "0");
6813
6885
  var dateGroupUnits = (group) => PIVOT_DATE_UNITS.filter((unit) => group.by.includes(unit));
6814
- var dateGroupFieldName = (unit, field) => `${UNIT_TITLES[unit]} (${field})`;
6886
+ var dateGroupFieldName = (unit, field, group) => group?.localized?.[unit]?.name ?? `${UNIT_TITLES[unit]} (${field})`;
6815
6887
  var dateGroupDays = (group) => group.by.length === 1 && group.by[0] === "days" ? group.days ?? 1 : 1;
6816
6888
  function dateGroupRange(group, serials) {
6817
6889
  let min = Infinity;
@@ -6834,7 +6906,7 @@ var secondsOfDay = (serial) => Math.round((serial - Math.floor(serial)) * 86400)
6834
6906
  function dayBuckets(range, days) {
6835
6907
  return Math.max(1, Math.ceil((Math.floor(range.end) - Math.floor(range.start) + 1) / days));
6836
6908
  }
6837
- function dateUnitLabels(unit, range, days, date1904) {
6909
+ function englishDateUnitLabels(unit, range, days, date1904) {
6838
6910
  const labels = [`<${isoDay(range.start, date1904)}`];
6839
6911
  if (unit === "seconds" || unit === "minutes")
6840
6912
  for (let i2 = 0; i2 < 60; i2++) labels.push(`:${pad4(i2)}`);
@@ -6863,6 +6935,11 @@ function dateUnitLabels(unit, range, days, date1904) {
6863
6935
  labels.push(`>${isoDay(range.end, date1904)}`);
6864
6936
  return labels;
6865
6937
  }
6938
+ function dateUnitLabels(unit, range, days, date1904, group) {
6939
+ const english = englishDateUnitLabels(unit, range, days, date1904);
6940
+ const localized = group?.localized?.[unit]?.labels;
6941
+ return localized?.length === english.length ? localized : english;
6942
+ }
6866
6943
  function dateUnitIndex(unit, range, days, date1904, serial, count2) {
6867
6944
  if (serial < range.start) return 0;
6868
6945
  if (serial > range.end) return count2 - 1;
@@ -6886,7 +6963,7 @@ function derivedDateFields(pivot) {
6886
6963
  for (const group of pivot.dateGroups ?? [])
6887
6964
  for (const unit of dateGroupUnits(group))
6888
6965
  derived.push({
6889
- name: dateGroupFieldName(unit, group.field),
6966
+ name: dateGroupFieldName(unit, group.field, group),
6890
6967
  unit,
6891
6968
  group,
6892
6969
  index: databaseFields + derived.length
@@ -6897,7 +6974,7 @@ function countDerived(pivot) {
6897
6974
  let count2 = 0;
6898
6975
  for (const group of pivot.dateGroups ?? [])
6899
6976
  for (const unit of dateGroupUnits(group))
6900
- if (pivot.fields.includes(dateGroupFieldName(unit, group.field))) count2++;
6977
+ if (pivot.fields.includes(dateGroupFieldName(unit, group.field, group))) count2++;
6901
6978
  return count2;
6902
6979
  }
6903
6980
  var pivotAxisFieldNames = (pivot) => [
@@ -6917,7 +6994,7 @@ function derivedDateLabels(pivot, name) {
6917
6994
  if (!entry3) return void 0;
6918
6995
  const [group] = resolveDateGroups({ ...pivot, dateGroups: [entry3.group] });
6919
6996
  const range = { start: group.start, end: group.end };
6920
- return dateUnitLabels(entry3.unit, range, dateGroupDays(group), pivot.date1904 ?? false);
6997
+ return dateUnitLabels(entry3.unit, range, dateGroupDays(group), pivot.date1904 ?? false, group);
6921
6998
  }
6922
6999
  function validateDateGroups(pivot) {
6923
7000
  const groups = pivot.dateGroups;
@@ -6933,18 +7010,16 @@ function validateDateGroups(pivot) {
6933
7010
  seen.add(group.field);
6934
7011
  if (!(pivot.dateFields ?? []).includes(group.field))
6935
7012
  throw new Error("Only fields that contain dates can be grouped by date.");
6936
- if (pivot.pageFilter || pivot.dateFilter)
6937
- throw new Error("Date groups cannot be combined with report filters or timelines.");
6938
7013
  const serials = pivot.records.map((record) => record[index3]);
6939
7014
  if (!serials.length || serials.some((v) => typeof v !== "number" || !Number.isFinite(v)))
6940
7015
  throw new Error("Only fields that contain dates can be grouped by date.");
6941
7016
  const range = dateGroupRange(group, serials);
6942
7017
  if (range.start >= range.end) throw new Error("The date group must end after it starts.");
6943
7018
  for (const unit of dateGroupUnits(group)) {
6944
- const name = dateGroupFieldName(unit, group.field);
7019
+ const name = dateGroupFieldName(unit, group.field, group);
6945
7020
  if (pivot.fields.includes(name))
6946
7021
  throw new Error("A source field already has the name of a date group field.");
6947
- if (dateUnitLabels(unit, range, dateGroupDays(group), pivot.date1904 ?? false).length > MAX_ITEMS)
7022
+ if (dateUnitLabels(unit, range, dateGroupDays(group), pivot.date1904 ?? false, group).length > MAX_ITEMS)
6948
7023
  throw new Error("The date group has too many items.");
6949
7024
  }
6950
7025
  }
@@ -6958,7 +7033,7 @@ function expandDateGroups(pivot) {
6958
7033
  const tables = derived.map((entry3) => {
6959
7034
  const range = { start: entry3.group.start, end: entry3.group.end };
6960
7035
  const days = dateGroupDays(entry3.group);
6961
- const labels = dateUnitLabels(entry3.unit, range, days, date1904);
7036
+ const labels = dateUnitLabels(entry3.unit, range, days, date1904, entry3.group);
6962
7037
  return {
6963
7038
  base: pivot.fields.indexOf(entry3.group.field),
6964
7039
  labels,
@@ -7081,15 +7156,13 @@ function fieldSubtotalFunctions(pivot, field) {
7081
7156
  if (entry3) return PIVOT_SUBTOTAL_ORDER.filter((fn) => entry3.functions.includes(fn));
7082
7157
  return field === pivot.rowField && pivot.subtotals === false ? [] : "auto";
7083
7158
  }
7084
- function validateFieldSubtotals(pivot, rowFields) {
7159
+ function validateFieldSubtotals(pivot, axisFields) {
7085
7160
  const entries = pivot.fieldSubtotals;
7086
7161
  if (entries === void 0) return;
7087
7162
  if (!Array.isArray(entries)) throw new Error("Choose valid field subtotals.");
7088
- if (entries.length && pivot.valuesAxis === "rows")
7089
- throw new Error("Field subtotals require Values on columns.");
7090
7163
  const seen = /* @__PURE__ */ new Set();
7091
7164
  for (const entry3 of entries) {
7092
- 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)
7165
+ 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)
7093
7166
  throw new Error("Choose valid field subtotals.");
7094
7167
  seen.add(entry3.field);
7095
7168
  }
@@ -7157,6 +7230,17 @@ function validatePivotItemFilters(pivot) {
7157
7230
  }
7158
7231
  }
7159
7232
 
7233
+ // xlsx/pivot/item-labels.ts
7234
+ var keyOf = (field, item) => `${field}\0${pivotValueKey(item)}`;
7235
+ function pivotItemLabeler(pivot) {
7236
+ const blank = pivotCaptions(pivot).blank;
7237
+ const names = pivot.itemNames?.length ? new Map(pivot.itemNames.map((entry3) => [keyOf(entry3.field, entry3.item), entry3.name])) : void 0;
7238
+ return (field, value2) => names?.get(keyOf(field, value2)) ?? (value2 === null || value2 === "" ? blank : pivotItemLabel(value2));
7239
+ }
7240
+ var pivotItemName = (pivot, field, item) => pivot.itemNames?.find(
7241
+ (entry3) => entry3.field === field && pivotValueKey(entry3.item) === pivotValueKey(item)
7242
+ )?.name;
7243
+
7160
7244
  // xlsx/pivot/page-filter.ts
7161
7245
  function validatePivotPageFilter(pivot) {
7162
7246
  const filter2 = pivot.pageFilter;
@@ -7168,23 +7252,24 @@ function validatePivotPageFilter(pivot) {
7168
7252
  pivot.columnField,
7169
7253
  pivot.valueField,
7170
7254
  ...extras.map((v) => v?.field)
7171
- ].includes(filter2.field) || pivot.valuesAxis === "rows")
7172
- throw new Error("Report filters require Values on columns and a separate source field.");
7255
+ ].includes(filter2.field))
7256
+ throw new Error("Report filters require a separate source field.");
7173
7257
  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))
7174
7258
  throw new Error("Choose a cached literal report filter item.");
7175
7259
  }
7176
7260
  function pivotPageProjection(pivot) {
7177
- return applyPivotGroups(applyPivotItemFilters(pagedProjection(pivot)));
7261
+ const groups = pivot.dateGroups?.length ? { ...pivot, dateGroups: resolveDateGroups(pivot) } : pivot;
7262
+ return applyPivotGroups(applyPivotItemFilters(pagedProjection(groups)));
7178
7263
  }
7179
7264
  function pagedProjection(pivot) {
7180
7265
  const filter2 = pivot.pageFilter;
7181
7266
  if (!filter2) return pivot;
7182
7267
  const labels = /* @__PURE__ */ new Map();
7183
7268
  for (const item of pivotItems(pivot, filter2.field)) {
7184
- const label5 = String(pivotItemLabel(item)).toLowerCase(), key2 = pivotValueKey(item);
7185
- if (label5 === "(all)" || labels.has(label5) && labels.get(label5) !== key2)
7269
+ const label2 = String(pivotItemLabel(item)).toLowerCase(), key2 = pivotValueKey(item);
7270
+ if (label2 === "(all)" || labels.has(label2) && labels.get(label2) !== key2)
7186
7271
  throw new Error("Ambiguous report filter item captions are preserved.");
7187
- labels.set(label5, key2);
7272
+ labels.set(label2, key2);
7188
7273
  }
7189
7274
  if (filter2.item === void 0) return pivot;
7190
7275
  const index3 = pivot.fields.indexOf(filter2.field), key = pivotValueKey(filter2.item);
@@ -7202,7 +7287,7 @@ function prependPivotPage(grid, pivot) {
7202
7287
  values: [
7203
7288
  [
7204
7289
  pivot.pageFilter.field,
7205
- pivot.pageFilter.item === void 0 ? "(All)" : pivotItemLabel(pivot.pageFilter.item),
7290
+ pivot.pageFilter.item === void 0 ? pivotCaptions(pivot).all : pivotItemLabeler(pivot)(pivot.pageFilter.field, pivot.pageFilter.item),
7206
7291
  ...Array(width - 2).fill(null)
7207
7292
  ],
7208
7293
  Array(width).fill(null),
@@ -7299,13 +7384,9 @@ function validatePivotFields(pivot) {
7299
7384
  const columns = pivotColumnFields(pivot);
7300
7385
  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")))
7301
7386
  throw new Error("Choose valid PivotTable column fields.");
7302
- if (pivot.valuesAxis === "rows" && rows.length > 2)
7303
- throw new Error("Values on rows support at most two row fields.");
7304
- if (pivot.valuesAxis === "rows" && columns.length > 1)
7305
- throw new Error("Values on rows support one column field.");
7306
7387
  if (pivot.pageFilter && columns.length > 1)
7307
7388
  throw new Error("Report filters support one column field.");
7308
- validateFieldSubtotals(pivot, rows);
7389
+ validateFieldSubtotals(pivot, [...rows, ...columns]);
7309
7390
  const axisNames = pivotAxisFieldNames(pivot);
7310
7391
  if ((pivot.dateGroups ?? []).some(
7311
7392
  (group) => [...rows, ...columns].some((name) => name === group.field)
@@ -7314,13 +7395,14 @@ function validatePivotFields(pivot) {
7314
7395
  const extras = pivot.additionalValues ?? [];
7315
7396
  if (pivot.valuesAxis !== void 0 && !["columns", "rows"].includes(pivot.valuesAxis))
7316
7397
  throw new Error("Choose a valid Values axis.");
7317
- if (pivot.valuesPosition !== void 0 && !["last", "between", "first"].includes(pivot.valuesPosition))
7398
+ const position = pivot.valuesPosition;
7399
+ if (position !== void 0 && !["last", "between", "first"].includes(position) && !(typeof position === "number" && Number.isInteger(position) && position >= 0))
7318
7400
  throw new Error("Choose a valid Values position.");
7319
- if ((pivot.valuesPosition === "between" || pivot.valuesPosition === "first") && (pivot.valuesAxis !== "rows" || !pivot.secondRowField))
7401
+ if (position !== void 0 && position !== "last" && (pivot.valuesAxis !== "rows" || position === "between" && !pivot.secondRowField || typeof position === "number" && position > rows.length))
7320
7402
  throw new Error("Values before or between fields require two row fields and Values on rows.");
7321
7403
  if (pivot.valuesAxis === "rows" && (!Array.isArray(extras) || !extras.length))
7322
7404
  throw new Error("Values on rows require multiple measures.");
7323
- if (extras.length > 0 && pivot.sourceXml && parseXml(pivot.sourceXml).documentElement.getAttribute("dataCaption") !== "Values")
7405
+ if (extras.length > 0 && pivot.sourceXml && parseXml(pivot.sourceXml).documentElement.getAttribute("dataCaption") !== pivotCaptions(pivot).values)
7324
7406
  throw new Error("This PivotTable uses unsupported Values header captions.");
7325
7407
  if (!Array.isArray(extras) || extras.length > 15 || extras.some(
7326
7408
  (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())
@@ -7334,314 +7416,6 @@ function validatePivotFields(pivot) {
7334
7416
  throw new Error("Choose valid PivotTable fields; row and column fields must differ.");
7335
7417
  }
7336
7418
 
7337
- // xlsx/pivot/measures.ts
7338
- var pivotMeasures = (pivot) => [
7339
- { field: pivot.valueField, aggregate: pivot.aggregate, caption: pivot.valueCaption },
7340
- ...pivot.additionalValues ?? []
7341
- ];
7342
- var DIV0 = { error: "#DIV/0!" };
7343
- function variance(numbers3, sample) {
7344
- const n = numbers3.length;
7345
- if (n < (sample ? 2 : 1)) return DIV0;
7346
- const mean2 = numbers3.reduce((total2, value2) => total2 + value2, 0) / n;
7347
- const squares = numbers3.reduce((total2, value2) => total2 + (value2 - mean2) ** 2, 0);
7348
- return squares / (sample ? n - 1 : n);
7349
- }
7350
- function aggregateValues(records, field, type) {
7351
- if (!records.length) return null;
7352
- const values2 = records.map((record) => record[field] ?? null);
7353
- if (type === "count") return values2.filter((value2) => value2 !== null && value2 !== "").length;
7354
- if (type === "countNums") return values2.filter((value2) => typeof value2 === "number").length;
7355
- const error = values2.find(isCellError);
7356
- if (error) return error;
7357
- const numbers3 = values2.filter((value2) => typeof value2 === "number");
7358
- if (type === "var" || type === "varp" || type === "stdDev" || type === "stdDevp") {
7359
- const result2 = variance(numbers3, type === "var" || type === "stdDev");
7360
- return typeof result2 === "number" && (type === "stdDev" || type === "stdDevp") ? Math.sqrt(result2) : result2;
7361
- }
7362
- if (!numbers3.length) return type === "average" ? DIV0 : 0;
7363
- if (type === "min") return numbers3.reduce((a2, b) => Math.min(a2, b));
7364
- if (type === "max") return numbers3.reduce((a2, b) => Math.max(a2, b));
7365
- if (type === "product") return numbers3.reduce((total2, value2) => total2 * value2, 1);
7366
- const sum3 = numbers3.reduce((total2, value2) => total2 + value2, 0);
7367
- return type === "average" ? sum3 / numbers3.length : sum3;
7368
- }
7369
- var pivotMeasureNumber = (pivot, records, measure) => aggregateValues(records, pivot.fields.indexOf(measure.field), measure.aggregate);
7370
- var pivotNumbers = (pivot, records) => pivotMeasures(pivot).map((measure) => pivotMeasureNumber(pivot, records, measure));
7371
- function pivotHeaderDimensions(pivot, columnItems, rowLabels) {
7372
- return {
7373
- rows: (pivot.columnField ? 2 : 1) + (pivot.pageFilter ? 2 : 0),
7374
- width: rowLabels + (pivot.columnField ? columnItems + 1 : 1)
7375
- };
7376
- }
7377
- function pivotHeaders(pivot, columns, labels, label5) {
7378
- const rowLabels = pivot.layout === "compact" ? ["Row Labels"] : pivot.valuesPosition === "first" ? ["Values", ...labels] : pivot.valuesPosition === "between" ? [labels[0], "Values", labels[1]] : [...labels, "Values"];
7379
- return pivot.columnField ? [
7380
- [
7381
- ...rowLabels.map(() => null),
7382
- pivot.layout === "compact" ? "Column Labels" : pivot.columnField,
7383
- ...columns.map(() => null)
7384
- ],
7385
- [...rowLabels, ...columns.map(label5), "Grand Total"]
7386
- ] : [[...rowLabels, null]];
7387
- }
7388
-
7389
- // xlsx/pivot/hierarchy-first.ts
7390
- function appendFirstPivotValues(pivot, context) {
7391
- const {
7392
- rowItems,
7393
- secondRowItems,
7394
- columnItems,
7395
- children: children2,
7396
- innerIndices,
7397
- groups,
7398
- details,
7399
- buckets,
7400
- width,
7401
- rowLabels,
7402
- top,
7403
- bottom,
7404
- append
7405
- } = context;
7406
- const compact = pivot.layout === "compact";
7407
- const tabular = !pivot.layout || pivot.layout === "tabular";
7408
- const blank = () => Array(width - rowLabels).fill(null);
7409
- pivotMeasures(pivot).forEach((measure, m) => {
7410
- const numbers3 = (keys, records) => [
7411
- ...columnItems.map(
7412
- (column2) => pivotMeasureNumber(
7413
- pivot,
7414
- buckets.get(JSON.stringify([...keys, pivotValueKey(column2)])) ?? [],
7415
- measure
7416
- )
7417
- ),
7418
- pivotMeasureNumber(pivot, records, measure)
7419
- ];
7420
- if (!tabular)
7421
- append([measure.caption, ...Array(rowLabels - 1).fill(null)], blank(), {
7422
- indices: [m],
7423
- measure: m
7424
- });
7425
- let first2 = true;
7426
- rowItems.forEach((outer, outerIndex) => {
7427
- const key = pivotValueKey(outer);
7428
- const group = groups.get(key) ?? [];
7429
- if (!tabular)
7430
- append(
7431
- compact ? [pivotItemLabel(outer)] : [null, pivotItemLabel(outer), null],
7432
- top ? numbers3([key], group) : blank(),
7433
- { indices: [m, outerIndex], measure: m },
7434
- compact ? 1 : 0
7435
- );
7436
- const innerKeys = [...children2.get(key)].sort(
7437
- (a2, b) => innerIndices.get(a2) - innerIndices.get(b)
7438
- );
7439
- innerKeys.forEach((innerKey, child4) => {
7440
- const innerIndex = innerIndices.get(innerKey);
7441
- append(
7442
- compact ? [pivotItemLabel(secondRowItems[innerIndex])] : [
7443
- tabular && first2 ? measure.caption : null,
7444
- pivot.repeatLabels || tabular && child4 === 0 ? pivotItemLabel(outer) : null,
7445
- pivotItemLabel(secondRowItems[innerIndex])
7446
- ],
7447
- numbers3([key, innerKey], details.get(JSON.stringify([key, innerKey]))),
7448
- { indices: [m, outerIndex, innerIndex], measure: m },
7449
- compact ? 2 : 0
7450
- );
7451
- first2 = false;
7452
- });
7453
- if (bottom)
7454
- append(
7455
- compact ? [`${String(pivotItemLabel(outer))} Total`] : [null, `${String(pivotItemLabel(outer))} Total`, null],
7456
- numbers3([key], group),
7457
- { indices: [m, outerIndex], measure: m, type: "default" },
7458
- compact ? 1 : 0
7459
- );
7460
- });
7461
- });
7462
- }
7463
-
7464
- // xlsx/pivot/hierarchy.ts
7465
- var label = pivotItemLabel;
7466
- function hierarchicalPivotGrid(pivot) {
7467
- const rowItems = pivotItems(pivot, pivot.rowField);
7468
- const secondRowItems = pivotItems(pivot, pivot.secondRowField);
7469
- const columnItems = pivot.columnField ? pivotItems(pivot, pivot.columnField) : [];
7470
- const outerField = pivot.fields.indexOf(pivot.rowField);
7471
- const innerField = pivot.fields.indexOf(pivot.secondRowField);
7472
- const columnField = pivot.columnField ? pivot.fields.indexOf(pivot.columnField) : -1;
7473
- const layout3 = pivot.layout ?? "tabular";
7474
- const compact = layout3 === "compact";
7475
- const firstValues = pivot.valuesPosition === "first";
7476
- const between = pivot.valuesPosition === "between";
7477
- const measures = pivotMeasures(pivot);
7478
- const top = firstValues && layout3 !== "tabular" && pivot.subtotals !== false && (pivot.subtotalPosition ?? "top") === "top";
7479
- const bottom = pivot.subtotals !== false && !top;
7480
- const rowLabelColumns = compact ? 1 : 3;
7481
- const groups = /* @__PURE__ */ new Map();
7482
- const details = /* @__PURE__ */ new Map();
7483
- const children2 = /* @__PURE__ */ new Map();
7484
- const innerIndices = new Map(secondRowItems.map((item, index3) => [pivotValueKey(item), index3]));
7485
- const buckets = /* @__PURE__ */ new Map();
7486
- const collect = (map, key, record) => {
7487
- const list = map.get(key);
7488
- if (list) list.push(record);
7489
- else map.set(key, [record]);
7490
- };
7491
- for (const record of pivot.records) {
7492
- const outer = pivotValueKey(record[outerField] ?? null);
7493
- const inner = pivotValueKey(record[innerField] ?? null);
7494
- collect(groups, outer, record);
7495
- collect(details, JSON.stringify([outer, inner]), record);
7496
- if (!children2.has(outer)) children2.set(outer, /* @__PURE__ */ new Set());
7497
- children2.get(outer).add(inner);
7498
- if (pivot.columnField) {
7499
- const column2 = pivotValueKey(record[columnField] ?? null);
7500
- for (const key of [[], [outer], [outer, inner]])
7501
- collect(buckets, JSON.stringify([...key, column2]), record);
7502
- }
7503
- }
7504
- const dimensions = pivotHeaderDimensions(pivot, columnItems.length, rowLabelColumns);
7505
- const rows = (details.size + rowItems.length * Number(bottom) + 1) * measures.length + rowItems.length * Number(layout3 !== "tabular") * (firstValues ? measures.length : 1) + (firstValues ? measures.length : between ? rowItems.length * measures.length : details.size) * Number(layout3 !== "tabular") + dimensions.rows;
7506
- if (rows * dimensions.width > 1e6) throw new Error("The PivotTable result is too large.");
7507
- const labels = compact ? ["Row Labels"] : [pivot.rowField, pivot.secondRowField];
7508
- const values2 = pivotHeaders(pivot, columnItems, labels, label);
7509
- const firstDataRow = values2.length;
7510
- const indents = values2.map(() => 0);
7511
- const rowEntries = [];
7512
- const append = (labels2, numbers4, entry3, indent = 0) => {
7513
- values2.push([...labels2, ...numbers4]);
7514
- rowEntries.push(entry3);
7515
- indents.push(indent);
7516
- };
7517
- const bands = (keys, records) => [
7518
- ...columnItems.map(
7519
- (column2) => pivotNumbers(pivot, buckets.get(JSON.stringify([...keys, pivotValueKey(column2)])) ?? [])
7520
- ),
7521
- pivotNumbers(pivot, records)
7522
- ];
7523
- const numbers3 = (keys, records) => bands(keys, records).flat();
7524
- const appendMeasures = (labels2, keys, records, indices, type) => {
7525
- const values3 = bands(keys, records);
7526
- measures.forEach(
7527
- (measure, m) => append(
7528
- type ? [
7529
- `${type === "grand" ? "Total" : String(labels2[0])} ${measure.caption}`,
7530
- ...Array(rowLabelColumns - 1).fill(null)
7531
- ] : compact ? [measure.caption] : [
7532
- ...labels2.map(
7533
- (label5) => layout3 === "tabular" && m === 0 || pivot.repeatLabels ? label5 : null
7534
- ),
7535
- measure.caption
7536
- ],
7537
- values3.map((band) => band[m] ?? null),
7538
- { indices: type ? indices : [...indices, m], measure: m, ...type ? { type } : {} },
7539
- compact && !type ? 2 : 0
7540
- )
7541
- );
7542
- };
7543
- if (firstValues)
7544
- appendFirstPivotValues(pivot, {
7545
- rowItems,
7546
- secondRowItems,
7547
- columnItems,
7548
- children: children2,
7549
- innerIndices,
7550
- groups,
7551
- details,
7552
- buckets,
7553
- width: dimensions.width,
7554
- rowLabels: rowLabelColumns,
7555
- top,
7556
- bottom,
7557
- append
7558
- });
7559
- else
7560
- rowItems.forEach((outer, outerIndex) => {
7561
- const key = pivotValueKey(outer);
7562
- if (layout3 !== "tabular")
7563
- append(
7564
- [label(outer), ...Array(rowLabelColumns - 1).fill(null)],
7565
- top ? numbers3([key], groups.get(key) ?? []) : Array(dimensions.width - rowLabelColumns).fill(null),
7566
- { indices: [outerIndex] }
7567
- );
7568
- let first2 = true;
7569
- const innerKeys = [...children2.get(key)].sort(
7570
- (a2, b) => innerIndices.get(a2) - innerIndices.get(b)
7571
- );
7572
- if (between)
7573
- measures.forEach((measure, m) => {
7574
- if (layout3 !== "tabular")
7575
- append(
7576
- compact ? [measure.caption] : [pivot.repeatLabels ? label(outer) : null, measure.caption, null],
7577
- Array(dimensions.width - rowLabelColumns).fill(null),
7578
- { indices: [outerIndex, m], measure: m },
7579
- compact ? 1 : 0
7580
- );
7581
- innerKeys.forEach((innerKey, child4) => {
7582
- const innerIndex = innerIndices.get(innerKey);
7583
- const keys = [key, innerKey];
7584
- const records = details.get(JSON.stringify(keys));
7585
- append(
7586
- compact ? [label(secondRowItems[innerIndex])] : [
7587
- pivot.repeatLabels || layout3 === "tabular" && m === 0 && child4 === 0 ? label(outer) : null,
7588
- layout3 === "tabular" && child4 === 0 ? measure.caption : null,
7589
- label(secondRowItems[innerIndex])
7590
- ],
7591
- [
7592
- ...columnItems.map(
7593
- (column2) => pivotMeasureNumber(
7594
- pivot,
7595
- buckets.get(JSON.stringify([...keys, pivotValueKey(column2)])) ?? [],
7596
- measure
7597
- )
7598
- ),
7599
- pivotMeasureNumber(pivot, records, measure)
7600
- ],
7601
- { indices: [outerIndex, m, innerIndex], measure: m },
7602
- compact ? 2 : 0
7603
- );
7604
- });
7605
- });
7606
- else
7607
- innerKeys.forEach((innerKey) => {
7608
- const innerIndex = innerIndices.get(innerKey);
7609
- const inner = secondRowItems[innerIndex];
7610
- const keys = [key, innerKey];
7611
- const records = details.get(JSON.stringify(keys));
7612
- if (!records) return;
7613
- if (layout3 !== "tabular")
7614
- append(
7615
- compact ? [label(inner)] : [pivot.repeatLabels ? label(outer) : null, label(inner), null],
7616
- Array(dimensions.width - rowLabelColumns).fill(null),
7617
- { indices: [outerIndex, innerIndex] },
7618
- compact ? 1 : 0
7619
- );
7620
- appendMeasures(
7621
- [pivot.repeatLabels || first2 ? label(outer) : null, label(inner)],
7622
- keys,
7623
- records,
7624
- [outerIndex, innerIndex]
7625
- );
7626
- first2 = false;
7627
- });
7628
- if (bottom)
7629
- appendMeasures([label(outer)], [key], groups.get(key) ?? [], [outerIndex], "default");
7630
- });
7631
- appendMeasures([], [], pivot.records, [0], "grand");
7632
- return {
7633
- values: values2,
7634
- rowItems,
7635
- secondRowItems,
7636
- columnItems,
7637
- rowEntries,
7638
- firstDataRow,
7639
- rowLabelColumns,
7640
- indents,
7641
- firstHeaderRow: 1
7642
- };
7643
- }
7644
-
7645
7419
  // xlsx/write/xml-out.ts
7646
7420
  var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n';
7647
7421
  var CONTROL = "\0-\b\v\f-" + String.fromCharCode(65534, 65535);
@@ -7681,15 +7455,49 @@ function inlineFragment(xml) {
7681
7455
  return head.includes(MAIN_NS) ? head.replace(MAIN_NS, "") + xml.slice(end) : xml;
7682
7456
  }
7683
7457
 
7458
+ // xlsx/pivot/measures.ts
7459
+ var pivotMeasures = (pivot) => [
7460
+ { field: pivot.valueField, aggregate: pivot.aggregate, caption: pivot.valueCaption },
7461
+ ...pivot.additionalValues ?? []
7462
+ ];
7463
+ var DIV0 = { error: "#DIV/0!" };
7464
+ function variance(numbers3, sample) {
7465
+ const n = numbers3.length;
7466
+ if (n < (sample ? 2 : 1)) return DIV0;
7467
+ const mean2 = numbers3.reduce((total2, value2) => total2 + value2, 0) / n;
7468
+ const squares = numbers3.reduce((total2, value2) => total2 + (value2 - mean2) ** 2, 0);
7469
+ return squares / (sample ? n - 1 : n);
7470
+ }
7471
+ function aggregateValues(records, field, type) {
7472
+ if (!records.length) return null;
7473
+ const values2 = records.map((record) => record[field] ?? null);
7474
+ if (type === "count") return values2.filter((value2) => value2 !== null && value2 !== "").length;
7475
+ if (type === "countNums") return values2.filter((value2) => typeof value2 === "number").length;
7476
+ const error = values2.find(isCellError);
7477
+ if (error) return error;
7478
+ const numbers3 = values2.filter((value2) => typeof value2 === "number");
7479
+ if (type === "var" || type === "varp" || type === "stdDev" || type === "stdDevp") {
7480
+ const result2 = variance(numbers3, type === "var" || type === "stdDev");
7481
+ return typeof result2 === "number" && (type === "stdDev" || type === "stdDevp") ? Math.sqrt(result2) : result2;
7482
+ }
7483
+ if (!numbers3.length) return type === "average" ? DIV0 : 0;
7484
+ if (type === "min") return numbers3.reduce((a2, b) => Math.min(a2, b));
7485
+ if (type === "max") return numbers3.reduce((a2, b) => Math.max(a2, b));
7486
+ if (type === "product") return numbers3.reduce((total2, value2) => total2 * value2, 1);
7487
+ const sum3 = numbers3.reduce((total2, value2) => total2 + value2, 0);
7488
+ return type === "average" ? sum3 / numbers3.length : sum3;
7489
+ }
7490
+ var pivotMeasureNumber = (pivot, records, measure) => aggregateValues(records, pivot.fields.indexOf(measure.field), measure.aggregate);
7491
+
7684
7492
  // xlsx/pivot/columns.ts
7685
7493
  var SEPARATOR = "";
7686
- var label2 = pivotItemLabel;
7687
7494
  var columnKey = (keys, depth) => keys.slice(0, depth).join(SEPARATOR);
7688
7495
  var recordColumnKeys = (record, indices) => indices.map((index3) => pivotValueKey(record[index3] ?? null));
7689
7496
  function pivotColumnEntries(pivot) {
7690
7497
  const names = pivotColumnFields(pivot);
7691
7498
  const items = names.map((name) => pivotItems(pivot, name));
7692
7499
  const entries = [];
7500
+ const functions = names.map((name) => fieldSubtotalFunctions(pivot, name));
7693
7501
  if (names.length) {
7694
7502
  const order = items.map(
7695
7503
  (list) => new Map(list.map((item, index3) => [pivotValueKey(item), index3]))
@@ -7724,7 +7532,9 @@ function pivotColumnEntries(pivot) {
7724
7532
  if (level === names.length - 1) entries.push({ kind: "leaf", ...entry3 });
7725
7533
  else {
7726
7534
  visit(child4[1], level + 1, here.path, here.values, here.keys);
7727
- entries.push({ kind: "subtotal", ...entry3 });
7535
+ const own = functions[level];
7536
+ if (own === "auto") entries.push({ kind: "subtotal", ...entry3 });
7537
+ else for (const fn of own) entries.push({ kind: "subtotal", ...entry3, fn });
7728
7538
  }
7729
7539
  }
7730
7540
  };
@@ -7733,26 +7543,31 @@ function pivotColumnEntries(pivot) {
7733
7543
  entries.push({ kind: "grand", path: [], key: "", values: [] });
7734
7544
  return { names, items, entries };
7735
7545
  }
7736
- function pivotColumnDimensions(pivot, columns, labelColumns) {
7737
- const measures = 1 + (pivot.additionalValues?.length ?? 0);
7546
+ function pivotColumnDimensions(pivot, columns, labelColumns, valuesOnRows = false) {
7547
+ const measures = valuesOnRows ? 1 : 1 + (pivot.additionalValues?.length ?? 0);
7738
7548
  const levels = columns.names.length;
7739
7549
  return {
7740
7550
  rows: (levels ? levels + 1 + Number(measures > 1) : 1) + (pivot.pageFilter ? 2 : 0),
7741
7551
  width: labelColumns + (levels ? columns.entries.length : 1) * measures
7742
7552
  };
7743
7553
  }
7744
- function pivotColumnHeaders(pivot, columns, rowLabels) {
7745
- const measures = pivotMeasures(pivot);
7554
+ function pivotColumnHeaders(pivot, columns, rowLabels, valuesOnRows = false) {
7555
+ const measures = valuesOnRows ? pivotMeasures(pivot).slice(0, 1) : pivotMeasures(pivot);
7746
7556
  const count2 = measures.length;
7747
7557
  const levels = columns.names.length;
7748
- if (!levels) return [[...rowLabels, ...measures.map((measure) => measure.caption)]];
7558
+ if (!levels)
7559
+ return [
7560
+ [...rowLabels, ...valuesOnRows ? [null] : measures.map((measure) => measure.caption)]
7561
+ ];
7749
7562
  const compact = pivot.layout === "compact";
7750
7563
  const labelColumns = rowLabels.length;
7751
7564
  const width = labelColumns + columns.entries.length * count2;
7752
7565
  const rows = levels + 1 + Number(count2 > 1);
7753
7566
  const grid = Array.from({ length: rows }, () => Array(width).fill(null));
7754
- if (count2 === 1) grid[0][0] = pivot.valueCaption;
7755
- const titles = compact ? ["Column Labels"] : [...columns.names, ...count2 > 1 ? ["Values"] : []];
7567
+ if (count2 === 1 && !valuesOnRows) grid[0][0] = pivot.valueCaption;
7568
+ const caps = pivotCaptions(pivot);
7569
+ const labelOf = pivotItemLabeler(pivot);
7570
+ const titles = compact ? [caps.columnLabels] : [...columns.names, ...count2 > 1 ? [caps.values] : []];
7756
7571
  titles.forEach((title, i2) => {
7757
7572
  grid[0][labelColumns + i2] = title;
7758
7573
  });
@@ -7765,16 +7580,17 @@ function pivotColumnHeaders(pivot, columns, rowLabels) {
7765
7580
  if (entry3.kind === "leaf") {
7766
7581
  entry3.path.forEach((_index, level) => {
7767
7582
  const continued = entry3.path.slice(0, level + 1).every((p, i2) => p === previous[i2]);
7768
- if (!continued) grid[1 + level][at] = label2(entry3.values[level]);
7583
+ if (!continued) grid[1 + level][at] = labelOf(columns.names[level], entry3.values[level]);
7769
7584
  });
7770
7585
  previous = entry3.path;
7771
7586
  if (count2 > 1) measures.forEach((measure, m) => grid[rows - 1][at + m] = measure.caption);
7772
7587
  return;
7773
7588
  }
7774
7589
  const row2 = entry3.kind === "grand" ? 1 : entry3.path.length;
7775
- const name = entry3.kind === "grand" ? "" : String(label2(entry3.values.at(-1)));
7590
+ const name = entry3.kind === "grand" ? "" : String(labelOf(columns.names[entry3.path.length - 1], entry3.values.at(-1)));
7776
7591
  measures.forEach((measure, m) => {
7777
- grid[row2][at + m] = count2 === 1 ? entry3.kind === "grand" ? "Grand Total" : `${name} Total` : entry3.kind === "grand" ? `Total ${measure.caption}` : `${name} ${measure.caption}`;
7592
+ const custom = entry3.fn ? caps.functions[entry3.fn] : void 0;
7593
+ 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}`;
7778
7594
  });
7779
7595
  });
7780
7596
  return grid;
@@ -7799,7 +7615,7 @@ function pivotColumnItemsXml(entries, measures, remap) {
7799
7615
  const prefix = sharedPrefix(path2, previous);
7800
7616
  const xs = path2.slice(prefix).map((index3) => `<x${attrs({ v: index3 || void 0 })}/>`);
7801
7617
  out.push(
7802
- `<i${attrs({ t: entry3.kind === "subtotal" ? "default" : void 0, r: prefix || void 0, i: m || void 0 })}>${xs.join("")}</i>`
7618
+ `<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>`
7803
7619
  );
7804
7620
  previous = path2;
7805
7621
  }
@@ -7807,7 +7623,6 @@ function pivotColumnItemsXml(entries, measures, remap) {
7807
7623
  }
7808
7624
 
7809
7625
  // xlsx/pivot/nested.ts
7810
- var label3 = pivotItemLabel;
7811
7626
  var MAX_CELLS = 1e6;
7812
7627
  var node = (index3, value2) => ({
7813
7628
  index: index3,
@@ -7819,6 +7634,10 @@ var node = (index3, value2) => ({
7819
7634
  function nestedPivotGrid(pivot) {
7820
7635
  const names = pivotRowFields(pivot);
7821
7636
  const depth = names.length;
7637
+ const valuesAt = pivotValuesIndex(pivot);
7638
+ const onRows = valuesAt >= 0;
7639
+ const levels = depth + (onRows ? 1 : 0);
7640
+ const fieldOf = (level) => !onRows || level < valuesAt ? level : level === valuesAt ? -1 : level - 1;
7822
7641
  const axisItems = names.map((name) => pivotItems(pivot, name));
7823
7642
  const itemIndices = axisItems.map(
7824
7643
  (items) => new Map(items.map((item, index3) => [pivotValueKey(item), index3]))
@@ -7830,125 +7649,170 @@ function nestedPivotGrid(pivot) {
7830
7649
  const compact = layout3 === "compact";
7831
7650
  const tabular = layout3 === "tabular";
7832
7651
  const above = !tabular && (pivot.subtotalPosition ?? "top") === "top";
7833
- const labelColumns = compact ? 1 : depth;
7652
+ const labelColumns = compact ? 1 : levels;
7834
7653
  const measures = pivotMeasures(pivot);
7654
+ const functions = names.map((name) => fieldSubtotalFunctions(pivot, name));
7655
+ const caps = pivotCaptions(pivot);
7656
+ const labelOf = pivotItemLabeler(pivot);
7835
7657
  const root = node(0, null);
7836
7658
  for (const record of pivot.records) {
7837
7659
  const keys = recordColumnKeys(record, columnFields);
7838
7660
  let current = root;
7839
- for (let level = -1; level < depth; level++) {
7840
- if (level >= 0) {
7841
- const value2 = record[fieldIndices[level]] ?? null;
7661
+ for (let field = -1; field < depth; field++) {
7662
+ if (field >= 0) {
7663
+ const value2 = record[fieldIndices[field]] ?? null;
7842
7664
  const key = pivotValueKey(value2);
7843
7665
  let child4 = current.children.get(key);
7844
7666
  if (!child4) {
7845
- child4 = node(itemIndices[level].get(key), value2);
7667
+ child4 = node(itemIndices[field].get(key), value2);
7846
7668
  current.children.set(key, child4);
7847
7669
  }
7848
7670
  current = child4;
7849
7671
  }
7850
7672
  current.records.push(record);
7851
- for (let width = 1; width <= keys.length; width++) {
7852
- const key = columnKey(keys, width);
7673
+ for (let width2 = 1; width2 <= keys.length; width2++) {
7674
+ const key = columnKey(keys, width2);
7853
7675
  const list = current.columns.get(key);
7854
7676
  if (list) list.push(record);
7855
7677
  else current.columns.set(key, [record]);
7856
7678
  }
7857
7679
  }
7858
7680
  }
7859
- const dimensions = pivotColumnDimensions(pivot, columns, labelColumns);
7860
- const functions = names.map((name) => fieldSubtotalFunctions(pivot, name));
7861
- let rows = 1;
7862
- const count2 = (parent, level) => {
7863
- for (const child4 of parent.children.values()) {
7864
- rows++;
7865
- if (level < depth - 1) {
7866
- const f6 = functions[level];
7867
- rows += f6 === "auto" ? 1 : f6.length;
7868
- count2(child4, level + 1);
7869
- }
7870
- }
7871
- };
7872
- count2(root, 0);
7873
- if ((rows + dimensions.rows) * dimensions.width > MAX_CELLS)
7874
- throw new Error("The PivotTable result is too large.");
7875
- const values2 = pivotColumnHeaders(pivot, columns, compact ? ["Row Labels"] : names);
7876
- const firstDataRow = values2.length;
7877
- const indents = values2.map(() => 0);
7681
+ const dimensions = pivotColumnDimensions(pivot, columns, labelColumns, onRows);
7682
+ const rowTitles = names.map((name) => name);
7683
+ if (onRows) rowTitles.splice(valuesAt, 0, caps.values);
7684
+ let values2 = [];
7685
+ let indents = [];
7878
7686
  const rowEntries = [];
7879
- const blanks = () => Array(dimensions.width - labelColumns).fill(null);
7880
- const bands = (group, run2) => columns.entries.flatMap(
7881
- (entry3) => run2(entry3.kind === "grand" ? group.records : group.columns.get(entry3.key) ?? [])
7882
- );
7883
- const numbers3 = (group) => bands(group, (records) => pivotNumbers(pivot, records));
7884
- const subtotalNumbers = (group, fn) => bands(
7885
- group,
7886
- (records) => measures.map((measure) => aggregateValues(records, pivot.fields.indexOf(measure.field), fn))
7887
- );
7888
- const labelCells = (path2, shown, text2) => {
7687
+ let counting = true;
7688
+ let rowCount = 0;
7689
+ const width = dimensions.width - labelColumns;
7690
+ const blanks = () => Array(width).fill(null);
7691
+ const cells = (group, rowFn, measure) => columns.entries.flatMap((entry3) => {
7692
+ const records = entry3.kind === "grand" ? group.records : group.columns.get(entry3.key) ?? [];
7693
+ const picked = measure === void 0 ? measures : [measures[measure]];
7694
+ if (rowFn && entry3.fn && rowFn !== entry3.fn) return picked.map(() => null);
7695
+ const fn = rowFn ?? entry3.fn;
7696
+ return picked.map(
7697
+ (one2) => fn ? aggregateValues(records, pivot.fields.indexOf(one2.field), fn) : pivotMeasureNumber(pivot, records, one2)
7698
+ );
7699
+ });
7700
+ const labelCells = (path2, shown, level, text2) => {
7889
7701
  if (compact) return [text2];
7890
- const cells = Array(depth).fill(null);
7891
- path2.forEach((value2, level) => {
7892
- if (shown[level]) cells[level] = label3(value2);
7702
+ const row2 = Array(levels).fill(null);
7703
+ path2.labels.forEach((value2, at) => {
7704
+ if (shown[at]) row2[at] = value2;
7893
7705
  });
7894
- cells[path2.length] = text2;
7895
- return cells;
7706
+ row2[level] = text2;
7707
+ return row2;
7896
7708
  };
7897
- const push = (cells, numbersOnRow, entry3, indent) => {
7898
- values2.push([...cells, ...numbersOnRow]);
7709
+ const push = (indent, build2) => {
7710
+ if (counting) {
7711
+ if ((++rowCount + dimensions.rows) * dimensions.width > MAX_CELLS)
7712
+ throw new Error("The PivotTable result is too large.");
7713
+ return;
7714
+ }
7715
+ const [cells2, numbers3, entry3] = build2();
7716
+ values2.push([...cells2, ...numbers3]);
7899
7717
  rowEntries.push(entry3);
7900
7718
  indents.push(compact ? indent : 0);
7901
7719
  };
7902
- const emit = (parent, level, path2, indices, firsts) => {
7903
- const last = level === depth - 1;
7904
- const own = functions[level];
7905
- const children2 = [...parent.children.values()].sort((a2, b) => a2.index - b.index);
7720
+ const entryOf = (indices, measure, type) => ({
7721
+ indices,
7722
+ ...measure !== void 0 ? { measure } : {},
7723
+ ...type ? { type } : {}
7724
+ });
7725
+ const walk = (level, group, measure, path2) => {
7726
+ const field = fieldOf(level);
7727
+ const last = level === levels - 1;
7728
+ const repeated = Array.from(
7729
+ { length: level },
7730
+ (_v, k) => !!pivot.repeatLabels && fieldOf(k) >= 0
7731
+ );
7732
+ const leafShown = (firsts) => repeated.map((repeat, k) => repeat || tabular && firsts.slice(k + 1).every(Boolean));
7733
+ if (field < 0) {
7734
+ measures.forEach((one2, m) => {
7735
+ const here = {
7736
+ labels: [...path2.labels, one2.caption],
7737
+ indices: [...path2.indices, m],
7738
+ firsts: [...path2.firsts, m === 0]
7739
+ };
7740
+ if (last)
7741
+ return push(level, () => [
7742
+ labelCells(path2, leafShown(here.firsts), level, one2.caption),
7743
+ cells(group, void 0, m),
7744
+ entryOf(here.indices, m)
7745
+ ]);
7746
+ if (!tabular)
7747
+ push(level, () => [
7748
+ labelCells(path2, repeated, level, one2.caption),
7749
+ blanks(),
7750
+ entryOf(here.indices, m)
7751
+ ]);
7752
+ walk(level + 1, group, m, here);
7753
+ });
7754
+ return;
7755
+ }
7756
+ const own = functions[field];
7757
+ const valuesAbove = !onRows || valuesAt < level;
7758
+ const showsValue = above && own === "auto" && valuesAbove;
7759
+ const children2 = [...group.children.values()].sort((a2, b) => a2.index - b.index);
7906
7760
  children2.forEach((child4, position) => {
7907
- const here = [...path2, child4.value];
7908
- const at = [...indices, child4.index];
7909
- const firstHere = [...firsts, position === 0];
7910
- const repeated = Array(level).fill(!!pivot.repeatLabels);
7911
- if (last) {
7912
- const shown = repeated.map(
7913
- (repeat, k) => repeat || tabular && firstHere.slice(k + 1).every(Boolean)
7914
- );
7915
- push(labelCells(path2, shown, label3(child4.value)), numbers3(child4), { indices: at }, level);
7916
- return;
7917
- }
7761
+ const here = {
7762
+ labels: [...path2.labels, labelOf(names[field], child4.value)],
7763
+ indices: [...path2.indices, child4.index],
7764
+ firsts: [...path2.firsts, position === 0]
7765
+ };
7766
+ const text2 = labelOf(names[field], child4.value);
7767
+ if (last)
7768
+ return push(level, () => [
7769
+ labelCells(path2, leafShown(here.firsts), level, text2),
7770
+ cells(child4, void 0, measure),
7771
+ entryOf(here.indices, measure)
7772
+ ]);
7918
7773
  if (!tabular)
7919
- push(
7920
- labelCells(path2, repeated, label3(child4.value)),
7921
- own === "auto" && above ? numbers3(child4) : blanks(),
7922
- { indices: at },
7923
- level
7924
- );
7925
- emit(child4, level + 1, here, at, firstHere);
7926
- const caption = String(label3(child4.value));
7774
+ push(level, () => [
7775
+ labelCells(path2, repeated, level, text2),
7776
+ showsValue ? cells(child4, void 0, measure) : blanks(),
7777
+ entryOf(here.indices, measure)
7778
+ ]);
7779
+ walk(level + 1, child4, measure, here);
7780
+ if (field === depth - 1) return;
7781
+ const caption = String(text2);
7782
+ const subtotal = (title, fn, one2) => push(level, () => [
7783
+ labelCells(path2, repeated, level, title),
7784
+ cells(child4, fn, one2),
7785
+ entryOf(here.indices, one2, fn ?? "default")
7786
+ ]);
7927
7787
  if (own === "auto") {
7928
- if (!above)
7929
- push(
7930
- labelCells(path2, repeated, `${caption} Total`),
7931
- numbers3(child4),
7932
- { indices: at, type: "default" },
7933
- level
7934
- );
7788
+ if (showsValue) return;
7789
+ if (valuesAbove) subtotal(fillCaption(caps.subtotal, caption), void 0, measure);
7790
+ else measures.forEach((one2, m) => subtotal(`${caption} ${one2.caption}`, void 0, m));
7935
7791
  } else
7936
7792
  for (const fn of own)
7937
- push(
7938
- labelCells(path2, repeated, `${caption} ${PIVOT_SUBTOTALS[fn].label}`),
7939
- subtotalNumbers(child4, fn),
7940
- { indices: at, type: fn },
7941
- level
7942
- );
7793
+ if (valuesAbove) subtotal(`${caption} ${caps.functions[fn]}`, fn, measure);
7794
+ else
7795
+ measures.forEach(
7796
+ (one2, m) => subtotal(`${caption} ${caps.functions[fn]} of ${one2.field}`, fn, m)
7797
+ );
7943
7798
  });
7944
7799
  };
7945
- emit(root, 0, [], [], []);
7946
- push(
7947
- compact ? ["Grand Total"] : ["Grand Total", ...Array(depth - 1).fill(null)],
7948
- numbers3(root),
7949
- { indices: [0], type: "grand" },
7950
- 0
7951
- );
7800
+ const grand = (text2, measure) => push(0, () => [
7801
+ compact ? [text2] : [text2, ...Array(levels - 1).fill(null)],
7802
+ cells(root, void 0, measure),
7803
+ entryOf([0], measure, "grand")
7804
+ ]);
7805
+ const build = () => {
7806
+ walk(0, root, void 0, { labels: [], indices: [], firsts: [] });
7807
+ if (onRows) measures.forEach((one2, m) => grand(fillCaption(caps.measureTotal, one2.caption), m));
7808
+ else grand(caps.grandTotal);
7809
+ };
7810
+ build();
7811
+ counting = false;
7812
+ values2 = pivotColumnHeaders(pivot, columns, compact ? [caps.rowLabels] : rowTitles, onRows);
7813
+ const firstDataRow = values2.length;
7814
+ indents = values2.map(() => 0);
7815
+ build();
7952
7816
  return {
7953
7817
  values: values2,
7954
7818
  rowItems: axisItems[0],
@@ -7960,105 +7824,15 @@ function nestedPivotGrid(pivot) {
7960
7824
  rowEntries,
7961
7825
  firstDataRow,
7962
7826
  rowLabelColumns: labelColumns,
7963
- indents
7827
+ indents,
7828
+ ...onRows ? { firstHeaderRow: 1 } : {}
7964
7829
  };
7965
7830
  }
7966
7831
 
7967
7832
  // xlsx/pivot/aggregate.ts
7968
7833
  function pivotGrid(pivot) {
7969
7834
  validatePivotFields(pivot);
7970
- return prependPivotPage(pivotDataGrid(pivotPageProjection(pivot)), pivot);
7971
- }
7972
- function pivotDataGrid(pivot) {
7973
- if (pivot.valuesAxis !== "rows") return nestedPivotGrid(pivot);
7974
- if (pivot.secondRowField) return hierarchicalPivotGrid(pivot);
7975
- const rowItems = pivotItems(pivot, pivot.rowField);
7976
- const columnItems = pivot.columnField ? pivotItems(pivot, pivot.columnField) : [];
7977
- const compact = pivot.layout === "compact";
7978
- const headings = pivot.layout !== void 0 && pivot.layout !== "tabular";
7979
- const dimensions = pivotHeaderDimensions(pivot, columnItems.length, compact ? 1 : 2);
7980
- const dataRows = (rowItems.length + 1) * (1 + (pivot.additionalValues?.length ?? 0)) + (headings ? rowItems.length : 0);
7981
- if ((dataRows + dimensions.rows) * dimensions.width > 1e6)
7982
- throw new Error("The PivotTable result is too large.");
7983
- const label5 = pivotItemLabel;
7984
- const values2 = pivotHeaders(pivot, columnItems, [compact ? "Row Labels" : pivot.rowField], label5);
7985
- const rowField = pivot.fields.indexOf(pivot.rowField);
7986
- const colField = pivot.columnField ? pivot.fields.indexOf(pivot.columnField) : -1;
7987
- const groups = /* @__PURE__ */ new Map();
7988
- const cells = /* @__PURE__ */ new Map();
7989
- const columns = /* @__PURE__ */ new Map();
7990
- const collect = (map, key, record) => {
7991
- const found = map.get(key);
7992
- if (found) found.push(record);
7993
- else map.set(key, [record]);
7994
- };
7995
- for (const record of pivot.records) {
7996
- const key = pivotValueKey(record[rowField] ?? null);
7997
- collect(groups, key, record);
7998
- if (pivot.columnField) {
7999
- const col = pivotValueKey(record[colField] ?? null);
8000
- collect(columns, col, record);
8001
- collect(cells, JSON.stringify([key, col]), record);
8002
- }
8003
- }
8004
- const firstDataRow = values2.length;
8005
- const measures = pivotMeasures(pivot);
8006
- const rowEntries = [];
8007
- const indents = values2.map(() => 0);
8008
- const append = (caption, bands, index3, grand = false) => {
8009
- measures.forEach((measure, m) => {
8010
- values2.push([
8011
- ...compact ? [grand ? `Total ${measure.caption}` : measure.caption] : [
8012
- grand ? `Total ${measure.caption}` : pivot.repeatLabels || !headings && m === 0 ? caption : null,
8013
- grand ? null : measure.caption
8014
- ],
8015
- ...bands.map((band) => band[m] ?? null)
8016
- ]);
8017
- indents.push(compact && !grand ? 1 : 0);
8018
- rowEntries.push({
8019
- indices: grand ? [0] : [index3, m],
8020
- measure: m,
8021
- ...grand ? { type: "grand" } : {}
8022
- });
8023
- });
8024
- };
8025
- rowItems.forEach((item, index3) => {
8026
- const key = pivotValueKey(item);
8027
- if (headings) {
8028
- values2.push([label5(item), ...Array(dimensions.width - 1).fill(null)]);
8029
- rowEntries.push({ indices: [index3] });
8030
- indents.push(0);
8031
- }
8032
- append(
8033
- label5(item),
8034
- [
8035
- ...columnItems.map(
8036
- (col) => pivotNumbers(pivot, cells.get(JSON.stringify([key, pivotValueKey(col)])) ?? [])
8037
- ),
8038
- pivotNumbers(pivot, groups.get(key) ?? [])
8039
- ],
8040
- index3
8041
- );
8042
- });
8043
- append(
8044
- "Grand Total",
8045
- [
8046
- ...columnItems.map((col) => pivotNumbers(pivot, columns.get(pivotValueKey(col)) ?? [])),
8047
- pivotNumbers(pivot, pivot.records)
8048
- ],
8049
- 0,
8050
- true
8051
- );
8052
- return {
8053
- values: values2,
8054
- rowItems,
8055
- columnItems,
8056
- firstDataRow,
8057
- rowLabelColumns: compact ? 1 : 2,
8058
- indents,
8059
- firstHeaderRow: 1,
8060
- rowEntries
8061
- };
7835
+ return prependPivotPage(nestedPivotGrid(pivotPageProjection(pivot)), pivot);
8062
7836
  }
8063
7837
  function pivotTableAt(sheet, at) {
8064
7838
  return sheet.pivotTables?.find((pivot) => rangeContains(pivot.location, at));
@@ -8068,14 +7842,14 @@ function pivotTableAt(sheet, at) {
8068
7842
  var X14 = "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main";
8069
7843
  var LAYOUT = "http://schemas.microsoft.com/office/spreadsheetml/2016/pivotdefaultlayout";
8070
7844
  var TABLE = {
8071
- 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",
7845
+ 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",
8072
7846
  location: "ref firstHeaderRow firstDataRow firstDataCol rowPageCount colPageCount",
8073
7847
  pageFields: "count",
8074
7848
  pageField: "fld item hier",
8075
7849
  pivotFields: "count",
8076
7850
  pivotField: "axis dataField compact outline showAll subtotalTop defaultSubtotal numFmtId sumSubtotal countASubtotal avgSubtotal maxSubtotal minSubtotal productSubtotal countSubtotal stdDevSubtotal stdDevPSubtotal varSubtotal varPSubtotal",
8077
7851
  items: "count",
8078
- item: "x t h",
7852
+ item: "x t h n",
8079
7853
  rowFields: "count",
8080
7854
  colFields: "count",
8081
7855
  field: "x",
@@ -8188,6 +7962,121 @@ function assertPivotRecords(records) {
8188
7962
  );
8189
7963
  }
8190
7964
 
7965
+ // xlsx/pivot/captions-read.ts
7966
+ var ATTRIBUTES = {
7967
+ rowHeaderCaption: "rowLabels",
7968
+ colHeaderCaption: "columnLabels",
7969
+ grandTotalCaption: "grandTotal",
7970
+ dataCaption: "values"
7971
+ };
7972
+ function readPivotCaptionAttributes(root) {
7973
+ const out = {};
7974
+ for (const [attribute2, key] of Object.entries(ATTRIBUTES)) {
7975
+ const text2 = att(root, attribute2);
7976
+ if (text2 !== void 0)
7977
+ out[key] = decodeEscapes(text2);
7978
+ }
7979
+ return out;
7980
+ }
7981
+ function aggregateCaptionsOf(pivot) {
7982
+ const out = {};
7983
+ for (const measure of [
7984
+ { field: pivot.valueField, aggregate: pivot.aggregate, caption: pivot.valueCaption },
7985
+ ...pivot.additionalValues ?? []
7986
+ ]) {
7987
+ const at = measure.caption.indexOf(measure.field);
7988
+ if (at < 0 || measure.caption === measure.field) continue;
7989
+ const template = `${measure.caption.slice(0, at)}{0}${measure.caption.slice(at + measure.field.length)}`;
7990
+ if (template !== ENGLISH_PIVOT_CAPTIONS.aggregates[measure.aggregate])
7991
+ out[measure.aggregate] = template;
7992
+ }
7993
+ return Object.keys(out).length ? out : void 0;
7994
+ }
7995
+ var MARK = "";
7996
+ var SENTINELS = {
7997
+ rowLabels: `${MARK}R`,
7998
+ columnLabels: `${MARK}C`,
7999
+ grandTotal: `${MARK}G`,
8000
+ values: `${MARK}V`,
8001
+ all: `${MARK}A`,
8002
+ blank: `${MARK}B`,
8003
+ subtotal: `{0}${MARK}S`,
8004
+ measureTotal: `${MARK}M{0}`,
8005
+ functions: Object.fromEntries(
8006
+ Object.keys(ENGLISH_PIVOT_CAPTIONS.functions).map((fn) => [fn, `${MARK}F${fn}`])
8007
+ ),
8008
+ aggregates: ENGLISH_PIVOT_CAPTIONS.aggregates
8009
+ };
8010
+ function templateOf(cached, arg) {
8011
+ if (!arg || !cached.includes(arg)) return void 0;
8012
+ if (cached.startsWith(arg)) return `{0}${cached.slice(arg.length)}`;
8013
+ if (cached.endsWith(arg)) return `${cached.slice(0, -arg.length)}{0}`;
8014
+ const at = cached.indexOf(arg);
8015
+ return `${cached.slice(0, at)}{0}${cached.slice(at + arg.length)}`;
8016
+ }
8017
+ function inferPivotCaptions(pivot, sheet, named2) {
8018
+ const known = pivotCaptions({ captions: named2 });
8019
+ const probe = { ...SENTINELS };
8020
+ for (const key of Object.keys(named2))
8021
+ if (typeof named2[key] === "string")
8022
+ probe[key] = known[key];
8023
+ const grid = pivotGrid({ ...pivot, captions: probe });
8024
+ const found = /* @__PURE__ */ new Map();
8025
+ const set = (key, value2) => {
8026
+ if (value2 === void 0) return;
8027
+ const before = found.get(key);
8028
+ found.set(key, before === void 0 || before === value2 ? value2 : null);
8029
+ };
8030
+ grid.values.forEach(
8031
+ (line2, r) => line2.forEach((expected, c2) => {
8032
+ if (typeof expected !== "string" || !expected.includes(MARK)) return;
8033
+ const cached = getCell(
8034
+ sheet,
8035
+ pivot.location.start.row + r,
8036
+ pivot.location.start.col + c2
8037
+ )?.value;
8038
+ if (typeof cached !== "string") return;
8039
+ const kind = /\u0001([RCGVASMFB])(\w*)/.exec(expected);
8040
+ if (!kind) return;
8041
+ const at = kind.index;
8042
+ switch (kind[1]) {
8043
+ case "R":
8044
+ return set("rowLabels", cached);
8045
+ case "C":
8046
+ return set("columnLabels", cached);
8047
+ case "G":
8048
+ return set("grandTotal", cached);
8049
+ case "V":
8050
+ return set("values", cached);
8051
+ case "A":
8052
+ return set("all", cached);
8053
+ case "B":
8054
+ return set("blank", cached);
8055
+ case "S":
8056
+ return set("subtotal", templateOf(cached, expected.slice(0, at)));
8057
+ case "M":
8058
+ return set("measureTotal", templateOf(cached, expected.slice(at + 2)));
8059
+ case "F": {
8060
+ const item = expected.slice(0, at - 1);
8061
+ const of = / of (.*)$/.exec(expected.slice(at));
8062
+ const word = cached.slice(item.length + 1, of ? cached.length - of[0].length : void 0);
8063
+ if (cached.startsWith(`${item} `) && (!of || cached.endsWith(of[0])))
8064
+ set(`function:${kind[2]}`, word);
8065
+ }
8066
+ }
8067
+ })
8068
+ );
8069
+ const out = pivotCaptions({ captions: named2 });
8070
+ const functions = { ...out.functions };
8071
+ for (const [key, value2] of found) {
8072
+ if (value2 === null) continue;
8073
+ if (key.startsWith("function:")) functions[key.slice(9)] = value2;
8074
+ else out[key] = value2;
8075
+ }
8076
+ out.functions = functions;
8077
+ return trimmedCaptions(out);
8078
+ }
8079
+
8191
8080
  // xlsx/slicer/read-slicers.ts
8192
8081
  var TABLE_SLICER_URI = "{2F2917AC-EB37-4324-AD4E-5DD8C200BD13}";
8193
8082
  var X152 = "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main";
@@ -8627,7 +8516,7 @@ function readFieldGroups(fields, names) {
8627
8516
  throw new Error("Unsupported pivot field group");
8628
8517
  const labels = children(list, "s", NS.x).map((node2) => decodeEscapes(att(node2, "v") ?? ""));
8629
8518
  const expected = numberGroupLabels({ start, end, by });
8630
- if (elements(list).length !== labels.length || labels.length !== expected.length || labels.some((label5, i2) => label5 !== expected[i2]))
8519
+ if (elements(list).length !== labels.length || labels.length !== expected.length || labels.some((label2, i2) => label2 !== expected[i2]))
8631
8520
  throw new Error("Unsupported pivot group items");
8632
8521
  groups.push({ field: names[index3] ?? "", start, end, by });
8633
8522
  });
@@ -8705,14 +8594,18 @@ function readDateGroups(fields, count2, names, dateFields, records, date1904) {
8705
8594
  const expected = dateGroupRange(group, serials);
8706
8595
  if (!close(expected.start, start) || !close(expected.end, end))
8707
8596
  throw unsupported("stale range");
8597
+ const localized = {};
8708
8598
  for (const entry3 of list) {
8709
- const labels = dateUnitLabels(entry3.unit, expected, dateGroupDays(group), date1904);
8599
+ const labels = englishDateUnitLabels(entry3.unit, expected, dateGroupDays(group), date1904);
8710
8600
  const node2 = first(first(entry3.node, "fieldGroup", NS.x), "groupItems", NS.x);
8711
8601
  const actual = children(node2, "s", NS.x).map((item) => decodeEscapes(att(item, "v") ?? ""));
8712
- 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]))
8602
+ const name = decodeEscapes(att(entry3.node, "name") ?? "");
8603
+ if (!name || elements(node2).length !== actual.length || actual.length !== labels.length || actual.some((label2) => !label2) || new Set(actual).size !== actual.length)
8713
8604
  throw unsupported("group items");
8605
+ if (name !== dateGroupFieldName(entry3.unit, field) || actual.some((l, i2) => l !== labels[i2]))
8606
+ localized[entry3.unit] = { name, labels: actual };
8714
8607
  }
8715
- groups.push(group);
8608
+ groups.push(Object.keys(localized).length ? { ...group, localized } : group);
8716
8609
  }
8717
8610
  return groups;
8718
8611
  }
@@ -8765,12 +8658,32 @@ function readItemFilters(fields, names, shared) {
8765
8658
  return filters.length ? filters : void 0;
8766
8659
  }
8767
8660
 
8661
+ // xlsx/pivot/item-names-read.ts
8662
+ function readItemNames(tableFields, names, shared) {
8663
+ const out = [];
8664
+ tableFields.forEach((field, index3) => {
8665
+ const list = first(field, "items", NS.x);
8666
+ if (!list || index3 >= names.length) return;
8667
+ for (const item of children(list, "item", NS.x)) {
8668
+ const name = att(item, "n");
8669
+ if (name === void 0) continue;
8670
+ const at = Number(att(item, "x"));
8671
+ const value2 = shared[index3]?.[at];
8672
+ if (att(item, "t") !== void 0 || !Number.isInteger(at) || value2 === void 0)
8673
+ throw new Error("Unsupported pivot item name");
8674
+ out.push({ field: names[index3], item: value2, name: decodeEscapes(name) });
8675
+ }
8676
+ });
8677
+ return out;
8678
+ }
8679
+
8768
8680
  // xlsx/pivot/values-axis.ts
8769
8681
  function remapPivotRowEntries(entries, axes2) {
8770
8682
  return entries.map(
8771
8683
  (entry3) => entry3.type === "grand" ? entry3 : {
8772
8684
  ...entry3,
8773
8685
  indices: entry3.indices.map((item, axis) => {
8686
+ if (axes2[axis] === null) return item;
8774
8687
  const index3 = axes2[axis]?.[item];
8775
8688
  if (index3 === void 0) throw new Error("Invalid report row axis item");
8776
8689
  return index3;
@@ -8789,7 +8702,7 @@ function pivotValueIndex(root, axis) {
8789
8702
  const position = root.getAttribute("dataPosition");
8790
8703
  if (position !== null && (!/^\d+$/.test(position.trim()) || Number(position) !== index3))
8791
8704
  throw new Error("Inconsistent Values axis position");
8792
- if (axis.length === 3 && index3 >= 0 && index3 < 2 && position === null)
8705
+ if (index3 >= 0 && index3 < axis.length - 1 && position === null)
8793
8706
  throw new Error("Missing leading or between-field Values position");
8794
8707
  return index3;
8795
8708
  }
@@ -8804,7 +8717,7 @@ function pivotValueAxisItems(measures) {
8804
8717
  function supportedPivotAxes(rows, columns, measures, valuesOnRows) {
8805
8718
  const index3 = pivotFieldIndex;
8806
8719
  if (valuesOnRows)
8807
- 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);
8720
+ 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);
8808
8721
  if (rows.some((field) => !Number.isInteger(index3(field)) || index3(field) < 0)) return false;
8809
8722
  if (measures > 1 && (!columns.length || index3(columns.at(-1)) !== -2)) return false;
8810
8723
  return (measures > 1 ? columns.slice(0, -1) : columns).every(
@@ -8866,6 +8779,9 @@ function assertPageAxisItems(root, pivot, shared, cache2, recordRoot) {
8866
8779
  literals(cache2);
8867
8780
  literals(recordRoot);
8868
8781
  const cacheFields = children(first(cache2, "cacheFields", NS.x), "cacheField", NS.x);
8782
+ const all2 = expandDateGroups(pivot).fields;
8783
+ const derived = all2.slice(pivot.fields.length).map((name) => groupLabelsOf(pivot, name) ?? []);
8784
+ const sharedAll = [...shared, ...derived];
8869
8785
  if (pivot.columnField) {
8870
8786
  const column2 = children(first(root, "pivotFields", NS.x), "pivotField", NS.x)[pivot.fields.indexOf(pivot.columnField)];
8871
8787
  const list = first(column2, "extLst", NS.x);
@@ -8884,13 +8800,13 @@ function assertPageAxisItems(root, pivot, shared, cache2, recordRoot) {
8884
8800
  ))
8885
8801
  throw new Error("Repeated report column labels are preserved");
8886
8802
  }
8887
- if (integer(first(cache2, "cacheFields", NS.x)?.getAttribute("count") ?? null) !== pivot.fields.length || integer(cache2.getAttribute("recordCount")) !== pivot.records.length || integer(recordRoot.getAttribute("count")) !== pivot.records.length)
8803
+ if (integer(first(cache2, "cacheFields", NS.x)?.getAttribute("count") ?? null) !== all2.length || integer(cache2.getAttribute("recordCount")) !== pivot.records.length || integer(recordRoot.getAttribute("count")) !== pivot.records.length)
8888
8804
  throw new Error("Inconsistent report cache counts");
8889
8805
  for (const name of [...pivotRowFields(pivot), pivot.columnField, pivot.pageFilter.field].filter(
8890
8806
  Boolean
8891
8807
  )) {
8892
- const field = pivot.fields.indexOf(name);
8893
- if (integer(first(cacheFields[field], "sharedItems", NS.x)?.getAttribute("count") ?? null) !== shared[field].length)
8808
+ const field = all2.indexOf(name);
8809
+ if (field < pivot.fields.length && integer(first(cacheFields[field], "sharedItems", NS.x)?.getAttribute("count") ?? null) !== shared[field].length)
8894
8810
  throw new Error("Inconsistent report shared-item counts");
8895
8811
  }
8896
8812
  for (const name of ["rowFields", "colFields"]) {
@@ -8900,7 +8816,7 @@ function assertPageAxisItems(root, pivot, shared, cache2, recordRoot) {
8900
8816
  }
8901
8817
  const projected = pivotPageProjection(pivot), fields = children(first(root, "pivotFields", NS.x), "pivotField", NS.x);
8902
8818
  const axisValues = (name, axis) => {
8903
- 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;
8819
+ const f6 = all2.indexOf(name), node2 = fields[f6], list = first(node2, "items", NS.x), items = children(list, "item", NS.x), count2 = sharedAll[f6].length;
8904
8820
  if (node2.getAttribute("axis") !== axis) throw new Error("Inconsistent report axis field");
8905
8821
  const defaults = node2.getAttribute("defaultSubtotal") !== "0";
8906
8822
  if (!list || integer(list.getAttribute("count")) !== items.length || items.length !== count2 + Number(defaults))
@@ -8909,7 +8825,7 @@ function assertPageAxisItems(root, pivot, shared, cache2, recordRoot) {
8909
8825
  const i2 = integer(item.getAttribute("x"));
8910
8826
  if (item.hasAttribute("t") || !Number.isInteger(i2) || i2 >= count2)
8911
8827
  throw new Error("Invalid page-axis cache item");
8912
- return shared[f6][i2];
8828
+ return sharedAll[f6][i2];
8913
8829
  });
8914
8830
  if (new Set(data.map(pivotValueKey)).size !== count2 || defaults && (items.at(-1)?.getAttribute("t") !== "default" || items.at(-1)?.hasAttribute("x")))
8915
8831
  throw new Error("Invalid page-axis default item");
@@ -8924,7 +8840,10 @@ function assertPageAxisItems(root, pivot, shared, cache2, recordRoot) {
8924
8840
  };
8925
8841
  const rowAxes = pivotRowFields(pivot).map((name) => axisValues(name, "axisRow")), rowItems = read("rowItems");
8926
8842
  const grid = pivotGrid(pivot);
8927
- const entries = grid.rowEntries ? remapPivotRowEntries(grid.rowEntries, rowAxes) : [
8843
+ const valuesAt = pivotValuesIndex(pivot);
8844
+ const levelAxes = [...rowAxes];
8845
+ if (valuesAt >= 0) levelAxes.splice(valuesAt, 0, null);
8846
+ const entries = grid.rowEntries ? remapPivotRowEntries(grid.rowEntries, levelAxes) : [
8928
8847
  ...rowAxes[0].map((index3) => ({ indices: [index3] })),
8929
8848
  { indices: [0], type: "grand" }
8930
8849
  ];
@@ -8934,11 +8853,11 @@ function assertPageAxisItems(root, pivot, shared, cache2, recordRoot) {
8934
8853
  const expected2 = entries[i2];
8935
8854
  const xs = children(item, "x", NS.x).map((x) => integer(x.getAttribute("v"), 0)), prefix = integer(item.getAttribute("r"), 0);
8936
8855
  const type = expected2.type === void 0 || expected2.type === "default" || expected2.type === "grand" ? expected2.type : PIVOT_SUBTOTALS[expected2.type].item;
8937
- 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))
8856
+ 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))
8938
8857
  throw new Error("Unmodeled page row item");
8939
8858
  previousRow = expected2.type === "grand" ? [] : expected2.indices;
8940
8859
  });
8941
- const measures = 1 + (pivot.additionalValues?.length ?? 0), columns = pivot.columnField ? axisValues(pivot.columnField, "axisCol") : void 0, expected = [];
8860
+ const measures = valuesAt >= 0 ? 1 : 1 + (pivot.additionalValues?.length ?? 0), columns = pivot.columnField ? axisValues(pivot.columnField, "axisCol") : void 0, expected = [];
8942
8861
  if (columns)
8943
8862
  for (const col of columns)
8944
8863
  for (let m = 0; m < measures; m++) expected.push(measures > 1 ? [col, m] : [col]);
@@ -8980,6 +8899,10 @@ function value(node2, date1904 = false) {
8980
8899
  if (node2.localName === "e" && isErrorCode(v)) return { error: v };
8981
8900
  throw new Error("Unsupported pivot cache item");
8982
8901
  }
8902
+ var namedAggregates = (pivot) => {
8903
+ const aggregates = aggregateCaptionsOf(pivot);
8904
+ return aggregates ? { aggregates } : {};
8905
+ };
8983
8906
  function readOne(workbook, source2, part) {
8984
8907
  const xml = source2.text(part);
8985
8908
  const root = parseXml(xml).documentElement;
@@ -9045,7 +8968,7 @@ function readOne(workbook, source2, part) {
9045
8968
  "dataField",
9046
8969
  NS.x
9047
8970
  );
9048
- 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")
8971
+ if (rowFields.length < 1 || dataFields.length < 1 || dataFields.length > 16 || !supportedPivotAxes(rowFields, colFields, dataFields.length, rowsAxis) || root.getAttribute("rowGrandTotals") === "0" || root.getAttribute("colGrandTotals") === "0")
9049
8972
  throw new Error("Unsupported pivot layout");
9050
8973
  const valueIndex = pivotValueIndex(root, rowsAxis ? rowFields : colFields);
9051
8974
  const measure = dataFields[0];
@@ -9115,8 +9038,8 @@ function readOne(workbook, source2, part) {
9115
9038
  const col = columnNames[0];
9116
9039
  const moreColumns = columnNames.slice(1);
9117
9040
  const columnDefinitions = columnDefs.map((field) => tableFields[Number(att(field, "x"))]);
9118
- if (fieldSubtotalsOf(columnDefinitions.slice(0, -1), columnNames.slice(0, -1)).length || columnNames.some((name) => !name))
9119
- throw new Error("Column subtotal settings are preserved");
9041
+ if (columnNames.some((name) => !name)) throw new Error("Invalid pivot column fields");
9042
+ const columnSubtotals = fieldSubtotalsOf(columnDefinitions, columnNames);
9120
9043
  const data = names[Number(att(measure, "fld"))];
9121
9044
  const location = parseRange(att(first(root, "location", NS.x), "ref") ?? "");
9122
9045
  if (!row2 || !data || !location || hasColumn && !col || realRows.length === 2 && !second)
@@ -9126,6 +9049,7 @@ function readOne(workbook, source2, part) {
9126
9049
  location.start.row -= 2;
9127
9050
  }
9128
9051
  const itemFilters = readItemFilters(tableFields, names, shared);
9052
+ const itemNames = readItemNames(tableFields, names, shared);
9129
9053
  const slicerCacheId = readSlicerCacheId(cache2);
9130
9054
  const fieldGroups = readFieldGroups(fields, names);
9131
9055
  const dateFields = readDateFields(fields, names);
@@ -9157,11 +9081,14 @@ function readOne(workbook, source2, part) {
9157
9081
  ]);
9158
9082
  if (dateFields.some((field) => onAxis.has(field)))
9159
9083
  throw new Error("Date fields used as rows, columns or values are preserved");
9160
- if ([...realRows, ...columnDefs].some((field) => pivotFieldIndex(field) >= databaseCount) && (pageFilter || dateFilter || itemFilters || slicerCacheId !== void 0))
9161
- throw new Error("Date groups with filters are preserved");
9084
+ const fieldSubtotals = [
9085
+ ...subtotalSettings.filter((entry4) => entry4.field !== row2 || entry4.functions.length),
9086
+ ...columnSubtotals
9087
+ ];
9162
9088
  const pivot = {
9163
9089
  ...pageFilter ? { pageFilter } : {},
9164
9090
  ...itemFilters ? { itemFilters } : {},
9091
+ ...itemNames.length ? { itemNames } : {},
9165
9092
  ...fieldGroups.length ? { fieldGroups } : {},
9166
9093
  ...dateFields.length ? { dateFields } : {},
9167
9094
  ...dateGroups.length ? { dateGroups } : {},
@@ -9173,13 +9100,11 @@ function readOne(workbook, source2, part) {
9173
9100
  rowField: row2,
9174
9101
  layout: layout3,
9175
9102
  ...rowsAxis ? { valuesAxis: "rows" } : {},
9176
- ...rowsAxis && realRows.length === 2 && valueIndex < 2 ? { valuesPosition: valueIndex === 0 ? "first" : "between" } : {},
9177
- subtotalPosition: att(outer, "subtotalTop") === "0" ? "bottom" : "top",
9178
- ...subtotalSettings.some((entry4) => entry4.field !== row2 || entry4.functions.length) ? {
9179
- fieldSubtotals: subtotalSettings.filter(
9180
- (entry4) => entry4.field !== row2 || entry4.functions.length
9181
- )
9103
+ ...rowsAxis && valueIndex < realRows.length ? {
9104
+ valuesPosition: valueIndex === 0 ? "first" : valueIndex === 1 && realRows.length === 2 ? "between" : valueIndex
9182
9105
  } : {},
9106
+ subtotalPosition: att(outer, "subtotalTop") === "0" ? "bottom" : "top",
9107
+ ...fieldSubtotals.length ? { fieldSubtotals } : {},
9183
9108
  ...more.length ? { moreRowFields: more } : {},
9184
9109
  ...second ? { secondRowField: second, subtotals: subtotal, repeatLabels: repeat[0] ?? false } : {
9185
9110
  ...subtotal ? {} : { subtotals: false },
@@ -9206,6 +9131,12 @@ function readOne(workbook, source2, part) {
9206
9131
  ...col ? { columnField: col } : {},
9207
9132
  ...moreColumns.length ? { moreColumnFields: moreColumns } : {}
9208
9133
  };
9134
+ const captions = trimmedCaptions(
9135
+ pivotCaptions({
9136
+ captions: { ...readPivotCaptionAttributes(root), ...namedAggregates(pivot) }
9137
+ })
9138
+ );
9139
+ if (captions) pivot.captions = captions;
9209
9140
  if (pageFilter && moreColumns.length) throw new Error("Report filters support one column field");
9210
9141
  assertPageAxisItems(root, pivot, shared, cache2, recordRoot);
9211
9142
  return pivot;
@@ -9233,6 +9164,12 @@ function readPivotTables(workbook, source2, warn, slicers) {
9233
9164
  if (slicers.blocked.has(pivotKey(sheet.sheetId, name)) || cache2 && (caches2.get(cache2) ?? 0) > 1)
9234
9165
  throw new Error("Shared pivot cache or unsupported slicer connection");
9235
9166
  const pivot = readOne(workbook, source2, part);
9167
+ const inferred = inferPivotCaptions(pivot, sheet, {
9168
+ ...readPivotCaptionAttributes(parseXml(pivot.sourceXml).documentElement),
9169
+ ...namedAggregates(pivot)
9170
+ });
9171
+ if (inferred) pivot.captions = inferred;
9172
+ else delete pivot.captions;
9236
9173
  const grid = pivotGrid(pivot);
9237
9174
  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(
9238
9175
  (line2, r) => line2.some(
@@ -9993,7 +9930,7 @@ function mergeSpacedAreas(tokens2) {
9993
9930
  }
9994
9931
  return out;
9995
9932
  }
9996
- function templateOf(formula) {
9933
+ function templateOf2(formula) {
9997
9934
  const cached = templates.get(formula);
9998
9935
  if (cached !== void 0) return cached;
9999
9936
  const raw2 = safeTokens(formula);
@@ -10023,7 +9960,7 @@ function templateOf(formula) {
10023
9960
  return template;
10024
9961
  }
10025
9962
  function rewriteTemplate(formula, rewrite2) {
10026
- const template = templateOf(formula);
9963
+ const template = templateOf2(formula);
10027
9964
  if (!template) return formula;
10028
9965
  let next;
10029
9966
  for (let i2 = 0; i2 < template.length; i2++) {
@@ -10605,8 +10542,8 @@ function parseDiagramDataModel(source2, part) {
10605
10542
  "CONNECTION_ENDPOINT_MISSING",
10606
10543
  `dgm:cxn ${attribute2} references missing point: ${id}.`
10607
10544
  );
10608
- const label5 = connectionLabel(connection, transitionText);
10609
- connections.push(label5 ? { ...connection, label: label5 } : connection);
10545
+ const label2 = connectionLabel(connection, transitionText);
10546
+ connections.push(label2 ? { ...connection, label: label2 } : connection);
10610
10547
  if ((!connection.type || connection.type === "parOf") && !parentById.has(connection.destId))
10611
10548
  parentById.set(connection.destId, connection.sourceId);
10612
10549
  }
@@ -10645,14 +10582,14 @@ function colorList(container2) {
10645
10582
  }
10646
10583
  function parseDiagramColors(source2) {
10647
10584
  const root = rootOf2(source2);
10648
- const labels = children(root, "styleLbl", NS.dgm).map((label5) => ({
10649
- name: stringAttribute(label5, "name") ?? "",
10650
- fill: colorList(first(label5, "fillClrLst", NS.dgm)),
10651
- line: colorList(first(label5, "linClrLst", NS.dgm)),
10652
- effect: colorList(first(label5, "effectClrLst", NS.dgm)),
10653
- textLine: colorList(first(label5, "txLinClrLst", NS.dgm)),
10654
- textFill: colorList(first(label5, "txFillClrLst", NS.dgm)),
10655
- textEffect: colorList(first(label5, "txEffectClrLst", NS.dgm))
10585
+ const labels = children(root, "styleLbl", NS.dgm).map((label2) => ({
10586
+ name: stringAttribute(label2, "name") ?? "",
10587
+ fill: colorList(first(label2, "fillClrLst", NS.dgm)),
10588
+ line: colorList(first(label2, "linClrLst", NS.dgm)),
10589
+ effect: colorList(first(label2, "effectClrLst", NS.dgm)),
10590
+ textLine: colorList(first(label2, "txLinClrLst", NS.dgm)),
10591
+ textFill: colorList(first(label2, "txFillClrLst", NS.dgm)),
10592
+ textEffect: colorList(first(label2, "txEffectClrLst", NS.dgm))
10656
10593
  }));
10657
10594
  return { ...parseDefinitionHeader(root), labels };
10658
10595
  }
@@ -10685,16 +10622,16 @@ function parseStyleReferences(style2) {
10685
10622
  var hasContent = (element2) => Boolean(element2 && (element2.attributes.length > 0 || elements(element2).length > 0));
10686
10623
  function parseDiagramQuickStyle(source2) {
10687
10624
  const root = rootOf2(source2);
10688
- const labels = children(root, "styleLbl", NS.dgm).map((label5) => ({
10689
- name: stringAttribute(label5, "name") ?? "",
10690
- ...parseStyleReferences(first(label5, "style", NS.dgm)),
10691
- hasScene3d: Boolean(first(label5, "scene3d", NS.dgm)),
10692
- hasShape3d: hasContent(first(label5, "sp3d", NS.dgm))
10625
+ const labels = children(root, "styleLbl", NS.dgm).map((label2) => ({
10626
+ name: stringAttribute(label2, "name") ?? "",
10627
+ ...parseStyleReferences(first(label2, "style", NS.dgm)),
10628
+ hasScene3d: Boolean(first(label2, "scene3d", NS.dgm)),
10629
+ hasShape3d: hasContent(first(label2, "sp3d", NS.dgm))
10693
10630
  }));
10694
10631
  return {
10695
10632
  ...parseDefinitionHeader(root),
10696
10633
  labels,
10697
- has3d: labels.some((label5) => label5.hasShape3d)
10634
+ has3d: labels.some((label2) => label2.hasShape3d)
10698
10635
  };
10699
10636
  }
10700
10637
  function parseDiagramLayoutSummary(source2) {
@@ -12371,10 +12308,10 @@ function parseDisplayUnits(context, element2) {
12371
12308
  if (!element2) return void 0;
12372
12309
  reportUnmodelled(context, element2, DISPLAY_UNITS);
12373
12310
  const labelElement = cChild(element2, "dispUnitsLbl");
12374
- let label5;
12311
+ let label2;
12375
12312
  if (labelElement) {
12376
12313
  reportUnmodelled(context, labelElement, DISPLAY_UNITS_LABEL);
12377
- label5 = assignDefined(
12314
+ label2 = assignDefined(
12378
12315
  {},
12379
12316
  {
12380
12317
  layout: manualLayout(labelElement),
@@ -12389,7 +12326,7 @@ function parseDisplayUnits(context, element2) {
12389
12326
  {
12390
12327
  builtInUnit: cVal(element2, "builtInUnit"),
12391
12328
  customUnit: cNumber(context, element2, "custUnit"),
12392
- label: label5,
12329
+ label: label2,
12393
12330
  extLst: extensionList(element2)
12394
12331
  }
12395
12332
  );
@@ -13985,8 +13922,8 @@ function parseTable(xml, partName) {
13985
13922
  if (id !== void 0 && Number.isInteger(id) && id >= 0) column2.sourceId = id;
13986
13923
  const fn = att(node2, "totalsRowFunction");
13987
13924
  if (fn && fn !== "none") column2.totalsRowFunction = fn;
13988
- const label5 = att(node2, "totalsRowLabel");
13989
- if (label5 !== void 0) column2.totalsRowLabel = label5;
13925
+ const label2 = att(node2, "totalsRowLabel");
13926
+ if (label2 !== void 0) column2.totalsRowLabel = label2;
13990
13927
  const calculated = xFirst(node2, "calculatedColumnFormula");
13991
13928
  if (calculated) column2.calculatedColumnFormula = stripFuturePrefixes(xText(calculated));
13992
13929
  return column2;
@@ -14870,10 +14807,10 @@ function titleXml(context, title) {
14870
14807
  function labelOptionsXml(context, options) {
14871
14808
  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));
14872
14809
  }
14873
- function labelXml(context, label5) {
14810
+ function labelXml(context, label2) {
14874
14811
  return elementXml(
14875
14812
  "dLbl",
14876
- valXml("idx", label5.index) + valXml("delete", label5.deleted) + layoutXml(context, label5.layout) + chartTextXml(context, label5.tx, false) + labelOptionsXml(context, label5) + raw(context, label5.extLst)
14813
+ valXml("idx", label2.index) + valXml("delete", label2.deleted) + layoutXml(context, label2.layout) + chartTextXml(context, label2.tx, false) + labelOptionsXml(context, label2) + raw(context, label2.extLst)
14877
14814
  );
14878
14815
  }
14879
14816
  function dataLabelsXml(context, labels) {
@@ -14881,7 +14818,7 @@ function dataLabelsXml(context, labels) {
14881
14818
  const leaderLines = labels.leaderLines ? elementXml("leaderLines", shapePropertiesXml(context, labels.leaderLines.spPr)) : "";
14882
14819
  return elementXml(
14883
14820
  "dLbls",
14884
- labels.labels.map((label5) => labelXml(context, label5)).join("") + valXml("delete", labels.deleted) + labelOptionsXml(context, labels) + valXml("showLeaderLines", labels.showLeaderLines) + leaderLines + raw(context, labels.extLst)
14821
+ labels.labels.map((label2) => labelXml(context, label2)).join("") + valXml("delete", labels.deleted) + labelOptionsXml(context, labels) + valXml("showLeaderLines", labels.showLeaderLines) + leaderLines + raw(context, labels.extLst)
14885
14822
  );
14886
14823
  }
14887
14824
 
@@ -14902,12 +14839,12 @@ function dataTableXml(context, table2) {
14902
14839
  }
14903
14840
  function displayUnitsXml(context, units) {
14904
14841
  if (!units) return "";
14905
- const label5 = units.label;
14842
+ const label2 = units.label;
14906
14843
  return elementXml(
14907
14844
  "dispUnits",
14908
- valXml("custUnit", units.customUnit) + (units.customUnit === void 0 ? valXml("builtInUnit", units.builtInUnit) : "") + (label5 ? elementXml(
14845
+ valXml("custUnit", units.customUnit) + (units.customUnit === void 0 ? valXml("builtInUnit", units.builtInUnit) : "") + (label2 ? elementXml(
14909
14846
  "dispUnitsLbl",
14910
- layoutXml(context, label5.layout) + chartTextXml(context, label5.tx, false) + shapePropertiesXml(context, label5.spPr) + textBodyXml(context, label5.txPr)
14847
+ layoutXml(context, label2.layout) + chartTextXml(context, label2.tx, false) + shapePropertiesXml(context, label2.spPr) + textBodyXml(context, label2.txPr)
14911
14848
  ) : "") + raw(context, units.extLst)
14912
14849
  );
14913
14850
  }
@@ -14932,11 +14869,11 @@ function axisXml(context, axis) {
14932
14869
  }
14933
14870
 
14934
14871
  // chart/write-analysis.ts
14935
- function trendlineLabelXml(context, label5) {
14936
- if (!label5) return "";
14872
+ function trendlineLabelXml(context, label2) {
14873
+ if (!label2) return "";
14937
14874
  return elementXml(
14938
14875
  "trendlineLbl",
14939
- layoutXml(context, label5.layout) + chartTextXml(context, label5.tx, false) + numberFormatXml(label5.numberFormat) + shapePropertiesXml(context, label5.spPr) + textBodyXml(context, label5.txPr) + raw(context, label5.extLst)
14876
+ layoutXml(context, label2.layout) + chartTextXml(context, label2.tx, false) + numberFormatXml(label2.numberFormat) + shapePropertiesXml(context, label2.spPr) + textBodyXml(context, label2.txPr) + raw(context, label2.extLst)
14940
14877
  );
14941
14878
  }
14942
14879
  function trendlineXml(context, trendline) {
@@ -16953,14 +16890,14 @@ function unique(args, ctx) {
16953
16890
  const byCol = args.length > 1 && args[1] !== null && toBool(ctx.toScalar(args[1] ?? null));
16954
16891
  const once = args.length > 2 && args[2] !== null && toBool(ctx.toScalar(args[2] ?? null));
16955
16892
  if (byCol) m = transpose(m);
16956
- const keyOf2 = (row2) => JSON.stringify(
16893
+ const keyOf3 = (row2) => JSON.stringify(
16957
16894
  row2.map(
16958
16895
  (v) => isError(v) ? `#${v.error}` : typeof v === "string" ? `s${v.toLowerCase()}` : v
16959
16896
  )
16960
16897
  );
16961
16898
  const counts = /* @__PURE__ */ new Map();
16962
16899
  for (const row2 of m.data) {
16963
- const key = keyOf2(row2);
16900
+ const key = keyOf3(row2);
16964
16901
  const entry3 = counts.get(key);
16965
16902
  if (entry3) entry3.count++;
16966
16903
  else counts.set(key, { row: row2, count: 1 });
@@ -17245,11 +17182,11 @@ function gammaLn(z) {
17245
17182
 
17246
17183
  // xlsx/formula/functions/database.ts
17247
17184
  var C3 = "Database";
17248
- var label4 = (value2) => value2 === null ? "" : typeof value2 === "string" ? value2 : String(value2);
17185
+ var label = (value2) => value2 === null ? "" : typeof value2 === "string" ? value2 : String(value2);
17249
17186
  function tableOf(ctx, value2) {
17250
17187
  const [head, ...records] = ctx.toMatrix(value2 ?? null).data;
17251
17188
  if (!head || records.length === 0) fail(ERR.VALUE);
17252
- return { headers: head.map((v) => label4(v).toLowerCase()), records };
17189
+ return { headers: head.map((v) => label(v).toLowerCase()), records };
17253
17190
  }
17254
17191
  function fieldIndex(table2, field) {
17255
17192
  const value2 = scalar2(field);
@@ -17259,7 +17196,7 @@ function fieldIndex(table2, field) {
17259
17196
  if (index4 < 0 || index4 >= table2.headers.length) fail(ERR.VALUE);
17260
17197
  return index4;
17261
17198
  }
17262
- const index3 = table2.headers.indexOf(label4(value2).toLowerCase());
17199
+ const index3 = table2.headers.indexOf(label(value2).toLowerCase());
17263
17200
  if (index3 < 0) fail(ERR.VALUE);
17264
17201
  return index3;
17265
17202
  }
@@ -17268,7 +17205,7 @@ function recordFilter(table2, criteria) {
17268
17205
  if (!head || rows.length === 0) fail(ERR.VALUE);
17269
17206
  const columns = head.map((name) => {
17270
17207
  if (name === null || name === "") return -1;
17271
- return table2.headers.indexOf(label4(name).toLowerCase());
17208
+ return table2.headers.indexOf(label(name).toLowerCase());
17272
17209
  });
17273
17210
  const alternatives = rows.map(
17274
17211
  (row2) => row2.flatMap((cell, c2) => {
@@ -24483,7 +24420,7 @@ function headerMode(args, i2, ctx, firstRow) {
24483
24420
  if (mode === 1 || mode === 3) return true;
24484
24421
  return fail(ERR.VALUE);
24485
24422
  }
24486
- var keyOf = (values2) => JSON.stringify(values2);
24423
+ var keyOf2 = (values2) => JSON.stringify(values2);
24487
24424
  var plain2 = (v) => v === void 0 || isError(v) ? null : v;
24488
24425
  function compareBy(keys, rows) {
24489
24426
  return (a2, b) => {
@@ -24523,7 +24460,7 @@ function groupby(args, ctx) {
24523
24460
  if (rows.length === 0) fail(ERR.CALC);
24524
24461
  const groups = /* @__PURE__ */ new Map();
24525
24462
  for (const r of rows) {
24526
- const key = keyOf(keysM.data[r]);
24463
+ const key = keyOf2(keysM.data[r]);
24527
24464
  const found = groups.get(key);
24528
24465
  if (found) found.push(r);
24529
24466
  else groups.set(key, [r]);
@@ -24590,8 +24527,8 @@ function pivotby(args, ctx) {
24590
24527
  const colKeys = /* @__PURE__ */ new Map();
24591
24528
  for (const r of used) {
24592
24529
  for (const [map, key] of [
24593
- [rowKeys, keyOf(rowsM.data[r])],
24594
- [colKeys, keyOf(colsM.data[r])]
24530
+ [rowKeys, keyOf2(rowsM.data[r])],
24531
+ [colKeys, keyOf2(colsM.data[r])]
24595
24532
  ]) {
24596
24533
  const found = map.get(key);
24597
24534
  if (found) found.push(r);
@@ -27389,15 +27326,15 @@ function derivedFields(pivot, date1904) {
27389
27326
  function derivedFieldXml(pivot, entry3, date1904) {
27390
27327
  const range = { start: entry3.group.start, end: entry3.group.end };
27391
27328
  const days = dateGroupDays(entry3.group);
27392
- const labels = dateUnitLabels(entry3.unit, range, days, date1904);
27329
+ const labels = dateUnitLabels(entry3.unit, range, days, date1904, entry3.group);
27393
27330
  const base = pivot.fields.indexOf(entry3.group.field);
27394
- 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="${escapeAttr3(label5)}"/>`).join("")}</groupItems></fieldGroup></cacheField>`;
27331
+ 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="${escapeAttr3(label2)}"/>`).join("")}</groupItems></fieldGroup></cacheField>`;
27395
27332
  }
27396
27333
  function groupXml2(pivot, name, index3) {
27397
27334
  const group = groupOf(pivot, name);
27398
27335
  if (!group) return "";
27399
27336
  const labels = numberGroupLabels(group);
27400
- 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="${escapeAttr3(label5)}"/>`).join("")}</groupItems></fieldGroup>`;
27337
+ 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="${escapeAttr3(label2)}"/>`).join("")}</groupItems></fieldGroup>`;
27401
27338
  }
27402
27339
  function slicerExt(pivot) {
27403
27340
  if (pivot.slicerCacheId === void 0) return "";
@@ -27418,8 +27355,6 @@ function pivotTableXml(source2, cacheId, cache2) {
27418
27355
  const pivot = expandDateGroups(source2);
27419
27356
  const rowNames = pivotRowFields(pivot);
27420
27357
  const rowIdx = rowNames.map((name) => pivot.fields.indexOf(name));
27421
- const row2 = rowIdx[0];
27422
- const second = rowIdx[1] ?? -1;
27423
27358
  const page = pivot.pageFilter ? pivot.fields.indexOf(pivot.pageFilter.field) : -1;
27424
27359
  const pageItems = page >= 0 ? pivotItems(pivot, pivot.pageFilter.field) : [];
27425
27360
  const filtered2 = filteredFields(pivot);
@@ -27447,7 +27382,10 @@ function pivotTableXml(source2, cacheId, cache2) {
27447
27382
  const columnIndicesFull = columnNames.map(
27448
27383
  (_name, k) => itemIndices(visibleColumns[k], columnItemsFull[k])
27449
27384
  );
27450
- const rowEntries = anyFull && grid.rowEntries ? remapPivotRowEntries(grid.rowEntries, rowIndicesFull) : grid.rowEntries;
27385
+ const valuesAt = pivotValuesIndex(pivot);
27386
+ const levelAxes = [...rowIndicesFull];
27387
+ if (valuesAt >= 0) levelAxes.splice(valuesAt, 0, null);
27388
+ const rowEntries = anyFull && grid.rowEntries ? remapPivotRowEntries(grid.rowEntries, levelAxes) : grid.rowEntries;
27451
27389
  const pageOffset = page >= 0 ? 2 : 0;
27452
27390
  const col = columnIdx[0] ?? -1;
27453
27391
  const measures = pivotMeasures(pivot);
@@ -27456,13 +27394,17 @@ function pivotTableXml(source2, cacheId, cache2) {
27456
27394
  const compact = pivot.layout === "compact";
27457
27395
  const outline = pivot.layout === "compact" || pivot.layout === "outline";
27458
27396
  const top = (pivot.subtotalPosition ?? (outline ? "top" : "bottom")) === "top";
27397
+ const named2 = (field, item) => {
27398
+ const text2 = pivotItemName(pivot, field, item);
27399
+ return text2 === void 0 ? "" : attrs({ n: encodeEscapes(text2) });
27400
+ };
27459
27401
  const fields = pivot.fields.map((name, index3) => {
27460
27402
  const isDate = pivot.dateFields?.includes(name) ?? false;
27461
27403
  const at = rowIdx.indexOf(index3);
27462
27404
  const colAt = columnIdx.indexOf(index3);
27463
27405
  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);
27464
27406
  const hidden = hiddenItemKeys(pivot, name);
27465
- const functions = at >= 0 ? fieldSubtotalFunctions(pivot, name) : "auto";
27407
+ const functions = at >= 0 || colAt >= 0 ? fieldSubtotalFunctions(pivot, name) : "auto";
27466
27408
  const automatic = functions === "auto";
27467
27409
  const custom = automatic ? [] : functions;
27468
27410
  const repeated = pivot.repeatLabels && at >= 0 ? `<extLst><ext uri="{2946ED86-A175-432a-8AC1-64E0C546D7DE}"><x14:pivotField xmlns:x14="${X143}" fillDownLabels="1"/></ext></extLst>` : "";
@@ -27470,37 +27412,27 @@ function pivotTableXml(source2, cacheId, cache2) {
27470
27412
  custom.map((fn) => [PIVOT_SUBTOTALS[fn].attr, true])
27471
27413
  );
27472
27414
  const entries = automatic ? '<item t="default"/>' : custom.map((fn) => `<item t="${PIVOT_SUBTOTALS[fn].item}"/>`).join("");
27473
- 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, 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>`;
27415
+ 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, 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>`;
27474
27416
  }).join("");
27475
27417
  const items = (count2, indices) => Array.from({ length: count2 }, (_v, i2) => `<i><x v="${indices?.[i2] ?? i2}"/></i>`).join("") + '<i t="grand"><x/></i>';
27476
27418
  const header = grid.firstHeaderRow !== void 0 ? grid.firstHeaderRow - pageOffset : col >= 0 ? 1 : grid.firstDataRow - pageOffset - 1;
27477
- const rowIndices = rowsAxis && pivot.valuesPosition === "first" ? [-2, row2, second] : rowsAxis && pivot.valuesPosition === "between" ? [row2, -2, second] : [...rowIdx, ...rowsAxis ? [-2] : []];
27419
+ const rowIndices = [...rowIdx];
27420
+ if (valuesAt >= 0) rowIndices.splice(valuesAt, 0, -2);
27478
27421
  let previous = [];
27479
27422
  const rowItems = rowEntries?.map((entry3) => {
27480
27423
  let prefix = 0;
27481
27424
  const type = entry3.type === void 0 || entry3.type === "default" || entry3.type === "grand" ? entry3.type : PIVOT_SUBTOTALS[entry3.type].item;
27482
- if (rowsAxis) {
27483
- if (entry3.type === "default" && pivot.valuesPosition === "first") prefix = 1;
27484
- else if (!entry3.type)
27485
- while (prefix < entry3.indices.length - 1 && entry3.indices[prefix] === previous[prefix])
27486
- prefix++;
27487
- previous = entry3.type && !(entry3.type === "default" && pivot.valuesPosition === "first") ? [] : entry3.indices;
27488
- } else {
27489
- if (entry3.type !== "grand") prefix = sharedPrefix(entry3.indices, previous);
27490
- previous = entry3.type === "grand" ? [] : entry3.indices;
27491
- }
27425
+ if (entry3.type !== "grand") prefix = sharedPrefix(entry3.indices, previous);
27426
+ previous = entry3.type === "grand" ? [] : entry3.indices;
27492
27427
  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>`;
27493
27428
  }).join("") ?? items(grid.rowItems.length, rowIndicesFull[0]);
27494
27429
  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>`;
27495
- if (!rowsAxis && col >= 0 && grid.columnEntries) {
27496
- const fieldsOnColumns = [...columnIdx, ...multiple ? [-2] : []];
27497
- body += `<colFields count="${fieldsOnColumns.length}">${fieldsOnColumns.map((index3) => `<field x="${index3}"/>`).join("")}</colFields>${pivotColumnItemsXml(grid.columnEntries, measures.length, (level, index3) => columnIndicesFull[level][index3])}`;
27430
+ if (col >= 0 && grid.columnEntries) {
27431
+ const fieldsOnColumns = [...columnIdx, ...multiple && !rowsAxis ? [-2] : []];
27432
+ 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])}`;
27498
27433
  } else if (multiple && !rowsAxis)
27499
27434
  body += `<colFields count="1"><field x="-2"/></colFields>${pivotValueAxisItems(measures.length)}`;
27500
- else if (col >= 0)
27501
- body += `<colFields count="1"><field x="${col}"/></colFields><colItems count="${grid.columnItems.length + 1}">${items(grid.columnItems.length, columnIndicesFull[0])}</colItems>`;
27502
- else
27503
- body += rowsAxis ? '<colItems count="1"><i/></colItems>' : page >= 0 ? '<colItems count="1"><i/></colItems>' : '<colItems count="1"><i><x/></i></colItems>';
27435
+ else body += '<colItems count="1"><i/></colItems>';
27504
27436
  if (page >= 0)
27505
27437
  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>`;
27506
27438
  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>`;
@@ -27510,9 +27442,17 @@ function pivotTableXml(source2, cacheId, cache2) {
27510
27442
  const root = doc.documentElement;
27511
27443
  root.setAttribute("name", pivot.name);
27512
27444
  root.setAttribute("cacheId", String(cacheId));
27445
+ const caps = pivotCaptions(pivot);
27446
+ root.setAttribute("dataCaption", caps.values);
27447
+ for (const [attribute2, key] of [
27448
+ ["rowHeaderCaption", "rowLabels"],
27449
+ ["colHeaderCaption", "columnLabels"],
27450
+ ["grandTotalCaption", "grandTotal"]
27451
+ ])
27452
+ if (caps[key] !== ENGLISH_PIVOT_CAPTIONS[key] || root.hasAttribute(attribute2))
27453
+ root.setAttribute(attribute2, caps[key]);
27513
27454
  root.setAttribute("dataOnRows", rowsAxis ? "1" : "0");
27514
- if (rowsAxis && (pivot.valuesPosition === "between" || pivot.valuesPosition === "first"))
27515
- root.setAttribute("dataPosition", pivot.valuesPosition === "first" ? "0" : "1");
27455
+ if (rowsAxis && valuesAt < rowIdx.length) root.setAttribute("dataPosition", String(valuesAt));
27516
27456
  else root.removeAttribute("dataPosition");
27517
27457
  root.setAttribute("compact", compact ? "1" : "0");
27518
27458
  root.setAttribute("compactData", compact ? "1" : "0");
@@ -27578,7 +27518,8 @@ function pivotTableXml(source2, cacheId, cache2) {
27578
27518
  }
27579
27519
  function dateFilterXml(pivot, filter2) {
27580
27520
  const x15 = "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main";
27581
- 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>`;
27521
+ const id = Number(/<filter [^>]*\bid="(\d+)"/.exec(pivot.sourceXml ?? "")?.[1] ?? 1);
27522
+ 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>`;
27582
27523
  }
27583
27524
 
27584
27525
  // xlsx/pivot/write.ts
@@ -30316,9 +30257,9 @@ function parseSheet(bound, records, start, globals) {
30316
30257
  default: {
30317
30258
  if (opcode === 157)
30318
30259
  hasAutoFilter = true;
30319
- const label5 = UNSUPPORTED[opcode];
30320
- if (label5)
30321
- addUnique(sheet.unsupported, label5);
30260
+ const label2 = UNSUPPORTED[opcode];
30261
+ if (label2)
30262
+ addUnique(sheet.unsupported, label2);
30322
30263
  }
30323
30264
  }
30324
30265
  }