@odoo/o-spreadsheet 16.2.17 → 16.2.19

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.
@@ -302,7 +302,16 @@ const DATE_JS_1900_OFFSET = INITIAL_JS_DAY - INITIAL_1900_DAY;
302
302
  const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
303
303
  const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
304
304
  const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
305
+ const CACHE = {};
305
306
  function parseDateTime(str) {
307
+ if (str in CACHE) {
308
+ return CACHE[str];
309
+ }
310
+ const date = _parseDateTime(str);
311
+ CACHE[str] = date;
312
+ return date;
313
+ }
314
+ function _parseDateTime(str) {
306
315
  str = str.trim();
307
316
  let time;
308
317
  const timeMatch = str.match(timeRegexp);
@@ -2144,8 +2153,9 @@ class RangeImpl {
2144
2153
  }
2145
2154
  get zone() {
2146
2155
  const { left, top, bottom, right } = this._zone;
2147
- if (right !== undefined && bottom !== undefined)
2148
- return { left, top, right, bottom };
2156
+ if (right !== undefined && bottom !== undefined) {
2157
+ return this._zone;
2158
+ }
2149
2159
  else if (bottom === undefined && right !== undefined) {
2150
2160
  return { right, top, left, bottom: this.getSheetSize(this.sheetId).numberOfRows - 1 };
2151
2161
  }
@@ -4297,6 +4307,9 @@ exports.CommandResult = void 0;
4297
4307
  CommandResult[CommandResult["InvalidQuantity"] = 87] = "InvalidQuantity";
4298
4308
  })(exports.CommandResult || (exports.CommandResult = {}));
4299
4309
 
4310
+ function isMatrix(x) {
4311
+ return Array.isArray(x) && Array.isArray(x[0]);
4312
+ }
4300
4313
  var DIRECTION;
