@odoo/o-spreadsheet 18.1.4 → 18.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/o-spreadsheet.cjs.js +206 -139
- package/dist/o-spreadsheet.d.ts +12 -14
- package/dist/o-spreadsheet.esm.js +206 -139
- package/dist/o-spreadsheet.iife.js +206 -139
- package/dist/o-spreadsheet.iife.min.js +7 -7
- package/dist/o_spreadsheet.xml +3 -3
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.1.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.1.6
|
|
6
|
+
* @date 2025-02-05T07:18:57.089Z
|
|
7
|
+
* @hash f5b97e0
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -3349,11 +3349,11 @@
|
|
|
3349
3349
|
* number from the point of view of the isNumber function.
|
|
3350
3350
|
*/
|
|
3351
3351
|
function parseNumber(str, locale) {
|
|
3352
|
+
// remove invaluable characters
|
|
3353
|
+
str = str.replace(getInvaluableSymbolsRegexp(locale), "");
|
|
3352
3354
|
if (locale.decimalSeparator !== ".") {
|
|
3353
3355
|
str = str.replace(locale.decimalSeparator, ".");
|
|
3354
3356
|
}
|
|
3355
|
-
// remove invaluable characters
|
|
3356
|
-
str = str.replace(getInvaluableSymbolsRegexp(locale), "");
|
|
3357
3357
|
let n = Number(str);
|
|
3358
3358
|
if (isNaN(n) && str.includes("%")) {
|
|
3359
3359
|
n = Number(str.split("%")[0]);
|
|
@@ -18455,19 +18455,20 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18455
18455
|
description: _t("Horizontal lookup"),
|
|
18456
18456
|
args: [
|
|
18457
18457
|
arg("search_key (string, number, boolean)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18458
|
-
arg("range (range)", _t("The range to consider for the search. The first row in the range is searched for the key specified in search_key.")),
|
|
18458
|
+
arg("range (any, range)", _t("The range to consider for the search. The first row in the range is searched for the key specified in search_key.")),
|
|
18459
18459
|
arg("index (number)", _t("The row index of the value to be returned, where the first row in range is numbered 1.")),
|
|
18460
18460
|
arg(`is_sorted (boolean, default=${DEFAULT_IS_SORTED})`, _t("Indicates whether the row to be searched (the first row of the specified range) is sorted, in which case the closest match for search_key will be returned.")),
|
|
18461
18461
|
],
|
|
18462
18462
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18463
18463
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18464
|
-
|
|
18464
|
+
const _range = toMatrix(range);
|
|
18465
|
+
assert(() => 1 <= _index && _index <= _range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18465
18466
|
const getValueFromRange = (range, index) => range[index][0].value;
|
|
18466
18467
|
const _isSorted = toBoolean(isSorted.value);
|
|
18467
18468
|
const colIndex = _isSorted
|
|
18468
|
-
? dichotomicSearch(
|
|
18469
|
-
: linearSearch(
|
|
18470
|
-
const col =
|
|
18469
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
|
|
18470
|
+
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange);
|
|
18471
|
+
const col = _range[colIndex];
|
|
18471
18472
|
if (col === undefined) {
|
|
18472
18473
|
return valueNotAvailable(searchKey);
|
|
18473
18474
|
}
|
|
@@ -18559,35 +18560,37 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18559
18560
|
description: _t("Look up a value."),
|
|
18560
18561
|
args: [
|
|
18561
18562
|
arg("search_key (string, number, boolean)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18562
|
-
arg("search_array (range)", _t("One method of using this function is to provide a single sorted row or column search_array to look through for the search_key with a second argument result_range. The other way is to combine these two arguments into one search_array where the first row or column is searched and a value is returned from the last row or column in the array. If search_key is not found, a non-exact match may be returned.")),
|
|
18563
|
-
arg("result_range (range, optional)", _t("The range from which to return a result. The value returned corresponds to the location where search_key is found in search_range. This range must be only a single row or column and should not be used if using the search_result_array method.")),
|
|
18563
|
+
arg("search_array (any, range)", _t("One method of using this function is to provide a single sorted row or column search_array to look through for the search_key with a second argument result_range. The other way is to combine these two arguments into one search_array where the first row or column is searched and a value is returned from the last row or column in the array. If search_key is not found, a non-exact match may be returned.")),
|
|
18564
|
+
arg("result_range (any, range, optional)", _t("The range from which to return a result. The value returned corresponds to the location where search_key is found in search_range. This range must be only a single row or column and should not be used if using the search_result_array method.")),
|
|
18564
18565
|
],
|
|
18565
18566
|
compute: function (searchKey, searchArray, resultRange) {
|
|
18566
|
-
|
|
18567
|
-
|
|
18567
|
+
const _searchArray = toMatrix(searchArray);
|
|
18568
|
+
const _resultRange = toMatrix(resultRange);
|
|
18569
|
+
let nbCol = _searchArray.length;
|
|
18570
|
+
let nbRow = _searchArray[0].length;
|
|
18568
18571
|
const verticalSearch = nbRow >= nbCol;
|
|
18569
18572
|
const getElement = verticalSearch
|
|
18570
18573
|
? (range, index) => range[0][index].value
|
|
18571
18574
|
: (range, index) => range[index][0].value;
|
|
18572
18575
|
const rangeLength = verticalSearch ? nbRow : nbCol;
|
|
18573
|
-
const index = dichotomicSearch(
|
|
18576
|
+
const index = dichotomicSearch(_searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
|
|
18574
18577
|
if (index === -1 ||
|
|
18575
|
-
(verticalSearch &&
|
|
18576
|
-
(!verticalSearch &&
|
|
18578
|
+
(verticalSearch && _searchArray[0][index] === undefined) ||
|
|
18579
|
+
(!verticalSearch && _searchArray[index][nbRow - 1] === undefined)) {
|
|
18577
18580
|
return valueNotAvailable(searchKey);
|
|
18578
18581
|
}
|
|
18579
|
-
if (
|
|
18580
|
-
return verticalSearch ?
|
|
18582
|
+
if (_resultRange[0].length === 0) {
|
|
18583
|
+
return verticalSearch ? _searchArray[nbCol - 1][index] : _searchArray[index][nbRow - 1];
|
|
18581
18584
|
}
|
|
18582
|
-
nbCol =
|
|
18583
|
-
nbRow =
|
|
18585
|
+
nbCol = _resultRange.length;
|
|
18586
|
+
nbRow = _resultRange[0].length;
|
|
18584
18587
|
assert(() => nbCol === 1 || nbRow === 1, _t("The result_range must be a single row or a single column."));
|
|
18585
18588
|
if (nbCol > 1) {
|
|
18586
18589
|
assert(() => index <= nbCol - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range row value %s.", (index + 1).toString()));
|
|
18587
|
-
return
|
|
18590
|
+
return _resultRange[index][0];
|
|
18588
18591
|
}
|
|
18589
18592
|
assert(() => index <= nbRow - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range column value %s.", (index + 1).toString()));
|
|
18590
|
-
return
|
|
18593
|
+
return _resultRange[0][index];
|
|
18591
18594
|
},
|
|
18592
18595
|
isExported: true,
|
|
18593
18596
|
};
|
|
@@ -18604,28 +18607,29 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18604
18607
|
],
|
|
18605
18608
|
compute: function (searchKey, range, searchType = { value: DEFAULT_SEARCH_TYPE }) {
|
|
18606
18609
|
let _searchType = toNumber(searchType, this.locale);
|
|
18607
|
-
const
|
|
18608
|
-
const
|
|
18610
|
+
const _range = toMatrix(range);
|
|
18611
|
+
const nbCol = _range.length;
|
|
18612
|
+
const nbRow = _range[0].length;
|
|
18609
18613
|
assert(() => nbCol === 1 || nbRow === 1, _t("The range must be a single row or a single column."));
|
|
18610
18614
|
let index = -1;
|
|
18611
18615
|
const getElement = nbCol === 1
|
|
18612
|
-
? (
|
|
18613
|
-
: (
|
|
18614
|
-
const rangeLen = nbCol === 1 ?
|
|
18616
|
+
? (_range, index) => _range[0][index].value
|
|
18617
|
+
: (_range, index) => _range[index][0].value;
|
|
18618
|
+
const rangeLen = nbCol === 1 ? _range[0].length : _range.length;
|
|
18615
18619
|
_searchType = Math.sign(_searchType);
|
|
18616
18620
|
switch (_searchType) {
|
|
18617
18621
|
case 1:
|
|
18618
|
-
index = dichotomicSearch(
|
|
18622
|
+
index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
|
|
18619
18623
|
break;
|
|
18620
18624
|
case 0:
|
|
18621
|
-
index = linearSearch(
|
|
18625
|
+
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement);
|
|
18622
18626
|
break;
|
|
18623
18627
|
case -1:
|
|
18624
|
-
index = dichotomicSearch(
|
|
18628
|
+
index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
18625
18629
|
break;
|
|
18626
18630
|
}
|
|
18627
|
-
if ((nbCol === 1 &&
|
|
18628
|
-
(nbCol !== 1 &&
|
|
18631
|
+
if ((nbCol === 1 && _range[0][index] === undefined) ||
|
|
18632
|
+
(nbCol !== 1 && _range[index] === undefined)) {
|
|
18629
18633
|
return valueNotAvailable(searchKey);
|
|
18630
18634
|
}
|
|
18631
18635
|
return index + 1;
|
|
@@ -18680,13 +18684,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18680
18684
|
],
|
|
18681
18685
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18682
18686
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18683
|
-
|
|
18687
|
+
const _range = toMatrix(range);
|
|
18688
|
+
assert(() => 1 <= _index && _index <= _range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18684
18689
|
const getValueFromRange = (range, index) => range[0][index].value;
|
|
18685
18690
|
const _isSorted = toBoolean(isSorted.value);
|
|
18686
18691
|
const rowIndex = _isSorted
|
|
18687
|
-
? dichotomicSearch(
|
|
18688
|
-
: linearSearch(
|
|
18689
|
-
const value =
|
|
18692
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
|
|
18693
|
+
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange);
|
|
18694
|
+
const value = _range[_index - 1][rowIndex];
|
|
18690
18695
|
if (value === undefined) {
|
|
18691
18696
|
return valueNotAvailable(searchKey);
|
|
18692
18697
|
}
|
|
@@ -18723,27 +18728,29 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18723
18728
|
compute: function (searchKey, lookupRange, returnRange, defaultValue, matchMode = { value: DEFAULT_MATCH_MODE }, searchMode = { value: DEFAULT_SEARCH_MODE }) {
|
|
18724
18729
|
const _matchMode = Math.trunc(toNumber(matchMode.value, this.locale));
|
|
18725
18730
|
const _searchMode = Math.trunc(toNumber(searchMode.value, this.locale));
|
|
18726
|
-
|
|
18731
|
+
const _lookupRange = toMatrix(lookupRange);
|
|
18732
|
+
const _returnRange = toMatrix(returnRange);
|
|
18733
|
+
assert(() => _lookupRange.length === 1 || _lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
|
|
18727
18734
|
assert(() => [-1, 1, -2, 2].includes(_searchMode), _t("search_mode should be a value in [-1, 1, -2, 2]."));
|
|
18728
18735
|
assert(() => [-1, 0, 1, 2].includes(_matchMode), _t("match_mode should be a value in [-1, 0, 1, 2]."));
|
|
18729
|
-
const lookupDirection =
|
|
18736
|
+
const lookupDirection = _lookupRange.length === 1 ? "col" : "row";
|
|
18730
18737
|
assert(() => !(_matchMode === 2 && [-2, 2].includes(_searchMode)), _t("the search and match mode combination is not supported for XLOOKUP evaluation."));
|
|
18731
18738
|
assert(() => lookupDirection === "col"
|
|
18732
|
-
?
|
|
18733
|
-
:
|
|
18739
|
+
? _returnRange[0].length === _lookupRange[0].length
|
|
18740
|
+
: _returnRange.length === _lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
|
|
18734
18741
|
const getElement = lookupDirection === "col"
|
|
18735
18742
|
? (range, index) => range[0][index].value
|
|
18736
18743
|
: (range, index) => range[index][0].value;
|
|
18737
|
-
const rangeLen = lookupDirection === "col" ?
|
|
18744
|
+
const rangeLen = lookupDirection === "col" ? _lookupRange[0].length : _lookupRange.length;
|
|
18738
18745
|
const mode = MATCH_MODE[_matchMode];
|
|
18739
18746
|
const reverseSearch = _searchMode === -1;
|
|
18740
18747
|
const index = _searchMode === 2 || _searchMode === -2
|
|
18741
|
-
? dichotomicSearch(
|
|
18742
|
-
: linearSearch(
|
|
18748
|
+
? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
|
|
18749
|
+
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, reverseSearch);
|
|
18743
18750
|
if (index !== -1) {
|
|
18744
18751
|
return lookupDirection === "col"
|
|
18745
|
-
?
|
|
18746
|
-
: [
|
|
18752
|
+
? _returnRange.map((col) => [col[index]])
|
|
18753
|
+
: [_returnRange[index]];
|
|
18747
18754
|
}
|
|
18748
18755
|
if (defaultValue === undefined) {
|
|
18749
18756
|
return valueNotAvailable(searchKey);
|
|
@@ -28435,11 +28442,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28435
28442
|
if (values.length < 2 || labels.length < 2 || newLabels.length === 0) {
|
|
28436
28443
|
return [];
|
|
28437
28444
|
}
|
|
28438
|
-
const
|
|
28439
|
-
const labelMax = Math.max(...labels);
|
|
28440
|
-
const labelRange = labelMax - labelMin;
|
|
28441
|
-
const normalizedLabels = labels.map((v) => (v - labelMin) / labelRange);
|
|
28442
|
-
const normalizedNewLabels = newLabels.map((v) => (v - labelMin) / labelRange);
|
|
28445
|
+
const { normalizedLabels, normalizedNewLabels } = normalizeLabels(labels, newLabels, config);
|
|
28443
28446
|
try {
|
|
28444
28447
|
switch (config.type) {
|
|
28445
28448
|
case "polynomial": {
|
|
@@ -28484,6 +28487,30 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28484
28487
|
return newLabels.map((x) => ({ x, y: NaN }));
|
|
28485
28488
|
}
|
|
28486
28489
|
}
|
|
28490
|
+
function normalizeLabels(labels, newLabels, config) {
|
|
28491
|
+
let normalizedLabels = [];
|
|
28492
|
+
let normalizedNewLabels = [];
|
|
28493
|
+
if (config.type === "logarithmic") {
|
|
28494
|
+
// Logarithmic trends in charts are used to visualize proportional growth or
|
|
28495
|
+
// relative changes. Therefore, we change the normalization technique for
|
|
28496
|
+
// logarithmic trend lines for a better fit. The method used here is Max Absolute
|
|
28497
|
+
// Scaling. This Technique is ideal for data spanning several orders of magnitude,
|
|
28498
|
+
// as it balances differences between small and large values by compressing larger
|
|
28499
|
+
// values while preserving proportionality and ensuring all values are scaled relative
|
|
28500
|
+
// to the largest magnitude.
|
|
28501
|
+
const labelMax = Math.max(...labels.map(Math.abs));
|
|
28502
|
+
normalizedLabels = labels.map((l) => l / labelMax);
|
|
28503
|
+
normalizedNewLabels = newLabels.map((l) => l / labelMax);
|
|
28504
|
+
}
|
|
28505
|
+
else {
|
|
28506
|
+
const labelMax = Math.max(...labels);
|
|
28507
|
+
const labelMin = Math.min(...labels);
|
|
28508
|
+
const labelRange = labelMax - labelMin;
|
|
28509
|
+
normalizedLabels = labels.map((l) => (l - labelMax) / labelRange);
|
|
28510
|
+
normalizedNewLabels = newLabels.map((l) => (l - labelMax) / labelRange);
|
|
28511
|
+
}
|
|
28512
|
+
return { normalizedLabels, normalizedNewLabels };
|
|
28513
|
+
}
|
|
28487
28514
|
function getChartAxisType(chart, labelRange, getters) {
|
|
28488
28515
|
if (isDateChart(chart, labelRange, getters) && isLuxonTimeAdapterInstalled()) {
|
|
28489
28516
|
return "time";
|
|
@@ -40368,6 +40395,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40368
40395
|
}
|
|
40369
40396
|
this.contentHelper.updateEl(el);
|
|
40370
40397
|
});
|
|
40398
|
+
this.env.model.selection.observe(this, {
|
|
40399
|
+
handleEvent: () => this.autoCompleteState.hide(),
|
|
40400
|
+
});
|
|
40401
|
+
owl.onWillUnmount(() => {
|
|
40402
|
+
this.env.model.selection.detachObserver(this);
|
|
40403
|
+
});
|
|
40371
40404
|
owl.useEffect(() => {
|
|
40372
40405
|
this.processContent();
|
|
40373
40406
|
if (document.activeElement === this.contentHelper.el &&
|
|
@@ -50481,11 +50514,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
50481
50514
|
switch (layer) {
|
|
50482
50515
|
case "Background":
|
|
50483
50516
|
this.drawGlobalBackground(renderingContext);
|
|
50484
|
-
for (const zone of this.getters.
|
|
50517
|
+
for (const { zone, rect } of this.getters.getAllActiveViewportsZonesAndRect()) {
|
|
50485
50518
|
const { ctx } = renderingContext;
|
|
50486
50519
|
ctx.save();
|
|
50487
50520
|
ctx.beginPath();
|
|
50488
|
-
const rect = this.getters.getVisibleRect(zone);
|
|
50489
50521
|
ctx.rect(rect.x, rect.y, rect.width, rect.height);
|
|
50490
50522
|
ctx.clip();
|
|
50491
50523
|
const boxes = this.getGridBoxes(zone);
|
|
@@ -50761,10 +50793,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
50761
50793
|
const { ctx, thinLineWidth } = renderingContext;
|
|
50762
50794
|
const visibleCols = this.getters.getSheetViewVisibleCols();
|
|
50763
50795
|
const left = visibleCols[0];
|
|
50764
|
-
const right = visibleCols[visibleCols.length - 1];
|
|
50765
50796
|
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
50766
50797
|
const top = visibleRows[0];
|
|
50767
|
-
const bottom = visibleRows[visibleRows.length - 1];
|
|
50768
50798
|
const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
|
|
50769
50799
|
const selection = this.getters.getSelectedZones();
|
|
50770
50800
|
const selectedCols = getZonesCols(selection);
|
|
@@ -50780,7 +50810,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
50780
50810
|
ctx.lineWidth = thinLineWidth;
|
|
50781
50811
|
ctx.strokeStyle = "#333";
|
|
50782
50812
|
// Columns headers background
|
|
50783
|
-
for (
|
|
50813
|
+
for (const col of visibleCols) {
|
|
50784
50814
|
const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
|
|
50785
50815
|
const { x, width } = this.getters.getVisibleRect(colZone);
|
|
50786
50816
|
const isColActive = activeCols.has(col);
|
|
@@ -50797,7 +50827,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
50797
50827
|
ctx.fillRect(x, 0, width, HEADER_HEIGHT);
|
|
50798
50828
|
}
|
|
50799
50829
|
// Rows headers background
|
|
50800
|
-
for (
|
|
50830
|
+
for (const row of visibleRows) {
|
|
50801
50831
|
const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
|
|
50802
50832
|
const { y, height } = this.getters.getVisibleRect(rowZone);
|
|
50803
50833
|
const isRowActive = activeRows.has(row);
|
|
@@ -50823,21 +50853,21 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
50823
50853
|
ctx.stroke();
|
|
50824
50854
|
ctx.beginPath();
|
|
50825
50855
|
// column text + separator
|
|
50826
|
-
for (const
|
|
50827
|
-
const colSize = this.getters.getColSize(sheetId,
|
|
50828
|
-
const colName = numberToLetters(
|
|
50829
|
-
ctx.fillStyle = activeCols.has(
|
|
50830
|
-
let colStart = this.getHeaderOffset("COL", left,
|
|
50856
|
+
for (const col of visibleCols) {
|
|
50857
|
+
const colSize = this.getters.getColSize(sheetId, col);
|
|
50858
|
+
const colName = numberToLetters(col);
|
|
50859
|
+
ctx.fillStyle = activeCols.has(col) ? "#fff" : TEXT_HEADER_COLOR;
|
|
50860
|
+
let colStart = this.getHeaderOffset("COL", left, col);
|
|
50831
50861
|
ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
|
|
50832
50862
|
ctx.moveTo(colStart + colSize, 0);
|
|
50833
50863
|
ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
|
|
50834
50864
|
}
|
|
50835
50865
|
// row text + separator
|
|
50836
|
-
for (const
|
|
50837
|
-
const rowSize = this.getters.getRowSize(sheetId,
|
|
50838
|
-
ctx.fillStyle = activeRows.has(
|
|
50839
|
-
let rowStart = this.getHeaderOffset("ROW", top,
|
|
50840
|
-
ctx.fillText(String(
|
|
50866
|
+
for (const row of visibleRows) {
|
|
50867
|
+
const rowSize = this.getters.getRowSize(sheetId, row);
|
|
50868
|
+
ctx.fillStyle = activeRows.has(row) ? "#fff" : TEXT_HEADER_COLOR;
|
|
50869
|
+
let rowStart = this.getHeaderOffset("ROW", top, row);
|
|
50870
|
+
ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
|
|
50841
50871
|
ctx.moveTo(0, rowStart + rowSize);
|
|
50842
50872
|
ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
|
|
50843
50873
|
}
|
|
@@ -51144,6 +51174,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51144
51174
|
canvas.width = width * dpr;
|
|
51145
51175
|
canvas.height = height * dpr;
|
|
51146
51176
|
canvas.setAttribute("style", `width:${width}px;height:${height}px;`);
|
|
51177
|
+
if (width === 0 || height === 0) {
|
|
51178
|
+
return;
|
|
51179
|
+
}
|
|
51147
51180
|
// Imagine each pixel as a large square. The whole-number coordinates (0, 1, 2…)
|
|
51148
51181
|
// are the edges of the squares. If you draw a one-unit-wide line between whole-number
|
|
51149
51182
|
// coordinates, it will overlap opposite sides of the pixel square, and the resulting
|
|
@@ -52690,7 +52723,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52690
52723
|
getCommonSides(border1, border2) {
|
|
52691
52724
|
const commonBorder = {};
|
|
52692
52725
|
for (let side of ["top", "bottom", "left", "right"]) {
|
|
52693
|
-
if (border1[side] && border1[side]
|
|
52726
|
+
if (border1[side] && deepEquals(border1[side], border2[side])) {
|
|
52694
52727
|
commonBorder[side] = border1[side];
|
|
52695
52728
|
}
|
|
52696
52729
|
}
|
|
@@ -61319,7 +61352,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
61319
61352
|
const symbolIndex = rowDomain.findIndex((row) => row.field === symbolName);
|
|
61320
61353
|
return this.getPivotHeaderValueAndFormat(rowDomain.slice(0, symbolIndex + 1));
|
|
61321
61354
|
}
|
|
61322
|
-
return this.
|
|
61355
|
+
return this.getPivotCellValueAndFormat(symbolName, domain);
|
|
61323
61356
|
};
|
|
61324
61357
|
const result = this.getters.evaluateCompiledFormula(measure.computedBy.sheetId, formula, getSymbolValue);
|
|
61325
61358
|
if (isMatrix(result)) {
|
|
@@ -64490,14 +64523,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
64490
64523
|
}
|
|
64491
64524
|
break;
|
|
64492
64525
|
case "AUTORESIZE_ROWS":
|
|
64493
|
-
|
|
64494
|
-
|
|
64495
|
-
|
|
64496
|
-
|
|
64497
|
-
|
|
64498
|
-
|
|
64499
|
-
});
|
|
64500
|
-
}
|
|
64526
|
+
this.dispatch("RESIZE_COLUMNS_ROWS", {
|
|
64527
|
+
elements: cmd.rows,
|
|
64528
|
+
dimension: "ROW",
|
|
64529
|
+
size: null,
|
|
64530
|
+
sheetId: cmd.sheetId,
|
|
64531
|
+
});
|
|
64501
64532
|
break;
|
|
64502
64533
|
}
|
|
64503
64534
|
}
|
|
@@ -66908,8 +66939,17 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66908
66939
|
this.getters = getters;
|
|
66909
66940
|
this.sheetId = sheetId;
|
|
66910
66941
|
this.boundaries = boundaries;
|
|
66911
|
-
|
|
66912
|
-
|
|
66942
|
+
if (sizeInGrid.width < 0 || sizeInGrid.height < 0) {
|
|
66943
|
+
throw new Error("Viewport size cannot be negative");
|
|
66944
|
+
}
|
|
66945
|
+
this.viewportWidth = sizeInGrid.height && sizeInGrid.width;
|
|
66946
|
+
this.viewportHeight = sizeInGrid.width && sizeInGrid.height;
|
|
66947
|
+
this.top = boundaries.top;
|
|
66948
|
+
this.bottom = boundaries.bottom;
|
|
66949
|
+
this.left = boundaries.left;
|
|
66950
|
+
this.right = boundaries.right;
|
|
66951
|
+
this.offsetX = offsets.x;
|
|
66952
|
+
this.offsetY = offsets.y;
|
|
66913
66953
|
this.offsetScrollbarX = offsets.x;
|
|
66914
66954
|
this.offsetScrollbarY = offsets.y;
|
|
66915
66955
|
this.canScrollVertically = options.canScrollVertically;
|
|
@@ -66952,9 +66992,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
66952
66992
|
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
66953
66993
|
);
|
|
66954
66994
|
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
66955
|
-
|
|
66956
|
-
|
|
66957
|
-
|
|
66995
|
+
if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
|
|
66996
|
+
height += FOOTER_HEIGHT;
|
|
66997
|
+
}
|
|
66958
66998
|
}
|
|
66959
66999
|
return { width, height };
|
|
66960
67000
|
}
|
|
@@ -67095,6 +67135,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67095
67135
|
!this.getters.isRowHidden(this.sheetId, row));
|
|
67096
67136
|
}
|
|
67097
67137
|
searchHeaderIndex(dimension, position, startIndex = 0) {
|
|
67138
|
+
if (this.viewportWidth <= 0 || this.viewportHeight <= 0) {
|
|
67139
|
+
return -1;
|
|
67140
|
+
}
|
|
67098
67141
|
const sheetId = this.sheetId;
|
|
67099
67142
|
const headers = this.getters.getNumberHeaders(sheetId, dimension);
|
|
67100
67143
|
// using a binary search:
|
|
@@ -67131,7 +67174,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67131
67174
|
this.adjustViewportZoneY();
|
|
67132
67175
|
}
|
|
67133
67176
|
/** Corrects the viewport's horizontal offset based on the current structure
|
|
67134
|
-
* To make sure that at least
|
|
67177
|
+
* To make sure that at least one column is visible inside the viewport.
|
|
67135
67178
|
*/
|
|
67136
67179
|
adjustViewportOffsetX() {
|
|
67137
67180
|
if (this.canScrollHorizontally) {
|
|
@@ -67143,7 +67186,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67143
67186
|
this.adjustViewportZoneX();
|
|
67144
67187
|
}
|
|
67145
67188
|
/** Corrects the viewport's vertical offset based on the current structure
|
|
67146
|
-
* To make sure that at least
|
|
67189
|
+
* To make sure that at least one row is visible inside the viewport.
|
|
67147
67190
|
*/
|
|
67148
67191
|
adjustViewportOffsetY() {
|
|
67149
67192
|
if (this.canScrollVertically) {
|
|
@@ -67160,11 +67203,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67160
67203
|
const sheetId = this.sheetId;
|
|
67161
67204
|
this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
|
|
67162
67205
|
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
|
|
67206
|
+
if (!this.viewportWidth) {
|
|
67207
|
+
return;
|
|
67208
|
+
}
|
|
67163
67209
|
if (this.left === -1) {
|
|
67164
67210
|
this.left = this.boundaries.left;
|
|
67165
67211
|
}
|
|
67166
67212
|
if (this.right === -1) {
|
|
67167
|
-
this.right = this.
|
|
67213
|
+
this.right = this.boundaries.right;
|
|
67168
67214
|
}
|
|
67169
67215
|
this.offsetX =
|
|
67170
67216
|
this.getters.getColDimensions(sheetId, this.left).start -
|
|
@@ -67176,11 +67222,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67176
67222
|
const sheetId = this.sheetId;
|
|
67177
67223
|
this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
|
|
67178
67224
|
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
|
|
67225
|
+
if (!this.viewportHeight) {
|
|
67226
|
+
return;
|
|
67227
|
+
}
|
|
67179
67228
|
if (this.top === -1) {
|
|
67180
67229
|
this.top = this.boundaries.top;
|
|
67181
67230
|
}
|
|
67182
67231
|
if (this.bottom === -1) {
|
|
67183
|
-
this.bottom = this.
|
|
67232
|
+
this.bottom = this.boundaries.bottom;
|
|
67184
67233
|
}
|
|
67185
67234
|
this.offsetY =
|
|
67186
67235
|
this.getters.getRowDimensions(sheetId, this.top).start -
|
|
@@ -67254,7 +67303,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67254
67303
|
"isPositionVisible",
|
|
67255
67304
|
"getColDimensionsInViewport",
|
|
67256
67305
|
"getRowDimensionsInViewport",
|
|
67257
|
-
"
|
|
67306
|
+
"getAllActiveViewportsZonesAndRect",
|
|
67258
67307
|
"getRect",
|
|
67259
67308
|
];
|
|
67260
67309
|
viewports = {};
|
|
@@ -67484,12 +67533,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67484
67533
|
const sheetId = this.getters.getActiveSheetId();
|
|
67485
67534
|
const viewports = this.getSubViewports(sheetId);
|
|
67486
67535
|
//TODO ake another commit to eimprove this
|
|
67487
|
-
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
67536
|
+
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => col >= 0 && !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
67488
67537
|
}
|
|
67489
67538
|
getSheetViewVisibleRows() {
|
|
67490
67539
|
const sheetId = this.getters.getActiveSheetId();
|
|
67491
67540
|
const viewports = this.getSubViewports(sheetId);
|
|
67492
|
-
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
67541
|
+
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => row >= 0 && !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
67493
67542
|
}
|
|
67494
67543
|
/**
|
|
67495
67544
|
* Get the positions of all the cells that are visible in the viewport, taking merges into account.
|
|
@@ -67532,19 +67581,19 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67532
67581
|
maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
|
|
67533
67582
|
};
|
|
67534
67583
|
}
|
|
67535
|
-
getColRowOffsetInViewport(dimension,
|
|
67536
|
-
|
|
67537
|
-
|
|
67538
|
-
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
67539
|
-
if (index < referenceIndex) {
|
|
67540
|
-
return -this.getColRowOffsetInViewport(dimension, index, referenceIndex);
|
|
67584
|
+
getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
|
|
67585
|
+
if (targetHeaderIndex < referenceHeaderIndex) {
|
|
67586
|
+
return -this.getColRowOffsetInViewport(dimension, targetHeaderIndex, referenceHeaderIndex);
|
|
67541
67587
|
}
|
|
67588
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
67589
|
+
const visibleHeaders = dimension === "COL"
|
|
67590
|
+
? this.getters.getSheetViewVisibleCols()
|
|
67591
|
+
: this.getters.getSheetViewVisibleRows();
|
|
67592
|
+
const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
|
|
67593
|
+
const endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
|
|
67594
|
+
const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
|
|
67542
67595
|
let offset = 0;
|
|
67543
|
-
const
|
|
67544
|
-
for (let i = referenceIndex; i < index; i++) {
|
|
67545
|
-
if (!visibleIndexes.includes(i)) {
|
|
67546
|
-
continue;
|
|
67547
|
-
}
|
|
67596
|
+
for (const i of relevantIndexes) {
|
|
67548
67597
|
offset += this.getters.getHeaderSize(sheetId, dimension, i);
|
|
67549
67598
|
}
|
|
67550
67599
|
return offset;
|
|
@@ -67591,7 +67640,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67591
67640
|
}
|
|
67592
67641
|
return { canEdgeScroll, direction, delay };
|
|
67593
67642
|
}
|
|
67594
|
-
getEdgeScrollRow(y, previousY,
|
|
67643
|
+
getEdgeScrollRow(y, previousY, startingY) {
|
|
67595
67644
|
let canEdgeScroll = false;
|
|
67596
67645
|
let direction = 0;
|
|
67597
67646
|
let delay = 0;
|
|
@@ -67612,7 +67661,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67612
67661
|
delay = scrollDelay(y - height);
|
|
67613
67662
|
direction = 1;
|
|
67614
67663
|
}
|
|
67615
|
-
else if (y < offsetCorrectionY &&
|
|
67664
|
+
else if (y < offsetCorrectionY && startingY >= offsetCorrectionY && currentOffsetY > 0) {
|
|
67616
67665
|
// 2
|
|
67617
67666
|
canEdgeScroll = true;
|
|
67618
67667
|
delay = scrollDelay(offsetCorrectionY - y);
|
|
@@ -67638,13 +67687,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67638
67687
|
*/
|
|
67639
67688
|
getVisibleRectWithoutHeaders(zone) {
|
|
67640
67689
|
const sheetId = this.getters.getActiveSheetId();
|
|
67641
|
-
|
|
67642
|
-
.map((viewport) => viewport.getVisibleRect(zone))
|
|
67643
|
-
.filter(isDefined);
|
|
67644
|
-
if (viewportRects.length === 0) {
|
|
67645
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
67646
|
-
}
|
|
67647
|
-
return this.recomposeRect(viewportRects);
|
|
67690
|
+
return this.mapViewportsToRect(sheetId, (viewport) => viewport.getVisibleRect(zone));
|
|
67648
67691
|
}
|
|
67649
67692
|
/**
|
|
67650
67693
|
* Computes the actual size and position (:Rect) of the zone on the canvas
|
|
@@ -67652,13 +67695,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67652
67695
|
*/
|
|
67653
67696
|
getRect(zone) {
|
|
67654
67697
|
const sheetId = this.getters.getActiveSheetId();
|
|
67655
|
-
const
|
|
67656
|
-
.map((viewport) => viewport.getFullRect(zone))
|
|
67657
|
-
.filter(isDefined);
|
|
67658
|
-
if (viewportRects.length === 0) {
|
|
67659
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
67660
|
-
}
|
|
67661
|
-
const rect = this.recomposeRect(viewportRects);
|
|
67698
|
+
const rect = this.mapViewportsToRect(sheetId, (viewport) => viewport.getFullRect(zone));
|
|
67662
67699
|
return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
|
|
67663
67700
|
}
|
|
67664
67701
|
/**
|
|
@@ -67703,9 +67740,18 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67703
67740
|
end: start + (isRowHidden ? 0 : size),
|
|
67704
67741
|
};
|
|
67705
67742
|
}
|
|
67706
|
-
|
|
67743
|
+
getAllActiveViewportsZonesAndRect() {
|
|
67707
67744
|
const sheetId = this.getters.getActiveSheetId();
|
|
67708
|
-
return this.getSubViewports(sheetId)
|
|
67745
|
+
return this.getSubViewports(sheetId).map((viewport) => {
|
|
67746
|
+
return {
|
|
67747
|
+
zone: viewport,
|
|
67748
|
+
rect: {
|
|
67749
|
+
x: viewport.offsetCorrectionX + this.gridOffsetX,
|
|
67750
|
+
y: viewport.offsetCorrectionY + this.gridOffsetY,
|
|
67751
|
+
...viewport.getMaxSize(),
|
|
67752
|
+
},
|
|
67753
|
+
};
|
|
67754
|
+
});
|
|
67709
67755
|
}
|
|
67710
67756
|
// ---------------------------------------------------------------------------
|
|
67711
67757
|
// Private
|
|
@@ -67764,12 +67810,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67764
67810
|
}
|
|
67765
67811
|
/** gets rid of deprecated sheetIds */
|
|
67766
67812
|
cleanViewports() {
|
|
67767
|
-
const
|
|
67768
|
-
for (
|
|
67769
|
-
|
|
67770
|
-
delete this.viewports[sheetId];
|
|
67771
|
-
}
|
|
67813
|
+
const newViewport = {};
|
|
67814
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
67815
|
+
newViewport[sheetId] = this.viewports[sheetId];
|
|
67772
67816
|
}
|
|
67817
|
+
this.viewports = newViewport;
|
|
67773
67818
|
}
|
|
67774
67819
|
resizeSheetView(height, width, gridOffsetX = 0, gridOffsetY = 0) {
|
|
67775
67820
|
this.sheetViewHeight = height;
|
|
@@ -67779,7 +67824,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67779
67824
|
this.recomputeViewports();
|
|
67780
67825
|
}
|
|
67781
67826
|
recomputeViewports() {
|
|
67782
|
-
for (
|
|
67827
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
67783
67828
|
this.resetViewports(sheetId);
|
|
67784
67829
|
}
|
|
67785
67830
|
}
|
|
@@ -67801,8 +67846,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67801
67846
|
const { xSplit, ySplit } = this.getters.getPaneDivisions(sheetId);
|
|
67802
67847
|
const nCols = this.getters.getNumberCols(sheetId);
|
|
67803
67848
|
const nRows = this.getters.getNumberRows(sheetId);
|
|
67804
|
-
const colOffset = this.getters.getColRowOffset("COL", 0, xSplit, sheetId);
|
|
67805
|
-
const rowOffset = this.getters.getColRowOffset("ROW", 0, ySplit, sheetId);
|
|
67849
|
+
const colOffset = Math.min(this.getters.getColRowOffset("COL", 0, xSplit, sheetId), this.sheetViewWidth);
|
|
67850
|
+
const rowOffset = Math.min(this.getters.getColRowOffset("ROW", 0, ySplit, sheetId), this.sheetViewHeight);
|
|
67851
|
+
const unfrozenWidth = Math.max(this.sheetViewWidth - colOffset, 0);
|
|
67852
|
+
const unfrozenHeight = Math.max(this.sheetViewHeight - rowOffset, 0);
|
|
67806
67853
|
const { xRatio, yRatio } = this.getFrozenSheetViewRatio(sheetId);
|
|
67807
67854
|
const canScrollHorizontally = xRatio < 1.0;
|
|
67808
67855
|
const canScrollVertically = yRatio < 1.0;
|
|
@@ -67813,14 +67860,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67813
67860
|
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: 0, bottom: ySplit - 1 }, { width: colOffset, height: rowOffset }, { canScrollHorizontally: false, canScrollVertically: false }, { x: 0, y: 0 })) ||
|
|
67814
67861
|
undefined,
|
|
67815
67862
|
topRight: (ySplit &&
|
|
67816
|
-
new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width:
|
|
67863
|
+
new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width: unfrozenWidth, height: rowOffset }, { canScrollHorizontally, canScrollVertically: false }, { x: canScrollHorizontally ? previousOffset.x : 0, y: 0 })) ||
|
|
67817
67864
|
undefined,
|
|
67818
67865
|
bottomLeft: (xSplit &&
|
|
67819
|
-
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height:
|
|
67866
|
+
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height: unfrozenHeight }, { canScrollHorizontally: false, canScrollVertically }, { x: 0, y: canScrollVertically ? previousOffset.y : 0 })) ||
|
|
67820
67867
|
undefined,
|
|
67821
67868
|
bottomRight: new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: ySplit, bottom: nRows - 1 }, {
|
|
67822
|
-
width:
|
|
67823
|
-
height:
|
|
67869
|
+
width: unfrozenWidth,
|
|
67870
|
+
height: unfrozenHeight,
|
|
67824
67871
|
}, { canScrollHorizontally, canScrollVertically }, {
|
|
67825
67872
|
x: canScrollHorizontally ? previousOffset.x : 0,
|
|
67826
67873
|
y: canScrollVertically ? previousOffset.y : 0,
|
|
@@ -67897,12 +67944,26 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67897
67944
|
const height = this.sheetViewHeight + this.gridOffsetY;
|
|
67898
67945
|
return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
|
|
67899
67946
|
}
|
|
67900
|
-
|
|
67901
|
-
|
|
67902
|
-
|
|
67903
|
-
|
|
67904
|
-
|
|
67905
|
-
|
|
67947
|
+
mapViewportsToRect(sheetId, rectCallBack) {
|
|
67948
|
+
let x = Infinity;
|
|
67949
|
+
let y = Infinity;
|
|
67950
|
+
let width = 0;
|
|
67951
|
+
let height = 0;
|
|
67952
|
+
let hasViewports = false;
|
|
67953
|
+
for (const viewport of this.getSubViewports(sheetId)) {
|
|
67954
|
+
const rect = rectCallBack(viewport);
|
|
67955
|
+
if (rect) {
|
|
67956
|
+
hasViewports = true;
|
|
67957
|
+
x = Math.min(x, rect.x);
|
|
67958
|
+
y = Math.min(y, rect.y);
|
|
67959
|
+
width = Math.max(width, rect.x + rect.width);
|
|
67960
|
+
height = Math.max(height, rect.y + rect.height);
|
|
67961
|
+
}
|
|
67962
|
+
}
|
|
67963
|
+
if (!hasViewports) {
|
|
67964
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
67965
|
+
}
|
|
67966
|
+
return { x, y, width: width - x, height: height - y };
|
|
67906
67967
|
}
|
|
67907
67968
|
}
|
|
67908
67969
|
|
|
@@ -71521,6 +71582,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
71521
71582
|
observe(owner, callbacks) {
|
|
71522
71583
|
this.observers.set(owner, { owner, callbacks });
|
|
71523
71584
|
}
|
|
71585
|
+
detachObserver(owner) {
|
|
71586
|
+
this.observers.delete(owner);
|
|
71587
|
+
}
|
|
71524
71588
|
/**
|
|
71525
71589
|
* Capture the stream for yourself
|
|
71526
71590
|
*/
|
|
@@ -71613,6 +71677,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
71613
71677
|
observe(owner, callbacks) {
|
|
71614
71678
|
this.stream.observe(owner, callbacks);
|
|
71615
71679
|
}
|
|
71680
|
+
detachObserver(owner) {
|
|
71681
|
+
this.stream.detachObserver(owner);
|
|
71682
|
+
}
|
|
71616
71683
|
release(owner) {
|
|
71617
71684
|
if (this.stream.isListening(owner)) {
|
|
71618
71685
|
this.stream.release(owner);
|
|
@@ -75032,9 +75099,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
75032
75099
|
exports.tokenize = tokenize;
|
|
75033
75100
|
|
|
75034
75101
|
|
|
75035
|
-
__info__.version = "18.1.
|
|
75036
|
-
__info__.date = "2025-
|
|
75037
|
-
__info__.hash = "
|
|
75102
|
+
__info__.version = "18.1.6";
|
|
75103
|
+
__info__.date = "2025-02-05T07:18:57.089Z";
|
|
75104
|
+
__info__.hash = "f5b97e0";
|
|
75038
75105
|
|
|
75039
75106
|
|
|
75040
75107
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|