@odoo/o-spreadsheet 18.0.15 → 18.0.17

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.
@@ -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.0.15
6
- * @date 2025-02-10T08:59:22.993Z
7
- * @hash 5b19f88
5
+ * @version 18.0.17
6
+ * @date 2025-02-25T05:58:39.632Z
7
+ * @hash 2ee4347
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -2064,17 +2064,7 @@ function toZoneWithoutBoundaryChanges(xc) {
2064
2064
  */
2065
2065
  function toUnboundedZone(xc) {
2066
2066
  const zone = toZoneWithoutBoundaryChanges(xc);
2067
- if (zone.right !== undefined && zone.right < zone.left) {
2068
- const tmp = zone.left;
2069
- zone.left = zone.right;
2070
- zone.right = tmp;
2071
- }
2072
- if (zone.bottom !== undefined && zone.bottom < zone.top) {
2073
- const tmp = zone.top;
2074
- zone.top = zone.bottom;
2075
- zone.bottom = tmp;
2076
- }
2077
- return zone;
2067
+ return reorderZone(zone);
2078
2068
  }
2079
2069
  /**
2080
2070
  * Convert from a cartesian reference to a Zone.
@@ -2348,11 +2338,11 @@ function positions(zone) {
2348
2338
  return positions;
2349
2339
  }
2350
2340
  function reorderZone(zone) {
2351
- if (zone.left > zone.right) {
2352
- zone = { left: zone.right, right: zone.left, top: zone.top, bottom: zone.bottom };
2341
+ if (zone.right !== undefined && zone.left > zone.right) {
2342
+ zone = { ...zone, left: zone.right, right: zone.left };
2353
2343
  }
2354
- if (zone.top > zone.bottom) {
2355
- zone = { left: zone.left, right: zone.right, top: zone.bottom, bottom: zone.top };
2344
+ if (zone.bottom !== undefined && zone.top > zone.bottom) {
2345
+ zone = { ...zone, top: zone.bottom, bottom: zone.top };
2356
2346
  }
2357
2347
  return zone;
2358
2348
  }
@@ -3246,12 +3236,12 @@ function isTargetDependent(cmd) {
3246
3236
  function isRangeDependant(cmd) {
3247
3237
  return "ranges" in cmd;
3248
3238
  }
3249
- function isZoneDependent(cmd) {
3250
- return "zone" in cmd;
3251
- }
3252
3239
  function isPositionDependent(cmd) {
3253
3240
  return "col" in cmd && "row" in cmd && "sheetId" in cmd;
3254
3241
  }
3242
+ function isZoneDependent(cmd) {
3243
+ return "sheetId" in cmd && "zone" in cmd;
3244
+ }
3255
3245
  const invalidateEvaluationCommands = new Set([
3256
3246
  "RENAME_SHEET",
3257
3247
  "DELETE_SHEET",
@@ -3263,6 +3253,7 @@ const invalidateEvaluationCommands = new Set([
3263
3253
  "REDO",
3264
3254
  "ADD_MERGE",
3265
3255
  "REMOVE_MERGE",
3256
+ "DUPLICATE_SHEET",
3266
3257
  "UPDATE_LOCALE",
3267
3258
  "ADD_PIVOT",
3268
3259
  "UPDATE_PIVOT",
@@ -3291,7 +3282,6 @@ const invalidateChartEvaluationCommands = new Set([
3291
3282
  ]);
3292
3283
  const invalidateDependenciesCommands = new Set(["MOVE_RANGES"]);
3293
3284
  const invalidateCFEvaluationCommands = new Set([
3294
- "DUPLICATE_SHEET",
3295
3285
  "EVALUATE_CELLS",
3296
3286
  "ADD_CONDITIONAL_FORMAT",
3297
3287
  "REMOVE_CONDITIONAL_FORMAT",
@@ -3460,6 +3450,7 @@ var CommandResult;
3460
3450
  CommandResult["InvalidRange"] = "InvalidRange";
3461
3451
  CommandResult["InvalidZones"] = "InvalidZones";
3462
3452
  CommandResult["InvalidSheetId"] = "InvalidSheetId";
3453
+ CommandResult["InvalidCellId"] = "InvalidCellId";
3463
3454
  CommandResult["InvalidFigureId"] = "InvalidFigureId";
3464
3455
  CommandResult["InputAlreadyFocused"] = "InputAlreadyFocused";
3465
3456
  CommandResult["MaximumRangesReached"] = "MaximumRangesReached";
@@ -6345,20 +6336,53 @@ class UuidGenerator {
6345
6336
  setIsFastStrategy(isFast) {
6346
6337
  this.isFastIdStrategy = isFast;
6347
6338
  }
6339
+ /**
6340
+ * Generates a custom UUID using a simple 36^12 method (8-character alphanumeric string with lowercase letters)
6341
+ * This has a higher chance of collision than a UUIDv4, but not only faster to generate than an UUIDV4,
6342
+ * it also has a smaller size, which is preferable to alleviate the overall data size.
6343
+ *
6344
+ * This method is preferable when generating uuids for the core data (sheetId, figureId, etc)
6345
+ * as they will appear several times in the revisions and local history.
6346
+ *
6347
+ */
6348
+ smallUuid() {
6349
+ if (this.isFastIdStrategy) {
6350
+ this.fastIdStart++;
6351
+ return String(this.fastIdStart);
6352
+ }
6353
+ else if (window.crypto) {
6354
+ return "10000000-1000".replace(/[01]/g, (c) => {
6355
+ const n = Number(c);
6356
+ return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
6357
+ });
6358
+ }
6359
+ else {
6360
+ // mainly for jest and other browsers that do not have the crypto functionality
6361
+ return "xxxxxxxx-xxxx".replace(/[xy]/g, function (c) {
6362
+ var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
6363
+ return v.toString(16);
6364
+ });
6365
+ }
6366
+ }
6367
+ /**
6368
+ * Generates an UUIDV4, has astronomically low chance of collision, but is larger in size than the smallUuid.
6369
+ * This method should be used when you need to avoid collisions at all costs, like the id of a revision.
6370
+ */
6348
6371
  uuidv4() {
6349
6372
  if (this.isFastIdStrategy) {
6350
6373
  this.fastIdStart++;
6351
6374
  return String(this.fastIdStart);
6352
- //@ts-ignore
6353
6375
  }
6354
- else if (window.crypto && window.crypto.getRandomValues) {
6355
- //@ts-ignore
6356
- return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
6376
+ else if (window.crypto) {
6377
+ return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => {
6378
+ const n = Number(c);
6379
+ return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
6380
+ });
6357
6381
  }
6358
6382
  else {
6359
6383
  // mainly for jest and other browsers that do not have the crypto functionality
6360
6384
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
6361
- var r = (Math.random() * 16) | 0, v = c === "x" ? r : (r & 0x3) | 0x8;
6385
+ var r = (Math.random() * 16) | 0, v = c == "x" ? r : (r & 0x3) | 0x8;
6362
6386
  return v.toString(16);
6363
6387
  });
6364
6388
  }
@@ -8337,7 +8361,7 @@ class ChartClipboardHandler extends AbstractFigureClipboardHandler {
8337
8361
  };
8338
8362
  }
8339
8363
  getPasteTarget(sheetId, target, content, options) {
8340
- const newId = new UuidGenerator().uuidv4();
8364
+ const newId = new UuidGenerator().smallUuid();
8341
8365
  return { zones: [], figureId: newId, sheetId };
8342
8366
  }
8343
8367
  paste(target, clippedContent, options) {
@@ -8503,7 +8527,7 @@ class ConditionalFormatClipboardHandler extends AbstractCellClipboardHandler {
8503
8527
  if (!targetCF && queuedCfs) {
8504
8528
  targetCF = queuedCfs.find((queued) => queued.cf.stopIfTrue === originCF.stopIfTrue && deepEquals(queued.cf.rule, originCF.rule))?.cf;
8505
8529
  }
8506
- return targetCF || { ...originCF, id: this.uuidGenerator.uuidv4(), ranges: [] };
8530
+ return targetCF || { ...originCF, id: this.uuidGenerator.smallUuid(), ranges: [] };
8507
8531
  }
8508
8532
  }
8509
8533
 
@@ -8596,7 +8620,7 @@ class DataValidationClipboardHandler extends AbstractCellClipboardHandler {
8596
8620
  }
8597
8621
  return (targetRule || {
8598
8622
  ...originRule,
8599
- id: newId ? this.uuidGenerator.uuidv4() : originRule.id,
8623
+ id: newId ? this.uuidGenerator.smallUuid() : originRule.id,
8600
8624
  ranges: [],
8601
8625
  });
8602
8626
  }
