@odoo/o-spreadsheet 18.4.3 → 18.4.4

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.3
6
- * @date 2025-07-28T13:39:06.036Z
7
- * @hash 4b596d7
5
+ * @version 18.4.4
6
+ * @date 2025-07-30T11:20:08.639Z
7
+ * @hash b14de14
8
8
  */
9
9
 
10
10
  'use strict';
@@ -8626,12 +8626,12 @@ const AGGREGATOR_NAMES = {
8626
8626
  avg: _t("Average"),
8627
8627
  sum: _t("Sum"),
8628
8628
  };
8629
- const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
8629
+ const DEFAULT_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
8630
8630
  const AGGREGATORS_BY_FIELD_TYPE = {
8631
- integer: NUMBER_CHAR_AGGREGATORS,
8632
- char: NUMBER_CHAR_AGGREGATORS,
8631
+ integer: DEFAULT_AGGREGATORS,
8632
+ char: DEFAULT_AGGREGATORS,
8633
+ datetime: DEFAULT_AGGREGATORS,
8633
8634
  boolean: ["count_distinct", "count", "bool_and", "bool_or"],
8634
- datetime: ["max", "min", "count_distinct", "count"],
8635
8635
  };
8636
8636
  const AGGREGATORS = {};
8637
8637
  for (const type in AGGREGATORS_BY_FIELD_TYPE) {
@@ -31709,7 +31709,7 @@ criterionEvaluatorRegistry.add("isValueInRange", {
31709
31709
  }
31710
31710
  const criterionValues = getters.getDataValidationRangeValues(sheetId, criterion);
31711
31711
  return criterionValues
31712
- .map((value) => value.toLowerCase())
31712
+ .map((value) => value.value.toLowerCase())
31713
31713
  .includes(value.toString().toLowerCase());
31714
31714
  },
31715
31715
  getErrorString: (criterion) => _t("The value must be a value in the range %s", String(criterion.values[0])),
@@ -52044,7 +52044,8 @@ class ConditionalFormattingEditor extends owl.Component {
52044
52044
  static props = {
52045
52045
  editedCf: Object,
52046
52046
  onCancel: Function,
52047
- onSave: Function,
52047
+ onExit: Function,
52048
+ isNewCf: Boolean,
52048
52049
  };
52049
52050
  static components = {
52050
52051
  SelectionInput,
@@ -52069,6 +52070,7 @@ class ConditionalFormattingEditor extends owl.Component {
52069
52070
  currentCFType: this.props.editedCf.rule.type,
52070
52071
  ranges: this.props.editedCf.ranges,
52071
52072
  rules: this.getDefaultRules(),
52073
+ hasEditedCf: this.props.isNewCf,
52072
52074
  });
52073
52075
  switch (this.props.editedCf.rule.type) {
52074
52076
  case "CellIsRule":
@@ -52120,6 +52122,9 @@ class ConditionalFormattingEditor extends owl.Component {
52120
52122
  ranges: ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(sheetId, xc)),
52121
52123
  sheetId,
52122
52124
  });
52125
+ if (result.isSuccessful) {
52126
+ this.state.hasEditedCf = true;
52127
+ }
52123
52128
  const reasons = result.reasons.filter((r) => r !== "NoChanges" /* CommandResult.NoChanges */);
52124
52129
  if (!newCf.suppressErrors) {
52125
52130
  this.state.errors = reasons;
@@ -52141,7 +52146,15 @@ class ConditionalFormattingEditor extends owl.Component {
52141
52146
  onSave() {
52142
52147
  const result = this.updateConditionalFormat({});
52143
52148
  if (result.length === 0) {
52144
- this.props.onSave();
52149
+ this.props.onExit();
52150
+ }
52151
+ }
52152
+ onCancel() {
52153
+ if (this.state.hasEditedCf) {
52154
+ this.props.onCancel();
52155
+ }
52156
+ else {
52157
+ this.props.onExit();
52145
52158
  }
52146
52159
  }
52147
52160
  getDefaultRules() {
@@ -67036,8 +67049,16 @@ class EvaluationDataValidationPlugin extends CoreViewPlugin {
67036
67049
  }
67037
67050
  getDataValidationRangeValues(sheetId, criterion) {
67038
67051
  const range = this.getters.getRangeFromSheetXC(sheetId, String(criterion.values[0]));
67039
- const criterionValues = this.getters.getRangeValues(range);
67040
- return criterionValues.map((value) => value?.toString()).filter(isDefined);
67052
+ const values = [];
67053
+ const labelsSet = new Set();
67054
+ for (const p of positions(range.zone)) {
67055
+ const cell = this.getters.getEvaluatedCell({ ...p, sheetId: range.sheetId });
67056
+ if (cell.formattedValue && !labelsSet.has(cell.formattedValue)) {
67057
+ labelsSet.add(cell.formattedValue);
67058
+ values.push({ label: cell.formattedValue, value: cell.value?.toString() || "" });
67059
+ }
67060
+ }
67061
+ return values;
67041
67062
  }
67042
67063
  isCellValidCheckbox(cellPosition) {
67043
67064
  if (!this.getters.isMainCellPosition(cellPosition)) {
@@ -75652,25 +75673,30 @@ autoCompleteProviders.add("dataValidation", {
75652
75673
  }
75653
75674
  const sheetId = this.composer.currentEditedCell.sheetId;
75654
75675
  const values = rule.criterion.type === "isValueInRange"
75655
- ? Array.from(new Set(this.getters.getDataValidationRangeValues(sheetId, rule.criterion)))
75656
- : rule.criterion.values;
75676
+ ? this.getters.getDataValidationRangeValues(sheetId, rule.criterion)
75677
+ : rule.criterion.values.map((value) => ({ label: value, value }));
75657
75678
  const isChip = rule.criterion.displayStyle === "chip";
75658
75679
  if (!isChip) {
75659
- return values.map((value) => ({ text: value }));
75680
+ return values.map((value) => ({
75681
+ text: value.value,
75682
+ fuzzySearchKey: value.label,
75683
+ htmlContent: [{ value: value.label }],
75684
+ }));
75660
75685
  }
75661
75686
  const colors = rule.criterion.colors;
75662
75687
  return values.map((value) => {
75663
- const color = colors?.[value];
75688
+ const color = colors?.[value.value];
75664
75689
  return {
75665
- text: value,
75690
+ text: value.value,
75666
75691
  htmlContent: [
75667
75692
  {
75668
- value,
75693
+ value: value.label,
75669
75694
  color: color ? chipTextColor(color) : undefined,
75670
75695
  backgroundColor: color || GRAY_200,
75671
75696
  classes: ["badge rounded-pill fs-6 fw-normal w-100 mt-1 text-start"],
75672
75697
  },
75673
75698
  ],
75699
+ fuzzySearchKey: value.label,
75674
75700
  };
75675
75701
  });
75676
75702
  },
@@ -84646,6 +84672,6 @@ exports.tokenColors = tokenColors;
84646
84672
  exports.tokenize = tokenize;
84647
84673
 
84648
84674
 
84649
- __info__.version = "18.4.3";
84650
- __info__.date = "2025-07-28T13:39:06.036Z";
84651
- __info__.hash = "4b596d7";
84675
+ __info__.version = "18.4.4";
84676
+ __info__.date = "2025-07-30T11:20:08.639Z";
84677
+ __info__.hash = "b14de14";
@@ -5557,7 +5557,10 @@ declare class EvaluationDataValidationPlugin extends CoreViewPlugin {
5557
5557
  * The value must be canonicalized.
5558
5558
  */
5559
5559
  getDataValidationInvalidCriterionValueMessage(criterionType: DataValidationCriterionType, value: string): string | undefined;
5560
- getDataValidationRangeValues(sheetId: UID, criterion: EvaluatedCriterion): string[];
5560
+ getDataValidationRangeValues(sheetId: UID, criterion: EvaluatedCriterion): {
5561
+ value: string;
5562
+ label: string;
5563
+ }[];
5561
5564
  isCellValidCheckbox(cellPosition: CellPosition): boolean;
5562
5565
  /** Get the validation result if the cell on the given position had the given value */
5563
5566
  getValidationResultForCellValue(cellValue: CellValue, cellPosition: CellPosition): ValidationResult;
@@ -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.3
6
- * @date 2025-07-28T13:39:06.036Z
7
- * @hash 4b596d7
5
+ * @version 18.4.4
6
+ * @date 2025-07-30T11:20:08.639Z
7
+ * @hash b14de14
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';
@@ -8624,12 +8624,12 @@ const AGGREGATOR_NAMES = {
8624
8624
  avg: _t("Average"),
8625
8625
  sum: _t("Sum"),
8626
8626
  };
8627
- const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
8627
+ const DEFAULT_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
8628
8628
  const AGGREGATORS_BY_FIELD_TYPE = {
8629
- integer: NUMBER_CHAR_AGGREGATORS,
8630
- char: NUMBER_CHAR_AGGREGATORS,
8629
+ integer: DEFAULT_AGGREGATORS,
8630
+ char: DEFAULT_AGGREGATORS,
8631
+ datetime: DEFAULT_AGGREGATORS,
8631
8632
  boolean: ["count_distinct", "count", "bool_and", "bool_or"],
8632
- datetime: ["max", "min", "count_distinct", "count"],
8633
8633
  };
8634
8634
  const AGGREGATORS = {};
8635
8635
  for (const type in AGGREGATORS_BY_FIELD_TYPE) {
@@ -31707,7 +31707,7 @@ criterionEvaluatorRegistry.add("isValueInRange", {
31707
31707
  }
31708
31708
  const criterionValues = getters.getDataValidationRangeValues(sheetId, criterion);
31709
31709
  return criterionValues
31710
- .map((value) => value.toLowerCase())
31710
+ .map((value) => value.value.toLowerCase())
31711
31711
  .includes(value.toString().toLowerCase());
31712
31712
  },
31713
31713
  getErrorString: (criterion) => _t("The value must be a value in the range %s", String(criterion.values[0])),
@@ -52042,7 +52042,8 @@ class ConditionalFormattingEditor extends Component {
52042
52042
  static props = {
52043
52043
  editedCf: Object,
52044
52044
  onCancel: Function,
52045
- onSave: Function,
52045
+ onExit: Function,
52046
+ isNewCf: Boolean,
52046
52047
  };
52047
52048
  static components = {
52048
52049
  SelectionInput,
@@ -52067,6 +52068,7 @@ class ConditionalFormattingEditor extends Component {
52067
52068
  currentCFType: this.props.editedCf.rule.type,
52068
52069
  ranges: this.props.editedCf.ranges,
52069
52070
  rules: this.getDefaultRules(),
52071
+ hasEditedCf: this.props.isNewCf,
52070
52072
  });
52071
52073
  switch (this.props.editedCf.rule.type) {
52072
52074
  case "CellIsRule":
@@ -52118,6 +52120,9 @@ class ConditionalFormattingEditor extends Component {
52118
52120
  ranges: ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(sheetId, xc)),
52119
52121
  sheetId,
52120
52122
  });
52123
+ if (result.isSuccessful) {
52124
+ this.state.hasEditedCf = true;
52125
+ }
52121
52126
  const reasons = result.reasons.filter((r) => r !== "NoChanges" /* CommandResult.NoChanges */);
52122
52127
  if (!newCf.suppressErrors) {
52123
52128
  this.state.errors = reasons;
@@ -52139,7 +52144,15 @@ class ConditionalFormattingEditor extends Component {
52139
52144
  onSave() {
52140
52145
  const result = this.updateConditionalFormat({});
52141
52146
  if (result.length === 0) {
52142
- this.props.onSave();
52147
+ this.props.onExit();
52148
+ }
52149
+ }
52150
+ onCancel() {
52151
+ if (this.state.hasEditedCf) {
52152
+ this.props.onCancel();
52153
+ }
52154
+ else {
52155
+ this.props.onExit();
52143
52156
  }
52144
52157
  }
52145
52158
  getDefaultRules() {
@@ -67034,8 +67047,16 @@ class EvaluationDataValidationPlugin extends CoreViewPlugin {
67034
67047
  }
67035
67048
  getDataValidationRangeValues(sheetId, criterion) {
67036
67049
  const range = this.getters.getRangeFromSheetXC(sheetId, String(criterion.values[0]));
67037
- const criterionValues = this.getters.getRangeValues(range);
67038
- return criterionValues.map((value) => value?.toString()).filter(isDefined);
67050
+ const values = [];
67051
+ const labelsSet = new Set();
67052
+ for (const p of positions(range.zone)) {
67053
+ const cell = this.getters.getEvaluatedCell({ ...p, sheetId: range.sheetId });
67054
+ if (cell.formattedValue && !labelsSet.has(cell.formattedValue)) {
67055
+ labelsSet.add(cell.formattedValue);
67056
+ values.push({ label: cell.formattedValue, value: cell.value?.toString() || "" });
67057
+ }
67058
+ }
67059
+ return values;
67039
67060
  }
67040
67061
  isCellValidCheckbox(cellPosition) {
67041
67062
  if (!this.getters.isMainCellPosition(cellPosition)) {
@@ -75650,25 +75671,30 @@ autoCompleteProviders.add("dataValidation", {
75650
75671
  }
75651
75672
  const sheetId = this.composer.currentEditedCell.sheetId;
75652
75673
  const values = rule.criterion.type === "isValueInRange"
75653
- ? Array.from(new Set(this.getters.getDataValidationRangeValues(sheetId, rule.criterion)))
75654
- : rule.criterion.values;
75674
+ ? this.getters.getDataValidationRangeValues(sheetId, rule.criterion)
75675
+ : rule.criterion.values.map((value) => ({ label: value, value }));
75655
75676
  const isChip = rule.criterion.displayStyle === "chip";
75656
75677
  if (!isChip) {
75657
- return values.map((value) => ({ text: value }));
75678
+ return values.map((value) => ({
75679
+ text: value.value,
75680
+ fuzzySearchKey: value.label,
75681
+ htmlContent: [{ value: value.label }],
75682
+ }));
75658
75683
  }
75659
75684
  const colors = rule.criterion.colors;
75660
75685
  return values.map((value) => {
75661
- const color = colors?.[value];
75686
+ const color = colors?.[value.value];
75662
75687
  return {
75663
- text: value,
75688
+ text: value.value,
75664
75689
  htmlContent: [
75665
75690
  {
75666
- value,
75691
+ value: value.label,
75667
75692
  color: color ? chipTextColor(color) : undefined,
75668
75693
  backgroundColor: color || GRAY_200,
75669
75694
  classes: ["badge rounded-pill fs-6 fw-normal w-100 mt-1 text-start"],
75670
75695
  },
75671
75696
  ],
75697
+ fuzzySearchKey: value.label,
75672
75698
  };
75673
75699
  });
75674
75700
  },
@@ -84596,6 +84622,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
84596
84622
  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 };
84597
84623
 
84598
84624
 
84599
- __info__.version = "18.4.3";
84600
- __info__.date = "2025-07-28T13:39:06.036Z";
84601
- __info__.hash = "4b596d7";
84625
+ __info__.version = "18.4.4";
84626
+ __info__.date = "2025-07-30T11:20:08.639Z";
84627
+ __info__.hash = "b14de14";
@@ -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.3
6
- * @date 2025-07-28T13:39:06.036Z
7
- * @hash 4b596d7
5
+ * @version 18.4.4
6
+ * @date 2025-07-30T11:20:08.639Z
7
+ * @hash b14de14
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -8625,12 +8625,12 @@
8625
8625
  avg: _t("Average"),
8626
8626
  sum: _t("Sum"),
8627
8627
  };
8628
- const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
8628
+ const DEFAULT_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
8629
8629
  const AGGREGATORS_BY_FIELD_TYPE = {
8630
- integer: NUMBER_CHAR_AGGREGATORS,
8631
- char: NUMBER_CHAR_AGGREGATORS,
8630
+ integer: DEFAULT_AGGREGATORS,
8631
+ char: DEFAULT_AGGREGATORS,
8632
+ datetime: DEFAULT_AGGREGATORS,
8632
8633
  boolean: ["count_distinct", "count", "bool_and", "bool_or"],
8633
- datetime: ["max", "min", "count_distinct", "count"],
8634
8634
  };
8635
8635
  const AGGREGATORS = {};
8636
8636
  for (const type in AGGREGATORS_BY_FIELD_TYPE) {
@@ -31708,7 +31708,7 @@ stores.inject(MyMetaStore, storeInstance);
31708
31708
  }
31709
31709
  const criterionValues = getters.getDataValidationRangeValues(sheetId, criterion);
31710
31710
  return criterionValues
31711
- .map((value) => value.toLowerCase())
31711
+ .map((value) => value.value.toLowerCase())
31712
31712
  .includes(value.toString().toLowerCase());
31713
31713
  },
31714
31714
  getErrorString: (criterion) => _t("The value must be a value in the range %s", String(criterion.values[0])),
@@ -52043,7 +52043,8 @@ stores.inject(MyMetaStore, storeInstance);
52043
52043
  static props = {
52044
52044
  editedCf: Object,
52045
52045
  onCancel: Function,
52046
- onSave: Function,
52046
+ onExit: Function,
52047
+ isNewCf: Boolean,
52047
52048
  };
52048
52049
  static components = {
52049
52050
  SelectionInput,
@@ -52068,6 +52069,7 @@ stores.inject(MyMetaStore, storeInstance);
52068
52069
  currentCFType: this.props.editedCf.rule.type,
52069
52070
  ranges: this.props.editedCf.ranges,
52070
52071
  rules: this.getDefaultRules(),
52072
+ hasEditedCf: this.props.isNewCf,
52071
52073
  });
52072
52074
  switch (this.props.editedCf.rule.type) {
52073
52075
  case "CellIsRule":
@@ -52119,6 +52121,9 @@ stores.inject(MyMetaStore, storeInstance);
52119
52121
  ranges: ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(sheetId, xc)),
52120
52122
  sheetId,
52121
52123
  });
52124
+ if (result.isSuccessful) {
52125
+ this.state.hasEditedCf = true;
52126
+ }
52122
52127
  const reasons = result.reasons.filter((r) => r !== "NoChanges" /* CommandResult.NoChanges */);
52123
52128
  if (!newCf.suppressErrors) {
52124
52129
  this.state.errors = reasons;
@@ -52140,7 +52145,15 @@ stores.inject(MyMetaStore, storeInstance);
52140
52145
  onSave() {
52141
52146
  const result = this.updateConditionalFormat({});
52142
52147
  if (result.length === 0) {
52143
- this.props.onSave();
52148
+ this.props.onExit();
52149
+ }
52150
+ }
52151
+ onCancel() {
52152
+ if (this.state.hasEditedCf) {
52153
+ this.props.onCancel();
52154
+ }
52155
+ else {
52156
+ this.props.onExit();
52144
52157
  }
52145
52158
  }
52146
52159
  getDefaultRules() {
@@ -67035,8 +67048,16 @@ stores.inject(MyMetaStore, storeInstance);
67035
67048
  }
67036
67049
  getDataValidationRangeValues(sheetId, criterion) {
67037
67050
  const range = this.getters.getRangeFromSheetXC(sheetId, String(criterion.values[0]));
67038
- const criterionValues = this.getters.getRangeValues(range);
67039
- return criterionValues.map((value) => value?.toString()).filter(isDefined);
67051
+ const values = [];
67052
+ const labelsSet = new Set();
67053
+ for (const p of positions(range.zone)) {
67054
+ const cell = this.getters.getEvaluatedCell({ ...p, sheetId: range.sheetId });
67055
+ if (cell.formattedValue && !labelsSet.has(cell.formattedValue)) {
67056
+ labelsSet.add(cell.formattedValue);
67057
+ values.push({ label: cell.formattedValue, value: cell.value?.toString() || "" });
67058
+ }
67059
+ }
67060
+ return values;
67040
67061
  }
67041
67062
  isCellValidCheckbox(cellPosition) {
67042
67063
  if (!this.getters.isMainCellPosition(cellPosition)) {
@@ -75651,25 +75672,30 @@ stores.inject(MyMetaStore, storeInstance);
75651
75672
  }
75652
75673
  const sheetId = this.composer.currentEditedCell.sheetId;
75653
75674
  const values = rule.criterion.type === "isValueInRange"
75654
- ? Array.from(new Set(this.getters.getDataValidationRangeValues(sheetId, rule.criterion)))
75655
- : rule.criterion.values;
75675
+ ? this.getters.getDataValidationRangeValues(sheetId, rule.criterion)
75676
+ : rule.criterion.values.map((value) => ({ label: value, value }));
75656
75677
  const isChip = rule.criterion.displayStyle === "chip";
75657
75678
  if (!isChip) {
75658
- return values.map((value) => ({ text: value }));
75679
+ return values.map((value) => ({
75680
+ text: value.value,
75681
+ fuzzySearchKey: value.label,
75682
+ htmlContent: [{ value: value.label }],
75683
+ }));
75659
75684
  }
75660
75685
  const colors = rule.criterion.colors;
75661
75686
  return values.map((value) => {
75662
- const color = colors?.[value];
75687
+ const color = colors?.[value.value];
75663
75688
  return {
75664
- text: value,
75689
+ text: value.value,
75665
75690
  htmlContent: [
75666
75691
  {
75667
- value,
75692
+ value: value.label,
75668
75693
  color: color ? chipTextColor(color) : undefined,
75669
75694
  backgroundColor: color || GRAY_200,
75670
75695
  classes: ["badge rounded-pill fs-6 fw-normal w-100 mt-1 text-start"],
75671
75696
  },
75672
75697
  ],
75698
+ fuzzySearchKey: value.label,
75673
75699
  };
75674
75700
  });
75675
75701
  },
@@ -84645,9 +84671,9 @@ stores.inject(MyMetaStore, storeInstance);
84645
84671
  exports.tokenize = tokenize;
84646
84672
 
84647
84673
 
84648
- __info__.version = "18.4.3";
84649
- __info__.date = "2025-07-28T13:39:06.036Z";
84650
- __info__.hash = "4b596d7";
84674
+ __info__.version = "18.4.4";
84675
+ __info__.date = "2025-07-30T11:20:08.639Z";
84676
+ __info__.hash = "b14de14";
84651
84677
 
84652
84678
 
84653
84679
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);