@odoo/o-spreadsheet 18.2.31 → 18.2.33

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.2.31
6
- * @date 2025-09-23T12:31:15.573Z
7
- * @hash 839667e
5
+ * @version 18.2.33
6
+ * @date 2025-10-16T06:39:40.421Z
7
+ * @hash 280596c
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';
@@ -873,9 +873,7 @@ function removeIndexesFromArray(array, indexes) {
873
873
  return newArray;
874
874
  }
875
875
  function insertItemsAtIndex(array, items, index) {
876
- const newArray = [...array];
877
- newArray.splice(index, 0, ...items);
878
- return newArray;
876
+ return array.slice(0, index).concat(items).concat(array.slice(index));
879
877
  }
880
878
  function replaceItemAtIndex(array, newItem, index) {
881
879
  const newArray = [...array];
@@ -3916,7 +3914,17 @@ function toNumberMatrix(data, argName) {
3916
3914
  return toMatrix(data).map((row) => {
3917
3915
  return row.map((cell) => {
3918
3916
  if (typeof cell.value !== "number") {
3919
- throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects number values for %s, but got a %s.", argName, typeof cell.value));
3917
+ let message = "";
3918
+ if (typeof cell === "object") {
3919
+ message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got an empty value.", argName);
3920
+ }
3921
+ else if (typeof cell === "string") {
3922
+ message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got a string.", argName);
3923
+ }
3924
+ else if (typeof cell === "boolean") {
3925
+ message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got a boolean.", argName);
3926
+ }
3927
+ throw new EvaluationError(message);
3920
3928
  }
3921
3929
  return cell.value;
3922
3930
  });
@@ -5116,7 +5124,7 @@ function tokensToTextInternalFormat(tokens) {
5116
5124
  * Replace in place tokens "mm" and "m" that denote minutes in date format with "MM" to avoid confusion with months.
5117
5125
  *
5118
5126
  * As per OpenXML specification, in date formats if a date token "m" or "mm" is followed by a date token "s" or
5119
- * preceded by a data token "h", then it's not a month but an minute.
5127
+ * preceded by a data token "h", then it's not a month but a minute.
5120
5128
  */
5121
5129
  function convertTokensToMinutesInDateFormat(tokens) {
5122
5130
  const dateParts = tokens.filter((token) => token.type === "DATE_PART");
@@ -5159,6 +5167,9 @@ function internalFormatPartToFormat(internalFormat) {
5159
5167
  case "REPEATED_CHAR":
5160
5168
  format += "*" + token.value;
5161
5169
  break;
5170
+ case "DATE_PART":
5171
+ format += token.value === "MM" ? "mm" : token.value; // Convert "MM" back to "mm" for minutes
5172
+ break;
5162
5173
  default:
5163
5174
  format += token.value;
5164
5175
  }
@@ -8815,7 +8826,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
8815
8826
  pasteCell(origin, target, clipboardOption) {
8816
8827
  const { sheetId, col, row } = target;
8817
8828
  const targetCell = this.getters.getEvaluatedCell(target);
8818
- const originFormat = origin?.format ?? origin.evaluatedCell.format;
8829
+ const originFormat = origin?.format || origin.evaluatedCell.format;
8819
8830
  if (clipboardOption?.pasteOption === "asValue") {
8820
8831
  this.dispatch("UPDATE_CELL", {
8821
8832
  ...target,
@@ -10436,6 +10447,10 @@ const chartShowValuesPlugin = {
10436
10447
  }
10437
10448
  const ctx = chart.ctx;
10438
10449
  ctx.save();
10450
+ const { left, top, height, width } = chart.chartArea;
10451
+ ctx.beginPath();
10452
+ ctx.rect(left, top, width, height);
10453
+ ctx.clip();
10439
10454
  ctx.textAlign = "center";
10440
10455
  ctx.textBaseline = "middle";
10441
10456
  ctx.miterLimit = 1; // Avoid sharp artifacts on strokeText
@@ -13641,7 +13656,7 @@ const GROWTH = {
13641
13656
  ],
13642
13657
  compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
13643
13658
  assertNonEmptyMatrix(knownDataY, "known_data_y");
13644
- 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)));
13659
+ return expM(predictLinearValues(logM(toNumberMatrix(knownDataY, "known_data_y")), toNumberMatrix(knownDataX, "known_data_x"), toNumberMatrix(newDataX, "new_data_y"), toBoolean(b)));
13645
13660
  },
13646
13661
  };
13647
13662
  // -----------------------------------------------------------------------------
@@ -13706,7 +13721,7 @@ const LINEST = {
13706
13721
  ],
13707
13722
  compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
13708
13723
  assertNonEmptyMatrix(dataY, "data_y");
13709
- return fullLinearRegression(toNumberMatrix(dataX, "the first argument (data_y)"), toNumberMatrix(dataY, "the second argument (data_x)"), toBoolean(calculateB), toBoolean(verbose));
13724
+ return fullLinearRegression(toNumberMatrix(dataX, "data_x"), toNumberMatrix(dataY, "data_y"), toBoolean(calculateB), toBoolean(verbose));
13710
13725
  },
13711
13726
  isExported: true,
13712
13727
  };
@@ -13723,7 +13738,7 @@ const LOGEST = {
13723
13738
  ],
13724
13739
  compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
13725
13740
  assertNonEmptyMatrix(dataY, "data_y");
13726
- const coeffs = fullLinearRegression(toNumberMatrix(dataX, "the second argument (data_x)"), logM(toNumberMatrix(dataY, "the first argument (data_y)")), toBoolean(calculateB), toBoolean(verbose));
13741
+ const coeffs = fullLinearRegression(toNumberMatrix(dataX, "data_x"), logM(toNumberMatrix(dataY, "data_y")), toBoolean(calculateB), toBoolean(verbose));
13727
13742
  for (let i = 0; i < coeffs.length; i++) {
13728
13743
  coeffs[i][0] = Math.exp(coeffs[i][0]);
13729
13744
  }
@@ -14313,7 +14328,7 @@ const TREND = {
14313
14328
  ],
14314
14329
  compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
14315
14330
  assertNonEmptyMatrix(knownDataY, "known_data_y");
14316
- 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));
14331
+ return predictLinearValues(toNumberMatrix(knownDataY, "known_data_y"), toNumberMatrix(knownDataX, "known_data_x"), toNumberMatrix(newDataX, "new_data_y"), toBoolean(b));
14317
14332
  },
