@odoo/o-spreadsheet 16.4.5 → 16.4.7

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.
@@ -614,13 +614,17 @@ function getAddHeaderStartIndex(position, base) {
614
614
  return position === "after" ? base + 1 : base;
615
615
  }
616
616
  /**
617
- * Compare two objects.
617
+ * Compares two objects.
618
618
  */
619
619
  function deepEquals(o1, o2) {
620
620
  if (o1 === o2)
621
621
  return true;
622
622
  if ((o1 && !o2) || (o2 && !o1))
623
623
  return false;
624
+ if (typeof o1 !== typeof o2)
625
+ return false;
626
+ if (typeof o1 !== "object")
627
+ return o1 === o2;
624
628
  // Objects can have different keys if the values are undefined
625
629
  const keys = new Set();
626
630
  Object.keys(o1).forEach((key) => keys.add(key));
@@ -5265,6 +5269,7 @@ css /* scss */ `
5265
5269
  padding: 10px;
5266
5270
  width: ${ERROR_TOOLTIP_WIDTH}px;
5267
5271
  box-sizing: border-box !important;
5272
+ overflow-wrap: break-word;
5268
5273
  }
5269
5274
  `;
5270
5275
  class ErrorToolTip extends owl.Component {
@@ -15120,13 +15125,42 @@ function isValidLocale(locale) {
15120
15125
  }
15121
15126
  return true;
15122
15127
  }
15123
- /** Change a content string to its canonical form (en_US locale) */
15128
+ /**
15129
+ * Change a content string from the given locale to its canonical form (en_US locale). Don't convert date string.
15130
+ *
15131
+ * @example
15132
+ * canonicalizeNumberContent("=SUM(1,5; 02/12/2012)", FR_LOCALE) // "=SUM(1.5, 02/12/2012)"
15133
+ * canonicalizeNumberContent("125,9", FR_LOCALE) // "125.9"
15134
+ * canonicalizeNumberContent("02/12/2012", FR_LOCALE) // "02/12/2012"
15135
+ */
15136
+ function canonicalizeNumberContent(content, locale) {
15137
+ return content.startsWith("=")
15138
+ ? canonicalizeFormula$1(content, locale)
15139
+ : canonicalizeNumberLiteral(content, locale);
15140
+ }
15141
+ /**
15142
+ * Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
15143
+ * This is destructive and won't preserve the original format.
15144
+ *
15145
+ * @example
15146
+ * canonicalizeContent("=SUM(1,5; 5)", FR_LOCALE) // "=SUM(1.5, 5)"
15147
+ * canonicalizeContent("125,9", FR_LOCALE) // "125.9"
15148
+ * canonicalizeContent("02/12/2012", FR_LOCALE) // "12/02/2012"
15149
+ * canonicalizeContent("02-12-2012", FR_LOCALE) // "12/02/2012"
15150
+ */
15124
15151
  function canonicalizeContent(content, locale) {
15125
15152
  return content.startsWith("=")
15126
15153
  ? canonicalizeFormula$1(content, locale)
15127
- : toCanonicalNumberString(content, locale);
15154
+ : canonicalizeLiteral(content, locale);
15128
15155
  }
15129
- /** Change the content of a cell to its canonical form (en_US locale) */
15156
+ /**
15157
+ * Change a content string from its canonical form (en_US locale) to the given locale. Also convert date string.
15158
+ *
15159
+ * @example
15160
+ * localizeContent("=SUM(1.5, 5)", FR_LOCALE) // "=SUM(1,5; 5)"
15161
+ * localizeContent("125.9", FR_LOCALE) // "125,9"
15162
+ * localizeContent("12/02/2012", FR_LOCALE) // "02/12/2012"
15163
+ */
15130
15164
  function localizeContent(content, locale) {
15131
15165
  return content.startsWith("=")
15132
15166
  ? localizeFormula(content, locale)
@@ -15161,24 +15195,75 @@ function _localizeFormula$1(formula, fromLocale, toLocale) {
15161
15195
  return localizedFormula;
15162
15196
  }
15163
15197
  /**
15164
- * Replace localized number with localized decimal separator by a number with "." as decimal separator
15198
+ * Change a literal string from the given locale to its canonical form (en_US locale). Don't convert date string.
15199
+ *
15200
+ * @example
15201
+ * canonicalizeNumberLiteral("125,9", FR_LOCALE) // "125.9"
15202
+ * canonicalizeNumberLiteral("02/12/2012", FR_LOCALE) // "02/12/2012"
15165
15203
  */
15166
- function toCanonicalNumberString(content, locale) {
15204
+ function canonicalizeNumberLiteral(content, locale) {
15167
15205
  if (locale.decimalSeparator === "." || !isNumber(content, locale)) {
15168
15206
  return content;
15169
15207
  }
15170
15208
  return content.replace(locale.decimalSeparator, ".");
15171
15209
  }
15172
- function localizeLiteral(content, locale) {
15173
- if (locale.decimalSeparator === "." || !isNumber(content, DEFAULT_LOCALE)) {
15174
- return content;
15210
+ /**
15211
+ * Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
15212
+ * This is destructive and won't preserve the original format.
15213
+ *
15214
+ * @example
15215
+ * canonicalizeLiteral("125,9", FR_LOCALE) // "125.9"
15216
+ * canonicalizeLiteral("02/12/2012", FR_LOCALE) // "12/02/2012"
15217
+ * canonicalizeLiteral("02-12-2012", FR_LOCALE) // "12/02/2012"
15218
+ */
15219
+ function canonicalizeLiteral(content, locale) {
15220
+ if (isDateTime(content, locale)) {
15221
+ const dateNumber = toNumber(content, locale);
15222
+ let format = DEFAULT_LOCALE.dateFormat;
15223
+ if (!Number.isInteger(dateNumber)) {
15224
+ format += " " + DEFAULT_LOCALE.timeFormat;
15225
+ }
15226
+ return formatValue(dateNumber, { locale: DEFAULT_LOCALE, format });
15227
+ }
15228
+ return canonicalizeNumberLiteral(content, locale);
15229
+ }
15230
+ /**
15231
+ * Change a literal string from its canonical form (en_US locale) to the given locale. Don't convert date string.
15232
+ * This is destructive and won't preserve the original format.
15233
+ *
15234
+ * @example
15235
+ * localizeNumberLiteral("125.9", FR_LOCALE) // "125,9"
15236
+ * localizeNumberLiteral("12/02/2012", FR_LOCALE) // "12/02/2012"
15237
+ * localizeNumberLiteral("12-02-2012", FR_LOCALE) // "12/02/2012"
15238
+ */
15239
+ function localizeNumberLiteral(literal, locale) {
15240
+ if (locale.decimalSeparator === "." || !isNumber(literal, DEFAULT_LOCALE)) {
15241
+ return literal;
15175
15242
  }
15176
15243
  const decimalNumberRegex = getDecimalNumberRegex(DEFAULT_LOCALE);
15177
- const localized = content.replace(decimalNumberRegex, (match) => {
15244
+ const localized = literal.replace(decimalNumberRegex, (match) => {
15178
15245
  return match.replace(".", locale.decimalSeparator);
15179
15246
  });
15180
15247
  return localized;
15181
15248
  }
15249
+ /**
15250
+ * Change a literal string from its canonical form (en_US locale) to the given locale. Also convert date string.
15251
+ *
15252
+ * @example
15253
+ * localizeLiteral("125.9", FR_LOCALE) // "125,9"
15254
+ * localizeLiteral("12/02/2012", FR_LOCALE) // "02/12/2012"
15255
+ */
15256
+ function localizeLiteral(literal, locale) {
15257
+ if (isDateTime(literal, DEFAULT_LOCALE)) {
15258
+ const dateNumber = toNumber(literal, DEFAULT_LOCALE);
15259
+ let format = locale.dateFormat;
15260
+ if (!Number.isInteger(dateNumber)) {
15261
+ format += " " + locale.timeFormat;
15262
+ }
15263
+ return formatValue(dateNumber, { locale, format });
15264
+ }
15265
+ return localizeNumberLiteral(literal, locale);
15266
+ }
15182
15267
  function canonicalizeCFRule(cf, locale) {
15183
15268
  return changeCFRuleLocale(cf, (content) => canonicalizeContent(content, locale));
15184
15269
  }
@@ -15535,7 +15620,9 @@ class LinkEditor extends owl.Component {
15535
15620
  save() {
15536
15621
  const { col, row } = this.props.cellPosition;
15537
15622
  const locale = this.env.model.getters.getLocale();
15538
- const label = this.link.label ? canonicalizeContent(this.link.label, locale) : this.link.url;
15623
+ const label = this.link.label
15624
+ ? canonicalizeNumberContent(this.link.label, locale)
15625
+ : this.link.url;
15539
15626
  this.env.model.dispatch("UPDATE_CELL", {
15540
15627
  col: col,
15541
15628
  row: row,
@@ -16878,6 +16965,7 @@ class LineChart extends AbstractChart {
16878
16965
  aggregated;
16879
16966
  type = "line";
16880
16967
  dataSetsHaveTitle;
16968
+ cumulative;
16881
16969
  constructor(definition, sheetId, getters) {
16882
16970
  super(definition, sheetId, getters);
16883
16971
  this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
@@ -16889,6 +16977,7 @@ class LineChart extends AbstractChart {
16889
16977
  this.stacked = definition.stacked;
16890
16978
  this.aggregated = definition.aggregated;
16891
16979
  this.dataSetsHaveTitle = definition.dataSetsHaveTitle;
16980
+ this.cumulative = definition.cumulative;
16892
16981
  }
16893
16982
  static validateChartDefinition(validator, definition) {
16894
16983
  return validator.checkValidations(definition, checkDataset, checkLabelRange);
@@ -16909,6 +16998,7 @@ class LineChart extends AbstractChart {
16909
16998
  labelRange: context.auxiliaryRange || undefined,
16910
16999
  stacked: false,
16911
17000
  aggregated: false,
17001
+ cumulative: false,
16912
17002
  };
16913
17003
  }
16914
17004
  getDefinition() {
@@ -16929,6 +17019,7 @@ class LineChart extends AbstractChart {
16929
17019
  labelsAsText: this.labelsAsText,
16930
17020
  stacked: this.stacked,
16931
17021
  aggregated: this.aggregated,
17022
+ cumulative: this.cumulative,
16932
17023
  };
16933
17024
  }
16934
17025
  getContextCreation() {
@@ -17139,6 +17230,16 @@ function createLineChartRuntime(chart, getters) {
17139
17230
  if (chart.stacked) {
17140
17231
  backgroundRGBA.a = LINE_FILL_TRANSPARENCY;
17141
17232
  }
17233
+ if (chart.cumulative) {
17234
+ let accumulator = 0;
17235
+ data = data.map((value) => {
17236
+ if (!isNaN(value)) {
17237
+ accumulator += parseFloat(value);
17238
+ return accumulator;
17239
+ }
17240
+ return value;
17241
+ });
17242
+ }
17142
17243
  const backgroundColor = rgbaToHex(backgroundRGBA);
17143
17244
  const dataset = {
17144
17245
  label,
@@ -18013,6 +18114,7 @@ function getSmartChartDefinition(zone, getters) {
18013
18114
  labelsAsText: false,
18014
18115
  stacked: false,
18015
18116
  aggregated: false,
18117
+ cumulative: false,
18016
18118
  labelRange: labelRangeXc,
18017
18119
  type: "line",
18018
18120
  dataSetsHaveTitle,
@@ -18176,6 +18278,13 @@ const REMOVE_ROWS_ACTION = (env) => {
18176
18278
  elements: rows,
18177
18279
  });
18178
18280
  };
18281
+ const CAN_REMOVE_COLUMNS_ROWS = (dimension, env) => {
18282
+ const sheetId = env.model.getters.getActiveSheetId();
18283
+ const selectedElements = env.model.getters.getElementsFromSelection(dimension);
18284
+ const includesAllVisibleHeaders = env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, dimension, selectedElements);
18285
+ const includesAllNonFrozenHeaders = env.model.getters.checkElementsIncludeAllNonFrozenHeaders(sheetId, dimension, selectedElements);
18286
+ return !includesAllVisibleHeaders && !includesAllNonFrozenHeaders;
18287
+ };
18179
18288
  const REMOVE_COLUMNS_NAME = (env) => {
18180
18289
  if (env.model.getters.getSelectedZones().length > 1) {
18181
18290
  return _lt("Delete columns");
@@ -18200,7 +18309,7 @@ const REMOVE_COLUMNS_NAME = (env) => {
18200
18309
  const NOT_ALL_VISIBLE_ROWS_SELECTED = (env) => {
18201
18310
  const sheetId = env.model.getters.getActiveSheetId();
18202
18311
  const selectedRows = env.model.getters.getElementsFromSelection("ROW");
18203
- return env.model.getters.canRemoveHeaders(sheetId, "ROW", selectedRows);
18312
+ return !env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, "ROW", selectedRows);
18204
18313
  };
18205
18314
  const REMOVE_COLUMNS_ACTION = (env) => {
18206
18315
  let columns = [...env.model.getters.getActiveCols()];
@@ -18219,7 +18328,7 @@ const REMOVE_COLUMNS_ACTION = (env) => {
18219
18328
  const NOT_ALL_VISIBLE_COLS_SELECTED = (env) => {
18220
18329
  const sheetId = env.model.getters.getActiveSheetId();
18221
18330
  const selectedCols = env.model.getters.getElementsFromSelection("COL");
18222
- return env.model.getters.canRemoveHeaders(sheetId, "COL", selectedCols);
18331
+ return !env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, "COL", selectedCols);
18223
18332
  };
18224
18333
  const INSERT_ROWS_BEFORE_ACTION = (env) => {
18225
18334
  const activeRows = env.model.getters.getActiveRows();
@@ -18491,7 +18600,7 @@ const deleteValues = {
18491
18600
  const deleteRows = {
18492
18601
  name: REMOVE_ROWS_NAME,
18493
18602
  execute: REMOVE_ROWS_ACTION,
18494
- isVisible: NOT_ALL_VISIBLE_ROWS_SELECTED,
18603
+ isVisible: (env) => CAN_REMOVE_COLUMNS_ROWS("ROW", env),
18495
18604
  };
18496
18605
  const deleteRow = {
18497
18606
  ...deleteRows,
@@ -18504,7 +18613,7 @@ const clearRows = {
18504
18613
  const deleteCols = {
18505
18614
  name: REMOVE_COLUMNS_NAME,
18506
18615
  execute: REMOVE_COLUMNS_ACTION,
18507
- isVisible: NOT_ALL_VISIBLE_COLS_SELECTED,
18616
+ isVisible: (env) => CAN_REMOVE_COLUMNS_ROWS("COL", env),
18508
18617
  };
18509
18618
  const deleteCol = {
18510
18619
  ...deleteCols,
@@ -21479,6 +21588,11 @@ class LineConfigPanel extends LineBarPieConfigPanel {
21479
21588
  aggregated: ev.target.checked,
21480
21589
  });
21481
21590
  }
21591
+ onUpdateCumulative(ev) {
21592
+ this.props.updateChart(this.props.figureId, {
21593
+ cumulative: ev.target.checked,
21594
+ });
21595
+ }
21482
21596
  }
21483
21597
 
21484
21598
  class LineChartDesignPanel extends LineBarPieDesignPanel {
@@ -25278,9 +25392,11 @@ function useCellHovered(env, gridRef, callback) {
25278
25392
  }
25279
25393
  }
25280
25394
  function updateMousePosition(e) {
25281
- x = e.offsetX;
25282
- y = e.offsetY;
25283
- lastMoved = Date.now();
25395
+ if (gridRef.el === e.target) {
25396
+ x = e.offsetX;
25397
+ y = e.offsetY;
25398
+ lastMoved = Date.now();
25399
+ }
25284
25400
  }
25285
25401
  function recompute() {
25286
25402
  const { col, row } = getPosition();
@@ -28452,6 +28568,7 @@ function convertChartData(chartData) {
28452
28568
  legendPosition: chartData.legendPosition,
28453
28569
  stacked: chartData.stacked || false,
28454
28570
  aggregated: false,
28571
+ cumulative: chartData.cumulative || false,
28455
28572
  labelsAsText: false,
28456
28573
  };
28457
28574
  }
@@ -33112,7 +33229,7 @@ class HeaderSizePlugin extends CorePlugin {
33112
33229
 
33113
33230
  class HeaderVisibilityPlugin extends CorePlugin {
33114
33231
  static getters = [
33115
- "canRemoveHeaders",
33232
+ "checkElementsIncludeAllVisibleHeaders",
33116
33233
  "getHiddenColsGroups",
33117
33234
  "getHiddenRowsGroups",
33118
33235
  "isRowHiddenByUser",
@@ -33146,7 +33263,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
33146
33263
  if (!this.getters.tryGetSheet(cmd.sheetId)) {
33147
33264
  return 28 /* CommandResult.InvalidSheetId */;
33148
33265
  }
33149
- if (!this.canRemoveHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
33266
+ if (this.checkElementsIncludeAllVisibleHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
33150
33267
  return 8 /* CommandResult.NotEnoughElements */;
33151
33268
  }
33152
33269
  return 0 /* CommandResult.Success */;
@@ -33196,9 +33313,9 @@ class HeaderVisibilityPlugin extends CorePlugin {
33196
33313
  }
33197
33314
  return;
33198
33315
  }
33199
- canRemoveHeaders(sheetId, dimension, elements) {
33316
+ checkElementsIncludeAllVisibleHeaders(sheetId, dimension, elements) {
33200
33317
  const visibleHeaders = this.getAllVisibleHeaders(sheetId, dimension);
33201
- return !includesAll(elements, visibleHeaders);
33318
+ return includesAll(elements, visibleHeaders);
33202
33319
  }
33203
33320
  isRowHiddenByUser(sheetId, index) {
33204
33321
  return this.hiddenHeaders[sheetId].ROW[index];
@@ -34303,6 +34420,7 @@ class SheetPlugin extends CorePlugin {
34303
34420
  "checkZonesExistInSheet",
34304
34421
  "getCommandZones",
34305
34422
  "getUnboundedZone",
34423
+ "checkElementsIncludeAllNonFrozenHeaders",
34306
34424
  ];
34307
34425
  sheetIdsMapName = {};
34308
34426
  orderedSheetIds = [];
@@ -34359,6 +34477,9 @@ class SheetPlugin extends CorePlugin {
34359
34477
  if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
34360
34478
  return 87 /* CommandResult.InvalidHeaderIndex */;
34361
34479
  }
34480
+ else if (this.checkElementsIncludeAllNonFrozenHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
34481
+ return 8 /* CommandResult.NotEnoughElements */;
34482
+ }
34362
34483
  else {
34363
34484
  return 0 /* CommandResult.Success */;
34364
34485
  }
@@ -34651,6 +34772,20 @@ class SheetPlugin extends CorePlugin {
34651
34772
  }
34652
34773
  this.history.update("sheets", sheetId, "panes", panes);
34653
34774
  }
34775
+ /**
34776
+ * Checks if all non-frozen header indices are present in the provided elements of selected rows/columns.
34777
+ * This validation ensures that all rows or columns cannot be deleted when frozen panes exist.
34778
+ */
34779
+ checkElementsIncludeAllNonFrozenHeaders(sheetId, dimension, elements) {
34780
+ const paneDivisions = this.getters.getPaneDivisions(sheetId);
34781
+ const startIndex = dimension === "ROW" ? paneDivisions.ySplit : paneDivisions.xSplit;
34782
+ const endIndex = this.getters.getNumberHeaders(sheetId, dimension);
34783
+ if (!startIndex) {
34784
+ return false;
34785
+ }
34786
+ const indicesToCheck = range(startIndex, endIndex);
34787
+ return includesAll(elements, indicesToCheck);
34788
+ }
34654
34789
  // ---------------------------------------------------------------------------
34655
34790
  // Row/Col manipulation
34656
34791
  // ---------------------------------------------------------------------------
@@ -36634,8 +36769,7 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
36634
36769
  if (cell.type === CellValueType.error) {
36635
36770
  return false;
36636
36771
  }
36637
- const locale = this.getters.getLocale();
36638
- const values = rule.values.map((val) => parseLiteral(val, locale));
36772
+ const values = rule.values.map((val) => parseLiteral(val, DEFAULT_LOCALE));
36639
36773
  switch (rule.operator) {
36640
36774
  case "IsEmpty":
36641
36775
  return cell.value.toString().trim() === "";
@@ -38719,7 +38853,7 @@ class FindAndReplacePlugin extends UIPlugin {
38719
38853
  const replaceRegex = new RegExp(this.currentSearchRegex.source, this.currentSearchRegex.flags + "g");
38720
38854
  const toReplace = this.getSearchableString({ sheetId, col, row });
38721
38855
  const content = toReplace.replace(replaceRegex, replaceWith);
38722
- const canonicalContent = canonicalizeContent(content, this.getters.getLocale());
38856
+ const canonicalContent = canonicalizeNumberContent(content, this.getters.getLocale());
38723
38857
  this.dispatch("UPDATE_CELL", { sheetId, col, row, content: canonicalContent });
38724
38858
  }
38725
38859
  /**
@@ -40893,7 +41027,7 @@ class SplitToColumnsPlugin extends UIPlugin {
40893
41027
  sheetId,
40894
41028
  col: col + index,
40895
41029
  row,
40896
- content: canonicalizeContent(content, this.getters.getLocale()),
41030
+ content: canonicalizeNumberContent(content, this.getters.getLocale()),
40897
41031
  format: "",
40898
41032
  style: mainCell?.style || null,
40899
41033
  });
@@ -41079,6 +41213,7 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
41079
41213
  cells;
41080
41214
  copiedTables;
41081
41215
  zones;
41216
+ uuidGenerator = new UuidGenerator();
41082
41217
  constructor(zones, operation, getters, dispatch, selection) {
41083
41218
  super(operation, getters, dispatch, selection);
41084
41219
  if (!zones.length) {
@@ -41540,8 +41675,9 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
41540
41675
  this.adaptCFRules(origin.sheetId, cf, [xc], toRemoveRange);
41541
41676
  }
41542
41677
  else {
41543
- this.adaptCFRules(target.sheetId, cf, [xc], []);
41544
41678
  this.adaptCFRules(origin.sheetId, cf, [], toRemoveRange);
41679
+ const cfToCopyTo = this.getCFToCopyTo(target.sheetId, cf);
41680
+ this.adaptCFRules(target.sheetId, cfToCopyTo, [xc], []);
41545
41681
  }
41546
41682
  }
41547
41683
  }
@@ -41565,6 +41701,12 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
41565
41701
  sheetId,
41566
41702
  });
41567
41703
  }
41704
+ getCFToCopyTo(targetSheetId, originCF) {
41705
+ const cfInTarget = this.getters
41706
+ .getConditionalFormats(targetSheetId)
41707
+ .find((cf) => cf.stopIfTrue === originCF.stopIfTrue && deepEquals(cf.rule, originCF.rule));
41708
+ return cfInTarget ? cfInTarget : { ...originCF, id: this.uuidGenerator.uuidv4(), ranges: [] };
41709
+ }
41568
41710
  }
41569
41711
 
41570
41712
  /** State of the clipboard when copying/cutting figures */
@@ -41696,7 +41838,7 @@ class ClipboardFigureImage {
41696
41838
  function canonicalizeNumberValue(content, locale) {
41697
41839
  return content.startsWith("=")
41698
41840
  ? canonicalizeFormula(content, locale)
41699
- : toCanonicalNumberString(content, locale);
41841
+ : canonicalizeNumberLiteral(content, locale);
41700
41842
  }
41701
41843
  /** Change a formula to its canonical form (en_US locale) */
41702
41844
  function canonicalizeFormula(formula, locale) {
@@ -41813,7 +41955,7 @@ class ClipboardPlugin extends UIPlugin {
41813
41955
  allowDispatch(cmd) {
41814
41956
  switch (cmd.type) {
41815
41957
  case "CUT":
41816
- const zones = cmd.cutTarget || this.getters.getSelectedZones();
41958
+ const zones = this.getters.getSelectedZones();
41817
41959
  const state = this.getClipboardState(zones, cmd.type);
41818
41960
  return state.isCutAllowed(zones);
41819
41961
  case "PASTE":
@@ -41848,7 +41990,7 @@ class ClipboardPlugin extends UIPlugin {
41848
41990
  switch (cmd.type) {
41849
41991
  case "COPY":
41850
41992
  case "CUT":
41851
- const zones = ("cutTarget" in cmd && cmd.cutTarget) || this.getters.getSelectedZones();
41993
+ const zones = this.getters.getSelectedZones();
41852
41994
  this.state = this.getClipboardState(zones, cmd.type);
41853
41995
  this.status = "visible";
41854
41996
  this.originSheetId = this.getters.getActiveSheetId();
@@ -42498,7 +42640,7 @@ class EditionPlugin extends UIPlugin {
42498
42640
  if (content) {
42499
42641
  const sheetId = this.getters.getActiveSheetId();
42500
42642
  const cell = this.getters.getEvaluatedCell({ sheetId, col: this.col, row: this.row });
42501
- content = canonicalizeContent(content, this.getters.getLocale());
42643
+ content = canonicalizeNumberContent(content, this.getters.getLocale());
42502
42644
  if (content.startsWith("=")) {
42503
42645
  const left = this.currentTokens.filter((t) => t.type === "LEFT_PAREN").length;
42504
42646
  const right = this.currentTokens.filter((t) => t.type === "RIGHT_PAREN").length;
@@ -43519,26 +43661,24 @@ class GridSelectionPlugin extends UIPlugin {
43519
43661
  const isBasedBefore = cmd.base < start;
43520
43662
  const deltaCol = isBasedBefore && isCol ? thickness : 0;
43521
43663
  const deltaRow = isBasedBefore && !isCol ? thickness : 0;
43522
- this.dispatch("CUT", {
43523
- cutTarget: [
43524
- {
43525
- left: isCol ? start + deltaCol : 0,
43526
- right: isCol ? end + deltaCol : this.getters.getNumberCols(cmd.sheetId) - 1,
43527
- top: !isCol ? start + deltaRow : 0,
43528
- bottom: !isCol ? end + deltaRow : this.getters.getNumberRows(cmd.sheetId) - 1,
43529
- },
43530
- ],
43531
- });
43532
- this.dispatch("PASTE", {
43533
- target: [
43534
- {
43535
- left: isCol ? cmd.base : 0,
43536
- right: isCol ? cmd.base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
43537
- top: !isCol ? cmd.base : 0,
43538
- bottom: !isCol ? cmd.base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
43539
- },
43540
- ],
43541
- });
43664
+ const target = [
43665
+ {
43666
+ left: isCol ? start + deltaCol : 0,
43667
+ right: isCol ? end + deltaCol : this.getters.getNumberCols(cmd.sheetId) - 1,
43668
+ top: !isCol ? start + deltaRow : 0,
43669
+ bottom: !isCol ? end + deltaRow : this.getters.getNumberRows(cmd.sheetId) - 1,
43670
+ },
43671
+ ];
43672
+ const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
43673
+ const pasteTarget = [
43674
+ {
43675
+ left: isCol ? cmd.base : 0,
43676
+ right: isCol ? cmd.base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
43677
+ top: !isCol ? cmd.base : 0,
43678
+ bottom: !isCol ? cmd.base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
43679
+ },
43680
+ ];
43681
+ state.paste(pasteTarget, { selectTarget: true });
43542
43682
  const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
43543
43683
  let currentIndex = cmd.base;
43544
43684
  for (const element of toRemove) {
@@ -43937,6 +44077,9 @@ class InternalViewport {
43937
44077
  const sheetId = this.sheetId;
43938
44078
  this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
43939
44079
  this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
44080
+ if (this.left === -1) {
44081
+ this.left = this.boundaries.left;
44082
+ }
43940
44083
  if (this.right === -1) {
43941
44084
  this.right = this.getters.getNumberCols(sheetId) - 1;
43942
44085
  }
@@ -43950,6 +44093,9 @@ class InternalViewport {
43950
44093
  const sheetId = this.sheetId;
43951
44094
  this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
43952
44095
  this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
44096
+ if (this.top === -1) {
44097
+ this.top = this.boundaries.top;
44098
+ }
43953
44099
  if (this.bottom === -1) {
43954
44100
  this.bottom = this.getters.getNumberRows(sheetId) - 1;
43955
44101
  }
@@ -50550,6 +50696,6 @@ exports.setTranslationMethod = setTranslationMethod;
50550
50696
  exports.tokenize = tokenize;
50551
50697
 
50552
50698
 
50553
- __info__.version = '16.4.5';
50554
- __info__.date = '2023-08-29T13:55:58.527Z';
50555
- __info__.hash = '105c130';
50699
+ __info__.version = '16.4.7';
50700
+ __info__.date = '2023-09-21T15:58:11.039Z';
50701
+ __info__.hash = 'eccdcce';
@@ -424,6 +424,7 @@ interface LineChartDefinition {
424
424
  readonly labelsAsText: boolean;
425
425
  readonly stacked: boolean;
426
426
  readonly aggregated?: boolean;
427
+ readonly cumulative: boolean;
427
428
  }
428
429
  type LineChartRuntime = {
429
430
  chartJsConfig: ChartConfiguration;
@@ -490,6 +491,7 @@ interface ExcelChartDefinition {
490
491
  readonly verticalAxisPosition: VerticalAxisPosition;
491
492
  readonly legendPosition: LegendPosition;
492
493
  readonly stacked?: boolean;
494
+ readonly cumulative?: boolean;
493
495
  }
494
496
  interface ChartCreationContext {
495
497
  readonly range?: string[];
@@ -1895,8 +1897,6 @@ interface CopyCommand {
1895
1897
  }
1896
1898
  interface CutCommand {
1897
1899
  type: "CUT";
1898
- /** Zones to cut. If none were given, will copy the zones in the selection*/
1899
- cutTarget?: Zone[];
1900
1900
  }
1901
1901
  interface PasteCommand {
1902
1902
  type: "PASTE";
@@ -3462,11 +3462,11 @@ declare class HeaderSizePlugin extends CorePlugin<HeaderSizeState$1> implements
3462
3462
  }
3463
3463
 
3464
3464
  declare class HeaderVisibilityPlugin extends CorePlugin {
3465
- static getters: readonly ["canRemoveHeaders", "getHiddenColsGroups", "getHiddenRowsGroups", "isRowHiddenByUser", "isColHiddenByUser"];
3465
+ static getters: readonly ["checkElementsIncludeAllVisibleHeaders", "getHiddenColsGroups", "getHiddenRowsGroups", "isRowHiddenByUser", "isColHiddenByUser"];
3466
3466
  private readonly hiddenHeaders;
3467
3467
  allowDispatch(cmd: Command): CommandResult.Success | CommandResult.NotEnoughElements | CommandResult.InvalidSheetId | CommandResult.TooManyHiddenElements | CommandResult.InvalidHeaderIndex;
3468
3468
  handle(cmd: Command): void;
3469
- canRemoveHeaders(sheetId: UID, dimension: Dimension, elements: HeaderIndex[]): boolean;
3469
+ checkElementsIncludeAllVisibleHeaders(sheetId: UID, dimension: Dimension, elements: HeaderIndex[]): boolean;
3470
3470
  isRowHiddenByUser(sheetId: UID, index: HeaderIndex): boolean;
3471
3471
  isColHiddenByUser(sheetId: UID, index: HeaderIndex): boolean;
3472
3472
  getHiddenColsGroups(sheetId: UID): ConsecutiveIndexes[];
@@ -3603,7 +3603,7 @@ interface SheetState$1 {
3603
3603
  readonly cellPosition: Record<UID, CellPosition | undefined>;
3604
3604
  }
3605
3605
  declare class SheetPlugin extends CorePlugin<SheetState$1> implements SheetState$1 {
3606
- static getters: readonly ["getSheetName", "tryGetSheetName", "getSheet", "tryGetSheet", "getSheetIdByName", "getSheetIds", "getVisibleSheetIds", "isSheetVisible", "getEvaluationSheets", "doesHeaderExist", "getCell", "getCellPosition", "getColsZone", "getRowCells", "getRowsZone", "getNumberCols", "getNumberRows", "getNumberHeaders", "getGridLinesVisibility", "getNextSheetName", "isEmpty", "getSheetSize", "getSheetZone", "getPaneDivisions", "checkZonesExistInSheet", "getCommandZones", "getUnboundedZone"];
3606
+ static getters: readonly ["getSheetName", "tryGetSheetName", "getSheet", "tryGetSheet", "getSheetIdByName", "getSheetIds", "getVisibleSheetIds", "isSheetVisible", "getEvaluationSheets", "doesHeaderExist", "getCell", "getCellPosition", "getColsZone", "getRowCells", "getRowsZone", "getNumberCols", "getNumberRows", "getNumberHeaders", "getGridLinesVisibility", "getNextSheetName", "isEmpty", "getSheetSize", "getSheetZone", "getPaneDivisions", "checkZonesExistInSheet", "getCommandZones", "getUnboundedZone", "checkElementsIncludeAllNonFrozenHeaders"];
3607
3607
  readonly sheetIdsMapName: Record<string, UID | undefined>;
3608
3608
  readonly orderedSheetIds: UID[];
3609
3609
  readonly sheets: Record<UID, Sheet | undefined>;
@@ -3646,6 +3646,11 @@ declare class SheetPlugin extends CorePlugin<SheetState$1> implements SheetState
3646
3646
  getUnboundedZone(sheetId: UID, zone: Zone): UnboundedZone;
3647
3647
  getPaneDivisions(sheetId: UID): Readonly<PaneDivision>;
3648
3648
  private setPaneDivisions;
3649
+ /**
3650
+ * Checks if all non-frozen header indices are present in the provided elements of selected rows/columns.
3651
+ * This validation ensures that all rows or columns cannot be deleted when frozen panes exist.
3652
+ */
3653
+ checkElementsIncludeAllNonFrozenHeaders(sheetId: UID, dimension: Dimension, elements: HeaderIndex[]): boolean;
3649
3654
  /**
3650
3655
  * Check if a zone only contains empty cells
3651
3656
  */
@@ -5354,6 +5359,7 @@ declare class LineConfigPanel extends LineBarPieConfigPanel {
5354
5359
  onUpdateLabelsAsText(ev: any): void;
5355
5360
  onUpdateStacked(ev: any): void;
5356
5361
  onUpdateAggregated(ev: any): void;
5362
+ onUpdateCumulative(ev: any): void;
5357
5363
  }
5358
5364
 
5359
5365
  interface Props$y {