@odoo/o-spreadsheet 18.3.18 → 18.3.20

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.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 18.3.18
6
- * @date 2025-08-26T10:14:21.408Z
7
- * @hash ec2777d
5
+ * @version 18.3.20
6
+ * @date 2025-09-11T08:45:37.934Z
7
+ * @hash ef829f4
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -3497,6 +3497,7 @@ const invalidateBordersCommands = new Set([
3497
3497
  "AUTOFILL_CELL",
3498
3498
  "SET_BORDER",
3499
3499
  "SET_ZONE_BORDERS",
3500
+ "SET_BORDERS_ON_TARGET",
3500
3501
  ]);
3501
3502
  const readonlyAllowedCommands = new Set([
3502
3503
  "START",
@@ -6442,40 +6443,44 @@ function orderRange(range) {
6442
6443
  };
6443
6444
  }
6444
6445
  function getRangeAdapter(cmd) {
6445
- switch (cmd.type) {
6446
- case "REMOVE_COLUMNS_ROWS":
6447
- return {
6448
- applyChange: getApplyRangeChangeRemoveColRow(cmd),
6449
- sheetId: cmd.sheetId,
6450
- sheetName: cmd.sheetName,
6451
- };
6452
- case "ADD_COLUMNS_ROWS":
6453
- return {
6454
- applyChange: getApplyRangeChangeAddColRow(cmd),
6455
- sheetId: cmd.sheetId,
6456
- sheetName: cmd.sheetName,
6457
- };
6458
- case "DELETE_SHEET":
6459
- return {
6460
- applyChange: getApplyRangeChangeDeleteSheet(cmd),
6461
- sheetId: cmd.sheetId,
6462
- sheetName: cmd.sheetName,
6463
- };
6464
- case "RENAME_SHEET":
6465
- return {
6466
- applyChange: getApplyRangeChangeRenameSheet(cmd),
6467
- sheetId: cmd.sheetId,
6468
- sheetName: cmd.oldName,
6469
- };
6470
- case "MOVE_RANGES":
6471
- return {
6472
- applyChange: getApplyRangeChangeMoveRange(cmd),
6473
- sheetId: cmd.sheetId,
6474
- sheetName: cmd.sheetName,
6475
- };
6446
+ return rangeAdapterRegistry.get(cmd.type)?.(cmd);
6447
+ }
6448
+ class RangeAdapterRegistry extends Registry {
6449
+ add(cmdType, fn) {
6450
+ super.add(cmdType, fn);
6451
+ return this;
6452
+ }
6453
+ get(cmdType) {
6454
+ return this.content[cmdType];
6476
6455
  }
6477
- return undefined;
6478
6456
  }
6457
+ const rangeAdapterRegistry = new RangeAdapterRegistry();
6458
+ rangeAdapterRegistry
6459
+ .add("REMOVE_COLUMNS_ROWS", (cmd) => ({
6460
+ applyChange: getApplyRangeChangeRemoveColRow(cmd),
6461
+ sheetId: cmd.sheetId,
6462
+ sheetName: { old: cmd.sheetName, current: cmd.sheetName },
6463
+ }))
6464
+ .add("ADD_COLUMNS_ROWS", (cmd) => ({
6465
+ applyChange: getApplyRangeChangeAddColRow(cmd),
6466
+ sheetId: cmd.sheetId,
6467
+ sheetName: { old: cmd.sheetName, current: cmd.sheetName },
6468
+ }))
6469
+ .add("DELETE_SHEET", (cmd) => ({
6470
+ applyChange: getApplyRangeChangeDeleteSheet(cmd),
6471
+ sheetId: cmd.sheetId,
6472
+ sheetName: { old: cmd.sheetName, current: cmd.sheetName },
6473
+ }))
6474
+ .add("RENAME_SHEET", (cmd) => ({
6475
+ applyChange: getApplyRangeChangeRenameSheet(cmd),
6476
+ sheetId: cmd.sheetId,
6477
+ sheetName: { old: cmd.oldName, current: cmd.newName },
6478
+ }))
6479
+ .add("MOVE_RANGES", (cmd) => ({
6480
+ applyChange: getApplyRangeChangeMoveRange(cmd),
6481
+ sheetId: cmd.sheetId,
6482
+ sheetName: { old: cmd.sheetName, current: cmd.sheetName },
6483
+ }));
6479
6484
  function getApplyRangeChangeRemoveColRow(cmd) {
6480
6485
  let start = cmd.dimension === "COL" ? "left" : "top";
6481
6486
  let end = cmd.dimension === "COL" ? "right" : "bottom";
@@ -7202,7 +7207,7 @@ class ClipboardHandler {
7202
7207
  this.getters = getters;
7203
7208
  this.dispatch = dispatch;
7204
7209
  }
7205
- copy(data, isCutOperation) {
7210
+ copy(data, isCutOperation, mode = "copyPaste") {
7206
7211
  return;
7207
7212
  }
7208
7213
  paste(target, clippedContent, options) { }
@@ -7221,7 +7226,7 @@ class ClipboardHandler {
7221
7226
  }
7222
7227
 
7223
7228
  class AbstractCellClipboardHandler extends ClipboardHandler {
7224
- copy(data) {
7229
+ copy(data, isCutOperation, mode = "copyPaste") {
7225
7230
  return;
7226
7231
  }
7227
7232
  pasteFromCopy(sheetId, target, content, options) {
@@ -7826,8 +7831,11 @@ function invertMatrix(M) {
7826
7831
  // (a) Swap 2 rows. This multiply the determinant by -1.
7827
7832
  // (b) Multiply a row by a scalar. This multiply the determinant by that scalar.
7828
7833
  // (c) Add to a row a multiple of another row. This does not change the determinant.
7834
+ if (M.length < 1 || M[0].length < 1) {
7835
+ throw new Error("invertMatrix: an empty matrix cannot be inverted.");
7836
+ }
7829
7837
  if (M.length !== M[0].length) {
7830
- throw new EvaluationError(_t("Function [[FUNCTION_NAME]] invert matrix error, only square matrices are invertible"));
7838
+ throw new Error("invertMatrix: only square matrices are invertible");
7831
7839
  }
7832
7840
  let determinant = 1;
7833
7841
  const dim = M.length;
@@ -7896,8 +7904,11 @@ function swapMatrixRows(matrix, row1, row2) {
7896
7904
  * Note: we use indexing [col][row] instead of the standard mathematical notation [row][col]
7897
7905
  */
7898
7906
  function multiplyMatrices(matrix1, matrix2) {
7907
+ if (matrix1.length < 1 || matrix2.length < 1) {
7908
+ throw new Error("multiplyMatrices: empty matrices cannot be multiplied.");
7909
+ }
7899
7910
  if (matrix1.length !== matrix2[0].length) {
7900
- throw new EvaluationError(_t("Cannot multiply matrices : incompatible matrices size."));
7911
+ throw new Error("multiplyMatrices: incompatible matrices size.");
7901
7912
  }
7902
7913
  const rowsM1 = matrix1[0].length;
7903
7914
  const colsM2 = matrix2.length;
@@ -7923,7 +7934,7 @@ function toScalar(arg) {
7923
7934
  return arg;
7924
7935
  }
7925
7936
  if (!isSingleElementMatrix(arg)) {
7926
- throw new EvaluationError(_t("The value should be a scalar or a 1x1 matrix"));
7937
+ throw new Error("The value should be a scalar or a 1x1 matrix");
7927
7938
  }
7928
7939
  return arg[0][0];
7929
7940
  }
@@ -8160,6 +8171,16 @@ function getMovingAverageValues(dataset, labels, windowSize = DEFAULT_WINDOW_SIZ
8160
8171
  }
8161
8172
  return values;
8162
8173
  }
8174
+ function assertNonEmptyMatrix(matrix, argName) {
8175
+ assert(() => matrix.length > 0 && matrix[0].length > 0, _t("[[FUNCTION_NAME]] expects the provided values of %(argName)s to be a non-empty matrix.", {
8176
+ argName,
8177
+ }));
8178
+ }
8179
+ function assertNonEmpty(...data) {
8180
+ if (data.length === 0 || data.some((arg) => arg.length === 0)) {
8181
+ throw new NotAvailableError(_t("[[FUNCTION_NAME]] has no valid input data."));
8182
+ }
8183
+ }
8163
8184
 
8164
8185
  const PREVIOUS_VALUE = "(previous)";
8165
8186
  const NEXT_VALUE = "(next)";
@@ -8928,7 +8949,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
8928
8949
  }
8929
8950
  return "Success" /* CommandResult.Success */;
8930
8951
  }
8931
- copy(data) {
8952
+ copy(data, isCutOperation, mode = "copyPaste") {
8932
8953
  const sheetId = data.sheetId;
8933
8954
  const { clippedZones, rowsIndexes, columnsIndexes } = data;
8934
8955
  const clippedCells = [];
@@ -8941,7 +8962,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
8941
8962
  const evaluatedCell = this.getters.getEvaluatedCell(position);
8942
8963
  const pivotId = this.getters.getPivotIdFromPosition(position);
8943
8964
  const spreader = this.getters.getArrayFormulaSpreadingOn(position);
8944
- if (pivotId && spreader) {
8965
+ if (mode !== "shiftCells" && pivotId && spreader) {
8945
8966
  const pivotZone = this.getters.getSpreadZone(spreader);
8946
8967
  if ((!deepEquals(spreader, position) || !isCopyingOneCell) &&
8947
8968
  pivotZone &&
@@ -8959,7 +8980,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
8959
8980
  };
8960
8981
  }
8961
8982
  }
8962
- else {
8983
+ else if (mode !== "shiftCells") {
8963
8984
  if (spreader && !deepEquals(spreader, position)) {
8964
8985
  const isSpreaderCopied = rowsIndexes.includes(spreader.row) && columnsIndexes.includes(spreader.col);
8965
8986
  const content = isSpreaderCopied
@@ -9659,7 +9680,7 @@ class SheetClipboardHandler extends AbstractCellClipboardHandler {
9659
9680
  }
9660
9681
 
9661
9682
  class TableClipboardHandler extends AbstractCellClipboardHandler {
9662
- copy(data, isCutOperation) {
9683
+ copy(data, isCutOperation, mode = "copyPaste") {
9663
9684
  const sheetId = data.sheetId;
9664
9685
  const { rowsIndexes, columnsIndexes, zones } = data;
9665
9686
  const copiedTablesIds = new Set();
@@ -9697,11 +9718,13 @@ class TableClipboardHandler extends AbstractCellClipboardHandler {
9697
9718
  type: coreTable.type,
9698
9719
  };
9699
9720
  }
9700
- tableCellsInRow.push({
9701
- table: copiedTable,
9702
- style: this.getTableStyleToCopy(position),
9703
- isWholeTableCopied: copiedTablesIds.has(table.id),
9704
- });
9721
+ if (mode !== "shiftCells") {
9722
+ tableCellsInRow.push({
9723
+ table: copiedTable,
9724
+ style: this.getTableStyleToCopy(position),
9725
+ isWholeTableCopied: copiedTablesIds.has(table.id),
9726
+ });
9727
+ }
9705
9728
  }
9706
9729
  }
9707
9730
  return {
@@ -10983,6 +11006,7 @@ const MMULT = {
10983
11006
  compute: function (matrix1, matrix2) {
10984
11007
  const _matrix1 = toNumberMatrix(matrix1, "matrix1");
10985
11008
  const _matrix2 = toNumberMatrix(matrix2, "matrix2");
11009
+ assert(() => _matrix1.length > 0 && _matrix2.length > 0, _t("The first and second arguments of [[FUNCTION_NAME]] must be non-empty matrices."));
10986
11010
  assert(() => _matrix1.length === _matrix2[0].length, _t("In [[FUNCTION_NAME]], the number of columns of the first matrix (%s) must be equal to the \
10987
11011
  number of rows of the second matrix (%s).", _matrix1.length.toString(), _matrix2[0].length.toString()));
10988
11012
  return multiplyMatrices(_matrix1, _matrix2);
@@ -12778,6 +12802,7 @@ const FORECAST = {
12778
12802
  ],
12779
12803
  compute: function (x, dataY, dataX) {
12780
12804
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
12805
+ assertNonEmpty(flatDataX, flatDataY);
12781
12806
  return predictLinearValues([flatDataY], [flatDataX], matrixMap(toMatrix(x), (value) => toNumber(value, this.locale)), true);
12782
12807
  },
12783
12808
  isExported: true,
@@ -12794,6 +12819,7 @@ const GROWTH = {
12794
12819
  arg("b (boolean, default=TRUE)", _t("Given a general exponential form of y = b*m^x for a curve fit, calculates b if TRUE or forces b to be 1 and only calculates the m values if FALSE.")),
12795
12820
  ],
12796
12821
  compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
12822
+ assertNonEmptyMatrix(knownDataY, "known_data_y");
12797
12823
  return expM(predictLinearValues(logM(toNumberMatrix(knownDataY, "the first argument (known_data_y)")), toNumberMatrix(knownDataX, "the second argument (known_data_x)"), toNumberMatrix(newDataX, "the third argument (new_data_y)"), toBoolean(b)));
12798
12824
  },
12799
12825
  };
@@ -12808,6 +12834,7 @@ const INTERCEPT = {
12808
12834
  ],
12809
12835
  compute: function (dataY, dataX) {
12810
12836
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
12837
+ assertNonEmpty(flatDataX, flatDataY);
12811
12838
  const [[], [intercept]] = fullLinearRegression([flatDataX], [flatDataY]);
12812
12839
  return intercept;
12813
12840
  },
@@ -12857,6 +12884,7 @@ const LINEST = {
12857
12884
  arg("verbose (boolean, default=FALSE)", _t("A flag specifying whether to return additional regression statistics or only the linear coefficients and the y-intercept")),
12858
12885
  ],
12859
12886
  compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
12887
+ assertNonEmptyMatrix(dataY, "data_y");
12860
12888
  return fullLinearRegression(toNumberMatrix(dataX, "the first argument (data_y)"), toNumberMatrix(dataY, "the second argument (data_x)"), toBoolean(calculateB), toBoolean(verbose));
12861
12889
  },
12862
12890
  isExported: true,
@@ -12873,6 +12901,7 @@ const LOGEST = {
12873
12901
  arg("verbose (boolean, default=FALSE)", _t("A flag specifying whether to return additional regression statistics or only the linear coefficients and the y-intercept")),
12874
12902
  ],
12875
12903
  compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
12904
+ assertNonEmptyMatrix(dataY, "data_y");
12876
12905
  const coeffs = fullLinearRegression(toNumberMatrix(dataX, "the second argument (data_x)"), logM(toNumberMatrix(dataY, "the first argument (data_y)")), toBoolean(calculateB), toBoolean(verbose));
12877
12906
  for (let i = 0; i < coeffs.length; i++) {
12878
12907
  coeffs[i][0] = Math.exp(coeffs[i][0]);
@@ -12894,9 +12923,7 @@ const MATTHEWS = {
12894
12923
  const flatX = dataX.flat();
12895
12924
  const flatY = dataY.flat();
12896
12925
  assertSameNumberOfElements(flatX, flatY);
12897
- if (flatX.length === 0) {
12898
- return new EvaluationError(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
12899
- }
12926
+ assertNonEmpty(flatX, flatY);
12900
12927
  const n = flatX.length;
12901
12928
  let trueN = 0, trueP = 0, falseP = 0, falseN = 0;
12902
12929
  for (let i = 0; i < n; ++i) {
@@ -13060,12 +13087,7 @@ const MINIFS = {
13060
13087
  // -----------------------------------------------------------------------------
13061
13088
  function pearson(dataY, dataX) {
13062
13089
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13063
- if (flatDataX.length === 0) {
13064
- throw new EvaluationError(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
13065
- }
13066
- if (flatDataX.length < 2) {
13067
- throw new EvaluationError(_t("[[FUNCTION_NAME]] needs at least two values for both parameters."));
13068
- }
13090
+ assertNonEmpty(flatDataX, flatDataY);
13069
13091
  const n = flatDataX.length;
13070
13092
  let sumX = 0, sumY = 0, sumXY = 0, sumXX = 0, sumYY = 0;
13071
13093
  for (let i = 0; i < n; i++) {
@@ -13154,6 +13176,7 @@ const POLYFIT_COEFFS = {
13154
13176
  ],
13155
13177
  compute: function (dataY, dataX, order, intercept = { value: true }) {
13156
13178
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13179
+ assertNonEmpty(flatDataX, flatDataY);
13157
13180
  return polynomialRegression(flatDataY, flatDataX, toNumber(order, this.locale), toBoolean(intercept));
13158
13181
  },
13159
13182
  isExported: false,
@@ -13173,6 +13196,7 @@ const POLYFIT_FORECAST = {
13173
13196
  compute: function (x, dataY, dataX, order, intercept = { value: true }) {
13174
13197
  const _order = toNumber(order, this.locale);
13175
13198
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13199
+ assertNonEmpty(flatDataX, flatDataY);
13176
13200
  const coeffs = polynomialRegression(flatDataY, flatDataX, _order, toBoolean(intercept)).flat();
13177
13201
  return matrixMap(toMatrix(x), (xij) => evaluatePolynomial(coeffs, toNumber(xij, this.locale), _order));
13178
13202
  },
@@ -13289,6 +13313,7 @@ const SLOPE = {
13289
13313
  ],
13290
13314
  compute: function (dataY, dataX) {
13291
13315
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13316
+ assertNonEmpty(flatDataX, flatDataY);
13292
13317
  const [[slope]] = fullLinearRegression([flatDataX], [flatDataY]);
13293
13318
  return slope;
13294
13319
  },
@@ -13337,6 +13362,7 @@ const SPEARMAN = {
13337
13362
  ],
13338
13363
  compute: function (dataX, dataY) {
13339
13364
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13365
+ assertNonEmpty(flatDataX, flatDataY);
13340
13366
  const n = flatDataX.length;
13341
13367
  const order = flatDataX.map((e, i) => [e, flatDataY[i]]);
13342
13368
  order.sort((a, b) => a[0] - b[0]);
@@ -13447,6 +13473,7 @@ const STEYX = {
13447
13473
  ],
13448
13474
  compute: function (dataY, dataX) {
13449
13475
  const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
13476
+ assertNonEmpty(flatDataX, flatDataY);
13450
13477
  const data = fullLinearRegression([flatDataX], [flatDataY], true, true);
13451
13478
  return data[1][2];
13452
13479
  },
@@ -13464,6 +13491,7 @@ const TREND = {
13464
13491
  arg("b (boolean, optional, default=TRUE)", _t("Given a general linear form of y = m*x+b for a curve fit, calculates b if TRUE or forces b to be 0 and only calculates the m values if FALSE, i.e. forces the curve fit to pass through the origin.")),
13465
13492
  ],
13466
13493
  compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
13494
+ assertNonEmptyMatrix(knownDataY, "known_data_y");
13467
13495
  return predictLinearValues(toNumberMatrix(knownDataY, "the first argument (known_data_y)"), toNumberMatrix(knownDataX, "the second argument (known_data_x)"), toNumberMatrix(newDataX, "the third argument (new_data_y)"), toBoolean(b));
13468
13496
  },
13469
13497
  };
@@ -20600,7 +20628,7 @@ function adaptFormulaStringRanges(defaultSheetId, formula, applyChange) {
20600
20628
  function adaptStringRange(defaultSheetId, sheetXC, applyChange) {
20601
20629
  const sheetName = splitReference(sheetXC).sheetName;
20602
20630
  if (sheetName
20603
- ? !isSheetNameEqual(sheetName, applyChange.sheetName)
20631
+ ? !isSheetNameEqual(sheetName, applyChange.sheetName.old)
20604
20632
  : defaultSheetId !== applyChange.sheetId) {
20605
20633
  return sheetXC;
20606
20634
  }
@@ -20617,7 +20645,7 @@ function adaptStringRange(defaultSheetId, sheetXC, applyChange) {
20617
20645
  }
20618
20646
  function getSheetNameGetter(applyChange) {
20619
20647
  return (sheetId) => {
20620
- return sheetId === applyChange.sheetId ? applyChange.sheetName : "";
20648
+ return sheetId === applyChange.sheetId ? applyChange.sheetName.current : "";
20621
20649
  };
20622
20650
  }
20623
20651
  function defaultGetSheetSize(sheetId) {
@@ -27580,9 +27608,13 @@ class GaugeChart extends AbstractChart {
27580
27608
  : undefined,
27581
27609
  };
27582
27610
  }
27583
- updateRanges(applyChange) {
27611
+ updateRanges(applyChange, sheetId, adaptSheetName) {
27584
27612
  const dataRange = adaptChartRange(this.dataRange, applyChange);
27585
- const adaptFormula = (formula) => this.getters.adaptFormulaStringDependencies(this.sheetId, formula, applyChange);
27613
+ const adaptFormula = (formula) => adaptFormulaStringRanges(this.sheetId, formula, {
27614
+ applyChange,
27615
+ sheetId,
27616
+ sheetName: adaptSheetName,
27617
+ });
27586
27618
  const sectionRule = adaptSectionRuleFormulas(this.sectionRule, adaptFormula);
27587
27619
  const definition = this.getDefinitionWithSpecificRanges(dataRange, sectionRule);
27588
27620
  return new GaugeChart(definition, this.sheetId, this.getters);
@@ -30209,7 +30241,8 @@ const inverseCommandRegistry = new Registry()
30209
30241
  .add("HIDE_COLUMNS_ROWS", inverseHideColumnsRows)
30210
30242
  .add("UNHIDE_COLUMNS_ROWS", inverseUnhideColumnsRows)
30211
30243
  .add("CREATE_TABLE_STYLE", inverseCreateTableStyle)
30212
- .add("ADD_PIVOT", inverseAddPivot);
30244
+ .add("ADD_PIVOT", inverseAddPivot)
30245
+ .add("RENAME_SHEET", inverseRenameSheet);
30213
30246
  for (const cmd of coreTypes.values()) {
30214
30247
  if (!inverseCommandRegistry.contains(cmd)) {
30215
30248
  inverseCommandRegistry.add(cmd, identity);
@@ -30307,6 +30340,16 @@ function inverseUnhideColumnsRows(cmd) {
30307
30340
  function inverseCreateTableStyle(cmd) {
30308
30341
  return [{ type: "REMOVE_TABLE_STYLE", tableStyleId: cmd.tableStyleId }];
30309
30342
  }
30343
+ function inverseRenameSheet(cmd) {
30344
+ return [
30345
+ {
30346
+ type: "RENAME_SHEET",
30347
+ sheetId: cmd.sheetId,
30348
+ oldName: cmd.newName,
30349
+ newName: cmd.oldName,
30350
+ },
30351
+ ];
30352
+ }
30310
30353
 
30311
30354
  /**
30312
30355
  * The class Registry is extended in order to add the function addChild
@@ -30843,7 +30886,7 @@ const SUPPORTED_HORIZONTAL_ALIGNMENTS = [
30843
30886
  ];
30844
30887
  const SUPPORTED_VERTICAL_ALIGNMENTS = ["top", "center", "bottom"];
30845
30888
  const SUPPORTED_FONTS = ["Arial"];
30846
- const SUPPORTED_FILL_PATTERNS = ["solid"];
30889
+ const SUPPORTED_FILL_PATTERNS = ["solid", "none"];
30847
30890
  const SUPPORTED_CF_TYPES = [
30848
30891
  "expression",
30849
30892
  "cellIs",
@@ -31028,7 +31071,7 @@ const SUBTOTAL_FUNCTION_CONVERSION_MAP = {
31028
31071
  };
31029
31072
  /** Mapping between Excel format indexes (see XLSX_FORMAT_MAP) and some supported formats */
31030
31073
  const XLSX_FORMATS_CONVERSION_MAP = {
31031
- 0: "",
31074
+ 0: "General",
31032
31075
  1: "0",
31033
31076
  2: "0.00",
31034
31077
  3: "#,#00",
@@ -31354,11 +31397,11 @@ const XLSX_DATE_FORMAT_REGEX = /^(yy|yyyy|m{1,5}|d{1,4}|h{1,2}|s{1,2}|am\/pm|a\/
31354
31397
  * Excel format are defined in openXML §18.8.31
31355
31398
  */
31356
31399
  function convertXlsxFormat(numFmtId, formats, warningManager) {
31357
- if (numFmtId === 0) {
31358
- return undefined;
31359
- }
31360
31400
  // Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
31361
31401
  let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || formats.find((f) => f.id === numFmtId)?.format;
31402
+ if (format === "General") {
31403
+ return undefined;
31404
+ }
31362
31405
  if (format) {
31363
31406
  try {
31364
31407
  let convertedFormat = format.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
@@ -31556,9 +31599,9 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
31556
31599
  if (!rule.operator || !rule.formula || rule.formula.length === 0)
31557
31600
  continue;
31558
31601
  operator = convertCFCellIsOperator(rule.operator);
31559
- values.push(rule.formula[0]);
31602
+ values.push(prefixFormula(rule.formula[0]));
31560
31603
  if (rule.formula.length === 2) {
31561
- values.push(rule.formula[1]);
31604
+ values.push(prefixFormula(rule.formula[1]));
31562
31605
  }
31563
31606
  break;
31564
31607
  }
@@ -31716,6 +31759,11 @@ function convertIcons(xlsxIconSet, index) {
31716
31759
  ? ICON_SETS[iconSet].neutral
31717
31760
  : ICON_SETS[iconSet].good;
31718
31761
  }
31762
+ /** Prefix the string by "=" if the string looks like a formula */
31763
+ function prefixFormula(formula) {
31764
+ const tokens = tokenize(formula);
31765
+ return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
31766
+ }
31719
31767
  // ---------------------------------------------------------------------------
31720
31768
  // Warnings
31721
31769
  // ---------------------------------------------------------------------------
@@ -31978,7 +32026,7 @@ function getColPosition(colIndex, sheetData) {
31978
32026
  function getRowPosition(rowIndex, sheetData) {
31979
32027
  let position = 0;
31980
32028
  for (let i = 0; i < rowIndex; i++) {
31981
- const rowAtIndex = sheetData.rows[i];
32029
+ const rowAtIndex = sheetData.rows.find((row) => row.index - 1 === i);
31982
32030
  if (rowAtIndex?.height) {
31983
32031
  position += rowAtIndex.height;
31984
32032
  }
@@ -32118,8 +32166,8 @@ function convertExcelRangeToSheetXC(range, dataSetsHaveTitle) {
32118
32166
  }
32119
32167
  function convertAnchor(XLSXanchor) {
32120
32168
  const offset = {
32121
- x: convertEMUToDotValue(XLSXanchor.colOffset),
32122
- y: convertEMUToDotValue(XLSXanchor.rowOffset),
32169
+ x: convertEMUToDotValue(XLSXanchor.colOffset) - FIGURE_BORDER_WIDTH,
32170
+ y: convertEMUToDotValue(XLSXanchor.rowOffset) - FIGURE_BORDER_WIDTH,
32123
32171
  };
32124
32172
  return { col: XLSXanchor.col, row: XLSXanchor.row, offset };
32125
32173
  }
@@ -32502,8 +32550,12 @@ function getSheetDims(sheet) {
32502
32550
  dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
32503
32551
  dims[1] = Math.max(dims[1], row.index);
32504
32552
  }
32505
- dims[0] = Math.max(dims[0], EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
32506
- dims[1] = Math.max(dims[1], EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS);
32553
+ for (const fig of sheet.figures) {
32554
+ dims[0] = Math.max(dims[0], fig.anchors[fig.anchors.length - 1]?.col ?? 0);
32555
+ dims[1] = Math.max(dims[1], fig.anchors[fig.anchors.length - 1]?.row ?? 0);
32556
+ }
32557
+ dims[0] = Math.max(dims[0] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
32558
+ dims[1] = Math.max(dims[1] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS);
32507
32559
  return dims;
32508
32560
  }
32509
32561
  /**
@@ -34194,10 +34246,11 @@ class XlsxSheetExtractor extends XlsxBaseExtractor {
34194
34246
  });
34195
34247
  }
34196
34248
  extractRows(worksheet) {
34249
+ const spilledCells = new Set();
34197
34250
  return this.mapOnElements({ parent: worksheet, query: "sheetData row" }, (rowElement) => {
34198
34251
  return {
34199
34252
  index: this.extractAttr(rowElement, "r", { required: true })?.asNum(),
34200
- cells: this.extractCells(rowElement),
34253
+ cells: this.extractCells(rowElement, spilledCells),
34201
34254
  height: this.extractAttr(rowElement, "ht")?.asNum(),
34202
34255
  customHeight: this.extractAttr(rowElement, "customHeight")?.asBool(),
34203
34256
  hidden: this.extractAttr(rowElement, "hidden")?.asBool(),
@@ -34207,14 +34260,26 @@ class XlsxSheetExtractor extends XlsxBaseExtractor {
34207
34260
  };
34208
34261
  });
34209
34262
  }
34210
- extractCells(row) {
34263
+ extractCells(row, spilledCells) {
34211
34264
  return this.mapOnElements({ parent: row, query: "c" }, (cellElement) => {
34265
+ const xc = this.extractAttr(cellElement, "r", { required: true })?.asString();
34266
+ const formula = this.extractCellFormula(cellElement);
34267
+ if (formula?.ref && formula.sharedIndex === undefined) {
34268
+ const zone = toZone(formula.ref);
34269
+ for (const { col, row } of positions(zone)) {
34270
+ const followerXc = toXC(col, row);
34271
+ if (followerXc !== xc) {
34272
+ spilledCells.add(followerXc);
34273
+ }
34274
+ }
34275
+ }
34276
+ const isSpilled = spilledCells.has(xc);
34212
34277
  return {
34213
- xc: this.extractAttr(cellElement, "r", { required: true })?.asString(),
34278
+ xc,
34214
34279
  styleIndex: this.extractAttr(cellElement, "s")?.asNum(),
34215
34280
  type: CELL_TYPE_CONVERSION_MAP[this.extractAttr(cellElement, "t", { default: "n" })?.asString()],
34216
- value: this.extractChildTextContent(cellElement, "v"),
34217
- formula: this.extractCellFormula(cellElement),
34281
+ value: isSpilled ? undefined : this.extractChildTextContent(cellElement, "v") ?? undefined,
34282
+ formula: isSpilled ? undefined : formula,
34218
34283
  };
34219
34284
  });
34220
34285
  }
@@ -34222,11 +34287,14 @@ class XlsxSheetExtractor extends XlsxBaseExtractor {
34222
34287
  const formulaElement = this.querySelector(cellElement, "f");
34223
34288
  if (!formulaElement)
34224
34289
  return undefined;
34225
- return {
34226
- content: this.extractTextContent(formulaElement),
34227
- sharedIndex: this.extractAttr(formulaElement, "si")?.asNum(),
34228
- ref: this.extractAttr(formulaElement, "ref")?.asString(),
34229
- };
34290
+ const content = this.extractTextContent(formulaElement);
34291
+ const sharedIndex = this.extractAttr(formulaElement, "si")?.asNum();
34292
+ const ref = this.extractAttr(formulaElement, "ref")?.asString();
34293
+ // This is the case of spilled cells of array formulas where <f> is empty
34294
+ if ((content === undefined || content.trim() === "") && sharedIndex === undefined) {
34295
+ return undefined;
34296
+ }
34297
+ return { content, sharedIndex, ref };
34230
34298
  }
34231
34299
  extractHyperLinks(worksheet) {
34232
34300
  return this.mapOnElements({ parent: worksheet, query: "hyperlink" }, (linkElement) => {
@@ -34508,7 +34576,7 @@ function getRelationFile(file, xmls) {
34508
34576
  return relsFile;
34509
34577
  }
34510
34578
 
34511
- const EXCEL_IMPORT_VERSION = "18.3";
34579
+ const EXCEL_IMPORT_VERSION = "18.3.1";
34512
34580
  class XlsxReader {
34513
34581
  warningManager;
34514
34582
  xmls;
@@ -38512,7 +38580,7 @@ const splitToColumns = {
38512
38580
  const reinsertDynamicPivotMenu = {
38513
38581
  id: "reinsert_dynamic_pivot",
38514
38582
  name: _t("Re-insert dynamic pivot"),
38515
- sequence: 1020,
38583
+ sequence: 60,
38516
38584
  icon: "o-spreadsheet-Icon.INSERT_PIVOT",
38517
38585
  children: [REINSERT_DYNAMIC_PIVOT_CHILDREN],
38518
38586
  isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
@@ -38520,7 +38588,7 @@ const reinsertDynamicPivotMenu = {
38520
38588
  const reinsertStaticPivotMenu = {
38521
38589
  id: "reinsert_static_pivot",
38522
38590
  name: _t("Re-insert static pivot"),
38523
- sequence: 1020,
38591
+ sequence: 70,
38524
38592
  icon: "o-spreadsheet-Icon.INSERT_PIVOT",
38525
38593
  children: [REINSERT_STATIC_PIVOT_CHILDREN],
38526
38594
  isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
@@ -40189,8 +40257,9 @@ topbarMenuRegistry
40189
40257
  sequence: 40,
40190
40258
  separator: true,
40191
40259
  })
40192
- .addChild("data_sources_data", ["data"], (env) => {
40260
+ .addChild("pivot_data_sources", ["data"], (env) => {
40193
40261
  const sequence = 50;
40262
+ const numberOfPivots = env.model.getters.getPivotIds().length;
40194
40263
  return env.model.getters.getPivotIds().map((pivotId, index) => {
40195
40264
  const highlightProvider = {
40196
40265
  get highlights() {
@@ -40200,7 +40269,7 @@ topbarMenuRegistry
40200
40269
  return {
40201
40270
  id: `item_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
40202
40271
  name: env.model.getters.getPivotDisplayName(pivotId),
40203
- sequence: sequence + index,
40272
+ sequence: sequence + index / numberOfPivots,
40204
40273
  isReadonlyAllowed: true,
40205
40274
  execute: (env) => env.openSidePanel("PivotSidePanel", { pivotId }),
40206
40275
  onStartHover: (env) => env.getStore(HighlightStore).register(highlightProvider),
@@ -57198,7 +57267,8 @@ class CorePlugin extends BasePlugin {
57198
57267
  * the type of change that occurred.
57199
57268
  *
57200
57269
  * @param applyChange a function that, when called, will adapt the range according to the change on the grid
57201
- * @param sheetId an optional sheetId to adapt either range of that sheet specifically, or ranges pointing to that sheet
57270
+ * @param sheetId an sheetId to adapt either range of that sheet specifically, or ranges pointing to that sheet
57271
+ * @param sheetName couple of old and new sheet names to adapt ranges pointing to that sheet
57202
57272
  */
57203
57273
  adaptRanges(applyChange, sheetId, sheetName) { }
57204
57274
  /**
@@ -57801,9 +57871,7 @@ class CellPlugin extends CorePlugin {
57801
57871
  for (const cell of Object.values(this.cells[sheet] || {})) {
57802
57872
  if (cell.isFormula) {
57803
57873
  for (const range of cell.compiledFormula.dependencies) {
57804
- if (!sheetId ||
57805
- range.sheetId === sheetId ||
57806
- (sheetName && range.invalidSheetName === sheetName)) {
57874
+ if (range.sheetId === sheetId || range.invalidSheetName === sheetName.old) {
57807
57875
  const change = applyChange(range);
57808
57876
  if (change.changeType !== "NONE") {
57809
57877
  this.history.update("cells", sheet, cell.id, "compiledFormula", "dependencies", cell.compiledFormula.dependencies.indexOf(range), change.range);
@@ -58419,9 +58487,9 @@ class ChartPlugin extends CorePlugin {
58419
58487
  charts = {};
58420
58488
  createChart = chartFactory(this.getters);
58421
58489
  validateChartDefinition = (cmd) => validateChartDefinition(this, cmd.definition);
58422
- adaptRanges(applyChange) {
58490
+ adaptRanges(applyChange, sheetId, adaptSheetName) {
58423
58491
  for (const [chartId, chart] of Object.entries(this.charts)) {
58424
- this.history.update("charts", chartId, chart?.updateRanges(applyChange));
58492
+ this.history.update("charts", chartId, chart?.updateRanges(applyChange, sheetId, adaptSheetName));
58425
58493
  }
58426
58494
  }
58427
58495
  // ---------------------------------------------------------------------------
@@ -58684,7 +58752,7 @@ class ConditionalFormatPlugin extends CorePlugin {
58684
58752
  }
58685
58753
  }
58686
58754
  }
58687
- adaptRanges(applyChange, sheetId, sheetName) {
58755
+ adaptRanges(applyChange, sheetId) {
58688
58756
  const sheetIds = sheetId ? [sheetId] : Object.keys(this.cfRules);
58689
58757
  for (const sheetId of sheetIds) {
58690
58758
  this.adaptCFRanges(sheetId, applyChange);
@@ -59080,11 +59148,8 @@ class DataValidationPlugin extends CorePlugin {
59080
59148
  "getValidationRuleForCell",
59081
59149
  ];
59082
59150
  rules = {};
59083
- adaptRanges(applyChange, sheetId, sheetName) {
59084
- const sheetIds = sheetId ? [sheetId] : Object.keys(this.rules);
59085
- for (const sheetId of sheetIds) {
59086
- this.adaptDVRanges(sheetId, applyChange);
59087
- }
59151
+ adaptRanges(applyChange, sheetId) {
59152
+ this.adaptDVRanges(sheetId, applyChange);
59088
59153
  this.adaptDVFormulas(applyChange);
59089
59154
  }
59090
59155
  adaptDVFormulas(applyChange) {
@@ -59374,9 +59439,6 @@ class FigurePlugin extends CorePlugin {
59374
59439
  // Command Handling
59375
59440
  // ---------------------------------------------------------------------------
59376
59441
  adaptRanges(applyChange, sheetId) {
59377
- if (!sheetId) {
59378
- return;
59379
- }
59380
59442
  for (const figure of this.getFigures(sheetId)) {
59381
59443
  const change = applyChange(this.getters.getRangeFromZone(sheetId, {
59382
59444
  left: figure.col,
@@ -60184,11 +60246,8 @@ class MergePlugin extends CorePlugin {
60184
60246
  break;
60185
60247
  }
60186
60248
  }
60187
- adaptRanges(applyChange, sheetId, sheetName) {
60188
- const sheetIds = sheetId ? [sheetId] : Object.keys(this.merges);
60189
- for (const sheetId of sheetIds) {
60190
- this.applyRangeChangeOnSheet(sheetId, applyChange);
60191
- }
60249
+ adaptRanges(applyChange, sheetId) {
60250
+ this.applyRangeChangeOnSheet(sheetId, applyChange);
60192
60251
  }
60193
60252
  // ---------------------------------------------------------------------------
60194
60253
  // Getters
@@ -61696,12 +61755,9 @@ class TablePlugin extends CorePlugin {
61696
61755
  static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
61697
61756
  tables = {};
61698
61757
  nextTableId = 1;
61699
- adaptRanges(applyChange, sheetId, sheetName) {
61700
- const sheetIds = sheetId ? [sheetId] : this.getters.getSheetIds();
61701
- for (const sheetId of sheetIds) {
61702
- for (const table of this.getCoreTables(sheetId)) {
61703
- this.applyRangeChangeOnTable(sheetId, table, applyChange);
61704
- }
61758
+ adaptRanges(applyChange, sheetId) {
61759
+ for (const table of this.getCoreTables(sheetId)) {
61760
+ this.applyRangeChangeOnTable(sheetId, table, applyChange);
61705
61761
  }
61706
61762
  }
61707
61763
  allowDispatch(cmd) {
@@ -62664,7 +62720,7 @@ class PivotCorePlugin extends CorePlugin {
62664
62720
  }
62665
62721
  }
62666
62722
  }
62667
- adaptRanges(applyChange, sheetId, sheetName) {
62723
+ adaptRanges(applyChange) {
62668
62724
  for (const sheetId in this.compiledMeasureFormulas) {
62669
62725
  for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
62670
62726
  const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
@@ -66825,7 +66881,7 @@ class PivotUIPlugin extends CoreViewPlugin {
66825
66881
  if (!result) {
66826
66882
  return EMPTY_PIVOT_CELL;
66827
66883
  }
66828
- const { functionName, args } = result;
66884
+ let { functionName, args } = result;
66829
66885
  const formulaId = args[0];
66830
66886
  if (!formulaId) {
66831
66887
  return EMPTY_PIVOT_CELL;
@@ -66855,6 +66911,9 @@ class PivotUIPlugin extends CoreViewPlugin {
66855
66911
  return pivotCells[pivotCol][pivotRow];
66856
66912
  }
66857
66913
  try {
66914
+ const offsetRow = position.row - mainPosition.row;
66915
+ const offsetCol = position.col - mainPosition.col;
66916
+ args = args.map((arg) => (isMatrix(arg) ? arg[offsetCol][offsetRow] : arg));
66858
66917
  if (functionName === "PIVOT.HEADER" && args.at(-2) === "measure") {
66859
66918
  const domain = pivot.parseArgsToPivotDomain(args.slice(1, -2).map((value) => ({ value })));
66860
66919
  return {
@@ -68053,7 +68112,8 @@ function transformAll(toTransform, executed) {
68053
68112
  // If the executed command is not in the registry, we skip it
68054
68113
  // because we know there won't be any transformation impacting the
68055
68114
  // commands to transform.
68056
- if (possibleTransformations.has(executedCommand.type)) {
68115
+ if (possibleTransformations.has(executedCommand.type) ||
68116
+ rangeAdapterRegistry.contains(executedCommand.type)) {
68057
68117
  transformedCommands = transformedCommands.reduce((acc, cmd) => {
68058
68118
  const transformed = transform(cmd, executedCommand);
68059
68119
  if (transformed) {
@@ -68787,7 +68847,7 @@ class DataCleanupPlugin extends UIPlugin {
68787
68847
  bottom: rowIndex,
68788
68848
  }));
68789
68849
  const handler = new CellClipboardHandler(this.getters, this.dispatch);
68790
- const data = handler.copy(getClipboardDataPositions(sheetId, rowsToKeep));
68850
+ const data = handler.copy(getClipboardDataPositions(sheetId, rowsToKeep), false);
68791
68851
  if (!data) {
68792
68852
  return;
68793
68853
  }
@@ -70827,12 +70887,12 @@ class ClipboardPlugin extends UIPlugin {
70827
70887
  }
70828
70888
  case "INSERT_CELL": {
70829
70889
  const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
70830
- const copiedData = this.copy(cut);
70890
+ const copiedData = this.copy(cut, "shiftCells");
70831
70891
  return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
70832
70892
  }
70833
70893
  case "DELETE_CELL": {
70834
70894
  const { cut, paste } = this.getDeleteCellsTargets(cmd.zone, cmd.shiftDimension);
70835
- const copiedData = this.copy(cut);
70895
+ const copiedData = this.copy(cut, "shiftCells");
70836
70896
  return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
70837
70897
  }
70838
70898
  }
@@ -70943,13 +71003,13 @@ class ClipboardPlugin extends UIPlugin {
70943
71003
  });
70944
71004
  break;
70945
71005
  }
70946
- const copiedData = this.copy(cut);
71006
+ const copiedData = this.copy(cut, "shiftCells");
70947
71007
  this.paste(paste, copiedData, { isCutOperation: true });
70948
71008
  break;
70949
71009
  }
70950
71010
  case "INSERT_CELL": {
70951
71011
  const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
70952
- const copiedData = this.copy(cut);
71012
+ const copiedData = this.copy(cut, "shiftCells");
70953
71013
  this.paste(paste, copiedData, { isCutOperation: true });
70954
71014
  break;
70955
71015
  }
@@ -71064,11 +71124,11 @@ class ClipboardPlugin extends UIPlugin {
71064
71124
  }
71065
71125
  return false;
71066
71126
  }
71067
- copy(zones) {
71127
+ copy(zones, mode = "copyPaste") {
71068
71128
  let copiedData = {};
71069
71129
  const clipboardData = this.getClipboardData(zones);
71070
71130
  for (const { handlerName, handler } of this.selectClipboardHandlers(clipboardData)) {
71071
- const data = handler.copy(clipboardData, this._isCutOperation);
71131
+ const data = handler.copy(clipboardData, this._isCutOperation, mode);
71072
71132
  copiedData[handlerName] = data;
71073
71133
  const minimalKeys = ["sheetId", "cells", "zones", "figureId"];
71074
71134
  for (const key of minimalKeys) {
@@ -72019,7 +72079,7 @@ class GridSelectionPlugin extends UIPlugin {
72019
72079
  ];
72020
72080
  for (const Handler of clipboardHandlersRegistries.cellHandlers.getAll()) {
72021
72081
  const handler = new Handler(this.getters, this.dispatch);
72022
- const data = handler.copy(getClipboardDataPositions(sheetId, target));
72082
+ const data = handler.copy(getClipboardDataPositions(sheetId, target), false, "shiftCells");
72023
72083
  if (!data) {
72024
72084
  continue;
72025
72085
  }
@@ -79214,7 +79274,7 @@ function figureCoordinates(headers, anchor, offset) {
79214
79274
  for (const [headerIndex, header] of headers.slice(anchor).entries()) {
79215
79275
  if (currentPosition <= offset && offset < currentPosition + header.size) {
79216
79276
  return {
79217
- index: headerIndex,
79277
+ index: anchor + headerIndex,
79218
79278
  offset: convertDotValueToEMU(offset - currentPosition + FIGURE_BORDER_WIDTH),
79219
79279
  };
79220
79280
  }
@@ -80907,6 +80967,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
80907
80967
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
80908
80968
 
80909
80969
 
80910
- __info__.version = "18.3.18";
80911
- __info__.date = "2025-08-26T10:14:21.408Z";
80912
- __info__.hash = "ec2777d";
80970
+ __info__.version = "18.3.20";
80971
+ __info__.date = "2025-09-11T08:45:37.934Z";
80972
+ __info__.hash = "ef829f4";