@odoo/o-spreadsheet 18.0.29 → 18.0.31
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 +206 -122
- package/dist/o-spreadsheet.esm.js +206 -122
- package/dist/o-spreadsheet.iife.js +206 -122
- package/dist/o-spreadsheet.iife.min.js +361 -361
- package/dist/o_spreadsheet.xml +6 -6
- 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.0.
|
|
6
|
-
* @date 2025-05-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.0.31
|
|
6
|
+
* @date 2025-05-30T08:43:10.315Z
|
|
7
|
+
* @hash d201086
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -3973,6 +3973,113 @@ function transposeMatrix(matrix) {
|
|
|
3973
3973
|
}
|
|
3974
3974
|
return generateMatrix(matrix[0].length, matrix.length, (i, j) => matrix[j][i]);
|
|
3975
3975
|
}
|
|
3976
|
+
/**
|
|
3977
|
+
* Enables a formula function to accept matrix or vector inputs instead of simple value, computing results across multiple dimensions.
|
|
3978
|
+
*
|
|
3979
|
+
* ```
|
|
3980
|
+
* / |‾ ‾| \ |‾ ‾|
|
|
3981
|
+
* | | [A] | | | compute(A, D, E), compute(A, D, F), compute(A, D, G) |
|
|
3982
|
+
* applyVectorization| compute, | [B], D, [E, F, G] | | <=> | compute(B, D, E), compute(B, D, F), compute(B, D, G) |
|
|
3983
|
+
* | | [C] | | | compute(C, D, E), compute(C, D, F), compute(C, D, G) |
|
|
3984
|
+
* \ |_ _| / |_ _|
|
|
3985
|
+
* ```
|
|
3986
|
+
*
|
|
3987
|
+
* By default, all arguments are vectorized. To control which arguments are vectorized,
|
|
3988
|
+
* pass an `acceptToVectorize` boolean array of the same length as `args`:
|
|
3989
|
+
* - `true` enables vectorization for that argument
|
|
3990
|
+
* - `false` disables vectorization for that argument
|
|
3991
|
+
*
|
|
3992
|
+
* For example, with `[true, true, false]` on previous example you get:
|
|
3993
|
+
*
|
|
3994
|
+
* ```
|
|
3995
|
+
* |‾ ‾|
|
|
3996
|
+
* | compute(A, D, [E, F, G]) |
|
|
3997
|
+
* | compute(B, D, [E, F, G]) |
|
|
3998
|
+
* | compute(C, D, [E, F, G]) |
|
|
3999
|
+
* |_ _|
|
|
4000
|
+
* ```
|
|
4001
|
+
*
|
|
4002
|
+
* @remarks
|
|
4003
|
+
* This helper is automatically applied (by default) to **all** `compute` functions
|
|
4004
|
+
* across the various spreadsheet formula modules:
|
|
4005
|
+
* - If an argument is declared **scalar** (not `"range"`), it is vectorized.
|
|
4006
|
+
* - If **all** arguments are declared **ranges**, no vectorization occurs.
|
|
4007
|
+
* - e.g. `SUM(A1:B2)` returns a 1×1 sum over the range.
|
|
4008
|
+
* - e.g. `COS(A1:B2)` over `A1:B2` returns a 2×2 element-wise result.
|
|
4009
|
+
* - For special behaviors (e.g. the `IF` function), you may declare all arguments
|
|
4010
|
+
* as ranges and invoke this helper directly within your `compute` implementation.
|
|
4011
|
+
*/
|
|
4012
|
+
function applyVectorization(formula, args, acceptToVectorize = undefined) {
|
|
4013
|
+
let countVectorizedCol = 1;
|
|
4014
|
+
let countVectorizedRow = 1;
|
|
4015
|
+
let vectorizedColLimit = Infinity;
|
|
4016
|
+
let vectorizedRowLimit = Infinity;
|
|
4017
|
+
let vectorArgsType = undefined;
|
|
4018
|
+
for (let i = 0; i < args.length; i++) {
|
|
4019
|
+
const arg = args[i];
|
|
4020
|
+
if (isMatrix(arg) && (acceptToVectorize === undefined || acceptToVectorize[i])) {
|
|
4021
|
+
const nColumns = arg.length;
|
|
4022
|
+
const nRows = arg[0].length;
|
|
4023
|
+
if (nColumns !== 1 || nRows !== 1) {
|
|
4024
|
+
vectorArgsType ??= new Array(args.length);
|
|
4025
|
+
if (nColumns !== 1 && nRows !== 1) {
|
|
4026
|
+
vectorArgsType[i] = "matrix";
|
|
4027
|
+
countVectorizedCol = Math.max(countVectorizedCol, nColumns);
|
|
4028
|
+
countVectorizedRow = Math.max(countVectorizedRow, nRows);
|
|
4029
|
+
vectorizedColLimit = Math.min(vectorizedColLimit, nColumns);
|
|
4030
|
+
vectorizedRowLimit = Math.min(vectorizedRowLimit, nRows);
|
|
4031
|
+
}
|
|
4032
|
+
else if (nColumns !== 1) {
|
|
4033
|
+
vectorArgsType[i] = "horizontal";
|
|
4034
|
+
countVectorizedCol = Math.max(countVectorizedCol, nColumns);
|
|
4035
|
+
vectorizedColLimit = Math.min(vectorizedColLimit, nColumns);
|
|
4036
|
+
}
|
|
4037
|
+
else if (nRows !== 1) {
|
|
4038
|
+
vectorArgsType[i] = "vertical";
|
|
4039
|
+
countVectorizedRow = Math.max(countVectorizedRow, nRows);
|
|
4040
|
+
vectorizedRowLimit = Math.min(vectorizedRowLimit, nRows);
|
|
4041
|
+
}
|
|
4042
|
+
}
|
|
4043
|
+
else {
|
|
4044
|
+
args[i] = arg[0][0];
|
|
4045
|
+
}
|
|
4046
|
+
}
|
|
4047
|
+
}
|
|
4048
|
+
if (countVectorizedCol === 1 && countVectorizedRow === 1) {
|
|
4049
|
+
// either this function is not vectorized or it ends up with a 1x1 dimension
|
|
4050
|
+
return formula(...args);
|
|
4051
|
+
}
|
|
4052
|
+
const getArgOffset = (i, j) => args.map((arg, index) => {
|
|
4053
|
+
switch (vectorArgsType?.[index]) {
|
|
4054
|
+
case "matrix":
|
|
4055
|
+
return arg[i][j];
|
|
4056
|
+
case "horizontal":
|
|
4057
|
+
return arg[i][0];
|
|
4058
|
+
case "vertical":
|
|
4059
|
+
return arg[0][j];
|
|
4060
|
+
case undefined:
|
|
4061
|
+
return arg;
|
|
4062
|
+
}
|
|
4063
|
+
});
|
|
4064
|
+
return generateMatrix(countVectorizedCol, countVectorizedRow, (col, row) => {
|
|
4065
|
+
if (col > vectorizedColLimit - 1 || row > vectorizedRowLimit - 1) {
|
|
4066
|
+
return new NotAvailableError(_t("Array arguments to [[FUNCTION_NAME]] are of different size."));
|
|
4067
|
+
}
|
|
4068
|
+
const singleCellComputeResult = formula(...getArgOffset(col, row));
|
|
4069
|
+
// In the case where the user tries to vectorize arguments of an array formula, we will get an
|
|
4070
|
+
// array for every combination of the vectorized arguments, which will lead to a 3D matrix and
|
|
4071
|
+
// we won't be able to return the values.
|
|
4072
|
+
// In this case, we keep the first element of each spreading part, just as Excel does, and
|
|
4073
|
+
// create an array with these parts.
|
|
4074
|
+
// For exemple, we have MUNIT(x) that return an unitary matrix of x*x. If we use it with a
|
|
4075
|
+
// range, like MUNIT(A1:A2), we will get two unitary matrices (one for the value in A1 and one
|
|
4076
|
+
// for the value in A2). In this case, we will simply take the first value of each matrix and
|
|
4077
|
+
// return the array [First value of MUNIT(A1), First value of MUNIT(A2)].
|
|
4078
|
+
return isMatrix(singleCellComputeResult)
|
|
4079
|
+
? singleCellComputeResult[0][0]
|
|
4080
|
+
: singleCellComputeResult;
|
|
4081
|
+
});
|
|
4082
|
+
}
|
|
3976
4083
|
// -----------------------------------------------------------------------------
|
|
3977
4084
|
// CONDITIONAL EXPLORE FUNCTIONS
|
|
3978
4085
|
// -----------------------------------------------------------------------------
|
|
@@ -7279,14 +7386,20 @@ function multiplyMatrices(matrix1, matrix2) {
|
|
|
7279
7386
|
/**
|
|
7280
7387
|
* Return the input if it's a scalar or the first element of the input if it's a matrix.
|
|
7281
7388
|
*/
|
|
7282
|
-
function toScalar(
|
|
7283
|
-
if (!isMatrix(
|
|
7284
|
-
return
|
|
7389
|
+
function toScalar(arg) {
|
|
7390
|
+
if (!isMatrix(arg)) {
|
|
7391
|
+
return arg;
|
|
7285
7392
|
}
|
|
7286
|
-
if (
|
|
7393
|
+
if (!isSingleElementMatrix(arg)) {
|
|
7287
7394
|
throw new EvaluationError(_t("The value should be a scalar or a 1x1 matrix"));
|
|
7288
7395
|
}
|
|
7289
|
-
return
|
|
7396
|
+
return arg[0][0];
|
|
7397
|
+
}
|
|
7398
|
+
function isSingleElementMatrix(matrix) {
|
|
7399
|
+
return matrix.length === 1 && matrix[0].length === 1;
|
|
7400
|
+
}
|
|
7401
|
+
function isMultipleElementMatrix(arg) {
|
|
7402
|
+
return isMatrix(arg) && !isSingleElementMatrix(arg);
|
|
7290
7403
|
}
|
|
7291
7404
|
|
|
7292
7405
|
function assertSameNumberOfElements(...args) {
|
|
@@ -8003,9 +8116,10 @@ const AGGREGATOR_NAMES = {
|
|
|
8003
8116
|
avg: _t("Average"),
|
|
8004
8117
|
sum: _t("Sum"),
|
|
8005
8118
|
};
|
|
8119
|
+
const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
|
|
8006
8120
|
const AGGREGATORS_BY_FIELD_TYPE = {
|
|
8007
|
-
integer:
|
|
8008
|
-
char:
|
|
8121
|
+
integer: NUMBER_CHAR_AGGREGATORS,
|
|
8122
|
+
char: NUMBER_CHAR_AGGREGATORS,
|
|
8009
8123
|
boolean: ["count_distinct", "count", "bool_and", "bool_or"],
|
|
8010
8124
|
};
|
|
8011
8125
|
const AGGREGATORS = {};
|
|
@@ -21487,7 +21601,7 @@ const FILTER = {
|
|
|
21487
21601
|
}
|
|
21488
21602
|
return mode === "row" ? transposeMatrix(result) : result;
|
|
21489
21603
|
},
|
|
21490
|
-
isExported:
|
|
21604
|
+
isExported: false,
|
|
21491
21605
|
};
|
|
21492
21606
|
// -----------------------------------------------------------------------------
|
|
21493
21607
|
// SORT
|
|
@@ -24455,16 +24569,23 @@ const FALSE = {
|
|
|
24455
24569
|
const IF = {
|
|
24456
24570
|
description: _t("Returns value depending on logical expression."),
|
|
24457
24571
|
args: [
|
|
24458
|
-
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.")),
|
|
24459
|
-
arg("value_if_true (any)", _t("The value the function returns if logical_expression is TRUE.")),
|
|
24460
|
-
arg("value_if_false (any, default=FALSE)", _t("The value the function returns if logical_expression is FALSE.")),
|
|
24572
|
+
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.")),
|
|
24573
|
+
arg("value_if_true (any, range)", _t("The value the function returns if logical_expression is TRUE.")),
|
|
24574
|
+
arg("value_if_false (any, range, default=FALSE)", _t("The value the function returns if logical_expression is FALSE.")),
|
|
24461
24575
|
],
|
|
24462
24576
|
compute: function (logicalExpression, valueIfTrue, valueIfFalse) {
|
|
24463
|
-
|
|
24577
|
+
if (isMultipleElementMatrix(logicalExpression)) {
|
|
24578
|
+
return applyVectorization(IF.compute, [logicalExpression, valueIfTrue, valueIfFalse]);
|
|
24579
|
+
}
|
|
24580
|
+
let result = toBoolean(toScalar(logicalExpression)) ? valueIfTrue : valueIfFalse;
|
|
24581
|
+
// useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
|
|
24582
|
+
if (!isMultipleElementMatrix(result)) {
|
|
24583
|
+
result = toScalar(result);
|
|
24584
|
+
}
|
|
24464
24585
|
if (result === undefined) {
|
|
24465
24586
|
return { value: "" };
|
|
24466
24587
|
}
|
|
24467
|
-
if (result.value === null) {
|
|
24588
|
+
if (!isMatrix(result) && result.value === null) {
|
|
24468
24589
|
return { ...result, value: "" };
|
|
24469
24590
|
}
|
|
24470
24591
|
return result;
|
|
@@ -24477,15 +24598,22 @@ const IF = {
|
|
|
24477
24598
|
const IFERROR = {
|
|
24478
24599
|
description: _t("Value if it is not an error, otherwise 2nd argument."),
|
|
24479
24600
|
args: [
|
|
24480
|
-
arg("value (any)", _t("The value to return if value itself is not an error.")),
|
|
24481
|
-
arg(`value_if_error (any, default="empty")`, _t("The value the function returns if value is an error.")),
|
|
24601
|
+
arg("value (any, range)", _t("The value to return if value itself is not an error.")),
|
|
24602
|
+
arg(`value_if_error (any, range, default="empty")`, _t("The value the function returns if value is an error.")),
|
|
24482
24603
|
],
|
|
24483
|
-
compute: function (value, valueIfError
|
|
24484
|
-
|
|
24604
|
+
compute: function (value, valueIfError) {
|
|
24605
|
+
if (isMultipleElementMatrix(value)) {
|
|
24606
|
+
return applyVectorization(IFERROR.compute, [value, valueIfError]);
|
|
24607
|
+
}
|
|
24608
|
+
let result = isEvaluationError(toScalar(value)?.value) ? valueIfError : value;
|
|
24609
|
+
// useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
|
|
24610
|
+
if (!isMultipleElementMatrix(result)) {
|
|
24611
|
+
result = toScalar(result);
|
|
24612
|
+
}
|
|
24485
24613
|
if (result === undefined) {
|
|
24486
24614
|
return { value: "" };
|
|
24487
24615
|
}
|
|
24488
|
-
if (result.value === null) {
|
|
24616
|
+
if (!isMatrix(result) && result.value === null) {
|
|
24489
24617
|
return { ...result, value: "" };
|
|
24490
24618
|
}
|
|
24491
24619
|
return result;
|
|
@@ -24498,15 +24626,22 @@ const IFERROR = {
|
|
|
24498
24626
|
const IFNA = {
|
|
24499
24627
|
description: _t("Value if it is not an #N/A error, otherwise 2nd argument."),
|
|
24500
24628
|
args: [
|
|
24501
|
-
arg("value (any)", _t("The value to return if value itself is not #N/A an error.")),
|
|
24502
|
-
arg(`value_if_error (any, default="empty")`, _t("The value the function returns if value is an #N/A error.")),
|
|
24629
|
+
arg("value (any, range)", _t("The value to return if value itself is not #N/A an error.")),
|
|
24630
|
+
arg(`value_if_error (any, range, default="empty")`, _t("The value the function returns if value is an #N/A error.")),
|
|
24503
24631
|
],
|
|
24504
|
-
compute: function (value, valueIfError
|
|
24505
|
-
|
|
24632
|
+
compute: function (value, valueIfError) {
|
|
24633
|
+
if (isMultipleElementMatrix(value)) {
|
|
24634
|
+
return applyVectorization(IFNA.compute, [value, valueIfError]);
|
|
24635
|
+
}
|
|
24636
|
+
let result = toScalar(value)?.value === CellErrorType.NotAvailable ? valueIfError : value;
|
|
24637
|
+
// useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
|
|
24638
|
+
if (!isMultipleElementMatrix(result)) {
|
|
24639
|
+
result = toScalar(result);
|
|
24640
|
+
}
|
|
24506
24641
|
if (result === undefined) {
|
|
24507
24642
|
return { value: "" };
|
|
24508
24643
|
}
|
|
24509
|
-
if (result.value === null) {
|
|
24644
|
+
if (!isMatrix(result) && result.value === null) {
|
|
24510
24645
|
return { ...result, value: "" };
|
|
24511
24646
|
}
|
|
24512
24647
|
return result;
|
|
@@ -24519,23 +24654,31 @@ const IFNA = {
|
|
|
24519
24654
|
const IFS = {
|
|
24520
24655
|
description: _t("Returns a value depending on multiple logical expressions."),
|
|
24521
24656
|
args: [
|
|
24522
|
-
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.")),
|
|
24523
|
-
arg("value1 (any)", _t("The returned value if condition1 is TRUE.")),
|
|
24524
|
-
arg("condition2 (boolean, any, repeating)", _t("Additional conditions to be evaluated if the previous ones are FALSE.")),
|
|
24525
|
-
arg("value2 (any, repeating)", _t("Additional values to be returned if their corresponding conditions are TRUE.")),
|
|
24657
|
+
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.")),
|
|
24658
|
+
arg("value1 (any, range)", _t("The returned value if condition1 is TRUE.")),
|
|
24659
|
+
arg("condition2 (boolean, any, range, repeating)", _t("Additional conditions to be evaluated if the previous ones are FALSE.")),
|
|
24660
|
+
arg("value2 (any, range, repeating)", _t("Additional values to be returned if their corresponding conditions are TRUE.")),
|
|
24526
24661
|
],
|
|
24527
24662
|
compute: function (...values) {
|
|
24528
24663
|
assert(() => values.length % 2 === 0, _t("Wrong number of arguments. Expected an even number of arguments."));
|
|
24529
|
-
|
|
24530
|
-
if (
|
|
24531
|
-
|
|
24532
|
-
|
|
24664
|
+
while (values.length > 0) {
|
|
24665
|
+
if (isMultipleElementMatrix(values[0])) {
|
|
24666
|
+
return applyVectorization(IFS.compute, values);
|
|
24667
|
+
}
|
|
24668
|
+
const condition = toBoolean(toScalar(values.shift()));
|
|
24669
|
+
let valueIfTrue = values.shift();
|
|
24670
|
+
if (condition) {
|
|
24671
|
+
// useful for interpreting empty cell references as empty strings. But must be removed to make empty cell references equal to zero
|
|
24672
|
+
if (!isMultipleElementMatrix(valueIfTrue)) {
|
|
24673
|
+
valueIfTrue = toScalar(valueIfTrue);
|
|
24674
|
+
}
|
|
24675
|
+
if (valueIfTrue === undefined) {
|
|
24533
24676
|
return { value: "" };
|
|
24534
24677
|
}
|
|
24535
|
-
if (
|
|
24536
|
-
return { ...
|
|
24678
|
+
if (!isMatrix(valueIfTrue) && valueIfTrue.value === null) {
|
|
24679
|
+
return { ...valueIfTrue, value: "" };
|
|
24537
24680
|
}
|
|
24538
|
-
return
|
|
24681
|
+
return valueIfTrue;
|
|
24539
24682
|
}
|
|
24540
24683
|
}
|
|
24541
24684
|
return new EvaluationError(_t("No match."));
|
|
@@ -26179,7 +26322,7 @@ const SPLIT = {
|
|
|
26179
26322
|
}
|
|
26180
26323
|
return transposeMatrix([result]);
|
|
26181
26324
|
},
|
|
26182
|
-
isExported:
|
|
26325
|
+
isExported: false,
|
|
26183
26326
|
};
|
|
26184
26327
|
// -----------------------------------------------------------------------------
|
|
26185
26328
|
// SUBSTITUTE
|
|
@@ -26372,86 +26515,21 @@ for (let category of categories) {
|
|
|
26372
26515
|
functionRegistry.add(name, { isExported: false, ...addDescr });
|
|
26373
26516
|
}
|
|
26374
26517
|
}
|
|
26375
|
-
|
|
26518
|
+
//------------------------------------------------------------------------------
|
|
26519
|
+
// CREATE COMPUTE FUNCTION
|
|
26520
|
+
//------------------------------------------------------------------------------
|
|
26376
26521
|
function createComputeFunction(descr, functionName) {
|
|
26377
26522
|
function vectorizedCompute(...args) {
|
|
26378
|
-
|
|
26379
|
-
let countVectorizableRow = 1;
|
|
26380
|
-
let vectorizableColLimit = Infinity;
|
|
26381
|
-
let vectorizableRowLimit = Infinity;
|
|
26382
|
-
let vectorArgsType = undefined;
|
|
26383
|
-
//#region Compute vectorisation limits
|
|
26523
|
+
const acceptToVectorize = [];
|
|
26384
26524
|
for (let i = 0; i < args.length; i++) {
|
|
26385
26525
|
const argDefinition = descr.args[descr.getArgToFocus(i + 1) - 1];
|
|
26386
26526
|
const arg = args[i];
|
|
26387
|
-
if (isMatrix(arg) && !argDefinition.acceptMatrix) {
|
|
26388
|
-
// if argDefinition does not accept a matrix but arg is still a matrix
|
|
26389
|
-
// --> triggers the arguments vectorization
|
|
26390
|
-
const nColumns = arg.length;
|
|
26391
|
-
const nRows = arg[0].length;
|
|
26392
|
-
if (nColumns !== 1 || nRows !== 1) {
|
|
26393
|
-
vectorArgsType ??= new Array(args.length);
|
|
26394
|
-
if (nColumns !== 1 && nRows !== 1) {
|
|
26395
|
-
vectorArgsType[i] = "matrix";
|
|
26396
|
-
countVectorizableCol = Math.max(countVectorizableCol, nColumns);
|
|
26397
|
-
countVectorizableRow = Math.max(countVectorizableRow, nRows);
|
|
26398
|
-
vectorizableColLimit = Math.min(vectorizableColLimit, nColumns);
|
|
26399
|
-
vectorizableRowLimit = Math.min(vectorizableRowLimit, nRows);
|
|
26400
|
-
}
|
|
26401
|
-
else if (nColumns !== 1) {
|
|
26402
|
-
vectorArgsType[i] = "horizontal";
|
|
26403
|
-
countVectorizableCol = Math.max(countVectorizableCol, nColumns);
|
|
26404
|
-
vectorizableColLimit = Math.min(vectorizableColLimit, nColumns);
|
|
26405
|
-
}
|
|
26406
|
-
else if (nRows !== 1) {
|
|
26407
|
-
vectorArgsType[i] = "vertical";
|
|
26408
|
-
countVectorizableRow = Math.max(countVectorizableRow, nRows);
|
|
26409
|
-
vectorizableRowLimit = Math.min(vectorizableRowLimit, nRows);
|
|
26410
|
-
}
|
|
26411
|
-
}
|
|
26412
|
-
else {
|
|
26413
|
-
args[i] = arg[0][0];
|
|
26414
|
-
}
|
|
26415
|
-
}
|
|
26416
26527
|
if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
|
|
26417
26528
|
throw new BadExpressionError(_t("Function %s expects the parameter '%s' to be reference to a cell or range.", functionName, (i + 1).toString()));
|
|
26418
26529
|
}
|
|
26530
|
+
acceptToVectorize.push(!argDefinition.acceptMatrix);
|
|
26419
26531
|
}
|
|
26420
|
-
|
|
26421
|
-
if (countVectorizableCol === 1 && countVectorizableRow === 1) {
|
|
26422
|
-
// either this function is not vectorized or it ends up with a 1x1 dimension
|
|
26423
|
-
return errorHandlingCompute.apply(this, args);
|
|
26424
|
-
}
|
|
26425
|
-
const getArgOffset = (i, j) => args.map((arg, index) => {
|
|
26426
|
-
switch (vectorArgsType?.[index]) {
|
|
26427
|
-
case "matrix":
|
|
26428
|
-
return arg[i][j];
|
|
26429
|
-
case "horizontal":
|
|
26430
|
-
return arg[i][0];
|
|
26431
|
-
case "vertical":
|
|
26432
|
-
return arg[0][j];
|
|
26433
|
-
case undefined:
|
|
26434
|
-
return arg;
|
|
26435
|
-
}
|
|
26436
|
-
});
|
|
26437
|
-
return generateMatrix(countVectorizableCol, countVectorizableRow, (col, row) => {
|
|
26438
|
-
if (col > vectorizableColLimit - 1 || row > vectorizableRowLimit - 1) {
|
|
26439
|
-
return notAvailableError;
|
|
26440
|
-
}
|
|
26441
|
-
const singleCellComputeResult = errorHandlingCompute.apply(this, getArgOffset(col, row));
|
|
26442
|
-
// In the case where the user tries to vectorize arguments of an array formula, we will get an
|
|
26443
|
-
// array for every combination of the vectorized arguments, which will lead to a 3D matrix and
|
|
26444
|
-
// we won't be able to return the values.
|
|
26445
|
-
// In this case, we keep the first element of each spreading part, just as Excel does, and
|
|
26446
|
-
// create an array with these parts.
|
|
26447
|
-
// For exemple, we have MUNIT(x) that return an unitary matrix of x*x. If we use it with a
|
|
26448
|
-
// range, like MUNIT(A1:A2), we will get two unitary matrices (one for the value in A1 and one
|
|
26449
|
-
// for the value in A2). In this case, we will simply take the first value of each matrix and
|
|
26450
|
-
// return the array [First value of MUNIT(A1), First value of MUNIT(A2)].
|
|
26451
|
-
return isMatrix(singleCellComputeResult)
|
|
26452
|
-
? singleCellComputeResult[0][0]
|
|
26453
|
-
: singleCellComputeResult;
|
|
26454
|
-
});
|
|
26532
|
+
return applyVectorization(errorHandlingCompute.bind(this), args, acceptToVectorize);
|
|
26455
26533
|
}
|
|
26456
26534
|
function errorHandlingCompute(...args) {
|
|
26457
26535
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -39440,7 +39518,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
39440
39518
|
proposals &&
|
|
39441
39519
|
!["ARG_SEPARATOR", "LEFT_PAREN", "OPERATOR"].includes(tokenAtCursor.type)) {
|
|
39442
39520
|
const filteredProposals = fuzzyLookup(searchTerm, proposals, (p) => p.fuzzySearchKey || p.text);
|
|
39443
|
-
if (!exactMatch || filteredProposals.length
|
|
39521
|
+
if (!exactMatch || filteredProposals.length) {
|
|
39444
39522
|
proposals = filteredProposals;
|
|
39445
39523
|
}
|
|
39446
39524
|
}
|
|
@@ -44049,7 +44127,9 @@ function compareDimensionValues(dimension, a, b) {
|
|
|
44049
44127
|
return dimension.order === "asc" ? -1 : 1;
|
|
44050
44128
|
}
|
|
44051
44129
|
if (dimension.type === "integer" || dimension.type === "datetime") {
|
|
44052
|
-
return dimension.order === "asc"
|
|
44130
|
+
return dimension.order === "asc"
|
|
44131
|
+
? toNumber(a, DEFAULT_LOCALE) - toNumber(b, DEFAULT_LOCALE)
|
|
44132
|
+
: toNumber(b, DEFAULT_LOCALE) - toNumber(a, DEFAULT_LOCALE);
|
|
44053
44133
|
}
|
|
44054
44134
|
return dimension.order === "asc" ? a.localeCompare(b) : b.localeCompare(a);
|
|
44055
44135
|
}
|
|
@@ -44585,12 +44665,7 @@ class SpreadsheetPivot {
|
|
|
44585
44665
|
entry[field.name] = { value: null, type: CellValueType.empty, formattedValue: "" };
|
|
44586
44666
|
}
|
|
44587
44667
|
else {
|
|
44588
|
-
|
|
44589
|
-
entry[field.name] = { ...cell, value: cell.formattedValue || null };
|
|
44590
|
-
}
|
|
44591
|
-
else {
|
|
44592
|
-
entry[field.name] = cell;
|
|
44593
|
-
}
|
|
44668
|
+
entry[field.name] = cell;
|
|
44594
44669
|
}
|
|
44595
44670
|
}
|
|
44596
44671
|
entry["__count"] = { value: 1, type: CellValueType.number, formattedValue: "1" };
|
|
@@ -46790,8 +46865,7 @@ class CellComposerStore extends AbstractComposerStore {
|
|
|
46790
46865
|
if (!spreader) {
|
|
46791
46866
|
return undefined;
|
|
46792
46867
|
}
|
|
46793
|
-
|
|
46794
|
-
return cell?.content;
|
|
46868
|
+
return this.getters.getCellText(spreader, { showFormula: true });
|
|
46795
46869
|
}
|
|
46796
46870
|
get currentEditedCell() {
|
|
46797
46871
|
return {
|
|
@@ -49594,6 +49668,7 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
49594
49668
|
const friction = 0.95;
|
|
49595
49669
|
const verticalScrollFactor = 1;
|
|
49596
49670
|
const horizontalScrollFactor = 1;
|
|
49671
|
+
const resetTimeoutDuration = 100;
|
|
49597
49672
|
function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
49598
49673
|
let lastX = 0;
|
|
49599
49674
|
let lastY = 0;
|
|
@@ -49601,6 +49676,7 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
|
49601
49676
|
let velocityY = 0;
|
|
49602
49677
|
let isMouseDown = false;
|
|
49603
49678
|
let lastTime = 0;
|
|
49679
|
+
let resetTimeout = null;
|
|
49604
49680
|
useRefListener(ref, "touchstart", onTouchStart, { capture: false });
|
|
49605
49681
|
useRefListener(ref, "touchmove", onTouchMove, { capture: false });
|
|
49606
49682
|
useRefListener(ref, "touchend", onTouchEnd, { capture: false });
|
|
@@ -49613,6 +49689,10 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
|
49613
49689
|
function onTouchMove(event) {
|
|
49614
49690
|
if (!isMouseDown)
|
|
49615
49691
|
return;
|
|
49692
|
+
if (resetTimeout) {
|
|
49693
|
+
clearTimeout(resetTimeout);
|
|
49694
|
+
resetTimeout = null;
|
|
49695
|
+
}
|
|
49616
49696
|
const currentTime = Date.now();
|
|
49617
49697
|
const { clientX, clientY } = event.touches[0];
|
|
49618
49698
|
let deltaX = lastX - clientX;
|
|
@@ -49629,6 +49709,10 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
|
|
|
49629
49709
|
}
|
|
49630
49710
|
event.stopPropagation();
|
|
49631
49711
|
}
|
|
49712
|
+
resetTimeout = setTimeout(() => {
|
|
49713
|
+
velocityX = 0;
|
|
49714
|
+
velocityY = 0;
|
|
49715
|
+
}, resetTimeoutDuration);
|
|
49632
49716
|
updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
|
|
49633
49717
|
}
|
|
49634
49718
|
function onTouchEnd(ev) {
|
|
@@ -74316,6 +74400,6 @@ exports.tokenColors = tokenColors;
|
|
|
74316
74400
|
exports.tokenize = tokenize;
|
|
74317
74401
|
|
|
74318
74402
|
|
|
74319
|
-
__info__.version = "18.0.
|
|
74320
|
-
__info__.date = "2025-05-
|
|
74321
|
-
__info__.hash = "
|
|
74403
|
+
__info__.version = "18.0.31";
|
|
74404
|
+
__info__.date = "2025-05-30T08:43:10.315Z";
|
|
74405
|
+
__info__.hash = "d201086";
|