@@ -8658,7 +8682,7 @@ class ImageClipboardHandler extends AbstractFigureClipboardHandler {
8658
8682
  };
8659
8683
  }
8660
8684
  getPasteTarget(sheetId, target, content, options) {
8661
- const newId = new UuidGenerator().uuidv4();
8685
+ const newId = new UuidGenerator().smallUuid();
8662
8686
  return { sheetId, zones: [], figureId: newId };
8663
8687
  }
8664
8688
  paste(target, clippedContent, options) {
@@ -9637,6 +9661,9 @@ function getTrendDatasetForBarChart(config, dataset) {
9637
9661
  const filteredValues = [];
9638
9662
  const filteredLabels = [];
9639
9663
  const labels = [];
9664
+ if (dataset.hidden) {
9665
+ return;
9666
+ }
9640
9667
  for (let i = 0; i < dataset.data.length; i++) {
9641
9668
  if (typeof dataset.data[i] === "number") {
9642
9669
  filteredValues.push(dataset.data[i]);
@@ -11972,6 +11999,25 @@ const LN = {
11972
11999
  isExported: true,
11973
12000
  };
11974
12001
  // -----------------------------------------------------------------------------
12002
+ // LOG
12003
+ // -----------------------------------------------------------------------------
12004
+ const LOG = {
12005
+ description: _t("The logarithm of a number, for a given base."),
12006
+ args: [
12007
+ arg("value (number)", _t("The value for which to calculate the logarithm.")),
12008
+ arg("base (number, default=10)", _t("The base of the logarithm.")),
12009
+ ],
12010
+ compute: function (value, base = { value: 10 }) {
12011
+ const _value = toNumber(value, this.locale);
12012
+ const _base = toNumber(base, this.locale);
12013
+ assert(() => _value > 0, _t("The value (%s) must be strictly positive.", _value.toString()));
12014
+ assert(() => _base > 0, _t("The base (%s) must be strictly positive.", _base.toString()));
12015
+ assert(() => _base !== 1, _t("The base must be different from 1."));
12016
+ return Math.log10(_value) / Math.log10(_base);
12017
+ },
12018
+ isExported: true,
12019
+ };
12020
+ // -----------------------------------------------------------------------------
11975
12021
  // MOD
11976
12022
  // -----------------------------------------------------------------------------
11977
12023
  function mod(dividend, divisor) {
@@ -12511,6 +12557,7 @@ var math = /*#__PURE__*/Object.freeze({
12511
12557
  ISODD: ISODD,
12512
12558
  ISO_CEILING: ISO_CEILING,
12513
12559
  LN: LN,
12560
+ LOG: LOG,
12514
12561
  MOD: MOD,
12515
12562
  MUNIT: MUNIT,
12516
12563
  ODD: ODD,
@@ -15060,7 +15107,7 @@ const SORTN = {
15060
15107
  }
15061
15108
  }
15062
15109
  },
15063
- isExported: true,
15110
+ isExported: false,
15064
15111
  };
15065
15112
  // -----------------------------------------------------------------------------
15066
15113
  // UNIQUE
@@ -28514,17 +28561,15 @@ function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, tr
28514
28561
  plugins: [],
28515
28562
  };
28516
28563
  }
28517
- function getChartLabelFormat(getters, range) {
28564
+ function getChartLabelFormat(getters, range, shouldRemoveFirstLabel) {
28518
28565
  if (!range)
28519
28566
  return undefined;
28520
- const { sheetId, zone: { left, top, bottom }, } = range;
28521
- for (let row = top; row <= bottom; row++) {
28522
- const format = getters.getEvaluatedCell({ sheetId, col: left, row }).format;
28523
- if (format) {
28524
- return format;
28525
- }
28567
+ const { sheetId, zone } = range;
28568
+ const formats = positions(zone).map((position) => getters.getEvaluatedCell({ sheetId, ...position }).format);
28569
+ if (shouldRemoveFirstLabel) {
28570
+ formats.shift();
28526
28571
  }
28527
- return undefined;
28572
+ return formats.find((format) => format !== undefined);
28528
28573
  }
28529
28574
  function getChartLabelValues(getters, dataSets, labelRange) {
28530
28575
  let labels = { values: [], formattedValues: [] };
@@ -28579,10 +28624,8 @@ function getChartDatasetFormat(getters, dataSets) {
28579
28624
  function getChartDatasetValues(getters, dataSets) {
28580
28625
  const datasetValues = [];
28581
28626
  for (const [dsIndex, ds] of Object.entries(dataSets)) {
28582
- if (getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left)) {
28583
- continue;
28584
- }
28585
28627
  let label;
28628
+ let hidden = getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left);
28586
28629
  if (ds.labelCell) {
28587
28630
  const labelRange = ds.labelCell;
28588
28631
  const cell = labelRange
@@ -28609,9 +28652,9 @@ function getChartDatasetValues(getters, dataSets) {
28609
28652
  data.fill(1);
28610
28653
  }
28611
28654
  else if (data.every((cell) => cell === undefined || cell === null || !isNumber(cell.toString(), DEFAULT_LOCALE))) {
28612
- continue;
28655
+ hidden = true;
28613
28656
  }
28614
- datasetValues.push({ data, label });
28657
+ datasetValues.push({ data, label, hidden });
28615
28658
  }
28616
28659
  return datasetValues;
28617
28660
  }
@@ -28678,6 +28721,20 @@ const backgroundColorChartJSPlugin = {
28678
28721
  ctx.restore();
28679
28722
  },
28680
28723
  };
28724
+ function getChartJsLegend(fontColor, legend = {}) {
28725
+ return {
28726
+ ...legend,
28727
+ labels: {
28728
+ color: fontColor,
28729
+ filter: (legendItem, data) => {
28730
+ return "datasetIndex" in legendItem
28731
+ ? !data.datasets[legendItem.datasetIndex].hidden
28732
+ : true;
28733
+ },
28734
+ ...legend.labels,
28735
+ },
28736
+ };
28737
+ }
28681
28738
 
28682
28739
  class BarChart extends AbstractChart {
28683
28740
  dataSets;
@@ -28812,9 +28869,7 @@ function createBarChartRuntime(chart, getters) {
28812
28869
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
28813
28870
  let labels = labelValues.formattedValues;
28814
28871
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
28815
- if (chart.dataSetsHaveTitle &&
28816
- dataSetsValues[0] &&
28817
- labels.length > dataSetsValues[0].data.length) {
28872
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
28818
28873
  labels.shift();
28819
28874
  }
28820
28875
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -28829,9 +28884,7 @@ function createBarChartRuntime(chart, getters) {
28829
28884
  ...localeFormat,
28830
28885
  horizontalChart: chart.horizontal,
28831
28886
  });
28832
- const legend = {
28833
- labels: { color: fontColor },
28834
- };
28887
+ const legend = getChartJsLegend(fontColor);
28835
28888
  if (chart.legendPosition === "none") {
28836
28889
  legend.display = false;
28837
28890
  }
@@ -28895,11 +28948,12 @@ function createBarChartRuntime(chart, getters) {
28895
28948
  const colors = getChartColorsGenerator(definition, dataSetsValues.length);
28896
28949
  const trendDatasets = [];
28897
28950
  for (const index in dataSetsValues) {
28898
- const { label, data } = dataSetsValues[index];
28951
+ const { label, data, hidden } = dataSetsValues[index];
28899
28952
  const color = colors.next();
28900
28953
  const dataset = {
28901
28954
  label,
28902
28955
  data,
28956
+ hidden,
28903
28957
  borderColor: definition.background || BACKGROUND_CHART_COLOR,
28904
28958
  borderWidth: definition.stacked ? 1 : 0,
28905
28959
  backgroundColor: color,
@@ -29083,8 +29137,8 @@ function fixEmptyLabelsForDateCharts(labels, dataSetsValues) {
29083
29137
  }
29084
29138
  return { labels: newLabels, dataSetsValues: newDatasets };
29085
29139
  }
29086
- function canChartParseLabels(labelRange, getters) {
29087
- return canBeDateChart(labelRange, getters) || canBeLinearChart(labelRange, getters);
29140
+ function canChartParseLabels(chart, getters) {
29141
+ return canBeDateChart(chart, getters) || canBeLinearChart(chart, getters);
29088
29142
  }
29089
29143
  function getChartAxisType(chart, getters) {
29090
29144
  if (isDateChart(chart, getters) && isLuxonTimeAdapterInstalled()) {
@@ -29096,23 +29150,26 @@ function getChartAxisType(chart, getters) {
29096
29150
  return "category";
29097
29151
  }
29098
29152
  function isDateChart(chart, getters) {
29099
- return !chart.labelsAsText && canBeDateChart(chart.labelRange, getters);
29153
+ return !chart.labelsAsText && canBeDateChart(chart, getters);
29100
29154
  }
29101
29155
  function isLinearChart(chart, getters) {
29102
- return !chart.labelsAsText && canBeLinearChart(chart.labelRange, getters);
29156
+ return !chart.labelsAsText && canBeLinearChart(chart, getters);
29103
29157
  }
29104
- function canBeDateChart(labelRange, getters) {
29105
- if (!labelRange || !canBeLinearChart(labelRange, getters)) {
29158
+ function canBeDateChart(chart, getters) {
29159
+ if (!chart.labelRange || !canBeLinearChart(chart, getters)) {
29106
29160
  return false;
29107
29161
  }
29108
- const labelFormat = getChartLabelFormat(getters, labelRange);
29162
+ const labelFormat = getChartLabelFormat(getters, chart.labelRange, shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle));
29109
29163
  return Boolean(labelFormat && timeFormatLuxonCompatible.test(labelFormat));
29110
29164
  }
29111
- function canBeLinearChart(labelRange, getters) {
29112
- if (!labelRange) {
29165
+ function canBeLinearChart(chart, getters) {
29166
+ if (!chart.labelRange) {
29113
29167
  return false;
29114
29168
  }
29115
- const labels = getters.getRangeValues(labelRange);
29169
+ const labels = getters.getRangeValues(chart.labelRange);
29170
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
29171
+ labels.shift();
29172
+ }
29116
29173
  if (labels.some((label) => isNaN(Number(label)) && label)) {
29117
29174
  return false;
29118
29175
  }
@@ -29140,6 +29197,9 @@ function getTrendDatasetForLineChart(config, dataset, axisType, locale) {
29140
29197
  const filteredLabels = [];
29141
29198
  const labels = [];
29142
29199
  const datasetLength = dataset.data.length;
29200
+ if (dataset.hidden) {
29201
+ return;
29202
+ }
29143
29203
  if (datasetLength < 2) {
29144
29204
  return;
29145
29205
  }
@@ -29196,9 +29256,8 @@ function createLineOrScatterChartRuntime(chart, getters) {
29196
29256
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
29197
29257
  let labels = axisType === "linear" ? labelValues.values : labelValues.formattedValues;
29198
29258
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
29199
- if (chart.dataSetsHaveTitle &&
29200
- dataSetsValues[0] &&
29201
- labels.length > dataSetsValues[0].data.length) {
29259
+ const removeFirstLabel = shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle);
29260
+ if (removeFirstLabel) {
29202
29261
  labels.shift();
29203
29262
  }
29204
29263
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -29214,9 +29273,8 @@ function createLineOrScatterChartRuntime(chart, getters) {
29214
29273
  const options = { format: dataSetFormat, locale, truncateLabels };
29215
29274
  const fontColor = chartFontColor(chart.background);
29216
29275
  const config = getDefaultChartJsRuntime(chart, labels, fontColor, options);
29217
- const legend = {
29276
+ const legend = getChartJsLegend(fontColor, {
29218
29277
  labels: {
29219
- color: fontColor,
29220
29278
  generateLabels(chart) {
29221
29279
  // color the legend labels with the dataset color, without any transparency
29222
29280
  const { data } = chart;
@@ -29227,7 +29285,7 @@ function createLineOrScatterChartRuntime(chart, getters) {
29227
29285
  return labels;
29228
29286
  },
29229
29287
  },
29230
- };
29288
+ });
29231
29289
  if (chart.legendPosition === "none") {
29232
29290
  legend.display = false;
29233
29291
  }
@@ -29288,12 +29346,7 @@ function createLineOrScatterChartRuntime(chart, getters) {
29288
29346
  background: chart.background,
29289
29347
  callback: formatTickValue(options),
29290
29348
  };
29291
- if (chart.dataSetsHaveTitle &&
29292
- dataSetsValues[0] &&
29293
- labels.length > dataSetsValues[0].data.length) {
29294
- labels.shift();
29295
- }
29296
- const labelFormat = getChartLabelFormat(getters, chart.labelRange);
29349
+ const labelFormat = getChartLabelFormat(getters, chart.labelRange, removeFirstLabel);
29297
29350
  if (axisType === "time") {
29298
29351
  const axis = {
29299
29352
  type: "time",
@@ -29332,7 +29385,7 @@ function createLineOrScatterChartRuntime(chart, getters) {
29332
29385
  const cumulative = "cumulative" in chart ? chart.cumulative : false;
29333
29386
  const definition = chart.getDefinition();
29334
29387
  const colors = getChartColorsGenerator(definition, dataSetsValues.length);
29335
- for (let [index, { label, data }] of dataSetsValues.entries()) {
29388
+ for (let [index, { label, data, hidden }] of dataSetsValues.entries()) {
29336
29389
  const color = colors.next();
29337
29390
  let backgroundRGBA = colorToRGBA(color);
29338
29391
  if (areaChart) {
@@ -29356,6 +29409,7 @@ function createLineOrScatterChartRuntime(chart, getters) {
29356
29409
  const dataset = {
29357
29410
  label,
29358
29411
  data,
29412
+ hidden,
29359
29413
  tension: 0, // 0 -> render straight lines, which is much faster
29360
29414
  borderColor: color,
29361
29415
  backgroundColor,
@@ -29551,9 +29605,7 @@ function createComboChartRuntime(chart, getters) {
29551
29605
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
29552
29606
  let labels = labelValues.formattedValues;
29553
29607
  let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
29554
- if (chart.dataSetsHaveTitle &&
29555
- dataSetsValues[0] &&
29556
- labels.length > dataSetsValues[0].data.length) {
29608
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
29557
29609
  labels.shift();
29558
29610
  }
29559
29611
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -29563,9 +29615,7 @@ function createComboChartRuntime(chart, getters) {
29563
29615
  const localeFormat = { format: mainDataSetFormat, locale };
29564
29616
  const fontColor = chartFontColor(chart.background);
29565
29617
  const config = getDefaultChartJsRuntime(chart, labels, fontColor, localeFormat);
29566
- const legend = {
29567
- labels: { color: fontColor },
29568
- };
29618
+ const legend = getChartJsLegend(fontColor);
29569
29619
  if (chart.legendPosition === "none") {
29570
29620
  legend.display = false;
29571
29621
  }
@@ -29629,13 +29679,14 @@ function createComboChartRuntime(chart, getters) {
29629
29679
  const colors = getChartColorsGenerator(definition, dataSetsValues.length);
29630
29680
  let maxLength = 0;
29631
29681
  const trendDatasets = [];
29632
- for (let [index, { label, data }] of dataSetsValues.entries()) {
29682
+ for (let [index, { label, data, hidden }] of dataSetsValues.entries()) {
29633
29683
  const design = definition.dataSets[index];
29634
29684
  const color = colors.next();
29635
29685
  const type = design?.type ?? "line";
29636
29686
  const dataset = {
29637
29687
  label: design?.label ?? label,
29638
29688
  data,
29689
+ hidden,
29639
29690
  borderColor: color,
29640
29691
  backgroundColor: color,
29641
29692
  yAxisID: design?.yAxisId ?? "y",
@@ -30243,10 +30294,8 @@ function filterNegativeValues(labels, datasets) {
30243
30294
  function createPieChartRuntime(chart, getters) {
30244
30295
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
30245
30296
  let labels = labelValues.formattedValues;
30246
- let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
30247
- if (chart.dataSetsHaveTitle &&
30248
- dataSetsValues[0] &&
30249
- labels.length > dataSetsValues[0].data.length) {
30297
+ let dataSetsValues = getChartDatasetValues(getters, chart.dataSets).filter((dataSet) => !dataSet.hidden);
30298
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
30250
30299
  labels.shift();
30251
30300
  }
30252
30301
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -30263,7 +30312,7 @@ function createPieChartRuntime(chart, getters) {
30263
30312
  const dataset = {
30264
30313
  label,
30265
30314
  data,
30266
- borderColor: BACKGROUND_CHART_COLOR,
30315
+ borderColor: chart.background || "#FFFFFF",
30267
30316
  backgroundColor,
30268
30317
  hoverOffset: 30,
30269
30318
  };
@@ -30392,8 +30441,9 @@ function createPyramidChartRuntime(chart, getters) {
30392
30441
  const barDef = { ...chart.getDefinition(), type: "bar" };
30393
30442
  const barChart = new BarChart(barDef, chart.sheetId, getters);
30394
30443
  const barRuntime = createBarChartRuntime(barChart, getters);
30444
+ // align design with filtered datasets
30395
30445
  const config = barRuntime.chartJsConfig;
30396
- let datasets = config.data?.datasets;
30446
+ let datasets = config.data?.datasets.filter((dataSet) => !dataSet.hidden);
30397
30447
  if (datasets && datasets[0]) {
30398
30448
  datasets[0].data = datasets[0].data.map((value) => (value > 0 ? value : 0));
30399
30449
  }
@@ -30790,10 +30840,8 @@ function getWaterfallConfiguration(chart, labels, dataSeriesLabels, localeFormat
30790
30840
  function createWaterfallChartRuntime(chart, getters) {
30791
30841
  const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
30792
30842
  let labels = labelValues.formattedValues;
30793
- let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
30794
- if (chart.dataSetsHaveTitle &&
30795
- dataSetsValues[0] &&
30796
- labels.length > dataSetsValues[0].data.length) {
30843
+ let dataSetsValues = getChartDatasetValues(getters, chart.dataSets).filter((ds) => !ds.hidden);
30844
+ if (shouldRemoveFirstLabel(chart.labelRange, chart.dataSets[0], chart.dataSetsHaveTitle)) {
30797
30845
  labels.shift();
30798
30846
  }
30799
30847
  ({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
@@ -32289,7 +32337,7 @@ const linkSheet = {
32289
32337
  const deleteSheet = {
32290
32338
  name: _t("Delete"),
32291
32339
  isVisible: (env) => {
32292
- return env.model.getters.getSheetIds().length > 1;
32340
+ return env.model.getters.getVisibleSheetIds().length > 1;
32293
32341
  },
32294
32342
  execute: (env) => env.askConfirmation(_t("Are you sure you want to delete this sheet?"), () => {
32295
32343
  env.model.dispatch("DELETE_SHEET", { sheetId: env.model.getters.getActiveSheetId() });
@@ -32300,7 +32348,7 @@ const duplicateSheet = {
32300
32348
  name: _t("Duplicate"),
32301
32349
  execute: (env) => {
32302
32350
  const sheetIdFrom = env.model.getters.getActiveSheetId();
32303
- const sheetIdTo = env.model.uuidGenerator.uuidv4();
32351
+ const sheetIdTo = env.model.uuidGenerator.smallUuid();
32304
32352
  env.model.dispatch("DUPLICATE_SHEET", {
32305
32353
  sheetId: sheetIdFrom,
32306
32354
  sheetIdTo,
@@ -32927,20 +32975,21 @@ function getSmartChartDefinition(zone, getters) {
32927
32975
  }
32928
32976
  // Only display legend for several datasets.
32929
32977
  const newLegendPos = dataSetZone.right === dataSetZone.left ? "none" : "top";
32930
- const labelRange = labelRangeXc ? getters.getRangeFromSheetXC(sheetId, labelRangeXc) : undefined;
32931
- if (canChartParseLabels(labelRange, getters)) {
32932
- return {
32933
- title: {},
32934
- dataSets,
32935
- labelsAsText: false,
32936
- stacked: false,
32937
- aggregated: false,
32938
- cumulative: false,
32939
- labelRange: labelRangeXc,
32940
- type: "line",
32941
- dataSetsHaveTitle,
32942
- legendPosition: newLegendPos,
32943
- };
32978
+ const lineChartDefinition = {
32979
+ title: {},
32980
+ dataSets,
32981
+ labelsAsText: false,
32982
+ stacked: false,
32983
+ aggregated: false,
32984
+ cumulative: false,
32985
+ labelRange: labelRangeXc,
32986
+ type: "line",
32987
+ dataSetsHaveTitle,
32988
+ legendPosition: newLegendPos,
32989
+ };
32990
+ const chart = new LineChart(lineChartDefinition, sheetId, getters);
32991
+ if (canChartParseLabels(chart, getters)) {
32992
+ return lineChartDefinition;
32944
32993
  }
32945
32994
  const _dataSets = createDataSets(getters, dataSets, sheetId, dataSetsHaveTitle);
32946
32995
  if (singleColumn &&
@@ -33308,7 +33357,7 @@ const HIDE_ROWS_NAME = (env) => {
33308
33357
  //------------------------------------------------------------------------------
33309
33358
  const CREATE_CHART = (env) => {
33310
33359
  const getters = env.model.getters;
33311
- const id = env.model.uuidGenerator.uuidv4();
33360
+ const id = env.model.uuidGenerator.smallUuid();
33312
33361
  const sheetId = getters.getActiveSheetId();
33313
33362
  if (getZoneArea(env.model.getters.getSelectedZone()) === 1) {
33314
33363
  env.model.selection.selectTableAroundSelection();
@@ -33331,8 +33380,8 @@ const CREATE_CHART = (env) => {
33331
33380
  // Pivots
33332
33381
  //------------------------------------------------------------------------------
33333
33382
  const CREATE_PIVOT = (env) => {
33334
- const pivotId = env.model.uuidGenerator.uuidv4();
33335
- const newSheetId = env.model.uuidGenerator.uuidv4();
33383
+ const pivotId = env.model.uuidGenerator.smallUuid();
33384
+ const newSheetId = env.model.uuidGenerator.smallUuid();
33336
33385
  const result = env.model.dispatch("INSERT_NEW_PIVOT", { pivotId, newSheetId });
33337
33386
  if (result.isSuccessful) {
33338
33387
  env.openSidePanel("PivotSidePanel", { pivotId });
@@ -33391,7 +33440,7 @@ async function requestImage(env) {
33391
33440
  const CREATE_IMAGE = async (env) => {
33392
33441
  if (env.imageProvider) {
33393
33442
  const sheetId = env.model.getters.getActiveSheetId();
33394
- const figureId = env.model.uuidGenerator.uuidv4();
33443
+ const figureId = env.model.uuidGenerator.smallUuid();
33395
33444
  const image = await requestImage(env);
33396
33445
  if (!image) {
33397
33446
  throw new Error("No image provider was given to the environment");
@@ -33944,7 +33993,7 @@ const insertCheckbox = {
33944
33993
  ranges,
33945
33994
  sheetId,
33946
33995
  rule: {
33947
- id: env.model.uuidGenerator.uuidv4(),
33996
+ id: env.model.uuidGenerator.smallUuid(),
33948
33997
  criterion: {
33949
33998
  type: "isBoolean",
33950
33999
  values: [],
@@ -33960,7 +34009,7 @@ const insertDropdown = {
33960
34009
  const zones = env.model.getters.getSelectedZones();
33961
34010
  const sheetId = env.model.getters.getActiveSheetId();
33962
34011
  const ranges = zones.map((zone) => env.model.getters.getRangeDataFromZone(sheetId, zone));
33963
- const ruleID = env.model.uuidGenerator.uuidv4();
34012
+ const ruleID = env.model.uuidGenerator.smallUuid();
33964
34013
  env.model.dispatch("ADD_DATA_VALIDATION_RULE", {
33965
34014
  ranges,
33966
34015
  sheetId,
@@ -33991,7 +34040,7 @@ const insertSheet = {
33991
34040
  execute: (env) => {
33992
34041
  const activeSheetId = env.model.getters.getActiveSheetId();
33993
34042
  const position = env.model.getters.getSheetIds().indexOf(activeSheetId) + 1;
33994
- const sheetId = env.model.uuidGenerator.uuidv4();
34043
+ const sheetId = env.model.uuidGenerator.smallUuid();
33995
34044
  env.model.dispatch("CREATE_SHEET", { sheetId, position });
33996
34045
  env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
33997
34046
  },
@@ -37986,7 +38035,7 @@ class LineConfigPanel extends GenericChartConfigPanel {
37986
38035
  get canTreatLabelsAsText() {
37987
38036
  const chart = this.env.model.getters.getChart(this.props.figureId);
37988
38037
  if (chart && chart instanceof LineChart) {
37989
- return canChartParseLabels(chart.labelRange, this.env.model.getters);
38038
+ return canChartParseLabels(chart, this.env.model.getters);
37990
38039
  }
37991
38040
  return false;
37992
38041
  }
@@ -38055,7 +38104,7 @@ class ScatterConfigPanel extends GenericChartConfigPanel {
38055
38104
  get canTreatLabelsAsText() {
38056
38105
  const chart = this.env.model.getters.getChart(this.props.figureId);
38057
38106
  if (chart && chart instanceof ScatterChart) {
38058
- return canChartParseLabels(chart.labelRange, this.env.model.getters);
38107
+ return canChartParseLabels(chart, this.env.model.getters);
38059
38108
  }
38060
38109
  return false;
38061
38110
  }
@@ -39870,7 +39919,7 @@ class ConditionalFormattingEditor extends Component {
39870
39919
  state;
39871
39920
  setup() {
39872
39921
  const cf = this.props.editedCf || {
39873
- id: this.env.model.uuidGenerator.uuidv4(),
39922
+ id: this.env.model.uuidGenerator.smallUuid(),
39874
39923
  ranges: this.env.model.getters
39875
39924
  .getSelectedZones()
39876
39925
  .map((zone) => this.env.model.getters.zoneToXC(this.env.model.getters.getActiveSheetId(), zone)),
@@ -41466,7 +41515,7 @@ class DataValidationEditor extends Component {
41466
41515
  .getSelectedZones()
41467
41516
  .map((zone) => zoneToXc(this.env.model.getters.getUnboundedZone(sheetId, zone)));
41468
41517
  return {
41469
- id: this.env.model.uuidGenerator.uuidv4(),
41518
+ id: this.env.model.uuidGenerator.smallUuid(),
41470
41519
  criterion: { type: "textContains", values: [""] },
41471
41520
  ranges,
41472
41521
  };
@@ -42985,8 +43034,8 @@ class PivotTitleSection extends Component {
42985
43034
  return this.env.model.getters.getPivotDisplayName(this.props.pivotId);
42986
43035
  }
42987
43036
  duplicatePivot() {
42988
- const newPivotId = this.env.model.uuidGenerator.uuidv4();
42989
- const newSheetId = this.env.model.uuidGenerator.uuidv4();
43037
+ const newPivotId = this.env.model.uuidGenerator.smallUuid();
43038
+ const newSheetId = this.env.model.uuidGenerator.smallUuid();
42990
43039
  const result = this.env.model.dispatch("DUPLICATE_PIVOT_IN_NEW_SHEET", {
42991
43040
  pivotId: this.props.pivotId,
42992
43041
  newPivotId,
@@ -45551,7 +45600,7 @@ class TableStyleEditorPanel extends Component {
45551
45600
  this.state.selectedTemplateName = templateName;
45552
45601
  }
45553
45602
  onConfirm() {
45554
- const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.uuidv4();
45603
+ const tableStyleId = this.props.styleId || this.env.model.uuidGenerator.smallUuid();
45555
45604
  this.env.model.dispatch("CREATE_TABLE_STYLE", {
45556
45605
  tableStyleId,
45557
45606
  tableStyleName: this.state.styleName,
@@ -51147,6 +51196,10 @@ class CellPlugin extends CorePlugin {
51147
51196
  return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
51148
51197
  case "CLEAR_CELL":
51149
51198
  return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
51199
+ case "UPDATE_CELL_POSITION":
51200
+ return !cmd.cellId || this.cells[cmd.sheetId]?.[cmd.cellId]
51201
+ ? "Success" /* CommandResult.Success */
51202
+ : "InvalidCellId" /* CommandResult.InvalidCellId */;
51150
51203
  default:
51151
51204
  return "Success" /* CommandResult.Success */;
51152
51205
  }
@@ -51191,6 +51244,9 @@ class CellPlugin extends CorePlugin {
51191
51244
  case "DELETE_CONTENT":
51192
51245
  this.clearZones(cmd.sheetId, cmd.target);
51193
51246
  break;
51247
+ case "DELETE_SHEET": {
51248
+ this.history.update("cells", cmd.sheetId, undefined);
51249
+ }
51194
51250
  }
51195
51251
  }
51196
51252
  clearZones(sheetId, zones) {
@@ -52412,8 +52468,14 @@ class DataValidationPlugin extends CorePlugin {
52412
52468
  allowDispatch(cmd) {
52413
52469
  switch (cmd.type) {
52414
52470
  case "ADD_DATA_VALIDATION_RULE":
52471
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
52472
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
52473
+ }
52415
52474
  return this.checkValidations(cmd, this.chainValidations(this.checkEmptyRange, this.checkCriterionTypeIsValid, this.checkCriterionHasValidNumberOfValues, this.checkCriterionValuesAreValid));
52416
52475
  case "REMOVE_DATA_VALIDATION_RULE":
52476
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
52477
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
52478
+ }
52417
52479
  if (!this.rules[cmd.sheetId].find((rule) => rule.id === cmd.id)) {
52418
52480
  return "UnknownDataValidationRule" /* CommandResult.UnknownDataValidationRule */;
52419
52481
  }
@@ -52633,6 +52695,7 @@ class DataValidationPlugin extends CorePlugin {
52633
52695
  class FigurePlugin extends CorePlugin {
52634
52696
  static getters = ["getFigures", "getFigure", "getFigureSheetId"];
52635
52697
  figures = {};
52698
+ insertionOrders = []; // TODO use a list in master
52636
52699
  // ---------------------------------------------------------------------------
52637
52700
  // Command Handling
52638
52701
  // ---------------------------------------------------------------------------
@@ -52735,11 +52798,14 @@ class FigurePlugin extends CorePlugin {
52735
52798
  }
52736
52799
  addFigure(figure, sheetId) {
52737
52800
  this.history.update("figures", sheetId, figure.id, figure);
52801
+ this.history.update("insertionOrders", this.insertionOrders.length, figure.id);
52738
52802
  }
52739
52803
  deleteSheet(sheetId) {
52804
+ this.history.update("insertionOrders", this.insertionOrders.filter((id) => !this.figures[sheetId]?.[id]));
52740
52805
  this.history.update("figures", sheetId, undefined);
52741
52806
  }
52742
52807
  removeFigure(id, sheetId) {
52808
+ this.history.update("insertionOrders", this.insertionOrders.filter((figureId) => figureId !== id));
52743
52809
  this.history.update("figures", sheetId, id, undefined);
52744
52810
  }
52745
52811
  checkFigureExists(sheetId, figureId) {
@@ -52758,7 +52824,14 @@ class FigurePlugin extends CorePlugin {
52758
52824
  // Getters
52759
52825
  // ---------------------------------------------------------------------------
52760
52826
  getFigures(sheetId) {
52761
- return Object.values(this.figures[sheetId] || {}).filter(isDefined);
52827
+ const figures = [];
52828
+ for (const figureId of this.insertionOrders) {
52829
+ const figure = this.figures[sheetId]?.[figureId];
52830
+ if (figure) {
52831
+ figures.push(figure);
52832
+ }
52833
+ }
52834
+ return figures;
52762
52835
  }
52763
52836
  getFigure(sheetId, figureId) {
52764
52837
  return this.figures[sheetId]?.[figureId];
@@ -52771,11 +52844,9 @@ class FigurePlugin extends CorePlugin {
52771
52844
  // ---------------------------------------------------------------------------
52772
52845
  import(data) {
52773
52846
  for (let sheet of data.sheets) {
52774
- const figures = {};
52775
- sheet.figures.forEach((figure) => {
52776
- figures[figure.id] = figure;
52777
- });
52778
- this.figures[sheet.id] = figures;
52847
+ for (const figure of sheet.figures) {
52848
+ this.addFigure(figure, sheet.id);
52849
+ }
52779
52850
  }
52780
52851
  }
52781
52852
  export(data) {
@@ -54201,6 +54272,9 @@ class SheetPlugin extends CorePlugin {
54201
54272
  case "CREATE_SHEET": {
54202
54273
  return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
54203
54274
  }
54275
+ case "DUPLICATE_SHEET": {
54276
+ return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
54277
+ }
54204
54278
  case "MOVE_SHEET":
54205
54279
  try {
54206
54280
  const currentIndex = this.orderedSheetIds.findIndex((id) => id === cmd.sheetId);
@@ -54217,7 +54291,7 @@ class SheetPlugin extends CorePlugin {
54217
54291
  ? "Success" /* CommandResult.Success */
54218
54292
  : "InvalidColor" /* CommandResult.InvalidColor */;
54219
54293
  case "DELETE_SHEET":
54220
- return this.orderedSheetIds.length > 1
54294
+ return this.getVisibleSheetIds().length > 1
54221
54295
  ? "Success" /* CommandResult.Success */
54222
54296
  : "NotEnoughSheets" /* CommandResult.NotEnoughSheets */;
54223
54297
  case "ADD_COLUMNS_ROWS":
@@ -55012,6 +55086,10 @@ class SheetPlugin extends CorePlugin {
55012
55086
  checkZonesAreInSheet(cmd) {
55013
55087
  if (!("sheetId" in cmd))
55014
55088
  return "Success" /* CommandResult.Success */;
55089
+ if ("ranges" in cmd &&
55090
+ cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
55091
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
55092
+ }
55015
55093
  return this.checkZonesExistInSheet(cmd.sheetId, this.getCommandZones(cmd));
55016
55094
  }
55017
55095
  }
@@ -55019,6 +55097,7 @@ class SheetPlugin extends CorePlugin {
55019
55097
  class TablePlugin extends CorePlugin {
55020
55098
  static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
55021
55099
  tables = {};
55100
+ insertionOrders = {};
55022
55101
  adaptRanges(applyChange, sheetId) {
55023
55102
  const sheetIds = sheetId ? [sheetId] : this.getters.getSheetIds();
55024
55103
  for (const sheetId of sheetIds) {
@@ -55030,6 +55109,9 @@ class TablePlugin extends CorePlugin {
55030
55109
  allowDispatch(cmd) {
55031
55110
  switch (cmd.type) {
55032
55111
  case "CREATE_TABLE":
55112
+ if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId) || rangeData._sheetId !== cmd.sheetId)) {
55113
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
55114
+ }
55033
55115
  const zones = cmd.ranges.map((rangeData) => this.getters.getRangeFromRangeData(rangeData).zone);
55034
55116
  if (!areZonesContinuous(zones)) {
55035
55117
  return "NonContinuousTargets" /* CommandResult.NonContinuousTargets */;
@@ -55060,11 +55142,13 @@ class TablePlugin extends CorePlugin {
55060
55142
  switch (cmd.type) {
55061
55143
  case "CREATE_SHEET":
55062
55144
  this.history.update("tables", cmd.sheetId, {});
55145
+ this.history.update("insertionOrders", cmd.sheetId, []);
55063
55146
  break;
55064
55147
  case "DELETE_SHEET": {
55065
55148
  const tables = { ...this.tables };
55066
55149
  delete tables[cmd.sheetId];
55067
55150
  this.history.update("tables", tables);
55151
+ this.history.update("insertionOrders", cmd.sheetId, undefined);
55068
55152
  break;
55069
55153
  }
55070
55154
  case "DUPLICATE_SHEET": {
@@ -55076,6 +55160,9 @@ class TablePlugin extends CorePlugin {
55076
55160
  : this.copyStaticTableForSheet(cmd.sheetIdTo, table);
55077
55161
  }
55078
55162
  this.history.update("tables", cmd.sheetIdTo, newTables);
55163
+ this.history.update("insertionOrders", cmd.sheetIdTo, [
55164
+ ...(this.insertionOrders[cmd.sheetId] ?? []),
55165
+ ]);
55079
55166
  break;
55080
55167
  }
55081
55168
  case "CREATE_TABLE": {
@@ -55083,12 +55170,16 @@ class TablePlugin extends CorePlugin {
55083
55170
  const union = this.getters.getRangesUnion(ranges);
55084
55171
  const mergesInTarget = this.getters.getMergesInZone(cmd.sheetId, union.zone);
55085
55172
  this.dispatch("REMOVE_MERGE", { sheetId: cmd.sheetId, target: mergesInTarget });
55086
- const id = this.uuidGenerator.uuidv4();
55173
+ const id = this.uuidGenerator.smallUuid();
55087
55174
  const config = cmd.config || DEFAULT_TABLE_CONFIG;
55088
55175
  const newTable = cmd.tableType === "dynamic"
55089
55176
  ? this.createDynamicTable(id, union, config)
55090
55177
  : this.createStaticTable(id, cmd.tableType, union, config);
55091
55178
  this.history.update("tables", cmd.sheetId, newTable.id, newTable);
55179
+ this.history.update("insertionOrders", cmd.sheetId, [
55180
+ ...(this.insertionOrders[cmd.sheetId] ?? []),
55181
+ newTable.id,
55182
+ ]);
55092
55183
  break;
55093
55184
  }
55094
55185
  case "REMOVE_TABLE": {
@@ -55099,6 +55190,7 @@ class TablePlugin extends CorePlugin {
55099
55190
  }
55100
55191
  }
55101
55192
  this.history.update("tables", cmd.sheetId, tables);
55193
+ this.history.update("insertionOrders", cmd.sheetId, this.insertionOrders[cmd.sheetId]?.filter((id) => id in tables));
55102
55194
  break;
55103
55195
  }
55104
55196
  case "UPDATE_TABLE": {
@@ -55134,7 +55226,14 @@ class TablePlugin extends CorePlugin {
55134
55226
  }
55135
55227
  }
55136
55228
  getCoreTables(sheetId) {
55137
- return this.tables[sheetId] ? Object.values(this.tables[sheetId]).filter(isDefined) : [];
55229
+ const tables = [];
55230
+ for (const tableId of this.insertionOrders[sheetId] || []) {
55231
+ const table = this.tables[sheetId][tableId];
55232
+ if (table) {
55233
+ tables.push(table);
55234
+ }
55235
+ }
55236
+ return tables;
55138
55237
  }
55139
55238
  getCoreTable({ sheetId, col, row }) {
55140
55239
  return this.getCoreTables(sheetId).find((table) => isInside(col, row, table.range.zone));
@@ -55236,7 +55335,7 @@ class TablePlugin extends CorePlugin {
55236
55335
  filters = [];
55237
55336
  for (const i of range(zone.left, zone.right + 1)) {
55238
55337
  const filterZone = { ...zone, left: i, right: i };
55239
- const uid = this.uuidGenerator.uuidv4();
55338
+ const uid = this.uuidGenerator.smallUuid();
55240
55339
  filters.push(this.createFilterFromZone(uid, tableRange.sheetId, filterZone, config));
55241
55340
  }
55242
55341
  }
@@ -55301,7 +55400,7 @@ class TablePlugin extends CorePlugin {
55301
55400
  ? table.filters.find((f) => f.col === i)
55302
55401
  : undefined;
55303
55402
  const filterZone = { ...tableZone, left: i, right: i };
55304
- const filterId = oldFilter?.id || this.uuidGenerator.uuidv4();
55403
+ const filterId = oldFilter?.id || this.uuidGenerator.smallUuid();
55305
55404
  filters.push(this.createFilterFromZone(filterId, tableRange.sheetId, filterZone, config));
55306
55405
  }
55307
55406
  }
@@ -55402,7 +55501,7 @@ class TablePlugin extends CorePlugin {
55402
55501
  if (filters.length < zoneToDimension(tableZone).numberOfCols) {
55403
55502
  for (let col = tableZone.left; col <= tableZone.right; col++) {
55404
55503
  if (!filters.find((filter) => filter.col === col)) {
55405
- const uid = this.uuidGenerator.uuidv4();
55504
+ const uid = this.uuidGenerator.smallUuid();
55406
55505
  const filterZone = { ...tableZone, left: col, right: col };
55407
55506
  filters.push(this.createFilterFromZone(uid, sheetId, filterZone, table.config));
55408
55507
  }
@@ -55417,6 +55516,7 @@ class TablePlugin extends CorePlugin {
55417
55516
  // ---------------------------------------------------------------------------
55418
55517
  import(data) {
55419
55518
  for (const sheet of data.sheets) {
55519
+ const tableIds = [];
55420
55520
  for (const tableData of sheet.tables || []) {
55421
55521
  const uuid = this.uuidGenerator.uuidv4();
55422
55522
  const tableConfig = tableData.config || DEFAULT_TABLE_CONFIG;
@@ -55426,7 +55526,9 @@ class TablePlugin extends CorePlugin {
55426
55526
  ? this.createDynamicTable(uuid, range, tableConfig)
55427
55527
  : this.createStaticTable(uuid, tableType, range, tableConfig);
55428
55528
  this.history.update("tables", sheet.id, table.id, table);
55529
+ tableIds.push(table.id);
55429
55530
  }
55531
+ this.history.update("insertionOrders", sheet.id, tableIds);
55430
55532
  }
55431
55533
  }
55432
55534
  export(data) {
@@ -55466,7 +55568,10 @@ class HeaderGroupingPlugin extends CorePlugin {
55466
55568
  allowDispatch(cmd) {
55467
55569
  switch (cmd.type) {
55468
55570
  case "GROUP_HEADERS": {
55469
- const { start, end } = cmd;
55571
+ const { start, end, sheetId } = cmd;
55572
+ if (!this.getters.tryGetSheet(sheetId)) {
55573
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
55574
+ }
55470
55575
  if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
55471
55576
  return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
55472
55577
  }
@@ -55479,7 +55584,10 @@ class HeaderGroupingPlugin extends CorePlugin {
55479
55584
  break;
55480
55585
  }
55481
55586
  case "UNGROUP_HEADERS": {
55482
- const { start, end } = cmd;
55587
+ const { start, end, sheetId } = cmd;
55588
+ if (!this.getters.tryGetSheet(sheetId)) {
55589
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
55590
+ }
55483
55591
  if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
55484
55592
  return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
55485
55593
  }
@@ -55490,6 +55598,9 @@ class HeaderGroupingPlugin extends CorePlugin {
55490
55598
  }
55491
55599
  case "UNFOLD_HEADER_GROUP":
55492
55600
  case "FOLD_HEADER_GROUP":
55601
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
55602
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
55603
+ }
55493
55604
  const group = this.findGroupWithStartEnd(cmd.sheetId, cmd.dimension, cmd.start, cmd.end);
55494
55605
  if (!group) {
55495
55606
  return "UnknownHeaderGroup" /* CommandResult.UnknownHeaderGroup */;
@@ -55890,6 +56001,9 @@ class PivotCorePlugin extends CorePlugin {
55890
56001
  return this.checkDuplicatedMeasureIds(cmd.pivot);
55891
56002
  }
55892
56003
  case "UPDATE_PIVOT": {
56004
+ if (!(cmd.pivotId in this.pivots)) {
56005
+ return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
56006
+ }
55893
56007
  if (deepEquals(cmd.pivot, this.pivots[cmd.pivotId]?.definition)) {
55894
56008
  return "NoChanges" /* CommandResult.NoChanges */;
55895
56009
  }
@@ -55906,6 +56020,8 @@ class PivotCorePlugin extends CorePlugin {
55906
56020
  return "EmptyName" /* CommandResult.EmptyName */;
55907
56021
  }
55908
56022
  break;
56023
+ case "REMOVE_PIVOT":
56024
+ case "DUPLICATE_PIVOT":
55909
56025
  case "INSERT_PIVOT": {
55910
56026
  if (!(cmd.pivotId in this.pivots)) {
55911
56027
  return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
@@ -55955,7 +56071,7 @@ class PivotCorePlugin extends CorePlugin {
55955
56071
  break;
55956
56072
  }
55957
56073
  case "UPDATE_PIVOT": {
55958
- this.history.update("pivots", cmd.pivotId, "definition", cmd.pivot);
56074
+ this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
55959
56075
  this.compileCalculatedMeasures(cmd.pivot.measures);
55960
56076
  break;
55961
56077
  }
@@ -56026,7 +56142,7 @@ class PivotCorePlugin extends CorePlugin {
56026
56142
  // Private
56027
56143
  // -------------------------------------------------------------------------
56028
56144
  addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
56029
- this.history.update("pivots", pivotId, { definition: pivot, formulaId });
56145
+ this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
56030
56146
  this.compileCalculatedMeasures(pivot.measures);
56031
56147
  this.history.update("formulaIds", formulaId, pivotId);
56032
56148
  this.history.update("nextFormulaId", this.nextFormulaId + 1);
@@ -60958,6 +61074,9 @@ function updateChartRangesTransformation(toTransform, executed) {
60958
61074
  };
60959
61075
  }
60960
61076
  function createSheetTransformation(toTransform, executed) {
61077
+ if (toTransform.sheetId === executed.sheetId) {
61078
+ toTransform = { ...toTransform, sheetId: `${toTransform.sheetId}~` };
61079
+ }
60961
61080
  if (toTransform.name === executed.name) {
60962
61081
  return {
60963
61082
  ...toTransform,
@@ -61610,21 +61729,14 @@ class Session extends EventBus {
61610
61729
  if (!message)
61611
61730
  return;
61612
61731
  if (message.type === "REMOTE_REVISION") {
61613
- const revision = this.revisions.get(message.nextRevisionId);
61732
+ let revision = this.revisions.get(message.nextRevisionId);
61614
61733
  if (revision.commands.length === 0) {
61615
61734
  /**
61616
- * The command is empty, we have to drop all the next local revisions
61735
+ * The command is empty, we have to rebase all the next local revisions
61617
61736
  * to avoid issues with undo/redo
61618
61737
  */
61619
- this.revisions.drop(revision.id);
61620
- const revisionIds = this.pendingMessages
61621
- .filter((message) => message.type === "REMOTE_REVISION")
61622
- .map((message) => message.nextRevisionId);
61623
- this.trigger("pending-revisions-dropped", { revisionIds });
61624
- this.waitingAck = false;
61625
- this.waitingUndoRedoAck = false;
61626
- this.pendingMessages = [];
61627
- return;
61738
+ this.revisions.rebase(revision.id);
61739
+ revision = this.revisions.get(message.nextRevisionId);
61628
61740
  }
61629
61741
  message = {
61630
61742
  ...message,
@@ -61648,7 +61760,6 @@ class Session extends EventBus {
61648
61760
  switch (message.type) {
61649
61761
  case "REMOTE_REVISION":
61650
61762
  case "REVISION_REDONE":
61651
- case "REVISION_UNDONE":
61652
61763
  case "SNAPSHOT_CREATED":
61653
61764
  this.waitingAck = false;
61654
61765
  this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
@@ -61657,6 +61768,25 @@ class Session extends EventBus {
61657
61768
  this.lastRevisionMessage = message;
61658
61769
  this.sendPendingMessage();
61659
61770
  break;
61771
+ case "REVISION_UNDONE": {
61772
+ this.waitingAck = false;
61773
+ this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
61774
+ const firstPendingRevisionId = this.pendingMessages.findIndex((message) => message.type === "REMOTE_REVISION");
61775
+ if (firstPendingRevisionId !== -1) {
61776
+ /**
61777
+ * Some revisions undergo transformations that may cause issues with
61778
+ * undo/redo if the transformation is destructive (we don't get back
61779
+ * the original command by transforming it with the inverse).
61780
+ * To prevent these problems, we must rebase all subsequent local
61781
+ * revisions.
61782
+ */
61783
+ this.revisions.rebase(this.pendingMessages[firstPendingRevisionId].nextRevisionId);
61784
+ }
61785
+ this.serverRevisionId = message.nextRevisionId;
61786
+ this.processedRevisions.add(message.nextRevisionId);
61787
+ this.sendPendingMessage();
61788
+ break;
61789
+ }
61660
61790
  }
61661
61791
  }
61662
61792
  isAlreadyProcessed(message) {
@@ -62739,6 +62869,10 @@ class SheetUIPlugin extends UIPlugin {
62739
62869
  */
62740
62870
  checkZonesAreInSheet(cmd) {
62741
62871
  const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.tryGetActiveSheetId();
62872
+ if ("ranges" in cmd &&
62873
+ cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
62874
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
62875
+ }
62742
62876
  const zones = this.getters.getCommandZones(cmd);
62743
62877
  if (!sheetId && zones.length > 0) {
62744
62878
  return "NoActiveSheet" /* CommandResult.NoActiveSheet */;
@@ -63088,23 +63222,23 @@ const uuidGenerator = new UuidGenerator();
63088
63222
  function repeatCreateChartCommand(getters, cmd) {
63089
63223
  return {
63090
63224
  ...repeatSheetDependantCommand(getters, cmd),
63091
- id: uuidGenerator.uuidv4(),
63225
+ id: uuidGenerator.smallUuid(),
63092
63226
  };
63093
63227
  }
63094
63228
  function repeatCreateImageCommand(getters, cmd) {
63095
63229
  return {
63096
63230
  ...repeatSheetDependantCommand(getters, cmd),
63097
- figureId: uuidGenerator.uuidv4(),
63231
+ figureId: uuidGenerator.smallUuid(),
63098
63232
  };
63099
63233
  }
63100
63234
  function repeatCreateFigureCommand(getters, cmd) {
63101
63235
  const newCmd = repeatSheetDependantCommand(getters, cmd);
63102
- newCmd.figure.id = uuidGenerator.uuidv4();
63236
+ newCmd.figure.id = uuidGenerator.smallUuid();
63103
63237
  return newCmd;
63104
63238
  }
63105
63239
  function repeatCreateSheetCommand(getters, cmd) {
63106
63240
  const newCmd = deepCopy(cmd);
63107
- newCmd.sheetId = uuidGenerator.uuidv4();
63241
+ newCmd.sheetId = uuidGenerator.smallUuid();
63108
63242
  const sheetName = cmd.name || getters.getSheet(getters.getActiveSheetId()).name;
63109
63243
  // Extract the prefix of the sheet name (everything before the number at the end of the name)
63110
63244
  const namePrefix = sheetName.match(/(.+?)\d*$/)?.[1] || sheetName;
@@ -63293,7 +63427,6 @@ class HistoryPlugin extends UIPlugin {
63293
63427
  super(config);
63294
63428
  this.session = config.session;
63295
63429
  this.session.on("new-local-state-update", this, this.onNewLocalStateUpdate);
63296
- this.session.on("pending-revisions-dropped", this, ({ revisionIds }) => this.drop(revisionIds));
63297
63430
  this.session.on("snapshot", this, () => {
63298
63431
  this.undoStack = [];
63299
63432
  this.redoStack = [];
@@ -63363,10 +63496,6 @@ class HistoryPlugin extends UIPlugin {
63363
63496
  const lastNonRedoRevision = this.getPossibleRevisionToRepeat();
63364
63497
  return canRepeatRevision(lastNonRedoRevision);
63365
63498
  }
63366
- drop(revisionIds) {
63367
- this.undoStack = this.undoStack.filter((id) => !revisionIds.includes(id));
63368
- this.redoStack = [];
63369
- }
63370
63499
  onNewLocalStateUpdate({ id }) {
63371
63500
  this.undoStack.push(id);
63372
63501
  this.redoStack = [];
@@ -64567,23 +64696,7 @@ class GridSelectionPlugin extends UIPlugin {
64567
64696
  gridSelection: deepCopy(gridSelection),
64568
64697
  };
64569
64698
  }
64570
- if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
64571
- const currentSheetIds = this.getters.getVisibleSheetIds();
64572
- this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
64573
- if (this.activeSheet.id in this.sheetsData) {
64574
- const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
64575
- this.selectCell(anchor.cell.col, anchor.cell.row);
64576
- }
64577
- else {
64578
- this.selectCell(0, 0);
64579
- }
64580
- const { col, row } = this.gridSelection.anchor.cell;
64581
- this.moveClient({
64582
- sheetId: this.getters.getActiveSheetId(),
64583
- col,
64584
- row,
64585
- });
64586
- }
64699
+ this.fallbackToVisibleSheet();
64587
64700
  const sheetId = this.getters.getActiveSheetId();
64588
64701
  this.gridSelection.zones = this.gridSelection.zones.map((z) => this.getters.expandZone(sheetId, z));
64589
64702
  this.gridSelection.anchor.zone = this.getters.expandZone(sheetId, this.gridSelection.anchor.zone);
@@ -64593,6 +64706,7 @@ class GridSelectionPlugin extends UIPlugin {
64593
64706
  }
64594
64707
  }
64595
64708
  finalize() {
64709
+ this.fallbackToVisibleSheet();
64596
64710
  /** Any change to the selection has to be reflected in the selection processor. */
64597
64711
  this.selection.resetDefaultAnchor(this, deepCopy(this.gridSelection.anchor));
64598
64712
  }
@@ -64896,6 +65010,25 @@ class GridSelectionPlugin extends UIPlugin {
64896
65010
  }
64897
65011
  return "Success" /* CommandResult.Success */;
64898
65012
  }
65013
+ fallbackToVisibleSheet() {
65014
+ if (!this.getters.tryGetSheet(this.getters.getActiveSheetId())) {
65015
+ const currentSheetIds = this.getters.getVisibleSheetIds();
65016
+ this.activeSheet = this.getters.getSheet(currentSheetIds[0]);
65017
+ if (this.activeSheet.id in this.sheetsData) {
65018
+ const { anchor } = this.clipSelection(this.activeSheet.id, this.sheetsData[this.activeSheet.id].gridSelection);
65019
+ this.selectCell(anchor.cell.col, anchor.cell.row);
65020
+ }
65021
+ else {
65022
+ this.selectCell(0, 0);
65023
+ }
65024
+ const { col, row } = this.gridSelection.anchor.cell;
65025
+ this.moveClient({
65026
+ sheetId: this.getters.getActiveSheetId(),
65027
+ col,
65028
+ row,
65029
+ });
65030
+ }
65031
+ }
64899
65032
  //-------------------------------------------
64900
65033
  // Helpers for extensions
64901
65034
  // ------------------------------------------
@@ -66062,7 +66195,9 @@ class HeaderPositionsUIPlugin extends UIPlugin {
66062
66195
  case "UNGROUP_HEADERS":
66063
66196
  case "GROUP_HEADERS":
66064
66197
  case "CREATE_SHEET":
66065
- this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
66198
+ if (this.getters.tryGetSheet(cmd.sheetId)) {
66199
+ this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
66200
+ }
66066
66201
  break;
66067
66202
  case "DUPLICATE_SHEET":
66068
66203
  this.headerPositions[cmd.sheetIdTo] = deepCopy(this.headerPositions[cmd.sheetId]);
@@ -66070,12 +66205,14 @@ class HeaderPositionsUIPlugin extends UIPlugin {
66070
66205
  }
66071
66206
  }
66072
66207
  finalize() {
66073
- if (this.isDirty) {
66074
- for (const sheetId of this.getters.getSheetIds()) {
66208
+ for (const sheetId of this.getters.getSheetIds()) {
66209
+ // sheets can be created without this plugin being aware of it
66210
+ // in concurrent situations.
66211
+ if (this.isDirty || !this.headerPositions[sheetId]) {
66075
66212
  this.headerPositions[sheetId] = this.computeHeaderPositionsOfSheet(sheetId);
66076
66213
  }
66077
- this.isDirty = false;
66078
66214
  }
66215
+ this.isDirty = false;
66079
66216
  }
66080
66217
  /**
66081
66218
  * Returns the size, start and end coordinates of a column on an unfolded sheet
@@ -66898,7 +67035,7 @@ class BottomBar extends Component {
66898
67035
  clickAddSheet(ev) {
66899
67036
  const activeSheetId = this.env.model.getters.getActiveSheetId();
66900
67037
  const position = this.env.model.getters.getSheetIds().findIndex((sheetId) => sheetId === activeSheetId) + 1;
66901
- const sheetId = this.env.model.uuidGenerator.uuidv4();
67038
+ const sheetId = this.env.model.uuidGenerator.smallUuid();
66902
67039
  const name = this.env.model.getters.getNextSheetName(_t("Sheet"));
66903
67040
  this.env.model.dispatch("CREATE_SHEET", { sheetId, position, name });
66904
67041
  this.env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom: activeSheetId, sheetIdTo: sheetId });
@@ -67986,7 +68123,7 @@ css /* scss */ `
67986
68123
  .o-font-size-editor {
67987
68124
  height: calc(100% - 4px);
67988
68125
  input.o-font-size {
67989
- outline-color: ${SELECTION_BORDER_COLOR};
68126
+ outline: none;
67990
68127
  height: 20px;
67991
68128
  width: 23px;
67992
68129
  }
@@ -69273,7 +69410,7 @@ class Tree {
69273
69410
  }
69274
69411
  /**
69275
69412
  * Drop the operation and all following operations in every
69276
- * branch
69413
+ * branches
69277
69414
  */
69278
69415
  drop(operationId) {
69279
69416
  for (const branch of this.branches) {
@@ -69578,9 +69715,16 @@ class SelectiveHistory {
69578
69715
  this.fastForward();
69579
69716
  this.insert(redoId, this.buildEmpty(redoId), insertAfter);
69580
69717
  }
69581
- drop(operationId) {
69718
+ rebase(operationId) {
69719
+ const operation = this.get(operationId);
69720
+ const execution = [...this.tree.execution(this.HEAD_BRANCH).startAfter(operationId)];
69582
69721
  this.revertBefore(operationId);
69722
+ const baseId = this.HEAD_OPERATION.id;
69583
69723
  this.tree.drop(operationId);
69724
+ this.insert(operationId, operation, baseId);
69725
+ for (const { operation } of execution) {
69726
+ this.insert(operation.id, operation.data, this.HEAD_OPERATION.id);
69727
+ }
69584
69728
  }
69585
69729
  /**
69586
69730
  * Revert the state as it was *before* the given operation was executed.
@@ -72622,6 +72766,11 @@ class Model extends EventBus {
72622
72766
  dispatch: (command) => {
72623
72767
  const result = this.checkDispatchAllowed(command);
72624
72768
  if (!result.isSuccessful) {
72769
+ // core views plugins need to be invalidated
72770
+ this.dispatchToHandlers(this.coreHandlers, {
72771
+ type: "UNDO",
72772
+ commands: [command],
72773
+ });
72625
72774
  return;
72626
72775
  }
72627
72776
  this.isReplayingCommand = true;
@@ -72650,7 +72799,7 @@ class Model extends EventBus {
72650
72799
  }
72651
72800
  setupConfig(config) {
72652
72801
  const client = config.client || {
72653
- id: this.uuidGenerator.uuidv4(),
72802
+ id: this.uuidGenerator.smallUuid(),
72654
72803
  name: _t("Anonymous").toString(),
72655
72804
  };
72656
72805
  const transportService = config.transportService || new LocalTransportService();
@@ -73137,6 +73286,6 @@ const constants = {
73137
73286
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, 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 };
73138
73287
 
73139
73288
 
73140
- __info__.version = "18.0.15";
73141
- __info__.date = "2025-02-10T08:59:22.993Z";
73142
- __info__.hash = "5b19f88";
73289
+ __info__.version = "18.0.17";
73290
+ __info__.date = "2025-02-25T05:58:39.632Z";
73291
+ __info__.hash = "2ee4347";