4301
4314
  (function (DIRECTION) {
4302
4315
  DIRECTION["UP"] = "up";
@@ -15163,6 +15176,36 @@ const HLOOKUP = {
15163
15176
  isExported: true,
15164
15177
  };
15165
15178
  // -----------------------------------------------------------------------------
15179
+ // INDEX
15180
+ // -----------------------------------------------------------------------------
15181
+ const INDEX = {
15182
+ description: _lt(`Returns the content of a cell, specified by row and column offset.`),
15183
+ args: [
15184
+ arg("reference (any, range)", _lt("The range of cells from which the values are returned.")),
15185
+ arg("row (number)", _lt("The index of the row to be returned from within the reference range of cells.")),
15186
+ arg("column (number)", _lt("The index of the column to be returned from within the reference range of cells.")),
15187
+ ],
15188
+ returns: ["ANY"],
15189
+ computeFormat: (reference, row, column) => {
15190
+ var _a;
15191
+ const _row = toNumber(row.value);
15192
+ const _column = toNumber(column.value);
15193
+ return (_a = reference[_column - 1][_row - 1]) === null || _a === void 0 ? void 0 : _a.format;
15194
+ },
15195
+ compute: function (reference, row, column) {
15196
+ const _reference = isMatrix(reference) ? reference : [[reference]];
15197
+ const _row = toNumber(row);
15198
+ const _column = toNumber(column);
15199
+ assert(() => _column >= 0 &&
15200
+ _column - 1 < _reference.length &&
15201
+ _row >= 0 &&
15202
+ _row - 1 < _reference[0].length, _lt("Index out of range."));
15203
+ assert(() => row !== 0 && column !== 0, _lt("This function can only return a single cell value, not an array. Provide valid row and column indices."));
15204
+ return _reference[_column - 1][_row - 1];
15205
+ },
15206
+ isExported: true,
15207
+ };
15208
+ // -----------------------------------------------------------------------------
15166
15209
  // LOOKUP
15167
15210
  // -----------------------------------------------------------------------------
15168
15211
  const LOOKUP = {
@@ -15357,6 +15400,7 @@ var lookup = /*#__PURE__*/Object.freeze({
15357
15400
  COLUMN: COLUMN,
15358
15401
  COLUMNS: COLUMNS,
15359
15402
  HLOOKUP: HLOOKUP,
15403
+ INDEX: INDEX,
15360
15404
  LOOKUP: LOOKUP,
15361
15405
  MATCH: MATCH,
15362
15406
  ROW: ROW,
@@ -21176,7 +21220,14 @@ class AbstractResizer extends owl.Component {
21176
21220
  return;
21177
21221
  }
21178
21222
  if (this.state.waitingForMove === true) {
21179
- this.startMovement(ev);
21223
+ if (!this.env.model.getters.isGridSelectionActive()) {
21224
+ this._selectElement(index, false);
21225
+ }
21226
+ else {
21227
+ // FIXME: Consider reintroducing this feature for all type of selection if we find
21228
+ // a way to have the grid selection follow the other selections evolution
21229
+ this.startMovement(ev);
21230
+ }
21180
21231
  return;
21181
21232
  }
21182
21233
  if (this.env.model.getters.getEditionMode() === "editing") {
@@ -25509,12 +25560,15 @@ function createXMLFile(doc, path, contentType) {
25509
25560
  };
25510
25561
  }
25511
25562
  function xmlEscape(str) {
25512
- return String(str)
25563
+ return (String(str)
25513
25564
  .replace(/\&/g, "&amp;")
25514
25565
  .replace(/\</g, "&lt;")
25515
25566
  .replace(/\>/g, "&gt;")
25516
25567
  .replace(/\"/g, "&quot;")
25517
- .replace(/\'/g, "&apos;");
25568
+ .replace(/\'/g, "&apos;")
25569
+ // Delete all ASCII control characters except for TAB (\x09), LF (\x0A) and CR (\x0D)
25570
+ // They are not valid at all in XML 1.0 (even escaped)
25571
+ .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, ""));
25518
25572
  }
25519
25573
  function formatAttributes(attrs) {
25520
25574
  return new XMLString(attrs.map(([key, val]) => `${key}="${xmlEscape(val)}"`).join(" "));
@@ -28136,10 +28190,11 @@ class CellPlugin extends CorePlugin {
28136
28190
  * Reconstructs the original formula string based on a normalized form and its dependencies
28137
28191
  */
28138
28192
  buildFormulaContent(sheetId, cell, dependencies) {
28139
- const ranges = dependencies || [...cell.dependencies];
28193
+ const ranges = dependencies || cell.dependencies;
28194
+ let rangeIndex = 0;
28140
28195
  return concat(cell.compiledFormula.tokens.map((token) => {
28141
28196
  if (token.type === "REFERENCE") {
28142
- const range = ranges.shift();
28197
+ const range = ranges[rangeIndex++];
28143
28198
  return this.getters.getRangeString(range, sheetId);
28144
28199
  }
28145
28200
  return token.value;
@@ -32576,6 +32631,10 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
32576
32631
  }
32577
32632
  currentRanges = currentRanges.concat(toAdd);
32578
32633
  const newRangesXC = recomputeZones(currentRanges, toRemove);
32634
+ if (newRangesXC.length === 0) {
32635
+ this.dispatch("REMOVE_CONDITIONAL_FORMAT", { id: cf.id, sheetId });
32636
+ return;
32637
+ }
32579
32638
  this.dispatch("ADD_CONDITIONAL_FORMAT", {
32580
32639
  cf: {
32581
32640
  id: cf.id,
@@ -39245,6 +39304,9 @@ class GridSelectionPlugin extends UIPlugin {
39245
39304
  // ---------------------------------------------------------------------------
39246
39305
  // Getters
39247
39306
  // ---------------------------------------------------------------------------
39307
+ isGridSelectionActive() {
39308
+ return this.selection.isListening(this);
39309
+ }
39248
39310
  getActiveSheet() {
39249
39311
  return this.activeSheet;
39250
39312
  }
@@ -39619,6 +39681,7 @@ GridSelectionPlugin.getters = [
39619
39681
  "getSheetPosition",
39620
39682
  "isSelected",
39621
39683
  "getElementsFromSelection",
39684
+ "isGridSelectionActive",
39622
39685
  ];
39623
39686
 
39624
39687
  const corePluginRegistry = new Registry()
@@ -43097,6 +43160,9 @@ class SelectionStreamProcessorImpl {
43097
43160
  anchor: { zone, cell: this.anchor.cell },
43098
43161
  });
43099
43162
  }
43163
+ isListening(owner) {
43164
+ return this.stream.isListening(owner);
43165
+ }
43100
43166
  /**
43101
43167
  * Process a new anchor selection event. If the new anchor is inside
43102
43168
  * the sheet boundaries, the event is pushed to the event stream to
@@ -45460,6 +45526,6 @@ exports.setTranslationMethod = setTranslationMethod;
45460
45526
  exports.tokenize = tokenize;
45461
45527
 
45462
45528
 
45463
- __info__.version = '16.2.17';
45464
- __info__.date = '2023-10-03T12:42:54.642Z';
45465
- __info__.hash = '146867a';
45529
+ __info__.version = '16.2.19';
45530
+ __info__.date = '2023-10-19T14:22:48.890Z';
45531
+ __info__.hash = '79980d5';
@@ -249,7 +249,7 @@ declare class RangeImpl implements Range {
249
249
  constructor(args: ConstructorArgs, getSheetSize: (sheetId: UID) => ZoneDimension);
250
250
  static fromRange(range: Range, getters: CoreGetters): RangeImpl;
251
251
  get unboundedZone(): UnboundedZone;
252
- get zone(): Zone;
252
+ get zone(): Readonly<Zone>;
253
253
  static getRangeParts(xc: string, zone: UnboundedZone): RangePart[];
254
254
  get isFullCol(): boolean;
255
255
  get isFullRow(): boolean;
@@ -347,6 +347,7 @@ interface SelectionProcessor {
347
347
  selectAll(): DispatchResult;
348
348
  loopSelection(): DispatchResult;
349
349
  selectTableAroundSelection(): DispatchResult;
350
+ isListening(owner: unknown): boolean;
350
351
  }
351
352
  type SelectionStreamProcessor = SelectionProcessor & StatefulStream<SelectionEvent, AnchorZone>;
352
353
 
@@ -4554,7 +4555,7 @@ declare class ClipboardPlugin extends UIPlugin {
4554
4555
  */
4555
4556
  declare class GridSelectionPlugin extends UIPlugin {
4556
4557
  static layers: LAYERS[];
4557
- static getters: readonly ["getActiveSheet", "getActiveSheetId", "getActiveCell", "getActiveCols", "getActiveRows", "getCurrentStyle", "getSelectedZones", "getSelectedZone", "getStatisticFnResults", "getAggregate", "getSelectedFigureId", "getSelection", "getActivePosition", "getSheetPosition", "isSelected", "getElementsFromSelection"];
4558
+ static getters: readonly ["getActiveSheet", "getActiveSheetId", "getActiveCell", "getActiveCols", "getActiveRows", "getCurrentStyle", "getSelectedZones", "getSelectedZone", "getStatisticFnResults", "getAggregate", "getSelectedFigureId", "getSelection", "getActivePosition", "getSheetPosition", "isSelected", "getElementsFromSelection", "isGridSelectionActive"];
4558
4559
  private gridSelection;
4559
4560
  private selectedFigureId;
4560
4561
  private sheetsData;
@@ -4564,6 +4565,7 @@ declare class GridSelectionPlugin extends UIPlugin {
4564
4565
  allowDispatch(cmd: Command): CommandResult;
4565
4566
  private handleEvent;
4566
4567
  handle(cmd: Command): void;
4568
+ isGridSelectionActive(): boolean;
4567
4569
  getActiveSheet(): Readonly<Sheet>;
4568
4570
  getActiveSheetId(): UID;
4569
4571
  getActiveCell(): EvaluatedCell;
@@ -298,7 +298,16 @@ const DATE_JS_1900_OFFSET = INITIAL_JS_DAY - INITIAL_1900_DAY;
298
298
  const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
299
299
  const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
300
300
  const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
301
+ const CACHE = {};
301
302
  function parseDateTime(str) {
303
+ if (str in CACHE) {
304
+ return CACHE[str];
305
+ }
306
+ const date = _parseDateTime(str);
307
+ CACHE[str] = date;
308
+ return date;
309
+ }
310
+ function _parseDateTime(str) {
302
311
  str = str.trim();
303
312
  let time;
304
313
  const timeMatch = str.match(timeRegexp);
@@ -2140,8 +2149,9 @@ class RangeImpl {
2140
2149
  }
2141
2150
  get zone() {
2142
2151
  const { left, top, bottom, right } = this._zone;
2143
- if (right !== undefined && bottom !== undefined)
2144
- return { left, top, right, bottom };
2152
+ if (right !== undefined && bottom !== undefined) {
2153
+ return this._zone;
2154
+ }
2145
2155
  else if (bottom === undefined && right !== undefined) {
2146
2156
  return { right, top, left, bottom: this.getSheetSize(this.sheetId).numberOfRows - 1 };
2147
2157
  }
@@ -4293,6 +4303,9 @@ var CommandResult;
4293
4303
  CommandResult[CommandResult["InvalidQuantity"] = 87] = "InvalidQuantity";
4294
4304
  })(CommandResult || (CommandResult = {}));
4295
4305
 
4306
+ function isMatrix(x) {
4307
+ return Array.isArray(x) && Array.isArray(x[0]);
4308
+ }
4296
4309
  var DIRECTION;
4297
4310
  (function (DIRECTION) {
4298
4311
  DIRECTION["UP"] = "up";
@@ -15159,6 +15172,36 @@ const HLOOKUP = {
15159
15172
  isExported: true,
15160
15173
  };
15161
15174
  // -----------------------------------------------------------------------------
15175
+ // INDEX
15176
+ // -----------------------------------------------------------------------------
15177
+ const INDEX = {
15178
+ description: _lt(`Returns the content of a cell, specified by row and column offset.`),
15179
+ args: [
15180
+ arg("reference (any, range)", _lt("The range of cells from which the values are returned.")),
15181
+ arg("row (number)", _lt("The index of the row to be returned from within the reference range of cells.")),
15182
+ arg("column (number)", _lt("The index of the column to be returned from within the reference range of cells.")),
15183
+ ],
15184
+ returns: ["ANY"],
15185
+ computeFormat: (reference, row, column) => {
15186
+ var _a;
15187
+ const _row = toNumber(row.value);
15188
+ const _column = toNumber(column.value);
15189
+ return (_a = reference[_column - 1][_row - 1]) === null || _a === void 0 ? void 0 : _a.format;
15190
+ },
15191
+ compute: function (reference, row, column) {
15192
+ const _reference = isMatrix(reference) ? reference : [[reference]];
15193
+ const _row = toNumber(row);
15194
+ const _column = toNumber(column);
15195
+ assert(() => _column >= 0 &&
15196
+ _column - 1 < _reference.length &&
15197
+ _row >= 0 &&
15198
+ _row - 1 < _reference[0].length, _lt("Index out of range."));
15199
+ assert(() => row !== 0 && column !== 0, _lt("This function can only return a single cell value, not an array. Provide valid row and column indices."));
15200
+ return _reference[_column - 1][_row - 1];
15201
+ },
15202
+ isExported: true,
15203
+ };
15204
+ // -----------------------------------------------------------------------------
15162
15205
  // LOOKUP
15163
15206
  // -----------------------------------------------------------------------------
15164
15207
  const LOOKUP = {
@@ -15353,6 +15396,7 @@ var lookup = /*#__PURE__*/Object.freeze({
15353
15396
  COLUMN: COLUMN,
15354
15397
  COLUMNS: COLUMNS,
15355
15398
  HLOOKUP: HLOOKUP,
15399
+ INDEX: INDEX,
15356
15400
  LOOKUP: LOOKUP,
15357
15401
  MATCH: MATCH,
15358
15402
  ROW: ROW,
@@ -21172,7 +21216,14 @@ class AbstractResizer extends Component {
21172
21216
  return;
21173
21217
  }
21174
21218
  if (this.state.waitingForMove === true) {
21175
- this.startMovement(ev);
21219
+ if (!this.env.model.getters.isGridSelectionActive()) {
21220
+ this._selectElement(index, false);
21221
+ }
21222
+ else {
21223
+ // FIXME: Consider reintroducing this feature for all type of selection if we find
21224
+ // a way to have the grid selection follow the other selections evolution
21225
+ this.startMovement(ev);
21226
+ }
21176
21227
  return;
21177
21228
  }
21178
21229
  if (this.env.model.getters.getEditionMode() === "editing") {
@@ -25505,12 +25556,15 @@ function createXMLFile(doc, path, contentType) {
25505
25556
  };
25506
25557
  }
25507
25558
  function xmlEscape(str) {
25508
- return String(str)
25559
+ return (String(str)
25509
25560
  .replace(/\&/g, "&amp;")
25510
25561
  .replace(/\</g, "&lt;")
25511
25562
  .replace(/\>/g, "&gt;")
25512
25563
  .replace(/\"/g, "&quot;")
25513
- .replace(/\'/g, "&apos;");
25564
+ .replace(/\'/g, "&apos;")
25565
+ // Delete all ASCII control characters except for TAB (\x09), LF (\x0A) and CR (\x0D)
25566
+ // They are not valid at all in XML 1.0 (even escaped)
25567
+ .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, ""));
25514
25568
  }
25515
25569
  function formatAttributes(attrs) {
25516
25570
  return new XMLString(attrs.map(([key, val]) => `${key}="${xmlEscape(val)}"`).join(" "));
@@ -28132,10 +28186,11 @@ class CellPlugin extends CorePlugin {
28132
28186
  * Reconstructs the original formula string based on a normalized form and its dependencies
28133
28187
  */
28134
28188
  buildFormulaContent(sheetId, cell, dependencies) {
28135
- const ranges = dependencies || [...cell.dependencies];
28189
+ const ranges = dependencies || cell.dependencies;
28190
+ let rangeIndex = 0;
28136
28191
  return concat(cell.compiledFormula.tokens.map((token) => {
28137
28192
  if (token.type === "REFERENCE") {
28138
- const range = ranges.shift();
28193
+ const range = ranges[rangeIndex++];
28139
28194
  return this.getters.getRangeString(range, sheetId);
28140
28195
  }
28141
28196
  return token.value;
@@ -32572,6 +32627,10 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
32572
32627
  }
32573
32628
  currentRanges = currentRanges.concat(toAdd);
32574
32629
  const newRangesXC = recomputeZones(currentRanges, toRemove);
32630
+ if (newRangesXC.length === 0) {
32631
+ this.dispatch("REMOVE_CONDITIONAL_FORMAT", { id: cf.id, sheetId });
32632
+ return;
32633
+ }
32575
32634
  this.dispatch("ADD_CONDITIONAL_FORMAT", {
32576
32635
  cf: {
32577
32636
  id: cf.id,
@@ -39241,6 +39300,9 @@ class GridSelectionPlugin extends UIPlugin {
39241
39300
  // ---------------------------------------------------------------------------
39242
39301
  // Getters
39243
39302
  // ---------------------------------------------------------------------------
39303
+ isGridSelectionActive() {
39304
+ return this.selection.isListening(this);
39305
+ }
39244
39306
  getActiveSheet() {
39245
39307
  return this.activeSheet;
39246
39308
  }
@@ -39615,6 +39677,7 @@ GridSelectionPlugin.getters = [
39615
39677
  "getSheetPosition",
39616
39678
  "isSelected",
39617
39679
  "getElementsFromSelection",
39680
+ "isGridSelectionActive",
39618
39681
  ];
39619
39682
 
39620
39683
  const corePluginRegistry = new Registry()
@@ -43093,6 +43156,9 @@ class SelectionStreamProcessorImpl {
43093
43156
  anchor: { zone, cell: this.anchor.cell },
43094
43157
  });
43095
43158
  }
43159
+ isListening(owner) {
43160
+ return this.stream.isListening(owner);
43161
+ }
43096
43162
  /**
43097
43163
  * Process a new anchor selection event. If the new anchor is inside
43098
43164
  * the sheet boundaries, the event is pushed to the event stream to
@@ -45428,6 +45494,6 @@ function addFunction(functionName, functionDescription) {
45428
45494
  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 };
45429
45495
 
45430
45496
 
45431
- __info__.version = '16.2.17';
45432
- __info__.date = '2023-10-03T12:42:54.642Z';
45433
- __info__.hash = '146867a';
45497
+ __info__.version = '16.2.19';
45498
+ __info__.date = '2023-10-19T14:22:48.890Z';
45499
+ __info__.hash = '79980d5';
@@ -299,7 +299,16 @@
299
299
  const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
300
300
  const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
301
301
  const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
302
+ const CACHE = {};
302
303
  function parseDateTime(str) {
304
+ if (str in CACHE) {
305
+ return CACHE[str];
306
+ }
307
+ const date = _parseDateTime(str);
308
+ CACHE[str] = date;
309
+ return date;
310
+ }
311
+ function _parseDateTime(str) {
303
312
  str = str.trim();
304
313
  let time;
305
314
  const timeMatch = str.match(timeRegexp);
@@ -2141,8 +2150,9 @@
2141
2150
  }
2142
2151
  get zone() {
2143
2152
  const { left, top, bottom, right } = this._zone;
2144
- if (right !== undefined && bottom !== undefined)
2145
- return { left, top, right, bottom };
2153
+ if (right !== undefined && bottom !== undefined) {
2154
+ return this._zone;
2155
+ }
2146
2156
  else if (bottom === undefined && right !== undefined) {
2147
2157
  return { right, top, left, bottom: this.getSheetSize(this.sheetId).numberOfRows - 1 };
2148
2158
  }
@@ -4294,6 +4304,9 @@
4294
4304
  CommandResult[CommandResult["InvalidQuantity"] = 87] = "InvalidQuantity";
4295
4305
  })(exports.CommandResult || (exports.CommandResult = {}));
4296
4306
 
4307
+ function isMatrix(x) {
4308
+ return Array.isArray(x) && Array.isArray(x[0]);
4309
+ }
4297
4310
  var DIRECTION;
4298
4311
  (function (DIRECTION) {
4299
4312
  DIRECTION["UP"] = "up";
@@ -15160,6 +15173,36 @@
15160
15173
  isExported: true,
15161
15174
  };
15162
15175
  // -----------------------------------------------------------------------------
15176
+ // INDEX
15177
+ // -----------------------------------------------------------------------------
15178
+ const INDEX = {
15179
+ description: _lt(`Returns the content of a cell, specified by row and column offset.`),
15180
+ args: [
15181
+ arg("reference (any, range)", _lt("The range of cells from which the values are returned.")),
15182
+ arg("row (number)", _lt("The index of the row to be returned from within the reference range of cells.")),
15183
+ arg("column (number)", _lt("The index of the column to be returned from within the reference range of cells.")),
15184
+ ],
15185
+ returns: ["ANY"],
15186
+ computeFormat: (reference, row, column) => {
15187
+ var _a;
15188
+ const _row = toNumber(row.value);
15189
+ const _column = toNumber(column.value);
15190
+ return (_a = reference[_column - 1][_row - 1]) === null || _a === void 0 ? void 0 : _a.format;
15191
+ },
15192
+ compute: function (reference, row, column) {
15193
+ const _reference = isMatrix(reference) ? reference : [[reference]];
15194
+ const _row = toNumber(row);
15195
+ const _column = toNumber(column);
15196
+ assert(() => _column >= 0 &&
15197
+ _column - 1 < _reference.length &&
15198
+ _row >= 0 &&
15199
+ _row - 1 < _reference[0].length, _lt("Index out of range."));
15200
+ assert(() => row !== 0 && column !== 0, _lt("This function can only return a single cell value, not an array. Provide valid row and column indices."));
15201
+ return _reference[_column - 1][_row - 1];
15202
+ },
15203
+ isExported: true,
15204
+ };
15205
+ // -----------------------------------------------------------------------------
15163
15206
  // LOOKUP
15164
15207
  // -----------------------------------------------------------------------------
15165
15208
  const LOOKUP = {
@@ -15354,6 +15397,7 @@
15354
15397
  COLUMN: COLUMN,
15355
15398
  COLUMNS: COLUMNS,
15356
15399
  HLOOKUP: HLOOKUP,
15400
+ INDEX: INDEX,
15357
15401
  LOOKUP: LOOKUP,
15358
15402
  MATCH: MATCH,
15359
15403
  ROW: ROW,
@@ -21173,7 +21217,14 @@
21173
21217
  return;
21174
21218
  }
21175
21219
  if (this.state.waitingForMove === true) {
21176
- this.startMovement(ev);
21220
+ if (!this.env.model.getters.isGridSelectionActive()) {
21221
+ this._selectElement(index, false);
21222
+ }
21223
+ else {
21224
+ // FIXME: Consider reintroducing this feature for all type of selection if we find
21225
+ // a way to have the grid selection follow the other selections evolution
21226
+ this.startMovement(ev);
21227
+ }
21177
21228
  return;
21178
21229
  }
21179
21230
  if (this.env.model.getters.getEditionMode() === "editing") {
@@ -25506,12 +25557,15 @@
25506
25557
  };
25507
25558
  }
25508
25559
  function xmlEscape(str) {
25509
- return String(str)
25560
+ return (String(str)
25510
25561
  .replace(/\&/g, "&amp;")
25511
25562
  .replace(/\</g, "&lt;")
25512
25563
  .replace(/\>/g, "&gt;")
25513
25564
  .replace(/\"/g, "&quot;")
25514
- .replace(/\'/g, "&apos;");
25565
+ .replace(/\'/g, "&apos;")
25566
+ // Delete all ASCII control characters except for TAB (\x09), LF (\x0A) and CR (\x0D)
25567
+ // They are not valid at all in XML 1.0 (even escaped)
25568
+ .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, ""));
25515
25569
  }
25516
25570
  function formatAttributes(attrs) {
25517
25571
  return new XMLString(attrs.map(([key, val]) => `${key}="${xmlEscape(val)}"`).join(" "));
@@ -28133,10 +28187,11 @@
28133
28187
  * Reconstructs the original formula string based on a normalized form and its dependencies
28134
28188
  */
28135
28189
  buildFormulaContent(sheetId, cell, dependencies) {
28136
- const ranges = dependencies || [...cell.dependencies];
28190
+ const ranges = dependencies || cell.dependencies;
28191
+ let rangeIndex = 0;
28137
28192
  return concat(cell.compiledFormula.tokens.map((token) => {
28138
28193
  if (token.type === "REFERENCE") {
28139
- const range = ranges.shift();
28194
+ const range = ranges[rangeIndex++];
28140
28195
  return this.getters.getRangeString(range, sheetId);
28141
28196
  }
28142
28197
  return token.value;
@@ -32573,6 +32628,10 @@
32573
32628
  }
32574
32629
  currentRanges = currentRanges.concat(toAdd);
32575
32630
  const newRangesXC = recomputeZones(currentRanges, toRemove);
32631
+ if (newRangesXC.length === 0) {
32632
+ this.dispatch("REMOVE_CONDITIONAL_FORMAT", { id: cf.id, sheetId });
32633
+ return;
32634
+ }
32576
32635
  this.dispatch("ADD_CONDITIONAL_FORMAT", {
32577
32636
  cf: {
32578
32637
  id: cf.id,
@@ -39242,6 +39301,9 @@
39242
39301
  // ---------------------------------------------------------------------------
39243
39302
  // Getters
39244
39303
  // ---------------------------------------------------------------------------
39304
+ isGridSelectionActive() {
39305
+ return this.selection.isListening(this);
39306
+ }
39245
39307
  getActiveSheet() {
39246
39308
  return this.activeSheet;
39247
39309
  }
@@ -39616,6 +39678,7 @@
39616
39678
  "getSheetPosition",
39617
39679
  "isSelected",
39618
39680
  "getElementsFromSelection",
39681
+ "isGridSelectionActive",
39619
39682
  ];
39620
39683
 
39621
39684
  const corePluginRegistry = new Registry()
@@ -43094,6 +43157,9 @@
43094
43157
  anchor: { zone, cell: this.anchor.cell },
43095
43158
  });
43096
43159
  }
43160
+ isListening(owner) {
43161
+ return this.stream.isListening(owner);
43162
+ }
43097
43163
  /**
43098
43164
  * Process a new anchor selection event. If the new anchor is inside
43099
43165
  * the sheet boundaries, the event is pushed to the event stream to
@@ -45459,9 +45525,9 @@
45459
45525
  Object.defineProperty(exports, '__esModule', { value: true });
45460
45526
 
45461
45527
 
45462
- __info__.version = '16.2.17';
45463
- __info__.date = '2023-10-03T12:42:54.642Z';
45464
- __info__.hash = '146867a';
45528
+ __info__.version = '16.2.19';
45529
+ __info__.date = '2023-10-19T14:22:48.890Z';
45530
+ __info__.hash = '79980d5';
45465
45531
 
45466
45532
 
45467
45533
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);