@odoo/o-spreadsheet 17.2.0-alpha.8 → 17.2.1

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.
@@ -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.0-alpha.8
7
- * @date 2024-03-15T11:01:01.388Z
8
- * @hash 11cf381
6
+ * @version 17.2.1
7
+ * @date 2024-03-25T09:41:58.737Z
8
+ * @hash f97284c
9
9
  */
10
10
 
11
11
  import { reactive, useEnv, useSubEnv, useState, onWillUnmount, markRaw, toRaw, Component, useRef, onMounted, useEffect, onPatched, useComponent, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv } from '@odoo/owl';
@@ -29,7 +29,6 @@ const DEFAULT_COLOR_SCALE_MIDPOINT_COLOR = 0xb6d7a8;
29
29
  const LINK_COLOR = "#017E84";
30
30
  const FILTERS_COLOR = "#188038";
31
31
  const BACKGROUND_HEADER_FILTER_COLOR = "#E6F4EA";
32
- const BACKGROUND_HEADER_SELECTED_FILTER_COLOR = "#CEEAD6";
33
32
  const SEPARATOR_COLOR = "#E0E2E4";
34
33
  const ICONS_COLOR = "#4A4F59";
35
34
  const HEADER_GROUPING_BACKGROUND_COLOR = "#F5F5F5";
@@ -640,21 +639,6 @@ function isConsecutive(iterable) {
640
639
  }
641
640
  return true;
642
641
  }
643
- class JetSet extends Set {
644
- addMany(iterable) {
645
- for (const element of iterable) {
646
- super.add(element);
647
- }
648
- return this;
649
- }
650
- deleteMany(iterable) {
651
- let wasDeleted = false;
652
- for (const element of iterable) {
653
- wasDeleted ||= super.delete(element);
654
- }
655
- return wasDeleted;
656
- }
657
- }
658
642
  /**
659
643
  * Creates a version of the function that's memoized on the value of its first
660
644
  * argument, if any.
@@ -4100,14 +4084,6 @@ function positions(zone) {
4100
4084
  }
4101
4085
  return positions;
4102
4086
  }
4103
- function forEachPositionsInZone(zone, callback) {
4104
- const { left, right, top, bottom } = zone;
4105
- for (let col = left; col <= right; col++) {
4106
- for (let row = top; row <= bottom; row++) {
4107
- callback(col, row);
4108
- }
4109
- }
4110
- }
4111
4087
  /**
4112
4088
  * This function returns a zone with coordinates modified according to the change
4113
4089
  * applied to the zone. It may be possible to change the zone by resizing or moving
@@ -8026,6 +8002,9 @@ class DependencyContainer {
8026
8002
  instantiate(Store, ...args) {
8027
8003
  return this.factory.build(Store, ...args);
8028
8004
  }
8005
+ resetStores() {
8006
+ this.dependencies.clear();
8007
+ }
8029
8008
  }
8030
8009
  class StoreFactory {
8031
8010
  get;
@@ -10053,6 +10032,9 @@ function makeArg(str, description) {
10053
10032
  result.default = true;
10054
10033
  result.defaultValue = defaultValue;
10055
10034
  }
10035
+ if (types.some((t) => t.startsWith("RANGE"))) {
10036
+ result.acceptMatrix = true;
10037
+ }
10056
10038
  return result;
10057
10039
  }
10058
10040
  /**
@@ -18623,11 +18605,27 @@ class FunctionRegistry extends Registry {
18623
18605
  }
18624
18606
  const descr = addMetaInfoFromArg(addDescr);
18625
18607
  validateArguments(descr.args);
18626
- this.mapping[name] = addErrorHandling(addResultHandling(descr.compute), name);
18608
+ this.mapping[name] = addErrorHandling(addResultHandling(addInputHandling(descr)), name);
18627
18609
  super.add(name, descr);
18628
18610
  return this;
18629
18611
  }
18630
18612
  }
18613
+ function addInputHandling(descr) {
18614
+ function computeWithInputHandling(...args) {
18615
+ for (let i = 0; i < args.length; i++) {
18616
+ const argDefinition = descr.args[descr.getArgToFocus(i + 1) - 1];
18617
+ const arg = args[i];
18618
+ if (isMatrix(arg) && !argDefinition.acceptMatrix) {
18619
+ if (arg.length !== 1 || arg[0].length !== 1) {
18620
+ throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects the parameter '%s' to be a single value or a single cell reference, not a range.", argDefinition.name));
18621
+ }
18622
+ args[i] = arg[0][0];
18623
+ }
18624
+ }
18625
+ return descr.compute.apply(this, args);
18626
+ }
18627
+ return computeWithInputHandling;
18628
+ }
18631
18629
  function addErrorHandling(compute, functionName) {
18632
18630
  return function (...args) {
18633
18631
  try {
@@ -24217,14 +24215,19 @@ const categorieFunctionAll = {
24217
24215
  children: [allFunctionListMenuBuilder],
24218
24216
  };
24219
24217
  function allFunctionListMenuBuilder() {
24220
- const fnNames = functionRegistry.getKeys();
24218
+ const fnNames = functionRegistry.getKeys().filter((key) => !functionRegistry.get(key).hidden);
24221
24219
  return createFormulaFunctions(fnNames);
24222
24220
  }
24223
24221
  const categoriesFunctionListMenuBuilder = () => {
24224
24222
  const functions = functionRegistry.content;
24225
- const categories = [...new Set(functionRegistry.getAll().map((fn) => fn.category))].filter(isDefined$1);
24223
+ const categories = [
24224
+ ...new Set(functionRegistry
24225
+ .getAll()
24226
+ .filter((fn) => !fn.hidden)
24227
+ .map((fn) => fn.category)),
24228
+ ].filter(isDefined$1);
24226
24229
  return categories.sort().map((category, i) => {
24227
- const functionsInCategory = Object.keys(functions).filter((key) => functions[key].category === category);
24230
+ const functionsInCategory = Object.keys(functions).filter((key) => functions[key].category === category && !functions[key].hidden);
24228
24231
  return {
24229
24232
  name: category,
24230
24233
  children: createFormulaFunctions(functionsInCategory),
@@ -28382,11 +28385,9 @@ css /* scss */ `
28382
28385
  }
28383
28386
  .o-cell-is-operator {
28384
28387
  margin-bottom: 5px;
28385
- width: 96%;
28386
28388
  }
28387
28389
  .o-cell-is-value {
28388
28390
  margin-bottom: 5px;
28389
- width: 96%;
28390
28391
  }
28391
28392
  .o-color-picker-widget .o-color-picker-button {
28392
28393
  pointer-events: all;
@@ -31088,6 +31089,9 @@ class FigureComponent extends Component {
31088
31089
  el?.focus({ preventScroll: true });
31089
31090
  }
31090
31091
  }, () => [this.env.model.getters.getSelectedFigureId(), this.props.figure.id, this.figureRef.el]);
31092
+ onWillUnmount(() => {
31093
+ this.props.onFigureDeleted();
31094
+ });
31091
31095
  }
31092
31096
  clickAnchor(dirX, dirY, ev) {
31093
31097
  this.props.onClickAnchor(dirX, dirY, ev);
@@ -31106,6 +31110,7 @@ class FigureComponent extends Component {
31106
31110
  this.props.onFigureDeleted();
31107
31111
  ev.stopPropagation();
31108
31112
  ev.preventDefault();
31113
+ ev.stopPropagation();
31109
31114
  break;
31110
31115
  case "ArrowDown":
31111
31116
  case "ArrowLeft":
@@ -31126,6 +31131,7 @@ class FigureComponent extends Component {
31126
31131
  });
31127
31132
  ev.stopPropagation();
31128
31133
  ev.preventDefault();
31134
+ ev.stopPropagation();
31129
31135
  break;
31130
31136
  }
31131
31137
  }
@@ -31793,6 +31799,7 @@ function compareContentToSpanElement(content, node) {
31793
31799
  // -----------------------------------------------------------------------------
31794
31800
  css /* scss */ `
