@odoo/o-spreadsheet 18.4.12 → 18.4.13

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.4.12
6
- * @date 2025-09-23T12:37:43.708Z
7
- * @hash 0c91305
5
+ * @version 18.4.13
6
+ * @date 2025-10-07T10:00:55.413Z
7
+ * @hash d4df70e
8
8
  */
9
9
 
10
10
  'use strict';
@@ -906,9 +906,7 @@ function removeIndexesFromArray(array, indexes) {
906
906
  return newArray;
907
907
  }
908
908
  function insertItemsAtIndex(array, items, index) {
909
- const newArray = [...array];
910
- newArray.splice(index, 0, ...items);
911
- return newArray;
909
+ return array.slice(0, index).concat(items).concat(array.slice(index));
912
910
  }
913
911
  function replaceItemAtIndex(array, newItem, index) {
914
912
  const newArray = [...array];
@@ -4315,7 +4313,7 @@ function tokensToTextInternalFormat(tokens) {
4315
4313
  * Replace in place tokens "mm" and "m" that denote minutes in date format with "MM" to avoid confusion with months.
4316
4314
  *
4317
4315
  * As per OpenXML specification, in date formats if a date token "m" or "mm" is followed by a date token "s" or
4318
- * preceded by a data token "h", then it's not a month but an minute.
4316
+ * preceded by a data token "h", then it's not a month but a minute.
4319
4317
  */
4320
4318
  function convertTokensToMinutesInDateFormat(tokens) {
4321
4319
  const dateParts = tokens.filter((token) => token.type === "DATE_PART");
@@ -4358,6 +4356,9 @@ function internalFormatPartToFormat(internalFormat) {
4358
4356
  case "REPEATED_CHAR":
4359
4357
  format += "*" + token.value;
4360
4358
  break;
4359
+ case "DATE_PART":
4360
+ format += token.value === "MM" ? "mm" : token.value; // Convert "MM" back to "mm" for minutes
4361
+ break;
4361
4362
  default:
4362
4363
  format += token.value;
4363
4364
  }
@@ -54246,7 +54247,7 @@ class PivotMeasureEditor extends owl.Component {
54246
54247
  return undefined;
54247
54248
  }
54248
54249
  get isCalculatedMeasureInvalid() {
54249
- return this.env.model.getters.getMeasureCompiledFormula(this.props.measure).isBadExpression;
54250
+ return compile(this.props.measure.computedBy?.formula ?? "").isBadExpression;
54250
54251
  }
54251
54252
  }
54252
54253
 
@@ -61258,11 +61259,11 @@ class HeaderSizePlugin extends CorePlugin {
61258
61259
  break;
61259
61260
  }
61260
61261
  case "ADD_COLUMNS_ROWS": {
61261
- const sizes = [...this.sizes[cmd.sheetId][cmd.dimension]];
61262
+ const sizes = this.sizes[cmd.sheetId][cmd.dimension];
61262
61263
  const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
61263
61264
  const baseSize = sizes[cmd.base];
61264
- sizes.splice(addIndex, 0, ...Array(cmd.quantity).fill(baseSize));
61265
- this.history.update("sizes", cmd.sheetId, cmd.dimension, sizes);
61265
+ const newSizes = insertItemsAtIndex(sizes, Array(cmd.quantity).fill(baseSize), addIndex);
61266
+ this.history.update("sizes", cmd.sheetId, cmd.dimension, newSizes);
61266
61267
  break;
61267
61268
  }
61268
61269
  case "RESIZE_COLUMNS_ROWS":
@@ -61413,9 +61414,8 @@ class HeaderVisibilityPlugin extends CorePlugin {
61413
61414
  break;
61414
61415
  }
61415
61416
  case "ADD_COLUMNS_ROWS": {
61416
- const hiddenHeaders = [...this.hiddenHeaders[cmd.sheetId][cmd.dimension]];
61417
61417
  const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
61418
- hiddenHeaders.splice(addIndex, 0, ...Array(cmd.quantity).fill(false));
61418
+ const hiddenHeaders = insertItemsAtIndex([...this.hiddenHeaders[cmd.sheetId][cmd.dimension]], Array(cmd.quantity).fill(false), addIndex);
61419
61419
  this.history.update("hiddenHeaders", cmd.sheetId, cmd.dimension, hiddenHeaders);
61420
61420
  break;
61421
61421
  }
@@ -65450,12 +65450,12 @@ class SpreadsheetRTree {
65450
65450
  this.rTrees[sheetId].remove(item, this.rtreeItemComparer);
65451
65451
  }
65452
65452
  rtreeItemComparer(left, right) {
65453
- return (left.data === right.data &&
65454
- left.boundingBox.sheetId === right.boundingBox.sheetId &&
65453
+ return (left.boundingBox.sheetId === right.boundingBox.sheetId &&
65455
65454
  left.boundingBox?.zone.left === right.boundingBox.zone.left &&
65456
65455
  left.boundingBox?.zone.top === right.boundingBox.zone.top &&
65457
65456
  left.boundingBox?.zone.right === right.boundingBox.zone.right &&
65458
- left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom);
65457
+ left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom &&
65458
+ deepEquals(left.data, right.data));
65459
65459
  }
65460
65460
  }
65461
65461
  /**
@@ -78695,6 +78695,9 @@ class SmallBottomBar extends owl.Component {
78695
78695
  ? this.composerFocusStore.focusMode
78696
78696
  : "inactive";
78697
78697
  }
78698
+ get showFxIcon() {
78699
+ return this.focus === "inactive" && !this.composerStore.currentContent;
78700
+ }
78698
78701
  get rect() {
78699
78702
  return this.composerRef.el
78700
78703
  ? getBoundingRectAsPOJO(this.composerRef.el)
@@ -78737,12 +78740,6 @@ class SmallBottomBar extends owl.Component {
78737
78740
  }
78738
78741
 
78739
78742
  const COMPOSER_MAX_HEIGHT = 100;
78740
- /* svg free of use from https://uxwing.com/formula-fx-icon/ */
78741
- const FX_SVG = /*xml*/ `
78742
- <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 121.8 122.9' width='16' height='16' focusable='false'>
78743
- <path d='m28 34-4 5v2h10l-6 40c-4 22-6 28-7 30-2 2-3 3-5 3-3 0-7-2-9-4H4c-2 2-4 4-4 7s4 6 8 6 9-2 15-8c8-7 13-17 18-39l7-35 13-1 3-6H49c4-23 7-27 11-27 2 0 5 2 8 6h4c1-1 4-4 4-7 0-2-3-6-9-6-5 0-13 4-20 10-6 7-9 14-11 24h-8zm41 16c4-5 7-7 8-7s2 1 5 9l3 12c-7 11-12 17-16 17l-3-1-2-1c-3 0-6 3-6 7s3 7 7 7c6 0 12-6 22-23l3 10c3 9 6 13 10 13 5 0 11-4 18-15l-3-4c-4 6-7 8-8 8-2 0-4-3-6-10l-5-15 8-10 6-4 3 1 3 2c2 0 6-3 6-7s-2-7-6-7c-6 0-11 5-21 20l-2-6c-3-9-5-14-9-14-5 0-12 6-18 15l3 3z' fill='#BDBDBD'/>
78744
- </svg>
78745
- `;
78746
78743
  css /* scss */ `
78747
78744
  .o-topbar-composer-container {
78748
78745
  height: ${DESKTOP_TOPBAR_TOOLBAR_HEIGHT}px;
@@ -78754,14 +78751,6 @@ css /* scss */ `
78754
78751
  margin-bottom: -1px;
78755
78752
  border: 1px solid;
78756
78753
  font-family: ${DEFAULT_FONT};
78757
-
78758
- /* In readonly we always show the fx icon if the composer is empty, not matter the focus */
78759
- .o-composer:empty:not(:focus):not(.active)::before,
78760
- &.o-topbar-composer-readonly .o-composer:empty::before {
78761
- content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
78762
- position: relative;
78763
- top: 20%;
78764
- }
78765
78754
  }
