@odoo/o-spreadsheet 18.2.13 → 18.2.14
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.
- package/dist/o-spreadsheet.cjs.js +202 -114
- package/dist/o-spreadsheet.esm.js +202 -114
- package/dist/o-spreadsheet.iife.js +202 -114
- package/dist/o-spreadsheet.iife.min.js +368 -368
- package/dist/o_spreadsheet.xml +5 -5
- package/package.json +1 -1
|
@@ -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.
|
|
6
|
-
* @date 2025-05-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.2.14
|
|
6
|
+
* @date 2025-05-26T12:35:51.528Z
|
|
7
|
+
* @hash db90fca
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -4151,6 +4151,113 @@ function transposeMatrix(matrix) {
|
|
|
4151
4151
|
}
|
|
4152
4152
|
return generateMatrix(matrix[0].length, matrix.length, (i, j) => matrix[j][i]);
|
|
4153
4153
|
}
|
|
4154
|
+
/**
|
|
4155
|
+
* Enables a formula function to accept matrix or vector inputs instead of simple value, computing results across multiple dimensions.
|
|
4156
|
+
*
|
|
4157
|
+
* ```
|
|
4158
|
+
* / |‾ ‾| \ |‾ ‾|
|
|
4159
|
+
* | | [A] | | | compute(A, D, E), compute(A, D, F), compute(A, D, G) |
|
|
4160
|
+
* applyVectorization| compute, | [B], D, [E, F, G] | | <=> | compute(B, D, E), compute(B, D, F), compute(B, D, G) |
|
|
4161
|
+
* | | [C] | | | compute(C, D, E), compute(C, D, F), compute(C, D, G) |
|
|
4162
|
+
* \ |_ _| / |_ _|
|
|
4163
|
+
* ```
|
|
4164
|
+
*
|
|
4165
|
+
* By default, all arguments are vectorized. To control which arguments are vectorized,
|
|
4166
|
+
* pass an `acceptToVectorize` boolean array of the same length as `args`:
|
|
4167
|
+
* - `true` enables vectorization for that argument
|
|
4168
|
+
* - `false` disables vectorization for that argument
|
|
4169
|
+
*
|
|
4170
|
+
* For example, with `[true, true, false]` on previous example you get:
|
|
4171
|
+
*
|
|
4172
|
+
* ```
|
|
4173
|
+
* |‾ ‾|
|
|
4174
|
+
* | compute(A, D, [E, F, G]) |
|
|
4175
|
+
* | compute(B, D, [E, F, G]) |
|
|
4176
|
+
* | compute(C, D, [E, F, G]) |
|
|
4177
|
+
* |_ _|
|
|
4178
|
+
* ```
|
|
4179
|
+
*
|
|
4180
|
+
* @remarks
|
|
4181
|
+
* This helper is automatically applied (by default) to **all** `compute` functions
|
|
4182
|
+
* across the various spreadsheet formula modules:
|
|
4183
|
+
* - If an argument is declared **scalar** (not `"range"`), it is vectorized.
|
|
4184
|
+
* - If **all** arguments are declared **ranges**, no vectorization occurs.
|
|
4185
|
+
* - e.g. `SUM(A1:B2)` returns a 1×1 sum over the range.
|
|
4186
|
+
* - e.g. `COS(A1:B2)` over `A1:B2` returns a 2×2 element-wise result.
|
|
4187
|
+
* - For special behaviors (e.g. the `IF` function), you may declare all arguments
|
|
4188
|
+
* as ranges and invoke this helper directly within your `compute` implementation.
|
|
4189
|
+
*/
|
|
4190
|
+
function applyVectorization(formula, args, acceptToVectorize = undefined) {
|
|
4191
|
+
let countVectorizedCol = 1;
|
|
4192
|
+
let countVectorizedRow = 1;
|
|
4193
|
+
let vectorizedColLimit = Infinity;
|
|
4194
|
+
let vectorizedRowLimit = Infinity;
|
|
4195
|
+
let vectorArgsType = undefined;
|
|
4196
|
+
for (let i = 0; i < args.length; i++) {
|
|
4197
|
+
const arg = args[i];
|
|
4198
|
+
if (isMatrix(arg) && (acceptToVectorize === undefined || acceptToVectorize[i])) {
|
|
4199
|
+
const nColumns = arg.length;
|
|
4200
|
+
const nRows = arg[0].length;
|
|
4201
|
+
if (nColumns !== 1 || nRows !== 1) {
|
|
4202
|
+
vectorArgsType ??= new Array(args.length);
|
|
4203
|
+
if (nColumns !== 1 && nRows !== 1) {
|
|
4204
|
+
vectorArgsType[i] = "matrix";
|
|
4205
|
+
countVectorizedCol = Math.max(countVectorizedCol, nColumns);
|
|
4206
|
+
countVectorizedRow = Math.max(countVectorizedRow, nRows);
|
|
4207
|
+
vectorizedColLimit = Math.min(vectorizedColLimit, nColumns);
|
|
4208
|
+
vectorizedRowLimit = Math.min(vectorizedRowLimit, nRows);
|
|
4209
|
+
}
|
|
4210
|
+
else if (nColumns !== 1) {
|
|
4211
|
+
vectorArgsType[i] = "horizontal";
|
|
4212
|
+
countVectorizedCol = Math.max(countVectorizedCol, nColumns);
|
|
4213
|
+
vectorizedColLimit = Math.min(vectorizedColLimit, nColumns);
|
|
4214
|
+
}
|
|
4215
|
+
else if (nRows !== 1) {
|
|
4216
|
+
vectorArgsType[i] = "vertical";
|
|
4217
|
+
countVectorizedRow = Math.max(countVectorizedRow, nRows);
|
|
4218
|
+
vectorizedRowLimit = Math.min(vectorizedRowLimit, nRows);
|
|
4219
|
+
}
|
|
4220
|
+
}
|
|
4221
|
+
else {
|
|
4222
|
+
args[i] = arg[0][0];
|
|
4223
|
+
}
|
|
4224
|
+
}
|
|
4225
|
+
}
|
|
4226
|
+
if (countVectorizedCol === 1 && countVectorizedRow === 1) {
|
|
4227
|
+
// either this function is not vectorized or it ends up with a 1x1 dimension
|
|
4228
|
+
return formula(...args);
|
|
4229
|
+
}
|
|
4230
|
+
const getArgOffset = (i, j) => args.map((arg, index) => {
|
|
4231
|
+
switch (vectorArgsType?.[index]) {
|
|
4232
|
+
case "matrix":
|
|
4233
|
+
return arg[i][j];
|
|
4234
|
+
case "horizontal":
|
|
4235
|
+
return arg[i][0];
|
|
4236
|
+
case "vertical":
|
|
4237
|
+
return arg[0][j];
|
|
4238
|
+
case undefined:
|
|
4239
|
+
return arg;
|
|
4240
|
+
}
|
|
4241
|
+
});
|
|
4242
|
+
return generateMatrix(countVectorizedCol, countVectorizedRow, (col, row) => {
|
|
4243
|
+
if (col > vectorizedColLimit - 1 || row > vectorizedRowLimit - 1) {
|
|
4244
|
+
return new NotAvailableError(_t("Array arguments to [[FUNCTION_NAME]] are of different size."));
|
|
4245
|
+
}
|
|
4246
|
+
const singleCellComputeResult = formula(...getArgOffset(col, row));
|
|
4247
|
+
// In the case where the user tries to vectorize arguments of an array formula, we will get an
|
|
4248
|
+
// array for every combination of the vectorized arguments, which will lead to a 3D matrix and
|
|
4249
|
+
// we won't be able to return the values.
|
|
4250
|
+
// In this case, we keep the first element of each spreading part, just as Excel does, and
|
|
4251
|
+
// create an array with these parts.
|
|
4252
|
+
// For exemple, we have MUNIT(x) that return an unitary matrix of x*x. If we use it with a
|
|
4253
|
+
// range, like MUNIT(A1:A2), we will get two unitary matrices (one for the value in A1 and one
|
|
4254
|
+
// for the value in A2). In this case, we will simply take the first value of each matrix and
|
|
4255
|
+
// return the array [First value of MUNIT(A1), First value of MUNIT(A2)].
|
|
4256
|
+
return isMatrix(singleCellComputeResult)
|
|
4257
|
+
? singleCellComputeResult[0][0]
|
|
4258
|
+
: singleCellComputeResult;
|
|
4259
|
+
});
|
|
4260
|
+
}
|
|
4154
4261
|
// -----------------------------------------------------------------------------
|
|
4155
4262
|
// CONDITIONAL EXPLORE FUNCTIONS
|
|
4156
4263
|
// -----------------------------------------------------------------------------
|
|
@@ -7442,14 +7549,20 @@ function multiplyMatrices(matrix1, matrix2) {
|
|
|
7442
7549
|
/**
|
|
7443
7550
|
* Return the input if it's a scalar or the first element of the input if it's a matrix.
|
|
7444
7551
|
*/
|
|
7445
|
-
function toScalar(
|
|
7446
|
-
if (!isMatrix(
|
|
7447
|
-
return
|
|
7552
|
+
function toScalar(arg) {
|
|
7553
|
+
if (!isMatrix(arg)) {
|
|
7554
|
+
return arg;
|
|
7448
7555
|
}
|
|
7449
|
-
if (
|
|
7556
|
+
if (!isSingleElementMatrix(arg)) {
|
|
7450
7557
|
throw new EvaluationError(_t("The value should be a scalar or a 1x1 matrix"));
|
|
7451
7558
|
}
|
|
7452
|
-
return
|
|
7559
|
+
return arg[0][0];
|
|
7560
|
+
}
|
|
7561
|
+
function isSingleElementMatrix(matrix) {
|
|
7562
|
+
return matrix.length === 1 && matrix[0].length === 1;
|
|
7563
|
+
}
|
|
7564
|
+
function isMultipleElementMatrix(arg) {
|
|
7565
|
+
return isMatrix(arg) && !isSingleElementMatrix(arg);
|
|
7453
7566
|
}
|
|
7454
7567
|
|
|
7455
7568
|
function assertSameNumberOfElements(...args) {
|
|
@@ -15457,7 +15570,7 @@ const FILTER = {
|
|
|
15457
15570
|
}
|
|
15458
15571
|
return mode === "row" ? transposeMatrix(result) : result;
|
|
15459
15572
|
},
|
|
15460
|
-
isExported:
|
|
15573
|
+
isExported: false,
|
|
15461
15574
|
};
|
|
15462
15575
|
// -----------------------------------------------------------------------------
|
|
15463
15576
|
// SORT
|
|
@@ -18588,16 +18701,23 @@ const FALSE = {
|
|
|
18588
18701
|
const IF = {
|
|
18589
18702
|
description: _t("Returns value depending on logical expression."),
|
|
18590
18703
|
args: [
|
|
18591
|
-
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.")),
|
|
18592
|
-
arg("value_if_true (any)", _t("The value the function returns if logical_expression is TRUE.")),
|
|
18593
|
-
arg("value_if_false (any, default=FALSE)", _t("The value the function returns if logical_expression is FALSE.")),
|
|
18704
|
+
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.")),
|
|
18705
|
+
arg("value_if_true (any, range)", _t("The value the function returns if logical_expression is TRUE.")),
|
|
18706
|
+
arg("value_if_false (any, range, default=FALSE)", _t("The value the function returns if logical_expression is FALSE.")),
|
|
18594
18707
|
],
|
|
18595
18708
|
compute: function (logicalExpression, valueIfTrue, valueIfFalse) {
|
|
18596
|
-
|
|
18709
|
+
if (isMultipleElementMatrix(logicalExpression)) {
|
|
18710
|
+
return applyVectorization(IF.compute, [logicalExpression, valueIfTrue, valueIfFalse]);
|
|
18711
|
+
}
|
|
18712
|
+
let result = toBoolean(toScalar(logicalExpression)) ? valueIfTrue : valueIfFalse;
|
|
18713
|
+
// useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
|
|
18714
|
+
if (!isMultipleElementMatrix(result)) {
|
|
18715
|
+
result = toScalar(result);
|
|
18716
|
+
}
|
|
18597
18717
|
if (result === undefined) {
|
|
18598
18718
|
return { value: "" };
|
|
18599
18719
|
}
|
|
18600
|
-
if (result.value === null) {
|
|
18720
|
+
if (!isMatrix(result) && result.value === null) {
|
|
18601
18721
|
return { ...result, value: "" };
|
|
18602
18722
|
}
|
|
18603
18723
|
return result;
|
|
@@ -18610,15 +18730,22 @@ const IF = {
|
|
|
18610
18730
|
const IFERROR = {
|
|
18611
18731
|
description: _t("Value if it is not an error, otherwise 2nd argument."),
|
|
18612
18732
|
args: [
|
|
18613
|
-
arg("value (any)", _t("The value to return if value itself is not an error.")),
|
|
18614
|
-
arg(`value_if_error (any, default="empty")`, _t("The value the function returns if value is an error.")),
|
|
18733
|
+
arg("value (any, range)", _t("The value to return if value itself is not an error.")),
|
|
18734
|
+
arg(`value_if_error (any, range, default="empty")`, _t("The value the function returns if value is an error.")),
|
|
18615
18735
|
],
|
|
18616
|
-
compute: function (value, valueIfError
|
|
18617
|
-
|
|
18736
|
+
compute: function (value, valueIfError) {
|
|
18737
|
+
if (isMultipleElementMatrix(value)) {
|
|
18738
|
+
return applyVectorization(IFERROR.compute, [value, valueIfError]);
|
|
18739
|
+
}
|
|
18740
|
+
let result = isEvaluationError(toScalar(value)?.value) ? valueIfError : value;
|
|
18741
|
+
// useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
|
|
18742
|
+
if (!isMultipleElementMatrix(result)) {
|
|
18743
|
+
result = toScalar(result);
|
|
18744
|
+
}
|
|
18618
18745
|
if (result === undefined) {
|
|
18619
18746
|
return { value: "" };
|
|
18620
18747
|
}
|
|
18621
|
-
if (result.value === null) {
|
|
18748
|
+
if (!isMatrix(result) && result.value === null) {
|
|
18622
18749
|
return { ...result, value: "" };
|
|
18623
18750
|
}
|
|
18624
18751
|
return result;
|
|
@@ -18631,15 +18758,22 @@ const IFERROR = {
|
|
|
18631
18758
|
const IFNA = {
|
|
18632
18759
|
description: _t("Value if it is not an #N/A error, otherwise 2nd argument."),
|
|
18633
18760
|
args: [
|
|
18634
|
-
arg("value (any)", _t("The value to return if value itself is not #N/A an error.")),
|
|
18635
|
-
arg(`value_if_error (any, default="empty")`, _t("The value the function returns if value is an #N/A error.")),
|
|
18761
|
+
arg("value (any, range)", _t("The value to return if value itself is not #N/A an error.")),
|
|
18762
|
+
arg(`value_if_error (any, range, default="empty")`, _t("The value the function returns if value is an #N/A error.")),
|
|
18636
18763
|
],
|
|
18637
|
-
compute: function (value, valueIfError
|
|
18638
|
-
|
|
18764
|
+
compute: function (value, valueIfError) {
|
|
18765
|
+
if (isMultipleElementMatrix(value)) {
|
|
18766
|
+
return applyVectorization(IFNA.compute, [value, valueIfError]);
|
|
18767
|
+
}
|
|
18768
|
+
let result = toScalar(value)?.value === CellErrorType.NotAvailable ? valueIfError : value;
|
|
18769
|
+
// useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
|
|
18770
|
+
if (!isMultipleElementMatrix(result)) {
|
|
18771
|
+
result = toScalar(result);
|
|
18772
|
+
}
|
|
18639
18773
|
if (result === undefined) {
|
|
18640
18774
|
return { value: "" };
|
|
18641
18775
|
}
|
|
18642
|
-
if (result.value === null) {
|
|
18776
|
+
if (!isMatrix(result) && result.value === null) {
|
|
18643
18777
|
return { ...result, value: "" };
|
|
18644
18778
|
}
|
|
18645
18779
|
return result;
|
|
@@ -18652,23 +18786,31 @@ const IFNA = {
|
|
|
18652
18786
|
const IFS = {
|
|
18653
18787
|
description: _t("Returns a value depending on multiple logical expressions."),
|
|
18654
18788
|
args: [
|
|
18655
|
-
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.")),
|
|
18656
|
-
arg("value1 (any)", _t("The returned value if condition1 is TRUE.")),
|
|
18657
|
-
arg("condition2 (boolean, any, repeating)", _t("Additional conditions to be evaluated if the previous ones are FALSE.")),
|
|
18658
|
-
arg("value2 (any, repeating)", _t("Additional values to be returned if their corresponding conditions are TRUE.")),
|
|
18789
|
+
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.")),
|
|
18790
|
+
arg("value1 (any, range)", _t("The returned value if condition1 is TRUE.")),
|
|
18791
|
+
arg("condition2 (boolean, any, range, repeating)", _t("Additional conditions to be evaluated if the previous ones are FALSE.")),
|
|
18792
|
+
arg("value2 (any, range, repeating)", _t("Additional values to be returned if their corresponding conditions are TRUE.")),
|
|
18659
18793
|
],
|
|
18660
18794
|
compute: function (...values) {
|
|
18661
18795
|
assert(() => values.length % 2 === 0, _t("Wrong number of arguments. Expected an even number of arguments."));
|
|
18662
|
-
|
|
18663
|
-
if (
|
|
18664
|
-
|
|
18665
|
-
|
|
18796
|
+
while (values.length > 0) {
|
|
18797
|
+
if (isMultipleElementMatrix(values[0])) {
|
|
18798
|
+
return applyVectorization(IFS.compute, values);
|
|
18799
|
+
}
|
|
18800
|
+
const condition = toBoolean(toScalar(values.shift()));
|
|
18801
|
+
let valueIfTrue = values.shift();
|
|
18802
|
+
if (condition) {
|
|
18803
|
+
// useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
|
|
18804
|
+
if (!isMultipleElementMatrix(valueIfTrue)) {
|
|
18805
|
+
valueIfTrue = toScalar(valueIfTrue);
|
|
18806
|
+
}
|
|
18807
|
+
if (valueIfTrue === undefined) {
|
|
18666
18808
|
return { value: "" };
|
|
18667
18809
|
}
|
|
18668
|
-
if (
|
|
18669
|
-
return { ...
|
|
18810
|
+
if (!isMatrix(valueIfTrue) && valueIfTrue.value === null) {
|
|
18811
|
+
return { ...valueIfTrue, value: "" };
|
|
18670
18812
|
}
|
|
18671
|
-
return
|
|
18813
|
+
return valueIfTrue;
|
|
18672
18814
|
}
|
|
18673
18815
|
}
|
|
18674
18816
|
return new EvaluationError(_t("No match."));
|
|
@@ -20330,7 +20472,7 @@ const SPLIT = {
|
|
|
20330
20472
|
}
|
|
20331
20473
|
return transposeMatrix([result]);
|
|
20332
20474
|
},
|
|
20333
|
-
isExported:
|
|
20475
|
+
isExported: false,
|
|
20334
20476
|
};
|
|
20335
20477
|
// -----------------------------------------------------------------------------
|
|
20336
20478
|
// SUBSTITUTE
|
|
@@ -20523,86 +20665,21 @@ for (let category of categories) {
|
|
|
20523
20665
|
functionRegistry.add(name, { isExported: false, ...addDescr });
|
|
20524
20666
|
}
|
|
20525
20667
|
}
|
|
20526
|
-
|
|
20668
|
+
//------------------------------------------------------------------------------
|
|
20669
|
+
// CREATE COMPUTE FUNCTION
|
|
20670
|
+
//------------------------------------------------------------------------------
|
|
20527
20671
|
function createComputeFunction(descr, functionName) {
|
|
20528
20672
|
function vectorizedCompute(...args) {
|
|
20529
|
-
|
|
20530
|
-
let countVectorizableRow = 1;
|
|
20531
|
-
let vectorizableColLimit = Infinity;
|
|
20532
|
-
let vectorizableRowLimit = Infinity;
|
|
20533
|
-
let vectorArgsType = undefined;
|
|
20534
|
-
//#region Compute vectorisation limits
|
|
20673
|
+
const acceptToVectorize = [];
|
|
20535
20674
|
for (let i = 0; i < args.length; i++) {
|
|
20536
20675
|
const argDefinition = descr.args[descr.getArgToFocus(i + 1) - 1];
|
|
20537
20676
|
const arg = args[i];
|
|
20538
|
-
if (isMatrix(arg) && !argDefinition.acceptMatrix) {
|
|
20539
|
-
// if argDefinition does not accept a matrix but arg is still a matrix
|
|
20540
|
-
// --> triggers the arguments vectorization
|
|
20541
|
-
const nColumns = arg.length;
|
|
20542
|
-
const nRows = arg[0].length;
|
|
20543
|
-
if (nColumns !== 1 || nRows !== 1) {
|
|
20544
|
-
vectorArgsType ??= new Array(args.length);
|
|
20545
|
-
if (nColumns !== 1 && nRows !== 1) {
|
|
20546
|
-
vectorArgsType[i] = "matrix";
|
|
20547
|
-
countVectorizableCol = Math.max(countVectorizableCol, nColumns);
|
|
20548
|
-
countVectorizableRow = Math.max(countVectorizableRow, nRows);
|
|
20549
|
-
vectorizableColLimit = Math.min(vectorizableColLimit, nColumns);
|
|
20550
|
-
vectorizableRowLimit = Math.min(vectorizableRowLimit, nRows);
|
|
20551
|
-
}
|
|
20552
|
-
else if (nColumns !== 1) {
|
|
20553
|
-
vectorArgsType[i] = "horizontal";
|
|
20554
|
-
countVectorizableCol = Math.max(countVectorizableCol, nColumns);
|
|
20555
|
-
vectorizableColLimit = Math.min(vectorizableColLimit, nColumns);
|
|
20556
|
-
}
|
|
20557
|
-
else if (nRows !== 1) {
|
|
20558
|
-
vectorArgsType[i] = "vertical";
|
|
20559
|
-
countVectorizableRow = Math.max(countVectorizableRow, nRows);
|
|
20560
|
-
vectorizableRowLimit = Math.min(vectorizableRowLimit, nRows);
|
|
20561
|
-
}
|
|
20562
|
-
}
|
|
20563
|
-
else {
|
|
20564
|
-
args[i] = arg[0][0];
|
|
20565
|
-
}
|
|
20566
|
-
}
|
|
20567
20677
|
if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
|
|
20568
20678
|
throw new BadExpressionError(_t("Function %s expects the parameter '%s' to be reference to a cell or range.", functionName, (i + 1).toString()));
|
|
20569
20679
|
}
|
|
20680
|
+
acceptToVectorize.push(!argDefinition.acceptMatrix);
|
|
20570
20681
|
}
|
|
20571
|
-
|
|
20572
|
-
if (countVectorizableCol === 1 && countVectorizableRow === 1) {
|
|
20573
|
-
// either this function is not vectorized or it ends up with a 1x1 dimension
|
|
20574
|
-
return errorHandlingCompute.apply(this, args);
|
|
20575
|
-
}
|
|
20576
|
-
const getArgOffset = (i, j) => args.map((arg, index) => {
|
|
20577
|
-
switch (vectorArgsType?.[index]) {
|
|
20578
|
-
case "matrix":
|
|
20579
|
-
return arg[i][j];
|
|
20580
|
-
case "horizontal":
|
|
20581
|
-
return arg[i][0];
|
|
20582
|
-
case "vertical":
|
|
20583
|
-
return arg[0][j];
|
|
20584
|
-
case undefined:
|
|
20585
|
-
return arg;
|
|
20586
|
-
}
|
|
20587
|
-
});
|
|
20588
|
-
return generateMatrix(countVectorizableCol, countVectorizableRow, (col, row) => {
|
|
20589
|
-
if (col > vectorizableColLimit - 1 || row > vectorizableRowLimit - 1) {
|
|
20590
|
-
return notAvailableError;
|
|
20591
|
-
}
|
|
20592
|
-
const singleCellComputeResult = errorHandlingCompute.apply(this, getArgOffset(col, row));
|
|
20593
|
-
// In the case where the user tries to vectorize arguments of an array formula, we will get an
|
|
20594
|
-
// array for every combination of the vectorized arguments, which will lead to a 3D matrix and
|
|
20595
|
-
// we won't be able to return the values.
|
|
20596
|
-
// In this case, we keep the first element of each spreading part, just as Excel does, and
|
|
20597
|
-
// create an array with these parts.
|
|
20598
|
-
// For exemple, we have MUNIT(x) that return an unitary matrix of x*x. If we use it with a
|
|
20599
|
-
// range, like MUNIT(A1:A2), we will get two unitary matrices (one for the value in A1 and one
|
|
20600
|
-
// for the value in A2). In this case, we will simply take the first value of each matrix and
|
|
20601
|
-
// return the array [First value of MUNIT(A1), First value of MUNIT(A2)].
|
|
20602
|
-
return isMatrix(singleCellComputeResult)
|
|
20603
|
-
? singleCellComputeResult[0][0]
|
|
20604
|
-
: singleCellComputeResult;
|
|
20605
|
-
});
|
|
20682
|
+
return applyVectorization(errorHandlingCompute.bind(this), args, acceptToVectorize);
|
|
20606
20683
|
}
|
|
20607
20684
|
function errorHandlingCompute(...args) {
|
|
20608
20685
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -21447,7 +21524,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
21447
21524
|
proposals &&
|
|
21448
21525
|
!["ARG_SEPARATOR", "LEFT_PAREN", "OPERATOR"].includes(tokenAtCursor.type)) {
|
|
21449
21526
|
const filteredProposals = fuzzyLookup(searchTerm, proposals, (p) => p.fuzzySearchKey || p.text);
|
|
21450
|
-
if (!exactMatch || filteredProposals.length
|
|
21527
|
+
if (!exactMatch || filteredProposals.length) {
|
|
21451
21528
|
proposals = filteredProposals;
|
|
21452
21529
|
}
|
|
21453
21530
|
}
|
|
@@ -46483,7 +46560,9 @@ function compareDimensionValues(dimension, a, b) {
|
|
|
46483
46560
|
return dimension.order === "asc" ? -1 : 1;
|
|
46484
46561
|
}
|
|
46485
46562
|
if (dimension.type === "integer" || dimension.type === "datetime") {
|
|
46486
|
-
return dimension.order === "asc"
|
|
46563
|
+
return dimension.order === "asc"
|
|
46564
|
+
? toNumber(a, DEFAULT_LOCALE) - toNumber(b, DEFAULT_LOCALE)
|
|
46565
|
+
: toNumber(b, DEFAULT_LOCALE) - toNumber(a, DEFAULT_LOCALE);
|
|
46487
46566
|
}
|
|
46488
46567
|
return dimension.order === "asc" ? a.localeCompare(b) : b.localeCompare(a);
|
|
46489
46568
|
}
|
|
@@ -49246,8 +49325,7 @@ class CellComposerStore extends AbstractComposerStore {
|
|
|
49246
49325
|
if (!spreader) {
|
|
49247
49326
|
return undefined;
|
|
49248
49327
|
}
|
|
49249
|
-
|
|
49250
|
-
return cell?.content;
|
|
49328
|
+
return this.getters.getCellText(spreader, { showFormula: true });
|
|
49251
49329
|
}
|
|
49252
49330
|
get currentEditedCell() {
|
|
49253
49331
|
return {
|
|
@@ -52168,6 +52246,7 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
52168
52246
|
const friction = 0.95;
|
|
52169
52247
|
const verticalScrollFactor = 1;
|
|
52170
52248
|
const horizontalScrollFactor = 1;
|
|
52249
|
+
const resetTimeoutDuration = 100;
|
|
52171
52250
|
function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
52172
52251
|
let lastX = 0;
|
|
52173
52252
|
let lastY = 0;
|
|
@@ -52175,6 +52254,7 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
|
52175
52254
|
let velocityY = 0;
|
|
52176
52255
|
let isMouseDown = false;
|
|
52177
52256
|
let lastTime = 0;
|
|
52257
|
+
let resetTimeout = null;
|
|
52178
52258
|
useRefListener(ref, "touchstart", onTouchStart, { capture: false });
|
|
52179
52259
|
useRefListener(ref, "touchmove", onTouchMove, { capture: false });
|
|
52180
52260
|
useRefListener(ref, "touchend", onTouchEnd, { capture: false });
|
|
@@ -52187,6 +52267,10 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
|
52187
52267
|
function onTouchMove(event) {
|
|
52188
52268
|
if (!isMouseDown)
|
|
52189
52269
|
return;
|
|
52270
|
+
if (resetTimeout) {
|
|
52271
|
+
clearTimeout(resetTimeout);
|
|
52272
|
+
resetTimeout = null;
|
|
52273
|
+
}
|
|
52190
52274
|
const currentTime = Date.now();
|
|
52191
52275
|
const { clientX, clientY } = event.touches[0];
|
|
52192
52276
|
let deltaX = lastX - clientX;
|
|
@@ -52203,6 +52287,10 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
|
52203
52287
|
}
|
|
52204
52288
|
event.stopPropagation();
|
|
52205
52289
|
}
|
|
52290
|
+
resetTimeout = setTimeout(() => {
|
|
52291
|
+
velocityX = 0;
|
|
52292
|
+
velocityY = 0;
|
|
52293
|
+
}, resetTimeoutDuration);
|
|
52206
52294
|
updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
|
|
52207
52295
|
}
|
|
52208
52296
|
function onTouchEnd(ev) {
|
|
@@ -76827,6 +76915,6 @@ exports.tokenColors = tokenColors;
|
|
|
76827
76915
|
exports.tokenize = tokenize;
|
|
76828
76916
|
|
|
76829
76917
|
|
|
76830
|
-
__info__.version = "18.2.
|
|
76831
|
-
__info__.date = "2025-05-
|
|
76832
|
-
__info__.hash = "
|
|
76918
|
+
__info__.version = "18.2.14";
|
|
76919
|
+
__info__.date = "2025-05-26T12:35:51.528Z";
|
|
76920
|
+
__info__.hash = "db90fca";
|