@odoo/o-spreadsheet 17.0.50 → 17.0.52
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 +252 -157
- package/dist/o-spreadsheet.d.ts +8 -4
- package/dist/o-spreadsheet.esm.js +252 -157
- package/dist/o-spreadsheet.iife.js +252 -157
- package/dist/o-spreadsheet.iife.min.js +272 -254
- package/dist/o_spreadsheet.xml +48 -36
- package/package.json +2 -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 17.0.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.0.52
|
|
6
|
+
* @date 2025-03-07T10:30:04.783Z
|
|
7
|
+
* @hash c19cd9a
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { Component, useRef, onMounted, useEffect, onWillPatch, useState, onWillUpdateProps, onPatched, useComponent, useExternalListener, onWillUnmount, onWillStart, xml, useChildSubEnv, useSubEnv, markRaw } from '@odoo/owl';
|
|
@@ -4731,11 +4731,12 @@ class UuidGenerator {
|
|
|
4731
4731
|
if (this.isFastIdStrategy) {
|
|
4732
4732
|
this.fastIdStart++;
|
|
4733
4733
|
return String(this.fastIdStart);
|
|
4734
|
-
//@ts-ignore
|
|
4735
4734
|
}
|
|
4736
|
-
else if (window.crypto
|
|
4737
|
-
|
|
4738
|
-
|
|
4735
|
+
else if (window.crypto) {
|
|
4736
|
+
return "10000000-1000".replace(/[01]/g, (c) => {
|
|
4737
|
+
const n = Number(c);
|
|
4738
|
+
return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
|
|
4739
|
+
});
|
|
4739
4740
|
}
|
|
4740
4741
|
else {
|
|
4741
4742
|
// mainly for jest and other browsers that do not have the crypto functionality
|
|
@@ -4753,11 +4754,12 @@ class UuidGenerator {
|
|
|
4753
4754
|
if (this.isFastIdStrategy) {
|
|
4754
4755
|
this.fastIdStart++;
|
|
4755
4756
|
return String(this.fastIdStart);
|
|
4756
|
-
//@ts-ignore
|
|
4757
4757
|
}
|
|
4758
|
-
else if (window.crypto
|
|
4759
|
-
|
|
4760
|
-
|
|
4758
|
+
else if (window.crypto) {
|
|
4759
|
+
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => {
|
|
4760
|
+
const n = Number(c);
|
|
4761
|
+
return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
|
|
4762
|
+
});
|
|
4761
4763
|
}
|
|
4762
4764
|
else {
|
|
4763
4765
|
// mainly for jest and other browsers that do not have the crypto functionality
|
|
@@ -6210,7 +6212,7 @@ autofillRulesRegistry
|
|
|
6210
6212
|
condition: (cell) => !cell.isFormula &&
|
|
6211
6213
|
evaluateLiteral(cell.content, { locale: DEFAULT_LOCALE }).type === CellValueType.text &&
|
|
6212
6214
|
alphaNumericValueRegExp.test(cell.content),
|
|
6213
|
-
generateRule: (cell, cells) => {
|
|
6215
|
+
generateRule: (cell, cells, direction) => {
|
|
6214
6216
|
const numberPostfix = parseInt(cell.content.match(numberPostfixRegExp)[0]);
|
|
6215
6217
|
const prefix = cell.content.match(stringPrefixRegExp)[0];
|
|
6216
6218
|
const numberPostfixLength = cell.content.length - prefix.length;
|
|
@@ -6218,7 +6220,10 @@ autofillRulesRegistry
|
|
|
6218
6220
|
alphaNumericValueRegExp.test(evaluatedCell.value)) // get consecutive alphanumeric cells, no matter what the prefix is
|
|
6219
6221
|
.filter((cell) => prefix === cell.value.toString().match(stringPrefixRegExp)[0])
|
|
6220
6222
|
.map((cell) => parseInt(cell.value.toString().match(numberPostfixRegExp)[0]));
|
|
6221
|
-
|
|
6223
|
+
let increment = calculateIncrementBasedOnGroup(group);
|
|
6224
|
+
if (["up", "left"].includes(direction) && group.length === 1) {
|
|
6225
|
+
increment = -increment;
|
|
6226
|
+
}
|
|
6222
6227
|
return {
|
|
6223
6228
|
type: "ALPHANUMERIC_INCREMENT_MODIFIER",
|
|
6224
6229
|
prefix,
|
|
@@ -6247,9 +6252,12 @@ autofillRulesRegistry
|
|
|
6247
6252
|
.add("increment_number", {
|
|
6248
6253
|
condition: (cell) => !cell.isFormula &&
|
|
6249
6254
|
evaluateLiteral(cell.content, { locale: DEFAULT_LOCALE }).type === CellValueType.number,
|
|
6250
|
-
generateRule: (cell, cells) => {
|
|
6255
|
+
generateRule: (cell, cells, direction) => {
|
|
6251
6256
|
const group = getGroup(cell, cells, (evaluatedCell) => evaluatedCell.type === CellValueType.number).map((cell) => Number(cell.value));
|
|
6252
|
-
|
|
6257
|
+
let increment = calculateIncrementBasedOnGroup(group);
|
|
6258
|
+
if (["up", "left"].includes(direction) && group.length === 1) {
|
|
6259
|
+
increment = -increment;
|
|
6260
|
+
}
|
|
6253
6261
|
const evaluation = evaluateLiteral(cell.content, { locale: DEFAULT_LOCALE });
|
|
6254
6262
|
return {
|
|
6255
6263
|
type: "INCREMENT_MODIFIER",
|
|
@@ -6983,10 +6991,6 @@ class Popover extends Component {
|
|
|
6983
6991
|
this.currentDisplayValue = newDisplay;
|
|
6984
6992
|
if (!anchor)
|
|
6985
6993
|
return;
|
|
6986
|
-
el.style.top = "";
|
|
6987
|
-
el.style.left = "";
|
|
6988
|
-
el.style["max-height"] = "";
|
|
6989
|
-
el.style["max-width"] = "";
|
|
6990
6994
|
const propsMaxSize = { width: this.props.maxWidth, height: this.props.maxHeight };
|
|
6991
6995
|
let elDims = {
|
|
6992
6996
|
width: el.getBoundingClientRect().width,
|
|
@@ -9728,7 +9732,7 @@ function createPieChartRuntime(chart, getters) {
|
|
|
9728
9732
|
const dataset = {
|
|
9729
9733
|
label,
|
|
9730
9734
|
data,
|
|
9731
|
-
borderColor: "#FFFFFF",
|
|
9735
|
+
borderColor: chart.background || "#FFFFFF",
|
|
9732
9736
|
backgroundColor,
|
|
9733
9737
|
};
|
|
9734
9738
|
config.data.datasets.push(dataset);
|
|
@@ -26760,25 +26764,21 @@ css /* scss */ `
|
|
|
26760
26764
|
}
|
|
26761
26765
|
}
|
|
26762
26766
|
}
|
|
26767
|
+
}
|
|
26768
|
+
.o-spreadsheet .o-composer-assistant {
|
|
26769
|
+
pointer-events: none;
|
|
26763
26770
|
|
|
26764
|
-
.o-
|
|
26765
|
-
|
|
26766
|
-
|
|
26767
|
-
|
|
26768
|
-
|
|
26769
|
-
|
|
26770
|
-
.o-semi-bold {
|
|
26771
|
-
/** FIXME: to remove in favor of Bootstrap
|
|
26772
|
-
* 'fw-semibold' when we upgrade to Bootstrap 5.2
|
|
26773
|
-
*/
|
|
26774
|
-
font-weight: 600 !important;
|
|
26775
|
-
}
|
|
26771
|
+
.o-semi-bold {
|
|
26772
|
+
/** FIXME: to remove in favor of Bootstrap
|
|
26773
|
+
* 'fw-semibold' when we upgrade to Bootstrap 5.2
|
|
26774
|
+
*/
|
|
26775
|
+
font-weight: 600 !important;
|
|
26776
26776
|
}
|
|
26777
26777
|
}
|
|
26778
26778
|
`;
|
|
26779
26779
|
class Composer extends Component {
|
|
26780
26780
|
static template = "o-spreadsheet-Composer";
|
|
26781
|
-
static components = { TextValueProvider, FunctionDescriptionProvider };
|
|
26781
|
+
static components = { TextValueProvider, FunctionDescriptionProvider, Popover };
|
|
26782
26782
|
static defaultProps = {
|
|
26783
26783
|
inputStyle: "",
|
|
26784
26784
|
isDefaultFocus: false,
|
|
@@ -26803,35 +26803,13 @@ class Composer extends Component {
|
|
|
26803
26803
|
argToFocus: 0,
|
|
26804
26804
|
});
|
|
26805
26805
|
compositionActive = false;
|
|
26806
|
-
spreadsheetRect = useSpreadsheetRect();
|
|
26807
26806
|
get assistantStyle() {
|
|
26808
|
-
const composerRect = this.composerRef.el.getBoundingClientRect();
|
|
26809
26807
|
const assistantStyle = {};
|
|
26810
|
-
|
|
26808
|
+
const minWidth = Math.min(getBoundingRectAsPOJO(this.composerRef.el).width || Infinity, ASSISTANT_WIDTH);
|
|
26809
|
+
assistantStyle["min-width"] = `${minWidth}px`;
|
|
26811
26810
|
if (this.autoCompleteState.type === "function") {
|
|
26812
26811
|
assistantStyle.width = `${ASSISTANT_WIDTH}px`;
|
|
26813
26812
|
}
|
|
26814
|
-
if (this.props.delimitation && this.props.rect) {
|
|
26815
|
-
const { x: cellX, y: cellY, height: cellHeight } = this.props.rect;
|
|
26816
|
-
const remainingHeight = this.props.delimitation.height - (cellY + cellHeight);
|
|
26817
|
-
assistantStyle["max-height"] = `${remainingHeight}px`;
|
|
26818
|
-
if (cellY > remainingHeight) {
|
|
26819
|
-
const availableSpaceAbove = cellY;
|
|
26820
|
-
assistantStyle["max-height"] = `${availableSpaceAbove}px`;
|
|
26821
|
-
// render top
|
|
26822
|
-
// We compensate 2 px of margin on the assistant style + 1px for design reasons
|
|
26823
|
-
assistantStyle.top = `-3px`;
|
|
26824
|
-
assistantStyle.transform = `translate(0, -100%)`;
|
|
26825
|
-
}
|
|
26826
|
-
if (cellX + ASSISTANT_WIDTH > this.props.delimitation.width) {
|
|
26827
|
-
// render left
|
|
26828
|
-
assistantStyle.right = `0px`;
|
|
26829
|
-
}
|
|
26830
|
-
}
|
|
26831
|
-
if (this.props.focus === "contentFocus" &&
|
|
26832
|
-
composerRect.left + ASSISTANT_WIDTH > this.spreadsheetRect.width) {
|
|
26833
|
-
assistantStyle.right = "0px";
|
|
26834
|
-
}
|
|
26835
26813
|
return cssPropertiesToCss(assistantStyle);
|
|
26836
26814
|
}
|
|
26837
26815
|
// we can't allow input events to be triggered while we remove and add back the content of the composer in processContent
|
|
@@ -27080,7 +27058,7 @@ class Composer extends Component {
|
|
|
27080
27058
|
this.autoCompleteState.selectedIndex = 0;
|
|
27081
27059
|
}
|
|
27082
27060
|
updateAutoCompleteIndex(index) {
|
|
27083
|
-
this.autoCompleteState.selectedIndex =
|
|
27061
|
+
this.autoCompleteState.selectedIndex = index;
|
|
27084
27062
|
}
|
|
27085
27063
|
/**
|
|
27086
27064
|
* This is required to ensure the content helper selection is
|
|
@@ -27368,11 +27346,16 @@ class Composer extends Component {
|
|
|
27368
27346
|
this.autoCompleteState.values = values.map((value) => ({ text: value, description: "" }));
|
|
27369
27347
|
this.autoCompleteState.getHtmlContent = (value) => [{ value }];
|
|
27370
27348
|
}
|
|
27349
|
+
get popoverProps() {
|
|
27350
|
+
return {
|
|
27351
|
+
anchorRect: getBoundingRectAsPOJO(this.composerRef.el),
|
|
27352
|
+
positioning: "BottomLeft",
|
|
27353
|
+
verticalOffset: 0,
|
|
27354
|
+
};
|
|
27355
|
+
}
|
|
27371
27356
|
}
|
|
27372
27357
|
Composer.props = {
|
|
27373
27358
|
inputStyle: { type: String, optional: true },
|
|
27374
|
-
rect: { type: Object, optional: true },
|
|
27375
|
-
delimitation: { type: Object, optional: true },
|
|
27376
27359
|
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
27377
27360
|
onComposerCellFocused: { type: Function, optional: true },
|
|
27378
27361
|
onComposerContentFocused: Function,
|
|
@@ -27442,13 +27425,7 @@ class GridComposer extends Component {
|
|
|
27442
27425
|
});
|
|
27443
27426
|
}
|
|
27444
27427
|
get composerProps() {
|
|
27445
|
-
const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
|
|
27446
27428
|
return {
|
|
27447
|
-
rect: { ...this.rect },
|
|
27448
|
-
delimitation: {
|
|
27449
|
-
width,
|
|
27450
|
-
height,
|
|
27451
|
-
},
|
|
27452
27429
|
focus: this.props.focus,
|
|
27453
27430
|
isDefaultFocus: true,
|
|
27454
27431
|
onComposerContentFocused: this.props.onComposerContentFocused,
|
|
@@ -28990,6 +28967,9 @@ class ColResizer extends AbstractResizer {
|
|
|
28990
28967
|
this.MAX_SIZE_MARGIN = 90;
|
|
28991
28968
|
this.MIN_ELEMENT_SIZE = MIN_COL_WIDTH;
|
|
28992
28969
|
}
|
|
28970
|
+
get sheetId() {
|
|
28971
|
+
return this.env.model.getters.getActiveSheetId();
|
|
28972
|
+
}
|
|
28993
28973
|
_getEvOffset(ev) {
|
|
28994
28974
|
return ev.offsetX;
|
|
28995
28975
|
}
|
|
@@ -29012,10 +28992,10 @@ class ColResizer extends AbstractResizer {
|
|
|
29012
28992
|
return this.env.model.getters.getEdgeScrollCol(position, position, position);
|
|
29013
28993
|
}
|
|
29014
28994
|
_getDimensionsInViewport(index) {
|
|
29015
|
-
return this.env.model.getters.getColDimensionsInViewport(this.
|
|
28995
|
+
return this.env.model.getters.getColDimensionsInViewport(this.sheetId, index);
|
|
29016
28996
|
}
|
|
29017
28997
|
_getElementSize(index) {
|
|
29018
|
-
return this.env.model.getters.getColSize(this.
|
|
28998
|
+
return this.env.model.getters.getColSize(this.sheetId, index);
|
|
29019
28999
|
}
|
|
29020
29000
|
_getMaxSize() {
|
|
29021
29001
|
return this.colResizerRef.el.clientWidth;
|
|
@@ -29026,7 +29006,7 @@ class ColResizer extends AbstractResizer {
|
|
|
29026
29006
|
const cols = this.env.model.getters.getActiveCols();
|
|
29027
29007
|
this.env.model.dispatch("RESIZE_COLUMNS_ROWS", {
|
|
29028
29008
|
dimension: "COL",
|
|
29029
|
-
sheetId: this.
|
|
29009
|
+
sheetId: this.sheetId,
|
|
29030
29010
|
elements: cols.has(index) ? [...cols] : [index],
|
|
29031
29011
|
size,
|
|
29032
29012
|
});
|
|
@@ -29039,7 +29019,7 @@ class ColResizer extends AbstractResizer {
|
|
|
29039
29019
|
elements.push(colIndex);
|
|
29040
29020
|
}
|
|
29041
29021
|
const result = this.env.model.dispatch("MOVE_COLUMNS_ROWS", {
|
|
29042
|
-
sheetId: this.
|
|
29022
|
+
sheetId: this.sheetId,
|
|
29043
29023
|
dimension: "COL",
|
|
29044
29024
|
base: this.state.base,
|
|
29045
29025
|
elements,
|
|
@@ -29058,7 +29038,7 @@ class ColResizer extends AbstractResizer {
|
|
|
29058
29038
|
_fitElementSize(index) {
|
|
29059
29039
|
const cols = this.env.model.getters.getActiveCols();
|
|
29060
29040
|
this.env.model.dispatch("AUTORESIZE_COLUMNS", {
|
|
29061
|
-
sheetId: this.
|
|
29041
|
+
sheetId: this.sheetId,
|
|
29062
29042
|
cols: cols.has(index) ? [...cols] : [index],
|
|
29063
29043
|
});
|
|
29064
29044
|
}
|
|
@@ -29069,7 +29049,7 @@ class ColResizer extends AbstractResizer {
|
|
|
29069
29049
|
return this.env.model.getters.getActiveCols();
|
|
29070
29050
|
}
|
|
29071
29051
|
_getPreviousVisibleElement(index) {
|
|
29072
|
-
const sheetId = this.
|
|
29052
|
+
const sheetId = this.sheetId;
|
|
29073
29053
|
let row;
|
|
29074
29054
|
for (row = index - 1; row >= 0; row--) {
|
|
29075
29055
|
if (!this.env.model.getters.isColHidden(sheetId, row)) {
|
|
@@ -29080,7 +29060,7 @@ class ColResizer extends AbstractResizer {
|
|
|
29080
29060
|
}
|
|
29081
29061
|
unhide(hiddenElements) {
|
|
29082
29062
|
this.env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
|
|
29083
|
-
sheetId: this.
|
|
29063
|
+
sheetId: this.sheetId,
|
|
29084
29064
|
elements: hiddenElements,
|
|
29085
29065
|
dimension: "COL",
|
|
29086
29066
|
});
|
|
@@ -29096,7 +29076,7 @@ css /* scss */ `
|
|
|
29096
29076
|
left: 0;
|
|
29097
29077
|
right: 0;
|
|
29098
29078
|
width: ${HEADER_WIDTH}px;
|
|
29099
|
-
height: 100
|
|
29079
|
+
height: calc(100% - ${HEADER_HEIGHT + SCROLLBAR_WIDTH}px);
|
|
29100
29080
|
&.o-dragging {
|
|
29101
29081
|
cursor: grabbing;
|
|
29102
29082
|
}
|
|
@@ -29164,6 +29144,9 @@ class RowResizer extends AbstractResizer {
|
|
|
29164
29144
|
this.MIN_ELEMENT_SIZE = MIN_ROW_HEIGHT;
|
|
29165
29145
|
}
|
|
29166
29146
|
rowResizerRef;
|
|
29147
|
+
get sheetId() {
|
|
29148
|
+
return this.env.model.getters.getActiveSheetId();
|
|
29149
|
+
}
|
|
29167
29150
|
_getEvOffset(ev) {
|
|
29168
29151
|
return ev.offsetY;
|
|
29169
29152
|
}
|
|
@@ -29186,10 +29169,10 @@ class RowResizer extends AbstractResizer {
|
|
|
29186
29169
|
return this.env.model.getters.getEdgeScrollRow(position, position, position);
|
|
29187
29170
|
}
|
|
29188
29171
|
_getDimensionsInViewport(index) {
|
|
29189
|
-
return this.env.model.getters.getRowDimensionsInViewport(this.
|
|
29172
|
+
return this.env.model.getters.getRowDimensionsInViewport(this.sheetId, index);
|
|
29190
29173
|
}
|
|
29191
29174
|
_getElementSize(index) {
|
|
29192
|
-
return this.env.model.getters.getRowSize(this.
|
|
29175
|
+
return this.env.model.getters.getRowSize(this.sheetId, index);
|
|
29193
29176
|
}
|
|
29194
29177
|
_getMaxSize() {
|
|
29195
29178
|
return this.rowResizerRef.el.clientHeight;
|
|
@@ -29200,7 +29183,7 @@ class RowResizer extends AbstractResizer {
|
|
|
29200
29183
|
const rows = this.env.model.getters.getActiveRows();
|
|
29201
29184
|
this.env.model.dispatch("RESIZE_COLUMNS_ROWS", {
|
|
29202
29185
|
dimension: "ROW",
|
|
29203
|
-
sheetId: this.
|
|
29186
|
+
sheetId: this.sheetId,
|
|
29204
29187
|
elements: rows.has(index) ? [...rows] : [index],
|
|
29205
29188
|
size,
|
|
29206
29189
|
});
|
|
@@ -29213,7 +29196,7 @@ class RowResizer extends AbstractResizer {
|
|
|
29213
29196
|
elements.push(rowIndex);
|
|
29214
29197
|
}
|
|
29215
29198
|
const result = this.env.model.dispatch("MOVE_COLUMNS_ROWS", {
|
|
29216
|
-
sheetId: this.
|
|
29199
|
+
sheetId: this.sheetId,
|
|
29217
29200
|
dimension: "ROW",
|
|
29218
29201
|
base: this.state.base,
|
|
29219
29202
|
elements,
|
|
@@ -29232,7 +29215,7 @@ class RowResizer extends AbstractResizer {
|
|
|
29232
29215
|
_fitElementSize(index) {
|
|
29233
29216
|
const rows = this.env.model.getters.getActiveRows();
|
|
29234
29217
|
this.env.model.dispatch("AUTORESIZE_ROWS", {
|
|
29235
|
-
sheetId: this.
|
|
29218
|
+
sheetId: this.sheetId,
|
|
29236
29219
|
rows: rows.has(index) ? [...rows] : [index],
|
|
29237
29220
|
});
|
|
29238
29221
|
}
|
|
@@ -29243,7 +29226,7 @@ class RowResizer extends AbstractResizer {
|
|
|
29243
29226
|
return this.env.model.getters.getActiveRows();
|
|
29244
29227
|
}
|
|
29245
29228
|
_getPreviousVisibleElement(index) {
|
|
29246
|
-
const sheetId = this.
|
|
29229
|
+
const sheetId = this.sheetId;
|
|
29247
29230
|
let row;
|
|
29248
29231
|
for (row = index - 1; row >= 0; row--) {
|
|
29249
29232
|
if (!this.env.model.getters.isRowHidden(sheetId, row)) {
|
|
@@ -29254,7 +29237,7 @@ class RowResizer extends AbstractResizer {
|
|
|
29254
29237
|
}
|
|
29255
29238
|
unhide(hiddenElements) {
|
|
29256
29239
|
this.env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
|
|
29257
|
-
sheetId: this.
|
|
29240
|
+
sheetId: this.sheetId,
|
|
29258
29241
|
dimension: "ROW",
|
|
29259
29242
|
elements: hiddenElements,
|
|
29260
29243
|
});
|
|
@@ -30399,6 +30382,7 @@ const DRAWING_NS_C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
|
|
|
30399
30382
|
const CONTENT_TYPES = {
|
|
30400
30383
|
workbook: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
|
|
30401
30384
|
sheet: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
|
|
30385
|
+
metadata: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",
|
|
30402
30386
|
sharedStrings: "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
|
|
30403
30387
|
styles: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
|
|
30404
30388
|
drawing: "application/vnd.openxmlformats-officedocument.drawing+xml",
|
|
@@ -30411,6 +30395,7 @@ const CONTENT_TYPES = {
|
|
|
30411
30395
|
const XLSX_RELATION_TYPE = {
|
|
30412
30396
|
document: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
|
|
30413
30397
|
sheet: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet",
|
|
30398
|
+
metadata: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata",
|
|
30414
30399
|
sharedStrings: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings",
|
|
30415
30400
|
styles: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
|
|
30416
30401
|
drawing: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
|
|
@@ -30420,6 +30405,7 @@ const XLSX_RELATION_TYPE = {
|
|
|
30420
30405
|
hyperlink: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
|
|
30421
30406
|
image: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
|
30422
30407
|
};
|
|
30408
|
+
const ARRAY_FORMULA_URI = "bdbb8cdc-fa1e-496e-a857-3c3f30c029c3";
|
|
30423
30409
|
const RELATIONSHIP_NSR = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
30424
30410
|
const HEIGHT_FACTOR = 0.75; // 100px => 75 u
|
|
30425
30411
|
/**
|
|
@@ -32249,29 +32235,33 @@ function applyStyleToZone(appliedStyle, zone, cells, styles) {
|
|
|
32249
32235
|
* In all the sheets, replace the table-only references in the formula cells with standard references.
|
|
32250
32236
|
*/
|
|
32251
32237
|
function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
|
|
32252
|
-
for (let
|
|
32253
|
-
const tables = xlsxSheets.find((s) => s.sheetName ===
|
|
32238
|
+
for (let tableSheet of convertedSheets) {
|
|
32239
|
+
const tables = xlsxSheets.find((s) => s.sheetName === tableSheet.name).tables;
|
|
32254
32240
|
for (let table of tables) {
|
|
32255
32241
|
const tabRef = table.name + "[";
|
|
32256
|
-
for (let
|
|
32257
|
-
|
|
32258
|
-
|
|
32259
|
-
|
|
32260
|
-
|
|
32261
|
-
|
|
32262
|
-
|
|
32263
|
-
|
|
32264
|
-
|
|
32265
|
-
|
|
32266
|
-
|
|
32267
|
-
|
|
32242
|
+
for (let sheet of convertedSheets) {
|
|
32243
|
+
for (let xc in sheet.cells) {
|
|
32244
|
+
const cell = sheet.cells[xc];
|
|
32245
|
+
if (cell && cell.content && cell.content.startsWith("=")) {
|
|
32246
|
+
let refIndex;
|
|
32247
|
+
while ((refIndex = cell.content.indexOf(tabRef)) !== -1) {
|
|
32248
|
+
let endIndex = refIndex + tabRef.length;
|
|
32249
|
+
let openBrackets = 1;
|
|
32250
|
+
while (openBrackets > 0 && endIndex < cell.content.length) {
|
|
32251
|
+
if (cell.content[endIndex] === "[") {
|
|
32252
|
+
openBrackets++;
|
|
32253
|
+
}
|
|
32254
|
+
else if (cell.content[endIndex] === "]") {
|
|
32255
|
+
openBrackets--;
|
|
32256
|
+
}
|
|
32257
|
+
endIndex++;
|
|
32258
|
+
}
|
|
32259
|
+
let reference = cell.content.slice(refIndex + tabRef.length, endIndex - 1);
|
|
32260
|
+
const sheetPrefix = tableSheet.id === sheet.id ? "" : tableSheet.name + "!";
|
|
32261
|
+
const convertedRef = convertTableReference(sheetPrefix, reference, table, xc);
|
|
32262
|
+
cell.content =
|
|
32263
|
+
cell.content.slice(0, refIndex) + convertedRef + cell.content.slice(endIndex);
|
|
32268
32264
|
}
|
|
32269
|
-
reference = reference.slice(0, endIndex);
|
|
32270
|
-
const convertedRef = convertTableReference(reference, table, xc);
|
|
32271
|
-
cell.content =
|
|
32272
|
-
cell.content.slice(0, refIndex) +
|
|
32273
|
-
convertedRef +
|
|
32274
|
-
cell.content.slice(tabRef.length + refIndex + endIndex + 1);
|
|
32275
32265
|
}
|
|
32276
32266
|
}
|
|
32277
32267
|
}
|
|
@@ -32279,11 +32269,17 @@ function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
|
|
|
32279
32269
|
}
|
|
32280
32270
|
}
|
|
32281
32271
|
/**
|
|
32282
|
-
* Convert table-specific references in formulas into standard references.
|
|
32272
|
+
* Convert table-specific references in formulas into standard references. A table reference is composed of columns names,
|
|
32273
|
+
* and of keywords determining the rows of the table to reference.
|
|
32283
32274
|
*
|
|
32284
32275
|
* A reference in a table can have the form (only the part between brackets should be given to this function):
|
|
32285
32276
|
* - tableName[colName] : reference to the whole column "colName"
|
|
32277
|
+
* - tableName[#keyword] : reference to the whatever row the keyword refers to
|
|
32286
32278
|
* - tableName[[#keyword], [colName]] : reference to some of the element(s) of the column colName
|
|
32279
|
+
* - tableName[[#keyword], [colName]:[col2Name]] : reference to some of the element(s) of the columns colName to col2Name
|
|
32280
|
+
* - tableName[[#keyword1], [#keyword2], [colName]] : reference to all the rows referenced by the keywords in the column colName
|
|
32281
|
+
* - tableName[[#keyword1], [colName], [#keyword2]]: the keywords and colName can be in any order
|
|
32282
|
+
*
|
|
32287
32283
|
*
|
|
32288
32284
|
* The available keywords are :
|
|
32289
32285
|
* - #All : all the column (including totals)
|
|
@@ -32291,58 +32287,109 @@ function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
|
|
|
32291
32287
|
* - #Headers : only the header of the column
|
|
32292
32288
|
* - #Totals : only the totals of the column
|
|
32293
32289
|
* - #This Row : only the element in the same row as the cell
|
|
32290
|
+
*
|
|
32291
|
+
* Note that the only valid combination of multiple keywords are #Data + #Totals and #Headers + #Data.
|
|
32294
32292
|
*/
|
|
32295
|
-
function convertTableReference(expr, table, cellXc) {
|
|
32296
|
-
|
|
32293
|
+
function convertTableReference(sheetPrefix, expr, table, cellXc) {
|
|
32294
|
+
// TODO: Ideally we'd want to make a real tokenizer, this simple approach won't work if for example the column name
|
|
32295
|
+
// contain # or , characters. But that's probably an edge case that we can ignore for now.
|
|
32296
|
+
const parts = expr.split(",").map((part) => part.trim());
|
|
32297
32297
|
const tableZone = toZone(table.ref);
|
|
32298
|
-
const
|
|
32299
|
-
|
|
32300
|
-
|
|
32301
|
-
|
|
32302
|
-
|
|
32303
|
-
|
|
32304
|
-
|
|
32305
|
-
|
|
32306
|
-
|
|
32307
|
-
|
|
32308
|
-
|
|
32298
|
+
const colIndexes = [];
|
|
32299
|
+
const rowIndexes = [];
|
|
32300
|
+
const foundKeywords = [];
|
|
32301
|
+
for (const part of parts) {
|
|
32302
|
+
if (removeBrackets(part).startsWith("#")) {
|
|
32303
|
+
const keyWord = removeBrackets(part);
|
|
32304
|
+
foundKeywords.push(keyWord);
|
|
32305
|
+
switch (keyWord) {
|
|
32306
|
+
case "#All":
|
|
32307
|
+
rowIndexes.push(tableZone.top, tableZone.bottom);
|
|
32308
|
+
break;
|
|
32309
|
+
case "#Data":
|
|
32310
|
+
const top = table.headerRowCount ? tableZone.top + table.headerRowCount : tableZone.top;
|
|
32311
|
+
const bottom = table.totalsRowCount
|
|
32312
|
+
? tableZone.bottom - table.totalsRowCount
|
|
32313
|
+
: tableZone.bottom;
|
|
32314
|
+
rowIndexes.push(top, bottom);
|
|
32315
|
+
break;
|
|
32316
|
+
case "#This Row":
|
|
32317
|
+
rowIndexes.push(toCartesian(cellXc).row);
|
|
32318
|
+
break;
|
|
32319
|
+
case "#Headers":
|
|
32320
|
+
if (!table.headerRowCount) {
|
|
32321
|
+
return INCORRECT_RANGE_STRING;
|
|
32322
|
+
}
|
|
32323
|
+
rowIndexes.push(tableZone.top);
|
|
32324
|
+
break;
|
|
32325
|
+
case "#Totals":
|
|
32326
|
+
if (!table.totalsRowCount) {
|
|
32327
|
+
return INCORRECT_RANGE_STRING;
|
|
32328
|
+
}
|
|
32329
|
+
rowIndexes.push(tableZone.bottom);
|
|
32330
|
+
break;
|
|
32331
|
+
}
|
|
32309
32332
|
}
|
|
32310
|
-
|
|
32311
|
-
|
|
32312
|
-
|
|
32313
|
-
|
|
32314
|
-
|
|
32315
|
-
|
|
32316
|
-
|
|
32317
|
-
|
|
32318
|
-
|
|
32319
|
-
|
|
32320
|
-
|
|
32321
|
-
|
|
32322
|
-
|
|
32323
|
-
|
|
32324
|
-
|
|
32325
|
-
|
|
32326
|
-
|
|
32327
|
-
if (!table.headerRowCount) {
|
|
32328
|
-
isReferencedZoneValid = false;
|
|
32329
|
-
}
|
|
32330
|
-
break;
|
|
32331
|
-
case "#Totals":
|
|
32332
|
-
refZone.top = refZone.bottom = tableZone.bottom;
|
|
32333
|
-
if (!table.totalsRowCount) {
|
|
32334
|
-
isReferencedZoneValid = false;
|
|
32333
|
+
else {
|
|
32334
|
+
const columns = part
|
|
32335
|
+
.split(":")
|
|
32336
|
+
.map((part) => part.trim())
|
|
32337
|
+
.map(removeBrackets);
|
|
32338
|
+
if (colIndexes.length) {
|
|
32339
|
+
return INCORRECT_RANGE_STRING;
|
|
32340
|
+
}
|
|
32341
|
+
const colRelativeIndex = table.cols.findIndex((col) => col.name === columns[0]);
|
|
32342
|
+
if (colRelativeIndex === -1) {
|
|
32343
|
+
return INCORRECT_RANGE_STRING;
|
|
32344
|
+
}
|
|
32345
|
+
colIndexes.push(colRelativeIndex + tableZone.left);
|
|
32346
|
+
if (columns[1]) {
|
|
32347
|
+
const colRelativeIndex2 = table.cols.findIndex((col) => col.name === columns[1]);
|
|
32348
|
+
if (colRelativeIndex2 === -1) {
|
|
32349
|
+
return INCORRECT_RANGE_STRING;
|
|
32335
32350
|
}
|
|
32336
|
-
|
|
32351
|
+
colIndexes.push(colRelativeIndex2 + tableZone.left);
|
|
32352
|
+
}
|
|
32337
32353
|
}
|
|
32338
|
-
const colRef = refElements[1].slice(1, refElements[1].length - 1);
|
|
32339
|
-
const colRelativeIndex = table.cols.findIndex((col) => col.name === colRef);
|
|
32340
|
-
refZone.left = refZone.right = colRelativeIndex + tableZone.left;
|
|
32341
32354
|
}
|
|
32342
|
-
if (!
|
|
32355
|
+
if (!areKeywordsCompatible(foundKeywords)) {
|
|
32343
32356
|
return INCORRECT_RANGE_STRING;
|
|
32344
32357
|
}
|
|
32345
|
-
|
|
32358
|
+
if (rowIndexes.length === 0) {
|
|
32359
|
+
const top = table.headerRowCount ? tableZone.top + table.headerRowCount : tableZone.top;
|
|
32360
|
+
const bottom = table.totalsRowCount
|
|
32361
|
+
? tableZone.bottom - table.totalsRowCount
|
|
32362
|
+
: tableZone.bottom;
|
|
32363
|
+
rowIndexes.push(top, bottom);
|
|
32364
|
+
}
|
|
32365
|
+
if (colIndexes.length === 0) {
|
|
32366
|
+
colIndexes.push(tableZone.left, tableZone.right);
|
|
32367
|
+
}
|
|
32368
|
+
const refZone = {
|
|
32369
|
+
top: Math.min(...rowIndexes),
|
|
32370
|
+
left: Math.min(...colIndexes),
|
|
32371
|
+
bottom: Math.max(...rowIndexes),
|
|
32372
|
+
right: Math.max(...colIndexes),
|
|
32373
|
+
};
|
|
32374
|
+
return sheetPrefix + zoneToXc(refZone);
|
|
32375
|
+
}
|
|
32376
|
+
function removeBrackets(str) {
|
|
32377
|
+
return str.startsWith("[") && str.endsWith("]") ? str.slice(1, str.length - 1) : str;
|
|
32378
|
+
}
|
|
32379
|
+
function areKeywordsCompatible(keywords) {
|
|
32380
|
+
if (keywords.length < 2) {
|
|
32381
|
+
return true;
|
|
32382
|
+
}
|
|
32383
|
+
else if (keywords.length > 2) {
|
|
32384
|
+
return false;
|
|
32385
|
+
}
|
|
32386
|
+
else if (keywords.includes("#Data") && keywords.includes("#Totals")) {
|
|
32387
|
+
return true;
|
|
32388
|
+
}
|
|
32389
|
+
else if (keywords.includes("#Headers") && keywords.includes("#Data")) {
|
|
32390
|
+
return true;
|
|
32391
|
+
}
|
|
32392
|
+
return false;
|
|
32346
32393
|
}
|
|
32347
32394
|
|
|
32348
32395
|
// -------------------------------------
|
|
@@ -33895,7 +33942,7 @@ function normalizeV9(formula) {
|
|
|
33895
33942
|
* a breaking change is made in the way the state is handled, and an upgrade
|
|
33896
33943
|
* function should be defined
|
|
33897
33944
|
*/
|
|
33898
|
-
const CURRENT_VERSION = 14;
|
|
33945
|
+
const CURRENT_VERSION = 14.5;
|
|
33899
33946
|
const INITIAL_SHEET_ID = "Sheet1";
|
|
33900
33947
|
/**
|
|
33901
33948
|
* This function tries to load anything that could look like a valid
|
|
@@ -42404,6 +42451,9 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
42404
42451
|
// Export
|
|
42405
42452
|
// ---------------------------------------------------------------------------
|
|
42406
42453
|
exportForExcel(data) {
|
|
42454
|
+
for (const sheet of data.sheets) {
|
|
42455
|
+
sheet.formulaSpillRanges = {};
|
|
42456
|
+
}
|
|
42407
42457
|
for (const position of this.evaluator.getEvaluatedPositions()) {
|
|
42408
42458
|
const evaluatedCell = this.evaluator.getEvaluatedCell(position);
|
|
42409
42459
|
const xc = toXC(position.col, position.row);
|
|
@@ -42415,8 +42465,9 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
42415
42465
|
const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
|
|
42416
42466
|
const formulaCell = this.getCorrespondingFormulaCell(position);
|
|
42417
42467
|
if (formulaCell) {
|
|
42468
|
+
const cell = this.getters.getCell(position);
|
|
42418
42469
|
isExported = isExportableToExcel(formulaCell.compiledFormula.tokens);
|
|
42419
|
-
isFormula = isExported;
|
|
42470
|
+
isFormula = isExported && cell?.content === formulaCell.content;
|
|
42420
42471
|
if (!isExported) {
|
|
42421
42472
|
// If the cell contains a non-exported formula and that is evaluates to
|
|
42422
42473
|
// nothing* ,we don't export it.
|
|
@@ -42440,6 +42491,14 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
42440
42491
|
content = !isExported ? newContent : exportedCellData.content;
|
|
42441
42492
|
}
|
|
42442
42493
|
exportedSheetData.cells[xc] = { ...exportedCellData, value, isFormula, content, format };
|
|
42494
|
+
const spillCells = this.getSpreadPositionsOf(position);
|
|
42495
|
+
spillCells.push(position);
|
|
42496
|
+
const spillZones = spillCells.map((cell) => positionToZone(cell));
|
|
42497
|
+
const spillZone = union(...spillZones);
|
|
42498
|
+
const spillZoneXc = this.getters.getRangeString(this.getters.getRangeFromZone(position.sheetId, spillZone), position.sheetId);
|
|
42499
|
+
if (spillZoneXc && spillZoneXc !== "#REF") {
|
|
42500
|
+
exportedSheetData.formulaSpillRanges[xc] = spillZoneXc;
|
|
42501
|
+
}
|
|
42443
42502
|
}
|
|
42444
42503
|
}
|
|
42445
42504
|
/**
|
|
@@ -43640,7 +43699,7 @@ class AutofillPlugin extends UIPlugin {
|
|
|
43640
43699
|
getRule(cell, cells) {
|
|
43641
43700
|
const rules = autofillRulesRegistry.getAll().sort((a, b) => a.sequence - b.sequence);
|
|
43642
43701
|
const rule = rules.find((rule) => rule.condition(cell, cells));
|
|
43643
|
-
return rule && rule.generateRule(cell, cells);
|
|
43702
|
+
return rule && this.direction && rule.generateRule(cell, cells, this.direction);
|
|
43644
43703
|
}
|
|
43645
43704
|
/**
|
|
43646
43705
|
* Create the generator to be able to autofill the next cells.
|
|
@@ -51310,7 +51369,8 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51310
51369
|
? this.getters.getSheetViewVisibleCols()
|
|
51311
51370
|
: this.getters.getSheetViewVisibleRows();
|
|
51312
51371
|
const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
|
|
51313
|
-
|
|
51372
|
+
let endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
|
|
51373
|
+
endIndex = endIndex === -1 ? visibleHeaders.length : endIndex;
|
|
51314
51374
|
const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
|
|
51315
51375
|
let offset = 0;
|
|
51316
51376
|
for (const i of relevantIndexes) {
|
|
@@ -56109,7 +56169,7 @@ function numberRef(reference) {
|
|
|
56109
56169
|
`;
|
|
56110
56170
|
}
|
|
56111
56171
|
|
|
56112
|
-
function addFormula(cell) {
|
|
56172
|
+
function addFormula(cell, formulaSpillRange) {
|
|
56113
56173
|
const formula = cell.content;
|
|
56114
56174
|
if (!formula) {
|
|
56115
56175
|
return { attrs: [], node: escapeXml `` };
|
|
@@ -56118,10 +56178,17 @@ function addFormula(cell) {
|
|
|
56118
56178
|
if (type === undefined) {
|
|
56119
56179
|
return { attrs: [], node: escapeXml `` };
|
|
56120
56180
|
}
|
|
56121
|
-
const attrs = [
|
|
56181
|
+
const attrs = [
|
|
56182
|
+
["cm", "1"],
|
|
56183
|
+
["t", type],
|
|
56184
|
+
];
|
|
56122
56185
|
const XlsxFormula = adaptFormulaToExcel(formula);
|
|
56123
56186
|
const exportedValue = adaptFormulaValueToExcel(cell.value);
|
|
56124
|
-
|
|
56187
|
+
// We treat all formulas as array formulas (a simple formula
|
|
56188
|
+
// is an array formula that spills on only one cell) to avoid
|
|
56189
|
+
// trying to detect spilling sub-formulas which is not a trivial task.
|
|
56190
|
+
let node;
|
|
56191
|
+
node = escapeXml /*xml*/ `<f t="array" ref="${formulaSpillRange}">${XlsxFormula}</f><v>${exportedValue}</v>`;
|
|
56125
56192
|
return { attrs, node };
|
|
56126
56193
|
}
|
|
56127
56194
|
function addContent(content, sharedStrings, forceString = false) {
|
|
@@ -56933,7 +57000,7 @@ function addRows(construct, data, sheet) {
|
|
|
56933
57000
|
let cellNode = escapeXml ``;
|
|
56934
57001
|
// Either formula or static value inside the cell
|
|
56935
57002
|
if (cell.isFormula) {
|
|
56936
|
-
const res = addFormula(cell);
|
|
57003
|
+
const res = addFormula(cell, sheet.formulaSpillRanges[xc] ?? xc);
|
|
56937
57004
|
if (!res) {
|
|
56938
57005
|
continue;
|
|
56939
57006
|
}
|
|
@@ -57190,6 +57257,30 @@ function createWorksheets(data, construct) {
|
|
|
57190
57257
|
`;
|
|
57191
57258
|
files.push(createXMLFile(parseXML(sheetXml), `xl/worksheets/sheet${sheetIndex}.xml`, "sheet"));
|
|
57192
57259
|
}
|
|
57260
|
+
const sheetMetadataXml = escapeXml /*xml*/ `
|
|
57261
|
+
<metadata xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:xda="http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray">
|
|
57262
|
+
<metadataTypes count="1">
|
|
57263
|
+
<metadataType name="XLDAPR" minSupportedVersion="120000" copy="1" pasteAll="1"
|
|
57264
|
+
pasteValues="1" merge="1" splitFirst="1" rowColShift="1" clearFormats="1"
|
|
57265
|
+
clearComments="1" assign="1" coerce="1" cellMeta="1" />
|
|
57266
|
+
</metadataTypes>
|
|
57267
|
+
<futureMetadata name="XLDAPR" count="1">
|
|
57268
|
+
<bk>
|
|
57269
|
+
<extLst>
|
|
57270
|
+
<ext uri="{${ARRAY_FORMULA_URI}}">
|
|
57271
|
+
<xda:dynamicArrayProperties fDynamic="1" fCollapsed="0" />
|
|
57272
|
+
</ext>
|
|
57273
|
+
</extLst>
|
|
57274
|
+
</bk>
|
|
57275
|
+
</futureMetadata>
|
|
57276
|
+
<cellMetadata count="1">
|
|
57277
|
+
<bk>
|
|
57278
|
+
<rc t="1" v="0" />
|
|
57279
|
+
</bk>
|
|
57280
|
+
</cellMetadata>
|
|
57281
|
+
</metadata>
|
|
57282
|
+
`;
|
|
57283
|
+
files.push(createXMLFile(parseXML(sheetMetadataXml), "xl/metadata.xml", "metadata"));
|
|
57193
57284
|
addRelsToFile(construct.relsFiles, "xl/_rels/workbook.xml.rels", {
|
|
57194
57285
|
type: XLSX_RELATION_TYPE.sharedStrings,
|
|
57195
57286
|
target: "sharedStrings.xml",
|
|
@@ -57198,6 +57289,10 @@ function createWorksheets(data, construct) {
|
|
|
57198
57289
|
type: XLSX_RELATION_TYPE.styles,
|
|
57199
57290
|
target: "styles.xml",
|
|
57200
57291
|
});
|
|
57292
|
+
addRelsToFile(construct.relsFiles, "xl/_rels/workbook.xml.rels", {
|
|
57293
|
+
type: XLSX_RELATION_TYPE.metadata,
|
|
57294
|
+
target: "metadata.xml",
|
|
57295
|
+
});
|
|
57201
57296
|
return files;
|
|
57202
57297
|
}
|
|
57203
57298
|
/**
|
|
@@ -57937,6 +58032,6 @@ const constants = {
|
|
|
57937
58032
|
export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
|
|
57938
58033
|
|
|
57939
58034
|
|
|
57940
|
-
__info__.version = "17.0.
|
|
57941
|
-
__info__.date = "2025-
|
|
57942
|
-
__info__.hash = "
|
|
58035
|
+
__info__.version = "17.0.52";
|
|
58036
|
+
__info__.date = "2025-03-07T10:30:04.783Z";
|
|
58037
|
+
__info__.hash = "c19cd9a";
|