@rowsncolumns/toolkit 24.5.3 → 24.5.5

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 (79) hide show
  1. package/dist/cjs/autofilter-condition.js +6 -2
  2. package/dist/cjs/excel-parser/helpers.d.ts +9 -1
  3. package/dist/cjs/excel-parser/helpers.d.ts.map +1 -1
  4. package/dist/cjs/excel-parser/helpers.js +70 -16
  5. package/dist/cjs/excel-parser/interface.d.ts +9 -1
  6. package/dist/cjs/excel-parser/interface.d.ts.map +1 -1
  7. package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.d.ts.map +1 -1
  8. package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.js +61 -6
  9. package/dist/cjs/excel-parser/plugins/xlsx/data-validations.d.ts.map +1 -1
  10. package/dist/cjs/excel-parser/plugins/xlsx/data-validations.js +13 -2
  11. package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts +8 -1
  12. package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
  13. package/dist/cjs/excel-parser/plugins/xlsx/index.js +159 -26
  14. package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts +17 -2
  15. package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts.map +1 -1
  16. package/dist/cjs/excel-parser/plugins/xlsx/styles.js +25 -14
  17. package/dist/cjs/excel-parser/types.d.ts +5 -1
  18. package/dist/cjs/excel-parser/types.d.ts.map +1 -1
  19. package/dist/cjs/excel-parser/workbook.d.ts +1 -0
  20. package/dist/cjs/excel-parser/workbook.d.ts.map +1 -1
  21. package/dist/cjs/excel-parser/workbook.js +4 -0
  22. package/dist/cjs/excel-parser/worker.js +3 -0
  23. package/dist/cjs/exporter/xlsx/chart-builder.d.ts.map +1 -1
  24. package/dist/cjs/exporter/xlsx/chart-builder.js +167 -53
  25. package/dist/cjs/exporter/xlsx/future-functions.d.ts +6 -7
  26. package/dist/cjs/exporter/xlsx/future-functions.d.ts.map +1 -1
  27. package/dist/cjs/exporter/xlsx/future-functions.js +5 -261
  28. package/dist/cjs/exporter/xlsx/style-builder.d.ts.map +1 -1
  29. package/dist/cjs/exporter/xlsx/style-builder.js +62 -19
  30. package/dist/cjs/exporter/xlsx/xlsx-export.d.ts +10 -2
  31. package/dist/cjs/exporter/xlsx/xlsx-export.d.ts.map +1 -1
  32. package/dist/cjs/exporter/xlsx/xlsx-export.js +409 -160
  33. package/dist/cjs/helpers/excel-formula-prefixes.d.ts +51 -0
  34. package/dist/cjs/helpers/excel-formula-prefixes.d.ts.map +1 -0
  35. package/dist/cjs/helpers/excel-formula-prefixes.js +548 -0
  36. package/dist/cjs/helpers.d.ts +2 -0
  37. package/dist/cjs/helpers.d.ts.map +1 -1
  38. package/dist/cjs/helpers.js +21 -12
  39. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  40. package/dist/esm/autofilter-condition.js +6 -2
  41. package/dist/esm/excel-parser/helpers.d.ts +9 -1
  42. package/dist/esm/excel-parser/helpers.d.ts.map +1 -1
  43. package/dist/esm/excel-parser/helpers.js +65 -3
  44. package/dist/esm/excel-parser/interface.d.ts +9 -1
  45. package/dist/esm/excel-parser/interface.d.ts.map +1 -1
  46. package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.d.ts.map +1 -1
  47. package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.js +42 -1
  48. package/dist/esm/excel-parser/plugins/xlsx/data-validations.d.ts.map +1 -1
  49. package/dist/esm/excel-parser/plugins/xlsx/data-validations.js +11 -2
  50. package/dist/esm/excel-parser/plugins/xlsx/index.d.ts +8 -1
  51. package/dist/esm/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
  52. package/dist/esm/excel-parser/plugins/xlsx/index.js +109 -4
  53. package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts +17 -2
  54. package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts.map +1 -1
  55. package/dist/esm/excel-parser/plugins/xlsx/styles.js +20 -8
  56. package/dist/esm/excel-parser/types.d.ts +5 -1
  57. package/dist/esm/excel-parser/types.d.ts.map +1 -1
  58. package/dist/esm/excel-parser/workbook.d.ts +1 -0
  59. package/dist/esm/excel-parser/workbook.d.ts.map +1 -1
  60. package/dist/esm/excel-parser/workbook.js +3 -0
  61. package/dist/esm/excel-parser/worker.js +3 -0
  62. package/dist/esm/exporter/xlsx/chart-builder.d.ts.map +1 -1
  63. package/dist/esm/exporter/xlsx/chart-builder.js +80 -0
  64. package/dist/esm/exporter/xlsx/future-functions.d.ts +6 -7
  65. package/dist/esm/exporter/xlsx/future-functions.d.ts.map +1 -1
  66. package/dist/esm/exporter/xlsx/future-functions.js +5 -261
  67. package/dist/esm/exporter/xlsx/style-builder.d.ts.map +1 -1
  68. package/dist/esm/exporter/xlsx/style-builder.js +56 -18
  69. package/dist/esm/exporter/xlsx/xlsx-export.d.ts +10 -2
  70. package/dist/esm/exporter/xlsx/xlsx-export.d.ts.map +1 -1
  71. package/dist/esm/exporter/xlsx/xlsx-export.js +343 -108
  72. package/dist/esm/helpers/excel-formula-prefixes.d.ts +51 -0
  73. package/dist/esm/helpers/excel-formula-prefixes.d.ts.map +1 -0
  74. package/dist/esm/helpers/excel-formula-prefixes.js +531 -0
  75. package/dist/esm/helpers.d.ts +2 -0
  76. package/dist/esm/helpers.d.ts.map +1 -1
  77. package/dist/esm/helpers.js +23 -12
  78. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  79. package/package.json +4 -4
@@ -1,5 +1,5 @@
1
1
  import { __assign, __awaiter, __generator, __read, __spreadArray, __values } from "tslib";
2
- import { cellRangeToAddress, cellToAddress, escapeCharacters, getCellEffectiveFormat, getCellEffectiveValue, getCellFormattedValue, getCellUserEnteredFormat, getCellUserEnteredValue, getExtendedValueBool, getExtendedValueError, getExtendedValueFormula, getExtendedValueNumber, getExtendedValueString, isNil, sortSheetsByIndex, } from "@rowsncolumns/utils";
2
+ import { cellRangeToAddress, cellToAddress, escapeCharacters, getCellEffectiveFormat, getCellEffectiveValue, getCellFormattedValue, getCellUserEnteredFormat, getCellUserEnteredValue, getExtendedValueBool, getExtendedValueError, getExtendedValueFormula, getExtendedValueNumber, getExtendedValueString, isNil, sortSheetsByIndex, conditionOperandToFormulaText, } from "@rowsncolumns/utils";
3
3
  import { zipSync } from "fflate";
4
4
  import { omitInvalidDataValidationError } from "../invalid-data-validation";
5
5
  import { buildAutoFilterCriteriaXml } from "../../autofilter-condition";
@@ -31,10 +31,10 @@ var pixelToPoints = function (px) {
31
31
  return Math.max(1, Number(((px * 72) / 96).toFixed(2)));
32
32
  };
33
33
  export var createExcelFile = function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
34
- var sortedSheets, sharedStrings, personRegistry, styleBuilder, customTableStyleRecords, customTableStyleNames, exportableTables, tableIdMap, preparedTables, chartCount, embedsBySheet, textBoxesBySheet, shapesBySheet, formControlsBySheet, ctrlProps, chartsBySheet, remappedSlicers, slicersBySheet, workbookSheetNames, sheetNameById, dataValidationsById, globalSlicerIndex, slicerCacheEntries, slicerEntries, globalPivotIndex, pivotCacheEntries, pivotCacheRelsEntries, pivotTableEntries, pivotTableRelsEntries, pivotSourceNameById, _loop_1, pivotTables_1, pivotTables_1_1, p, resolvePivotSourceName, pivotsByTargetSheet, pivotTables_2, pivotTables_2_1, p, sid, list, workbookPivotCacheRefs, worksheetCount, chartsheetCount, worksheetEntries, _d, workbookRelationshipsXml, sheetRelationshipIds, slicerCacheRelationshipIds, pivotCacheRelationshipIds, externalLinkRelationshipIds, workbookXml, sharedStringsXml, rootRelationshipsXml, appXml, coreXml, tablePartFiles, preparedTables_1, preparedTables_1_1, table, rows, tableXml, stylesXml, themeXml, files, worksheetEntries_1, worksheetEntries_1_1, entry, personsXml, globalImageIndex, globalChartIndex, drawingSheets, imageExtensions, chartEntries, chartExEntries, globalChartExIndex, worksheetEntries_2, worksheetEntries_2_1, entry, placements, textBoxesForSheet, shapesForSheet, chartsForSheet, slicersForSheet, drawingParts, _e, _f, media, _g, _h, chartEntry, _j, _k, chartExEntry, e_1_1, chartEntries_1, chartEntries_1_1, chartEntry, chartExEntries_1, chartExEntries_1_1, chartExEntry, slicerCacheEntries_1, slicerCacheEntries_1_1, slicerCacheEntry, slicerEntries_1, slicerEntries_1_1, slicerEntry, pivotCacheEntries_1, pivotCacheEntries_1_1, cacheEntry, pivotCacheRelsEntries_1, pivotCacheRelsEntries_1_1, cacheRels, pivotTableEntries_1, pivotTableEntries_1_1, tableEntry, pivotTableRelsEntries_1, pivotTableRelsEntries_1_1, tableRels, i, link, linkPath, relsPath, commentsSheets, hasVmlDrawings, _l, _m, part, threadedCommentsSheets, contentTypesXml, zipBytes;
34
+ var sortedSheets, sharedStrings, personRegistry, styleBuilder, customTableStyleRecords, customTableStyleNames, exportableTables, tableIdMap, preparedTables, chartCount, embedsBySheet, textBoxesBySheet, shapesBySheet, formControlsBySheet, ctrlProps, chartsBySheet, remappedSlicers, slicersBySheet, workbookSheetNames, sheetNameById, dataValidationsById, globalSlicerIndex, slicerCacheEntries, slicerEntries, globalPivotIndex, pivotCacheEntries, pivotCacheRelsEntries, pivotTableEntries, pivotTableRelsEntries, pivotSourceNameById, _loop_1, pivotTables_1, pivotTables_1_1, p, resolvePivotSourceName, pivotsByTargetSheet, pivotTables_2, pivotTables_2_1, p, sid, list, workbookPivotCacheRefs, worksheetCount, chartsheetCount, worksheetEntries, hasDynamicArrays, _d, workbookRelationshipsXml, sheetRelationshipIds, slicerCacheRelationshipIds, pivotCacheRelationshipIds, externalLinkRelationshipIds, workbookXml, sharedStringsXml, rootRelationshipsXml, appXml, coreXml, tablePartFiles, preparedTables_1, preparedTables_1_1, table, rows, tableXml, stylesXml, themeXml, files, worksheetEntries_1, worksheetEntries_1_1, entry, personsXml, globalImageIndex, globalChartIndex, drawingSheets, imageExtensions, chartEntries, chartExEntries, globalChartExIndex, worksheetEntries_2, worksheetEntries_2_1, entry, placements, textBoxesForSheet, shapesForSheet, chartsForSheet, slicersForSheet, drawingParts, _e, _f, media, _g, _h, chartEntry, _j, _k, chartExEntry, e_1_1, chartEntries_1, chartEntries_1_1, chartEntry, chartExEntries_1, chartExEntries_1_1, chartExEntry, slicerCacheEntries_1, slicerCacheEntries_1_1, slicerCacheEntry, slicerEntries_1, slicerEntries_1_1, slicerEntry, pivotCacheEntries_1, pivotCacheEntries_1_1, cacheEntry, pivotCacheRelsEntries_1, pivotCacheRelsEntries_1_1, cacheRels, pivotTableEntries_1, pivotTableEntries_1_1, tableEntry, pivotTableRelsEntries_1, pivotTableRelsEntries_1_1, tableRels, i, link, linkPath, relsPath, commentsSheets, hasVmlDrawings, _l, _m, part, threadedCommentsSheets, contentTypesXml, zipBytes;
35
35
  var e_2, _o, e_3, _p, e_4, _q, e_5, _s, e_1, _t, e_6, _u, e_7, _v, e_8, _w, e_9, _x, e_10, _y, e_11, _z, e_12, _0, e_13, _1, e_14, _2, e_15, _3, e_16, _4, e_17, _5;
36
36
  var _6, _7, _8, _9, _10, _11, _12, _13, _14;