78766
78755
 
78767
78756
  .user-select-text {
@@ -78794,6 +78783,9 @@ class TopBarComposer extends owl.Component {
78794
78783
  ? this.composerFocusStore.focusMode
78795
78784
  : "inactive";
78796
78785
  }
78786
+ get showFxIcon() {
78787
+ return this.focus === "inactive" && !this.composerStore.currentContent;
78788
+ }
78797
78789
  get composerStyle() {
78798
78790
  const style = {
78799
78791
  padding: "5px 0px 5px 8px",
@@ -84859,6 +84851,6 @@ exports.tokenColors = tokenColors;
84859
84851
  exports.tokenize = tokenize;
84860
84852
 
84861
84853
 
84862
- __info__.version = "18.4.12";
84863
- __info__.date = "2025-09-23T12:37:43.708Z";
84864
- __info__.hash = "0c91305";
84854
+ __info__.version = "18.4.13";
84855
+ __info__.date = "2025-10-07T10:00:55.413Z";
84856
+ __info__.hash = "d4df70e";
@@ -12204,6 +12204,7 @@ declare class SmallBottomBar extends Component<Props$1, SpreadsheetChildEnv> {
12204
12204
  private menuState;
12205
12205
  setup(): void;
12206
12206
  get focus(): ComposerFocusType;
12207
+ get showFxIcon(): boolean;
12207
12208
  get rect(): Rect;
12208
12209
  get composerProps(): CellComposerProps;
12209
12210
  get symbols(): string[];
@@ -12256,6 +12257,7 @@ declare class TopBarComposer extends Component<any, SpreadsheetChildEnv> {
12256
12257
  private composerInterface;
12257
12258
  setup(): void;
12258
12259
  get focus(): ComposerFocusType;
12260
+ get showFxIcon(): boolean;
12259
12261
  get composerStyle(): string;
12260
12262
  get containerStyle(): string;
12261
12263
  onFocus(selection: ComposerSelection): void;
@@ -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.4.12
6
- * @date 2025-09-23T12:37:43.708Z
7
- * @hash 0c91305
5
+ * @version 18.4.13
6
+ * @date 2025-10-07T10:00:55.413Z
7
+ * @hash d4df70e
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, useExternalListener, onWillUpdateProps, onWillStart, onWillPatch, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -904,9 +904,7 @@ function removeIndexesFromArray(array, indexes) {
904
904
  return newArray;
905
905
  }
906
906
  function insertItemsAtIndex(array, items, index) {
907
- const newArray = [...array];
908
- newArray.splice(index, 0, ...items);
909
- return newArray;
907
+ return array.slice(0, index).concat(items).concat(array.slice(index));
910
908
  }
911
909
  function replaceItemAtIndex(array, newItem, index) {
912
910
  const newArray = [...array];
@@ -4313,7 +4311,7 @@ function tokensToTextInternalFormat(tokens) {
4313
4311
  * Replace in place tokens "mm" and "m" that denote minutes in date format with "MM" to avoid confusion with months.
4314
4312
  *
4315
4313
  * As per OpenXML specification, in date formats if a date token "m" or "mm" is followed by a date token "s" or
4316
- * preceded by a data token "h", then it's not a month but an minute.
4314
+ * preceded by a data token "h", then it's not a month but a minute.
4317
4315
  */
4318
4316
  function convertTokensToMinutesInDateFormat(tokens) {
4319
4317
  const dateParts = tokens.filter((token) => token.type === "DATE_PART");
@@ -4356,6 +4354,9 @@ function internalFormatPartToFormat(internalFormat) {
4356
4354
  case "REPEATED_CHAR":
4357
4355
  format += "*" + token.value;
4358
4356
  break;
4357
+ case "DATE_PART":
4358
+ format += token.value === "MM" ? "mm" : token.value; // Convert "MM" back to "mm" for minutes
4359
+ break;
4359
4360
  default:
4360
4361
  format += token.value;
4361
4362
  }
@@ -54244,7 +54245,7 @@ class PivotMeasureEditor extends Component {
54244
54245
  return undefined;
54245
54246
  }
54246
54247
  get isCalculatedMeasureInvalid() {
54247
- return this.env.model.getters.getMeasureCompiledFormula(this.props.measure).isBadExpression;
54248
+ return compile(this.props.measure.computedBy?.formula ?? "").isBadExpression;
54248
54249
  }
54249
54250
  }
54250
54251
 
@@ -61256,11 +61257,11 @@ class HeaderSizePlugin extends CorePlugin {
61256
61257
  break;
61257
61258
  }
61258
61259
  case "ADD_COLUMNS_ROWS": {
61259
- const sizes = [...this.sizes[cmd.sheetId][cmd.dimension]];
61260
+ const sizes = this.sizes[cmd.sheetId][cmd.dimension];
61260
61261
  const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
61261
61262
  const baseSize = sizes[cmd.base];
61262
- sizes.splice(addIndex, 0, ...Array(cmd.quantity).fill(baseSize));
61263
- this.history.update("sizes", cmd.sheetId, cmd.dimension, sizes);
61263
+ const newSizes = insertItemsAtIndex(sizes, Array(cmd.quantity).fill(baseSize), addIndex);
61264
+ this.history.update("sizes", cmd.sheetId, cmd.dimension, newSizes);
61264
61265
  break;
61265
61266
  }
61266
61267
  case "RESIZE_COLUMNS_ROWS":
@@ -61411,9 +61412,8 @@ class HeaderVisibilityPlugin extends CorePlugin {
61411
61412
  break;
61412
61413
  }
61413
61414
  case "ADD_COLUMNS_ROWS": {
61414
- const hiddenHeaders = [...this.hiddenHeaders[cmd.sheetId][cmd.dimension]];
61415
61415
  const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
61416
- hiddenHeaders.splice(addIndex, 0, ...Array(cmd.quantity).fill(false));
61416
+ const hiddenHeaders = insertItemsAtIndex([...this.hiddenHeaders[cmd.sheetId][cmd.dimension]], Array(cmd.quantity).fill(false), addIndex);
61417
61417
  this.history.update("hiddenHeaders", cmd.sheetId, cmd.dimension, hiddenHeaders);
61418
61418
  break;
61419
61419
  }
@@ -65448,12 +65448,12 @@ class SpreadsheetRTree {
65448
65448
  this.rTrees[sheetId].remove(item, this.rtreeItemComparer);
65449
65449
  }
65450
65450
  rtreeItemComparer(left, right) {
65451
- return (left.data === right.data &&
65452
- left.boundingBox.sheetId === right.boundingBox.sheetId &&
65451
+ return (left.boundingBox.sheetId === right.boundingBox.sheetId &&
65453
65452
  left.boundingBox?.zone.left === right.boundingBox.zone.left &&
65454
65453
  left.boundingBox?.zone.top === right.boundingBox.zone.top &&
65455
65454
  left.boundingBox?.zone.right === right.boundingBox.zone.right &&
65456
- left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom);
65455
+ left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom &&
65456
+ deepEquals(left.data, right.data));
65457
65457
  }
65458
65458
  }
65459
65459
  /**
@@ -78693,6 +78693,9 @@ class SmallBottomBar extends Component {
78693
78693
  ? this.composerFocusStore.focusMode
78694
78694
  : "inactive";
78695
78695
  }
78696
+ get showFxIcon() {
78697
+ return this.focus === "inactive" && !this.composerStore.currentContent;
78698
+ }
78696
78699
  get rect() {
78697
78700
  return this.composerRef.el
78698
78701
  ? getBoundingRectAsPOJO(this.composerRef.el)
@@ -78735,12 +78738,6 @@ class SmallBottomBar extends Component {
78735
78738
  }
78736
78739
 
78737
78740
  const COMPOSER_MAX_HEIGHT = 100;
78738
- /* svg free of use from https://uxwing.com/formula-fx-icon/ */
78739
- const FX_SVG = /*xml*/ `
78740
- <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 121.8 122.9' width='16' height='16' focusable='false'>
78741
- <path d='m28 34-4 5v2h10l-6 40c-4 22-6 28-7 30-2 2-3 3-5 3-3 0-7-2-9-4H4c-2 2-4 4-4 7s4 6 8 6 9-2 15-8c8-7 13-17 18-39l7-35 13-1 3-6H49c4-23 7-27 11-27 2 0 5 2 8 6h4c1-1 4-4 4-7 0-2-3-6-9-6-5 0-13 4-20 10-6 7-9 14-11 24h-8zm41 16c4-5 7-7 8-7s2 1 5 9l3 12c-7 11-12 17-16 17l-3-1-2-1c-3 0-6 3-6 7s3 7 7 7c6 0 12-6 22-23l3 10c3 9 6 13 10 13 5 0 11-4 18-15l-3-4c-4 6-7 8-8 8-2 0-4-3-6-10l-5-15 8-10 6-4 3 1 3 2c2 0 6-3 6-7s-2-7-6-7c-6 0-11 5-21 20l-2-6c-3-9-5-14-9-14-5 0-12 6-18 15l3 3z' fill='#BDBDBD'/>
78742
- </svg>
78743
- `;
78744
78741
  css /* scss */ `
78745
78742
  .o-topbar-composer-container {
78746
78743
  height: ${DESKTOP_TOPBAR_TOOLBAR_HEIGHT}px;
@@ -78752,14 +78749,6 @@ css /* scss */ `
78752
78749
  margin-bottom: -1px;
78753
78750
  border: 1px solid;
78754
78751
  font-family: ${DEFAULT_FONT};
78755
-
78756
- /* In readonly we always show the fx icon if the composer is empty, not matter the focus */
78757
- .o-composer:empty:not(:focus):not(.active)::before,
78758
- &.o-topbar-composer-readonly .o-composer:empty::before {
78759
- content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
78760
- position: relative;
78761
- top: 20%;
78762
- }
78763
78752
  }
78764
78753
 
78765
78754
  .user-select-text {
@@ -78792,6 +78781,9 @@ class TopBarComposer extends Component {
78792
78781
  ? this.composerFocusStore.focusMode
78793
78782
  : "inactive";
78794
78783
  }
78784
+ get showFxIcon() {
78785
+ return this.focus === "inactive" && !this.composerStore.currentContent;
78786
+ }
78795
78787
  get composerStyle() {
78796
78788
  const style = {
78797
78789
  padding: "5px 0px 5px 8px",
@@ -84809,6 +84801,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
84809
84801
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
84810
84802
 
84811
84803
 
84812
- __info__.version = "18.4.12";
84813
- __info__.date = "2025-09-23T12:37:43.708Z";
84814
- __info__.hash = "0c91305";
84804
+ __info__.version = "18.4.13";
84805
+ __info__.date = "2025-10-07T10:00:55.413Z";
84806
+ __info__.hash = "d4df70e";
@@ -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.4.12
6
- * @date 2025-09-23T12:37:43.708Z
7
- * @hash 0c91305
5
+ * @version 18.4.13
6
+ * @date 2025-10-07T10:00:55.413Z
7
+ * @hash d4df70e
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -905,9 +905,7 @@
905
905
  return newArray;
906
906
  }
907
907
  function insertItemsAtIndex(array, items, index) {
908
- const newArray = [...array];
909
- newArray.splice(index, 0, ...items);
910
- return newArray;
908
+ return array.slice(0, index).concat(items).concat(array.slice(index));
911
909
  }
912
910
  function replaceItemAtIndex(array, newItem, index) {
913
911
  const newArray = [...array];
@@ -4314,7 +4312,7 @@
4314
4312
  * Replace in place tokens "mm" and "m" that denote minutes in date format with "MM" to avoid confusion with months.
4315
4313
  *
4316
4314
  * As per OpenXML specification, in date formats if a date token "m" or "mm" is followed by a date token "s" or
4317
- * preceded by a data token "h", then it's not a month but an minute.
4315
+ * preceded by a data token "h", then it's not a month but a minute.
4318
4316
  */
4319
4317
  function convertTokensToMinutesInDateFormat(tokens) {
4320
4318
  const dateParts = tokens.filter((token) => token.type === "DATE_PART");
@@ -4357,6 +4355,9 @@
4357
4355
  case "REPEATED_CHAR":
4358
4356
  format += "*" + token.value;
4359
4357
  break;
4358
+ case "DATE_PART":
4359
+ format += token.value === "MM" ? "mm" : token.value; // Convert "MM" back to "mm" for minutes
4360
+ break;
4360
4361
  default:
4361
4362
  format += token.value;
4362
4363
  }
@@ -54245,7 +54246,7 @@ stores.inject(MyMetaStore, storeInstance);
54245
54246
  return undefined;
54246
54247
  }
54247
54248
  get isCalculatedMeasureInvalid() {
54248
- return this.env.model.getters.getMeasureCompiledFormula(this.props.measure).isBadExpression;
54249
+ return compile(this.props.measure.computedBy?.formula ?? "").isBadExpression;
54249
54250
  }
54250
54251
  }
54251
54252
 
@@ -61257,11 +61258,11 @@ stores.inject(MyMetaStore, storeInstance);
61257
61258
  break;
61258
61259
  }
61259
61260
  case "ADD_COLUMNS_ROWS": {
61260
- const sizes = [...this.sizes[cmd.sheetId][cmd.dimension]];
61261
+ const sizes = this.sizes[cmd.sheetId][cmd.dimension];
61261
61262
  const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
61262
61263
  const baseSize = sizes[cmd.base];
61263
- sizes.splice(addIndex, 0, ...Array(cmd.quantity).fill(baseSize));
61264
- this.history.update("sizes", cmd.sheetId, cmd.dimension, sizes);
61264
+ const newSizes = insertItemsAtIndex(sizes, Array(cmd.quantity).fill(baseSize), addIndex);
61265
+ this.history.update("sizes", cmd.sheetId, cmd.dimension, newSizes);
61265
61266
  break;
61266
61267
  }
61267
61268
  case "RESIZE_COLUMNS_ROWS":
@@ -61412,9 +61413,8 @@ stores.inject(MyMetaStore, storeInstance);
61412
61413
  break;
61413
61414
  }
61414
61415
  case "ADD_COLUMNS_ROWS": {
61415
- const hiddenHeaders = [...this.hiddenHeaders[cmd.sheetId][cmd.dimension]];
61416
61416
  const addIndex = getAddHeaderStartIndex(cmd.position, cmd.base);
61417
- hiddenHeaders.splice(addIndex, 0, ...Array(cmd.quantity).fill(false));
61417
+ const hiddenHeaders = insertItemsAtIndex([...this.hiddenHeaders[cmd.sheetId][cmd.dimension]], Array(cmd.quantity).fill(false), addIndex);
61418
61418
  this.history.update("hiddenHeaders", cmd.sheetId, cmd.dimension, hiddenHeaders);
61419
61419
  break;
61420
61420
  }
@@ -65449,12 +65449,12 @@ stores.inject(MyMetaStore, storeInstance);
65449
65449
  this.rTrees[sheetId].remove(item, this.rtreeItemComparer);
65450
65450
  }
65451
65451
  rtreeItemComparer(left, right) {
65452
- return (left.data === right.data &&
65453
- left.boundingBox.sheetId === right.boundingBox.sheetId &&
65452
+ return (left.boundingBox.sheetId === right.boundingBox.sheetId &&
65454
65453
  left.boundingBox?.zone.left === right.boundingBox.zone.left &&
65455
65454
  left.boundingBox?.zone.top === right.boundingBox.zone.top &&
65456
65455
  left.boundingBox?.zone.right === right.boundingBox.zone.right &&
65457
- left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom);
65456
+ left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom &&
65457
+ deepEquals(left.data, right.data));
65458
65458
  }
65459
65459
  }
65460
65460
  /**
@@ -78694,6 +78694,9 @@ stores.inject(MyMetaStore, storeInstance);
78694
78694
  ? this.composerFocusStore.focusMode
78695
78695
  : "inactive";
78696
78696
  }
78697
+ get showFxIcon() {
78698
+ return this.focus === "inactive" && !this.composerStore.currentContent;
78699
+ }
78697
78700
  get rect() {
78698
78701
  return this.composerRef.el
78699
78702
  ? getBoundingRectAsPOJO(this.composerRef.el)
@@ -78736,12 +78739,6 @@ stores.inject(MyMetaStore, storeInstance);
78736
78739
  }
78737
78740
 
78738
78741
  const COMPOSER_MAX_HEIGHT = 100;
78739
- /* svg free of use from https://uxwing.com/formula-fx-icon/ */
78740
- const FX_SVG = /*xml*/ `
78741
- <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 121.8 122.9' width='16' height='16' focusable='false'>
78742
- <path d='m28 34-4 5v2h10l-6 40c-4 22-6 28-7 30-2 2-3 3-5 3-3 0-7-2-9-4H4c-2 2-4 4-4 7s4 6 8 6 9-2 15-8c8-7 13-17 18-39l7-35 13-1 3-6H49c4-23 7-27 11-27 2 0 5 2 8 6h4c1-1 4-4 4-7 0-2-3-6-9-6-5 0-13 4-20 10-6 7-9 14-11 24h-8zm41 16c4-5 7-7 8-7s2 1 5 9l3 12c-7 11-12 17-16 17l-3-1-2-1c-3 0-6 3-6 7s3 7 7 7c6 0 12-6 22-23l3 10c3 9 6 13 10 13 5 0 11-4 18-15l-3-4c-4 6-7 8-8 8-2 0-4-3-6-10l-5-15 8-10 6-4 3 1 3 2c2 0 6-3 6-7s-2-7-6-7c-6 0-11 5-21 20l-2-6c-3-9-5-14-9-14-5 0-12 6-18 15l3 3z' fill='#BDBDBD'/>
78743
- </svg>
78744
- `;
78745
78742
  css /* scss */ `
78746
78743
  .o-topbar-composer-container {
78747
78744
  height: ${DESKTOP_TOPBAR_TOOLBAR_HEIGHT}px;
@@ -78753,14 +78750,6 @@ stores.inject(MyMetaStore, storeInstance);
78753
78750
  margin-bottom: -1px;
78754
78751
  border: 1px solid;
78755
78752
  font-family: ${DEFAULT_FONT};
78756
-
78757
- /* In readonly we always show the fx icon if the composer is empty, not matter the focus */
78758
- .o-composer:empty:not(:focus):not(.active)::before,
78759
- &.o-topbar-composer-readonly .o-composer:empty::before {
78760
- content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
78761
- position: relative;
78762
- top: 20%;
78763
- }
78764
78753
  }
78765
78754
 
78766
78755
  .user-select-text {
@@ -78793,6 +78782,9 @@ stores.inject(MyMetaStore, storeInstance);
78793
78782
  ? this.composerFocusStore.focusMode
78794
78783
  : "inactive";
78795
78784
  }
78785
+ get showFxIcon() {
78786
+ return this.focus === "inactive" && !this.composerStore.currentContent;
78787
+ }
78796
78788
  get composerStyle() {
78797
78789
  const style = {
78798
78790
  padding: "5px 0px 5px 8px",
@@ -84858,9 +84850,9 @@ stores.inject(MyMetaStore, storeInstance);
84858
84850
  exports.tokenize = tokenize;
84859
84851
 
84860
84852
 
84861
- __info__.version = "18.4.12";
84862
- __info__.date = "2025-09-23T12:37:43.708Z";
84863
- __info__.hash = "0c91305";
84853
+ __info__.version = "18.4.13";
84854
+ __info__.date = "2025-10-07T10:00:55.413Z";
84855
+ __info__.hash = "d4df70e";
84864
84856
 
84865
84857
 
84866
84858
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);