@odoo/o-spreadsheet 17.2.8 → 17.2.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 +150 -113
- package/dist/o-spreadsheet.d.ts +4 -2
- package/dist/o-spreadsheet.esm.js +150 -113
- package/dist/o-spreadsheet.iife.js +150 -113
- package/dist/o-spreadsheet.iife.min.js +101 -101
- package/dist/o_spreadsheet.xml +3 -3
- package/package.json +2 -2
|
@@ -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.2.
|
|
7
|
-
* @date 2024-
|
|
8
|
-
* @hash
|
|
6
|
+
* @version 17.2.9
|
|
7
|
+
* @date 2024-06-03T14:56:21.684Z
|
|
8
|
+
* @hash 086af6d
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw } from '@odoo/owl';
|
|
@@ -2658,7 +2658,7 @@ function evaluatePredicate(value, criterion) {
|
|
|
2658
2658
|
return false;
|
|
2659
2659
|
}
|
|
2660
2660
|
if (typeof operand === "number" && operator === "=") {
|
|
2661
|
-
return toString(
|
|
2661
|
+
return value.toString() === operand.toString();
|
|
2662
2662
|
}
|
|
2663
2663
|
if (operator === "<>" || operator === "=") {
|
|
2664
2664
|
let result;
|
|
@@ -2718,14 +2718,13 @@ function visitMatchingRanges(args, cb, locale, isQuery = false) {
|
|
|
2718
2718
|
if (countArg % 2 === 1) {
|
|
2719
2719
|
throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects criteria_range and criterion to be in pairs."));
|
|
2720
2720
|
}
|
|
2721
|
-
const
|
|
2722
|
-
const
|
|
2721
|
+
const firstArg = toMatrix(args[0]);
|
|
2722
|
+
const dimRow = firstArg.length;
|
|
2723
|
+
const dimCol = firstArg[0].length;
|
|
2723
2724
|
let predicates = [];
|
|
2724
2725
|
for (let i = 0; i < countArg - 1; i += 2) {
|
|
2725
|
-
const criteriaRange = args[i];
|
|
2726
|
-
if (
|
|
2727
|
-
criteriaRange.length !== dimRow ||
|
|
2728
|
-
criteriaRange[0].length !== dimCol) {
|
|
2726
|
+
const criteriaRange = toMatrix(args[i]);
|
|
2727
|
+
if (criteriaRange.length !== dimRow || criteriaRange[0].length !== dimCol) {
|
|
2729
2728
|
throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects criteria_range to have the same dimension"));
|
|
2730
2729
|
}
|
|
2731
2730
|
const description = toString(args[i + 1]);
|
|
@@ -2739,7 +2738,7 @@ function visitMatchingRanges(args, cb, locale, isQuery = false) {
|
|
|
2739
2738
|
for (let j = 0; j < dimCol; j++) {
|
|
2740
2739
|
let validatedPredicates = true;
|
|
2741
2740
|
for (let k = 0; k < countArg - 1; k += 2) {
|
|
2742
|
-
const criteriaValue = args[k][i][j].value;
|
|
2741
|
+
const criteriaValue = toMatrix(args[k])[i][j].value;
|
|
2743
2742
|
const criterion = predicates[k / 2];
|
|
2744
2743
|
validatedPredicates = evaluatePredicate(criteriaValue ?? undefined, criterion);
|
|
2745
2744
|
if (!validatedPredicates) {
|
|
@@ -4456,8 +4455,11 @@ function copyRangeWithNewSheetId(sheetIdFrom, sheetIdTo, range) {
|
|
|
4456
4455
|
/**
|
|
4457
4456
|
* Create a range from a xc. If the xc is empty, this function returns undefined.
|
|
4458
4457
|
*/
|
|
4459
|
-
function
|
|
4460
|
-
|
|
4458
|
+
function createValidRange(getters, sheetId, xc) {
|
|
4459
|
+
if (!xc)
|
|
4460
|
+
return;
|
|
4461
|
+
const range = getters.getRangeFromSheetXC(sheetId, xc);
|
|
4462
|
+
return !(range.invalidSheetName || range.invalidXc) ? range : undefined;
|
|
4461
4463
|
}
|
|
4462
4464
|
/**
|
|
4463
4465
|
* Spread multiple colrows zone to one row/col zone and add a many new input range as needed.
|
|
@@ -9644,8 +9646,8 @@ let ScorecardChart$1 = class ScorecardChart extends AbstractChart {
|
|
|
9644
9646
|
type = "scorecard";
|
|
9645
9647
|
constructor(definition, sheetId, getters) {
|
|
9646
9648
|
super(definition, sheetId, getters);
|
|
9647
|
-
this.keyValue =
|
|
9648
|
-
this.baseline =
|
|
9649
|
+
this.keyValue = createValidRange(getters, sheetId, definition.keyValue);
|
|
9650
|
+
this.baseline = createValidRange(getters, sheetId, definition.baseline);
|
|
9649
9651
|
this.baselineMode = definition.baselineMode;
|
|
9650
9652
|
this.baselineDescr = definition.baselineDescr;
|
|
9651
9653
|
this.background = definition.background;
|
|
@@ -10215,6 +10217,9 @@ function makeArg(str, description) {
|
|
|
10215
10217
|
if (types.some((t) => t.startsWith("RANGE"))) {
|
|
10216
10218
|
result.acceptMatrix = true;
|
|
10217
10219
|
}
|
|
10220
|
+
if (types.every((t) => t.startsWith("RANGE"))) {
|
|
10221
|
+
result.acceptMatrixOnly = true;
|
|
10222
|
+
}
|
|
10218
10223
|
return result;
|
|
10219
10224
|
}
|
|
10220
10225
|
/**
|
|
@@ -10496,11 +10501,16 @@ const CHOOSECOLS = {
|
|
|
10496
10501
|
compute: function (array, ...columns) {
|
|
10497
10502
|
const _array = toMatrix(array);
|
|
10498
10503
|
const _columns = flattenRowFirst(columns, (item) => toInteger(item?.value, this.locale));
|
|
10499
|
-
|
|
10504
|
+
const argOutOfRange = _columns.filter((col) => col === 0 || _array.length < Math.abs(col));
|
|
10505
|
+
assert(() => argOutOfRange.length === 0, _t("The columns arguments must be between -%s and %s (got %s), excluding 0.", _array.length.toString(), _array.length.toString(), argOutOfRange.join(",")));
|
|
10500
10506
|
const result = Array(_columns.length);
|
|
10501
10507
|
for (let col = 0; col < _columns.length; col++) {
|
|
10502
|
-
|
|
10503
|
-
|
|
10508
|
+
if (_columns[col] > 0) {
|
|
10509
|
+
result[col] = _array[_columns[col] - 1]; // -1 because columns arguments are 1-indexed
|
|
10510
|
+
}
|
|
10511
|
+
else {
|
|
10512
|
+
result[col] = _array[_array.length + _columns[col]];
|
|
10513
|
+
}
|
|
10504
10514
|
}
|
|
10505
10515
|
return result;
|
|
10506
10516
|
},
|
|
@@ -10521,8 +10531,14 @@ const CHOOSEROWS = {
|
|
|
10521
10531
|
const _array = toMatrix(array);
|
|
10522
10532
|
const _rows = flattenRowFirst(rows, (item) => toInteger(item?.value, this.locale));
|
|
10523
10533
|
const _nbColumns = _array.length;
|
|
10524
|
-
|
|
10525
|
-
|
|
10534
|
+
const argOutOfRange = _rows.filter((row) => row === 0 || _array[0].length < Math.abs(row));
|
|
10535
|
+
assert(() => argOutOfRange.length === 0, _t("The rows arguments must be between -%s and %s (got %s), excluding 0.", _array[0].length.toString(), _array[0].length.toString(), argOutOfRange.join(",")));
|
|
10536
|
+
return generateMatrix(_nbColumns, _rows.length, (col, row) => {
|
|
10537
|
+
if (_rows[row] > 0) {
|
|
10538
|
+
return _array[col][_rows[row] - 1]; // -1 because columns arguments are 1-indexed
|
|
10539
|
+
}
|
|
10540
|
+
return _array[col][_array[col].length + _rows[row]];
|
|
10541
|
+
});
|
|
10526
10542
|
},
|
|
10527
10543
|
isExported: true,
|
|
10528
10544
|
};
|
|
@@ -11430,7 +11446,7 @@ const COUNTUNIQUEIFS = {
|
|
|
11430
11446
|
compute: function (range, ...args) {
|
|
11431
11447
|
let uniqueValues = new Set();
|
|
11432
11448
|
visitMatchingRanges(args, (i, j) => {
|
|
11433
|
-
const data = range[i][j];
|
|
11449
|
+
const data = range[i]?.[j];
|
|
11434
11450
|
if (isDefined(data)) {
|
|
11435
11451
|
uniqueValues.add(data.value);
|
|
11436
11452
|
}
|
|
@@ -12060,7 +12076,7 @@ const SUMIF = {
|
|
|
12060
12076
|
}
|
|
12061
12077
|
let sum = 0;
|
|
12062
12078
|
visitMatchingRanges([criteriaRange, criterion], (i, j) => {
|
|
12063
|
-
const value = sumRange[i][j]
|
|
12079
|
+
const value = sumRange[i]?.[j]?.value;
|
|
12064
12080
|
if (typeof value === "number") {
|
|
12065
12081
|
sum += value;
|
|
12066
12082
|
}
|
|
@@ -12085,7 +12101,7 @@ const SUMIFS = {
|
|
|
12085
12101
|
compute: function (sumRange, ...criters) {
|
|
12086
12102
|
let sum = 0;
|
|
12087
12103
|
visitMatchingRanges(criters, (i, j) => {
|
|
12088
|
-
const value = sumRange[i][j]
|
|
12104
|
+
const value = sumRange[i]?.[j]?.value;
|
|
12089
12105
|
if (typeof value === "number") {
|
|
12090
12106
|
sum += value;
|
|
12091
12107
|
}
|
|
@@ -12632,7 +12648,7 @@ const AVERAGEIF = {
|
|
|
12632
12648
|
let count = 0;
|
|
12633
12649
|
let sum = 0;
|
|
12634
12650
|
visitMatchingRanges([criteriaRange, criterion], (i, j) => {
|
|
12635
|
-
const value = _averageRange[i][j]
|
|
12651
|
+
const value = _averageRange[i]?.[j]?.value;
|
|
12636
12652
|
if (typeof value === "number") {
|
|
12637
12653
|
count += 1;
|
|
12638
12654
|
sum += value;
|
|
@@ -12661,7 +12677,7 @@ const AVERAGEIFS = {
|
|
|
12661
12677
|
let count = 0;
|
|
12662
12678
|
let sum = 0;
|
|
12663
12679
|
visitMatchingRanges(args, (i, j) => {
|
|
12664
|
-
const value = _averageRange[i][j]
|
|
12680
|
+
const value = _averageRange[i]?.[j]?.value;
|
|
12665
12681
|
if (typeof value === "number") {
|
|
12666
12682
|
count += 1;
|
|
12667
12683
|
sum += value;
|
|
@@ -12966,7 +12982,7 @@ const MAXIFS = {
|
|
|
12966
12982
|
compute: function (range, ...args) {
|
|
12967
12983
|
let result = -Infinity;
|
|
12968
12984
|
visitMatchingRanges(args, (i, j) => {
|
|
12969
|
-
const value = range[i][j]
|
|
12985
|
+
const value = range[i]?.[j]?.value;
|
|
12970
12986
|
if (typeof value === "number") {
|
|
12971
12987
|
result = result < value ? value : result;
|
|
12972
12988
|
}
|
|
@@ -13049,7 +13065,7 @@ const MINIFS = {
|
|
|
13049
13065
|
compute: function (range, ...args) {
|
|
13050
13066
|
let result = Infinity;
|
|
13051
13067
|
visitMatchingRanges(args, (i, j) => {
|
|
13052
|
-
const value = range[i][j]
|
|
13068
|
+
const value = range[i]?.[j]?.value;
|
|
13053
13069
|
if (typeof value === "number") {
|
|
13054
13070
|
result = result > value ? value : result;
|
|
13055
13071
|
}
|
|
@@ -18801,6 +18817,9 @@ function addInputHandling(descr) {
|
|
|
18801
18817
|
}
|
|
18802
18818
|
args[i] = arg[0][0];
|
|
18803
18819
|
}
|
|
18820
|
+
if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
|
|
18821
|
+
throw new BadExpressionError(_t("Function [[FUNCTION_NAME]] expects the parameter '%s' to be reference to a cell or range.", (i + 1).toString()));
|
|
18822
|
+
}
|
|
18804
18823
|
}
|
|
18805
18824
|
return descr.compute.apply(this, args);
|
|
18806
18825
|
}
|
|
@@ -19803,7 +19822,7 @@ class BarChart extends AbstractChart {
|
|
|
19803
19822
|
constructor(definition, sheetId, getters) {
|
|
19804
19823
|
super(definition, sheetId, getters);
|
|
19805
19824
|
this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
19806
|
-
this.labelRange =
|
|
19825
|
+
this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
|
|
19807
19826
|
this.background = definition.background;
|
|
19808
19827
|
this.verticalAxisPosition = definition.verticalAxisPosition;
|
|
19809
19828
|
this.legendPosition = definition.legendPosition;
|
|
@@ -20047,7 +20066,7 @@ class GaugeChart extends AbstractChart {
|
|
|
20047
20066
|
type = "gauge";
|
|
20048
20067
|
constructor(definition, sheetId, getters) {
|
|
20049
20068
|
super(definition, sheetId, getters);
|
|
20050
|
-
this.dataRange =
|
|
20069
|
+
this.dataRange = createValidRange(this.getters, this.sheetId, definition.dataRange);
|
|
20051
20070
|
this.sectionRule = definition.sectionRule;
|
|
20052
20071
|
this.background = definition.background;
|
|
20053
20072
|
}
|
|
@@ -20568,7 +20587,7 @@ class LineChart extends AbstractChart {
|
|
|
20568
20587
|
constructor(definition, sheetId, getters) {
|
|
20569
20588
|
super(definition, sheetId, getters);
|
|
20570
20589
|
this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
20571
|
-
this.labelRange =
|
|
20590
|
+
this.labelRange = createValidRange(this.getters, sheetId, definition.labelRange);
|
|
20572
20591
|
this.background = definition.background;
|
|
20573
20592
|
this.verticalAxisPosition = definition.verticalAxisPosition;
|
|
20574
20593
|
this.legendPosition = definition.legendPosition;
|
|
@@ -20683,7 +20702,7 @@ class PieChart extends AbstractChart {
|
|
|
20683
20702
|
constructor(definition, sheetId, getters) {
|
|
20684
20703
|
super(definition, sheetId, getters);
|
|
20685
20704
|
this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
20686
|
-
this.labelRange =
|
|
20705
|
+
this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
|
|
20687
20706
|
this.background = definition.background;
|
|
20688
20707
|
this.legendPosition = definition.legendPosition;
|
|
20689
20708
|
this.aggregated = definition.aggregated;
|
|
@@ -20885,7 +20904,7 @@ class ScatterChart extends AbstractChart {
|
|
|
20885
20904
|
constructor(definition, sheetId, getters) {
|
|
20886
20905
|
super(definition, sheetId, getters);
|
|
20887
20906
|
this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
20888
|
-
this.labelRange =
|
|
20907
|
+
this.labelRange = createValidRange(this.getters, sheetId, definition.labelRange);
|
|
20889
20908
|
this.background = definition.background;
|
|
20890
20909
|
this.verticalAxisPosition = definition.verticalAxisPosition;
|
|
20891
20910
|
this.legendPosition = definition.legendPosition;
|
|
@@ -20971,13 +20990,6 @@ function createScatterChartRuntime(chart, getters) {
|
|
|
20971
20990
|
// have less options than the line chart (it only works with linear labels)
|
|
20972
20991
|
chartJsConfig.type = "line";
|
|
20973
20992
|
const configOptions = chartJsConfig.options;
|
|
20974
|
-
configOptions.elements = {
|
|
20975
|
-
point: {
|
|
20976
|
-
radius: 3,
|
|
20977
|
-
hoverRadius: 3,
|
|
20978
|
-
hitRadius: 8,
|
|
20979
|
-
},
|
|
20980
|
-
};
|
|
20981
20993
|
const locale = getters.getLocale();
|
|
20982
20994
|
configOptions.plugins.tooltip.callbacks.title = () => "";
|
|
20983
20995
|
configOptions.plugins.tooltip.callbacks.label = (tooltipItem) => {
|
|
@@ -26811,7 +26823,7 @@ class LineBarPieConfigPanel extends Component {
|
|
|
26811
26823
|
}
|
|
26812
26824
|
const getters = this.env.model.getters;
|
|
26813
26825
|
const sheetId = getters.getActiveSheetId();
|
|
26814
|
-
const labelRange =
|
|
26826
|
+
const labelRange = createValidRange(getters, sheetId, this.labelRange);
|
|
26815
26827
|
const dataSets = createDataSets(getters, this.dataSeriesRanges, sheetId, this.props.definition.dataSetsHaveTitle);
|
|
26816
26828
|
if (dataSets.length) {
|
|
26817
26829
|
return dataSets[0].dataRange.zone.top + 1;
|
|
@@ -26840,15 +26852,23 @@ class BarConfigPanel extends LineBarPieConfigPanel {
|
|
|
26840
26852
|
}
|
|
26841
26853
|
}
|
|
26842
26854
|
|
|
26855
|
+
/**
|
|
26856
|
+
* Start listening to pointer events and apply the given callbacks.
|
|
26857
|
+
*
|
|
26858
|
+
* @returns A function to remove the listeners.
|
|
26859
|
+
*/
|
|
26843
26860
|
function startDnd(onMouseMove, onMouseUp, onMouseDown = () => { }) {
|
|
26844
|
-
const
|
|
26845
|
-
onMouseUp(ev);
|
|
26861
|
+
const removeListeners = () => {
|
|
26846
26862
|
window.removeEventListener("pointerdown", onMouseDown);
|
|
26847
26863
|
window.removeEventListener("pointerup", _onMouseUp);
|
|
26848
26864
|
window.removeEventListener("dragstart", _onDragStart);
|
|
26849
26865
|
window.removeEventListener("pointermove", onMouseMove);
|
|
26850
26866
|
window.removeEventListener("wheel", onMouseMove);
|
|
26851
26867
|
};
|
|
26868
|
+
const _onMouseUp = (ev) => {
|
|
26869
|
+
onMouseUp(ev);
|
|
26870
|
+
removeListeners();
|
|
26871
|
+
};
|
|
26852
26872
|
function _onDragStart(ev) {
|
|
26853
26873
|
ev.preventDefault();
|
|
26854
26874
|
}
|
|
@@ -26860,6 +26880,7 @@ function startDnd(onMouseMove, onMouseUp, onMouseDown = () => { }) {
|
|
|
26860
26880
|
// preventDefault() is not allowed in passive event handler.
|
|
26861
26881
|
// https://chromestatus.com/feature/6662647093133312
|
|
26862
26882
|
window.addEventListener("wheel", onMouseMove, { passive: false });
|
|
26883
|
+
return removeListeners;
|
|
26863
26884
|
}
|
|
26864
26885
|
/**
|
|
26865
26886
|
* Function to be used during a pointerdown event, this function allows to
|
|
@@ -28054,6 +28075,7 @@ function useDragAndDropListItems() {
|
|
|
28054
28075
|
state.itemsStyle = {};
|
|
28055
28076
|
document.body.style.cursor = previousCursor;
|
|
28056
28077
|
args.onCancel?.();
|
|
28078
|
+
cleanUp();
|
|
28057
28079
|
};
|
|
28058
28080
|
const onDragEnd = (itemId, indexAtEnd) => {
|
|
28059
28081
|
state.draggedItemId = undefined;
|
|
@@ -28074,7 +28096,8 @@ function useDragAndDropListItems() {
|
|
|
28074
28096
|
onDragEnd,
|
|
28075
28097
|
onCancel: state.cancel,
|
|
28076
28098
|
});
|
|
28077
|
-
startDnd(dndHelper.onMouseMove.bind(dndHelper), dndHelper.onMouseUp.bind(dndHelper));
|
|
28099
|
+
const stopListening = startDnd(dndHelper.onMouseMove.bind(dndHelper), dndHelper.onMouseUp.bind(dndHelper));
|
|
28100
|
+
cleanupFns.push(stopListening);
|
|
28078
28101
|
const onScroll = dndHelper.onScroll.bind(dndHelper);
|
|
28079
28102
|
args.containerEl.addEventListener("scroll", onScroll);
|
|
28080
28103
|
cleanupFns.push(() => args.containerEl.removeEventListener("scroll", onScroll));
|
|
@@ -28151,7 +28174,7 @@ class DOMDndHelper {
|
|
|
28151
28174
|
this.moveDraggedItemToPosition(this.currentMousePosition + this.scrollOffset);
|
|
28152
28175
|
}
|
|
28153
28176
|
onMouseMove(ev) {
|
|
28154
|
-
if (ev.button
|
|
28177
|
+
if (ev.button > 1) {
|
|
28155
28178
|
this.onCancel();
|
|
28156
28179
|
return;
|
|
28157
28180
|
}
|
|
@@ -31321,14 +31344,14 @@ class FigureComponent extends Component {
|
|
|
31321
31344
|
}
|
|
31322
31345
|
onKeyDown(ev) {
|
|
31323
31346
|
const figure = this.props.figure;
|
|
31324
|
-
|
|
31347
|
+
const keyDownShortcut = keyboardEventToShortcutString(ev);
|
|
31348
|
+
switch (keyDownShortcut) {
|
|
31325
31349
|
case "Delete":
|
|
31326
31350
|
this.env.model.dispatch("DELETE_FIGURE", {
|
|
31327
31351
|
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
31328
31352
|
id: figure.id,
|
|
31329
31353
|
});
|
|
31330
31354
|
this.props.onFigureDeleted();
|
|
31331
|
-
ev.stopPropagation();
|
|
31332
31355
|
ev.preventDefault();
|
|
31333
31356
|
ev.stopPropagation();
|
|
31334
31357
|
break;
|
|
@@ -31349,7 +31372,22 @@ class FigureComponent extends Component {
|
|
|
31349
31372
|
x: figure.x + delta[0],
|
|
31350
31373
|
y: figure.y + delta[1],
|
|
31351
31374
|
});
|
|
31375
|
+
ev.preventDefault();
|
|
31376
|
+
ev.stopPropagation();
|
|
31377
|
+
break;
|
|
31378
|
+
case "Ctrl+A":
|
|
31379
|
+
// Maybe in the future we will implement a way to select all figures
|
|
31380
|
+
ev.preventDefault();
|
|
31352
31381
|
ev.stopPropagation();
|
|
31382
|
+
break;
|
|
31383
|
+
case "Ctrl+Y":
|
|
31384
|
+
case "Ctrl+Z":
|
|
31385
|
+
if (keyDownShortcut === "Ctrl+Y") {
|
|
31386
|
+
this.env.model.dispatch("REQUEST_REDO");
|
|
31387
|
+
}
|
|
31388
|
+
else if (keyDownShortcut === "Ctrl+Z") {
|
|
31389
|
+
this.env.model.dispatch("REQUEST_UNDO");
|
|
31390
|
+
}
|
|
31353
31391
|
ev.preventDefault();
|
|
31354
31392
|
ev.stopPropagation();
|
|
31355
31393
|
break;
|
|
@@ -41137,12 +41175,6 @@ function compileTokens(tokens) {
|
|
|
41137
41175
|
// detect when an argument need to be evaluated as a meta argument
|
|
41138
41176
|
const isMeta = argTypes.includes("META");
|
|
41139
41177
|
const hasRange = argTypes.some((t) => isRangeType(t));
|
|
41140
|
-
const isRangeOnly = argTypes.every((t) => isRangeType(t));
|
|
41141
|
-
if (isRangeOnly) {
|
|
41142
|
-
if (!isRangeInput(currentArg)) {
|
|
41143
|
-
throw new BadExpressionError(_t("Function %s expects the parameter %s to be reference to a cell or range, not a %s.", functionName, (i + 1).toString(), currentArg.type.toLowerCase()));
|
|
41144
|
-
}
|
|
41145
|
-
}
|
|
41146
41178
|
compiledArgs.push(compileAST(currentArg, isMeta, hasRange, {
|
|
41147
41179
|
functionName,
|
|
41148
41180
|
paramIndex: i + 1,
|
|
@@ -41313,16 +41345,6 @@ function assertEnoughArgs(ast) {
|
|
|
41313
41345
|
function isRangeType(type) {
|
|
41314
41346
|
return type.startsWith("RANGE");
|
|
41315
41347
|
}
|
|
41316
|
-
function isRangeInput(arg) {
|
|
41317
|
-
if (arg.type === "REFERENCE") {
|
|
41318
|
-
return true;
|
|
41319
|
-
}
|
|
41320
|
-
if (arg.type === "FUNCALL") {
|
|
41321
|
-
const fnDef = functions$1[arg.value.toUpperCase()];
|
|
41322
|
-
return fnDef && isRangeType(fnDef.returns[0]);
|
|
41323
|
-
}
|
|
41324
|
-
return false;
|
|
41325
|
-
}
|
|
41326
41348
|
|
|
41327
41349
|
const functions = functionRegistry.content;
|
|
41328
41350
|
function isExportableToExcel(tokens) {
|
|
@@ -44060,6 +44082,9 @@ class RangeAdapter {
|
|
|
44060
44082
|
if (range.invalidXc) {
|
|
44061
44083
|
return range.invalidXc;
|
|
44062
44084
|
}
|
|
44085
|
+
if (!this.getters.tryGetSheet(range.sheetId)) {
|
|
44086
|
+
return CellErrorType.InvalidReference;
|
|
44087
|
+
}
|
|
44063
44088
|
if (range.zone.bottom - range.zone.top < 0 || range.zone.right - range.zone.left < 0) {
|
|
44064
44089
|
return CellErrorType.InvalidReference;
|
|
44065
44090
|
}
|
|
@@ -47444,7 +47469,6 @@ class PositionSet {
|
|
|
47444
47469
|
*
|
|
47445
47470
|
*/
|
|
47446
47471
|
class SpreadingRelation {
|
|
47447
|
-
createEmptyPositionSet;
|
|
47448
47472
|
/**
|
|
47449
47473
|
* Internal structure:
|
|
47450
47474
|
* For something like
|
|
@@ -47475,9 +47499,6 @@ class SpreadingRelation {
|
|
|
47475
47499
|
*/
|
|
47476
47500
|
resultsToArrayFormulas = new PositionMap();
|
|
47477
47501
|
arrayFormulasToResults = new PositionMap();
|
|
47478
|
-
constructor(createEmptyPositionSet) {
|
|
47479
|
-
this.createEmptyPositionSet = createEmptyPositionSet;
|
|
47480
|
-
}
|
|
47481
47502
|
getFormulaPositionsSpreadingOn(resultPosition) {
|
|
47482
47503
|
return this.resultsToArrayFormulas.get(resultPosition) || EMPTY_ARRAY;
|
|
47483
47504
|
}
|
|
@@ -47496,13 +47517,13 @@ class SpreadingRelation {
|
|
|
47496
47517
|
*/
|
|
47497
47518
|
addRelation({ arrayFormulaPosition, resultPosition, }) {
|
|
47498
47519
|
if (!this.resultsToArrayFormulas.has(resultPosition)) {
|
|
47499
|
-
this.resultsToArrayFormulas.set(resultPosition,
|
|
47520
|
+
this.resultsToArrayFormulas.set(resultPosition, []);
|
|
47500
47521
|
}
|
|
47501
|
-
this.resultsToArrayFormulas.get(resultPosition)?.
|
|
47522
|
+
this.resultsToArrayFormulas.get(resultPosition)?.push(arrayFormulaPosition);
|
|
47502
47523
|
if (!this.arrayFormulasToResults.has(arrayFormulaPosition)) {
|
|
47503
|
-
this.arrayFormulasToResults.set(arrayFormulaPosition,
|
|
47524
|
+
this.arrayFormulasToResults.set(arrayFormulaPosition, []);
|
|
47504
47525
|
}
|
|
47505
|
-
this.arrayFormulasToResults.get(arrayFormulaPosition)?.
|
|
47526
|
+
this.arrayFormulasToResults.get(arrayFormulaPosition)?.push(resultPosition);
|
|
47506
47527
|
}
|
|
47507
47528
|
hasArrayFormulaResult(position) {
|
|
47508
47529
|
return this.resultsToArrayFormulas.has(position);
|
|
@@ -47523,7 +47544,7 @@ class Evaluator {
|
|
|
47523
47544
|
evaluatedCells = new PositionMap();
|
|
47524
47545
|
formulaDependencies = lazy(new FormulaDependencyGraph(this.createEmptyPositionSet.bind(this)));
|
|
47525
47546
|
blockedArrayFormulas = new PositionSet({});
|
|
47526
|
-
spreadingRelations = new SpreadingRelation(
|
|
47547
|
+
spreadingRelations = new SpreadingRelation();
|
|
47527
47548
|
constructor(context, getters) {
|
|
47528
47549
|
this.context = context;
|
|
47529
47550
|
this.getters = getters;
|
|
@@ -47600,7 +47621,7 @@ class Evaluator {
|
|
|
47600
47621
|
}
|
|
47601
47622
|
buildDependencyGraph() {
|
|
47602
47623
|
this.blockedArrayFormulas = this.createEmptyPositionSet();
|
|
47603
|
-
this.spreadingRelations = new SpreadingRelation(
|
|
47624
|
+
this.spreadingRelations = new SpreadingRelation();
|
|
47604
47625
|
this.formulaDependencies = lazy(() => {
|
|
47605
47626
|
const dependencies = [...this.getAllCells()].flatMap((position) => this.getDirectDependencies(position)
|
|
47606
47627
|
.filter((range) => !range.invalidSheetName && !range.invalidXc)
|
|
@@ -48089,16 +48110,22 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
48089
48110
|
let newContent = undefined;
|
|
48090
48111
|
let newFormat = undefined;
|
|
48091
48112
|
let isExported = true;
|
|
48113
|
+
const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
|
|
48092
48114
|
const formulaCell = this.getCorrespondingFormulaCell(position);
|
|
48093
48115
|
if (formulaCell) {
|
|
48094
48116
|
isExported = isExportableToExcel(formulaCell.compiledFormula.tokens);
|
|
48095
48117
|
isFormula = isExported;
|
|
48096
48118
|
if (!isExported) {
|
|
48097
|
-
|
|
48098
|
-
|
|
48119
|
+
// If the cell contains a non-exported formula and that is evaluates to
|
|
48120
|
+
// nothing* ,we don't export it.
|
|
48121
|
+
// * non-falsy value are relevant and so are 0 and FALSE, which only leaves
|
|
48122
|
+
// the empty string.
|
|
48123
|
+
if (value !== "") {
|
|
48124
|
+
newContent = (value ?? "").toString();
|
|
48125
|
+
newFormat = evaluatedCell.format;
|
|
48126
|
+
}
|
|
48099
48127
|
}
|
|
48100
48128
|
}
|
|
48101
|
-
const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
|
|
48102
48129
|
const exportedCellData = exportedSheetData.cells[xc] || {};
|
|
48103
48130
|
const format = newFormat
|
|
48104
48131
|
? getItemId(newFormat, data.formats)
|
|
@@ -52088,7 +52115,7 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52088
52115
|
paintFormatStatus = "inactive";
|
|
52089
52116
|
originSheetId;
|
|
52090
52117
|
copiedData;
|
|
52091
|
-
_isCutOperation;
|
|
52118
|
+
_isCutOperation = false;
|
|
52092
52119
|
// ---------------------------------------------------------------------------
|
|
52093
52120
|
// Command Handling
|
|
52094
52121
|
// ---------------------------------------------------------------------------
|
|
@@ -52100,14 +52127,17 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52100
52127
|
case "PASTE_FROM_OS_CLIPBOARD": {
|
|
52101
52128
|
const copiedData = this.convertOSClipboardData(cmd.text);
|
|
52102
52129
|
const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
|
|
52103
|
-
return this.isPasteAllowed(cmd.target, copiedData, { pasteOption });
|
|
52130
|
+
return this.isPasteAllowed(cmd.target, copiedData, { pasteOption, isCutOperation: false });
|
|
52104
52131
|
}
|
|
52105
52132
|
case "PASTE": {
|
|
52106
52133
|
if (!this.copiedData) {
|
|
52107
52134
|
return "EmptyClipboard" /* CommandResult.EmptyClipboard */;
|
|
52108
52135
|
}
|
|
52109
52136
|
const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
|
|
52110
|
-
return this.isPasteAllowed(cmd.target, this.copiedData, {
|
|
52137
|
+
return this.isPasteAllowed(cmd.target, this.copiedData, {
|
|
52138
|
+
pasteOption: pasteOption,
|
|
52139
|
+
isCutOperation: this._isCutOperation,
|
|
52140
|
+
});
|
|
52111
52141
|
}
|
|
52112
52142
|
case "COPY_PASTE_CELLS_ABOVE": {
|
|
52113
52143
|
const zones = this.getters.getSelectedZones();
|
|
@@ -52125,13 +52155,13 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52125
52155
|
}
|
|
52126
52156
|
case "INSERT_CELL": {
|
|
52127
52157
|
const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
52128
|
-
const copiedData = this.copy(
|
|
52129
|
-
return this.isPasteAllowed(paste, copiedData, {});
|
|
52158
|
+
const copiedData = this.copy(cut);
|
|
52159
|
+
return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
|
|
52130
52160
|
}
|
|
52131
52161
|
case "DELETE_CELL": {
|
|
52132
52162
|
const { cut, paste } = this.getDeleteCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
52133
|
-
const copiedData = this.copy(
|
|
52134
|
-
return this.isPasteAllowed(paste, copiedData, {});
|
|
52163
|
+
const copiedData = this.copy(cut);
|
|
52164
|
+
return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
|
|
52135
52165
|
}
|
|
52136
52166
|
case "ACTIVATE_PAINT_FORMAT": {
|
|
52137
52167
|
if (this.paintFormatStatus !== "inactive") {
|
|
@@ -52149,23 +52179,27 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52149
52179
|
const zones = this.getters.getSelectedZones();
|
|
52150
52180
|
this.status = "visible";
|
|
52151
52181
|
this.originSheetId = this.getters.getActiveSheetId();
|
|
52152
|
-
this.copiedData = this.copy(
|
|
52182
|
+
this.copiedData = this.copy(zones);
|
|
52183
|
+
this._isCutOperation = cmd.type === "CUT";
|
|
52153
52184
|
break;
|
|
52154
52185
|
case "PASTE_FROM_OS_CLIPBOARD": {
|
|
52186
|
+
this._isCutOperation = false;
|
|
52155
52187
|
this.copiedData = this.convertOSClipboardData(cmd.text);
|
|
52156
52188
|
const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
|
|
52157
|
-
this.paste(cmd.target, {
|
|
52189
|
+
this.paste(cmd.target, this.copiedData, {
|
|
52158
52190
|
pasteOption,
|
|
52159
52191
|
selectTarget: true,
|
|
52192
|
+
isCutOperation: false,
|
|
52160
52193
|
});
|
|
52161
52194
|
this.status = "invisible";
|
|
52162
52195
|
break;
|
|
52163
52196
|
}
|
|
52164
52197
|
case "PASTE": {
|
|
52165
52198
|
const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
|
|
52166
|
-
this.paste(cmd.target, {
|
|
52199
|
+
this.paste(cmd.target, this.copiedData, {
|
|
52167
52200
|
pasteOption,
|
|
52168
52201
|
selectTarget: true,
|
|
52202
|
+
isCutOperation: this._isCutOperation,
|
|
52169
52203
|
});
|
|
52170
52204
|
if (this.paintFormatStatus === "oneOff") {
|
|
52171
52205
|
this.paintFormatStatus = "inactive";
|
|
@@ -52186,9 +52220,9 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52186
52220
|
top: multipleRowsInSelection ? zone.top : zone.top - 1,
|
|
52187
52221
|
};
|
|
52188
52222
|
this.originSheetId = this.getters.getActiveSheetId();
|
|
52189
|
-
|
|
52190
|
-
this.paste([zone], {
|
|
52191
|
-
|
|
52223
|
+
const copiedData = this.copy([copyTarget]);
|
|
52224
|
+
this.paste([zone], copiedData, {
|
|
52225
|
+
isCutOperation: false,
|
|
52192
52226
|
selectTarget: true,
|
|
52193
52227
|
});
|
|
52194
52228
|
}
|
|
@@ -52203,9 +52237,9 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52203
52237
|
left: multipleColsInSelection ? zone.left : zone.left - 1,
|
|
52204
52238
|
};
|
|
52205
52239
|
this.originSheetId = this.getters.getActiveSheetId();
|
|
52206
|
-
|
|
52207
|
-
this.paste([zone], {
|
|
52208
|
-
|
|
52240
|
+
const copiedData = this.copy([copyTarget]);
|
|
52241
|
+
this.paste([zone], copiedData, {
|
|
52242
|
+
isCutOperation: false,
|
|
52209
52243
|
selectTarget: true,
|
|
52210
52244
|
});
|
|
52211
52245
|
}
|
|
@@ -52221,14 +52255,14 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52221
52255
|
}
|
|
52222
52256
|
break;
|
|
52223
52257
|
}
|
|
52224
|
-
|
|
52225
|
-
this.paste(paste, {});
|
|
52258
|
+
const copiedData = this.copy(cut);
|
|
52259
|
+
this.paste(paste, copiedData, { isCutOperation: true });
|
|
52226
52260
|
break;
|
|
52227
52261
|
}
|
|
52228
52262
|
case "INSERT_CELL": {
|
|
52229
52263
|
const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
52230
|
-
|
|
52231
|
-
this.paste(paste, {});
|
|
52264
|
+
const copiedData = this.copy(cut);
|
|
52265
|
+
this.paste(paste, copiedData, { isCutOperation: true });
|
|
52232
52266
|
break;
|
|
52233
52267
|
}
|
|
52234
52268
|
case "ADD_COLUMNS_ROWS": {
|
|
@@ -52260,7 +52294,8 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52260
52294
|
break;
|
|
52261
52295
|
}
|
|
52262
52296
|
case "REPEAT_PASTE": {
|
|
52263
|
-
this.paste(cmd.target, {
|
|
52297
|
+
this.paste(cmd.target, this.copiedData, {
|
|
52298
|
+
isCutOperation: false,
|
|
52264
52299
|
pasteOption: cmd.pasteOption,
|
|
52265
52300
|
selectTarget: true,
|
|
52266
52301
|
});
|
|
@@ -52268,7 +52303,7 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52268
52303
|
}
|
|
52269
52304
|
case "ACTIVATE_PAINT_FORMAT": {
|
|
52270
52305
|
const zones = this.getters.getSelectedZones();
|
|
52271
|
-
this.copiedData = this.copy(
|
|
52306
|
+
this.copiedData = this.copy(zones);
|
|
52272
52307
|
this.status = "visible";
|
|
52273
52308
|
if (cmd.persistent) {
|
|
52274
52309
|
this.paintFormatStatus = "persistent";
|
|
@@ -52299,7 +52334,6 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52299
52334
|
}
|
|
52300
52335
|
}
|
|
52301
52336
|
convertOSClipboardData(clipboardData) {
|
|
52302
|
-
this._isCutOperation = false;
|
|
52303
52337
|
const handlers = clipboardHandlersRegistries.figureHandlers
|
|
52304
52338
|
.getAll()
|
|
52305
52339
|
.map((handler) => new handler(this.getters, this.dispatch));
|
|
@@ -52337,7 +52371,6 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52337
52371
|
for (const handler of this.selectClipboardHandlers(copiedData)) {
|
|
52338
52372
|
const result = handler.isPasteAllowed(this.getters.getActiveSheetId(), target, copiedData, {
|
|
52339
52373
|
...options,
|
|
52340
|
-
isCutOperation: this.isCutOperation(),
|
|
52341
52374
|
});
|
|
52342
52375
|
if (result !== "Success" /* CommandResult.Success */) {
|
|
52343
52376
|
return result;
|
|
@@ -52360,9 +52393,8 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52360
52393
|
}
|
|
52361
52394
|
return false;
|
|
52362
52395
|
}
|
|
52363
|
-
copy(
|
|
52396
|
+
copy(zones) {
|
|
52364
52397
|
let copiedData = {};
|
|
52365
|
-
this._isCutOperation = operation === "CUT";
|
|
52366
52398
|
const clipboardData = this.getClipboardData(zones);
|
|
52367
52399
|
for (const handler of this.selectClipboardHandlers(clipboardData)) {
|
|
52368
52400
|
const data = handler.copy(clipboardData);
|
|
@@ -52370,8 +52402,8 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52370
52402
|
}
|
|
52371
52403
|
return copiedData;
|
|
52372
52404
|
}
|
|
52373
|
-
paste(zones, options) {
|
|
52374
|
-
if (!
|
|
52405
|
+
paste(zones, copiedData, options) {
|
|
52406
|
+
if (!copiedData) {
|
|
52375
52407
|
return;
|
|
52376
52408
|
}
|
|
52377
52409
|
let zone = undefined;
|
|
@@ -52379,12 +52411,9 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52379
52411
|
let target = {
|
|
52380
52412
|
zones,
|
|
52381
52413
|
};
|
|
52382
|
-
const handlers = this.selectClipboardHandlers(
|
|
52414
|
+
const handlers = this.selectClipboardHandlers(copiedData);
|
|
52383
52415
|
for (const handler of handlers) {
|
|
52384
|
-
const currentTarget = handler.getPasteTarget(zones,
|
|
52385
|
-
...options,
|
|
52386
|
-
isCutOperation: this.isCutOperation(),
|
|
52387
|
-
});
|
|
52416
|
+
const currentTarget = handler.getPasteTarget(zones, copiedData, options);
|
|
52388
52417
|
if (currentTarget.figureId) {
|
|
52389
52418
|
target.figureId = currentTarget.figureId;
|
|
52390
52419
|
}
|
|
@@ -52400,7 +52429,7 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52400
52429
|
if (zone !== undefined) {
|
|
52401
52430
|
this.addMissingDimensions(this.getters.getActiveSheetId(), zone.right - zone.left + 1, zone.bottom - zone.top + 1, zone.left, zone.top);
|
|
52402
52431
|
}
|
|
52403
|
-
handlers.forEach((handler) => handler.paste(target,
|
|
52432
|
+
handlers.forEach((handler) => handler.paste(target, copiedData, options));
|
|
52404
52433
|
if (!options?.selectTarget) {
|
|
52405
52434
|
return;
|
|
52406
52435
|
}
|
|
@@ -54870,6 +54899,7 @@ class BottomBarSheet extends Component {
|
|
|
54870
54899
|
sheetDivRef = useRef("sheetDiv");
|
|
54871
54900
|
sheetNameRef = useRef("sheetNameSpan");
|
|
54872
54901
|
editionState = "initializing";
|
|
54902
|
+
DOMFocusableElementStore;
|
|
54873
54903
|
setup() {
|
|
54874
54904
|
onMounted(() => {
|
|
54875
54905
|
if (this.isSheetActive) {
|
|
@@ -54882,6 +54912,7 @@ class BottomBarSheet extends Component {
|
|
|
54882
54912
|
this.focusInputAndSelectContent();
|
|
54883
54913
|
}
|
|
54884
54914
|
});
|
|
54915
|
+
this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
|
|
54885
54916
|
}
|
|
54886
54917
|
focusInputAndSelectContent() {
|
|
54887
54918
|
if (!this.state.isEditing || !this.sheetNameRef.el)
|
|
@@ -54923,9 +54954,11 @@ class BottomBarSheet extends Component {
|
|
|
54923
54954
|
if (ev.key === "Enter") {
|
|
54924
54955
|
ev.preventDefault();
|
|
54925
54956
|
this.stopEdition();
|
|
54957
|
+
this.DOMFocusableElementStore.focus();
|
|
54926
54958
|
}
|
|
54927
54959
|
if (ev.key === "Escape") {
|
|
54928
54960
|
this.cancelEdition();
|
|
54961
|
+
this.DOMFocusableElementStore.focus();
|
|
54929
54962
|
}
|
|
54930
54963
|
}
|
|
54931
54964
|
onClickSheetName(ev) {
|
|
@@ -59648,7 +59681,11 @@ function addRows(construct, data, sheet) {
|
|
|
59648
59681
|
let cellNode = escapeXml ``;
|
|
59649
59682
|
// Either formula or static value inside the cell
|
|
59650
59683
|
if (cell.isFormula) {
|
|
59651
|
-
|
|
59684
|
+
const res = addFormula(cell);
|
|
59685
|
+
if (!res) {
|
|
59686
|
+
continue;
|
|
59687
|
+
}
|
|
59688
|
+
({ attrs: additionalAttrs, node: cellNode } = res);
|
|
59652
59689
|
}
|
|
59653
59690
|
else if (cell.content && isMarkdownLink(cell.content)) {
|
|
59654
59691
|
const { label } = parseMarkdownLink(cell.content);
|
|
@@ -60687,6 +60724,6 @@ const constants = {
|
|
|
60687
60724
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, 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 };
|
|
60688
60725
|
|
|
60689
60726
|
|
|
60690
|
-
__info__.version = "17.2.
|
|
60691
|
-
__info__.date = "2024-
|
|
60692
|
-
__info__.hash = "
|
|
60727
|
+
__info__.version = "17.2.9";
|
|
60728
|
+
__info__.date = "2024-06-03T14:56:21.684Z";
|
|
60729
|
+
__info__.hash = "086af6d";
|