@odoo/o-spreadsheet 16.2.22 → 16.2.23

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.
@@ -603,13 +603,6 @@ function getYearFrac(startDate, endDate, _dayCountConvention) {
603
603
  }
604
604
 
605
605
  //------------------------------------------------------------------------------
606
- /**
607
- * Stringify an object, like JSON.stringify, except that the first level of keys
608
- * is ordered.
609
- */
610
- function stringify(obj) {
611
- return JSON.stringify(obj, Object.keys(obj).sort());
612
- }
613
606
  /**
614
607
  * Remove quotes from a quoted string
615
608
  * ```js
@@ -909,7 +902,7 @@ function isObjectEmptyRecursive(argument) {
909
902
  */
910
903
  function getItemId(item, itemsDic) {
911
904
  for (let [key, value] of Object.entries(itemsDic)) {
912
- if (stringify(value) === stringify(item)) {
905
+ if (deepEquals(value, item)) {
913
906
  return parseInt(key, 10);
914
907
  }
915
908
  }
@@ -975,6 +968,22 @@ function lazy(fn) {
975
968
  lazyValue.map = (callback) => lazy(() => callback(lazyValue()));
976
969
  return lazyValue;
977
970
  }
971
+ /**
972
+ * Creates a version of the function that's memoized on the value of its first
973
+ * argument, if any.
974
+ */
975
+ function memoize(func) {
976
+ const cache = new Map();
977
+ const funcName = func.name ? func.name + " (memoized)" : "memoized";
978
+ return {
979
+ [funcName](...args) {
980
+ if (!cache.has(args[0])) {
981
+ cache.set(args[0], func(...args));
982
+ }
983
+ return cache.get(args[0]);
984
+ },
985
+ }[funcName];
986
+ }
978
987
  /**
979
988
  * Find the next defined value after the given index in an array of strings. If there is no defined value
980
989
  * after the index, return the closest defined value before the index. Return an empty string if no
@@ -3572,12 +3581,12 @@ function toString(value) {
3572
3581
  }
3573
3582
  }
3574
3583
  /** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
3575
- function normalizeString(str) {
3584
+ const normalizeString = memoize(function normalizeString(str) {
3576
3585
  return str
3577
3586
  .toLowerCase()
3578
3587
  .normalize("NFD")
3579
3588
  .replace(/[\u0300-\u036f]/g, "");
3580
- }
3589
+ });
3581
3590
  /**
3582
3591
  * Normalize a value.
3583
3592
  * If the cell value is a string, this will set it to lowercase and replacing accent letters with plain letters
@@ -4301,6 +4310,7 @@ var CommandResult;
4301
4310
  CommandResult[CommandResult["ChartDoesNotExist"] = 85] = "ChartDoesNotExist";
4302
4311
  CommandResult[CommandResult["InvalidHeaderIndex"] = 86] = "InvalidHeaderIndex";
4303
4312
  CommandResult[CommandResult["InvalidQuantity"] = 87] = "InvalidQuantity";
4313
+ CommandResult[CommandResult["NoChanges"] = 88] = "NoChanges";
4304
4314
  })(CommandResult || (CommandResult = {}));
4305
4315
 
4306
4316
  function isMatrix(x) {
@@ -27516,6 +27526,14 @@ class BordersPlugin extends CorePlugin {
27516
27526
  // ---------------------------------------------------------------------------
27517
27527
  // Command Handling
27518
27528
  // ---------------------------------------------------------------------------
27529
+ allowDispatch(cmd) {
27530
+ switch (cmd.type) {
27531
+ case "SET_BORDER":
27532
+ return this.checkBordersUnchanged(cmd);
27533
+ default:
27534
+ return 0 /* CommandResult.Success */;
27535
+ }
27536
+ }
27519
27537
  handle(cmd) {
27520
27538
  switch (cmd.type) {
27521
27539
  case "ADD_MERGE":
@@ -27911,6 +27929,15 @@ class BordersPlugin extends CorePlugin {
27911
27929
  this.setBorders(sheetId, [{ ...zone, left: right }], "right");
27912
27930
  }
27913
27931
  }
27932
+ checkBordersUnchanged(cmd) {
27933
+ var _a, _b, _c, _d;
27934
+ const currentBorder = this.getCellBorder(cmd);
27935
+ const areAllNewBordersUndefined = !((_a = cmd.border) === null || _a === void 0 ? void 0 : _a.bottom) && !((_b = cmd.border) === null || _b === void 0 ? void 0 : _b.left) && !((_c = cmd.border) === null || _c === void 0 ? void 0 : _c.right) && !((_d = cmd.border) === null || _d === void 0 ? void 0 : _d.top);
27936
+ if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
27937
+ return 88 /* CommandResult.NoChanges */;
27938
+ }
27939
+ return 0 /* CommandResult.Success */;
27940
+ }
27914
27941
  // ---------------------------------------------------------------------------
