@odoo/o-spreadsheet 17.1.9 → 17.1.11

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 17.1.9
6
- * @date 2024-03-25T09:43:27.017Z
7
- * @hash 5fb076e
5
+ * @version 17.1.11
6
+ * @date 2024-04-10T12:27:11.107Z
7
+ * @hash 246caf7
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -459,7 +459,7 @@
459
459
  }
460
460
  // Generate new Id if the item didn't exist in the dictionary
461
461
  const ids = Object.keys(itemsDic);
462
- const maxId = ids.length === 0 ? 0 : Math.max(...ids.map((id) => parseInt(id, 10)));
462
+ const maxId = ids.length === 0 ? 0 : largeMax(ids.map((id) => parseInt(id, 10)));
463
463
  itemsDic[maxId + 1] = item;
464
464
  return maxId + 1;
465
465
  }
@@ -550,7 +550,7 @@
550
550
  if (typeof o1 !== typeof o2)
551
551
  return false;
552
552
  if (typeof o1 !== "object")
553
- return o1 === o2;
553
+ return false;
554
554
  // Objects can have different keys if the values are undefined
555
555
  for (const key in o2) {
556
556
  if (!(key in o1) && o2[key] !== undefined) {
@@ -676,6 +676,34 @@
676
676
  }
677
677
  return value >= min && value <= max;
678
678
  }
679
+ /**
680
+ * Alternative to Math.max that works with large arrays.
681
+ * Typically useful for arrays bigger than 100k elements.
682
+ */
683
+ function largeMax(array) {
684
+ let len = array.length;
685
+ if (len < 100000)
686
+ return Math.max(...array);
687
+ let max = -Infinity;
688
+ while (len--) {
689
+ max = array[len] > max ? array[len] : max;
690
+ }
691
+ return max;
692
+ }
693
+ /**
694
+ * Alternative to Math.min that works with large arrays.
695
+ * Typically useful for arrays bigger than 100k elements.
696
+ */
697
+ function largeMin(array) {
698
+ let len = array.length;
699
+ if (len < 100000)
700
+ return Math.min(...array);
701
+ let min = +Infinity;
702
+ while (len--) {
703
+ min = array[len] < min ? array[len] : min;
704
+ }
705
+ return min;
706
+ }
679
707
 
680
708
  const RBA_REGEX = /rgba?\(|\s+|\)/gi;
681
709
  const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/;
@@ -4478,8 +4506,9 @@
4478
4506
  * Get the default height of the cell given its style.
4479
4507
  */
4480
4508
  function getDefaultCellHeight(ctx, cell, colSize) {
4481
- if (!cell || !cell.content)
4509
+ if (!cell || (!cell.isFormula && !cell.content)) {
4482
4510
  return DEFAULT_CELL_HEIGHT;
4511
+ }
4483
4512
  const maxWidth = cell.style?.wrapping === "wrap" ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
4484
4513
  const numberOfLines = cell.isFormula
4485
4514
  ? 1
@@ -8381,10 +8410,10 @@
8381
8410
  }
8382
8411
  }
8383
8412
  return {
8384
- labels: Object.keys(labelMap),
8413
+ labels: Array.from(labelSet),
8385
8414
  dataSetsValues: datasets.map((dataset, indexOfDataset) => ({
8386
8415
  ...dataset,
8387
- data: Object.values(labelMap).map((dataOfLabel) => dataOfLabel[indexOfDataset]),
8416
+ data: Array.from(labelSet).map((label) => labelMap[label][indexOfDataset]),
8388
8417
  })),
8389
8418
  };
8390
8419
  }
@@ -8435,7 +8464,7 @@
8435
8464
  const xLabel = tooltipItem.dataset?.label || tooltipItem.label;
8436
8465
  // tooltipItem.parsed.y can be an object or a number for pie charts
8437
8466
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
8438
- const toolTipFormat = !format && yLabel > 1000 ? "#,##" : format;
8467
+ const toolTipFormat = !format && Math.abs(yLabel) >= 1000 ? "#,##" : format;
8439
8468
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
8440
8469
  return xLabel ? `${xLabel}: ${yLabelStr}` : yLabelStr;