31795
31801
  .o-formula-assistant {
31802
+ background: #ffffff;
31796
31803
  .o-formula-assistant-head {
31797
31804
  background-color: #f2f2f2;
31798
31805
  padding: 10px;
@@ -31848,6 +31855,9 @@ class FunctionDescriptionProvider extends Component {
31848
31855
  this.assistantState.allowCellSelectionBehind = false;
31849
31856
  }, 2000);
31850
31857
  }
31858
+ get formulaArgSeparator() {
31859
+ return this.env.model.getters.getLocale().formulaArgSeparator + " ";
31860
+ }
31851
31861
  }
31852
31862
 
31853
31863
  const functions$2 = functionRegistry.content;
@@ -34617,19 +34627,16 @@ class GridRenderer {
34617
34627
  for (let col = left; col <= right; col++) {
34618
34628
  const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
34619
34629
  const { x, width } = this.getters.getVisibleRect(colZone);
34620
- const colHasFilter = this.getters.doesZonesContainFilter(sheetId, [colZone]);
34621
34630
  const isColActive = activeCols.has(col);
34622
34631
  const isColSelected = selectedCols.has(col);
34623
34632
  if (isColActive) {
34624
- ctx.fillStyle = colHasFilter ? FILTERS_COLOR : BACKGROUND_HEADER_ACTIVE_COLOR;
34633
+ ctx.fillStyle = BACKGROUND_HEADER_ACTIVE_COLOR;
34625
34634
  }
34626
34635
  else if (isColSelected) {
34627
- ctx.fillStyle = colHasFilter
34628
- ? BACKGROUND_HEADER_SELECTED_FILTER_COLOR
34629
- : BACKGROUND_HEADER_SELECTED_COLOR;
34636
+ ctx.fillStyle = BACKGROUND_HEADER_SELECTED_COLOR;
34630
34637
  }
34631
34638
  else {
34632
- ctx.fillStyle = colHasFilter ? BACKGROUND_HEADER_FILTER_COLOR : BACKGROUND_HEADER_COLOR;
34639
+ ctx.fillStyle = BACKGROUND_HEADER_COLOR;
34633
34640
  }
34634
34641
  ctx.fillRect(x, 0, width, HEADER_HEIGHT);
34635
34642
  }
@@ -34637,19 +34644,16 @@ class GridRenderer {
34637
34644
  for (let row = top; row <= bottom; row++) {
34638
34645
  const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
34639
34646
  const { y, height } = this.getters.getVisibleRect(rowZone);
34640
- const rowHasFilter = this.getters.doesZonesContainFilter(sheetId, [rowZone]);
34641
34647
  const isRowActive = activeRows.has(row);
34642
34648
  const isRowSelected = selectedRows.has(row);
34643
34649
  if (isRowActive) {
34644
- ctx.fillStyle = rowHasFilter ? FILTERS_COLOR : BACKGROUND_HEADER_ACTIVE_COLOR;
34650
+ ctx.fillStyle = BACKGROUND_HEADER_ACTIVE_COLOR;
34645
34651
  }
34646
34652
  else if (isRowSelected) {
34647
- ctx.fillStyle = rowHasFilter
34648
- ? BACKGROUND_HEADER_SELECTED_FILTER_COLOR
34649
- : BACKGROUND_HEADER_SELECTED_COLOR;
34653
+ ctx.fillStyle = BACKGROUND_HEADER_SELECTED_COLOR;
34650
34654
  }
34651
34655
  else {
34652
- ctx.fillStyle = rowHasFilter ? BACKGROUND_HEADER_FILTER_COLOR : BACKGROUND_HEADER_COLOR;
34656
+ ctx.fillStyle = BACKGROUND_HEADER_COLOR;
34653
34657
  }
34654
34658
  ctx.fillRect(0, y, HEADER_WIDTH, height);
34655
34659
  }
@@ -44822,7 +44826,6 @@ class SheetPlugin extends CorePlugin {
44822
44826
 
44823
44827
  class TablePlugin extends CorePlugin {
44824
44828
  static getters = [
44825
- "doesZonesContainFilter",
44826
44829
  "getFilter",
44827
44830
  "getFilters",
44828
44831
  "getTable",
@@ -44979,10 +44982,6 @@ class TablePlugin extends CorePlugin {
44979
44982
  getTablesOverlappingZones(sheetId, zones) {
44980
44983
  return this.getTables(sheetId).filter((table) => zones.some((zone) => overlap(table.range.zone, zone)));
44981
44984
  }
44982
- doesZonesContainFilter(sheetId, zones) {
44983
- return (this.getTablesOverlappingZones(sheetId, zones).filter((table) => table.config.hasFilters)
44984
- .length > 0);
44985
- }
44986
44985
  getFilterHeaders(sheetId) {
44987
44986
  const headers = [];
44988
44987
  for (const table of this.getTables(sheetId)) {
@@ -45849,6 +45848,41 @@ class CompilationParametersBuilder {
45849
45848
  }
45850
45849
  }
45851
45850
 
45851
+ class PositionMap {
45852
+ map = {};
45853
+ set({ sheetId, col, row }, value) {
45854
+ const map = this.map;
45855
+ if (!map[sheetId]) {
45856
+ map[sheetId] = {};
45857
+ }
45858
+ if (!map[sheetId][col]) {
45859
+ map[sheetId][col] = {};
45860
+ }
45861
+ map[sheetId][col][row] = value;
45862
+ }
45863
+ get({ sheetId, col, row }) {
45864
+ return this.map[sheetId]?.[col]?.[row];
45865
+ }
45866
+ has({ sheetId, col, row }) {
45867
+ return this.map[sheetId]?.[col]?.[row] !== undefined;
45868
+ }
45869
+ delete({ sheetId, col, row }) {
45870
+ delete this.map[sheetId]?.[col]?.[row];
45871
+ }
45872
+ keys() {
45873
+ const map = this.map;
45874
+ const keys = [];
45875
+ for (const sheetId in map) {
45876
+ for (const col in map[sheetId]) {
45877
+ for (const row in map[sheetId][col]) {
45878
+ keys.push({ sheetId, col: parseInt(col), row: parseInt(row) });
45879
+ }
45880
+ }
45881
+ }
45882
+ return keys;
45883
+ }
45884
+ }
45885
+
45852
45886
  function quickselect(arr, k, left, right, compare) {
45853
45887
  quickselectStep(arr, k, left || 0, right || (arr.length - 1), compare || defaultCompare);
45854
45888
  }
@@ -46575,26 +46609,26 @@ class ZoneRBush extends RBush {
46575
46609
  * It uses an R-Tree data structure to efficiently find dependent cells.
46576
46610
  */
46577
46611
  class FormulaDependencyGraph {
46578
- encoder;
46579
- dependencies = new Map();
46612
+ createEmptyPositionSet;
46613
+ dependencies = new PositionMap();
46580
46614
  rTree;
46581
- constructor(encoder, data = []) {
46582
- this.encoder = encoder;
46615
+ constructor(createEmptyPositionSet, data = []) {
46616
+ this.createEmptyPositionSet = createEmptyPositionSet;
46583
46617
  this.rTree = new SpreadsheetRTree(data);
46584
46618
  }
46585
- removeAllDependencies(formulaPositionId) {
46586
- const ranges = this.dependencies.get(formulaPositionId);
46619
+ removeAllDependencies(formulaPosition) {
46620
+ const ranges = this.dependencies.get(formulaPosition);
46587
46621
  if (!ranges) {
46588
46622
  return;
46589
46623
  }
46590
46624
  for (const range of ranges) {
46591
46625
  this.rTree.remove(range);
46592
46626
  }
46593
- this.dependencies.delete(formulaPositionId);
46627
+ this.dependencies.delete(formulaPosition);
46594
46628
  }
46595
- addDependencies(formulaPositionId, dependencies) {
46629
+ addDependencies(formulaPosition, dependencies) {
46596
46630
  const rTreeItems = dependencies.map(({ sheetId, zone }) => ({
46597
- data: formulaPositionId,
46631
+ data: formulaPosition,
46598
46632
  boundingBox: {
46599
46633
  zone,
46600
46634
  sheetId,
@@ -46603,12 +46637,12 @@ class FormulaDependencyGraph {
46603
46637
  for (const item of rTreeItems) {
46604
46638
  this.rTree.insert(item);
46605
46639
  }
46606
- const existingDependencies = this.dependencies.get(formulaPositionId);
46640
+ const existingDependencies = this.dependencies.get(formulaPosition);
46607
46641
  if (existingDependencies) {
46608
46642
  existingDependencies.push(...rTreeItems);
46609
46643
  }
46610
46644
  else {
46611
- this.dependencies.set(formulaPositionId, rTreeItems);
46645
+ this.dependencies.set(formulaPosition, rTreeItems);
46612
46646
  }
46613
46647
  }
46614
46648
  /**
@@ -46617,23 +46651,194 @@ class FormulaDependencyGraph {
46617
46651
  * This is called a topological ordering (excluding cycles)
46618
46652
  */
46619
46653
  getCellsDependingOn(ranges) {
46620
- const visited = new JetSet();
46654
+ const visited = this.createEmptyPositionSet();
46621
46655
  const queue = Array.from(ranges).reverse();
46622
46656
  while (queue.length > 0) {
46623
46657
  const range = queue.pop();
46624
- visited.addMany(this.encoder.encodeBoundingBox(range));
46625
- const impactedPositionIds = this.rTree.search(range).map((dep) => dep.data);
46626
- for (const positionId of impactedPositionIds) {
46627
- if (!visited.has(positionId)) {
46628
- queue.push(this.encoder.decodeToBoundingBox(positionId));
46658
+ visited.addMany(positions(range.zone).map((position) => ({ sheetId: range.sheetId, ...position })));
46659
+ const impactedPositions = this.rTree.search(range).map((dep) => dep.data);
46660
+ for (const position of impactedPositions) {
46661
+ if (!visited.has(position)) {
46662
+ queue.push({ sheetId: position.sheetId, zone: positionToZone(position) });
46629
46663
  }
46630
46664
  }
46631
46665
  }
46632
- visited.deleteMany(ranges.flatMap((r) => this.encoder.encodeBoundingBox(r)));
46666
+ visited.deleteMany(ranges.flatMap((r) => positions(r.zone).map((position) => ({ sheetId: r.sheetId, ...position }))));
46633
46667
  return visited;
46634
46668
  }
46635
46669
  }
46636
46670
 
46671
+ /**
46672
+ * Implements a fixed-sized grid or 2D matrix of bits.
46673
+ * based on https://github.com/zandaqo/structurae
46674
+ *
46675
+ * The grid is implemented as a 1D array of 32-bit integers, where each bit represents a cell in the grid.
46676
+ * It follows row-major order, with each row stored consecutively in 32-bit blocks.
46677
+ * Pads the number of columns to the next power of 2 to allow quick lookups with bitwise operations.
46678
+ *
46679
+ * Key terminology:
46680
+ * - bucket: Index of an item in the Uint32Array, a 32-bit integer.
46681
+ * - bitPosition: The position of a bit within the bucket 32-bit integer.
46682
+ */
46683
+ class BinaryGrid extends Uint32Array {
46684
+ columnOffset = 0;
46685
+ cols = 0;
46686
+ rows = 0;
46687
+ /**
46688
+ * Creates a binary grid of specified dimensions.
46689
+ */
46690
+ static create(rows, columns) {
46691
+ const columnOffset = log2Ceil(columns);
46692
+ const length = (rows << columnOffset) >> 5;
46693
+ const grid = new this(length + 1);
46694
+ grid.columnOffset = columnOffset;
46695
+ grid.cols = columns;
46696
+ grid.rows = rows;
46697
+ return grid;
46698
+ }
46699
+ /**
46700
+ * Returns the bit at given coordinates.
46701
+ */
46702
+ getValue(position) {
46703
+ const [bucket, bitPosition] = this.getCoordinates(position);
46704
+ return ((this[bucket] >> bitPosition) & 1);
46705
+ }
46706
+ /**
46707
+ * Sets the bit at given coordinates.
46708
+ */
46709
+ setValue(position, value) {
46710
+ const [bucket, bitPosition] = this.getCoordinates(position);
46711
+ const currentValue = (this[bucket] >> bitPosition) & 1;
46712
+ const hasBeenInserted = currentValue === 0 && value === 1;
46713
+ this[bucket] = (this[bucket] & ~(1 << bitPosition)) | (value << bitPosition);
46714
+ return hasBeenInserted;
46715
+ // Let's breakdown of the above line:
46716
+ // with an example with a 4-bit integer (instead of 32-bit).
46717
+ //
46718
+ // Let's say we want to set the bit at position 2 to 1 and the existing
46719
+ // bit sequence this[bucket] is 1001. The final bit sequence should be 1101.
46720
+ //
46721
+ // First, we clear the bit at position 2 by AND-ing this[bucket] with a
46722
+ // mask having all 1s except a 0 at the bit position (~ (1 << bitPosition)).
46723
+ // 1 << bitPosition is 0100 (shifting 0001 to the left by 2)
46724
+ // Inverting the bits with ~ gives the final mask ~(1 << bitPosition): 1011
46725
+ //
46726
+ // Then, we shift the value by the bit position (value << bitPosition: 0100)
46727
+ // and OR the result with the previous step's result:
46728
+ // (1001 & 1011) | 0100 = 1101
46729
+ }
46730
+ isEmpty() {
46731
+ return !this.some((bucket) => bucket !== 0);
46732
+ }
46733
+ fillAllPositions() {
46734
+ const thirtyTwoOnes = -1 >>> 0; // same as 2 ** 32 - 1, a 32-bit number with all bits set to 1
46735
+ this.fill(thirtyTwoOnes);
46736
+ }
46737
+ clear() {
46738
+ this.fill(0);
46739
+ }
46740
+ getCoordinates(position) {
46741
+ const { row, col } = position;
46742
+ const index = (row << this.columnOffset) + col;
46743
+ const bucket = index >> 5;
46744
+ return [bucket, index - (bucket << 5)];
46745
+ }
46746
+ }
46747
+ function log2Ceil(value) {
46748
+ // A faster version of Math.ceil(Math.log2(value)).
46749
+ if (value === 0) {
46750
+ return -Infinity;
46751
+ }
46752
+ else if (value < 0) {
46753
+ return NaN;
46754
+ }
46755
+ // --value handles the case where value is a power of 2
46756
+ return 32 - Math.clz32(--value);
46757
+ }
46758
+
46759
+ class PositionSet {
46760
+ sheets = {};
46761
+ /**
46762
+ * List of positions in the order they were inserted.
46763
+ */
46764
+ insertions = [];
46765
+ maxSize = 0;
46766
+ constructor(sheetSizes) {
46767
+ for (const sheetId in sheetSizes) {
46768
+ const cols = sheetSizes[sheetId].cols;
46769
+ const rows = sheetSizes[sheetId].rows;
46770
+ this.maxSize += cols * rows;
46771
+ this.sheets[sheetId] = BinaryGrid.create(rows, cols);
46772
+ }
46773
+ }
46774
+ add(position) {
46775
+ const hasBeenInserted = this.sheets[position.sheetId].setValue(position, 1);
46776
+ if (hasBeenInserted) {
46777
+ this.insertions.push(position);
46778
+ }
46779
+ }
46780
+ addMany(positions) {
46781
+ for (const position of positions) {
46782
+ this.add(position);
46783
+ }
46784
+ }
46785
+ delete(position) {
46786
+ this.sheets[position.sheetId].setValue(position, 0);
46787
+ }
46788
+ deleteMany(positions) {
46789
+ for (const position of positions) {
46790
+ this.delete(position);
46791
+ }
46792
+ }
46793
+ has(position) {
46794
+ return this.sheets[position.sheetId].getValue(position) === 1;
46795
+ }
46796
+ clear() {
46797
+ const insertions = this.insertions;
46798
+ this.insertions = [];
46799
+ for (const sheetId in this.sheets) {
46800
+ this.sheets[sheetId].clear();
46801
+ }
46802
+ return insertions;
46803
+ }
46804
+ isEmpty() {
46805
+ if (this.insertions.length === 0) {
46806
+ return true;
46807
+ }
46808
+ for (const sheetId in this.sheets) {
46809
+ if (!this.sheets[sheetId].isEmpty()) {
46810
+ return false;
46811
+ }
46812
+ }
46813
+ return true;
46814
+ }
46815
+ fillAllPositions() {
46816
+ this.insertions = new Array(this.maxSize);
46817
+ let index = 0;
46818
+ for (const sheetId in this.sheets) {
46819
+ const grid = this.sheets[sheetId];
46820
+ grid.fillAllPositions();
46821
+ for (let i = 0; i < grid.rows; i++) {
46822
+ for (let j = 0; j < grid.cols; j++) {
46823
+ this.insertions[index++] = { sheetId, row: i, col: j };
46824
+ }
46825
+ }
46826
+ }
46827
+ }
46828
+ /**
46829
+ * Iterate over the positions in the order of insertion.
46830
+ * Note that the same position may be yielded multiple times if the value was added
46831
+ * to the set then removed and then added again.
46832
+ */
46833
+ *[Symbol.iterator]() {
46834
+ for (const position of this.insertions) {
46835
+ if (this.sheets[position.sheetId].getValue(position) === 1) {
46836
+ yield position;
46837
+ }
46838
+ }
46839
+ }
46840
+ }
46841
+
46637
46842
  /**
46638
46843
  * Contains, for each cell, the array
46639
46844
  * formulas that could potentially spread on it
@@ -46647,6 +46852,7 @@ class FormulaDependencyGraph {
46647
46852
  *
46648
46853
  */
46649
46854
  class SpreadingRelation {
46855
+ createEmptyPositionSet;
46650
46856
  /**
46651
46857
  * Internal structure:
46652
46858
  * For something like
@@ -46675,39 +46881,42 @@ class SpreadingRelation {
46675
46881
  * - (B1) --> (B2, B3, B4) meaning B1 spreads on B2, B3 and B4
46676
46882
  *
46677
46883
  */
46678
- resultsToArrayFormulas = new Map();
46679
- arrayFormulasToResults = new Map();
46680
- getFormulaPositionsSpreadingOn(resultPositionId) {
46681
- return this.resultsToArrayFormulas.get(resultPositionId) || EMPTY_ARRAY;
46884
+ resultsToArrayFormulas = new PositionMap();
46885
+ arrayFormulasToResults = new PositionMap();
46886
+ constructor(createEmptyPositionSet) {
46887
+ this.createEmptyPositionSet = createEmptyPositionSet;
46888
+ }
46889
+ getFormulaPositionsSpreadingOn(resultPosition) {
46890
+ return this.resultsToArrayFormulas.get(resultPosition) || EMPTY_ARRAY;
46682
46891
  }
46683
- getArrayResultPositionIds(formulasPositionId) {
46684
- return this.arrayFormulasToResults.get(formulasPositionId) || EMPTY_ARRAY;
46892
+ getArrayResultPositions(formulasPosition) {
46893
+ return this.arrayFormulasToResults.get(formulasPosition) || EMPTY_ARRAY;
46685
46894
  }
46686
46895
  /**
46687
46896
  * Remove a node, also remove it from other nodes adjacency list
46688
46897
  */
46689
- removeNode(positionId) {
46690
- this.resultsToArrayFormulas.delete(positionId);
46691
- this.arrayFormulasToResults.delete(positionId);
46898
+ removeNode(position) {
46899
+ this.resultsToArrayFormulas.delete(position);
46900
+ this.arrayFormulasToResults.delete(position);
46692
46901
  }
46693
46902
  /**
46694
46903
  * Create a spreading relation between two cells
46695
46904
  */
46696
- addRelation({ arrayFormulaPositionId, resultPositionId, }) {
46697
- if (!this.resultsToArrayFormulas.has(resultPositionId)) {
46698
- this.resultsToArrayFormulas.set(resultPositionId, new Set());
46905
+ addRelation({ arrayFormulaPosition, resultPosition, }) {
46906
+ if (!this.resultsToArrayFormulas.has(resultPosition)) {
46907
+ this.resultsToArrayFormulas.set(resultPosition, this.createEmptyPositionSet());
46699
46908
  }
46700
- this.resultsToArrayFormulas.get(resultPositionId)?.add(arrayFormulaPositionId);
46701
- if (!this.arrayFormulasToResults.has(arrayFormulaPositionId)) {
46702
- this.arrayFormulasToResults.set(arrayFormulaPositionId, new Set());
46909
+ this.resultsToArrayFormulas.get(resultPosition)?.add(arrayFormulaPosition);
46910
+ if (!this.arrayFormulasToResults.has(arrayFormulaPosition)) {
46911
+ this.arrayFormulasToResults.set(arrayFormulaPosition, this.createEmptyPositionSet());
46703
46912
  }
46704
- this.arrayFormulasToResults.get(arrayFormulaPositionId)?.add(resultPositionId);
46913
+ this.arrayFormulasToResults.get(arrayFormulaPosition)?.add(resultPosition);
46705
46914
  }
46706
- hasArrayFormulaResult(positionId) {
46707
- return this.resultsToArrayFormulas.has(positionId);
46915
+ hasArrayFormulaResult(position) {
46916
+ return this.resultsToArrayFormulas.has(position);
46708
46917
  }
46709
- isArrayFormula(positionId) {
46710
- return this.arrayFormulasToResults.has(positionId);
46918
+ isArrayFormula(position) {
46919
+ return this.arrayFormulasToResults.has(position);
46711
46920
  }
46712
46921
  }
46713
46922
  const EMPTY_ARRAY = [];
@@ -46719,50 +46928,41 @@ class Evaluator {
46719
46928
  context;
46720
46929
  getters;
46721
46930
  compilationParams;
46722
- encoder = new PositionBitsEncoder();
46723
- evaluatedCells = new Map();
46724
- formulaDependencies = lazy(new FormulaDependencyGraph(this.encoder));
46725
- blockedArrayFormulas = new Set();
46726
- spreadingRelations = new SpreadingRelation();
46931
+ evaluatedCells = new PositionMap();
46932
+ formulaDependencies = lazy(new FormulaDependencyGraph(this.createEmptyPositionSet.bind(this)));
46933
+ blockedArrayFormulas = new PositionSet({});
46934
+ spreadingRelations = new SpreadingRelation(this.createEmptyPositionSet.bind(this));
46727
46935
  constructor(context, getters) {
46728
46936
  this.context = context;
46729
46937
  this.getters = getters;
46730
46938
  this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
46731
46939
  }
46732
46940
  getEvaluatedCell(position) {
46733
- return this.evaluatedCells.get(this.encoder.encode(position)) || EMPTY_CELL;
46941
+ return this.evaluatedCells.get(position) || EMPTY_CELL;
46734
46942
  }
46735
46943
  getSpreadPositionsOf(position) {
46736
- const positionId = this.encoder.encode(position);
46737
- if (!this.spreadingRelations.isArrayFormula(positionId)) {
46944
+ if (!this.spreadingRelations.isArrayFormula(position)) {
46738
46945
  return [];
46739
46946
  }
46740
- return Array.from(this.spreadingRelations.getArrayResultPositionIds(positionId)).map((positionId) => this.encoder.decode(positionId));
46741
- }
46742
- getArrayFormulaSpreadingOn(position) {
46743
- const positionId = this.encoder.encode(position);
46744
- const formulaPosition = this.getArrayFormulaSpreadingOnId(positionId);
46745
- return formulaPosition !== undefined ? this.encoder.decode(formulaPosition) : undefined;
46947
+ return Array.from(this.spreadingRelations.getArrayResultPositions(position));
46746
46948
  }
46747
46949
  getEvaluatedPositions() {
46748
- return [...this.evaluatedCells.keys()].map((p) => this.encoder.decode(p));
46950
+ return this.evaluatedCells.keys();
46749
46951
  }
46750
- getArrayFormulaSpreadingOnId(positionId) {
46751
- if (!this.spreadingRelations.hasArrayFormulaResult(positionId)) {
46952
+ getArrayFormulaSpreadingOn(position) {
46953
+ if (!this.spreadingRelations.hasArrayFormulaResult(position)) {
46752
46954
  return undefined;
46753
46955
  }
46754
- const arrayFormulas = this.spreadingRelations.getFormulaPositionsSpreadingOn(positionId);
46755
- return Array.from(arrayFormulas).find((positionId) => !this.blockedArrayFormulas.has(positionId));
46956
+ const arrayFormulas = this.spreadingRelations.getFormulaPositionsSpreadingOn(position);
46957
+ return Array.from(arrayFormulas).find((position) => !this.blockedArrayFormulas.has(position));
46756
46958
  }
46757
46959
  updateDependencies(position) {
46758
- const positionId = this.encoder.encode(position);
46759
- this.formulaDependencies().removeAllDependencies(positionId);
46760
- const dependencies = this.getDirectDependencies(positionId);
46761
- this.formulaDependencies().addDependencies(positionId, dependencies);
46960
+ this.formulaDependencies().removeAllDependencies(position);
46961
+ const dependencies = this.getDirectDependencies(position);
46962
+ this.formulaDependencies().addDependencies(position, dependencies);
46762
46963
  }
46763
46964
  addDependencies(position, dependencies) {
46764
- const positionId = this.encoder.encode(position);
46765
- this.formulaDependencies().addDependencies(positionId, dependencies);
46965
+ this.formulaDependencies().addDependencies(position, dependencies);
46766
46966
  }
46767
46967
  updateCompilationParameters() {
46768
46968
  // rebuild the compilation parameters (with a clean cache)
@@ -46770,47 +46970,57 @@ class Evaluator {
46770
46970
  this.compilationParams.evalContext.updateDependencies = this.updateDependencies.bind(this);
46771
46971
  this.compilationParams.evalContext.addDependencies = this.addDependencies.bind(this);
46772
46972
  }
46973
+ createEmptyPositionSet() {
46974
+ const sheetSizes = {};
46975
+ for (const sheetId of this.getters.getSheetIds()) {
46976
+ sheetSizes[sheetId] = {
46977
+ rows: this.getters.getNumberRows(sheetId),
46978
+ cols: this.getters.getNumberCols(sheetId),
46979
+ };
46980
+ }
46981
+ return new PositionSet(sheetSizes);
46982
+ }
46773
46983
  evaluateCells(positions) {
46774
- const cells = positions.map((p) => this.encoder.encode(p));
46775
- const cellsToCompute = new JetSet(cells);
46776
- const arrayFormulasPositionIds = this.getArrayFormulasImpactedByChangesOf(cells);
46777
- cellsToCompute.addMany(this.getCellsDependingOn(cells));
46778
- cellsToCompute.addMany(arrayFormulasPositionIds);
46779
- cellsToCompute.addMany(this.getCellsDependingOn(arrayFormulasPositionIds));
46984
+ const cellsToCompute = this.createEmptyPositionSet();
46985
+ cellsToCompute.addMany(positions);
46986
+ const arrayFormulasPositions = this.getArrayFormulasImpactedByChangesOf(positions);
46987
+ cellsToCompute.addMany(this.getCellsDependingOn(positions));
46988
+ cellsToCompute.addMany(arrayFormulasPositions);
46989
+ cellsToCompute.addMany(this.getCellsDependingOn(arrayFormulasPositions));
46780
46990
  this.evaluate(cellsToCompute);
46781
46991
  }
46782
- getArrayFormulasImpactedByChangesOf(positionIds) {
46783
- const impactedPositionIds = new JetSet();
46784
- for (const positionId of positionIds) {
46785
- const content = this.getCell(positionId)?.content;
46786
- const arrayFormulaPositionId = this.getArrayFormulaSpreadingOnId(positionId);
46787
- if (arrayFormulaPositionId !== undefined) {
46992
+ getArrayFormulasImpactedByChangesOf(positions) {
46993
+ const impactedPositions = this.createEmptyPositionSet();
46994
+ for (const position of positions) {
46995
+ const content = this.getters.getCell(position)?.content;
46996
+ const arrayFormulaPosition = this.getArrayFormulaSpreadingOn(position);
46997
+ if (arrayFormulaPosition !== undefined) {
46788
46998
  // take into account new collisions.
46789
- impactedPositionIds.add(arrayFormulaPositionId);
46999
+ impactedPositions.add(arrayFormulaPosition);
46790
47000
  }
46791
47001
  if (!content) {
46792
47002
  // The previous content could have blocked some array formulas
46793
- impactedPositionIds.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(positionId));
47003
+ impactedPositions.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(position));
46794
47004
  }
46795
47005
  }
46796
- return impactedPositionIds;
47006
+ return impactedPositions;
46797
47007
  }
46798
47008
  buildDependencyGraph() {
46799
- this.blockedArrayFormulas = new Set();
46800
- this.spreadingRelations = new SpreadingRelation();
47009
+ this.blockedArrayFormulas = this.createEmptyPositionSet();
47010
+ this.spreadingRelations = new SpreadingRelation(this.createEmptyPositionSet.bind(this));
46801
47011
  this.formulaDependencies = lazy(() => {
46802
- const dependencies = [...this.getAllCells()].flatMap((positionId) => this.getDirectDependencies(positionId).map((range) => ({
46803
- data: positionId,
47012
+ const dependencies = [...this.getAllCells()].flatMap((position) => this.getDirectDependencies(position).map((range) => ({
47013
+ data: position,
46804
47014
  boundingBox: {
46805
47015
  zone: range.zone,
46806
47016
  sheetId: range.sheetId,
46807
47017
  },
46808
47018
  })));
46809
- return new FormulaDependencyGraph(this.encoder, dependencies);
47019
+ return new FormulaDependencyGraph(this.createEmptyPositionSet.bind(this), dependencies);
46810
47020
  });
46811
47021
  }
46812
47022
  evaluateAllCells() {
46813
- this.evaluatedCells = new Map();
47023
+ this.evaluatedCells = new PositionMap();
46814
47024
  this.evaluate(this.getAllCells());
46815
47025
  }
46816
47026
  evaluateFormula(sheetId, formulaString) {
@@ -46827,57 +47037,50 @@ class Evaluator {
46827
47037
  return result.value;
46828
47038
  }
46829
47039
  getAllCells() {
46830
- const positionIds = new JetSet();
46831
- for (const sheetId of this.getters.getSheetIds()) {
46832
- const cellIds = this.getters.getCells(sheetId);
46833
- for (const cellId in cellIds) {
46834
- positionIds.add(this.encoder.encode(this.getters.getCellPosition(cellId)));
46835
- }
46836
- }
46837
- return positionIds;
47040
+ const positions = this.createEmptyPositionSet();
47041
+ positions.fillAllPositions();
47042
+ return positions;
46838
47043
  }
46839
- getArrayFormulasBlockedByOrSpreadingOn(positionId) {
46840
- if (!this.spreadingRelations.hasArrayFormulaResult(positionId)) {
47044
+ getArrayFormulasBlockedByOrSpreadingOn(position) {
47045
+ if (!this.spreadingRelations.hasArrayFormulaResult(position)) {
46841
47046
  return [];
46842
47047
  }
46843
- const arrayFormulas = this.spreadingRelations.getFormulaPositionsSpreadingOn(positionId);
46844
- const cells = new JetSet(arrayFormulas);
46845
- cells.addMany(this.getCellsDependingOn(arrayFormulas));
46846
- return cells;
47048
+ const arrayFormulas = this.spreadingRelations.getFormulaPositionsSpreadingOn(position);
47049
+ const positions = this.createEmptyPositionSet();
47050
+ positions.addMany(arrayFormulas);
47051
+ positions.addMany(this.getCellsDependingOn(arrayFormulas));
47052
+ return positions;
46847
47053
  }
46848
- nextPositionsToUpdate = new JetSet();
47054
+ nextPositionsToUpdate = new PositionSet({});
46849
47055
  cellsBeingComputed = new Set();
46850
- evaluate(cells) {
47056
+ evaluate(positions) {
46851
47057
  this.cellsBeingComputed = new Set();
46852
- this.nextPositionsToUpdate = cells;
47058
+ this.nextPositionsToUpdate = positions;
46853
47059
  let currentIteration = 0;
46854
- while (this.nextPositionsToUpdate.size && currentIteration++ < MAX_ITERATION) {
47060
+ while (!this.nextPositionsToUpdate.isEmpty() && currentIteration++ < MAX_ITERATION) {
46855
47061
  this.updateCompilationParameters();
46856
- const positionIds = Array.from(this.nextPositionsToUpdate);
46857
- this.nextPositionsToUpdate.clear();
46858
- for (let i = 0; i < positionIds.length; ++i) {
46859
- const cell = positionIds[i];
46860
- this.evaluatedCells.delete(cell);
47062
+ const positions = this.nextPositionsToUpdate.clear();
47063
+ for (let i = 0; i < positions.length; ++i) {
47064
+ this.evaluatedCells.delete(positions[i]);
46861
47065
  }
46862
- for (let i = 0; i < positionIds.length; ++i) {
46863
- const cell = positionIds[i];
46864
- this.setEvaluatedCell(cell, this.computeCell(cell));
47066
+ for (let i = 0; i < positions.length; ++i) {
47067
+ const position = positions[i];
47068
+ const evaluatedCell = this.computeCell(position);
47069
+ if (evaluatedCell !== EMPTY_CELL) {
47070
+ this.evaluatedCells.set(position, evaluatedCell);
47071
+ }
46865
47072
  }
46866
47073
  }
46867
47074
  }
46868
- setEvaluatedCell(positionId, evaluatedCell) {
46869
- this.evaluatedCells.set(positionId, evaluatedCell);
46870
- }
46871
- computeCell(positionId) {
46872
- const evaluation = this.evaluatedCells.get(positionId);
47075
+ computeCell(position) {
47076
+ const evaluation = this.evaluatedCells.get(position);
46873
47077
  if (evaluation) {
46874
47078
  return evaluation; // already computed
46875
47079
  }
46876
- if (!this.blockedArrayFormulas.has(positionId)) {
46877
- this.invalidateSpreading(positionId);
47080
+ if (!this.blockedArrayFormulas.has(position)) {
47081
+ this.invalidateSpreading(position);
46878
47082
  }
46879
- const cellPosition = this.encoder.decode(positionId);
46880
- const cell = this.getters.getCell(cellPosition);
47083
+ const cell = this.getters.getCell(position);
46881
47084
  if (cell === undefined) {
46882
47085
  return EMPTY_CELL;
46883
47086
  }
@@ -46889,7 +47092,7 @@ class Evaluator {
46889
47092
  }
46890
47093
  this.cellsBeingComputed.add(cellId);
46891
47094
  return cell.isFormula
46892
- ? this.computeFormulaCell(cellPosition.sheetId, cell)
47095
+ ? this.computeFormulaCell(position.sheetId, cell)
46893
47096
  : evaluateLiteral(cell.content, localeFormat);
46894
47097
  }
46895
47098
  catch (e) {
@@ -46902,10 +47105,9 @@ class Evaluator {
46902
47105
  }
46903
47106
  }
46904
47107
  computeAndSave(position) {
46905
- const positionId = this.encoder.encode(position);
46906
- const evaluatedCell = this.computeCell(positionId);
46907
- if (!this.evaluatedCells.has(positionId)) {
46908
- this.setEvaluatedCell(positionId, evaluatedCell);
47108
+ const evaluatedCell = this.computeCell(position);
47109
+ if (!this.evaluatedCells.has(position)) {
47110
+ this.evaluatedCells.set(position, evaluatedCell);
46909
47111
  }
46910
47112
  return evaluatedCell;
46911
47113
  }
@@ -46943,24 +47145,23 @@ class Evaluator {
46943
47145
  throw new EvaluationError(_t("Result couldn't be automatically expanded. Please insert more columns and rows."));
46944
47146
  }
46945
47147
  updateSpreadRelation({ sheetId, col, row, }) {
46946
- const arrayFormulaPositionId = this.encoder.encode({ sheetId, col, row });
47148
+ const arrayFormulaPosition = { sheetId, col, row };
46947
47149
  return (i, j) => {
46948
47150
  const position = { sheetId, col: i + col, row: j + row };
46949
- const resultPositionId = this.encoder.encode(position);
46950
- this.spreadingRelations.addRelation({ resultPositionId, arrayFormulaPositionId });
47151
+ this.spreadingRelations.addRelation({ resultPosition: position, arrayFormulaPosition });
46951
47152
  };
46952
47153
  }
46953
- checkCollision({ sheetId, col, row }) {
46954
- const formulaPositionId = this.encoder.encode({ sheetId, col, row });
47154
+ checkCollision(formulaPosition) {
47155
+ const { sheetId, col, row } = formulaPosition;
46955
47156
  return (i, j) => {
46956
47157
  const position = { sheetId: sheetId, col: i + col, row: j + row };
46957
47158
  const rawCell = this.getters.getCell(position);
46958
47159
  if (rawCell?.content ||
46959
47160
  this.getters.getEvaluatedCell(position).type !== CellValueType.empty) {
46960
- this.blockedArrayFormulas.add(formulaPositionId);
47161
+ this.blockedArrayFormulas.add(formulaPosition);
46961
47162
  throw new EvaluationError(_t("Array result was not expanded because it would overwrite data in %s.", toXC(position.col, position.row)));
46962
47163
  }
46963
- this.blockedArrayFormulas.delete(formulaPositionId);
47164
+ this.blockedArrayFormulas.delete(formulaPosition);
46964
47165
  };
46965
47166
  }
46966
47167
  spreadValues({ sheetId, col, row }, matrixResult) {
@@ -46968,19 +47169,18 @@ class Evaluator {
46968
47169
  const position = { sheetId, col: i + col, row: j + row };
46969
47170
  const cell = this.getters.getCell(position);
46970
47171
  const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell);
46971
- const positionId = this.encoder.encode(position);
46972
- this.setEvaluatedCell(positionId, evaluatedCell);
47172
+ this.evaluatedCells.set(position, evaluatedCell);
46973
47173
  // check if formula dependencies present in the spread zone
46974
47174
  // if so, they need to be recomputed
46975
- this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([positionId]));
47175
+ this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([position]));
46976
47176
  };
46977
47177
  }
46978
- invalidateSpreading(positionId) {
46979
- if (!this.spreadingRelations.isArrayFormula(positionId)) {
47178
+ invalidateSpreading(position) {
47179
+ if (!this.spreadingRelations.isArrayFormula(position)) {
46980
47180
  return;
46981
47181
  }
46982
- for (const child of this.spreadingRelations.getArrayResultPositionIds(positionId)) {
46983
- const content = this.getCell(child)?.content;
47182
+ for (const child of this.spreadingRelations.getArrayResultPositions(position)) {
47183
+ const content = this.getters.getCell(child)?.content;
46984
47184
  if (content) {
46985
47185
  // there's no point at re-evaluating overlapping array formulas,
46986
47186
  // there's still a collision
@@ -46990,28 +47190,25 @@ class Evaluator {
46990
47190
  this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([child]));
46991
47191
  this.nextPositionsToUpdate.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(child));
46992
47192
  }
46993
- this.spreadingRelations.removeNode(positionId);
47193
+ this.spreadingRelations.removeNode(position);
46994
47194
  }
46995
47195
  // ----------------------------------------------------------
46996
47196
  // COMMON FUNCTIONALITY
46997
47197
  // ----------------------------------------------------------
46998
- getDirectDependencies(positionId) {
46999
- const cell = this.getCell(positionId);
47198
+ getDirectDependencies(position) {
47199
+ const cell = this.getters.getCell(position);
47000
47200
  if (!cell?.isFormula) {
47001
47201
  return [];
47002
47202
  }
47003
47203
  return cell.compiledFormula.dependencies;
47004
47204
  }
47005
- getCellsDependingOn(positionIds) {
47205
+ getCellsDependingOn(positions) {
47006
47206
  const ranges = [];
47007
- for (const positionId of positionIds) {
47008
- ranges.push(this.encoder.decodeToBoundingBox(positionId));
47207
+ for (const position of positions) {
47208
+ ranges.push({ sheetId: position.sheetId, zone: positionToZone(position) });
47009
47209
  }
47010
47210
  return this.formulaDependencies().getCellsDependingOn(ranges);
47011
47211
  }
47012
- getCell(positionId) {
47013
- return this.getters.getCell(this.encoder.decode(positionId));
47014
- }
47015
47212
  }
47016
47213
  function forEachSpreadPositionInMatrix(nbColumns, nbRows, callback) {
47017
47214
  for (let i = 0; i < nbColumns; ++i) {
@@ -47037,85 +47234,6 @@ function nullValueToZeroValue(fPayload) {
47037
47234
  }
47038
47235
  return fPayload;
47039
47236
  }
47040
- /**
47041
- * Encode (and decode) cell positions { sheetId, col, row }
47042
- * to a single integer.
47043
- *
47044
- * `col` and `row` values are encoded on 21 bits each (max 2^21 = 2_097_152),
47045
- * An incremental integer id is assigned to each different sheet id, starting at 0.
47046
- *
47047
- * e.g.
47048
- * Given { col: 10, row: 4, sheetId: "abcde" }
47049
- * we have:
47050
- * - row "4" encoded on 21 bits: 000000000000000000100
47051
- * - col "10" encoded on 21 bits: 000000000000000001010
47052
- * - sheetId: let's say it's the 4th sheetId met, encoded to: 11
47053
- *
47054
- * The final encoded value is found by concatenating the 3 bit sequences:
47055
- *
47056
- * sheetId: 11
47057
- * col: 000000000000000001010
47058
- * row: 000000000000000000100
47059
- * => 11000000000000000001010000000000000000000100
47060
- *
47061
- * this binary sequence is the integer 13194160504836
47062
- */
47063
- class PositionBitsEncoder {
47064
- sheetMapping = {};
47065
- inverseSheetMapping = new Map();
47066
- constructor() {
47067
- try {
47068
- // @ts-ignore
47069
- o_spreadsheet.__DEBUG__ = o_spreadsheet.__DEBUG__ || {};
47070
- // @ts-ignore
47071
- o_spreadsheet.__DEBUG__.decodePosition = this.decode.bind(this);
47072
- // @ts-ignore
47073
- o_spreadsheet.__DEBUG__.encodePosition = this.encode.bind(this);
47074
- }
47075
- catch (error) { }
47076
- }
47077
- /**
47078
- * Encode a cell position to a single integer.
47079
- */
47080
- encode({ sheetId, col, row }) {
47081
- return (this.encodeSheet(sheetId) << 42n) | (BigInt(col) << 21n) | BigInt(row);
47082
- }
47083
- encodeBoundingBox({ sheetId, zone }) {
47084
- const positions = [];
47085
- forEachPositionsInZone(zone, (col, row) => {
47086
- positions.push(this.encode({ sheetId, col, row }));
47087
- });
47088
- return positions;
47089
- }
47090
- decode(id) {
47091
- // keep only the last 21 bits by AND-ing the bit sequence with 21 ones
47092
- const row = Number(id & 2097151n);
47093
- const col = Number((id >> 21n) & 2097151n);
47094
- const sheetId = this.decodeSheet(id >> 42n);
47095
- return { sheetId, col, row };
47096
- }
47097
- decodeToBoundingBox(id) {
47098
- const { sheetId, col, row } = this.decode(id);
47099
- return { sheetId, zone: { left: col, top: row, right: col, bottom: row } };
47100
- }
47101
- encodeSheet(sheetId) {
47102
- const sheetKey = this.sheetMapping[sheetId];
47103
- if (sheetKey === undefined) {
47104
- const newSheetKey = BigInt(Object.keys(this.sheetMapping).length);
47105
- this.sheetMapping[sheetId] = newSheetKey;
47106
- this.inverseSheetMapping.set(newSheetKey, sheetId);
47107
- return newSheetKey;
47108
- }
47109
- return sheetKey;
47110
- }
47111
- decodeSheet(sheetKey) {
47112
- const sheetId = this.inverseSheetMapping.get(sheetKey);
47113
- if (sheetId === undefined) {
47114
- throw new Error("Sheet id not found");
47115
- }
47116
- return sheetId;
47117
- }
47118
- }
47119
47237
  function updateEvalContextAndExecute(compiledFormula, compilationParams, sheetId, cellId) {
47120
47238
  compilationParams.evalContext.__originCellXC = lazy(() => {
47121
47239
  if (!cellId) {
@@ -47262,6 +47380,10 @@ class EvaluationPlugin extends UIPlugin {
47262
47380
  this.evaluator.updateDependencies(cmd);
47263
47381
  }
47264
47382
  break;
47383
+ case "DUPLICATE_SHEET":
47384
+ case "CREATE_SHEET":
47385
+ this.shouldRebuildDependenciesGraph = true;
47386
+ break;
47265
47387
  case "EVALUATE_CELLS":
47266
47388
  this.evaluator.evaluateAllCells();
47267
47389
  break;
@@ -52354,6 +52476,7 @@ class GridSelectionPlugin extends UIPlugin {
52354
52476
  this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
52355
52477
  this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
52356
52478
  this.setSelectionMixin(this.gridSelection.anchor, this.gridSelection.zones);
52479
+ this.selectedFigureId = null;
52357
52480
  break;
52358
52481
  }
52359
52482
  /** Any change to the selection has to be reflected in the selection processor. */
@@ -55972,9 +56095,6 @@ css /* scss */ `
55972
56095
  .text-muted {
55973
56096
  color: grey !important;
55974
56097
  }
55975
- button {
55976
- color: #333;
55977
- }
55978
56098
  .o-disabled {
55979
56099
  opacity: 0.4;
55980
56100
  pointer: default;
@@ -56095,17 +56215,17 @@ css /* scss */ `
56095
56215
  }
56096
56216
 
56097
56217
  .o-button {
56098
- border: 1px solid lightgrey;
56218
+ border: 1px solid;
56099
56219
  padding: 0px 20px 0px 20px;
56100
56220
  border-radius: 4px;
56101
56221
  font-weight: 500;
56102
56222
  font-size: 14px;
56103
56223
  height: 30px;
56104
56224
  line-height: 16px;
56105
- background: white;
56106
56225
  margin-right: 8px;
56107
- &:hover:enabled {
56108
- background-color: rgba(0, 0, 0, 0.08);
56226
+
56227
+ &:not(:hover) {
56228
+ background-color: transparent;
56109
56229
  }
56110
56230
 
56111
56231
  &:enabled {
@@ -56119,6 +56239,15 @@ css /* scss */ `
56119
56239
  &:last-child {
56120
56240
  margin-right: 0px;
56121
56241
  }
56242
+
56243
+ &.o-button-grey {
56244
+ border-color: lightgrey;
56245
+ background: #ffffff;
56246
+ color: #333;
56247
+ &:hover:enabled {
56248
+ background-color: rgba(0, 0, 0, 0.08);
56249
+ }
56250
+ }
56122
56251
  }
56123
56252
 
56124
56253
  .o-input {
@@ -60005,6 +60134,6 @@ const constants = {
60005
60134
  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 };
60006
60135
 
60007
60136
 
60008
- __info__.version = "17.2.0-alpha.8";
60009
- __info__.date = "2024-03-15T11:01:01.388Z";
60010
- __info__.hash = "11cf381";
60137
+ __info__.version = "17.2.1";
60138
+ __info__.date = "2024-03-25T09:41:58.737Z";
60139
+ __info__.hash = "f97284c";