37
- var _conditionalFormats = _b.conditionalFormats, _dataValidations = _b.dataValidations, sheets = _b.sheets, sheetData = _b.sheetData, sourceSharedStrings = _b.sharedStrings, _15 = _b.tables, _tables = _15 === void 0 ? [] : _15, cellXfs = _b.cellXfs, theme = _b.theme, defaultFont = _b.defaultFont, _16 = _b.embeds, embeds = _16 === void 0 ? [] : _16, _17 = _b.charts, charts = _17 === void 0 ? [] : _17, _18 = _b.slicers, slicers = _18 === void 0 ? [] : _18, _19 = _b.pivotTables, pivotTables = _19 === void 0 ? [] : _19, _20 = _b.externalLinks, externalLinks = _20 === void 0 ? [] : _20, _21 = _b.namedRanges, namedRanges = _21 === void 0 ? [] : _21, _22 = _b.protectedRanges, protectedRanges = _22 === void 0 ? [] : _22, namedCellStyles = _b.namedCellStyles, customTableStyles = _b.customTableStyles, iterativeCalculationOptions = _b.iterativeCalculationOptions, ignoreFormulaPatterns = _b.ignoreFormulaPatterns, citations = _b.citations, comments = _b.comments, password = _b.password, locale = _b.locale, _23 = _b.use1904, use1904 = _23 === void 0 ? false : _23, properties = _b.properties, powerQuery = _b.powerQuery;
37
+ var _conditionalFormats = _b.conditionalFormats, _dataValidations = _b.dataValidations, sheets = _b.sheets, sheetData = _b.sheetData, sourceSharedStrings = _b.sharedStrings, _15 = _b.tables, _tables = _15 === void 0 ? [] : _15, cellXfs = _b.cellXfs, theme = _b.theme, defaultFont = _b.defaultFont, _16 = _b.embeds, embeds = _16 === void 0 ? [] : _16, _17 = _b.charts, charts = _17 === void 0 ? [] : _17, _18 = _b.slicers, slicers = _18 === void 0 ? [] : _18, _19 = _b.pivotTables, pivotTables = _19 === void 0 ? [] : _19, _20 = _b.externalLinks, externalLinks = _20 === void 0 ? [] : _20, _21 = _b.namedRanges, namedRanges = _21 === void 0 ? [] : _21, _22 = _b.protectedRanges, protectedRanges = _22 === void 0 ? [] : _22, namedCellStyles = _b.namedCellStyles, customTableStyles = _b.customTableStyles, iterativeCalculationOptions = _b.iterativeCalculationOptions, workbookProtection = _b.workbookProtection, ignoreFormulaPatterns = _b.ignoreFormulaPatterns, citations = _b.citations, comments = _b.comments, password = _b.password, locale = _b.locale, _23 = _b.use1904, use1904 = _23 === void 0 ? false : _23, properties = _b.properties, powerQuery = _b.powerQuery;
38
38
  return __generator(this, function (_24) {
39
39
  switch (_24.label) {
40
40
  case 0:
@@ -411,13 +411,15 @@ export var createExcelFile = function (_a) { return __awaiter(void 0, [_a], void
411
411
  commentsXml: result.commentsXml,
412
412
  vmlDrawingXml: result.vmlDrawingXml,
413
413
  threadedCommentsXml: result.threadedCommentsXml,
414
+ hasDynamicArrays: result.hasDynamicArrays,
414
415
  };
415
416
  });
417
+ hasDynamicArrays = worksheetEntries.some(function (entry) { return entry.hasDynamicArrays; });
416
418
  _d = buildWorkbookRelationships(worksheetEntries.map(function (entry) { return ({
417
419
  chartsheet: entry.isChartsheet,
418
420
  target: entry.path.replace(/^xl\//, ""),
419
- }); }), slicerCacheEntries.length, externalLinks.length, pivotCacheEntries.length, !personRegistry.isEmpty()), workbookRelationshipsXml = _d.xml, sheetRelationshipIds = _d.sheetRelationshipIds, slicerCacheRelationshipIds = _d.slicerCacheRelationshipIds, pivotCacheRelationshipIds = _d.pivotCacheRelationshipIds, externalLinkRelationshipIds = _d.externalLinkRelationshipIds;
420
- workbookXml = buildWorkbookXml(sortedSheets, sheetRelationshipIds, workbookSheetNames, namedRanges, iterativeCalculationOptions, slicerCacheRelationshipIds, use1904, externalLinkRelationshipIds, pivotCacheRelationshipIds);
421
+ }); }), slicerCacheEntries.length, externalLinks.length, pivotCacheEntries.length, !personRegistry.isEmpty(), hasDynamicArrays), workbookRelationshipsXml = _d.xml, sheetRelationshipIds = _d.sheetRelationshipIds, slicerCacheRelationshipIds = _d.slicerCacheRelationshipIds, pivotCacheRelationshipIds = _d.pivotCacheRelationshipIds, externalLinkRelationshipIds = _d.externalLinkRelationshipIds;
422
+ workbookXml = buildWorkbookXml(sortedSheets, sheetRelationshipIds, workbookSheetNames, namedRanges, iterativeCalculationOptions, slicerCacheRelationshipIds, use1904, externalLinkRelationshipIds, pivotCacheRelationshipIds, workbookProtection);
421
423
  sharedStringsXml = buildSharedStringsXml(sharedStrings);
422
424
  rootRelationshipsXml = buildRootRelationshipsXml();
423
425
  appXml = buildAppXml(workbookSheetNames, sortedSheets.map(function (sheet) { return sheet.type === "chartsheet"; }), properties);