8441
8470
  },
@@ -8722,7 +8751,10 @@
8722
8751
  if (isNaN(value))
8723
8752
  return value;
8724
8753
  const { locale, format } = localeFormat;
8725
- return formatValue(value, { locale, format: !format && value > 1000 ? "#,##" : format });
8754
+ return formatValue(value, {
8755
+ locale,
8756
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
8757
+ });
8726
8758
  },
8727
8759
  },
8728
8760
  },
@@ -9136,7 +9168,7 @@
9136
9168
  return undefined;
9137
9169
  }
9138
9170
  const labelsTimestamps = labelDates.map((date) => date.getTime());
9139
- const period = Math.max(...labelsTimestamps) - Math.min(...labelsTimestamps);
9171
+ const period = largeMax(labelsTimestamps) - largeMin(labelsTimestamps);
9140
9172
  const minUnit = getFormatMinDisplayUnit(format);
9141
9173
  if (UNIT_LENGTH.second >= UNIT_LENGTH[minUnit] && Milliseconds.inSeconds(period) < 180) {
9142
9174
  return "second";
@@ -9373,7 +9405,10 @@
9373
9405
  if (isNaN(value))
9374
9406
  return value;
9375
9407
  const { locale, format } = localeFormat;
9376
- return formatValue(value, { locale, format: !format && value > 1000 ? "#,##" : format });
9408
+ return formatValue(value, {
9409
+ locale,
9410
+ format: !format && Math.abs(value) >= 1000 ? "#,##" : format,
9411
+ });
9377
9412
  },
9378
9413
  },
9379
9414
  },
@@ -9600,7 +9635,7 @@
9600
9635
  const percentage = calculatePercentage(data, dataIndex);
9601
9636
  const xLabel = tooltipItem.label || tooltipItem.dataset.label;
9602
9637
  const yLabel = tooltipItem.parsed.y ?? tooltipItem.parsed;
9603
- const toolTipFormat = !format && yLabel > 1000 ? "#,##" : format;
9638
+ const toolTipFormat = !format && yLabel >= 1000 ? "#,##" : format;
9604
9639
  const yLabelStr = formatValue(yLabel, { format: toolTipFormat, locale });
9605
9640
  return xLabel ? `${xLabel}: ${yLabelStr} (${percentage}%)` : `${yLabelStr} (${percentage}%)`;
9606
9641
  };
@@ -9608,7 +9643,7 @@
9608
9643
  }
