@odoo/o-spreadsheet 18.1.21 → 18.1.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.
@@ -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.1.21
6
- * @date 2025-05-20T05:54:45.398Z
7
- * @hash 89ed6a9
5
+ * @version 18.1.23
6
+ * @date 2025-05-30T08:45:44.408Z
7
+ * @hash a21fa01
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -4140,6 +4140,113 @@ function transposeMatrix(matrix) {
4140
4140
  }
4141
4141
  return generateMatrix(matrix[0].length, matrix.length, (i, j) => matrix[j][i]);
4142
4142
  }
4143
+ /**
4144
+ * Enables a formula function to accept matrix or vector inputs instead of simple value, computing results across multiple dimensions.
4145
+ *
4146
+ * ```
4147
+ * / |‾ ‾| \ |‾ ‾|
4148
+ * | | [A] | | | compute(A, D, E), compute(A, D, F), compute(A, D, G) |
4149
+ * applyVectorization| compute, | [B], D, [E, F, G] | | <=> | compute(B, D, E), compute(B, D, F), compute(B, D, G) |
4150
+ * | | [C] | | | compute(C, D, E), compute(C, D, F), compute(C, D, G) |
4151
+ * \ |_ _| / |_ _|
4152
+ * ```
4153
+ *
4154
+ * By default, all arguments are vectorized. To control which arguments are vectorized,
4155
+ * pass an `acceptToVectorize` boolean array of the same length as `args`:
4156
+ * - `true` enables vectorization for that argument
4157
+ * - `false` disables vectorization for that argument
4158
+ *
4159
+ * For example, with `[true, true, false]` on previous example you get:
4160
+ *
4161
+ * ```
4162
+ * |‾ ‾|
4163
+ * | compute(A, D, [E, F, G]) |
4164
+ * | compute(B, D, [E, F, G]) |
4165
+ * | compute(C, D, [E, F, G]) |
4166
+ * |_ _|
4167
+ * ```
4168
+ *
4169
+ * @remarks
4170
+ * This helper is automatically applied (by default) to **all** `compute` functions
4171
+ * across the various spreadsheet formula modules:
4172
+ * - If an argument is declared **scalar** (not `"range"`), it is vectorized.
4173
+ * - If **all** arguments are declared **ranges**, no vectorization occurs.
4174
+ * - e.g. `SUM(A1:B2)` returns a 1×1 sum over the range.
4175
+ * - e.g. `COS(A1:B2)` over `A1:B2` returns a 2×2 element-wise result.
4176
+ * - For special behaviors (e.g. the `IF` function), you may declare all arguments
4177
+ * as ranges and invoke this helper directly within your `compute` implementation.
4178
+ */
4179
+ function applyVectorization(formula, args, acceptToVectorize = undefined) {
4180
+ let countVectorizedCol = 1;
4181
+ let countVectorizedRow = 1;
4182
+ let vectorizedColLimit = Infinity;
4183
+ let vectorizedRowLimit = Infinity;
4184
+ let vectorArgsType = undefined;
4185
+ for (let i = 0; i < args.length; i++) {
4186
+ const arg = args[i];
4187
+ if (isMatrix(arg) && (acceptToVectorize === undefined || acceptToVectorize[i])) {
4188
+ const nColumns = arg.length;
4189
+ const nRows = arg[0].length;
4190
+ if (nColumns !== 1 || nRows !== 1) {
4191
+ vectorArgsType ??= new Array(args.length);
4192
+ if (nColumns !== 1 && nRows !== 1) {
4193
+ vectorArgsType[i] = "matrix";
4194
+ countVectorizedCol = Math.max(countVectorizedCol, nColumns);
4195
+ countVectorizedRow = Math.max(countVectorizedRow, nRows);
4196
+ vectorizedColLimit = Math.min(vectorizedColLimit, nColumns);
4197
+ vectorizedRowLimit = Math.min(vectorizedRowLimit, nRows);
4198
+ }
4199
+ else if (nColumns !== 1) {
4200
+ vectorArgsType[i] = "horizontal";
4201
+ countVectorizedCol = Math.max(countVectorizedCol, nColumns);
4202
+ vectorizedColLimit = Math.min(vectorizedColLimit, nColumns);
4203
+ }
4204
+ else if (nRows !== 1) {
4205
+ vectorArgsType[i] = "vertical";
4206
+ countVectorizedRow = Math.max(countVectorizedRow, nRows);
4207
+ vectorizedRowLimit = Math.min(vectorizedRowLimit, nRows);
4208
+ }
4209
+ }
4210
+ else {
4211
+ args[i] = arg[0][0];
4212
+ }
4213
+ }
4214
+ }
4215
+ if (countVectorizedCol === 1 && countVectorizedRow === 1) {
4216
+ // either this function is not vectorized or it ends up with a 1x1 dimension
4217
+ return formula(...args);
4218
+ }
4219
+ const getArgOffset = (i, j) => args.map((arg, index) => {
4220
+ switch (vectorArgsType?.[index]) {
4221
+ case "matrix":
4222
+ return arg[i][j];
4223
+ case "horizontal":
4224
+ return arg[i][0];
4225
+ case "vertical":
4226
+ return arg[0][j];
4227
+ case undefined:
4228
+ return arg;
4229
+ }
4230
+ });
4231
+ return generateMatrix(countVectorizedCol, countVectorizedRow, (col, row) => {
4232
+ if (col > vectorizedColLimit - 1 || row > vectorizedRowLimit - 1) {
4233
+ return new NotAvailableError(_t("Array arguments to [[FUNCTION_NAME]] are of different size."));
4234
+ }
4235
+ const singleCellComputeResult = formula(...getArgOffset(col, row));
4236
+ // In the case where the user tries to vectorize arguments of an array formula, we will get an
4237
+ // array for every combination of the vectorized arguments, which will lead to a 3D matrix and
4238
+ // we won't be able to return the values.
4239
+ // In this case, we keep the first element of each spreading part, just as Excel does, and
4240
+ // create an array with these parts.
4241
+ // For exemple, we have MUNIT(x) that return an unitary matrix of x*x. If we use it with a
4242
+ // range, like MUNIT(A1:A2), we will get two unitary matrices (one for the value in A1 and one
4243
+ // for the value in A2). In this case, we will simply take the first value of each matrix and
4244
+ // return the array [First value of MUNIT(A1), First value of MUNIT(A2)].
4245
+ return isMatrix(singleCellComputeResult)
4246
+ ? singleCellComputeResult[0][0]
4247
+ : singleCellComputeResult;
4248
+ });
4249
+ }
4143
4250
  // -----------------------------------------------------------------------------