@@ -452,6 +454,9 @@ export var createExcelFile = function (_a) { return __awaiter(void 0, [_a], void
452
454
  "xl/styles.xml": encodeXml(stylesXml),
453
455
  "xl/theme/theme1.xml": encodeXml(themeXml),
454
456
  };
457
+ if (hasDynamicArrays) {
458
+ files["xl/metadata.xml"] = encodeXml(DYNAMIC_ARRAY_METADATA_XML);
459
+ }
455
460
  try {
456
461
  for (worksheetEntries_1 = __values(worksheetEntries), worksheetEntries_1_1 = worksheetEntries_1.next(); !worksheetEntries_1_1.done; worksheetEntries_1_1 = worksheetEntries_1.next()) {
457
462
  entry = worksheetEntries_1_1.value;
@@ -744,6 +749,7 @@ export var createExcelFile = function (_a) { return __awaiter(void 0, [_a], void
744
749
  externalLinkCount: externalLinks.length,
745
750
  hasVmlDrawings: hasVmlDrawings,
746
751
  ctrlPropCount: ctrlProps.parts.length,
752
+ hasSheetMetadata: hasDynamicArrays,
747
753
  });
748
754
  files["[Content_Types].xml"] = encodeXml(contentTypesXml);
749
755
  // Preserved Power Query machinery (DataMashup customXml, connections.xml, queryTable parts) is
@@ -882,11 +888,12 @@ export var normalizeSqrefMembers = function (refs) {
882
888
  return out;
883
889
  };
884
890
  var DataValidationCollector = /** @class */ (function () {
885
- function DataValidationCollector() {
891
+ function DataValidationCollector(locale) {
892
+ this.locale = locale;
886
893
  this.entries = new Map();
887
894
  }
888
895
  DataValidationCollector.prototype.add = function (address, rule) {
889
- var config = convertDataValidationRule(rule);
896
+ var config = convertDataValidationRule(rule, this.locale);
890
897
  if (!config)
891
898
  return;
892
899
  var key = getDataValidationKey(config);
@@ -1040,7 +1047,7 @@ var buildWorksheetXml = function (_a) {
1040
1047
  var defaultRowHeightPx = getDefaultRowHeightPx(sheet);
1041
1048
  var rowXmlChunks = [];
1042
1049
  var collectedImages = [];
1043
- var dataValidationCollector = new DataValidationCollector();
1050
+ var dataValidationCollector = new DataValidationCollector(locale);
1044
1051
  var hyperlinkEntries = [];
1045
1052
  var commentsCollector = new CommentsCollector();
1046
1053
  var threadedCommentsCollector = new ThreadedCommentsCollector(comments, personRegistry !== null && personRegistry !== void 0 ? personRegistry : new PersonRegistry());
@@ -1119,6 +1126,8 @@ var buildWorksheetXml = function (_a) {
1119
1126
  // see `<f t="shared" si="N"/>` with no corresponding leader and read the
1120
1127
  // cell as having no formula at all.
1121
1128
  var validSharedFormulaLeaders = new Set();
1129
+ // Any `cm="1"` anchor on this sheet makes the workbook carry xl/metadata.xml.
1130
+ var hasDynamicArrays = false;
1122
1131
  for (var rowIndex = 1; rowIndex < maxRows; rowIndex++) {
1123
1132
  var row = rows[rowIndex];
1124
1133
  var rowValues = row === null || row === void 0 ? void 0 : row.values;
@@ -1163,6 +1172,9 @@ var buildWorksheetXml = function (_a) {
1163
1172
  sheets: sheets,
1164
1173
  locale: locale,
1165
1174
  validSharedFormulaLeaders: validSharedFormulaLeaders,
1175
+ onDynamicArray: function () {
1176
+ hasDynamicArrays = true;
1177
+ },
1166
1178
  onImage: function (image) {
1167
1179
  collectedImages.push(image);
1168
1180
  drawingContext.ensureRel();
@@ -1212,6 +1224,7 @@ var buildWorksheetXml = function (_a) {
1212
1224
  sheetId: sheet.sheetId,
1213
1225
  conditionalFormats: conditionalFormats,
1214
1226
  styleBuilder: styleBuilder,
1227
+ locale: locale,
1215
1228
  });
1216
1229
  var tablePartsXml = buildTablePartsXml(tables, relationships);
1217
1230
  var drawingXml = drawingContext.hasDrawing()
@@ -1307,7 +1320,7 @@ var buildWorksheetXml = function (_a) {
1307
1320
  var sheetFormatPrAttrs = ["defaultRowHeight=\"".concat(defaultRowHeightPt, "\"")];
1308
1321
  if (typeof explicitDefaultColumnWidthPx === "number" &&
1309
1322
  explicitDefaultColumnWidthPx > 0) {
1310
- sheetFormatPrAttrs.push("defaultColWidth=\"".concat(columnPixelToChars(explicitDefaultColumnWidthPx).toFixed(2), "\""));
1323
+ sheetFormatPrAttrs.push("defaultColWidth=\"".concat(columnPixelToChars(explicitDefaultColumnWidthPx), "\""));
1311
1324
  }
1312
1325
  var worksheetXml = "".concat(XML_DECLARATION, "<worksheet xmlns=\"").concat(WORKSHEET_NS, "\" xmlns:r=\"").concat(REL_NS, "\">").concat(sheetPrXml, "<dimension ref=\"").concat(dimension, "\"/>").concat(sheetViews, "<sheetFormatPr ").concat(sheetFormatPrAttrs.join(" "), "/>").concat(columnXml).concat(sheetDataXml).concat(protectionXml).concat(basicFilterXml).concat(mergeXml).concat(conditionalFormattingXml).concat(dataValidationsXml).concat(hyperlinksXml).concat(printSettingsXml).concat(drawingXml).concat(legacyDrawingXml).concat(controlsXml).concat(tablePartsXml).concat(extLstXml, "</worksheet>");
1313
1326
  return {
@@ -1317,6 +1330,7 @@ var buildWorksheetXml = function (_a) {
1317
1330
  commentsXml: commentsXml,
1318
1331
  vmlDrawingXml: vmlDrawingXml,
1319
1332
  threadedCommentsXml: threadedCommentsXml,
1333
+ hasDynamicArrays: hasDynamicArrays,
1320
1334
  };
1321
1335
  };
1322
1336
  /**
@@ -1340,6 +1354,7 @@ var buildChartsheetXml = function (_a) {
1340
1354
  commentsXml: undefined,
1341
1355
  vmlDrawingXml: undefined,
1342
1356
  threadedCommentsXml: undefined,
1357
+ hasDynamicArrays: false,
1343
1358
  };
1344
1359
  };
1345
1360
  /**
@@ -1549,7 +1564,7 @@ var normalizeXlsxSourceListFormula1 = function (formula1) {
1549
1564
  return trimmed;
1550
1565
  return "\"".concat(escapeFormulaText(trimmed), "\"");
1551
1566
  };
1552
- var convertDataValidationRule = function (rule) {
1567
+ var convertDataValidationRule = function (rule, locale) {
1553
1568
  var _a, _b, _d, _e, _f, _g;
1554
1569
  if (!rule)
1555
1570
  return undefined;
@@ -1592,7 +1607,7 @@ var convertDataValidationRule = function (rule) {
1592
1607
  rejectedListSource = normalizeXlsxSourceListFormula1(src.formula1);
1593
1608
  }
1594
1609
  }
1595
- var synthesized = convertDataValidationCondition(rule, baseConfig);
1610
+ var synthesized = convertDataValidationCondition(rule, baseConfig, locale);
1596
1611
  if (synthesized)
1597
1612
  return synthesized;
1598
1613
  // A rejected `list` source with no usable condition is still kept — its
@@ -1606,7 +1621,7 @@ var convertDataValidationRule = function (rule) {
1606
1621
  // The condition-based synthesizer: the Excel config for a rule that has no
1607
1622
  // replayable `xlsxSource` (UI-authored, edited after import, or rejected by
1608
1623
  // the round-trip guard above).
1609
- var convertDataValidationCondition = function (rule, baseConfig) {
1624
+ var convertDataValidationCondition = function (rule, baseConfig, locale) {
1610
1625
  var _a, _b, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _s, _t, _u, _v, _w, _x, _y, _z;
1611
1626
  if (!((_a = rule.condition) === null || _a === void 0 ? void 0 : _a.type)) {
1612
1627
  // Prompt-only DV (no validation rule, just an input-message tooltip
@@ -1619,10 +1634,9 @@ var convertDataValidationCondition = function (rule, baseConfig) {
1619
1634
  }
1620
1635
  var condition = rule.condition;
1621
1636
  var values = (_b = condition.values) !== null && _b !== void 0 ? _b : [];
1637
+ // OOXML `<formula1>` carries the formula text WITHOUT a leading `=` — Excel
1638
+ // never writes one (the xlsxSource replay path strips it the same way).
1622
1639
  var currentCell = 'INDIRECT("RC",FALSE)';
1623
- var ensureFormula = function (value) {
1624
- return value.startsWith("=") ? value : "=".concat(value);
1625
- };
1626
1640
  var ifErrorWrap = function (formula) { return "IFERROR(".concat(formula, ",TRUE)"); };
1627
1641
  if (condition.type === "ONE_OF_LIST") {
1628
1642
  var entries = values
@@ -1639,62 +1653,61 @@ var convertDataValidationCondition = function (rule, baseConfig) {
1639
1653
  .filter(function (value) { return typeof value === "string"; });
1640
1654
  if (!references.length)
1641
1655
  return undefined;
1642
- var formula1 = references.join(",");
1643
- return __assign({ type: "list", formula1: formula1.startsWith("=") ? formula1 : "=".concat(formula1), showDropDown: rule.displayStyle === "plain" ? true : undefined }, baseConfig);
1656
+ return __assign({ type: "list", formula1: stripLeadingEquals(references.join(",")), showDropDown: rule.displayStyle === "plain" ? true : undefined }, baseConfig);
1644
1657
  }
1645
1658
  if (condition.type === "CUSTOM_FORMULA") {
1646
1659
  var raw = (_e = (_d = values[0]) === null || _d === void 0 ? void 0 : _d.userEnteredValue) !== null && _e !== void 0 ? _e : "";
1647
1660
  if (!raw)
1648
1661
  return undefined;
1649
- return __assign({ type: "custom", formula1: ensureFormula(raw) }, baseConfig);
1662
+ return __assign({ type: "custom", formula1: stripLeadingEquals(raw) }, baseConfig);
1650
1663
  }
1651
1664
  if (condition.type === "BOOLEAN") {
1652
- return __assign({ type: "custom", formula1: "=OR(".concat(currentCell, "=TRUE,").concat(currentCell, "=FALSE)") }, baseConfig);
1665
+ return __assign({ type: "custom", formula1: "OR(".concat(currentCell, "=TRUE,").concat(currentCell, "=FALSE)") }, baseConfig);
1653
1666
  }
1654
1667
  if (condition.type === "BLANK") {
1655
- return __assign({ type: "custom", formula1: "=".concat(currentCell, "=\"\"") }, baseConfig);
1668
+ return __assign({ type: "custom", formula1: "".concat(currentCell, "=\"\"") }, baseConfig);
1656
1669
  }
1657
1670
  if (condition.type === "NOT_BLANK") {
1658
- return __assign({ type: "custom", formula1: "=".concat(currentCell, "<>\"\"") }, baseConfig);
1671
+ return __assign({ type: "custom", formula1: "".concat(currentCell, "<>\"\"") }, baseConfig);
1659
1672
  }
1660
1673
  if (condition.type === "TEXT_EQ" || condition.type === "TEXT_NOT_EQ") {
1661
1674
  var raw = (_g = (_f = values[0]) === null || _f === void 0 ? void 0 : _f.userEnteredValue) !== null && _g !== void 0 ? _g : "";
1662
1675
  if (!raw)
1663
1676
  return undefined;
1664
1677
  var op = condition.type === "TEXT_EQ" ? "=" : "<>";
1665
- return __assign({ type: "custom", formula1: "=".concat(currentCell).concat(op, "\"").concat(escapeFormulaText(raw), "\"") }, baseConfig);
1678
+ return __assign({ type: "custom", formula1: "".concat(currentCell).concat(op, "\"").concat(escapeFormulaText(raw), "\"") }, baseConfig);
1666
1679
  }
1667
1680
  if (condition.type === "TEXT_CONTAINS") {
1668
1681
  var raw = (_j = (_h = values[0]) === null || _h === void 0 ? void 0 : _h.userEnteredValue) !== null && _j !== void 0 ? _j : "";
1669
1682
  if (!raw)
1670
1683
  return undefined;
1671
- return __assign({ type: "custom", formula1: "=ISNUMBER(SEARCH(\"".concat(escapeFormulaText(raw), "\",").concat(currentCell, "))") }, baseConfig);
1684
+ return __assign({ type: "custom", formula1: "ISNUMBER(SEARCH(\"".concat(escapeFormulaText(raw), "\",").concat(currentCell, "))") }, baseConfig);
1672
1685
  }
1673
1686
  if (condition.type === "TEXT_NOT_CONTAINS") {
1674
1687
  var raw = (_l = (_k = values[0]) === null || _k === void 0 ? void 0 : _k.userEnteredValue) !== null && _l !== void 0 ? _l : "";
1675
1688
  if (!raw)
1676
1689
  return undefined;
1677
- return __assign({ type: "custom", formula1: "=ISERROR(SEARCH(\"".concat(escapeFormulaText(raw), "\",").concat(currentCell, "))") }, baseConfig);
1690
+ return __assign({ type: "custom", formula1: "ISERROR(SEARCH(\"".concat(escapeFormulaText(raw), "\",").concat(currentCell, "))") }, baseConfig);
1678
1691
  }
1679
1692
  if (condition.type === "TEXT_STARTS_WITH") {
1680
1693
  var raw = (_o = (_m = values[0]) === null || _m === void 0 ? void 0 : _m.userEnteredValue) !== null && _o !== void 0 ? _o : "";
1681
1694
  if (!raw)
1682
1695
  return undefined;
1683
1696
  var text = escapeFormulaText(raw);
1684
- return __assign({ type: "custom", formula1: "=LEFT(".concat(currentCell, ",LEN(\"").concat(text, "\"))=\"").concat(text, "\"") }, baseConfig);
1697
+ return __assign({ type: "custom", formula1: "LEFT(".concat(currentCell, ",LEN(\"").concat(text, "\"))=\"").concat(text, "\"") }, baseConfig);
1685
1698
  }
1686
1699
  if (condition.type === "TEXT_ENDS_WITH") {
1687
1700
  var raw = (_q = (_p = values[0]) === null || _p === void 0 ? void 0 : _p.userEnteredValue) !== null && _q !== void 0 ? _q : "";
1688
1701
  if (!raw)
1689
1702
  return undefined;
1690
1703
  var text = escapeFormulaText(raw);
1691
- return __assign({ type: "custom", formula1: "=RIGHT(".concat(currentCell, ",LEN(\"").concat(text, "\"))=\"").concat(text, "\"") }, baseConfig);
1704
+ return __assign({ type: "custom", formula1: "RIGHT(".concat(currentCell, ",LEN(\"").concat(text, "\"))=\"").concat(text, "\"") }, baseConfig);
1692
1705
  }
1693
1706
  if (condition.type === "TEXT_IS_EMAIL") {
1694
- return __assign({ type: "custom", formula1: "=AND(ISNUMBER(SEARCH(\"@\",".concat(currentCell, ")),ISNUMBER(SEARCH(\".\",").concat(currentCell, ")))") }, baseConfig);
1707
+ return __assign({ type: "custom", formula1: "AND(ISNUMBER(SEARCH(\"@\",".concat(currentCell, ")),ISNUMBER(SEARCH(\".\",").concat(currentCell, ")))") }, baseConfig);
1695
1708
  }
1696
1709
  if (condition.type === "TEXT_IS_URL") {
1697
- return __assign({ type: "custom", formula1: "=OR(LEFT(".concat(currentCell, ",7)=\"http://\",LEFT(").concat(currentCell, ",8)=\"https://\")") }, baseConfig);
1710
+ return __assign({ type: "custom", formula1: "OR(LEFT(".concat(currentCell, ",7)=\"http://\",LEFT(").concat(currentCell, ",8)=\"https://\")") }, baseConfig);
1698
1711
  }
1699
1712
  if (condition.type === "NUMBER_BETWEEN" ||
1700
1713
  condition.type === "NUMBER_NOT_BETWEEN" ||
@@ -1718,9 +1731,12 @@ var convertDataValidationCondition = function (rule, baseConfig) {
1718
1731
  NUMBER_LESS: "lessThan",
1719
1732
  NUMBER_LESS_THAN_EQ: "lessThanOrEqual",
1720
1733
  };
1721
- return __assign({ type: "decimal", operator: operatorMap[condition.type], formula1: first, formula2: condition.type === "NUMBER_BETWEEN" ||
1734
+ // Bounds are written the way Excel stores them: typed literals normalized
1735
+ // (`50%` → `0.5`, a typed date → its serial), formulas without their `=`,
1736
+ // references / names / function calls verbatim.
1737
+ return __assign({ type: "decimal", operator: operatorMap[condition.type], formula1: conditionOperandToFormulaText(first, locale), formula2: condition.type === "NUMBER_BETWEEN" ||
1722
1738
  condition.type === "NUMBER_NOT_BETWEEN"
1723
- ? second
1739
+ ? conditionOperandToFormulaText(second, locale)
1724
1740
  : undefined }, baseConfig);
1725
1741
  }
1726
1742
  if (condition.type === "NUMBER_GREATER_THAN_PREVIOUS" ||
@@ -1734,7 +1750,7 @@ var convertDataValidationCondition = function (rule, baseConfig) {
1734
1750
  NUMBER_LESS_THAN_EQ_PREVIOUS: "<=",
1735
1751
  };
1736
1752
  var op = opMap[condition.type];
1737
- return __assign({ type: "custom", formula1: "=".concat(ifErrorWrap("".concat(currentCell).concat(op, "INDIRECT(\"R[-1]C\",FALSE)"))) }, baseConfig);
1753
+ return __assign({ type: "custom", formula1: "".concat(ifErrorWrap("".concat(currentCell).concat(op, "INDIRECT(\"R[-1]C\",FALSE)"))) }, baseConfig);
1738
1754
  }
1739
1755
  if (condition.type === "DATE_EQ" ||
1740
1756
  condition.type === "DATE_NOT_EQ" ||
@@ -1758,13 +1774,13 @@ var convertDataValidationCondition = function (rule, baseConfig) {
1758
1774
  DATE_BETWEEN: "between",
1759
1775
  DATE_NOT_BETWEEN: "notBetween",
1760
1776
  };
1761
- return __assign({ type: "date", operator: operatorMap[condition.type], formula1: first, formula2: condition.type === "DATE_BETWEEN" ||
1777
+ return __assign({ type: "date", operator: operatorMap[condition.type], formula1: conditionOperandToFormulaText(first, locale), formula2: condition.type === "DATE_BETWEEN" ||
1762
1778
  condition.type === "DATE_NOT_BETWEEN"
1763
- ? second
1779
+ ? conditionOperandToFormulaText(second, locale)
1764
1780
  : undefined }, baseConfig);
1765
1781
  }
1766
1782
  if (condition.type === "DATE_IS_VALID") {
1767
- return __assign({ type: "custom", formula1: "=ISNUMBER(".concat(currentCell, ")") }, baseConfig);
1783
+ return __assign({ type: "custom", formula1: "ISNUMBER(".concat(currentCell, ")") }, baseConfig);
1768
1784
  }
1769
1785
  return undefined;
1770
1786
  };
@@ -1845,7 +1861,7 @@ var resolveCellDataValidation = function (cell, map) {
1845
1861
  };
1846
1862
  var buildWorksheetRow = function (_a) {
1847
1863
  var _b, _d;
1848
- var rowNumber = _a.rowNumber, row = _a.row, rowMetadata = _a.rowMetadata, defaultRowHeightPx = _a.defaultRowHeightPx, sharedStrings = _a.sharedStrings, sourceSharedStrings = _a.sourceSharedStrings, cellXfs = _a.cellXfs, styleBuilder = _a.styleBuilder, onImage = _a.onImage, onHyperlink = _a.onHyperlink, dataValidationsById = _a.dataValidationsById, onDataValidation = _a.onDataValidation, tableNameMap = _a.tableNameMap, tables = _a.tables, ignoreFormulaPatterns = _a.ignoreFormulaPatterns, commentsCollector = _a.commentsCollector, onCommentThread = _a.onCommentThread, sheetId = _a.sheetId, sheetData = _a.sheetData, sheets = _a.sheets, locale = _a.locale, validSharedFormulaLeaders = _a.validSharedFormulaLeaders;
1864
+ var rowNumber = _a.rowNumber, row = _a.row, rowMetadata = _a.rowMetadata, defaultRowHeightPx = _a.defaultRowHeightPx, sharedStrings = _a.sharedStrings, sourceSharedStrings = _a.sourceSharedStrings, cellXfs = _a.cellXfs, styleBuilder = _a.styleBuilder, onImage = _a.onImage, onHyperlink = _a.onHyperlink, dataValidationsById = _a.dataValidationsById, onDataValidation = _a.onDataValidation, tableNameMap = _a.tableNameMap, tables = _a.tables, ignoreFormulaPatterns = _a.ignoreFormulaPatterns, commentsCollector = _a.commentsCollector, onCommentThread = _a.onCommentThread, sheetId = _a.sheetId, sheetData = _a.sheetData, sheets = _a.sheets, locale = _a.locale, validSharedFormulaLeaders = _a.validSharedFormulaLeaders, onDynamicArray = _a.onDynamicArray;
1849
1865
  var values = (_b = row === null || row === void 0 ? void 0 : row.values) !== null && _b !== void 0 ? _b : [];
1850
1866
  var cellXmlChunks = [];
1851
1867
  var minColumn = Number.POSITIVE_INFINITY;
@@ -1874,6 +1890,7 @@ var buildWorksheetRow = function (_a) {
1874
1890
  sheets: sheets,
1875
1891
  locale: locale,
1876
1892
  validSharedFormulaLeaders: validSharedFormulaLeaders,
1893
+ onDynamicArray: onDynamicArray,
1877
1894
  });
1878
1895
  if (!cellXml)
1879
1896
  continue;
@@ -1946,8 +1963,8 @@ var buildWorksheetRow = function (_a) {
1946
1963
  };
1947
1964
  var buildCellXml = function (_a) {
1948
1965
  var e_33, _b;
1949
- var _d, _e, _f, _g, _h, _j, _k, _l;
1950
- var rowNumber = _a.rowNumber, columnIndex = _a.columnIndex, cell = _a.cell, sharedStrings = _a.sharedStrings, sourceSharedStrings = _a.sourceSharedStrings, cellXfs = _a.cellXfs, styleBuilder = _a.styleBuilder, onImage = _a.onImage, onHyperlink = _a.onHyperlink, dataValidationsById = _a.dataValidationsById, onDataValidation = _a.onDataValidation, tableNameMap = _a.tableNameMap, tables = _a.tables, ignoreFormulaPatterns = _a.ignoreFormulaPatterns, commentsCollector = _a.commentsCollector, onCommentThread = _a.onCommentThread, sheetId = _a.sheetId, sheetData = _a.sheetData, sheets = _a.sheets, locale = _a.locale, validSharedFormulaLeaders = _a.validSharedFormulaLeaders;
1966
+ var _d, _e, _f, _g, _h, _j, _k, _l, _m;
1967
+ var rowNumber = _a.rowNumber, columnIndex = _a.columnIndex, cell = _a.cell, sharedStrings = _a.sharedStrings, sourceSharedStrings = _a.sourceSharedStrings, cellXfs = _a.cellXfs, styleBuilder = _a.styleBuilder, onImage = _a.onImage, onHyperlink = _a.onHyperlink, dataValidationsById = _a.dataValidationsById, onDataValidation = _a.onDataValidation, tableNameMap = _a.tableNameMap, tables = _a.tables, ignoreFormulaPatterns = _a.ignoreFormulaPatterns, commentsCollector = _a.commentsCollector, onCommentThread = _a.onCommentThread, sheetId = _a.sheetId, sheetData = _a.sheetData, sheets = _a.sheets, locale = _a.locale, validSharedFormulaLeaders = _a.validSharedFormulaLeaders, onDynamicArray = _a.onDynamicArray;
1951
1968
  var normalizedCell = cell;
1952
1969
  if (!normalizedCell)
1953
1970
  return undefined;
@@ -2091,12 +2108,25 @@ var buildCellXml = function (_a) {
2091
2108
  }
2092
2109
  var xmlParts = [];
2093
2110
  var typeAttr = "";
2111
+ var dynamicArrayAttr = "";
2094
2112
  if (exportedFormulaValue) {
2095
2113
  // Array formula anchor: emit <f t="array" ref="..."/>. Spilled cells in
2096
2114
  // the range carry no `ue` formula (they're populated by the calculator
2097
2115
  // as side-effects of the anchor's evaluation), so they never reach this
2098
- // branch and correctly emit only <v>.
2099
- var arrayRef = normalizedCell.af;
2116
+ // branch and correctly emit only <v>. `af` is stamped by the calculator
2117
+ // on every spilling anchor and captured from `<f t="array" ref>` on
2118
+ // import; a bare array constant (`={1,2;3,4}`) that never went through
2119
+ // the calculator still gets its range from the constant's own shape.
2120
+ var arrayRef = (_m = normalizedCell.af) !== null && _m !== void 0 ? _m : arrayConstantSpillRef(exportedFormulaValue, rowNumber, columnIndex);
2121
+ // Excel distinguishes the two kinds of `<f t="array">`: a dynamic array
2122
+ // carries `cm="1"` on the `<c>` (pointing at the XLDAPR record in
2123
+ // xl/metadata.xml) and re-opens as a spilling formula; without `cm` Excel
2124
+ // reads a legacy Ctrl+Shift+Enter array (`{=…}`). Only an anchor imported
2125
+ // as a CSE array (`cse`) is written back that way.
2126
+ if (arrayRef && !(normalizedCell.af && normalizedCell.cse)) {
2127
+ dynamicArrayAttr = " cm=\"1\"";
2128
+ onDynamicArray === null || onDynamicArray === void 0 ? void 0 : onDynamicArray();
2129
+ }
2100
2130
  // Shared formula: emit `<f t="shared" si="N" ref="A1:A10">FORMULA</f>`
2101
2131
  // on the leader cell (carries both `si` and `ref`) and
2102
2132
  // `<f t="shared" si="N"/>` on followers (carries only `si` — no formula
@@ -2181,7 +2211,7 @@ var buildCellXml = function (_a) {
2181
2211
  }
2182
2212
  return "<c r=\"".concat(address, "\"").concat(styleAttr, "/>");
2183
2213
  }
2184
- return "<c r=\"".concat(address, "\"").concat(typeAttr).concat(styleAttr, ">").concat(xmlParts.join(""), "</c>");
2214
+ return "<c r=\"".concat(address, "\"").concat(typeAttr).concat(styleAttr).concat(dynamicArrayAttr, ">").concat(xmlParts.join(""), "</c>");
2185
2215
  };
2186
2216
  var normalizeHyperlinkValue = function (hyperlink) {
2187
2217
  if (!hyperlink) {
@@ -2267,6 +2297,56 @@ function stripFormula(formula) {
2267
2297
  var trimmed = formula.startsWith("=") ? formula.slice(1) : formula;
2268
2298
  return sanitizeFormulaText(trimmed);
2269
2299
  }
2300
+ /**
2301
+ * The A1 range an array constant spills over from its anchor: `={1,2;3,4}` at
2302
+ * B3 → `B3:C4`. `undefined` for anything that is not exactly one array
2303
+ * constant (a constant nested in a larger expression, a malformed literal).
2304
+ * Separators inside string elements are skipped.
2305
+ */
2306
+ function arrayConstantSpillRef(formula, rowNumber, columnIndex) {
2307
+ var e_34, _a;
2308
+ var body = (formula.startsWith("=") ? formula.slice(1) : formula).trim();
2309
+ if (!body.startsWith("{") || !body.endsWith("}"))
2310
+ return undefined;
2311
+ var rows = 1;
2312
+ var columns = 1;
2313
+ var inString = false;
2314
+ try {
2315
+ for (var _b = __values(body.slice(1, -1)), _d = _b.next(); !_d.done; _d = _b.next()) {
2316
+ var char = _d.value;
2317
+ if (char === '"') {
2318
+ inString = !inString;
2319
+ }
2320
+ else if (inString) {
2321
+ continue;
2322
+ }
2323
+ else if (char === "{" || char === "}") {
2324
+ return undefined;
2325
+ }
2326
+ else if (char === "," && rows === 1) {
2327
+ columns++;
2328
+ }
2329
+ else if (char === ";") {
2330
+ rows++;
2331
+ }
2332
+ }
2333
+ }
2334
+ catch (e_34_1) { e_34 = { error: e_34_1 }; }
2335
+ finally {
2336
+ try {
2337
+ if (_d && !_d.done && (_a = _b.return)) _a.call(_b);
2338
+ }
2339
+ finally { if (e_34) throw e_34.error; }
2340
+ }
2341
+ if (inString)
2342
+ return undefined;
2343
+ return cellRangeToAddress(undefined, {
2344
+ startRowIndex: rowNumber,
2345
+ startColumnIndex: columnIndex,
2346
+ endRowIndex: rowNumber + rows - 1,
2347
+ endColumnIndex: columnIndex + columns - 1,
2348
+ });
2349
+ }
2270
2350
  function hasPropertyReference(formula) {
2271
2351
  if (!formula)
2272
2352
  return false;
@@ -2284,7 +2364,7 @@ function isValidExcelDateSerial(value) {
2284
2364
  return value >= MIN_EXCEL_DATE_SERIAL && value <= MAX_EXCEL_DATE_SERIAL;
2285
2365
  }
2286
2366
  function rewriteTableNamesInFormula(formula, tableNameMap) {
2287
- var e_34, _a;
2367
+ var e_35, _a;
2288
2368
  if (!(tableNameMap === null || tableNameMap === void 0 ? void 0 : tableNameMap.size))
2289
2369
  return formula;
2290
2370
  var normalized = formula;
@@ -2299,12 +2379,12 @@ function rewriteTableNamesInFormula(formula, tableNameMap) {
2299
2379
  normalized = normalized.replace(new RegExp("".concat(escaped, "(?=\\[)"), "g"), exportedName);
2300
2380
  }
2301
2381
  }
2302
- catch (e_34_1) { e_34 = { error: e_34_1 }; }
2382
+ catch (e_35_1) { e_35 = { error: e_35_1 }; }
2303
2383
  finally {
2304
2384
  try {
2305
2385
  if (tableNameMap_1_1 && !tableNameMap_1_1.done && (_a = tableNameMap_1.return)) _a.call(tableNameMap_1);
2306
2386
  }
2307
- finally { if (e_34) throw e_34.error; }
2387
+ finally { if (e_35) throw e_35.error; }
2308
2388
  }
2309
2389
  return normalized;
2310
2390
  }
@@ -2400,6 +2480,30 @@ function rewriteStructuredReferenceFormula(formula, tableNameMap, tables, rowNum
2400
2480
  var qualified = prefixUnqualifiedStructuredReferences(normalized, table.name);
2401
2481
  return normalizeThisRowStructuredReferences(qualified, table.name);
2402
2482
  }
2483
+ /**
2484
+ * `xl/metadata.xml` for a workbook with dynamic-array anchors — one XLDAPR
2485
+ * (dynamic array properties) record every `cm="1"` cell points at, exactly as
2486
+ * Excel 365 writes it. `fDynamic="1"` marks the anchor as a spilling formula;
2487
+ * `fCollapsed="0"` says the spill is shown expanded.
2488
+ */
2489
+ var DYNAMIC_ARRAY_METADATA_XML = "".concat(XML_DECLARATION, "<metadata xmlns=\"").concat(WORKSHEET_NS, "\" xmlns:xda=\"http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray\"><metadataTypes count=\"1\"><metadataType name=\"XLDAPR\" minSupportedVersion=\"120000\" copy=\"1\" pasteAll=\"1\" pasteValues=\"1\" merge=\"1\" splitFirst=\"1\" rowColShift=\"1\" clearFormats=\"1\" clearComments=\"1\" assign=\"1\" coerce=\"1\" cellMeta=\"1\"/></metadataTypes><futureMetadata name=\"XLDAPR\" count=\"1\"><bk><extLst><ext uri=\"{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}\"><xda:dynamicArrayProperties fDynamic=\"1\" fCollapsed=\"0\"/></ext></extLst></bk></futureMetadata><cellMetadata count=\"1\"><bk><rc t=\"1\" v=\"0\"/></bk></cellMetadata></metadata>");
2490
+ /**
2491
+ * A defined-name expression that is a formula rather than a constant: a
2492
+ * function call, an operator expression, a reference. Constants (`123`,
2493
+ * `"text"`, `TRUE`) are written verbatim.
2494
+ */
2495
+ function isAFormulaExpression(expression) {
2496
+ var trimmed = expression.trim();
2497
+ if (!trimmed)
2498
+ return false;
2499
+ if (/^"(?:[^"]|"")*"$/.test(trimmed))
2500
+ return false;
2501
+ if (/^-?\d+(?:\.\d+)?(?:e[+-]?\d+)?%?$/i.test(trimmed))
2502
+ return false;
2503
+ if (/^(?:TRUE|FALSE)$/i.test(trimmed))
2504
+ return false;
2505
+ return true;
2506
+ }
2403
2507
  function sanitizeFormulaText(formula) {
2404
2508
  var normalized = sanitizeXmlText(formula);
2405
2509
  // `@x` is persisted as `_xlfn.SINGLE(x)`; encoding first lets the
@@ -2514,8 +2618,11 @@ var buildColumnsXml = function (sheet, bounds) {
2514
2618
  continue;
2515
2619
  var attributes = ["min=\"".concat(columnIndex, "\""), "max=\"".concat(columnIndex, "\"")];
2516
2620
  if (hasExplicitSize) {
2621
+ // Full precision on purpose: the stored value is a multiple of 1/256
2622
+ // (Excel writes e.g. 9.140625), and rounding to two decimals would
2623
+ // break the exact export → import pixel fixed point.
2517
2624
  var width = columnPixelToChars(getColumnWidthPx(sheet, columnIndex - 1));
2518
- attributes.push("width=\"".concat(width.toFixed(2), "\""));
2625
+ attributes.push("width=\"".concat(width, "\""));
2519
2626
  attributes.push("customWidth=\"1\"");
2520
2627
  }
2521
2628
  if (hasHiddenFlag) {
@@ -2704,7 +2811,7 @@ var buildRichRunProperties = function (format) {
2704
2811
  * style flag, but that's a cell-style concern, not a sharedString one.
2705
2812
  */
2706
2813
  var buildRichTextRuns = function (text, runs) {
2707
- var e_35, _a;
2814
+ var e_36, _a;
2708
2815
  var sorted = __spreadArray([], __read(runs), false).sort(function (a, b) { return a.startIndex - b.startIndex; });
2709
2816
  var out = [];
2710
2817
  var cursor = 0;
@@ -2737,12 +2844,12 @@ var buildRichTextRuns = function (text, runs) {
2737
2844
  cursor = end;
2738
2845
  }
2739
2846
  }
2740
- catch (e_35_1) { e_35 = { error: e_35_1 }; }
2847
+ catch (e_36_1) { e_36 = { error: e_36_1 }; }
2741
2848
  finally {
2742
2849
  try {
2743
2850
  if (sorted_2_1 && !sorted_2_1.done && (_a = sorted_2.return)) _a.call(sorted_2);
2744
2851
  }
2745
- finally { if (e_35) throw e_35.error; }
2852
+ finally { if (e_36) throw e_36.error; }
2746
2853
  }
2747
2854
  if (cursor < text.length) {
2748
2855
  emit(text.slice(cursor), "");
@@ -2763,7 +2870,7 @@ var buildSharedStringsXml = function (sharedStrings) {
2763
2870
  return "".concat(XML_DECLARATION, "<sst xmlns=\"").concat(WORKSHEET_NS, "\" count=\"").concat(sharedStrings.totalCount, "\" uniqueCount=\"").concat(sharedStrings.entries.length, "\">").concat(entries, "</sst>");
2764
2871
  };
2765
2872
  var buildTableNameMap = function (tables) {
2766
- var e_36, _a;
2873
+ var e_37, _a;
2767
2874
  var _b;
2768
2875
  var map = new Map();
2769
2876
  try {
@@ -2775,12 +2882,12 @@ var buildTableNameMap = function (tables) {
2775
2882
  map.set(tableTitle, table.name);
2776
2883
  }
2777
2884
  }
2778
- catch (e_36_1) { e_36 = { error: e_36_1 }; }
2885
+ catch (e_37_1) { e_37 = { error: e_37_1 }; }
2779
2886
  finally {
2780
2887
  try {
2781
2888
  if (tables_1_1 && !tables_1_1.done && (_a = tables_1.return)) _a.call(tables_1);
2782
2889
  }
2783
- finally { if (e_36) throw e_36.error; }
2890
+ finally { if (e_37) throw e_37.error; }
2784
2891
  }
2785
2892
  return map;
2786
2893
  };
@@ -2788,7 +2895,7 @@ var buildTableNameMap = function (tables) {
2788
2895
  // whose box intersects another table on the same sheet. Drop both before
2789
2896
  // emitting so the workbook opens without "We found a problem" recovery prompts.
2790
2897
  var filterExportableTables = function (tables) {
2791
- var e_37, _a;
2898
+ var e_38, _a;
2792
2899
  var _b;
2793
2900
  var isValidBox = function (range) {
2794
2901
  if (!range)
@@ -2831,12 +2938,12 @@ var filterExportableTables = function (tables) {
2831
2938
  _loop_5(table);
2832
2939
  }
2833
2940
  }
2834
- catch (e_37_1) { e_37 = { error: e_37_1 }; }
2941
+ catch (e_38_1) { e_38 = { error: e_38_1 }; }
2835
2942
  finally {
2836
2943
  try {
2837
2944
  if (tables_2_1 && !tables_2_1.done && (_a = tables_2.return)) _a.call(tables_2);
2838
2945
  }
2839
- finally { if (e_37) throw e_37.error; }
2946
+ finally { if (e_38) throw e_38.error; }
2840
2947
  }
2841
2948
  return result;
2842
2949
  };
@@ -3000,11 +3107,17 @@ var buildTableXml = function (table, rows, sourceSharedStrings, styleBuilder, cu
3000
3107
  .filter(function (idx) { var _a, _b; return ((_b = (_a = table.columns) === null || _a === void 0 ? void 0 : _a[idx]) === null || _b === void 0 ? void 0 : _b.filterButton) === false; }));
3001
3108
  var autoFilter = headerRowCount > 0 && table.filterButton !== false
3002
3109
  ? (function () {
3003
- var _a, _b, _d;
3110
+ var _a, _b, _d, _e;
3004
3111
  var filterColumns = buildFilterColumnsXml((_a = table.filterSpecs) !== null && _a !== void 0 ? _a : [], table.range, rows, (_b = table.headerRow) !== null && _b !== void 0 ? _b : true, (_d = table.totalRow) !== null && _d !== void 0 ? _d : false, styleBuilder, hiddenButtonColumns);
3112
+ // Excel's table `<autoFilter ref>` spans the header and data rows
3113
+ // only — a ref that reaches into the totals row makes Excel repair
3114
+ // the table (the totals row is never filtered or sorted).
3115
+ var filterRef = totalsRowCount > 0
3116
+ ? ((_e = gridRangeToRef(__assign(__assign({}, table.range), { endRowIndex: table.range.endRowIndex - totalsRowCount }))) !== null && _e !== void 0 ? _e : rangeRef)
3117
+ : rangeRef;
3005
3118
  return filterColumns
3006
- ? "<autoFilter ref=\"".concat(rangeRef, "\">").concat(filterColumns, "</autoFilter>")
3007
- : "<autoFilter ref=\"".concat(rangeRef, "\"/>");
3119
+ ? "<autoFilter ref=\"".concat(filterRef, "\">").concat(filterColumns, "</autoFilter>")
3120
+ : "<autoFilter ref=\"".concat(filterRef, "\"/>");
3008
3121
  })()
3009
3122
  : "";
3010
3123
  var sortState = buildTableSortStateXml(table, headerRowCount, totalsRowCount, styleBuilder);
@@ -3119,7 +3232,7 @@ var SHEET_PROTECTION_FLAG_ATTRS = [
3119
3232
  * Excel's schema default applies). Mirrors `rnc-export`'s `sheet_protection_xml`.
3120
3233
  */
3121
3234
  var buildSheetProtectionElementXml = function (protection) {
3122
- var e_38, _a;
3235
+ var e_39, _a;
3123
3236
  var attrs = [];
3124
3237
  if (protection.algorithmName) {
3125
3238
  attrs.push("algorithmName=\"".concat(escapeXmlAttr(protection.algorithmName), "\""));
@@ -3145,12 +3258,12 @@ var buildSheetProtectionElementXml = function (protection) {
3145
3258
  }
3146
3259
  }
3147
3260
  }
3148
- catch (e_38_1) { e_38 = { error: e_38_1 }; }
3261
+ catch (e_39_1) { e_39 = { error: e_39_1 }; }
3149
3262
  finally {
3150
3263
  try {
3151
3264
  if (SHEET_PROTECTION_FLAG_ATTRS_1_1 && !SHEET_PROTECTION_FLAG_ATTRS_1_1.done && (_a = SHEET_PROTECTION_FLAG_ATTRS_1.return)) _a.call(SHEET_PROTECTION_FLAG_ATTRS_1);
3152
3265
  }
3153
- finally { if (e_38) throw e_38.error; }
3266
+ finally { if (e_39) throw e_39.error; }
3154
3267
  }
3155
3268
  return attrs.length ? "<sheetProtection ".concat(attrs.join(" "), "/>") : "";
3156
3269
  };
@@ -3162,7 +3275,7 @@ var buildSheetProtectionElementXml = function (protection) {
3162
3275
  * is the range's id, synthesized as `Range{n}` when absent (schema requires it).
3163
3276
  */
3164
3277
  var buildSheetProtectionXml = function (sheet, protectedRanges) {
3165
- var e_39, _a;
3278
+ var e_40, _a;
3166
3279
  var protectionXml = sheet.sheetProtection
3167
3280
  ? buildSheetProtectionElementXml(sheet.sheetProtection)
3168
3281
  : "";
@@ -3203,12 +3316,12 @@ var buildSheetProtectionXml = function (sheet, protectedRanges) {
3203
3316
  rangeItems.push("<protectedRange sqref=\"".concat(escapeXmlAttr(sqref), "\" name=\"").concat(escapeXmlAttr(name_1), "\"").concat(securityDescriptor, "/>"));
3204
3317
  }
3205
3318
  }
3206
- catch (e_39_1) { e_39 = { error: e_39_1 }; }
3319
+ catch (e_40_1) { e_40 = { error: e_40_1 }; }
3207
3320
  finally {
3208
3321
  try {
3209
3322
  if (_d && !_d.done && (_a = _b.return)) _a.call(_b);
3210
3323
  }
3211
- finally { if (e_39) throw e_39.error; }
3324
+ finally { if (e_40) throw e_40.error; }
3212
3325
  }
3213
3326
  var rangesXml = rangeItems.length
3214
3327
  ? "<protectedRanges>".concat(rangeItems.join(""), "</protectedRanges>")
@@ -3341,7 +3454,7 @@ var buildPrintSettingsXml = function (print) {
3341
3454
  var buildFilterColumnsXml = function (filterSpecs, range, rows, headerRow, totalRow, styleBuilder,
3342
3455
  /** Table-relative column ids whose header hides its filter button. */
3343
3456
  hiddenButtonColumns) {
3344
- var e_40, _a;
3457
+ var e_41, _a;
3345
3458
  if (headerRow === void 0) { headerRow = true; }
3346
3459
  if (totalRow === void 0) { totalRow = false; }
3347
3460
  var entries = new Map();
@@ -3353,12 +3466,12 @@ hiddenButtonColumns) {
3353
3466
  entries.set(spec.columnIndex, xml);
3354
3467
  }
3355
3468
  }
3356
- catch (e_40_1) { e_40 = { error: e_40_1 }; }
3469
+ catch (e_41_1) { e_41 = { error: e_41_1 }; }
3357
3470
  finally {
3358
3471
  try {
3359
3472
  if (_d && !_d.done && (_a = _b.return)) _a.call(_b);
3360
3473
  }
3361
- finally { if (e_40) throw e_40.error; }
3474
+ finally { if (e_41) throw e_41.error; }
3362
3475
  }
3363
3476
  // `hiddenButton="1"` rides the column's criteria element when it has one,
3364
3477
  // else a bare `<filterColumn/>` carries it.
@@ -3379,55 +3492,99 @@ hiddenButtonColumns) {
3379
3492
  })
3380
3493
  .join("");
3381
3494
  };
3495
+ /**
3496
+ * One `<filterColumn colId=…>`, or `""` when the criteria have no autoFilter
3497
+ * representation. `CT_FilterColumn` is a CHOICE of exactly one of `filters` /
3498
+ * `top10` / `customFilters` / `dynamicFilter` / `colorFilter` / `iconFilter` —
3499
+ * a second child is a schema violation Excel repairs — so the first
3500
+ * representable criterion wins: colorFilter, iconFilter, condition(s), then
3501
+ * the value list (`<filters>`: the checked values, `blank="1"` for the
3502
+ * "(Blanks)" entry, and Excel's `<dateGroupItem>` date-tree entries). The
3503
+ * Rust exporter (`rnc-export` `filter_column_xml`) uses the same precedence.
3504
+ */
3382
3505
  var buildFilterColumnXml = function (spec, range, rows, headerRow, totalRow, styleBuilder) {
3383
3506
  var _a, _b, _d, _e, _f;
3384
3507
  if (headerRow === void 0) { headerRow = true; }
3385
3508
  if (totalRow === void 0) { totalRow = false; }
3386
- var parts = [];
3387
- // <colorFilter dxfId="N" cellColor="1|0"/> — Excel matches against the
3388
- // dxf table. We register the color as a dxf and emit the resulting id.
3389
- var colorFilter = (_a = spec.filterCriteria) === null || _a === void 0 ? void 0 : _a.colorFilter;
3390
- if (colorFilter && styleBuilder) {
3391
- var dxfId = colorFilter.mode === "cellColor"
3392
- ? styleBuilder.registerDifferentialFormat({
3393
- backgroundColor: colorFilter.color,
3394
- })
3395
- : styleBuilder.registerDifferentialFormat({
3396
- textFormat: { color: colorFilter.color },
3397
- });
3398
- if (typeof dxfId === "number") {
3399
- var cellColorAttr = colorFilter.mode === "cellColor" ? "1" : "0";
3400
- parts.push("<colorFilter dxfId=\"".concat(dxfId, "\" cellColor=\"").concat(cellColorAttr, "\"/>"));
3401
- }
3402
- }
3403
- // <iconFilter iconSet="…" iconId="…"/>
3404
- var iconFilter = (_b = spec.filterCriteria) === null || _b === void 0 ? void 0 : _b.iconFilter;
3405
- if (iconFilter === null || iconFilter === void 0 ? void 0 : iconFilter.iconSet) {
3406
- parts.push("<iconFilter iconSet=\"".concat(escapeXmlAttr(iconFilter.iconSet), "\" iconId=\"").concat((_d = iconFilter.iconId) !== null && _d !== void 0 ? _d : 0, "\"/>"));
3407
- }
3408
- // A condition filter (greater-than / contains / between / relative-date /
3409
- // above-average …) takes precedence over a value-list and is emitted as
3410
- // <customFilters> or <dynamicFilter>. Falls back to the value list when the
3411
- // condition has no AutoFilter representation.
3412
- var conditionXml = spec.filterCriteria
3509
+ var child = (_f = (_e = (_b = buildColorFilterXml((_a = spec.filterCriteria) === null || _a === void 0 ? void 0 : _a.colorFilter, styleBuilder)) !== null && _b !== void 0 ? _b : buildIconFilterXml((_d = spec.filterCriteria) === null || _d === void 0 ? void 0 : _d.iconFilter)) !== null && _e !== void 0 ? _e : (spec.filterCriteria
3413
3510
  ? buildAutoFilterCriteriaXml(spec.filterCriteria)
3414
- : null;
3415
- if (conditionXml) {
3416
- parts.push(conditionXml);
3417
- }
3418
- else {
3419
- // <filters><filter val=…/></filters>
3420
- var values = (_f = (_e = spec.filterCriteria) === null || _e === void 0 ? void 0 : _e.visibleValues) !== null && _f !== void 0 ? _f : getFilterVisibleValues(spec, range, rows, headerRow, totalRow);
3421
- if (values === null || values === void 0 ? void 0 : values.length) {
3422
- var filters = values
3423
- .map(function (value) { return "<filter val=\"".concat(escapeXmlAttr(value), "\"/>"); })
3424
- .join("");
3425
- parts.push("<filters>".concat(filters, "</filters>"));
3426
- }
3427
- }
3428
- if (!parts.length)
3511
+ : null)) !== null && _f !== void 0 ? _f : buildFilterValueListXml(spec, range, rows, headerRow, totalRow);
3512
+ if (!child)
3429
3513
  return "";
3430
- return "<filterColumn colId=\"".concat(spec.columnIndex, "\">").concat(parts.join(""), "</filterColumn>");
3514
+ return "<filterColumn colId=\"".concat(spec.columnIndex, "\">").concat(child, "</filterColumn>");
3515
+ };
3516
+ /**
3517
+ * `<colorFilter dxfId="N" cellColor="1|0"/>` — Excel matches against the dxf
3518
+ * table; the color is registered as a dxf and referenced by id.
3519
+ */
3520
+ var buildColorFilterXml = function (colorFilter, styleBuilder) {
3521
+ if (!colorFilter || !styleBuilder)
3522
+ return null;
3523
+ var dxfId = colorFilter.mode === "cellColor"
3524
+ ? styleBuilder.registerDifferentialFormat({
3525
+ backgroundColor: colorFilter.color,
3526
+ })
3527
+ : styleBuilder.registerDifferentialFormat({
3528
+ textFormat: { color: colorFilter.color },
3529
+ });
3530
+ if (typeof dxfId !== "number")
3531
+ return null;
3532
+ var cellColorAttr = colorFilter.mode === "cellColor" ? "1" : "0";
3533
+ return "<colorFilter dxfId=\"".concat(dxfId, "\" cellColor=\"").concat(cellColorAttr, "\"/>");
3534
+ };
3535
+ /** `<iconFilter iconSet="…" iconId="…"/>`. */
3536
+ var buildIconFilterXml = function (iconFilter) {
3537
+ var _a;
3538
+ if (!(iconFilter === null || iconFilter === void 0 ? void 0 : iconFilter.iconSet))
3539
+ return null;
3540
+ return "<iconFilter iconSet=\"".concat(escapeXmlAttr(iconFilter.iconSet), "\" iconId=\"").concat((_a = iconFilter.iconId) !== null && _a !== void 0 ? _a : 0, "\"/>");
3541
+ };
3542
+ /**
3543
+ * `<filters>` — the checked values (`blank="1"` for the engine's "(Blanks)"
3544
+ * sentinel; Excel never writes it as a `<filter val>`) plus the date-grouped
3545
+ * `<dateGroupItem>` entries. Without explicit `visibleValues` the list is
3546
+ * derived from the column's cells (every value visible).
3547
+ */
3548
+ var buildFilterValueListXml = function (spec, range, rows, headerRow, totalRow) {
3549
+ var _a, _b, _d, _e;
3550
+ var dateGroups = (_b = (_a = spec.filterCriteria) === null || _a === void 0 ? void 0 : _a.dateGroups) !== null && _b !== void 0 ? _b : [];
3551
+ var values = (_e = (_d = spec.filterCriteria) === null || _d === void 0 ? void 0 : _d.visibleValues) !== null && _e !== void 0 ? _e : (dateGroups.length
3552
+ ? []
3553
+ : getFilterVisibleValues(spec, range, rows, headerRow, totalRow));
3554
+ if (!values.length && !dateGroups.length)
3555
+ return null;
3556
+ var showBlanks = values.includes(BLANK_LABEL);
3557
+ var filters = values
3558
+ .filter(function (value) { return value !== BLANK_LABEL; })
3559
+ .map(function (value) { return "<filter val=\"".concat(escapeXmlAttr(value), "\"/>"); })
3560
+ .join("");
3561
+ var groups = dateGroups
3562
+ .map(function (group) {
3563
+ var e_42, _a;
3564
+ var _b;
3565
+ var attrs = ["year=\"".concat(group.year, "\"")];
3566
+ try {
3567
+ for (var _d = __values(["month", "day", "hour", "minute", "second"]), _e = _d.next(); !_e.done; _e = _d.next()) {
3568
+ var name_2 = _e.value;
3569
+ var value = group[name_2];
3570
+ if (value !== undefined && value !== null) {
3571
+ attrs.push("".concat(name_2, "=\"").concat(value, "\""));
3572
+ }
3573
+ }
3574
+ }
3575
+ catch (e_42_1) { e_42 = { error: e_42_1 }; }
3576
+ finally {
3577
+ try {
3578
+ if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
3579
+ }
3580
+ finally { if (e_42) throw e_42.error; }
3581
+ }
3582
+ attrs.push("dateTimeGrouping=\"".concat(escapeXmlAttr((_b = group.dateTimeGrouping) !== null && _b !== void 0 ? _b : "day"), "\""));
3583
+ return "<dateGroupItem ".concat(attrs.join(" "), "/>");
3584
+ })
3585
+ .join("");
3586
+ var blankAttr = showBlanks ? " blank=\"1\"" : "";
3587
+ return "<filters".concat(blankAttr, ">").concat(filters).concat(groups, "</filters>");
3431
3588
  };
3432
3589
  var gridRangeToRef = function (range) {
3433
3590
  if (!range)
@@ -3695,7 +3852,7 @@ var groupChartsBySheet = function (charts) {
3695
3852
  return result;
3696
3853
  };
3697
3854
  var groupSlicersBySheet = function (slicers) {
3698
- var e_41, _a;
3855
+ var e_43, _a;
3699
3856
  var _b, _d, _e, _f, _g, _h;
3700
3857
  var result = new Map();
3701
3858
  try {
@@ -3718,19 +3875,19 @@ var groupSlicersBySheet = function (slicers) {
3718
3875
  result.set(slicer.position.sheetId, list);
3719
3876
  }
3720
3877
  }
3721
- catch (e_41_1) { e_41 = { error: e_41_1 }; }
3878
+ catch (e_43_1) { e_43 = { error: e_43_1 }; }
3722
3879
  finally {
3723
3880
  try {
3724
3881
  if (_k && !_k.done && (_a = _j.return)) _a.call(_j);
3725
3882
  }
3726
- finally { if (e_41) throw e_41.error; }
3883
+ finally { if (e_43) throw e_43.error; }
3727
3884
  }
3728
3885
  return result;
3729
3886
  };
3730
3887
  var buildConditionalFormattingXml = function (_a) {
3731
- var e_42, _b;
3888
+ var e_44, _b;
3732
3889
  var _d, _e, _f;
3733
- var conditionalFormats = _a.conditionalFormats, sheetId = _a.sheetId, styleBuilder = _a.styleBuilder;
3890
+ var conditionalFormats = _a.conditionalFormats, sheetId = _a.sheetId, styleBuilder = _a.styleBuilder, locale = _a.locale;
3734
3891
  if (!(conditionalFormats === null || conditionalFormats === void 0 ? void 0 : conditionalFormats.length)) {
3735
3892
  return "";
3736
3893
  }
@@ -3782,6 +3939,7 @@ var buildConditionalFormattingXml = function (_a) {
3782
3939
  styleBuilder: styleBuilder,
3783
3940
  priority: basePriority,
3784
3941
  baseCellAddress: baseCellAddress,
3942
+ locale: locale,
3785
3943
  });
3786
3944
  if (!(cfRulesXml === null || cfRulesXml === void 0 ? void 0 : cfRulesXml.length))
3787
3945
  continue;
@@ -3792,12 +3950,12 @@ var buildConditionalFormattingXml = function (_a) {
3792
3950
  parts.push("<conditionalFormatting sqref=\"".concat(sqrefParts.join(" "), "\">").concat(ruleXmlEntries.join(""), "</conditionalFormatting>"));
3793
3951
  }
3794
3952
  }
3795
- catch (e_42_1) { e_42 = { error: e_42_1 }; }
3953
+ catch (e_44_1) { e_44 = { error: e_44_1 }; }
3796
3954
  finally {
3797
3955
  try {
3798
3956
  if (orderedRules_1_1 && !orderedRules_1_1.done && (_b = orderedRules_1.return)) _b.call(orderedRules_1);
3799
3957
  }
3800
- finally { if (e_42) throw e_42.error; }
3958
+ finally { if (e_44) throw e_44.error; }
3801
3959
  }
3802
3960
  return parts.join("");
3803
3961
  };
@@ -3897,7 +4055,7 @@ var buildXlsxSourceCfRuleXml = function (rule, styleBuilder, priority) {
3897
4055
  };
3898
4056
  var buildConditionalFormattingRuleXml = function (_a) {
3899
4057
  var _b;
3900
- var rule = _a.rule, styleBuilder = _a.styleBuilder, priority = _a.priority, baseCellAddress = _a.baseCellAddress;
4058
+ var rule = _a.rule, styleBuilder = _a.styleBuilder, priority = _a.priority, baseCellAddress = _a.baseCellAddress, locale = _a.locale;
3901
4059
  // Round-trip via xlsxSource when present (imported rules). Falls through
3902
4060
  // to synthesizer for rules without source metadata (UI-created).
3903
4061
  if ((_b = rule.xlsxSource) === null || _b === void 0 ? void 0 : _b.type) {
@@ -4035,8 +4193,11 @@ var buildConditionalFormattingRuleXml = function (_a) {
4035
4193
  NUMBER_LESS_THAN_EQ: "lessThanOrEqual",
4036
4194
  };
4037
4195
  var operator = operatorMap[condition.type];
4038
- var first = stripFormula(firstRaw);
4039
- var second = stripFormula(secondRaw);
4196
+ // Typed literals are written the way Excel stores them (`50%` → `0.5`,
4197
+ // a typed date → its serial); formulas lose their `=`; references, names
4198
+ // and function calls are written verbatim.
4199
+ var first = conditionOperandToFormulaText(stripFormula(firstRaw), locale);
4200
+ var second = conditionOperandToFormulaText(stripFormula(secondRaw), locale);
4040
4201
  if ((operator === "between" || operator === "notBetween") && !secondRaw) {
4041
4202
  return undefined;
4042
4203
  }
@@ -4066,17 +4227,12 @@ var buildConditionalFormattingRuleXml = function (_a) {
4066
4227
  DATE_BETWEEN: "between",
4067
4228
  DATE_NOT_BETWEEN: "notBetween",
4068
4229
  };
4230
+ // A typed date (`2024-01-05`, `1/5/2024` in the document locale) is
4231
+ // exported as its serial — what Excel itself stores; the bare text would
4232
+ // be the arithmetic 2024-01-05 = 2022. Formulas lose their `=`;
4233
+ // references and function calls are written verbatim.
4069
4234
  var normalizeDateValue = function (raw) {
4070
- var trimmed = raw.trim();
4071
- if (!trimmed)
4072
- return "";
4073
- if (trimmed.startsWith("=")) {
4074
- return stripFormula(trimmed);
4075
- }
4076
- if (!isNaN(Number(trimmed))) {
4077
- return trimmed;
4078
- }
4079
- return "DATEVALUE(\"".concat(escapeFormulaText(trimmed), "\")");
4235
+ return conditionOperandToFormulaText(stripFormula(raw), locale);
4080
4236
  };
4081
4237
  var first = normalizeDateValue(firstRaw);
4082
4238
  var second = normalizeDateValue(secondRaw);
@@ -4293,8 +4449,8 @@ var buildConditionalFormattingRuleXml = function (_a) {
4293
4449
  return rules.length ? rules : undefined;
4294
4450
  };
4295
4451
  var buildDrawingParts = function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
4296
- var anchors, relationships, media, imageIndex, chartIndex, chartExIndex, pictureId, frameId, chartEntries, chartExEntries, orderedAnchors, orderOf, charts_1, charts_1_1, placement, chartExXml, relId_1, chartXml, relId, slicers_1, slicers_1_1, placement, textBoxes_1, textBoxes_1_1, placement, shapes_1, shapes_1_1, placement, placements_1, placements_1_1, placement, dataUrl, buffer, mediaPath, relId, e_43_1, orderedAnchors_1, orderedAnchors_1_1, entry, drawingXml;
4297
- var e_44, _d, e_45, _e, e_46, _f, e_47, _g, e_43, _h, e_48, _j;
4452
+ var anchors, relationships, media, imageIndex, chartIndex, chartExIndex, pictureId, frameId, chartEntries, chartExEntries, orderedAnchors, orderOf, charts_1, charts_1_1, placement, chartExXml, relId_1, chartXml, relId, slicers_1, slicers_1_1, placement, textBoxes_1, textBoxes_1_1, placement, shapes_1, shapes_1_1, placement, placements_1, placements_1_1, placement, dataUrl, buffer, mediaPath, relId, e_45_1, orderedAnchors_1, orderedAnchors_1_1, entry, drawingXml;
4453
+ var e_46, _d, e_47, _e, e_48, _f, e_49, _g, e_45, _h, e_50, _j;
4298
4454
  var placements = _b.placements, textBoxes = _b.textBoxes, _k = _b.shapes, shapes = _k === void 0 ? [] : _k, startImageIndex = _b.startImageIndex, startChartIndex = _b.startChartIndex, _l = _b.startChartExIndex, startChartExIndex = _l === void 0 ? 1 : _l, charts = _b.charts, slicers = _b.slicers, sheet = _b.sheet, sheetNameById = _b.sheetNameById, resolvePivotSourceName = _b.resolvePivotSourceName;
4299
4455
  return __generator(this, function (_m) {
4300
4456
  switch (_m.label) {
@@ -4366,12 +4522,12 @@ var buildDrawingParts = function (_a) { return __awaiter(void 0, [_a], void 0, f
4366
4522
  frameId += 1;
4367
4523
  }
4368
4524
  }
4369
- catch (e_44_1) { e_44 = { error: e_44_1 }; }
4525
+ catch (e_46_1) { e_46 = { error: e_46_1 }; }
4370
4526
  finally {
4371
4527
  try {
4372
4528
  if (charts_1_1 && !charts_1_1.done && (_d = charts_1.return)) _d.call(charts_1);
4373
4529
  }
4374
- finally { if (e_44) throw e_44.error; }
4530
+ finally { if (e_46) throw e_46.error; }
4375
4531
  }
4376
4532
  try {
4377
4533
  for (slicers_1 = __values(slicers), slicers_1_1 = slicers_1.next(); !slicers_1_1.done; slicers_1_1 = slicers_1.next()) {
@@ -4384,12 +4540,12 @@ var buildDrawingParts = function (_a) { return __awaiter(void 0, [_a], void 0, f
4384
4540
  frameId += 1;
4385
4541
  }
4386
4542
  }
4387
- catch (e_45_1) { e_45 = { error: e_45_1 }; }
4543
+ catch (e_47_1) { e_47 = { error: e_47_1 }; }
4388
4544
  finally {
4389
4545
  try {
4390
4546
  if (slicers_1_1 && !slicers_1_1.done && (_e = slicers_1.return)) _e.call(slicers_1);
4391
4547
  }
4392
- finally { if (e_45) throw e_45.error; }
4548
+ finally { if (e_47) throw e_47.error; }
4393
4549
  }
4394
4550
  try {
4395
4551
  for (textBoxes_1 = __values(textBoxes), textBoxes_1_1 = textBoxes_1.next(); !textBoxes_1_1.done; textBoxes_1_1 = textBoxes_1.next()) {
@@ -4405,12 +4561,12 @@ var buildDrawingParts = function (_a) { return __awaiter(void 0, [_a], void 0, f
4405
4561
  frameId += 1;
4406
4562
  }
4407
4563
  }
4408
- catch (e_46_1) { e_46 = { error: e_46_1 }; }
4564
+ catch (e_48_1) { e_48 = { error: e_48_1 }; }
4409
4565
  finally {
4410
4566
  try {
4411
4567
  if (textBoxes_1_1 && !textBoxes_1_1.done && (_f = textBoxes_1.return)) _f.call(textBoxes_1);
4412
4568
  }
4413
- finally { if (e_46) throw e_46.error; }
4569
+ finally { if (e_48) throw e_48.error; }
4414
4570
  }
4415
4571
  try {
4416
4572
  for (shapes_1 = __values(shapes), shapes_1_1 = shapes_1.next(); !shapes_1_1.done; shapes_1_1 = shapes_1.next()) {
@@ -4426,12 +4582,12 @@ var buildDrawingParts = function (_a) { return __awaiter(void 0, [_a], void 0, f
4426
4582
  frameId += 1;
4427
4583
  }
4428
4584
  }
4429
- catch (e_47_1) { e_47 = { error: e_47_1 }; }
4585
+ catch (e_49_1) { e_49 = { error: e_49_1 }; }
4430
4586
  finally {
4431
4587
  try {
4432
4588
  if (shapes_1_1 && !shapes_1_1.done && (_g = shapes_1.return)) _g.call(shapes_1);
4433
4589
  }
4434
- finally { if (e_47) throw e_47.error; }
4590
+ finally { if (e_49) throw e_49.error; }
4435
4591
  }
4436
4592
  _m.label = 1;
4437
4593
  case 1:
@@ -4473,14 +4629,14 @@ var buildDrawingParts = function (_a) { return __awaiter(void 0, [_a], void 0, f
4473
4629
  return [3 /*break*/, 2];
4474
4630
  case 5: return [3 /*break*/, 8];
4475
4631
  case 6:
4476
- e_43_1 = _m.sent();
4477
- e_43 = { error: e_43_1 };
4632
+ e_45_1 = _m.sent();
4633
+ e_45 = { error: e_45_1 };
4478
4634
  return [3 /*break*/, 8];
4479
4635
  case 7:
4480
4636
  try {
4481
4637
  if (placements_1_1 && !placements_1_1.done && (_h = placements_1.return)) _h.call(placements_1);
4482
4638
  }
4483
- finally { if (e_43) throw e_43.error; }
4639
+ finally { if (e_45) throw e_45.error; }
4484
4640
  return [7 /*endfinally*/];
4485
4641
  case 8:
4486
4642
  orderedAnchors.sort(function (a, b) { return a.order - b.order; });
@@ -4490,12 +4646,12 @@ var buildDrawingParts = function (_a) { return __awaiter(void 0, [_a], void 0, f
4490
4646
  anchors.push(entry.xml);
4491
4647
  }
4492
4648
  }
4493
- catch (e_48_1) { e_48 = { error: e_48_1 }; }
4649
+ catch (e_50_1) { e_50 = { error: e_50_1 }; }
4494
4650
  finally {
4495
4651
  try {
4496
4652
  if (orderedAnchors_1_1 && !orderedAnchors_1_1.done && (_j = orderedAnchors_1.return)) _j.call(orderedAnchors_1);
4497
4653
  }
4498
- finally { if (e_48) throw e_48.error; }
4654
+ finally { if (e_50) throw e_50.error; }
4499
4655
  }
4500
4656
  drawingXml = "".concat(XML_DECLARATION, "<xdr:wsDr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"").concat(REL_NS, "\">").concat(anchors.join(""), "</xdr:wsDr>");
4501
4657
  return [2 /*return*/, {
@@ -4866,7 +5022,7 @@ var buildTextWithTabs = function (text, rPrXml) {
4866
5022
  .join("");
4867
5023
  };
4868
5024
  var buildTextBodyXml = function (spec) {
4869
- var e_49, _a;
5025
+ var e_51, _a;
4870
5026
  var richText = spec.richText || [];
4871
5027
  var plainText = spec.text || "";
4872
5028
  // Build vertical alignment and wrap attributes
@@ -4907,12 +5063,12 @@ var buildTextBodyXml = function (spec) {
4907
5063
  }
4908
5064
  }
4909
5065
  }
4910
- catch (e_49_1) { e_49 = { error: e_49_1 }; }
5066
+ catch (e_51_1) { e_51 = { error: e_51_1 }; }
4911
5067
  finally {
4912
5068
  try {
4913
5069
  if (richText_1_1 && !richText_1_1.done && (_a = richText_1.return)) _a.call(richText_1);
4914
5070
  }
4915
- finally { if (e_49) throw e_49.error; }
5071
+ finally { if (e_51) throw e_51.error; }
4916
5072
  }
4917
5073
  paragraphsXml = paragraphs
4918
5074
  .filter(function (runs) { return runs.length > 0; })
@@ -5340,7 +5496,7 @@ var buildCalcPrXml = function (iterativeCalculationOptions) {
5340
5496
  }
5341
5497
  return "<calcPr ".concat(attrs.join(" "), "/>");
5342
5498
  };
5343
- var buildWorkbookXml = function (sheets, sheetRelIds, sheetNames, namedRanges, iterativeCalculationOptions, slicerCacheRelIds, use1904, externalLinkRelIds, pivotCacheRelIds) {
5499
+ var buildWorkbookXml = function (sheets, sheetRelIds, sheetNames, namedRanges, iterativeCalculationOptions, slicerCacheRelIds, use1904, externalLinkRelIds, pivotCacheRelIds, workbookProtection) {
5344
5500
  if (slicerCacheRelIds === void 0) { slicerCacheRelIds = []; }
5345
5501
  if (use1904 === void 0) { use1904 = false; }
5346
5502
  if (externalLinkRelIds === void 0) { externalLinkRelIds = []; }
@@ -5409,10 +5565,57 @@ var buildWorkbookXml = function (sheets, sheetRelIds, sheetNames, namedRanges, i
5409
5565
  var workbookPrXml = use1904
5410
5566
  ? "<workbookPr date1904=\"1\"/>"
5411
5567
  : "<workbookPr/>";
5412
- return "".concat(XML_DECLARATION, "<workbook xmlns=\"").concat(WORKSHEET_NS, "\" xmlns:r=\"").concat(REL_NS, "\">").concat(workbookPrXml).concat(calcPrXml, "<bookViews><workbookView activeTab=\"0\" firstSheet=\"0\"/></bookViews><sheets>").concat(sheetEntries, "</sheets>").concat(definedNamesXml).concat(externalReferencesXml).concat(pivotCachesXml).concat(slicerCachesXml, "</workbook>");
5568
+ // `CT_Workbook` puts `<workbookProtection>` right after `<workbookPr>`.
5569
+ var workbookProtectionXml = buildWorkbookProtectionXml(workbookProtection);
5570
+ return "".concat(XML_DECLARATION, "<workbook xmlns=\"").concat(WORKSHEET_NS, "\" xmlns:r=\"").concat(REL_NS, "\">").concat(workbookPrXml).concat(workbookProtectionXml).concat(calcPrXml, "<bookViews><workbookView activeTab=\"0\" firstSheet=\"0\"/></bookViews><sheets>").concat(sheetEntries, "</sheets>").concat(definedNamesXml).concat(externalReferencesXml).concat(pivotCachesXml).concat(slicerCachesXml, "</workbook>");
5571
+ };
5572
+ /**
5573
+ * `<workbookProtection …/>` from the `workbookProtection` export prop: the
5574
+ * agile hash quartets first, then the legacy password hashes, then the lock
5575
+ * flags — Excel's own attribute order — writing only what the model carries
5576
+ * (flags as `"1"` / `"0"`), so an imported element round-trips verbatim. An
5577
+ * absent model or one with no attribute at all writes nothing. Twin of
5578
+ * `rnc-export`'s `workbook_protection_xml`.
5579
+ */
5580
+ var buildWorkbookProtectionXml = function (protection) {
5581
+ if (!protection)
5582
+ return "";
5583
+ var attrs = [];
5584
+ var text = function (name) {
5585
+ var value = protection[name];
5586
+ if (typeof value === "string" && value) {
5587
+ attrs.push("".concat(name, "=\"").concat(escapeXmlAttr(value), "\""));
5588
+ }
5589
+ };
5590
+ var count = function (name) {
5591
+ var value = protection[name];
5592
+ if (typeof value === "number" && Number.isFinite(value)) {
5593
+ attrs.push("".concat(name, "=\"").concat(Math.trunc(value), "\""));
5594
+ }
5595
+ };
5596
+ var flag = function (name) {
5597
+ var value = protection[name];
5598
+ if (typeof value === "boolean") {
5599
+ attrs.push("".concat(name, "=\"").concat(value ? 1 : 0, "\""));
5600
+ }
5601
+ };
5602
+ text("workbookAlgorithmName");
5603
+ text("workbookHashValue");
5604
+ text("workbookSaltValue");
5605
+ count("workbookSpinCount");
5606
+ text("revisionsAlgorithmName");
5607
+ text("revisionsHashValue");
5608
+ text("revisionsSaltValue");
5609
+ count("revisionsSpinCount");
5610
+ text("workbookPassword");
5611
+ text("revisionsPassword");
5612
+ flag("lockStructure");
5613
+ flag("lockWindows");
5614
+ flag("lockRevision");
5615
+ return attrs.length ? "<workbookProtection ".concat(attrs.join(" "), "/>") : "";
5413
5616
  };
5414
5617
  var buildDefinedNamesXml = function (namedRanges, sheetNameById, printScopes) {
5415
- var e_50, _a, e_51, _b;
5618
+ var e_52, _a, e_53, _b;
5416
5619
  var _d, _e, _f;
5417
5620
  if (printScopes === void 0) { printScopes = []; }
5418
5621
  var entries = [];
@@ -5442,12 +5645,12 @@ var buildDefinedNamesXml = function (namedRanges, sheetNameById, printScopes) {
5442
5645
  ], false));
5443
5646
  }
5444
5647
  }
5445
- catch (e_50_1) { e_50 = { error: e_50_1 }; }
5648
+ catch (e_52_1) { e_52 = { error: e_52_1 }; }
5446
5649
  finally {
5447
5650
  try {
5448
5651
  if (_h && !_h.done && (_a = _g.return)) _a.call(_g);
5449
5652
  }
5450
- finally { if (e_50) throw e_50.error; }
5653
+ finally { if (e_52) throw e_52.error; }
5451
5654
  }
5452
5655
  printScopes.forEach(function (_a, index) {
5453
5656
  var _b;
@@ -5468,12 +5671,35 @@ var buildDefinedNamesXml = function (namedRanges, sheetNameById, printScopes) {
5468
5671
  entries.push("<definedName name=\"".concat(PRINT_TITLES_NAME, "\" localSheetId=\"").concat(index, "\">").concat(escapeXmlText(titles), "</definedName>"));
5469
5672
  }
5470
5673
  });
5674
+ // A sheet-scoped name (`scopeSheetId`) is written with `localSheetId` = the
5675
+ // sheet's position in `<sheets>`; a scope that names no exported sheet
5676
+ // falls back to workbook scope. Excel allows one entry per (name, scope)
5677
+ // pair and repairs the workbook when a pair repeats, so a duplicate (two
5678
+ // scoped `LocalRange`s that both lost their scope, or a multi-area name
5679
+ // imported as one range per area) is written once.
5680
+ var localSheetIdAttr = function (namedRange) {
5681
+ var scope = namedRange.scopeSheetId;
5682
+ if (scope === undefined || scope === null)
5683
+ return "";
5684
+ var sheetName = sheetNameById.get(scope);
5685
+ var index = sheetName ? sheetIndexByName.get(sheetName) : undefined;
5686
+ return index == null ? "" : " localSheetId=\"".concat(index, "\"");
5687
+ };
5688
+ var seenNameScopes = new Set();
5689
+ var claimNameScope = function (name, localSheetId) {
5690
+ var key = "".concat(name.toLowerCase(), "|").concat(localSheetId);
5691
+ if (seenNameScopes.has(key))
5692
+ return false;
5693
+ seenNameScopes.add(key);
5694
+ return true;
5695
+ };
5471
5696
  try {
5472
5697
  for (var _j = __values(namedRanges !== null && namedRanges !== void 0 ? namedRanges : []), _k = _j.next(); !_k.done; _k = _j.next()) {
5473
5698
  var namedRange = _k.value;
5474
5699
  if (!(namedRange === null || namedRange === void 0 ? void 0 : namedRange.name) || isBuiltinPrintName(namedRange.name))
5475
5700
  continue;
5476
5701
  var hiddenAttr = namedRange.hidden ? " hidden=\"1\"" : "";
5702
+ var scopeAttr = localSheetIdAttr(namedRange);
5477
5703
  if ((_f = namedRange.range) === null || _f === void 0 ? void 0 : _f.sheetId) {
5478
5704
  var sheetName = sheetNameById.get(namedRange.range.sheetId);
5479
5705
  if (!sheetName)
@@ -5481,26 +5707,42 @@ var buildDefinedNamesXml = function (namedRanges, sheetNameById, printScopes) {
5481
5707
  var ref = cellRangeToAddress(undefined, namedRange.range);
5482
5708
  if (!ref)
5483
5709
  continue;
5710
+ if (!claimNameScope(namedRange.name, scopeAttr))
5711
+ continue;
5484
5712
  var address = "".concat(escapeSheetName(sheetName), "!").concat(toAbsoluteRef(ref));
5485
- entries.push("<definedName name=\"".concat(escapeXmlAttr(namedRange.name), "\"").concat(hiddenAttr, ">").concat(escapeXmlText(address), "</definedName>"));
5713
+ entries.push("<definedName name=\"".concat(escapeXmlAttr(namedRange.name), "\"").concat(scopeAttr).concat(hiddenAttr, ">").concat(escapeXmlText(address), "</definedName>"));
5486
5714
  continue;
5487
5715
  }
5716
+ // A constant name reaches us as text (`"Hello"`, `0.2`) or, when the
5717
+ // XML layer coerced it, as a number / boolean — both are the same
5718
+ // `<definedName>` body in Excel.
5488
5719
  var rawValue = namedRange.value;
5489
- if (typeof rawValue !== "string")
5720
+ var valueText = typeof rawValue === "string"
5721
+ ? rawValue
5722
+ : typeof rawValue === "number" || typeof rawValue === "boolean"
5723
+ ? String(rawValue)
5724
+ : undefined;
5725
+ if (valueText === undefined)
5490
5726
  continue;
5491
- var trimmed = rawValue.trim();
5727
+ var trimmed = valueText.trim();
5492
5728
  if (!trimmed)
5493
5729
  continue;
5494
5730
  var expression = trimmed.startsWith("=") ? trimmed.slice(1) : trimmed;
5495
- entries.push("<definedName name=\"".concat(escapeXmlAttr(namedRange.name), "\"").concat(hiddenAttr, ">").concat(escapeXmlText(expression), "</definedName>"));
5731
+ if (!claimNameScope(namedRange.name, scopeAttr))
5732
+ continue;
5733
+ // A formula-valued name (`Dbl` = `LAMBDA(x,x*2)`) is stored with the same
5734
+ // markers as a cell formula: `_xlfn.LAMBDA(_xlpm.x,_xlpm.x*2)`.
5735
+ entries.push("<definedName name=\"".concat(escapeXmlAttr(namedRange.name), "\"").concat(scopeAttr).concat(hiddenAttr, ">").concat(escapeXmlText(isAFormulaExpression(expression)
5736
+ ? sanitizeFormulaText(expression)
5737
+ : expression), "</definedName>"));
5496
5738
  }
5497
5739
  }
5498
- catch (e_51_1) { e_51 = { error: e_51_1 }; }
5740
+ catch (e_53_1) { e_53 = { error: e_53_1 }; }
5499
5741
  finally {
5500
5742
  try {
5501
5743
  if (_k && !_k.done && (_b = _j.return)) _b.call(_j);
5502
5744
  }
5503
- finally { if (e_51) throw e_51.error; }
5745
+ finally { if (e_53) throw e_53.error; }
5504
5746
  }
5505
5747
  if (!entries.length)
5506
5748
  return "";
@@ -5535,11 +5777,12 @@ var buildWorkbookSlicerCachesXml = function (slicerCacheRelIds) {
5535
5777
  };
5536
5778
  var buildWorkbookRelationships = function (
5537
5779
  /** One entry per sheet in `<sheets>` order; `target` is relative to `xl/`. */
5538
- sheetParts, slicerCacheCount, externalLinkCount, pivotCacheCount, hasPersons) {
5780
+ sheetParts, slicerCacheCount, externalLinkCount, pivotCacheCount, hasPersons, hasSheetMetadata) {
5539
5781
  if (slicerCacheCount === void 0) { slicerCacheCount = 0; }
5540
5782
  if (externalLinkCount === void 0) { externalLinkCount = 0; }
5541
5783
  if (pivotCacheCount === void 0) { pivotCacheCount = 0; }
5542
5784
  if (hasPersons === void 0) { hasPersons = false; }
5785
+ if (hasSheetMetadata === void 0) { hasSheetMetadata = false; }
5543
5786
  var relationships = [];
5544
5787
  var sheetRelIds = [];
5545
5788
  var slicerCacheRelIds = [];
@@ -5556,6 +5799,9 @@ sheetParts, slicerCacheCount, externalLinkCount, pivotCacheCount, hasPersons) {
5556
5799
  relationships.push("<Relationship Id=\"".concat(themeId, "\" Type=\"").concat(REL_NS, "/theme\" Target=\"theme/theme1.xml\"/>"));
5557
5800
  relationships.push("<Relationship Id=\"".concat(sharedStringsId, "\" Type=\"").concat(REL_NS, "/sharedStrings\" Target=\"sharedStrings.xml\"/>"));
5558
5801
  var nextRelId = sheetCount + 4;
5802
+ if (hasSheetMetadata) {
5803
+ relationships.push("<Relationship Id=\"rId".concat(nextRelId++, "\" Type=\"").concat(REL_NS, "/sheetMetadata\" Target=\"metadata.xml\"/>"));
5804
+ }
5559
5805
  for (var i = 0; i < slicerCacheCount; i++) {
5560
5806
  var relId = "rId".concat(nextRelId++);
5561
5807
  slicerCacheRelIds.push(relId);
@@ -5593,7 +5839,10 @@ sheetParts, slicerCacheCount, externalLinkCount, pivotCacheCount, hasPersons) {
5593
5839
  };
5594
5840
  };
5595
5841
  var buildContentTypesXml = function (_a) {
5596
- var worksheetCount = _a.worksheetCount, _b = _a.chartsheetCount, chartsheetCount = _b === void 0 ? 0 : _b, tableCount = _a.tableCount, drawingSheets = _a.drawingSheets, mediaExtensions = _a.mediaExtensions, chartCount = _a.chartCount, _d = _a.chartExCount, chartExCount = _d === void 0 ? 0 : _d, _e = _a.slicerCount, slicerCount = _e === void 0 ? 0 : _e, _f = _a.slicerCacheCount, slicerCacheCount = _f === void 0 ? 0 : _f, _g = _a.pivotTableCount, pivotTableCount = _g === void 0 ? 0 : _g, _h = _a.pivotCacheCount, pivotCacheCount = _h === void 0 ? 0 : _h, _j = _a.commentsSheets, commentsSheets = _j === void 0 ? [] : _j, _k = _a.threadedCommentsSheets, threadedCommentsSheets = _k === void 0 ? [] : _k, _l = _a.hasPersons, hasPersons = _l === void 0 ? false : _l, _m = _a.externalLinkCount, externalLinkCount = _m === void 0 ? 0 : _m, _o = _a.hasVmlDrawings, hasVmlDrawings = _o === void 0 ? false : _o, _p = _a.ctrlPropCount, ctrlPropCount = _p === void 0 ? 0 : _p;
5842
+ var worksheetCount = _a.worksheetCount, _b = _a.chartsheetCount, chartsheetCount = _b === void 0 ? 0 : _b, tableCount = _a.tableCount, drawingSheets = _a.drawingSheets, mediaExtensions = _a.mediaExtensions, chartCount = _a.chartCount, _d = _a.chartExCount, chartExCount = _d === void 0 ? 0 : _d, _e = _a.slicerCount, slicerCount = _e === void 0 ? 0 : _e, _f = _a.slicerCacheCount, slicerCacheCount = _f === void 0 ? 0 : _f, _g = _a.pivotTableCount, pivotTableCount = _g === void 0 ? 0 : _g, _h = _a.pivotCacheCount, pivotCacheCount = _h === void 0 ? 0 : _h, _j = _a.commentsSheets, commentsSheets = _j === void 0 ? [] : _j, _k = _a.threadedCommentsSheets, threadedCommentsSheets = _k === void 0 ? [] : _k, _l = _a.hasPersons, hasPersons = _l === void 0 ? false : _l, _m = _a.externalLinkCount, externalLinkCount = _m === void 0 ? 0 : _m, _o = _a.hasVmlDrawings, hasVmlDrawings = _o === void 0 ? false : _o, _p = _a.ctrlPropCount, ctrlPropCount = _p === void 0 ? 0 : _p, _q = _a.hasSheetMetadata, hasSheetMetadata = _q === void 0 ? false : _q;
5843
+ var metadataOverride = hasSheetMetadata
5844
+ ? "<Override PartName=\"/xl/metadata.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml\"/>"
5845
+ : "";
5597
5846
  var sheetOverrides = Array.from({ length: worksheetCount }, function (_, index) {
5598
5847
  return "<Override PartName=\"/xl/worksheets/sheet".concat(index + 1, ".xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>");
5599
5848
  }).join("");
@@ -5654,7 +5903,7 @@ var buildContentTypesXml = function (_a) {
5654
5903
  var ctrlPropOverrides = Array.from({ length: ctrlPropCount }, function (_, index) {
5655
5904
  return "<Override PartName=\"/xl/ctrlProps/ctrlProp".concat(index + 1, ".xml\" ContentType=\"").concat(CTRL_PROP_CONTENT_TYPE, "\"/>");
5656
5905
  }).join("");
5657
- return "".concat(XML_DECLARATION, "<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/><Default Extension=\"xml\" ContentType=\"application/xml\"/>").concat(vmlDefault).concat(mediaDefaults, "<Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>").concat(sheetOverrides).concat(chartsheetOverrides).concat(tableOverrides).concat(drawingOverrides).concat(chartOverrides).concat(chartExOverrides).concat(slicerOverrides).concat(slicerCacheOverrides).concat(pivotTableOverrides).concat(pivotCacheOverrides).concat(externalLinkOverrides).concat(ctrlPropOverrides).concat(commentsOverrides).concat(threadedCommentsOverrides).concat(personOverride, "<Override PartName=\"/xl/theme/theme1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.theme+xml\"/><Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/><Override PartName=\"/xl/sharedStrings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml\"/><Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/><Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/></Types>");
5906
+ return "".concat(XML_DECLARATION, "<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/><Default Extension=\"xml\" ContentType=\"application/xml\"/>").concat(vmlDefault).concat(mediaDefaults, "<Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>").concat(sheetOverrides).concat(chartsheetOverrides).concat(tableOverrides).concat(drawingOverrides).concat(chartOverrides).concat(chartExOverrides).concat(slicerOverrides).concat(slicerCacheOverrides).concat(pivotTableOverrides).concat(pivotCacheOverrides).concat(externalLinkOverrides).concat(ctrlPropOverrides).concat(commentsOverrides).concat(threadedCommentsOverrides).concat(personOverride).concat(metadataOverride, "<Override PartName=\"/xl/theme/theme1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.theme+xml\"/><Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/><Override PartName=\"/xl/sharedStrings.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml\"/><Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/><Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/></Types>");
5658
5907
  };
5659
5908
  var buildRootRelationshipsXml = function () {
5660
5909
  return "".concat(XML_DECLARATION, "<Relationships xmlns=\"").concat(PACKAGE_REL_NS, "\"><Relationship Id=\"rId1\" Type=\"").concat(REL_NS, "/officeDocument\" Target=\"xl/workbook.xml\"/><Relationship Id=\"rId2\" Type=\"").concat(REL_NS, "/extended-properties\" Target=\"docProps/app.xml\"/><Relationship Id=\"rId3\" Type=\"").concat(REL_NS, "/core-properties\" Target=\"docProps/core.xml\"/></Relationships>");