9609
9644
  function getPieColors(colors, dataSetsValues) {
9610
9645
  const pieColors = [];
9611
- const maxLength = Math.max(...dataSetsValues.map((ds) => ds.data.length));
9646
+ const maxLength = largeMax(dataSetsValues.map((ds) => ds.data.length));
9612
9647
  for (let i = 0; i <= maxLength; i++) {
9613
9648
  pieColors.push(colors.next());
9614
9649
  }
@@ -10532,8 +10567,8 @@
10532
10567
  let last;
10533
10568
  const activesRows = env.model.getters.getActiveRows();
10534
10569
  if (activesRows.size !== 0) {
10535
- first = Math.min(...activesRows);
10536
- last = Math.max(...activesRows);
10570
+ first = largeMin([...activesRows]);
10571
+ last = largeMax([...activesRows]);
10537
10572
  }
10538
10573
  else {
10539
10574
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10561,8 +10596,8 @@
10561
10596
  let last;
10562
10597
  const activeCols = env.model.getters.getActiveCols();
10563
10598
  if (activeCols.size !== 0) {
10564
- first = Math.min(...activeCols);
10565
- last = Math.max(...activeCols);
10599
+ first = largeMin([...activeCols]);
10600
+ last = largeMax([...activeCols]);
10566
10601
  }
10567
10602
  else {
10568
10603
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10590,8 +10625,8 @@
10590
10625
  let last;
10591
10626
  const activesRows = env.model.getters.getActiveRows();
10592
10627
  if (activesRows.size !== 0) {
10593
- first = Math.min(...activesRows);
10594
- last = Math.max(...activesRows);
10628
+ first = largeMin([...activesRows]);
10629
+ last = largeMax([...activesRows]);
10595
10630
  }
10596
10631
  else {
10597
10632
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10632,8 +10667,8 @@
10632
10667
  let last;
10633
10668
  const activeCols = env.model.getters.getActiveCols();
10634
10669
  if (activeCols.size !== 0) {
10635
- first = Math.min(...activeCols);
10636
- last = Math.max(...activeCols);
10670
+ first = largeMin([...activeCols]);
10671
+ last = largeMax([...activeCols]);
10637
10672
  }
10638
10673
  else {
10639
10674
  const zone = env.model.getters.getSelectedZones()[0];
@@ -10674,7 +10709,7 @@
10674
10709
  let row;
10675
10710
  let quantity;
10676
10711
  if (activeRows.size) {
10677
- row = Math.min(...activeRows);
10712
+ row = largeMin([...activeRows]);
10678
10713
  quantity = activeRows.size;
10679
10714
  }
10680
10715
  else {
@@ -10695,7 +10730,7 @@
10695
10730
  let row;
10696
10731
  let quantity;
10697
10732
  if (activeRows.size) {
10698
- row = Math.max(...activeRows);
10733
+ row = largeMax([...activeRows]);
10699
10734
  quantity = activeRows.size;
10700
10735
  }
10701
10736
  else {
@@ -10716,7 +10751,7 @@
10716
10751
  let column;
10717
10752
  let quantity;
10718
10753
  if (activeCols.size) {
10719
- column = Math.min(...activeCols);
10754
+ column = largeMin([...activeCols]);
10720
10755
  quantity = activeCols.size;
10721
10756
  }
10722
10757
  else {
@@ -10737,7 +10772,7 @@
10737
10772
  let column;
10738
10773
  let quantity;
10739
10774
  if (activeCols.size) {
10740
- column = Math.max(...activeCols);
10775
+ column = largeMax([...activeCols]);
10741
10776
  quantity = activeCols.size;
10742
10777
  }
10743
10778
  else {
@@ -27073,6 +27108,7 @@
27073
27108
  onComposerCellFocused: { type: Function, optional: true },
27074
27109
  onComposerContentFocused: Function,
27075
27110
  isDefaultFocus: { type: Boolean, optional: true },
27111
+ onInputContextMenu: { type: Function, optional: true },
27076
27112
  };
27077
27113
  static components = { TextValueProvider, FunctionDescriptionProvider };
27078
27114
  static defaultProps = {
@@ -27431,6 +27467,11 @@
27431
27467
  }
27432
27468
  }
27433
27469
  }
27470
+ onContextMenu(ev) {
27471
+ if (this.env.model.getters.getEditionMode() === "inactive") {
27472
+ this.props.onInputContextMenu?.(ev);
27473
+ }
27474
+ }
27434
27475
  // ---------------------------------------------------------------------------
27435
27476
  // Private
27436
27477
  // ---------------------------------------------------------------------------
@@ -27698,6 +27739,7 @@
27698
27739
  onComposerCellFocused: Function,
27699
27740
  onComposerContentFocused: Function,
27700
27741
  gridDims: Object,
27742
+ onInputContextMenu: Function,
27701
27743
  };
27702
27744
  static components = { Composer };
27703
27745
  rect = this.defaultRect;
@@ -27742,6 +27784,7 @@
27742
27784
  isDefaultFocus: true,
27743
27785
  onComposerContentFocused: this.props.onComposerContentFocused,
27744
27786
  onComposerCellFocused: this.props.onComposerCellFocused,
27787
+ onInputContextMenu: this.props.onInputContextMenu,
27745
27788
  };
27746
27789
  }
27747
27790
  get containerStyle() {
@@ -29218,11 +29261,6 @@
29218
29261
  height: 10000px;
29219
29262
  background-color: ${SELECTION_BORDER_COLOR};
29220
29263
  }
29221
- .o-unhide-buttons {
29222
- width: fit-content;
29223
- gap: 5px;
29224
- transform: translate(-50%, 0);
29225
- }
29226
29264
  .o-unhide:hover {
29227
29265
  z-index: ${ComponentsImportance.Grid + 1};
29228
29266
  background-color: lightgrey;
@@ -29384,10 +29422,6 @@
29384
29422
  height: 1px;
29385
29423
  background-color: ${SELECTION_BORDER_COLOR};
29386
29424
  }
29387
- .o-unhide-buttons {
29388
- height: fit-content;
29389
- transform: translate(0, -50%);
29390
- }
29391
29425
  .o-unhide:hover {
29392
29426
  z-index: ${ComponentsImportance.Grid + 1};
29393
29427
  background-color: lightgrey;
@@ -31748,29 +31782,12 @@
31748
31782
  return width;
31749
31783
  return Math.round((width / WIDTH_FACTOR) * 100) / 100;
31750
31784
  }
31751
- function convertBorderDescr(descr) {
31752
- if (!descr) {
31753
- return undefined;
31754
- }
31755
- return {
31756
- style: descr.style,
31757
- color: { rgb: descr.color },
31758
- };
31759
- }
31760
31785
  function extractStyle(cell, data) {
31761
31786
  let style = {};
31762
31787
  if (cell.style) {
31763
31788
  style = data.styles[cell.style];
31764
31789
  }
31765
31790
  const format = extractFormat(cell, data);
31766
- const exportedBorder = {};
31767
- if (cell.border) {
31768
- const border = data.borders[cell.border];
31769
- exportedBorder.left = convertBorderDescr(border.left);
31770
- exportedBorder.right = convertBorderDescr(border.right);
31771
- exportedBorder.bottom = convertBorderDescr(border.bottom);
31772
- exportedBorder.top = convertBorderDescr(border.top);
31773
- }
31774
31791
  const styles = {
31775
31792
  font: {
31776
31793
  size: style?.fontSize || DEFAULT_FONT_SIZE,
@@ -31784,7 +31801,7 @@
31784
31801
  }
31785
31802
  : { reservedAttribute: "none" },
31786
31803
  numFmt: format ? { format: format, id: 0 /* id not used for export */ } : undefined,
31787
- border: exportedBorder || {},
31804
+ border: cell.border || 0,
31788
31805
  alignment: {
31789
31806
  horizontal: style.align,
31790
31807
  vertical: style.verticalAlign
@@ -31806,15 +31823,12 @@
31806
31823
  return undefined;
31807
31824
  }
31808
31825
  function normalizeStyle(construct, styles) {
31809
- const { id: fontId } = pushElement(styles["font"], construct.fonts);
31810
- const { id: fillId } = pushElement(styles["fill"], construct.fills);
31811
- const { id: borderId } = pushElement(styles["border"], construct.borders);
31812
31826
  // Normalize this
31813
31827
  const numFmtId = convertFormat(styles["numFmt"], construct.numFmts);
31814
31828
  const style = {
31815
- fontId,
31816
- fillId,
31817
- borderId,
31829
+ fontId: pushElement(styles.font, construct.fonts),
31830
+ fillId: pushElement(styles.fill, construct.fills),
31831
+ borderId: styles.border,
31818
31832
  numFmtId,
31819
31833
  alignment: {
31820
31834
  vertical: styles.alignment.vertical,
@@ -31822,8 +31836,7 @@
31822
31836
  wrapText: styles.alignment.wrapText,
31823
31837
  },
31824
31838
  };
31825
- const { id } = pushElement(style, construct.styles);
31826
- return id;
31839
+ return pushElement(style, construct.styles);
31827
31840
  }
31828
31841
  function convertFormat(format, numFmtStructure) {
31829
31842
  if (!format) {
@@ -31831,8 +31844,7 @@
31831
31844
  }
31832
31845
  let formatId = XLSX_FORMAT_MAP[format.format];
31833
31846
  if (!formatId) {
31834
- const { id } = pushElement(format, numFmtStructure);
31835
- formatId = id + FIRST_NUMFMT_ID;
31847
+ formatId = pushElement(format, numFmtStructure) + FIRST_NUMFMT_ID;
31836
31848
  }
31837
31849
  return formatId;
31838
31850
  }
@@ -31857,20 +31869,15 @@
31857
31869
  return id;
31858
31870
  }
31859
31871
  function pushElement(property, propertyList) {
31860
- for (let [key, value] of Object.entries(propertyList)) {
31861
- if (JSON.stringify(value) === JSON.stringify(property)) {
31862
- return { id: parseInt(key, 10), list: propertyList };
31872
+ let len = propertyList.length;
31873
+ const operator = typeof property === "object" ? deepEquals : (a, b) => a === b;
31874
+ for (let i = 0; i < len; i++) {
31875
+ if (operator(property, propertyList[i])) {
31876
+ return i;
31863
31877
  }
31864
31878
  }
31865
- let elemId = propertyList.findIndex((elem) => JSON.stringify(elem) === JSON.stringify(property));
31866
- if (elemId === -1) {
31867
- propertyList.push(property);
31868
- elemId = propertyList.length - 1;
31869
- }
31870
- return {
31871
- id: elemId,
31872
- list: propertyList,
31873
- };
31879
+ propertyList[propertyList.length] = property;
31880
+ return propertyList.length - 1;
31874
31881
  }
31875
31882
  const chartIds = [];
31876
31883
  /**
@@ -32328,7 +32335,7 @@
32328
32335
  function getSheetDims(sheet) {
32329
32336
  const dims = [0, 0];
32330
32337
  for (let row of sheet.rows) {
32331
- dims[0] = Math.max(dims[0], ...row.cells.map((cell) => toCartesian(cell.xc).col));
32338
+ dims[0] = Math.max(dims[0], largeMax(row.cells.map((cell) => toCartesian(cell.xc).col)));
32332
32339
  dims[1] = Math.max(dims[1], row.index);
32333
32340
  }
32334
32341
  dims[0] = Math.max(dims[0], EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
@@ -32597,7 +32604,25 @@
32597
32604
  }
32598
32605
  return document;
32599
32606
  }
32600
- function getDefaultXLSXStructure() {
32607
+ function convertBorderDescr(descr) {
32608
+ if (!descr) {
32609
+ return undefined;
32610
+ }
32611
+ return {
32612
+ style: descr.style,
32613
+ color: { rgb: descr.color },
32614
+ };
32615
+ }
32616
+ function getDefaultXLSXStructure(data) {
32617
+ const xlsxBorders = Object.values(data.borders).map((border) => {
32618
+ return {
32619
+ left: convertBorderDescr(border.left),
32620
+ right: convertBorderDescr(border.right),
32621
+ bottom: convertBorderDescr(border.bottom),
32622
+ top: convertBorderDescr(border.top),
32623
+ };
32624
+ });
32625
+ const borders = [{}, ...xlsxBorders];
32601
32626
  return {
32602
32627
  relsFiles: [],
32603
32628
  sharedStrings: [],
@@ -32620,7 +32645,7 @@
32620
32645
  },
32621
32646
  ],
32622
32647
  fills: [{ reservedAttribute: "none" }, { reservedAttribute: "gray125" }],
32623
- borders: [{}],
32648
+ borders,
32624
32649
  numFmts: [],
32625
32650
  dxfs: [],
32626
32651
  };
@@ -37228,6 +37253,9 @@
37228
37253
  if (newRule.criterion.type === "isBoolean") {
37229
37254
  this.setCenterStyleToBooleanCells(newRule);
37230
37255
  }
37256
+ else if (newRule.criterion.type === "isValueInList") {
37257
+ newRule.criterion.values = Array.from(new Set(newRule.criterion.values));
37258
+ }
37231
37259
  const adaptedRules = this.removeRangesFromRules(sheetId, newRule.ranges, rules);
37232
37260
  const ruleIndex = adaptedRules.findIndex((rule) => rule.id === newRule.id);
37233
37261
  if (ruleIndex !== -1) {
@@ -37813,7 +37841,17 @@
37813
37841
  }
37814
37842
  }
37815
37843
  exportForExcel(data) {
37816
- this.export(data);
37844
+ for (const sheet of data.sheets) {
37845
+ for (const filterTable of this.getFilterTables(sheet.id)) {
37846
+ if (zoneToDimension(filterTable.zone).numberOfRows === 1) {
37847
+ continue;
37848
+ }
37849
+ sheet.filterTables.push({
37850
+ range: zoneToXc(filterTable.zone),
37851
+ filters: [],
37852
+ });
37853
+ }
37854
+ }
37817
37855
  }
37818
37856
  }
37819
37857
 
@@ -37954,7 +37992,7 @@
37954
37992
  if (hiddenElements.size >= elements) {
37955
37993
  return "TooManyHiddenElements" /* CommandResult.TooManyHiddenElements */;
37956
37994
  }
37957
- else if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
37995
+ else if (largeMin(cmd.elements) < 0 || largeMax(cmd.elements) > elements) {
37958
37996
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
37959
37997
  }
37960
37998
  else {
@@ -38769,8 +38807,8 @@
38769
38807
  let newRange = range;
38770
38808
  let changeType = "NONE";
38771
38809
  for (let group of groups) {
38772
- const min = Math.min(...group);
38773
- const max = Math.max(...group);
38810
+ const min = largeMin(group);
38811
+ const max = largeMax(group);
38774
38812
  if (range.zone[start] <= min && min <= range.zone[end]) {
38775
38813
  const toRemove = Math.min(range.zone[end], max) - min + 1;
38776
38814
  changeType = "RESIZE";
@@ -39193,8 +39231,8 @@
39193
39231
  }
39194
39232
  return "Success" /* CommandResult.Success */;
39195
39233
  case "REMOVE_COLUMNS_ROWS": {
39196
- const min = Math.min(...cmd.elements);
39197
- const max = Math.max(...cmd.elements);
39234
+ const min = largeMin(cmd.elements);
39235
+ const max = largeMax(cmd.elements);
39198
39236
  if (min < 0 || !this.doesHeaderExist(cmd.sheetId, cmd.dimension, max)) {
39199
39237
  return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
39200
39238
  }
@@ -41533,7 +41571,9 @@
41533
41571
  this.blockedArrayFormulas = new Set();
41534
41572
  this.spreadingRelations = new SpreadingRelation();
41535
41573
  this.formulaDependencies = lazy(() => {
41536
- const dependencies = [...this.getAllCells()].flatMap((positionId) => this.getDirectDependencies(positionId).map((range) => ({
41574
+ const dependencies = [...this.getAllCells()].flatMap((positionId) => this.getDirectDependencies(positionId)
41575
+ .filter((range) => !range.invalidSheetName && !range.invalidXc)
41576
+ .map((range) => ({
41537
41577
  data: positionId,
41538
41578
  boundingBox: {
41539
41579
  zone: range.zone,
@@ -42102,7 +42142,7 @@
42102
42142
  ? getItemId(newFormat, data.formats)
42103
42143
  : exportedCellData.format;
42104
42144
  let content;
42105
- if (formulaCell instanceof FormulaCellWithDependencies) {
42145
+ if (isFormula && formulaCell instanceof FormulaCellWithDependencies) {
42106
42146
  content = formulaCell.contentWithFixedReferences;
42107
42147
  }
42108
42148
  else {
@@ -42523,13 +42563,13 @@
42523
42563
  .map((cell) => cell.value);
42524
42564
  switch (threshold.type) {
42525
42565
  case "value":
42526
- const result = functionName === "max" ? Math.max(...rangeValues) : Math.min(...rangeValues);
42566
+ const result = functionName === "max" ? largeMax(rangeValues) : largeMin(rangeValues);
42527
42567
  return result;
42528
42568
  case "number":
42529
42569
  return Number(threshold.value);
42530
42570
  case "percentage":
42531
- const min = Math.min(...rangeValues);
42532
- const max = Math.max(...rangeValues);
42571
+ const min = largeMin(rangeValues);
42572
+ const max = largeMax(rangeValues);
42533
42573
  const delta = max - min;
42534
42574
  return min + (delta * Number(threshold.value)) / 100;
42535
42575
  case "percentile":
@@ -43571,13 +43611,13 @@
43571
43611
  const cells = this.getters.getEvaluatedCellsInZone(sheet.id, zone);
43572
43612
  const cellPositions = range(end, -1, -1);
43573
43613
  const invalidCells = cellPositions.filter((position) => cells[position] && !cells[position].isAutoSummable);
43574
- const maxValidPosition = Math.max(...invalidCells);
43614
+ const maxValidPosition = largeMax(invalidCells);
43575
43615
  const numberSequences = groupConsecutive(cellPositions.filter((position) => this.isNumber(cells[position])));
43576
43616
  const firstSequence = numberSequences[0] || [];
43577
- if (Math.max(...firstSequence) < maxValidPosition) {
43617
+ if (largeMax(firstSequence) < maxValidPosition) {
43578
43618
  return Infinity;
43579
43619
  }
43580
- return Math.min(...firstSequence);
43620
+ return largeMin(firstSequence);
43581
43621
  }
43582
43622
  shouldFindData(sheetId, zone) {
43583
43623
  return this.getters.isEmpty(sheetId, zone) || this.getters.isSingleCellOrMerge(sheetId, zone);
@@ -46070,7 +46110,7 @@
46070
46110
  * column of the current viewport
46071
46111
  */
46072
46112
  getColDimensionsInViewport(sheetId, col) {
46073
- const left = Math.min(...this.getters.getSheetViewVisibleCols());
46113
+ const left = largeMin(this.getters.getSheetViewVisibleCols());
46074
46114
  const start = this.getters.getColRowOffsetInViewport("COL", left, col);
46075
46115
  const size = this.getters.getColSize(sheetId, col);
46076
46116
  const isColHidden = this.getters.isColHidden(sheetId, col);
@@ -46085,7 +46125,7 @@
46085
46125
  * of the current viewport
46086
46126
  */
46087
46127
  getRowDimensionsInViewport(sheetId, row) {
46088
- const top = Math.min(...this.getters.getSheetViewVisibleRows());
46128
+ const top = largeMin(this.getters.getSheetViewVisibleRows());
46089
46129
  const start = this.getters.getColRowOffsetInViewport("ROW", top, row);
46090
46130
  const size = this.getters.getRowSize(sheetId, row);
46091
46131
  const isRowHidden = this.getters.isRowHidden(sheetId, row);
@@ -47468,7 +47508,7 @@
47468
47508
  getColMaxWidth(sheetId, index) {
47469
47509
  const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
47470
47510
  const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
47471
- return Math.max(0, ...sizes);
47511
+ return Math.max(0, largeMax(sizes));
47472
47512
  }
47473
47513
  /**
47474
47514
  * Check that any "sheetId" in the command matches an existing
@@ -48235,7 +48275,7 @@
48235
48275
  }
48236
48276
  getPasteZone(target) {
48237
48277
  const height = this.values.length;
48238
- const width = Math.max(...this.values.map((a) => a.length));
48278
+ const width = largeMax(this.values.map((a) => a.length));
48239
48279
  const { left: activeCol, top: activeRow } = target[0];
48240
48280
  return {
48241
48281
  top: activeRow,
@@ -49181,11 +49221,11 @@
49181
49221
  }
49182
49222
  else {
49183
49223
  const range = this.getters.getRangeFromSheetXC(this.sheetId, rule.criterion.values[0]);
49184
- values = this.getters
49224
+ values = Array.from(new Set(this.getters
49185
49225
  .getRangeValues(range)
49186
49226
  .filter(isNotNull)
49187
49227
  .map((value) => value.toString())
49188
- .filter((val) => val !== "");
49228
+ .filter((val) => val !== "")));
49189
49229
  }
49190
49230
  const composerContent = this.getCurrentContent();
49191
49231
  if (composerContent && composerContent !== this.getInitialComposerContent()) {
@@ -51617,12 +51657,14 @@
51617
51657
  this.editionState = "initializing";
51618
51658
  }
51619
51659
  stopEdition() {
51620
- if (!this.state.isEditing)
51660
+ const input = this.sheetNameRef.el;
51661
+ if (!this.state.isEditing || !input)
51621
51662
  return;
51622
51663
  this.state.isEditing = false;
51623
51664
  this.editionState = "initializing";
51624
- this.sheetNameRef.el?.blur();
51665
+ input.blur();
51625
51666
  const inputValue = this.getInputContent() || "";
51667
+ input.innerText = inputValue;
51626
51668
  interactiveRenameSheet(this.env, this.props.sheetId, inputValue, () => this.startEdition());
51627
51669
  }
51628
51670
  cancelEdition() {
@@ -51913,7 +51955,7 @@
51913
51955
  this.sheetListRef.el.scrollTo({ top: 0, left: scroll, behavior: "smooth" });
51914
51956
  }
51915
51957
  onSheetMouseDown(sheetId, event) {
51916
- if (event.button !== 0)
51958
+ if (event.button !== 0 || this.env.model.getters.isReadonly())
51917
51959
  return;
51918
51960
  this.closeMenu();
51919
51961
  const visibleSheets = this.getVisibleSheets();
@@ -55367,7 +55409,7 @@
55367
55409
  }
55368
55410
  function addDoughnutChart(chart, chartSheetIndex, data, { holeSize } = { holeSize: 50 }) {
55369
55411
  const colors = new ChartColors();
55370
- const maxLength = Math.max(...chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
55412
+ const maxLength = largeMax(chart.dataSets.map((ds) => getRangeSize(ds.range, chartSheetIndex, data)));
55371
55413
  const doughnutColors = range(0, maxLength).map(() => toXlsxHexColor(colors.next()));
55372
55414
  const dataSetsNodes = [];
55373
55415
  for (const [dsIndex, dataset] of Object.entries(chart.dataSets).reverse()) {
@@ -55505,8 +55547,7 @@
55505
55547
  attrs.push(["t", "b"]);
55506
55548
  }
55507
55549
  else if (forceString || !isNumber(value, DEFAULT_LOCALE)) {
55508
- const { id } = pushElement(content, sharedStrings);
55509
- value = id.toString();
55550
+ value = pushElement(content, sharedStrings);
55510
55551
  attrs.push(["t", "s"]);
55511
55552
  }
55512
55553
  return { attrs, node: escapeXml /*xml*/ `<v>${value}</v>` };
@@ -55631,8 +55672,7 @@
55631
55672
  if (rule.style.fillColor) {
55632
55673
  dxf.fill = { fgColor: { rgb: rule.style.fillColor } };
55633
55674
  }
55634
- const { id } = pushElement(dxf, dxfs);
55635
- ruleAttributes.push(["dxfId", id]);
55675
+ ruleAttributes.push(["dxfId", pushElement(dxf, dxfs)]);
55636
55676
  return escapeXml /*xml*/ `
55637
55677
  <conditionalFormatting sqref="${cf.ranges.join(" ")}">
55638
55678
  <cfRule ${formatAttributes(ruleAttributes)}>
@@ -56442,7 +56482,7 @@
56442
56482
  */
56443
56483
  function getXLSX(data) {
56444
56484
  const files = [];
56445
- const construct = getDefaultXLSXStructure();
56485
+ const construct = getDefaultXLSXStructure(data);
56446
56486
  files.push(createWorkbook(data, construct));
56447
56487
  files.push(...createWorksheets(data, construct));
56448
56488
  files.push(createStylesSheet(construct));
@@ -57331,9 +57371,9 @@
57331
57371
  exports.tokenize = tokenize;
57332
57372
 
57333
57373
 
57334
- __info__.version = "17.1.9";
57335
- __info__.date = "2024-03-25T09:43:27.017Z";
57336
- __info__.hash = "5fb076e";
57374
+ __info__.version = "17.1.11";
57375
+ __info__.date = "2024-04-10T12:27:11.107Z";
57376
+ __info__.hash = "246caf7";
57337
57377
 
57338
57378
 
57339
57379
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);