@odoo/o-spreadsheet 17.3.7 → 17.3.9
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 +235 -193
- package/dist/o-spreadsheet.d.ts +6 -3
- package/dist/o-spreadsheet.esm.js +235 -193
- package/dist/o-spreadsheet.iife.js +235 -193
- package/dist/o-spreadsheet.iife.min.js +7 -7
- package/dist/o_spreadsheet.xml +4 -4
- package/package.json +1 -1
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
5
5
|
* @see https://github.com/odoo/o-spreadsheet
|
|
6
|
-
* @version 17.3.
|
|
7
|
-
* @date 2024-07-
|
|
8
|
-
* @hash
|
|
6
|
+
* @version 17.3.9
|
|
7
|
+
* @date 2024-07-11T06:37:05.603Z
|
|
8
|
+
* @hash 2346a16
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
(function (exports, owl) {
|
|
@@ -592,7 +592,7 @@
|
|
|
592
592
|
/**
|
|
593
593
|
* Compares two objects.
|
|
594
594
|
*/
|
|
595
|
-
function deepEquals(o1, o2
|
|
595
|
+
function deepEquals(o1, o2) {
|
|
596
596
|
if (o1 === o2)
|
|
597
597
|
return true;
|
|
598
598
|
if ((o1 && !o2) || (o2 && !o1))
|
|
@@ -608,17 +608,13 @@
|
|
|
608
608
|
}
|
|
609
609
|
}
|
|
610
610
|
for (const key in o1) {
|
|
611
|
-
|
|
612
|
-
if (typeOfO1Key !== typeof o2[key])
|
|
611
|
+
if (typeof o1[key] !== typeof o2[key])
|
|
613
612
|
return false;
|
|
614
|
-
if (
|
|
615
|
-
if (!deepEquals(o1[key], o2[key]
|
|
613
|
+
if (typeof o1[key] === "object") {
|
|
614
|
+
if (!deepEquals(o1[key], o2[key]))
|
|
616
615
|
return false;
|
|
617
616
|
}
|
|
618
617
|
else {
|
|
619
|
-
if (ignoreFunctions && typeOfO1Key === "function") {
|
|
620
|
-
continue;
|
|
621
|
-
}
|
|
622
618
|
if (o1[key] !== o2[key])
|
|
623
619
|
return false;
|
|
624
620
|
}
|
|
@@ -1831,7 +1827,7 @@
|
|
|
1831
1827
|
});
|
|
1832
1828
|
const getNumberRegex = memoize(function getNumberRegex(locale) {
|
|
1833
1829
|
const decimalSeparator = escapeRegExp(locale.decimalSeparator);
|
|
1834
|
-
const thousandsSeparator = escapeRegExp(locale.thousandsSeparator);
|
|
1830
|
+
const thousandsSeparator = escapeRegExp(locale.thousandsSeparator || "");
|
|
1835
1831
|
const pIntegerAndDecimals = `(\\d+(${thousandsSeparator}\\d{3,})*(${decimalSeparator}\\d*)?)`; // pattern that match integer number with or without decimal digits
|
|
1836
1832
|
const pOnlyDecimals = `(${decimalSeparator}\\d+)`; // pattern that match only expression with decimal digits
|
|
1837
1833
|
const pScientificFormat = "(e(\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
|
|
@@ -1858,7 +1854,7 @@
|
|
|
1858
1854
|
return getNumberRegex(locale).test(value.trim());
|
|
1859
1855
|
}
|
|
1860
1856
|
const getInvaluableSymbolsRegexp = memoize(function getInvaluableSymbolsRegexp(locale) {
|
|
1861
|
-
return new RegExp(`[\$€${escapeRegExp(locale.thousandsSeparator)}]`, "g");
|
|
1857
|
+
return new RegExp(`[\$€${escapeRegExp(locale.thousandsSeparator || "")}]`, "g");
|
|
1862
1858
|
});
|
|
1863
1859
|
/**
|
|
1864
1860
|
* Convert a string into a number. It assumes that the string actually represents
|
|
@@ -2765,6 +2761,9 @@
|
|
|
2765
2761
|
* If the character is a special regular expression character, it is escaped with "\\".
|
|
2766
2762
|
*/
|
|
2767
2763
|
const wildcardToRegExp = memoize(function wildcardToRegExp(operand) {
|
|
2764
|
+
if (operand === "*") {
|
|
2765
|
+
return /.+/;
|
|
2766
|
+
}
|
|
2768
2767
|
let exp = "";
|
|
2769
2768
|
let predecessor = "";
|
|
2770
2769
|
for (let char of operand) {
|
|
@@ -2788,9 +2787,9 @@
|
|
|
2788
2787
|
}
|
|
2789
2788
|
return new RegExp("^" + exp + "$", "i");
|
|
2790
2789
|
});
|
|
2791
|
-
function evaluatePredicate(value, criterion) {
|
|
2790
|
+
function evaluatePredicate(value = "", criterion) {
|
|
2792
2791
|
const { operator, operand } = criterion;
|
|
2793
|
-
if (
|
|
2792
|
+
if (operand === undefined || value === null || operand === null) {
|
|
2794
2793
|
return false;
|
|
2795
2794
|
}
|
|
2796
2795
|
if (typeof operand === "number" && operator === "=") {
|
|
@@ -5895,19 +5894,22 @@
|
|
|
5895
5894
|
}
|
|
5896
5895
|
|
|
5897
5896
|
function isValidLocale(locale) {
|
|
5898
|
-
if (!
|
|
5899
|
-
typeof locale
|
|
5900
|
-
typeof locale.
|
|
5901
|
-
typeof locale.code === "string" &&
|
|
5902
|
-
typeof locale.thousandsSeparator === "string" &&
|
|
5903
|
-
typeof locale.decimalSeparator === "string" &&
|
|
5904
|
-
typeof locale.dateFormat === "string" &&
|
|
5905
|
-
typeof locale.timeFormat === "string" &&
|
|
5906
|
-
typeof locale.formulaArgSeparator === "string")) {
|
|
5897
|
+
if (!locale ||
|
|
5898
|
+
typeof locale !== "object" ||
|
|
5899
|
+
!(!locale.thousandsSeparator || typeof locale.thousandsSeparator === "string")) {
|
|
5907
5900
|
return false;
|
|
5908
5901
|
}
|
|
5909
|
-
|
|
5910
|
-
|
|
5902
|
+
for (const property of [
|
|
5903
|
+
"code",
|
|
5904
|
+
"name",
|
|
5905
|
+
"decimalSeparator",
|
|
5906
|
+
"dateFormat",
|
|
5907
|
+
"timeFormat",
|
|
5908
|
+
"formulaArgSeparator",
|
|
5909
|
+
]) {
|
|
5910
|
+
if (!locale[property] || typeof locale[property] !== "string") {
|
|
5911
|
+
return false;
|
|
5912
|
+
}
|
|
5911
5913
|
}
|
|
5912
5914
|
if (locale.formulaArgSeparator === locale.decimalSeparator) {
|
|
5913
5915
|
return false;
|
|
@@ -6005,7 +6007,10 @@
|
|
|
6005
6007
|
if (locale.decimalSeparator === "." || !isNumber(content, locale)) {
|
|
6006
6008
|
return content;
|
|
6007
6009
|
}
|
|
6008
|
-
|
|
6010
|
+
if (locale.thousandsSeparator) {
|
|
6011
|
+
content = content.replaceAll(locale.thousandsSeparator, "");
|
|
6012
|
+
}
|
|
6013
|
+
return content.replace(locale.decimalSeparator, ".");
|
|
6009
6014
|
}
|
|
6010
6015
|
/**
|
|
6011
6016
|
* Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
|
|
@@ -6994,6 +6999,146 @@
|
|
|
6994
6999
|
return undefined;
|
|
6995
7000
|
}
|
|
6996
7001
|
|
|
7002
|
+
var State;
|
|
7003
|
+
(function (State) {
|
|
7004
|
+
/**
|
|
7005
|
+
* Initial state.
|
|
7006
|
+
* Expecting any reference for the left part of a range
|
|
7007
|
+
* e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
|
|
7008
|
+
*/
|
|
7009
|
+
State[State["LeftRef"] = 0] = "LeftRef";
|
|
7010
|
+
/**
|
|
7011
|
+
* Expecting any reference for the right part of a range
|
|
7012
|
+
* e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
|
|
7013
|
+
*/
|
|
7014
|
+
State[State["RightRef"] = 1] = "RightRef";
|
|
7015
|
+
/**
|
|
7016
|
+
* Expecting the separator without any constraint on the right part
|
|
7017
|
+
*/
|
|
7018
|
+
State[State["Separator"] = 2] = "Separator";
|
|
7019
|
+
/**
|
|
7020
|
+
* Expecting the separator for a full column range
|
|
7021
|
+
*/
|
|
7022
|
+
State[State["FullColumnSeparator"] = 3] = "FullColumnSeparator";
|
|
7023
|
+
/**
|
|
7024
|
+
* Expecting the separator for a full row range
|
|
7025
|
+
*/
|
|
7026
|
+
State[State["FullRowSeparator"] = 4] = "FullRowSeparator";
|
|
7027
|
+
/**
|
|
7028
|
+
* Expecting the right part of a full column range
|
|
7029
|
+
* e.g. "1", "A1"
|
|
7030
|
+
*/
|
|
7031
|
+
State[State["RightColumnRef"] = 5] = "RightColumnRef";
|
|
7032
|
+
/**
|
|
7033
|
+
* Expecting the right part of a full row range
|
|
7034
|
+
* e.g. "A", "A1"
|
|
7035
|
+
*/
|
|
7036
|
+
State[State["RightRowRef"] = 6] = "RightRowRef";
|
|
7037
|
+
/**
|
|
7038
|
+
* Final state. A range has been matched
|
|
7039
|
+
*/
|
|
7040
|
+
State[State["Found"] = 7] = "Found";
|
|
7041
|
+
})(State || (State = {}));
|
|
7042
|
+
const goTo = (state, guard = () => true) => [
|
|
7043
|
+
{
|
|
7044
|
+
goTo: state,
|
|
7045
|
+
guard,
|
|
7046
|
+
},
|
|
7047
|
+
];
|
|
7048
|
+
const goToMulti = (state, guard = () => true) => ({
|
|
7049
|
+
goTo: state,
|
|
7050
|
+
guard,
|
|
7051
|
+
});
|
|
7052
|
+
const machine = {
|
|
7053
|
+
[State.LeftRef]: {
|
|
7054
|
+
REFERENCE: goTo(State.Separator),
|
|
7055
|
+
NUMBER: goTo(State.FullRowSeparator),
|
|
7056
|
+
SYMBOL: [
|
|
7057
|
+
goToMulti(State.FullColumnSeparator, (token) => isColReference(token.value)),
|
|
7058
|
+
goToMulti(State.FullRowSeparator, (token) => isRowReference(token.value)),
|
|
7059
|
+
],
|
|
7060
|
+
},
|
|
7061
|
+
[State.FullColumnSeparator]: {
|
|
7062
|
+
SPACE: goTo(State.FullColumnSeparator),
|
|
7063
|
+
OPERATOR: goTo(State.RightColumnRef, (token) => token.value === ":"),
|
|
7064
|
+
},
|
|
7065
|
+
[State.FullRowSeparator]: {
|
|
7066
|
+
SPACE: goTo(State.FullRowSeparator),
|
|
7067
|
+
OPERATOR: goTo(State.RightRowRef, (token) => token.value === ":"),
|
|
7068
|
+
},
|
|
7069
|
+
[State.Separator]: {
|
|
7070
|
+
SPACE: goTo(State.Separator),
|
|
7071
|
+
OPERATOR: goTo(State.RightRef, (token) => token.value === ":"),
|
|
7072
|
+
},
|
|
7073
|
+
[State.RightRef]: {
|
|
7074
|
+
SPACE: goTo(State.RightRef),
|
|
7075
|
+
NUMBER: goTo(State.Found),
|
|
7076
|
+
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
7077
|
+
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
|
|
7078
|
+
},
|
|
7079
|
+
[State.RightColumnRef]: {
|
|
7080
|
+
SPACE: goTo(State.RightColumnRef),
|
|
7081
|
+
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
|
|
7082
|
+
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
7083
|
+
},
|
|
7084
|
+
[State.RightRowRef]: {
|
|
7085
|
+
SPACE: goTo(State.RightRowRef),
|
|
7086
|
+
NUMBER: goTo(State.Found),
|
|
7087
|
+
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
7088
|
+
SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
|
|
7089
|
+
},
|
|
7090
|
+
[State.Found]: {},
|
|
7091
|
+
};
|
|
7092
|
+
/**
|
|
7093
|
+
* Check if the list of tokens starts with a sequence of tokens representing
|
|
7094
|
+
* a range.
|
|
7095
|
+
* If a range is found, the sequence is removed from the list and is returned
|
|
7096
|
+
* as a single token.
|
|
7097
|
+
*/
|
|
7098
|
+
function matchReference(tokens) {
|
|
7099
|
+
let head = 0;
|
|
7100
|
+
let transitions = machine[State.LeftRef];
|
|
7101
|
+
let matchedTokens = "";
|
|
7102
|
+
while (transitions !== undefined) {
|
|
7103
|
+
const token = tokens[head++];
|
|
7104
|
+
if (!token) {
|
|
7105
|
+
return null;
|
|
7106
|
+
}
|
|
7107
|
+
const transition = transitions[token.type]?.find((transition) => transition.guard(token));
|
|
7108
|
+
const nextState = transition ? transition.goTo : undefined;
|
|
7109
|
+
switch (nextState) {
|
|
7110
|
+
case undefined:
|
|
7111
|
+
return null;
|
|
7112
|
+
case State.Found:
|
|
7113
|
+
matchedTokens += token.value;
|
|
7114
|
+
tokens.splice(0, head);
|
|
7115
|
+
return {
|
|
7116
|
+
type: "REFERENCE",
|
|
7117
|
+
value: matchedTokens,
|
|
7118
|
+
};
|
|
7119
|
+
default:
|
|
7120
|
+
transitions = machine[nextState];
|
|
7121
|
+
matchedTokens += token.value;
|
|
7122
|
+
break;
|
|
7123
|
+
}
|
|
7124
|
+
}
|
|
7125
|
+
return null;
|
|
7126
|
+
}
|
|
7127
|
+
/**
|
|
7128
|
+
* Take the result of the tokenizer and transform it to be usable in the
|
|
7129
|
+
* manipulations of range
|
|
7130
|
+
*
|
|
7131
|
+
* @param formula
|
|
7132
|
+
*/
|
|
7133
|
+
function rangeTokenize(formula, locale = DEFAULT_LOCALE) {
|
|
7134
|
+
const tokens = tokenize(formula, locale);
|
|
7135
|
+
const result = [];
|
|
7136
|
+
while (tokens.length) {
|
|
7137
|
+
result.push(matchReference(tokens) || tokens.shift());
|
|
7138
|
+
}
|
|
7139
|
+
return result;
|
|
7140
|
+
}
|
|
7141
|
+
|
|
6997
7142
|
const functionRegex = /[a-zA-Z0-9\_]+(\.[a-zA-Z0-9\_]+)*/;
|
|
6998
7143
|
const UNARY_OPERATORS_PREFIX = ["-", "+"];
|
|
6999
7144
|
const UNARY_OPERATORS_POSTFIX = ["%"];
|
|
@@ -7142,7 +7287,7 @@
|
|
|
7142
7287
|
* Parse an expression (as a string) into an AST.
|
|
7143
7288
|
*/
|
|
7144
7289
|
function parse(str) {
|
|
7145
|
-
return parseTokens(
|
|
7290
|
+
return parseTokens(rangeTokenize(str));
|
|
7146
7291
|
}
|
|
7147
7292
|
function parseTokens(tokens) {
|
|
7148
7293
|
tokens = tokens.filter((x) => x.type !== "SPACE");
|
|
@@ -7278,146 +7423,6 @@
|
|
|
7278
7423
|
return needParenthesis ? `(${astToFormula(rightOperation)})` : astToFormula(rightOperation);
|
|
7279
7424
|
}
|
|
7280
7425
|
|
|
7281
|
-
var State;
|
|
7282
|
-
(function (State) {
|
|
7283
|
-
/**
|
|
7284
|
-
* Initial state.
|
|
7285
|
-
* Expecting any reference for the left part of a range
|
|
7286
|
-
* e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
|
|
7287
|
-
*/
|
|
7288
|
-
State[State["LeftRef"] = 0] = "LeftRef";
|
|
7289
|
-
/**
|
|
7290
|
-
* Expecting any reference for the right part of a range
|
|
7291
|
-
* e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
|
|
7292
|
-
*/
|
|
7293
|
-
State[State["RightRef"] = 1] = "RightRef";
|
|
7294
|
-
/**
|
|
7295
|
-
* Expecting the separator without any constraint on the right part
|
|
7296
|
-
*/
|
|
7297
|
-
State[State["Separator"] = 2] = "Separator";
|
|
7298
|
-
/**
|
|
7299
|
-
* Expecting the separator for a full column range
|
|
7300
|
-
*/
|
|
7301
|
-
State[State["FullColumnSeparator"] = 3] = "FullColumnSeparator";
|
|
7302
|
-
/**
|
|
7303
|
-
* Expecting the separator for a full row range
|
|
7304
|
-
*/
|
|
7305
|
-
State[State["FullRowSeparator"] = 4] = "FullRowSeparator";
|
|
7306
|
-
/**
|
|
7307
|
-
* Expecting the right part of a full column range
|
|
7308
|
-
* e.g. "1", "A1"
|
|
7309
|
-
*/
|
|
7310
|
-
State[State["RightColumnRef"] = 5] = "RightColumnRef";
|
|
7311
|
-
/**
|
|
7312
|
-
* Expecting the right part of a full row range
|
|
7313
|
-
* e.g. "A", "A1"
|
|
7314
|
-
*/
|
|
7315
|
-
State[State["RightRowRef"] = 6] = "RightRowRef";
|
|
7316
|
-
/**
|
|
7317
|
-
* Final state. A range has been matched
|
|
7318
|
-
*/
|
|
7319
|
-
State[State["Found"] = 7] = "Found";
|
|
7320
|
-
})(State || (State = {}));
|
|
7321
|
-
const goTo = (state, guard = () => true) => [
|
|
7322
|
-
{
|
|
7323
|
-
goTo: state,
|
|
7324
|
-
guard,
|
|
7325
|
-
},
|
|
7326
|
-
];
|
|
7327
|
-
const goToMulti = (state, guard = () => true) => ({
|
|
7328
|
-
goTo: state,
|
|
7329
|
-
guard,
|
|
7330
|
-
});
|
|
7331
|
-
const machine = {
|
|
7332
|
-
[State.LeftRef]: {
|
|
7333
|
-
REFERENCE: goTo(State.Separator),
|
|
7334
|
-
NUMBER: goTo(State.FullRowSeparator),
|
|
7335
|
-
SYMBOL: [
|
|
7336
|
-
goToMulti(State.FullColumnSeparator, (token) => isColReference(token.value)),
|
|
7337
|
-
goToMulti(State.FullRowSeparator, (token) => isRowReference(token.value)),
|
|
7338
|
-
],
|
|
7339
|
-
},
|
|
7340
|
-
[State.FullColumnSeparator]: {
|
|
7341
|
-
SPACE: goTo(State.FullColumnSeparator),
|
|
7342
|
-
OPERATOR: goTo(State.RightColumnRef, (token) => token.value === ":"),
|
|
7343
|
-
},
|
|
7344
|
-
[State.FullRowSeparator]: {
|
|
7345
|
-
SPACE: goTo(State.FullRowSeparator),
|
|
7346
|
-
OPERATOR: goTo(State.RightRowRef, (token) => token.value === ":"),
|
|
7347
|
-
},
|
|
7348
|
-
[State.Separator]: {
|
|
7349
|
-
SPACE: goTo(State.Separator),
|
|
7350
|
-
OPERATOR: goTo(State.RightRef, (token) => token.value === ":"),
|
|
7351
|
-
},
|
|
7352
|
-
[State.RightRef]: {
|
|
7353
|
-
SPACE: goTo(State.RightRef),
|
|
7354
|
-
NUMBER: goTo(State.Found),
|
|
7355
|
-
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
7356
|
-
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
|
|
7357
|
-
},
|
|
7358
|
-
[State.RightColumnRef]: {
|
|
7359
|
-
SPACE: goTo(State.RightColumnRef),
|
|
7360
|
-
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
|
|
7361
|
-
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
7362
|
-
},
|
|
7363
|
-
[State.RightRowRef]: {
|
|
7364
|
-
SPACE: goTo(State.RightRowRef),
|
|
7365
|
-
NUMBER: goTo(State.Found),
|
|
7366
|
-
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
7367
|
-
SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
|
|
7368
|
-
},
|
|
7369
|
-
[State.Found]: {},
|
|
7370
|
-
};
|
|
7371
|
-
/**
|
|
7372
|
-
* Check if the list of tokens starts with a sequence of tokens representing
|
|
7373
|
-
* a range.
|
|
7374
|
-
* If a range is found, the sequence is removed from the list and is returned
|
|
7375
|
-
* as a single token.
|
|
7376
|
-
*/
|
|
7377
|
-
function matchReference(tokens) {
|
|
7378
|
-
let head = 0;
|
|
7379
|
-
let transitions = machine[State.LeftRef];
|
|
7380
|
-
let matchedTokens = "";
|
|
7381
|
-
while (transitions !== undefined) {
|
|
7382
|
-
const token = tokens[head++];
|
|
7383
|
-
if (!token) {
|
|
7384
|
-
return null;
|
|
7385
|
-
}
|
|
7386
|
-
const transition = transitions[token.type]?.find((transition) => transition.guard(token));
|
|
7387
|
-
const nextState = transition ? transition.goTo : undefined;
|
|
7388
|
-
switch (nextState) {
|
|
7389
|
-
case undefined:
|
|
7390
|
-
return null;
|
|
7391
|
-
case State.Found:
|
|
7392
|
-
matchedTokens += token.value;
|
|
7393
|
-
tokens.splice(0, head);
|
|
7394
|
-
return {
|
|
7395
|
-
type: "REFERENCE",
|
|
7396
|
-
value: matchedTokens,
|
|
7397
|
-
};
|
|
7398
|
-
default:
|
|
7399
|
-
transitions = machine[nextState];
|
|
7400
|
-
matchedTokens += token.value;
|
|
7401
|
-
break;
|
|
7402
|
-
}
|
|
7403
|
-
}
|
|
7404
|
-
return null;
|
|
7405
|
-
}
|
|
7406
|
-
/**
|
|
7407
|
-
* Take the result of the tokenizer and transform it to be usable in the
|
|
7408
|
-
* manipulations of range
|
|
7409
|
-
*
|
|
7410
|
-
* @param formula
|
|
7411
|
-
*/
|
|
7412
|
-
function rangeTokenize(formula, locale = DEFAULT_LOCALE) {
|
|
7413
|
-
const tokens = tokenize(formula, locale);
|
|
7414
|
-
const result = [];
|
|
7415
|
-
while (tokens.length) {
|
|
7416
|
-
result.push(matchReference(tokens) || tokens.shift());
|
|
7417
|
-
}
|
|
7418
|
-
return result;
|
|
7419
|
-
}
|
|
7420
|
-
|
|
7421
7426
|
/**
|
|
7422
7427
|
* Add the following information on tokens:
|
|
7423
7428
|
* - length
|
|
@@ -9835,7 +9840,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9835
9840
|
};
|
|
9836
9841
|
canvas = owl.useRef("graphContainer");
|
|
9837
9842
|
chart;
|
|
9838
|
-
currentRuntime;
|
|
9839
9843
|
get background() {
|
|
9840
9844
|
return this.chartRuntime.background;
|
|
9841
9845
|
}
|
|
@@ -9852,18 +9856,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
9852
9856
|
setup() {
|
|
9853
9857
|
owl.onMounted(() => {
|
|
9854
9858
|
const runtime = this.chartRuntime;
|
|
9855
|
-
this.currentRuntime = runtime;
|
|
9856
9859
|
// Note: chartJS modify the runtime in place, so it's important to give it a copy
|
|
9857
9860
|
this.createChart(deepCopy(runtime.chartJsConfig));
|
|
9858
9861
|
});
|
|
9859
9862
|
owl.onWillUnmount(() => this.chart?.destroy());
|
|
9860
|
-
owl.useEffect(() =>
|
|
9861
|
-
const runtime = this.chartRuntime;
|
|
9862
|
-
if (!deepEquals(runtime, this.currentRuntime, "ignoreFunctions")) {
|
|
9863
|
-
this.currentRuntime = runtime;
|
|
9864
|
-
this.updateChartJs(deepCopy(runtime));
|
|
9865
|
-
}
|
|
9866
|
-
});
|
|
9863
|
+
owl.useEffect(() => this.updateChartJs(deepCopy(this.chartRuntime)), () => [this.chartRuntime]);
|
|
9867
9864
|
}
|
|
9868
9865
|
createChart(chartData) {
|
|
9869
9866
|
const canvas = this.canvas.el;
|
|
@@ -22697,7 +22694,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
22697
22694
|
/**
|
|
22698
22695
|
* Get a default chart js configuration
|
|
22699
22696
|
*/
|
|
22700
|
-
function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, truncateLabels }) {
|
|
22697
|
+
function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, truncateLabels = true }) {
|
|
22701
22698
|
const chartTitle = chart.title.text ? chart.title : { ...chart.title, content: "" };
|
|
22702
22699
|
const options = {
|
|
22703
22700
|
// https://www.chartjs.org/docs/latest/general/responsive.html
|
|
@@ -23926,10 +23923,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
23926
23923
|
const colors = new ColorGenerator();
|
|
23927
23924
|
const definition = chart.getDefinition();
|
|
23928
23925
|
for (let [index, { label, data }] of dataSetsValues.entries()) {
|
|
23929
|
-
if (["linear", "time"].includes(axisType)) {
|
|
23930
|
-
// Replace empty string labels by undefined to make sure chartJS doesn't decide that "" is the same as 0
|
|
23931
|
-
data = data.map((y, index) => ({ x: labels[index] || undefined, y }));
|
|
23932
|
-
}
|
|
23933
23926
|
const color = colors.next();
|
|
23934
23927
|
let backgroundRGBA = colorToRGBA(color);
|
|
23935
23928
|
if (stacked) {
|
|
@@ -23945,6 +23938,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
23945
23938
|
return value;
|
|
23946
23939
|
});
|
|
23947
23940
|
}
|
|
23941
|
+
if (["linear", "time"].includes(axisType)) {
|
|
23942
|
+
// Replace empty string labels by undefined to make sure chartJS doesn't decide that "" is the same as 0
|
|
23943
|
+
data = data.map((y, index) => ({ x: labels[index] || undefined, y }));
|
|
23944
|
+
}
|
|
23948
23945
|
const backgroundColor = rgbaToHex(backgroundRGBA);
|
|
23949
23946
|
const dataset = {
|
|
23950
23947
|
label,
|
|
@@ -36262,7 +36259,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
36262
36259
|
}
|
|
36263
36260
|
async loadLocales() {
|
|
36264
36261
|
this.loadedLocales = (await this.env.loadLocales())
|
|
36265
|
-
.filter(
|
|
36262
|
+
.filter((locale) => {
|
|
36263
|
+
const isValid = isValidLocale(locale);
|
|
36264
|
+
if (!isValid) {
|
|
36265
|
+
console.warn(`Invalid locale: ${locale["code"]} ${locale}`);
|
|
36266
|
+
}
|
|
36267
|
+
return isValid;
|
|
36268
|
+
})
|
|
36266
36269
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
36267
36270
|
}
|
|
36268
36271
|
get numberFormatPreview() {
|
|
@@ -41414,6 +41417,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
41414
41417
|
return;
|
|
41415
41418
|
}
|
|
41416
41419
|
if (clipboardData.types.indexOf(ClipboardMIMEType.PlainText) > -1) {
|
|
41420
|
+
ev.preventDefault();
|
|
41417
41421
|
const content = clipboardData.getData(ClipboardMIMEType.PlainText);
|
|
41418
41422
|
const target = this.env.model.getters.getSelectedZones();
|
|
41419
41423
|
const clipboardString = this.env.model.getters.getClipboardTextContent();
|
|
@@ -45125,7 +45129,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
45125
45129
|
return relsFile;
|
|
45126
45130
|
}
|
|
45127
45131
|
|
|
45128
|
-
const EXCEL_IMPORT_VERSION =
|
|
45132
|
+
const EXCEL_IMPORT_VERSION = 17;
|
|
45129
45133
|
class XlsxReader {
|
|
45130
45134
|
warningManager;
|
|
45131
45135
|
xmls;
|
|
@@ -45257,7 +45261,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
45257
45261
|
* a breaking change is made in the way the state is handled, and an upgrade
|
|
45258
45262
|
* function should be defined
|
|
45259
45263
|
*/
|
|
45260
|
-
const CURRENT_VERSION =
|
|
45264
|
+
const CURRENT_VERSION = 17;
|
|
45261
45265
|
const INITIAL_SHEET_ID = "Sheet1";
|
|
45262
45266
|
/**
|
|
45263
45267
|
* This function tries to load anything that could look like a valid
|
|
@@ -46204,6 +46208,21 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
46204
46208
|
return [];
|
|
46205
46209
|
return Object.keys(sheetBorders).map((index) => parseInt(index, 10));
|
|
46206
46210
|
}
|
|
46211
|
+
/**
|
|
46212
|
+
* Get all the rows which contains at least a border
|
|
46213
|
+
*/
|
|
46214
|
+
getRowsWithBorders(sheetId) {
|
|
46215
|
+
const sheetBorders = this.borders[sheetId]?.filter(isDefined);
|
|
46216
|
+
if (!sheetBorders)
|
|
46217
|
+
return [];
|
|
46218
|
+
const rowsWithBorders = new Set();
|
|
46219
|
+
for (const rowBorders of sheetBorders) {
|
|
46220
|
+
for (const rowBorder in rowBorders) {
|
|
46221
|
+
rowsWithBorders.add(parseInt(rowBorder, 10));
|
|
46222
|
+
}
|
|
46223
|
+
}
|
|
46224
|
+
return Array.from(rowsWithBorders);
|
|
46225
|
+
}
|
|
46207
46226
|
/**
|
|
46208
46227
|
* Get the range of all the rows in the sheet
|
|
46209
46228
|
*/
|
|
@@ -46253,7 +46272,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
46253
46272
|
destructive: false,
|
|
46254
46273
|
});
|
|
46255
46274
|
}
|
|
46256
|
-
this.
|
|
46275
|
+
this.getRowsWithBorders(sheetId)
|
|
46257
46276
|
.filter((row) => row >= start)
|
|
46258
46277
|
.sort((a, b) => (delta < 0 ? a - b : b - a)) // start by the end when moving up
|
|
46259
46278
|
.forEach((row) => {
|
|
@@ -52585,7 +52604,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52585
52604
|
return this.sheets[position.sheetId].getValue(position) === 1;
|
|
52586
52605
|
}
|
|
52587
52606
|
clear() {
|
|
52588
|
-
const insertions = this
|
|
52607
|
+
const insertions = [...this];
|
|
52589
52608
|
this.insertions = [];
|
|
52590
52609
|
for (const sheetId in this.sheets) {
|
|
52591
52610
|
this.sheets[sheetId].clear();
|
|
@@ -52923,6 +52942,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52923
52942
|
}
|
|
52924
52943
|
finally {
|
|
52925
52944
|
this.cellsBeingComputed.delete(cellId);
|
|
52945
|
+
this.nextPositionsToUpdate.delete(position);
|
|
52926
52946
|
}
|
|
52927
52947
|
}
|
|
52928
52948
|
computeAndSave(position) {
|
|
@@ -52949,8 +52969,33 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52949
52969
|
forEachSpreadPositionInMatrix(nbColumns, nbRows,
|
|
52950
52970
|
// thanks to the isMatrix check above, we know that formulaReturn is MatrixFunctionReturn
|
|
52951
52971
|
this.spreadValues(formulaPosition, formulaReturn));
|
|
52972
|
+
this.invalidatePositionsDependingOnSpread(formulaPosition, nbColumns, nbRows);
|
|
52952
52973
|
return createEvaluatedCell(nullValueToZeroValue(formulaReturn[0][0]), this.getters.getLocale(), cellData);
|
|
52953
52974
|
}
|
|
52975
|
+
invalidatePositionsDependingOnSpread(arrayFormulaPosition, nbColumns, nbRows) {
|
|
52976
|
+
// the result matrix is split in 2 zones to exclude the array formula position
|
|
52977
|
+
const top = arrayFormulaPosition.row;
|
|
52978
|
+
const left = arrayFormulaPosition.col;
|
|
52979
|
+
const bottom = top + nbRows - 1;
|
|
52980
|
+
const leftColumnZone = {
|
|
52981
|
+
top: top + 1,
|
|
52982
|
+
bottom,
|
|
52983
|
+
left,
|
|
52984
|
+
right: left,
|
|
52985
|
+
};
|
|
52986
|
+
const rightPartZone = {
|
|
52987
|
+
top,
|
|
52988
|
+
bottom,
|
|
52989
|
+
left: left + 1,
|
|
52990
|
+
right: left + nbColumns - 1,
|
|
52991
|
+
};
|
|
52992
|
+
const sheetId = arrayFormulaPosition.sheetId;
|
|
52993
|
+
const invalidatedPositions = this.formulaDependencies().getCellsDependingOn([
|
|
52994
|
+
{ sheetId, zone: rightPartZone },
|
|
52995
|
+
{ sheetId, zone: leftColumnZone },
|
|
52996
|
+
]);
|
|
52997
|
+
this.nextPositionsToUpdate.addMany(invalidatedPositions);
|
|
52998
|
+
}
|
|
52954
52999
|
assertSheetHasEnoughSpaceToSpreadFormulaResult({ sheetId, col, row }, matrixResult) {
|
|
52955
53000
|
const numberOfCols = this.getters.getNumberCols(sheetId);
|
|
52956
53001
|
const numberOfRows = this.getters.getNumberRows(sheetId);
|
|
@@ -53005,9 +53050,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
53005
53050
|
const cell = this.getters.getCell(position);
|
|
53006
53051
|
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell);
|
|
53007
53052
|
this.evaluatedCells.set(position, evaluatedCell);
|
|
53008
|
-
// check if formula dependencies present in the spread zone
|
|
53009
|
-
// if so, they need to be recomputed
|
|
53010
|
-
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([position]));
|
|
53011
53053
|
};
|
|
53012
53054
|
}
|
|
53013
53055
|
invalidateSpreading(position) {
|
|
@@ -67045,9 +67087,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67045
67087
|
exports.tokenize = tokenize;
|
|
67046
67088
|
|
|
67047
67089
|
|
|
67048
|
-
__info__.version = "17.3.
|
|
67049
|
-
__info__.date = "2024-07-
|
|
67050
|
-
__info__.hash = "
|
|
67090
|
+
__info__.version = "17.3.9";
|
|
67091
|
+
__info__.date = "2024-07-11T06:37:05.603Z";
|
|
67092
|
+
__info__.hash = "2346a16";
|
|
67051
67093
|
|
|
67052
67094
|
|
|
67053
67095
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|