14318
14333
  };
14319
14334
  // -----------------------------------------------------------------------------
@@ -23744,6 +23759,74 @@ iconsOnCellRegistry.add("conditional_formatting", (getters, position) => {
23744
23759
  }
23745
23760
  });
23746
23761
 
23762
+ /**
23763
+ * Get the relative path between two files
23764
+ *
23765
+ * Eg.:
23766
+ * from "folder1/file1.txt" to "folder2/file2.txt" => "../folder2/file2.txt"
23767
+ */
23768
+ function getRelativePath(from, to) {
23769
+ const fromPathParts = from.split("/");
23770
+ const toPathParts = to.split("/");
23771
+ let relPath = "";
23772
+ let startIndex = 0;
23773
+ for (let i = 0; i < fromPathParts.length - 1; i++) {
23774
+ if (fromPathParts[i] === toPathParts[i]) {
23775
+ startIndex++;
23776
+ }
23777
+ else {
23778
+ relPath += "../";
23779
+ }
23780
+ }
23781
+ relPath += toPathParts.slice(startIndex).join("/");
23782
+ return relPath;
23783
+ }
23784
+ /**
23785
+ * Convert an array of element into an object where the objects keys were the elements position in the array.
23786
+ * Can give an offset as argument, and all the array indexes will we shifted by this offset in the returned object.
23787
+ *
23788
+ * eg. : ["a", "b"] => {0:"a", 1:"b"}
23789
+ */
23790
+ function arrayToObject(array, indexOffset = 0) {
23791
+ const obj = {};
23792
+ for (let i = 0; i < array.length; i++) {
23793
+ if (array[i]) {
23794
+ obj[i + indexOffset] = array[i];
23795
+ }
23796
+ }
23797
+ return obj;
23798
+ }
23799
+ /**
23800
+ * In xlsx we can have string with unicode characters with the format _x00fa_.
23801
+ * Replace with characters understandable by JS
23802
+ */
23803
+ function fixXlsxUnicode(str) {
23804
+ return str.replace(/_x([0-9a-zA-Z]{4})_/g, (match, code) => {
23805
+ return String.fromCharCode(parseInt(code, 16));
23806
+ });
23807
+ }
23808
+ /** Get a header in the SheetData. Create the header if it doesn't exist in the SheetData */
23809
+ function getSheetDataHeader(sheetData, dimension, index) {
23810
+ if (dimension === "COL") {
23811
+ if (!sheetData.cols[index]) {
23812
+ sheetData.cols[index] = {};
23813
+ }
23814
+ return sheetData.cols[index];
23815
+ }
23816
+ if (!sheetData.rows[index]) {
23817
+ sheetData.rows[index] = {};
23818
+ }
23819
+ return sheetData.rows[index];
23820
+ }
23821
+ /** Prefix the string by "=" if the string looks like a formula */
23822
+ function prefixFormulaWithEqual(formula) {
23823
+ if (formula[0] === "=") {
23824
+ return formula;
23825
+ }
23826
+ const tokens = tokenize(formula);
23827
+ return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
23828
+ }
23829
+
23747
23830
  /**
23748
23831
  * Map of the different types of conversions warnings and their name in error messages
23749
23832
  */