27915
27942
  // Import/Export
27916
27943
  // ---------------------------------------------------------------------------
@@ -27946,7 +27973,7 @@ class BordersPlugin extends CorePlugin {
27946
27973
  */
27947
27974
  function getBorderId(border) {
27948
27975
  for (let [key, value] of Object.entries(borders)) {
27949
- if (stringify(value) === stringify(border)) {
27976
+ if (deepEquals(value, border)) {
27950
27977
  return parseInt(key, 10);
27951
27978
  }
27952
27979
  }
@@ -28013,8 +28040,9 @@ class CellPlugin extends CorePlugin {
28013
28040
  allowDispatch(cmd) {
28014
28041
  switch (cmd.type) {
28015
28042
  case "UPDATE_CELL":
28043
+ return this.checkCellOutOfSheet(cmd);
28016
28044
  case "CLEAR_CELL":
28017
- return this.checkCellOutOfSheet(cmd.sheetId, cmd.col, cmd.row);
28045
+ return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
28018
28046
  default:
28019
28047
  return 0 /* CommandResult.Success */;
28020
28048
  }
@@ -28173,14 +28201,9 @@ class CellPlugin extends CorePlugin {
28173
28201
  */
28174
28202
  getCellById(cellId) {
28175
28203
  // this must be as fast as possible
28176
- for (const sheetId in this.cells) {
28177
- const sheet = this.cells[sheetId];
28178
- const cell = sheet[cellId];
28179
- if (cell) {
28180
- return cell;
28181
- }
28182
- }
28183
- return undefined;
28204
+ const position = this.getters.getCellPosition(cellId);
28205
+ const sheet = this.cells[position.sheetId];
28206
+ return sheet[cellId];
28184
28207
  }
28185
28208
  /*
28186
28209
  * Reconstructs the original formula string based on a normalized form and its dependencies
@@ -28418,13 +28441,23 @@ class CellPlugin extends CorePlugin {
28418
28441
  dependencies: [],
28419
28442
  };
28420
28443
  }
28421
- checkCellOutOfSheet(sheetId, col, row) {
28444
+ checkCellOutOfSheet(cmd) {
28445
+ const { sheetId, col, row } = cmd;
28422
28446
  const sheet = this.getters.tryGetSheet(sheetId);
28423
28447
  if (!sheet)
28424
28448
  return 27 /* CommandResult.InvalidSheetId */;
28425
28449
  const sheetZone = this.getters.getSheetZone(sheetId);
28426
28450
  return isInside(col, row, sheetZone) ? 0 /* CommandResult.Success */ : 18 /* CommandResult.TargetOutOfSheet */;
28427
28451
  }
28452
+ checkUselessClearCell(cmd) {
28453
+ const cell = this.getters.getCell(cmd);
28454
+ if (!cell)
28455
+ return 88 /* CommandResult.NoChanges */;
28456
+ if (!cell.content && !cell.style && !cell.format) {
28457
+ return 88 /* CommandResult.NoChanges */;
28458
+ }
28459
+ return 0 /* CommandResult.Success */;
28460
+ }
28428
28461
  }
28429
28462
  CellPlugin.getters = [
28430
28463
  "zoneToXC",
@@ -31490,10 +31523,13 @@ class SheetPlugin extends CorePlugin {
31490
31523
  // begin with the end.
31491
31524
  rows.sort((a, b) => b - a);
31492
31525
  for (let group of groupConsecutive(rows)) {
31526
+ // indexes are sorted in the descending order
31527
+ const from = group[group.length - 1];
31528
+ const to = group[0];
31493
31529
  // Move the cells.
31494
- this.moveCellOnRowsDeletion(sheet, group[group.length - 1], group[0]);
31495
- // Effectively delete the element and recompute the left-right/top-bottom.
31496
- group.map((row) => this.updateRowsStructureOnDeletion(row, sheet));
31530
+ this.moveCellOnRowsDeletion(sheet, from, to);
31531
+ // Effectively delete the rows
31532
+ this.updateRowsStructureOnDeletion(sheet, from, to);
31497
31533
  }
31498
31534
  const count = rows.filter((row) => row < sheet.panes.ySplit).length;
31499
31535
  if (count) {
@@ -31515,8 +31551,6 @@ class SheetPlugin extends CorePlugin {
31515
31551
  this.addEmptyRows(sheet, quantity);
31516
31552
  // Move the cells.
31517
31553
  this.moveCellsOnAddition(sheet, index, quantity, "rows");
31518
- // Recompute the left-right/top-bottom.
31519
- this.updateRowsStructureOnAddition(sheet, row, quantity);
31520
31554
  if (index < sheet.panes.ySplit) {
31521
31555
  this.setPaneDivisions(sheet.id, sheet.panes.ySplit + quantity, "ROW");
31522
31556
  }
@@ -31617,35 +31651,20 @@ class SheetPlugin extends CorePlugin {
31617
31651
  }
31618
31652
  }
31619
31653
  }
31620
- updateRowsStructureOnDeletion(index, sheet) {
31654
+ updateRowsStructureOnDeletion(sheet, deleteFromRow, deleteToRow) {
31621
31655
  const rows = [];
31622
- const cellsQueue = sheet.rows.map((row) => row.cells);
31656
+ const cellsQueue = sheet.rows.map((row) => row.cells).reverse();
31623
31657
  for (let i in sheet.rows) {
31624
- if (Number(i) === index) {
31658
+ const row = Number(i);
31659
+ if (row >= deleteFromRow && row <= deleteToRow) {
31625
31660
  continue;
31626
31661
  }
31627
31662
  rows.push({
31628
- cells: cellsQueue.shift(),
31663
+ cells: cellsQueue.pop(),
31629
31664
  });
31630
31665
  }
31631
31666
  this.history.update("sheets", sheet.id, "rows", rows);
31632
31667
  }
31633
- /**
31634
- * Update the rows of the sheet after an addition:
31635
- * - Rename the rows
31636
- *
31637
- * @param sheet Sheet on which the deletion occurs
31638
- * @param addedRow Index of the added row
31639
- * @param rowsToAdd Number of the rows to add
31640
- */
31641
- updateRowsStructureOnAddition(sheet, addedRow, rowsToAdd) {
31642
- const rows = [];
31643
- const cellsQueue = sheet.rows.map((row) => row.cells);
31644
- sheet.rows.forEach(() => rows.push({
31645
- cells: cellsQueue.shift(),
31646
- }));
31647
- this.history.update("sheets", sheet.id, "rows", rows);
31648
- }
31649
31668
  /**
31650
31669
  * Add empty rows at the end of the rows
31651
31670
  *
@@ -32129,6 +32148,7 @@ class EvaluationPlugin extends UIPlugin {
32129
32148
  }
32130
32149
  return evaluatedCell;
32131
32150
  };
32151
+ const rangeCache = {};
32132
32152
  /**
32133
32153
  * Return the values of the cell(s) used in reference, but always in the format of a range even
32134
32154
  * if a single cell is referenced. It is a list of col values. This is useful for the formulas that describe parameters as
@@ -32145,21 +32165,26 @@ class EvaluationPlugin extends UIPlugin {
32145
32165
  // Performance issue: Avoid fetching data on positions that are out of the spreadsheet
32146
32166
  // e.g. A1:ZZZ9999 in a sheet with 10 cols and 10 rows should ignore everything past J10 and return a 10x10 array
32147
32167
  const sheetZone = getters.getSheetZone(sheetId);
32148
- const result = [];
32149
32168
  const zone = intersection(range.zone, sheetZone);
32150
32169
  if (!zone) {
32151
- result.push([]);
32152
- return result;
32170
+ return [[]];
32171
+ }
32172
+ const { top, left, bottom, right } = zone;
32173
+ const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
32174
+ if (cacheKey in rangeCache) {
32175
+ return rangeCache[cacheKey];
32153
32176
  }
32177
+ const result = new Array(right - left + 1);
32154
32178
  // Performance issue: nested loop is faster than a map here
32155
- for (let col = zone.left; col <= zone.right; col++) {
32156
- const rowValues = [];
32157
- for (let row = zone.top; row <= zone.bottom; row++) {
32179
+ for (let col = left; col <= right; col++) {
32180
+ const rowValues = new Array(bottom - top + 1);
32181
+ for (let row = top; row <= bottom; row++) {
32158
32182
  const cell = evalContext.getters.getCell({ sheetId: range.sheetId, col, row });
32159
- rowValues.push(cell ? getEvaluatedCell(cell) : undefined);
32183
+ rowValues[row - top] = cell ? getEvaluatedCell(cell) : undefined;
32160
32184
  }
32161
- result.push(rowValues);
32185
+ result[col - left] = rowValues;
32162
32186
  }
32187
+ rangeCache[cacheKey] = result;
32163
32188
  return result;
32164
32189
  }
32165
32190
  /**
@@ -42686,9 +42711,9 @@ function revertChanges(revisions) {
42686
42711
  * Apply the changes of the given HistoryChange to the state
42687
42712
  */
42688
42713
  function applyChange(change, target) {
42689
- let val = change.root;
42690
- let key = change.path[change.path.length - 1];
42691
- for (let pathIndex = 0; pathIndex < change.path.slice(0, -1).length; pathIndex++) {
42714
+ let val = change.path[0];
42715
+ const key = change.path[change.path.length - 1];
42716
+ for (let pathIndex = 1; pathIndex < change.path.slice(0, -1).length; pathIndex++) {
42692
42717
  const p = change.path[pathIndex];
42693
42718
  if (val[p] === undefined) {
42694
42719
  const nextPath = change.path[pathIndex + 1];
@@ -43445,13 +43470,14 @@ class StateObserver {
43445
43470
  }
43446
43471
  addChange(...args) {
43447
43472
  const val = args.pop();
43448
- const [root, ...path] = args;
43473
+ const root = args[0];
43449
43474
  let value = root;
43450
- let key = path[path.length - 1];
43451
- for (let pathIndex = 0; pathIndex <= path.length - 2; pathIndex++) {
43452
- const p = path[pathIndex];
43475
+ let key = args[args.length - 1];
43476
+ const pathLength = args.length - 2;
43477
+ for (let pathIndex = 1; pathIndex <= pathLength; pathIndex++) {
43478
+ const p = args[pathIndex];
43453
43479
  if (value[p] === undefined) {
43454
- const nextPath = path[pathIndex + 1];
43480
+ const nextPath = args[pathIndex + 1];
43455
43481
  value[p] = createEmptyStructure(nextPath);
43456
43482
  }
43457
43483
  value = value[p];
@@ -43460,8 +43486,7 @@ class StateObserver {
43460
43486
  return;
43461
43487
  }
43462
43488
  this.changes.push({
43463
- root,
43464
- path,
43489
+ path: args,
43465
43490
  before: value[key],
43466
43491
  after: val,
43467
43492
  });
@@ -45313,7 +45338,10 @@ class Model extends EventBus {
45313
45338
  */
45314
45339
  checkDispatchAllowed(command) {
45315
45340
  const results = this.handlers.map((handler) => handler.allowDispatch(command));
45316
- return new DispatchResult(results.flat());
45341
+ if (results.some((r) => r !== 0 /* CommandResult.Success */)) {
45342
+ return new DispatchResult(results.flat());
45343
+ }
45344
+ return DispatchResult.Success;
45317
45345
  }
45318
45346
  finalize() {
45319
45347
  this.status = 3 /* Status.Finalizing */;
@@ -45512,6 +45540,6 @@ function addFunction(functionName, functionDescription) {
45512
45540
  export { AbstractChart, CommandResult, CorePlugin, DATETIME_FORMAT, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateEvaluationCommands, links, load, parse, readonlyAllowedCommands, registries, setTranslationMethod, tokenize };
45513
45541
 
45514
45542
 
45515
- __info__.version = '16.2.22';
45516
- __info__.date = '2023-11-16T11:57:01.482Z';
45517
- __info__.hash = 'b78d5dd';
45543
+ __info__.version = '16.2.23';
45544
+ __info__.date = '2023-11-24T13:11:02.651Z';
45545
+ __info__.hash = '3c723d3';
@@ -604,13 +604,6 @@
604
604
  }
605
605
 
606
606
  //------------------------------------------------------------------------------
607
- /**
608
- * Stringify an object, like JSON.stringify, except that the first level of keys
609
- * is ordered.
610
- */
611
- function stringify(obj) {
612
- return JSON.stringify(obj, Object.keys(obj).sort());
613
- }
614
607
  /**
615
608
  * Remove quotes from a quoted string
616
609
  * ```js
@@ -910,7 +903,7 @@
910
903
  */
911
904
  function getItemId(item, itemsDic) {
912
905
  for (let [key, value] of Object.entries(itemsDic)) {
913
- if (stringify(value) === stringify(item)) {
906
+ if (deepEquals(value, item)) {
914
907
  return parseInt(key, 10);
915
908
  }
916
909
  }
@@ -976,6 +969,22 @@
976
969
  lazyValue.map = (callback) => lazy(() => callback(lazyValue()));
977
970
  return lazyValue;
978
971
  }
972
+ /**
973
+ * Creates a version of the function that's memoized on the value of its first
974
+ * argument, if any.
975
+ */
976
+ function memoize(func) {
977
+ const cache = new Map();
978
+ const funcName = func.name ? func.name + " (memoized)" : "memoized";
979
+ return {
980
+ [funcName](...args) {
981
+ if (!cache.has(args[0])) {
982
+ cache.set(args[0], func(...args));
983
+ }
984
+ return cache.get(args[0]);
985
+ },
986
+ }[funcName];
987
+ }
979
988
  /**
980
989
  * Find the next defined value after the given index in an array of strings. If there is no defined value
981
990
  * after the index, return the closest defined value before the index. Return an empty string if no
@@ -3573,12 +3582,12 @@
3573
3582
  }
3574
3583
  }
3575
3584
  /** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
3576
- function normalizeString(str) {
3585
+ const normalizeString = memoize(function normalizeString(str) {
3577
3586
  return str
3578
3587
  .toLowerCase()
3579
3588
  .normalize("NFD")
3580
3589
  .replace(/[\u0300-\u036f]/g, "");
3581
- }
3590
+ });
3582
3591
  /**
3583
3592
  * Normalize a value.
3584
3593
  * If the cell value is a string, this will set it to lowercase and replacing accent letters with plain letters
@@ -4302,6 +4311,7 @@
4302
4311
  CommandResult[CommandResult["ChartDoesNotExist"] = 85] = "ChartDoesNotExist";
4303
4312
  CommandResult[CommandResult["InvalidHeaderIndex"] = 86] = "InvalidHeaderIndex";
4304
4313
  CommandResult[CommandResult["InvalidQuantity"] = 87] = "InvalidQuantity";
4314
+ CommandResult[CommandResult["NoChanges"] = 88] = "NoChanges";
4305
4315
  })(exports.CommandResult || (exports.CommandResult = {}));
4306
4316
 
4307
4317
  function isMatrix(x) {
@@ -27517,6 +27527,14 @@
27517
27527
  // ---------------------------------------------------------------------------
27518
27528
  // Command Handling
27519
27529
  // ---------------------------------------------------------------------------
27530
+ allowDispatch(cmd) {
27531
+ switch (cmd.type) {
27532
+ case "SET_BORDER":
27533
+ return this.checkBordersUnchanged(cmd);
27534
+ default:
27535
+ return 0 /* CommandResult.Success */;
27536
+ }
27537
+ }
27520
27538
  handle(cmd) {
27521
27539
  switch (cmd.type) {
27522
27540
  case "ADD_MERGE":
@@ -27912,6 +27930,15 @@
27912
27930
  this.setBorders(sheetId, [{ ...zone, left: right }], "right");
27913
27931
  }
27914
27932
  }
27933
+ checkBordersUnchanged(cmd) {
27934
+ var _a, _b, _c, _d;
27935
+ const currentBorder = this.getCellBorder(cmd);
27936
+ const areAllNewBordersUndefined = !((_a = cmd.border) === null || _a === void 0 ? void 0 : _a.bottom) && !((_b = cmd.border) === null || _b === void 0 ? void 0 : _b.left) && !((_c = cmd.border) === null || _c === void 0 ? void 0 : _c.right) && !((_d = cmd.border) === null || _d === void 0 ? void 0 : _d.top);
27937
+ if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
27938
+ return 88 /* CommandResult.NoChanges */;
27939
+ }
27940
+ return 0 /* CommandResult.Success */;
27941
+ }
27915
27942
  // ---------------------------------------------------------------------------
27916
27943
  // Import/Export
27917
27944
  // ---------------------------------------------------------------------------
@@ -27947,7 +27974,7 @@
27947
27974
  */
27948
27975
  function getBorderId(border) {
27949
27976
  for (let [key, value] of Object.entries(borders)) {
27950
- if (stringify(value) === stringify(border)) {
27977
+ if (deepEquals(value, border)) {
27951
27978
  return parseInt(key, 10);
27952
27979
  }
27953
27980
  }
@@ -28014,8 +28041,9 @@
28014
28041
  allowDispatch(cmd) {
28015
28042
  switch (cmd.type) {
28016
28043
  case "UPDATE_CELL":
28044
+ return this.checkCellOutOfSheet(cmd);
28017
28045
  case "CLEAR_CELL":
28018
- return this.checkCellOutOfSheet(cmd.sheetId, cmd.col, cmd.row);
28046
+ return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
28019
28047
  default:
28020
28048
  return 0 /* CommandResult.Success */;
28021
28049
  }
@@ -28174,14 +28202,9 @@
28174
28202
  */
28175
28203
  getCellById(cellId) {
28176
28204
  // this must be as fast as possible
28177
- for (const sheetId in this.cells) {
28178
- const sheet = this.cells[sheetId];
28179
- const cell = sheet[cellId];
28180
- if (cell) {
28181
- return cell;
28182
- }
28183
- }
28184
- return undefined;
28205
+ const position = this.getters.getCellPosition(cellId);
28206
+ const sheet = this.cells[position.sheetId];
28207
+ return sheet[cellId];
28185
28208
  }
28186
28209
  /*
28187
28210
  * Reconstructs the original formula string based on a normalized form and its dependencies
@@ -28419,13 +28442,23 @@
28419
28442
  dependencies: [],
28420
28443
  };
28421
28444
  }
28422
- checkCellOutOfSheet(sheetId, col, row) {
28445
+ checkCellOutOfSheet(cmd) {
28446
+ const { sheetId, col, row } = cmd;
28423
28447
  const sheet = this.getters.tryGetSheet(sheetId);
28424
28448
  if (!sheet)
28425
28449
  return 27 /* CommandResult.InvalidSheetId */;
28426
28450
  const sheetZone = this.getters.getSheetZone(sheetId);
28427
28451
  return isInside(col, row, sheetZone) ? 0 /* CommandResult.Success */ : 18 /* CommandResult.TargetOutOfSheet */;
28428
28452
  }
28453
+ checkUselessClearCell(cmd) {
28454
+ const cell = this.getters.getCell(cmd);
28455
+ if (!cell)
28456
+ return 88 /* CommandResult.NoChanges */;
28457
+ if (!cell.content && !cell.style && !cell.format) {
28458
+ return 88 /* CommandResult.NoChanges */;
28459
+ }
28460
+ return 0 /* CommandResult.Success */;
28461
+ }
28429
28462
  }
28430
28463
  CellPlugin.getters = [
28431
28464
  "zoneToXC",
@@ -31491,10 +31524,13 @@
31491
31524
  // begin with the end.
31492
31525
  rows.sort((a, b) => b - a);
31493
31526
  for (let group of groupConsecutive(rows)) {
31527
+ // indexes are sorted in the descending order
31528
+ const from = group[group.length - 1];
31529
+ const to = group[0];
31494
31530
  // Move the cells.
31495
- this.moveCellOnRowsDeletion(sheet, group[group.length - 1], group[0]);
31496
- // Effectively delete the element and recompute the left-right/top-bottom.
31497
- group.map((row) => this.updateRowsStructureOnDeletion(row, sheet));
31531
+ this.moveCellOnRowsDeletion(sheet, from, to);
31532
+ // Effectively delete the rows
31533
+ this.updateRowsStructureOnDeletion(sheet, from, to);
31498
31534
  }
31499
31535
  const count = rows.filter((row) => row < sheet.panes.ySplit).length;
31500
31536
  if (count) {
@@ -31516,8 +31552,6 @@
31516
31552
  this.addEmptyRows(sheet, quantity);
31517
31553
  // Move the cells.
31518
31554
  this.moveCellsOnAddition(sheet, index, quantity, "rows");
31519
- // Recompute the left-right/top-bottom.
31520
- this.updateRowsStructureOnAddition(sheet, row, quantity);
31521
31555
  if (index < sheet.panes.ySplit) {
31522
31556
  this.setPaneDivisions(sheet.id, sheet.panes.ySplit + quantity, "ROW");
31523
31557
  }
@@ -31618,35 +31652,20 @@
31618
31652
  }
31619
31653
  }
31620
31654
  }
31621
- updateRowsStructureOnDeletion(index, sheet) {
31655
+ updateRowsStructureOnDeletion(sheet, deleteFromRow, deleteToRow) {
31622
31656
  const rows = [];
31623
- const cellsQueue = sheet.rows.map((row) => row.cells);
31657
+ const cellsQueue = sheet.rows.map((row) => row.cells).reverse();
31624
31658
  for (let i in sheet.rows) {
31625
- if (Number(i) === index) {
31659
+ const row = Number(i);
31660
+ if (row >= deleteFromRow && row <= deleteToRow) {
31626
31661
  continue;
31627
31662
  }
31628
31663
  rows.push({
31629
- cells: cellsQueue.shift(),
31664
+ cells: cellsQueue.pop(),
31630
31665
  });
31631
31666
  }
31632
31667
  this.history.update("sheets", sheet.id, "rows", rows);
31633
31668
  }
31634
- /**
31635
- * Update the rows of the sheet after an addition:
31636
- * - Rename the rows
31637
- *
31638
- * @param sheet Sheet on which the deletion occurs
31639
- * @param addedRow Index of the added row
31640
- * @param rowsToAdd Number of the rows to add
31641
- */
31642
- updateRowsStructureOnAddition(sheet, addedRow, rowsToAdd) {
31643
- const rows = [];
31644
- const cellsQueue = sheet.rows.map((row) => row.cells);
31645
- sheet.rows.forEach(() => rows.push({
31646
- cells: cellsQueue.shift(),
31647
- }));
31648
- this.history.update("sheets", sheet.id, "rows", rows);
31649
- }
31650
31669
  /**
31651
31670
  * Add empty rows at the end of the rows
31652
31671
  *
@@ -32130,6 +32149,7 @@
32130
32149
  }
32131
32150
  return evaluatedCell;
32132
32151
  };
32152
+ const rangeCache = {};
32133
32153
  /**
32134
32154
  * Return the values of the cell(s) used in reference, but always in the format of a range even
32135
32155
  * if a single cell is referenced. It is a list of col values. This is useful for the formulas that describe parameters as
@@ -32146,21 +32166,26 @@
32146
32166
  // Performance issue: Avoid fetching data on positions that are out of the spreadsheet
32147
32167
  // e.g. A1:ZZZ9999 in a sheet with 10 cols and 10 rows should ignore everything past J10 and return a 10x10 array
32148
32168
  const sheetZone = getters.getSheetZone(sheetId);
32149
- const result = [];
32150
32169
  const zone = intersection(range.zone, sheetZone);
32151
32170
  if (!zone) {
32152
- result.push([]);
32153
- return result;
32171
+ return [[]];
32172
+ }
32173
+ const { top, left, bottom, right } = zone;
32174
+ const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
32175
+ if (cacheKey in rangeCache) {
32176
+ return rangeCache[cacheKey];
32154
32177
  }
32178
+ const result = new Array(right - left + 1);
32155
32179
  // Performance issue: nested loop is faster than a map here
32156
- for (let col = zone.left; col <= zone.right; col++) {
32157
- const rowValues = [];
32158
- for (let row = zone.top; row <= zone.bottom; row++) {
32180
+ for (let col = left; col <= right; col++) {
32181
+ const rowValues = new Array(bottom - top + 1);
32182
+ for (let row = top; row <= bottom; row++) {
32159
32183
  const cell = evalContext.getters.getCell({ sheetId: range.sheetId, col, row });
32160
- rowValues.push(cell ? getEvaluatedCell(cell) : undefined);
32184
+ rowValues[row - top] = cell ? getEvaluatedCell(cell) : undefined;
32161
32185
  }
32162
- result.push(rowValues);
32186
+ result[col - left] = rowValues;
32163
32187
  }
32188
+ rangeCache[cacheKey] = result;
32164
32189
  return result;
32165
32190
  }
32166
32191
  /**
@@ -42687,9 +42712,9 @@
42687
42712
  * Apply the changes of the given HistoryChange to the state
42688
42713
  */
42689
42714
  function applyChange(change, target) {
42690
- let val = change.root;
42691
- let key = change.path[change.path.length - 1];
42692
- for (let pathIndex = 0; pathIndex < change.path.slice(0, -1).length; pathIndex++) {
42715
+ let val = change.path[0];
42716
+ const key = change.path[change.path.length - 1];
42717
+ for (let pathIndex = 1; pathIndex < change.path.slice(0, -1).length; pathIndex++) {
42693
42718
  const p = change.path[pathIndex];
42694
42719
  if (val[p] === undefined) {
42695
42720
  const nextPath = change.path[pathIndex + 1];
@@ -43446,13 +43471,14 @@
43446
43471
  }
43447
43472
  addChange(...args) {
43448
43473
  const val = args.pop();
43449
- const [root, ...path] = args;
43474
+ const root = args[0];
43450
43475
  let value = root;
43451
- let key = path[path.length - 1];
43452
- for (let pathIndex = 0; pathIndex <= path.length - 2; pathIndex++) {
43453
- const p = path[pathIndex];
43476
+ let key = args[args.length - 1];
43477
+ const pathLength = args.length - 2;
43478
+ for (let pathIndex = 1; pathIndex <= pathLength; pathIndex++) {
43479
+ const p = args[pathIndex];
43454
43480
  if (value[p] === undefined) {
43455
- const nextPath = path[pathIndex + 1];
43481
+ const nextPath = args[pathIndex + 1];
43456
43482
  value[p] = createEmptyStructure(nextPath);
43457
43483
  }
43458
43484
  value = value[p];
@@ -43461,8 +43487,7 @@
43461
43487
  return;
43462
43488
  }
43463
43489
  this.changes.push({
43464
- root,
43465
- path,
43490
+ path: args,
43466
43491
  before: value[key],
43467
43492
  after: val,
43468
43493
  });
@@ -45314,7 +45339,10 @@
45314
45339
  */
45315
45340
  checkDispatchAllowed(command) {
45316
45341
  const results = this.handlers.map((handler) => handler.allowDispatch(command));
45317
- return new DispatchResult(results.flat());
45342
+ if (results.some((r) => r !== 0 /* CommandResult.Success */)) {
45343
+ return new DispatchResult(results.flat());
45344
+ }
45345
+ return DispatchResult.Success;
45318
45346
  }
45319
45347
  finalize() {
45320
45348
  this.status = 3 /* Status.Finalizing */;
@@ -45543,9 +45571,9 @@
45543
45571
  Object.defineProperty(exports, '__esModule', { value: true });
45544
45572
 
45545
45573
 
45546
- __info__.version = '16.2.22';
45547
- __info__.date = '2023-11-16T11:57:01.482Z';
45548
- __info__.hash = 'b78d5dd';
45574
+ __info__.version = '16.2.23';
45575
+ __info__.date = '2023-11-24T13:11:02.651Z';
45576
+ __info__.hash = '3c723d3';
45549
45577
 
45550
45578
 
45551
45579
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);