4144
4251
  // CONDITIONAL EXPLORE FUNCTIONS
4145
4252
  // -----------------------------------------------------------------------------
@@ -7431,14 +7538,20 @@ function multiplyMatrices(matrix1, matrix2) {
7431
7538
  /**
7432
7539
  * Return the input if it's a scalar or the first element of the input if it's a matrix.
7433
7540
  */
7434
- function toScalar(matrix) {
7435
- if (!isMatrix(matrix)) {
7436
- return matrix;
7541
+ function toScalar(arg) {
7542
+ if (!isMatrix(arg)) {
7543
+ return arg;
7437
7544
  }
7438
- if (matrix.length !== 1 || matrix[0].length !== 1) {
7545
+ if (!isSingleElementMatrix(arg)) {
7439
7546
  throw new EvaluationError(_t("The value should be a scalar or a 1x1 matrix"));
7440
7547
  }
7441
- return matrix[0][0];
7548
+ return arg[0][0];
7549
+ }
7550
+ function isSingleElementMatrix(matrix) {
7551
+ return matrix.length === 1 && matrix[0].length === 1;
7552
+ }
7553
+ function isMultipleElementMatrix(arg) {
7554
+ return isMatrix(arg) && !isSingleElementMatrix(arg);
7442
7555
  }
7443
7556
 
7444
7557
  function assertSameNumberOfElements(...args) {
@@ -8180,9 +8293,10 @@ const AGGREGATOR_NAMES = {
8180
8293
  avg: _t("Average"),
8181
8294
  sum: _t("Sum"),
8182
8295
  };
8296
+ const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
8183
8297
  const AGGREGATORS_BY_FIELD_TYPE = {
8184
- integer: ["max", "min", "avg", "sum", "count_distinct", "count"],
8185
- char: ["count_distinct", "count"],
8298
+ integer: NUMBER_CHAR_AGGREGATORS,
8299
+ char: NUMBER_CHAR_AGGREGATORS,
8186
8300
  boolean: ["count_distinct", "count", "bool_and", "bool_or"],
8187
8301
  };
8188
8302
  const AGGREGATORS = {};
@@ -15282,7 +15396,7 @@ const FILTER = {
15282
15396
  }
15283
15397
  return mode === "row" ? transposeMatrix(result) : result;
15284
15398
  },
15285
- isExported: true,
15399
+ isExported: false,
15286
15400
  };
15287
15401
  // -----------------------------------------------------------------------------
15288
15402
  // SORT
@@ -18413,16 +18527,23 @@ const FALSE = {
18413
18527
  const IF = {
18414
18528
  description: _t("Returns value depending on logical expression."),
18415
18529
  args: [
18416
- arg("logical_expression (boolean)", _t("An expression or reference to a cell containing an expression that represents some logical value, i.e. TRUE or FALSE.")),
18417
- arg("value_if_true (any)", _t("The value the function returns if logical_expression is TRUE.")),
18418
- arg("value_if_false (any, default=FALSE)", _t("The value the function returns if logical_expression is FALSE.")),
18530
+ arg("logical_expression (boolean, range<boolean>)", _t("An expression or reference to a cell containing an expression that represents some logical value, i.e. TRUE or FALSE.")),
18531
+ arg("value_if_true (any, range)", _t("The value the function returns if logical_expression is TRUE.")),
18532
+ arg("value_if_false (any, range, default=FALSE)", _t("The value the function returns if logical_expression is FALSE.")),
18419
18533
  ],
18420
18534
  compute: function (logicalExpression, valueIfTrue, valueIfFalse) {
18421
- const result = toBoolean(logicalExpression?.value) ? valueIfTrue : valueIfFalse;
18535
+ if (isMultipleElementMatrix(logicalExpression)) {
18536
+ return applyVectorization(IF.compute, [logicalExpression, valueIfTrue, valueIfFalse]);
18537
+ }
18538
+ let result = toBoolean(toScalar(logicalExpression)) ? valueIfTrue : valueIfFalse;
18539
+ // useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
18540
+ if (!isMultipleElementMatrix(result)) {
18541
+ result = toScalar(result);
18542
+ }
18422
18543
  if (result === undefined) {
18423
18544
  return { value: "" };
18424
18545
  }
18425
- if (result.value === null) {
18546
+ if (!isMatrix(result) && result.value === null) {
18426
18547
  return { ...result, value: "" };
18427
18548
  }
18428
18549
  return result;
@@ -18435,15 +18556,22 @@ const IF = {
18435
18556
  const IFERROR = {
18436
18557
  description: _t("Value if it is not an error, otherwise 2nd argument."),
18437
18558
  args: [
18438
- arg("value (any)", _t("The value to return if value itself is not an error.")),
18439
- arg(`value_if_error (any, default="empty")`, _t("The value the function returns if value is an error.")),
18559
+ arg("value (any, range)", _t("The value to return if value itself is not an error.")),
18560
+ arg(`value_if_error (any, range, default="empty")`, _t("The value the function returns if value is an error.")),
18440
18561
  ],
18441
- compute: function (value, valueIfError = { value: "" }) {
18442
- const result = isEvaluationError(value?.value) ? valueIfError : value;
18562
+ compute: function (value, valueIfError) {
18563
+ if (isMultipleElementMatrix(value)) {
18564
+ return applyVectorization(IFERROR.compute, [value, valueIfError]);
18565
+ }
18566
+ let result = isEvaluationError(toScalar(value)?.value) ? valueIfError : value;
18567
+ // useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
18568
+ if (!isMultipleElementMatrix(result)) {
18569
+ result = toScalar(result);
18570
+ }
18443
18571
  if (result === undefined) {
18444
18572
  return { value: "" };
18445
18573
  }
18446
- if (result.value === null) {
18574
+ if (!isMatrix(result) && result.value === null) {
18447
18575
  return { ...result, value: "" };
18448
18576
  }
18449
18577
  return result;
@@ -18456,15 +18584,22 @@ const IFERROR = {
18456
18584
  const IFNA = {
18457
18585
  description: _t("Value if it is not an #N/A error, otherwise 2nd argument."),
18458
18586
  args: [
18459
- arg("value (any)", _t("The value to return if value itself is not #N/A an error.")),
18460
- arg(`value_if_error (any, default="empty")`, _t("The value the function returns if value is an #N/A error.")),
18587
+ arg("value (any, range)", _t("The value to return if value itself is not #N/A an error.")),
18588
+ arg(`value_if_error (any, range, default="empty")`, _t("The value the function returns if value is an #N/A error.")),
18461
18589
  ],
18462
- compute: function (value, valueIfError = { value: "" }) {
18463
- const result = value?.value === CellErrorType.NotAvailable ? valueIfError : value;
18590
+ compute: function (value, valueIfError) {
18591
+ if (isMultipleElementMatrix(value)) {
18592
+ return applyVectorization(IFNA.compute, [value, valueIfError]);
18593
+ }
18594
+ let result = toScalar(value)?.value === CellErrorType.NotAvailable ? valueIfError : value;
18595
+ // useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
18596
+ if (!isMultipleElementMatrix(result)) {
18597
+ result = toScalar(result);
18598
+ }
18464
18599
  if (result === undefined) {
18465
18600
  return { value: "" };
18466
18601
  }
18467
- if (result.value === null) {
18602
+ if (!isMatrix(result) && result.value === null) {
18468
18603
  return { ...result, value: "" };
18469
18604
  }
18470
18605
  return result;
@@ -18477,23 +18612,31 @@ const IFNA = {
18477
18612
  const IFS = {
18478
18613
  description: _t("Returns a value depending on multiple logical expressions."),
18479
18614
  args: [
18480
- arg("condition1 (boolean)", _t("The first condition to be evaluated. This can be a boolean, a number, an array, or a reference to any of those.")),
18481
- arg("value1 (any)", _t("The returned value if condition1 is TRUE.")),
18482
- arg("condition2 (boolean, any, repeating)", _t("Additional conditions to be evaluated if the previous ones are FALSE.")),
18483
- arg("value2 (any, repeating)", _t("Additional values to be returned if their corresponding conditions are TRUE.")),
18615
+ arg("condition1 (boolean, range<boolean>)", _t("The first condition to be evaluated. This can be a boolean, a number, an array, or a reference to any of those.")),
18616
+ arg("value1 (any, range)", _t("The returned value if condition1 is TRUE.")),
18617
+ arg("condition2 (boolean, any, range, repeating)", _t("Additional conditions to be evaluated if the previous ones are FALSE.")),
18618
+ arg("value2 (any, range, repeating)", _t("Additional values to be returned if their corresponding conditions are TRUE.")),
18484
18619
  ],
18485
18620
  compute: function (...values) {
18486
18621
  assert(() => values.length % 2 === 0, _t("Wrong number of arguments. Expected an even number of arguments."));
18487
- for (let n = 0; n < values.length - 1; n += 2) {
18488
- if (toBoolean(values[n]?.value)) {
18489
- const result = values[n + 1];
18490
- if (result === undefined) {
18622
+ while (values.length > 0) {
18623
+ if (isMultipleElementMatrix(values[0])) {
18624
+ return applyVectorization(IFS.compute, values);
18625
+ }
18626
+ const condition = toBoolean(toScalar(values.shift()));
18627
+ let valueIfTrue = values.shift();
18628
+ if (condition) {
18629
+ // useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
18630
+ if (!isMultipleElementMatrix(valueIfTrue)) {
18631
+ valueIfTrue = toScalar(valueIfTrue);
18632
+ }
18633
+ if (valueIfTrue === undefined) {
18491
18634
  return { value: "" };
18492
18635
  }
18493
- if (result.value === null) {
18494
- return { ...result, value: "" };
18636
+ if (!isMatrix(valueIfTrue) && valueIfTrue.value === null) {
18637
+ return { ...valueIfTrue, value: "" };
18495
18638
  }
18496
- return result;
18639
+ return valueIfTrue;
18497
18640
  }
18498
18641
  }
18499
18642
  return new EvaluationError(_t("No match."));
@@ -20155,7 +20298,7 @@ const SPLIT = {
20155
20298
  }
20156
20299
  return transposeMatrix([result]);
20157
20300
  },
20158
- isExported: true,
20301
+ isExported: false,
20159
20302
  };
20160
20303
  // -----------------------------------------------------------------------------
20161
20304
  // SUBSTITUTE
@@ -20348,86 +20491,21 @@ for (let category of categories) {
20348
20491
  functionRegistry.add(name, { isExported: false, ...addDescr });
20349
20492
  }
20350
20493
  }
20351
- const notAvailableError = new NotAvailableError(_t("Array arguments to [[FUNCTION_NAME]] are of different size."));
20494
+ //------------------------------------------------------------------------------
20495
+ // CREATE COMPUTE FUNCTION
20496
+ //------------------------------------------------------------------------------
20352
20497
  function createComputeFunction(descr, functionName) {
20353
20498
  function vectorizedCompute(...args) {
20354
- let countVectorizableCol = 1;
20355
- let countVectorizableRow = 1;
20356
- let vectorizableColLimit = Infinity;
20357
- let vectorizableRowLimit = Infinity;
20358
- let vectorArgsType = undefined;
20359
- //#region Compute vectorisation limits
20499
+ const acceptToVectorize = [];
20360
20500
  for (let i = 0; i < args.length; i++) {
20361
20501
  const argDefinition = descr.args[descr.getArgToFocus(i + 1) - 1];
20362
20502
  const arg = args[i];
20363
- if (isMatrix(arg) && !argDefinition.acceptMatrix) {
20364
- // if argDefinition does not accept a matrix but arg is still a matrix
20365
- // --> triggers the arguments vectorization
20366
- const nColumns = arg.length;
20367
- const nRows = arg[0].length;
20368
- if (nColumns !== 1 || nRows !== 1) {
20369
- vectorArgsType ??= new Array(args.length);
20370
- if (nColumns !== 1 && nRows !== 1) {
20371
- vectorArgsType[i] = "matrix";
20372
- countVectorizableCol = Math.max(countVectorizableCol, nColumns);
20373
- countVectorizableRow = Math.max(countVectorizableRow, nRows);
20374
- vectorizableColLimit = Math.min(vectorizableColLimit, nColumns);
20375
- vectorizableRowLimit = Math.min(vectorizableRowLimit, nRows);
20376
- }
20377
- else if (nColumns !== 1) {
20378
- vectorArgsType[i] = "horizontal";
20379
- countVectorizableCol = Math.max(countVectorizableCol, nColumns);
20380
- vectorizableColLimit = Math.min(vectorizableColLimit, nColumns);
20381
- }
20382
- else if (nRows !== 1) {
20383
- vectorArgsType[i] = "vertical";
20384
- countVectorizableRow = Math.max(countVectorizableRow, nRows);
20385
- vectorizableRowLimit = Math.min(vectorizableRowLimit, nRows);
20386
- }
20387
- }
20388
- else {
20389
- args[i] = arg[0][0];
20390
- }
20391
- }
20392
20503
  if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
20393
20504
  throw new BadExpressionError(_t("Function %s expects the parameter '%s' to be reference to a cell or range.", functionName, (i + 1).toString()));
20394
20505
  }
20506
+ acceptToVectorize.push(!argDefinition.acceptMatrix);
20395
20507
  }
20396
- //#endregion
20397
- if (countVectorizableCol === 1 && countVectorizableRow === 1) {
20398
- // either this function is not vectorized or it ends up with a 1x1 dimension
20399
- return errorHandlingCompute.apply(this, args);
20400
- }
20401
- const getArgOffset = (i, j) => args.map((arg, index) => {
20402
- switch (vectorArgsType?.[index]) {
20403
- case "matrix":
20404
- return arg[i][j];
20405
- case "horizontal":
20406
- return arg[i][0];
20407
- case "vertical":
20408
- return arg[0][j];
20409
- case undefined:
20410
- return arg;
20411
- }
20412
- });
20413
- return generateMatrix(countVectorizableCol, countVectorizableRow, (col, row) => {
20414
- if (col > vectorizableColLimit - 1 || row > vectorizableRowLimit - 1) {
20415
- return notAvailableError;
20416
- }
20417
- const singleCellComputeResult = errorHandlingCompute.apply(this, getArgOffset(col, row));
20418
- // In the case where the user tries to vectorize arguments of an array formula, we will get an
20419
- // array for every combination of the vectorized arguments, which will lead to a 3D matrix and
20420
- // we won't be able to return the values.
20421
- // In this case, we keep the first element of each spreading part, just as Excel does, and
20422
- // create an array with these parts.
20423
- // For exemple, we have MUNIT(x) that return an unitary matrix of x*x. If we use it with a
20424
- // range, like MUNIT(A1:A2), we will get two unitary matrices (one for the value in A1 and one
20425
- // for the value in A2). In this case, we will simply take the first value of each matrix and
20426
- // return the array [First value of MUNIT(A1), First value of MUNIT(A2)].
20427
- return isMatrix(singleCellComputeResult)
20428
- ? singleCellComputeResult[0][0]
20429
- : singleCellComputeResult;
20430
- });
20508
+ return applyVectorization(errorHandlingCompute.bind(this), args, acceptToVectorize);
20431
20509
  }
20432
20510
  function errorHandlingCompute(...args) {
20433
20511
  for (let i = 0; i < args.length; i++) {
@@ -21272,7 +21350,7 @@ class AbstractComposerStore extends SpreadsheetStore {
21272
21350
  proposals &&
21273
21351
  !["ARG_SEPARATOR", "LEFT_PAREN", "OPERATOR"].includes(tokenAtCursor.type)) {
21274
21352
  const filteredProposals = fuzzyLookup(searchTerm, proposals, (p) => p.fuzzySearchKey || p.text);
21275
- if (!exactMatch || filteredProposals.length > 1) {
21353
+ if (!exactMatch || filteredProposals.length) {
21276
21354
  proposals = filteredProposals;
21277
21355
  }
21278
21356
  }
@@ -46139,7 +46217,9 @@ function compareDimensionValues(dimension, a, b) {
46139
46217
  return dimension.order === "asc" ? -1 : 1;
46140
46218
  }
46141
46219
  if (dimension.type === "integer" || dimension.type === "datetime") {
46142
- return dimension.order === "asc" ? Number(a) - Number(b) : Number(b) - Number(a);
46220
+ return dimension.order === "asc"
46221
+ ? toNumber(a, DEFAULT_LOCALE) - toNumber(b, DEFAULT_LOCALE)
46222
+ : toNumber(b, DEFAULT_LOCALE) - toNumber(a, DEFAULT_LOCALE);
46143
46223
  }
46144
46224
  return dimension.order === "asc" ? a.localeCompare(b) : b.localeCompare(a);
46145
46225
  }
@@ -46675,12 +46755,7 @@ class SpreadsheetPivot {
46675
46755
  entry[field.name] = { value: null, type: CellValueType.empty, formattedValue: "" };
46676
46756
  }
46677
46757
  else {
46678
- if (field.type === "char") {
46679
- entry[field.name] = { ...cell, value: cell.formattedValue || null };
46680
- }
46681
- else {
46682
- entry[field.name] = cell;
46683
- }
46758
+ entry[field.name] = cell;
46684
46759
  }
46685
46760
  }
46686
46761
  entry["__count"] = { value: 1, type: CellValueType.number, formattedValue: "1" };
@@ -48905,8 +48980,7 @@ class CellComposerStore extends AbstractComposerStore {
48905
48980
  if (!spreader) {
48906
48981
  return undefined;
48907
48982
  }
48908
- const cell = this.getters.getCell(spreader);
48909
- return cell?.content;
48983
+ return this.getters.getCellText(spreader, { showFormula: true });
48910
48984
  }
48911
48985
  get currentEditedCell() {
48912
48986
  return {
@@ -51717,6 +51791,7 @@ function useGridDrawing(refName, model, canvasSize) {
51717
51791
  const friction = 0.95;
51718
51792
  const verticalScrollFactor = 1;
51719
51793
  const horizontalScrollFactor = 1;
51794
+ const resetTimeoutDuration = 100;
51720
51795
  function useTouchScroll(ref, updateScroll, canMoveUp) {
51721
51796
  let lastX = 0;
51722
51797
  let lastY = 0;
@@ -51724,6 +51799,7 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
51724
51799
  let velocityY = 0;
51725
51800
  let isMouseDown = false;
51726
51801
  let lastTime = 0;
51802
+ let resetTimeout = null;
51727
51803
  useRefListener(ref, "touchstart", onTouchStart, { capture: false });
51728
51804
  useRefListener(ref, "touchmove", onTouchMove, { capture: false });
51729
51805
  useRefListener(ref, "touchend", onTouchEnd, { capture: false });
@@ -51736,6 +51812,10 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
51736
51812
  function onTouchMove(event) {
51737
51813
  if (!isMouseDown)
51738
51814
  return;
51815
+ if (resetTimeout) {
51816
+ clearTimeout(resetTimeout);
51817
+ resetTimeout = null;
51818
+ }
51739
51819
  const currentTime = Date.now();
51740
51820
  const { clientX, clientY } = event.touches[0];
51741
51821
  let deltaX = lastX - clientX;
@@ -51752,6 +51832,10 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
51752
51832
  }
51753
51833
  event.stopPropagation();
51754
51834
  }
51835
+ resetTimeout = setTimeout(() => {
51836
+ velocityX = 0;
51837
+ velocityY = 0;
51838
+ }, resetTimeoutDuration);
51755
51839
  updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
51756
51840
  }
51757
51841
  function onTouchEnd(ev) {
@@ -76303,6 +76387,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
76303
76387
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, 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 };
76304
76388
 
76305
76389
 
76306
- __info__.version = "18.1.21";
76307
- __info__.date = "2025-05-20T05:54:45.398Z";
76308
- __info__.hash = "89ed6a9";
76390
+ __info__.version = "18.1.23";
76391
+ __info__.date = "2025-05-30T08:45:44.408Z";
76392
+ __info__.hash = "a21fa01";