@@ -24251,66 +24334,6 @@ function hexaToInt(hex) {
24251
24334
  */
24252
24335
  const DEFAULT_SYSTEM_COLOR = "FF000000";
24253
24336
 
24254
- /**
24255
- * Get the relative path between two files
24256
- *
24257
- * Eg.:
24258
- * from "folder1/file1.txt" to "folder2/file2.txt" => "../folder2/file2.txt"
24259
- */
24260
- function getRelativePath(from, to) {
24261
- const fromPathParts = from.split("/");
24262
- const toPathParts = to.split("/");
24263
- let relPath = "";
24264
- let startIndex = 0;
24265
- for (let i = 0; i < fromPathParts.length - 1; i++) {
24266
- if (fromPathParts[i] === toPathParts[i]) {
24267
- startIndex++;
24268
- }
24269
- else {
24270
- relPath += "../";
24271
- }
24272
- }
24273
- relPath += toPathParts.slice(startIndex).join("/");
24274
- return relPath;
24275
- }
24276
- /**
24277
- * Convert an array of element into an object where the objects keys were the elements position in the array.
24278
- * Can give an offset as argument, and all the array indexes will we shifted by this offset in the returned object.
24279
- *
24280
- * eg. : ["a", "b"] => {0:"a", 1:"b"}
24281
- */
24282
- function arrayToObject(array, indexOffset = 0) {
24283
- const obj = {};
24284
- for (let i = 0; i < array.length; i++) {
24285
- if (array[i]) {
24286
- obj[i + indexOffset] = array[i];
24287
- }
24288
- }
24289
- return obj;
24290
- }
24291
- /**
24292
- * In xlsx we can have string with unicode characters with the format _x00fa_.
24293
- * Replace with characters understandable by JS
24294
- */
24295
- function fixXlsxUnicode(str) {
24296
- return str.replace(/_x([0-9a-zA-Z]{4})_/g, (match, code) => {
24297
- return String.fromCharCode(parseInt(code, 16));
24298
- });
24299
- }
24300
- /** Get a header in the SheetData. Create the header if it doesn't exist in the SheetData */
24301
- function getSheetDataHeader(sheetData, dimension, index) {
24302
- if (dimension === "COL") {
24303
- if (!sheetData.cols[index]) {
24304
- sheetData.cols[index] = {};
24305
- }
24306
- return sheetData.cols[index];
24307
- }
24308
- if (!sheetData.rows[index]) {
24309
- sheetData.rows[index] = {};
24310
- }
24311
- return sheetData.rows[index];
24312
- }
24313
-
24314
24337
  const XLSX_DATE_FORMAT_REGEX = /^(yy|yyyy|m{1,5}|d{1,4}|h{1,2}|s{1,2}|am\/pm|a\/m|\s|-|\/|\.|:)+$/i;
24315
24338
  /**
24316
24339
  * Convert excel format to o_spreadsheet format
@@ -24520,9 +24543,9 @@ function convertConditionalFormats(xlsxCfs, dxfs, warningManager) {
24520
24543
  if (!rule.operator || !rule.formula || rule.formula.length === 0)
24521
24544
  continue;
24522
24545
  operator = convertCFCellIsOperator(rule.operator);
24523
- values.push(prefixFormula(rule.formula[0]));
24546
+ values.push(prefixFormulaWithEqual(rule.formula[0]));
24524
24547
  if (rule.formula.length === 2) {
24525
- values.push(prefixFormula(rule.formula[1]));
24548
+ values.push(prefixFormulaWithEqual(rule.formula[1]));
24526
24549
  }
24527
24550
  break;
24528
24551
  }
@@ -24680,11 +24703,6 @@ function convertIcons(xlsxIconSet, index) {
24680
24703
  ? ICON_SETS[iconSet].neutral
24681
24704
  : ICON_SETS[iconSet].good;
24682
24705
  }
24683
- /** Prefix the string by "=" if the string looks like a formula */
24684
- function prefixFormula(formula) {
24685
- const tokens = tokenize(formula);
24686
- return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
24687
- }
24688
24706
  // ---------------------------------------------------------------------------
24689
24707
  // Warnings
24690
24708
  // ---------------------------------------------------------------------------
@@ -25105,7 +25123,7 @@ function convertDataValidationRules(xlsxDataValidations, warningManager) {
25105
25123
  dvRules.push(decimalRule);
25106
25124
  break;
25107
25125
  case "list":
25108
- const listRule = convertListrule(dvId++, dv);
25126
+ const listRule = convertListRule(dvId++, dv);
25109
25127
  dvRules.push(listRule);
25110
25128
  break;
25111
25129
  case "date":
@@ -25125,9 +25143,9 @@ function convertDataValidationRules(xlsxDataValidations, warningManager) {
25125
25143
  return dvRules;
25126
25144
  }
25127
25145
  function convertDecimalRule(id, dv) {
25128
- const values = [dv.formula1.toString()];
25146
+ const values = [prefixFormulaWithEqual(dv.formula1.toString())];
25129
25147
  if (dv.formula2) {
25130
- values.push(dv.formula2.toString());
25148
+ values.push(prefixFormulaWithEqual(dv.formula2.toString()));
25131
25149
  }
25132
25150
  return {
25133
25151
  id: id.toString(),
@@ -25139,7 +25157,7 @@ function convertDecimalRule(id, dv) {
25139
25157
  },
25140
25158
  };
25141
25159
  }
25142
- function convertListrule(id, dv) {
25160
+ function convertListRule(id, dv) {
25143
25161
  const formula1 = dv.formula1.toString();
25144
25162
  const isRangeRule = rangeReference.test(formula1);
25145
25163
  return {
@@ -25155,9 +25173,9 @@ function convertListrule(id, dv) {
25155
25173
  }
25156
25174
  function convertDateRule(id, dv) {
25157
25175
  let criterion;
25158
- const values = [dv.formula1.toString()];
25176
+ const values = [prefixFormulaWithEqual(dv.formula1.toString())];
25159
25177
  if (dv.formula2) {
25160
- values.push(dv.formula2.toString());
25178
+ values.push(prefixFormulaWithEqual(dv.formula2.toString()));
25161
25179
  criterion = {
25162
25180
  type: XLSX_DV_DATE_OPERATOR_TO_DV_TYPE_MAPPING[dv.operator],
25163
25181
  values: getDateCriterionFormattedValues(values, DEFAULT_LOCALE),
@@ -25184,7 +25202,7 @@ function convertCustomRule(id, dv) {
25184
25202
  isBlocking: dv.errorStyle !== "warning",
25185
25203
  criterion: {
25186
25204
  type: "customFormula",
25187
- values: [`=${dv.formula1.toString()}`],
25205
+ values: [prefixFormulaWithEqual(dv.formula1.toString())],
25188
25206
  },
25189
25207
  };
25190
25208
  }
@@ -28916,6 +28934,7 @@ function getChartTimeOptions(labels, labelFormat, locale) {
28916
28934
  parser: luxonFormat,
28917
28935
  displayFormats,
28918
28936
  unit: timeUnit ?? false,
28937
+ tooltipFormat: luxonFormat,
28919
28938
  };
28920
28939
  }
28921
28940
  /**
@@ -30094,6 +30113,7 @@ function getLineChartScales(definition, args) {
30094
30113
  };
30095
30114
  Object.assign(scales.x, axis);
30096
30115
  scales.x.ticks.maxTicksLimit = 15;
30116
+ delete scales?.x?.ticks?.callback;
30097
30117
  }
30098
30118
  else if (axisType === "linear") {
30099
30119
  scales.x.type = "linear";
@@ -44549,12 +44569,13 @@ class DataValidationEditor extends Component {
44549
44569
  onCloseSidePanel: { type: Function, optional: true },
44550
44570
  };
44551
44571
  state = useState({ rule: this.defaultDataValidationRule, errors: [] });
44572
+ editingSheetId;
44552
44573
  setup() {
44574
+ this.editingSheetId = this.env.model.getters.getActiveSheetId();
44553
44575
  if (this.props.rule) {
44554
- const sheetId = this.env.model.getters.getActiveSheetId();
44555
44576
  this.state.rule = {
44556
44577
  ...this.props.rule,
44557
- ranges: this.props.rule.ranges.map((range) => this.env.model.getters.getRangeString(range, sheetId)),
44578
+ ranges: this.props.rule.ranges.map((range) => this.env.model.getters.getRangeString(range, this.editingSheetId)),
44558
44579
  };
44559
44580
  this.state.rule.criterion.type = this.props.rule.criterion.type;
44560
44581
  }
@@ -44588,7 +44609,6 @@ class DataValidationEditor extends Component {
44588
44609
  const locale = this.env.model.getters.getLocale();
44589
44610
  const criterion = rule.criterion;
44590
44611
  const criterionEvaluator = dataValidationEvaluatorRegistry.get(criterion.type);
44591
- const sheetId = this.env.model.getters.getActiveSheetId();
44592
44612
  const values = criterion.values
44593
44613
  .slice(0, criterionEvaluator.numberOfValues(criterion))
44594
44614
  .map((value) => value?.trim())
@@ -44596,8 +44616,8 @@ class DataValidationEditor extends Component {
44596
44616
  .map((value) => canonicalizeContent(value, locale));
44597
44617
  rule.criterion = { ...criterion, values };
44598
44618
  return {
44599
- sheetId,
44600
- ranges: this.state.rule.ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(sheetId, xc)),
44619
+ sheetId: this.editingSheetId,
44620
+ ranges: this.state.rule.ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(this.editingSheetId, xc)),
44601
44621
  rule,
44602
44622
  };
44603
44623
  }
@@ -45127,6 +45147,7 @@ css /* scss */ `
45127
45147
  .o-button {
45128
45148
  height: 19px;
45129
45149
  width: 19px;
45150
+ box-sizing: content-box;
45130
45151
  .o-icon {
45131
45152
  height: 14px;
45132
45153
  width: 14px;
@@ -45884,7 +45905,7 @@ class PivotMeasureEditor extends Component {
45884
45905
  return undefined;
45885
45906
  }
45886
45907
  get isCalculatedMeasureInvalid() {
45887
- return this.env.model.getters.getMeasureCompiledFormula(this.props.measure).isBadExpression;
45908
+ return compile(this.props.measure.computedBy?.formula ?? "").isBadExpression;
45888
45909
  }
45889
45910
  }
45890
45911
 
@@ -56622,7 +56643,7 @@ class HeaderSizePlugin extends CorePlugin {
56622
56643
  let sizes = [...this.sizes[cmd.sheetId][cmd.dimension]];
56623
56644
  const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
56624
56645
  const baseSize = sizes[cmd.base];
56625
- sizes.splice(addIndex, 0, ...Array(cmd.quantity).fill(baseSize));
56646
+ sizes = insertItemsAtIndex(sizes, Array(cmd.quantity).fill(baseSize), addIndex);
56626
56647
  this.history.update("sizes", cmd.sheetId, cmd.dimension, sizes);
56627
56648
  break;
56628
56649
  }
@@ -56774,9 +56795,8 @@ class HeaderVisibilityPlugin extends CorePlugin {
56774
56795
  break;
56775
56796
  }
56776
56797
  case "ADD_COLUMNS_ROWS": {
56777
- const hiddenHeaders = [...this.hiddenHeaders[cmd.sheetId][cmd.dimension]];
56778
56798
  const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
56779
- hiddenHeaders.splice(addIndex, 0, ...Array(cmd.quantity).fill(false));
56799
+ const hiddenHeaders = insertItemsAtIndex([...this.hiddenHeaders[cmd.sheetId][cmd.dimension]], Array(cmd.quantity).fill(false), addIndex);
56780
56800
  this.history.update("hiddenHeaders", cmd.sheetId, cmd.dimension, hiddenHeaders);
56781
56801
  break;
56782
56802
  }
@@ -61059,12 +61079,12 @@ class SpreadsheetRTree {
61059
61079
  this.rTrees[sheetId].remove(item, this.rtreeItemComparer);
61060
61080
  }
61061
61081
  rtreeItemComparer(left, right) {
61062
- return (left.data == right.data &&
61063
- left.boundingBox.sheetId === right.boundingBox.sheetId &&
61082
+ return (left.boundingBox.sheetId === right.boundingBox.sheetId &&
61064
61083
  left.boundingBox?.zone.left === right.boundingBox.zone.left &&
61065
61084
  left.boundingBox?.zone.top === right.boundingBox.zone.top &&
61066
61085
  left.boundingBox?.zone.right === right.boundingBox.zone.right &&
61067
- left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom);
61086
+ left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom &&
61087
+ deepEquals(left.data, right.data));
61068
61088
  }
61069
61089
  }
61070
61090
  /**
@@ -61137,7 +61157,7 @@ class FormulaDependencyGraph {
61137
61157
  * in the correct order they should be evaluated.
61138
61158
  * This is called a topological ordering (excluding cycles)
61139
61159
  */
61140
- getCellsDependingOn(ranges) {
61160
+ getCellsDependingOn(ranges, ignore) {
61141
61161
  const visited = this.createEmptyPositionSet();
61142
61162
  const queue = Array.from(ranges).reverse();
61143
61163
  while (queue.length > 0) {
@@ -61152,7 +61172,7 @@ class FormulaDependencyGraph {
61152
61172
  const impactedPositions = this.rTree.search(range).map((dep) => dep.data);
61153
61173
  const nextInQueue = {};
61154
61174
  for (const position of impactedPositions) {
61155
- if (!visited.has(position)) {
61175
+ if (!visited.has(position) && !ignore.has(position)) {
61156
61176
  if (!nextInQueue[position.sheetId]) {
61157
61177
  nextInQueue[position.sheetId] = [];
61158
61178
  }
@@ -61709,7 +61729,7 @@ class Evaluator {
61709
61729
  }
61710
61730
  invalidatePositionsDependingOnSpread(sheetId, resultZone) {
61711
61731
  // the result matrix is split in 2 zones to exclude the array formula position
61712
- const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })));
61732
+ const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })), this.nextPositionsToUpdate);
61713
61733
  invalidatedPositions.delete({ sheetId, col: resultZone.left, row: resultZone.top });
61714
61734
  this.nextPositionsToUpdate.addMany(invalidatedPositions);
61715
61735
  }
@@ -61827,7 +61847,7 @@ class Evaluator {
61827
61847
  for (const sheetId in zonesBySheetIds) {
61828
61848
  ranges.push(...zonesBySheetIds[sheetId].map((zone) => ({ sheetId, zone })));
61829
61849
  }
61830
- return this.formulaDependencies().getCellsDependingOn(ranges);
61850
+ return this.formulaDependencies().getCellsDependingOn(ranges, this.nextPositionsToUpdate);
61831
61851
  }
61832
61852
  }
61833
61853
  function forEachSpreadPositionInMatrix(nbColumns, nbRows, callback) {
@@ -77306,6 +77326,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
77306
77326
  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, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
77307
77327
 
77308
77328
 
77309
- __info__.version = "18.2.31";
77310
- __info__.date = "2025-09-23T12:31:15.573Z";
77311
- __info__.hash = "839667e";
77329
+ __info__.version = "18.2.33";
77330
+ __info__.date = "2025-10-16T06:39:40.421Z";
77331
+ __info__.hash = "280596c";