@odoo/o-spreadsheet 16.3.18 → 16.3.24

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.
@@ -298,15 +298,80 @@ const FONT_SIZES = [6, 7, 8, 9, 10, 11, 12, 14, 18, 24, 36];
298
298
  // -----------------------------------------------------------------------------
299
299
  // Date Type
300
300
  // -----------------------------------------------------------------------------
301
+ /**
302
+ * A DateTime object that can be used to manipulate spreadsheet dates.
303
+ * Conceptually, a spreadsheet date is simply a number with a date format,
304
+ * and it is timezone-agnostic.
305
+ * This DateTime object consistently uses UTC time to represent a naive date and time.
306
+ */
307
+ class DateTime {
308
+ jsDate;
309
+ constructor(year, month, day, hours = 0, minutes = 0, seconds = 0) {
310
+ this.jsDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds, 0));
311
+ }
312
+ static fromTimestamp(timestamp) {
313
+ const date = new Date(timestamp);
314
+ return new DateTime(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
315
+ }
316
+ static now() {
317
+ const now = new Date();
318
+ return new DateTime(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds());
319
+ }
320
+ toString() {
321
+ return this.jsDate.toString();
322
+ }
323
+ toLocaleDateString() {
324
+ return this.jsDate.toLocaleDateString();
325
+ }
326
+ getTime() {
327
+ return this.jsDate.getTime();
328
+ }
329
+ getFullYear() {
330
+ return this.jsDate.getUTCFullYear();
331
+ }
332
+ getMonth() {
333
+ return this.jsDate.getUTCMonth();
334
+ }
335
+ getDate() {
336
+ return this.jsDate.getUTCDate();
337
+ }
338
+ getDay() {
339
+ return this.jsDate.getUTCDay();
340
+ }
341
+ getHours() {
342
+ return this.jsDate.getUTCHours();
343
+ }
344
+ getMinutes() {
345
+ return this.jsDate.getUTCMinutes();
346
+ }
347
+ getSeconds() {
348
+ return this.jsDate.getUTCSeconds();
349
+ }
350
+ setFullYear(year) {
351
+ this.jsDate.setFullYear(year);
352
+ }
353
+ setDate(date) {
354
+ this.jsDate.setUTCDate(date);
355
+ }
356
+ setHours(hours) {
357
+ this.jsDate.setUTCHours(hours);
358
+ }
359
+ setMinutes(minutes) {
360
+ this.jsDate.setUTCMinutes(minutes);
361
+ }
362
+ setSeconds(seconds) {
363
+ this.jsDate.setUTCSeconds(seconds);
364
+ }
365
+ }
301
366
  // -----------------------------------------------------------------------------
302
367
  // Parsing
303
368
  // -----------------------------------------------------------------------------
304
- const INITIAL_1900_DAY = new Date(1899, 11, 30);
369
+ const INITIAL_1900_DAY = new DateTime(1899, 11, 30);
305
370
  const MS_PER_DAY = 24 * 60 * 60 * 1000;
306
371
  const CURRENT_MILLENIAL = 2000; // note: don't forget to update this in 2999
307
- const CURRENT_YEAR = new Date().getFullYear();
308
- const INITIAL_JS_DAY = new Date(0);
309
- const DATE_JS_1900_OFFSET = INITIAL_JS_DAY - INITIAL_1900_DAY;
372
+ const CURRENT_YEAR = DateTime.now().getFullYear();
373
+ const INITIAL_JS_DAY = DateTime.fromTimestamp(0);
374
+ const DATE_JS_1900_OFFSET = INITIAL_JS_DAY.getTime() - INITIAL_1900_DAY.getTime();
310
375
  const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
311
376
  const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
312
377
  const timeRegexp = /((\d+(:\d+)?(:\d+)?\s*(AM|PM))|(\d+:\d+(:\d+)?))$/;
@@ -355,7 +420,7 @@ function _parseDateTime(str) {
355
420
  return {
356
421
  value: date.value + time.value,
357
422
  format: date.format + " " + (time.format === "hhhh:mm:ss" ? "hh:mm:ss" : time.format),
358
- jsDate: new Date(date.jsDate.getFullYear() + time.jsDate.getFullYear() - 1899, date.jsDate.getMonth() + time.jsDate.getMonth() - 11, date.jsDate.getDate() + time.jsDate.getDate() - 30, date.jsDate.getHours() + time.jsDate.getHours(), date.jsDate.getMinutes() + time.jsDate.getMinutes(), date.jsDate.getSeconds() + time.jsDate.getSeconds()),
423
+ jsDate: new DateTime(date.jsDate.getFullYear() + time.jsDate.getFullYear() - 1899, date.jsDate.getMonth() + time.jsDate.getMonth() - 11, date.jsDate.getDate() + time.jsDate.getDate() - 30, date.jsDate.getHours() + time.jsDate.getHours(), date.jsDate.getMinutes() + time.jsDate.getMinutes(), date.jsDate.getSeconds() + time.jsDate.getSeconds()),
359
424
  };
360
425
  }
361
426
  return date || time;
@@ -372,13 +437,13 @@ function parseDate(str, dateFormat) {
372
437
  const day = Number(parts[dayIndex]);
373
438
  const leadingZero = (parts[monthIndex].length === 2 && month < 10) || (parts[dayIndex].length === 2 && day < 10);
374
439
  const year = parts[yearIndex] ? inferYear(parts[yearIndex]) : CURRENT_YEAR;
375
- const jsDate = new Date(year, month - 1, day);
440
+ const jsDate = new DateTime(year, month - 1, day);
376
441
  const sep = str.match(/\/|-|\s/)[0];
377
442
  if (jsDate.getMonth() !== month - 1 || jsDate.getDate() !== day) {
378
443
  // invalid date
379
444
  return null;
380
445
  }
381
- const delta = jsDate - INITIAL_1900_DAY;
446
+ const delta = jsDate.getTime() - INITIAL_1900_DAY.getTime();
382
447
  let format = leadingZero ? `mm${sep}dd` : `m${sep}d`;
383
448
  if (parts[yearIndex]) {
384
449
  format = isMDY ? format + sep + "yyyy" : "yyyy" + sep + format;
@@ -438,7 +503,7 @@ function parseTime(str) {
438
503
  if (hours >= 24) {
439
504
  format = "hhhh:mm:ss";
440
505
  }
441
- const jsDate = new Date(1899, 11, 30, hours, minutes, seconds);
506
+ const jsDate = new DateTime(1899, 11, 30, hours, minutes, seconds);
442
507
  return {
443
508
  value: hours / 24 + minutes / 1440 + seconds / 86400,
444
509
  format: format,
@@ -452,7 +517,7 @@ function parseTime(str) {
452
517
  // -----------------------------------------------------------------------------
453
518
  function numberToJsDate(value) {
454
519
  const truncValue = Math.trunc(value);
455
- let date = new Date(truncValue * MS_PER_DAY - DATE_JS_1900_OFFSET);
520
+ let date = DateTime.fromTimestamp(truncValue * MS_PER_DAY - DATE_JS_1900_OFFSET);
456
521
  let time = value - truncValue;
457
522
  time = time < 0 ? 1 + time : time;
458
523
  const hours = Math.round(time * 24);
@@ -469,7 +534,7 @@ function jsDateToRoundNumber(date) {
469
534
  }
470
535
  /** Return the number of days in the current month of the given date */
471
536
  function getDaysInMonth(date) {
472
- return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
537
+ return new DateTime(date.getFullYear(), date.getMonth() + 1, 0).getDate();
473
538
  }
474
539
  function isLastDayOfMonth(date) {
475
540
  return getDaysInMonth(date) === date.getDate();
@@ -487,7 +552,7 @@ function addMonthsToDate(date, months, keepEndOfMonth) {
487
552
  const yStart = date.getFullYear();
488
553
  const mStart = date.getMonth();
489
554
  const dStart = date.getDate();
490
- const jsDate = new Date(yStart, mStart + months);
555
+ const jsDate = new DateTime(yStart, mStart + months, 1);
491
556
  if (keepEndOfMonth && dStart === getDaysInMonth(date)) {
492
557
  jsDate.setDate(getDaysInMonth(jsDate));
493
558
  }
@@ -647,13 +712,6 @@ function areTwoDatesWithinOneYear(startDate, endDate) {
647
712
  }
648
713
 
649
714
  //------------------------------------------------------------------------------
650
- /**
651
- * Stringify an object, like JSON.stringify, except that the first level of keys
652
- * is ordered.
653
- */
654
- function stringify(obj) {
655
- return JSON.stringify(obj, Object.keys(obj).sort());
656
- }
657
715
  /**
658
716
  * Remove quotes from a quoted string
659
717
  * ```js
@@ -883,7 +941,7 @@ function isBoolean(str) {
883
941
  function isDateTime(str) {
884
942
  return parseDateTime(str) !== null;
885
943
  }
886
- const MARKDOWN_LINK_REGEX = /^\[([^\[]+)\]\((.+)\)$/;
944
+ const MARKDOWN_LINK_REGEX = /^\[(.+)\]\((.+)\)$/;
887
945
  //link must start with http or https
888
946
  //https://stackoverflow.com/a/3809435/4760614
889
947
  const WEB_LINK_REGEX = /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/;
@@ -952,7 +1010,7 @@ function isObjectEmptyRecursive(argument) {
952
1010
  */
953
1011
  function getItemId(item, itemsDic) {
954
1012
  for (let [key, value] of Object.entries(itemsDic)) {
955
- if (stringify(value) === stringify(item)) {
1013
+ if (deepEquals(value, item)) {
956
1014
  return parseInt(key, 10);
957
1015
  }
958
1016
  }
@@ -1952,7 +2010,7 @@ function formatJSTime(jsDate, format) {
1952
2010
  .map((p) => {
1953
2011
  switch (p) {
1954
2012
  case "hhhh":
1955
- const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY) / (60 * 60 * 1000));
2013
+ const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY.getTime()) / (60 * 60 * 1000));
1956
2014
  return helapsedHours.toString();
1957
2015
  case "hh":
1958
2016
  return hours.toString().padStart(2, "0");
@@ -2015,27 +2073,30 @@ function detectFormat(content) {
2015
2073
  }
2016
2074
  function createLargeNumberFormat(format, magnitude, postFix) {
2017
2075
  const internalFormat = parseFormat(format || "#,##0");
2018
- const largeNumberFormat = internalFormat
2019
- .map((formatPart) => {
2020
- if (formatPart.type === "NUMBER") {
2021
- return [
2022
- {
2023
- ...formatPart,
2024
- format: {
2025
- ...formatPart.format,
2026
- magnitude,
2027
- decimalPart: undefined,
2028
- },
2029
- },
2030
- {
2031
- type: "STRING",
2032
- format: postFix,
2033
- },
2034
- ];
2076
+ const largeNumberFormat = [];
2077
+ for (let i = 0; i < internalFormat.length; i++) {
2078
+ const formatPart = internalFormat[i];
2079
+ if (formatPart.type !== "NUMBER") {
2080
+ largeNumberFormat.push(formatPart);
2081
+ continue;
2035
2082
  }
2036
- return formatPart;
2037
- })
2038
- .flat();
2083
+ largeNumberFormat.push({
2084
+ ...formatPart,
2085
+ format: {
2086
+ ...formatPart.format,
2087
+ magnitude,
2088
+ decimalPart: undefined,
2089
+ },
2090
+ });
2091
+ largeNumberFormat.push({
2092
+ type: "STRING",
2093
+ format: postFix,
2094
+ });
2095
+ const nextFormatPart = internalFormat[i + 1];
2096
+ if (nextFormatPart?.type === "STRING" && ["k", "m", "b"].includes(nextFormatPart.format)) {
2097
+ i++;
2098
+ }
2099
+ }
2039
2100
  return convertInternalFormatToFormat(largeNumberFormat);
2040
2101
  }
2041
2102
  function changeDecimalPlaces(format, step) {
@@ -2199,8 +2260,10 @@ function convertInternalFormatToFormat(internalFormat) {
2199
2260
  const cellReference = new RegExp(/\$?([A-Z]{1,3})\$?([0-9]{1,7})/, "i");
2200
2261
  // Same as above, but matches the exact string (nothing before or after)
2201
2262
  const singleCellReference = new RegExp(/^\$?([A-Z]{1,3})\$?([0-9]{1,7})$/, "i");
2202
- /** Reference of a column header (eg. A, AB) */
2203
- const colHeader = new RegExp(/^([A-Z]{1,3})+$/, "i");
2263
+ /** Reference of a column header (eg. A, AB, $A) */
2264
+ const colHeader = new RegExp(/^\$?([A-Z]{1,3})+$/, "i");
2265
+ /** Reference of a row header (eg. 1, $1) */
2266
+ const rowHeader = new RegExp(/^\$?([0-9]{1,7})+$/, "i");
2204
2267
  /** Reference of a column (eg. A, $CA, Sheet1!B) */
2205
2268
  const colReference = new RegExp(/^\s*('.+'!|[^']+!)?\$?([A-Z]{1,3})$/, "i");
2206
2269
  /** Reference of a row (eg. 1, 59, Sheet1!9) */
@@ -2230,6 +2293,9 @@ function isRowReference(xc) {
2230
2293
  function isColHeader(str) {
2231
2294
  return colHeader.test(str);
2232
2295
  }
2296
+ function isRowHeader(str) {
2297
+ return rowHeader.test(str);
2298
+ }
2233
2299
  /**
2234
2300
  * Return true if the given xc is the reference of a single cell,
2235
2301
  * without any specified sheet (e.g. A1)
@@ -2296,18 +2362,10 @@ class RangeImpl {
2296
2362
  if (isFullCol) {
2297
2363
  parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2298
2364
  parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2299
- if (zone.left === zone.right) {
2300
- parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
2301
- parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
2302
- }
2303
2365
  }
2304
2366
  if (isFullRow) {
2305
2367
  parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
2306
2368
  parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
2307
- if (zone.top === zone.bottom) {
2308
- parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2309
- parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2310
- }
2311
2369
  }
2312
2370
  return parts;
2313
2371
  }
@@ -4380,69 +4438,70 @@ var CommandResult;
4380
4438
  CommandResult[CommandResult["InvalidFigureId"] = 28] = "InvalidFigureId";
4381
4439
  CommandResult[CommandResult["InputAlreadyFocused"] = 29] = "InputAlreadyFocused";
4382
4440
  CommandResult[CommandResult["MaximumRangesReached"] = 30] = "MaximumRangesReached";
4383
- CommandResult[CommandResult["InvalidChartDefinition"] = 31] = "InvalidChartDefinition";
4384
- CommandResult[CommandResult["InvalidDataSet"] = 32] = "InvalidDataSet";
4385
- CommandResult[CommandResult["InvalidLabelRange"] = 33] = "InvalidLabelRange";
4386
- CommandResult[CommandResult["InvalidScorecardKeyValue"] = 34] = "InvalidScorecardKeyValue";
4387
- CommandResult[CommandResult["InvalidScorecardBaseline"] = 35] = "InvalidScorecardBaseline";
4388
- CommandResult[CommandResult["InvalidGaugeDataRange"] = 36] = "InvalidGaugeDataRange";
4389
- CommandResult[CommandResult["EmptyGaugeRangeMin"] = 37] = "EmptyGaugeRangeMin";
4390
- CommandResult[CommandResult["GaugeRangeMinNaN"] = 38] = "GaugeRangeMinNaN";
4391
- CommandResult[CommandResult["EmptyGaugeRangeMax"] = 39] = "EmptyGaugeRangeMax";
4392
- CommandResult[CommandResult["GaugeRangeMaxNaN"] = 40] = "GaugeRangeMaxNaN";
4393
- CommandResult[CommandResult["GaugeRangeMinBiggerThanRangeMax"] = 41] = "GaugeRangeMinBiggerThanRangeMax";
4394
- CommandResult[CommandResult["GaugeLowerInflectionPointNaN"] = 42] = "GaugeLowerInflectionPointNaN";
4395
- CommandResult[CommandResult["GaugeUpperInflectionPointNaN"] = 43] = "GaugeUpperInflectionPointNaN";
4396
- CommandResult[CommandResult["GaugeLowerBiggerThanUpper"] = 44] = "GaugeLowerBiggerThanUpper";
4397
- CommandResult[CommandResult["InvalidAutofillSelection"] = 45] = "InvalidAutofillSelection";
4398
- CommandResult[CommandResult["WrongComposerSelection"] = 46] = "WrongComposerSelection";
4399
- CommandResult[CommandResult["MinBiggerThanMax"] = 47] = "MinBiggerThanMax";
4400
- CommandResult[CommandResult["LowerBiggerThanUpper"] = 48] = "LowerBiggerThanUpper";
4401
- CommandResult[CommandResult["MidBiggerThanMax"] = 49] = "MidBiggerThanMax";
4402
- CommandResult[CommandResult["MinBiggerThanMid"] = 50] = "MinBiggerThanMid";
4403
- CommandResult[CommandResult["FirstArgMissing"] = 51] = "FirstArgMissing";
4404
- CommandResult[CommandResult["SecondArgMissing"] = 52] = "SecondArgMissing";
4405
- CommandResult[CommandResult["MinNaN"] = 53] = "MinNaN";
4406
- CommandResult[CommandResult["MidNaN"] = 54] = "MidNaN";
4407
- CommandResult[CommandResult["MaxNaN"] = 55] = "MaxNaN";
4408
- CommandResult[CommandResult["ValueUpperInflectionNaN"] = 56] = "ValueUpperInflectionNaN";
4409
- CommandResult[CommandResult["ValueLowerInflectionNaN"] = 57] = "ValueLowerInflectionNaN";
4410
- CommandResult[CommandResult["MinInvalidFormula"] = 58] = "MinInvalidFormula";
4411
- CommandResult[CommandResult["MidInvalidFormula"] = 59] = "MidInvalidFormula";
4412
- CommandResult[CommandResult["MaxInvalidFormula"] = 60] = "MaxInvalidFormula";
4413
- CommandResult[CommandResult["ValueUpperInvalidFormula"] = 61] = "ValueUpperInvalidFormula";
4414
- CommandResult[CommandResult["ValueLowerInvalidFormula"] = 62] = "ValueLowerInvalidFormula";
4415
- CommandResult[CommandResult["InvalidSortZone"] = 63] = "InvalidSortZone";
4416
- CommandResult[CommandResult["WaitingSessionConfirmation"] = 64] = "WaitingSessionConfirmation";
4417
- CommandResult[CommandResult["MergeOverlap"] = 65] = "MergeOverlap";
4418
- CommandResult[CommandResult["TooManyHiddenElements"] = 66] = "TooManyHiddenElements";
4419
- CommandResult[CommandResult["Readonly"] = 67] = "Readonly";
4420
- CommandResult[CommandResult["InvalidViewportSize"] = 68] = "InvalidViewportSize";
4421
- CommandResult[CommandResult["InvalidScrollingDirection"] = 69] = "InvalidScrollingDirection";
4422
- CommandResult[CommandResult["FigureDoesNotExist"] = 70] = "FigureDoesNotExist";
4423
- CommandResult[CommandResult["InvalidConditionalFormatId"] = 71] = "InvalidConditionalFormatId";
4424
- CommandResult[CommandResult["InvalidCellPopover"] = 72] = "InvalidCellPopover";
4425
- CommandResult[CommandResult["EmptyTarget"] = 73] = "EmptyTarget";
4426
- CommandResult[CommandResult["InvalidFreezeQuantity"] = 74] = "InvalidFreezeQuantity";
4427
- CommandResult[CommandResult["FrozenPaneOverlap"] = 75] = "FrozenPaneOverlap";
4428
- CommandResult[CommandResult["ValuesNotChanged"] = 76] = "ValuesNotChanged";
4429
- CommandResult[CommandResult["InvalidFilterZone"] = 77] = "InvalidFilterZone";
4430
- CommandResult[CommandResult["FilterOverlap"] = 78] = "FilterOverlap";
4431
- CommandResult[CommandResult["FilterNotFound"] = 79] = "FilterNotFound";
4432
- CommandResult[CommandResult["MergeInFilter"] = 80] = "MergeInFilter";
4433
- CommandResult[CommandResult["NonContinuousTargets"] = 81] = "NonContinuousTargets";
4434
- CommandResult[CommandResult["DuplicatedFigureId"] = 82] = "DuplicatedFigureId";
4435
- CommandResult[CommandResult["InvalidSelectionStep"] = 83] = "InvalidSelectionStep";
4436
- CommandResult[CommandResult["DuplicatedChartId"] = 84] = "DuplicatedChartId";
4437
- CommandResult[CommandResult["ChartDoesNotExist"] = 85] = "ChartDoesNotExist";
4438
- CommandResult[CommandResult["InvalidHeaderIndex"] = 86] = "InvalidHeaderIndex";
4439
- CommandResult[CommandResult["InvalidQuantity"] = 87] = "InvalidQuantity";
4440
- CommandResult[CommandResult["MoreThanOneColumnSelected"] = 88] = "MoreThanOneColumnSelected";
4441
- CommandResult[CommandResult["EmptySplitSeparator"] = 89] = "EmptySplitSeparator";
4442
- CommandResult[CommandResult["SplitWillOverwriteContent"] = 90] = "SplitWillOverwriteContent";
4443
- CommandResult[CommandResult["NoSplitSeparatorInSelection"] = 91] = "NoSplitSeparatorInSelection";
4444
- CommandResult[CommandResult["NoActiveSheet"] = 92] = "NoActiveSheet";
4445
- CommandResult[CommandResult["NoChanges"] = 93] = "NoChanges";
4441
+ CommandResult[CommandResult["InvalidInputId"] = 31] = "InvalidInputId";
4442
+ CommandResult[CommandResult["InvalidChartDefinition"] = 32] = "InvalidChartDefinition";
4443
+ CommandResult[CommandResult["InvalidDataSet"] = 33] = "InvalidDataSet";
4444
+ CommandResult[CommandResult["InvalidLabelRange"] = 34] = "InvalidLabelRange";
4445
+ CommandResult[CommandResult["InvalidScorecardKeyValue"] = 35] = "InvalidScorecardKeyValue";
4446
+ CommandResult[CommandResult["InvalidScorecardBaseline"] = 36] = "InvalidScorecardBaseline";
4447
+ CommandResult[CommandResult["InvalidGaugeDataRange"] = 37] = "InvalidGaugeDataRange";
4448
+ CommandResult[CommandResult["EmptyGaugeRangeMin"] = 38] = "EmptyGaugeRangeMin";
4449
+ CommandResult[CommandResult["GaugeRangeMinNaN"] = 39] = "GaugeRangeMinNaN";
4450
+ CommandResult[CommandResult["EmptyGaugeRangeMax"] = 40] = "EmptyGaugeRangeMax";
4451
+ CommandResult[CommandResult["GaugeRangeMaxNaN"] = 41] = "GaugeRangeMaxNaN";
4452
+ CommandResult[CommandResult["GaugeRangeMinBiggerThanRangeMax"] = 42] = "GaugeRangeMinBiggerThanRangeMax";
4453
+ CommandResult[CommandResult["GaugeLowerInflectionPointNaN"] = 43] = "GaugeLowerInflectionPointNaN";
4454
+ CommandResult[CommandResult["GaugeUpperInflectionPointNaN"] = 44] = "GaugeUpperInflectionPointNaN";
4455
+ CommandResult[CommandResult["GaugeLowerBiggerThanUpper"] = 45] = "GaugeLowerBiggerThanUpper";
4456
+ CommandResult[CommandResult["InvalidAutofillSelection"] = 46] = "InvalidAutofillSelection";
4457
+ CommandResult[CommandResult["WrongComposerSelection"] = 47] = "WrongComposerSelection";
4458
+ CommandResult[CommandResult["MinBiggerThanMax"] = 48] = "MinBiggerThanMax";
4459
+ CommandResult[CommandResult["LowerBiggerThanUpper"] = 49] = "LowerBiggerThanUpper";
4460
+ CommandResult[CommandResult["MidBiggerThanMax"] = 50] = "MidBiggerThanMax";
4461
+ CommandResult[CommandResult["MinBiggerThanMid"] = 51] = "MinBiggerThanMid";
4462
+ CommandResult[CommandResult["FirstArgMissing"] = 52] = "FirstArgMissing";
4463
+ CommandResult[CommandResult["SecondArgMissing"] = 53] = "SecondArgMissing";
4464
+ CommandResult[CommandResult["MinNaN"] = 54] = "MinNaN";
4465
+ CommandResult[CommandResult["MidNaN"] = 55] = "MidNaN";
4466
+ CommandResult[CommandResult["MaxNaN"] = 56] = "MaxNaN";
4467
+ CommandResult[CommandResult["ValueUpperInflectionNaN"] = 57] = "ValueUpperInflectionNaN";
4468
+ CommandResult[CommandResult["ValueLowerInflectionNaN"] = 58] = "ValueLowerInflectionNaN";
4469
+ CommandResult[CommandResult["MinInvalidFormula"] = 59] = "MinInvalidFormula";
4470
+ CommandResult[CommandResult["MidInvalidFormula"] = 60] = "MidInvalidFormula";
4471
+ CommandResult[CommandResult["MaxInvalidFormula"] = 61] = "MaxInvalidFormula";
4472
+ CommandResult[CommandResult["ValueUpperInvalidFormula"] = 62] = "ValueUpperInvalidFormula";
4473
+ CommandResult[CommandResult["ValueLowerInvalidFormula"] = 63] = "ValueLowerInvalidFormula";
4474
+ CommandResult[CommandResult["InvalidSortZone"] = 64] = "InvalidSortZone";
4475
+ CommandResult[CommandResult["WaitingSessionConfirmation"] = 65] = "WaitingSessionConfirmation";
4476
+ CommandResult[CommandResult["MergeOverlap"] = 66] = "MergeOverlap";
4477
+ CommandResult[CommandResult["TooManyHiddenElements"] = 67] = "TooManyHiddenElements";
4478
+ CommandResult[CommandResult["Readonly"] = 68] = "Readonly";
4479
+ CommandResult[CommandResult["InvalidViewportSize"] = 69] = "InvalidViewportSize";
4480
+ CommandResult[CommandResult["InvalidScrollingDirection"] = 70] = "InvalidScrollingDirection";
4481
+ CommandResult[CommandResult["FigureDoesNotExist"] = 71] = "FigureDoesNotExist";
4482
+ CommandResult[CommandResult["InvalidConditionalFormatId"] = 72] = "InvalidConditionalFormatId";
4483
+ CommandResult[CommandResult["InvalidCellPopover"] = 73] = "InvalidCellPopover";
4484
+ CommandResult[CommandResult["EmptyTarget"] = 74] = "EmptyTarget";
4485
+ CommandResult[CommandResult["InvalidFreezeQuantity"] = 75] = "InvalidFreezeQuantity";
4486
+ CommandResult[CommandResult["FrozenPaneOverlap"] = 76] = "FrozenPaneOverlap";
4487
+ CommandResult[CommandResult["ValuesNotChanged"] = 77] = "ValuesNotChanged";
4488
+ CommandResult[CommandResult["InvalidFilterZone"] = 78] = "InvalidFilterZone";
4489
+ CommandResult[CommandResult["FilterOverlap"] = 79] = "FilterOverlap";
4490
+ CommandResult[CommandResult["FilterNotFound"] = 80] = "FilterNotFound";
4491
+ CommandResult[CommandResult["MergeInFilter"] = 81] = "MergeInFilter";
4492
+ CommandResult[CommandResult["NonContinuousTargets"] = 82] = "NonContinuousTargets";
4493
+ CommandResult[CommandResult["DuplicatedFigureId"] = 83] = "DuplicatedFigureId";
4494
+ CommandResult[CommandResult["InvalidSelectionStep"] = 84] = "InvalidSelectionStep";
4495
+ CommandResult[CommandResult["DuplicatedChartId"] = 85] = "DuplicatedChartId";
4496
+ CommandResult[CommandResult["ChartDoesNotExist"] = 86] = "ChartDoesNotExist";
4497
+ CommandResult[CommandResult["InvalidHeaderIndex"] = 87] = "InvalidHeaderIndex";
4498
+ CommandResult[CommandResult["InvalidQuantity"] = 88] = "InvalidQuantity";
4499
+ CommandResult[CommandResult["MoreThanOneColumnSelected"] = 89] = "MoreThanOneColumnSelected";
4500
+ CommandResult[CommandResult["EmptySplitSeparator"] = 90] = "EmptySplitSeparator";
4501
+ CommandResult[CommandResult["SplitWillOverwriteContent"] = 91] = "SplitWillOverwriteContent";
4502
+ CommandResult[CommandResult["NoSplitSeparatorInSelection"] = 92] = "NoSplitSeparatorInSelection";
4503
+ CommandResult[CommandResult["NoActiveSheet"] = 93] = "NoActiveSheet";
4504
+ CommandResult[CommandResult["NoChanges"] = 94] = "NoChanges";
4446
4505
  })(CommandResult || (CommandResult = {}));
4447
4506
 
4448
4507
  const borderStyles = ["thin", "medium", "thick", "dashed", "dotted"];
@@ -5167,6 +5226,7 @@ const FilterMenuPopoverBuilder = {
5167
5226
  },
5168
5227
  };
5169
5228
 
5229
+ const macRegex = /Mac/i;
5170
5230
  /**
5171
5231
  * Return true if the event was triggered from
5172
5232
  * a child element.
@@ -5212,6 +5272,17 @@ function setElementScrollTop(el, scroll) {
5212
5272
  }
5213
5273
  function getOpenedMenus() {
5214
5274
  return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
5275
+ }
5276
+ function isMacOS() {
5277
+ return Boolean(macRegex.test(navigator.userAgent));
5278
+ }
5279
+ /**
5280
+ * @param {KeyboardEvent | MouseEvent} ev
5281
+ * @returns Returns true if the event was triggered with the "ctrl" modifier pressed.
5282
+ * On Mac, this is the "meta" or "command" key.
5283
+ */
5284
+ function isCtrlKey(ev) {
5285
+ return isMacOS() ? ev.metaKey : ev.ctrlKey;
5215
5286
  }
5216
5287
 
5217
5288
  /**
@@ -6390,14 +6461,8 @@ function createDataSets(getters, dataSetsString, sheetId, dataSetsHaveTitle) {
6390
6461
  : undefined));
6391
6462
  }
6392
6463
  }
6393
- else if (zone.left === zone.right && zone.top === zone.bottom) {
6394
- // A single cell. If it's only the title, the dataset is not added.
6395
- if (!dataSetsHaveTitle) {
6396
- dataSets.push(createDataSet(getters, dataSetSheetId, zone, undefined));
6397
- }
6398
- }
6399
6464
  else {
6400
- /* 1 row or 1 column */
6465
+ /* 1 cell, 1 row or 1 column */
6401
6466
  dataSets.push(createDataSet(getters, dataSetSheetId, zone, dataSetsHaveTitle
6402
6467
  ? {
6403
6468
  top: zone.top,
@@ -6446,8 +6511,10 @@ function toExcelDataset(getters, ds) {
6446
6511
  }
6447
6512
  const dataRange = ds.dataRange.clone({ zone: dataZone });
6448
6513
  return {
6449
- label: ds.labelCell ? getters.getRangeString(ds.labelCell, "forceSheetReference") : undefined,
6450
- range: getters.getRangeString(dataRange, "forceSheetReference"),
6514
+ label: ds.labelCell
6515
+ ? getters.getRangeString(ds.labelCell, "forceSheetReference", true)
6516
+ : undefined,
6517
+ range: getters.getRangeString(dataRange, "forceSheetReference", true),
6451
6518
  };
6452
6519
  }
6453
6520
  function toExcelLabelRange(getters, labelRange, shouldRemoveFirstLabel) {
@@ -6460,7 +6527,7 @@ function toExcelLabelRange(getters, labelRange, shouldRemoveFirstLabel) {
6460
6527
  zone.top = zone.top + 1;
6461
6528
  }
6462
6529
  const range = labelRange.clone({ zone });
6463
- return getters.getRangeString(range, "forceSheetReference");
6530
+ return getters.getRangeString(range, "forceSheetReference", true);
6464
6531
  }
6465
6532
  /**
6466
6533
  * Transform a chart definition which supports dataSets (dataSets and LabelRange)
@@ -6526,11 +6593,11 @@ function checkDataset(definition) {
6526
6593
  if (definition.dataSets) {
6527
6594
  const invalidRanges = definition.dataSets.find((range) => !rangeReference.test(range)) !== undefined;
6528
6595
  if (invalidRanges) {
6529
- return 32 /* CommandResult.InvalidDataSet */;
6596
+ return 33 /* CommandResult.InvalidDataSet */;
6530
6597
  }
6531
6598
  const zones = definition.dataSets.map(toUnboundedZone);
6532
6599
  if (zones.some((zone) => zone.top !== zone.bottom && isFullRow(zone))) {
6533
- return 32 /* CommandResult.InvalidDataSet */;
6600
+ return 33 /* CommandResult.InvalidDataSet */;
6534
6601
  }
6535
6602
  }
6536
6603
  return 0 /* CommandResult.Success */;
@@ -6539,7 +6606,7 @@ function checkLabelRange(definition) {
6539
6606
  if (definition.labelRange) {
6540
6607
  const invalidLabels = !rangeReference.test(definition.labelRange || "");
6541
6608
  if (invalidLabels) {
6542
- return 33 /* CommandResult.InvalidLabelRange */;
6609
+ return 34 /* CommandResult.InvalidLabelRange */;
6543
6610
  }
6544
6611
  }
6545
6612
  return 0 /* CommandResult.Success */;
@@ -6626,22 +6693,22 @@ function getChartPositionAtCenterOfViewport(getters, chartSize) {
6626
6693
  const CfTerms = {
6627
6694
  Errors: {
6628
6695
  [25 /* CommandResult.InvalidRange */]: _lt("The range is invalid"),
6629
- [51 /* CommandResult.FirstArgMissing */]: _lt("The argument is missing. Please provide a value"),
6630
- [52 /* CommandResult.SecondArgMissing */]: _lt("The second argument is missing. Please provide a value"),
6631
- [53 /* CommandResult.MinNaN */]: _lt("The minpoint must be a number"),
6632
- [54 /* CommandResult.MidNaN */]: _lt("The midpoint must be a number"),
6633
- [55 /* CommandResult.MaxNaN */]: _lt("The maxpoint must be a number"),
6634
- [56 /* CommandResult.ValueUpperInflectionNaN */]: _lt("The first value must be a number"),
6635
- [57 /* CommandResult.ValueLowerInflectionNaN */]: _lt("The second value must be a number"),
6636
- [47 /* CommandResult.MinBiggerThanMax */]: _lt("Minimum must be smaller then Maximum"),
6637
- [50 /* CommandResult.MinBiggerThanMid */]: _lt("Minimum must be smaller then Midpoint"),
6638
- [49 /* CommandResult.MidBiggerThanMax */]: _lt("Midpoint must be smaller then Maximum"),
6639
- [48 /* CommandResult.LowerBiggerThanUpper */]: _lt("Lower inflection point must be smaller than upper inflection point"),
6640
- [58 /* CommandResult.MinInvalidFormula */]: _lt("Invalid Minpoint formula"),
6641
- [60 /* CommandResult.MaxInvalidFormula */]: _lt("Invalid Maxpoint formula"),
6642
- [59 /* CommandResult.MidInvalidFormula */]: _lt("Invalid Midpoint formula"),
6643
- [61 /* CommandResult.ValueUpperInvalidFormula */]: _lt("Invalid upper inflection point formula"),
6644
- [62 /* CommandResult.ValueLowerInvalidFormula */]: _lt("Invalid lower inflection point formula"),
6696
+ [52 /* CommandResult.FirstArgMissing */]: _lt("The argument is missing. Please provide a value"),
6697
+ [53 /* CommandResult.SecondArgMissing */]: _lt("The second argument is missing. Please provide a value"),
6698
+ [54 /* CommandResult.MinNaN */]: _lt("The minpoint must be a number"),
6699
+ [55 /* CommandResult.MidNaN */]: _lt("The midpoint must be a number"),
6700
+ [56 /* CommandResult.MaxNaN */]: _lt("The maxpoint must be a number"),
6701
+ [57 /* CommandResult.ValueUpperInflectionNaN */]: _lt("The first value must be a number"),
6702
+ [58 /* CommandResult.ValueLowerInflectionNaN */]: _lt("The second value must be a number"),
6703
+ [48 /* CommandResult.MinBiggerThanMax */]: _lt("Minimum must be smaller then Maximum"),
6704
+ [51 /* CommandResult.MinBiggerThanMid */]: _lt("Minimum must be smaller then Midpoint"),
6705
+ [50 /* CommandResult.MidBiggerThanMax */]: _lt("Midpoint must be smaller then Maximum"),
6706
+ [49 /* CommandResult.LowerBiggerThanUpper */]: _lt("Lower inflection point must be smaller than upper inflection point"),
6707
+ [59 /* CommandResult.MinInvalidFormula */]: _lt("Invalid Minpoint formula"),
6708
+ [61 /* CommandResult.MaxInvalidFormula */]: _lt("Invalid Maxpoint formula"),
6709
+ [60 /* CommandResult.MidInvalidFormula */]: _lt("Invalid Midpoint formula"),
6710
+ [62 /* CommandResult.ValueUpperInvalidFormula */]: _lt("Invalid upper inflection point formula"),
6711
+ [63 /* CommandResult.ValueLowerInvalidFormula */]: _lt("Invalid lower inflection point formula"),
6645
6712
  [24 /* CommandResult.EmptyRange */]: _lt("A range needs to be defined"),
6646
6713
  Unexpected: _lt("The rule is invalid for an unknown reason"),
6647
6714
  },
@@ -6669,20 +6736,20 @@ const ChartTerms = {
6669
6736
  Errors: {
6670
6737
  Unexpected: _lt("The chart definition is invalid for an unknown reason"),
6671
6738
  // BASIC CHART ERRORS (LINE | BAR | PIE)
6672
- [32 /* CommandResult.InvalidDataSet */]: _lt("The dataset is invalid"),
6673
- [33 /* CommandResult.InvalidLabelRange */]: _lt("Labels are invalid"),
6739
+ [33 /* CommandResult.InvalidDataSet */]: _lt("The dataset is invalid"),
6740
+ [34 /* CommandResult.InvalidLabelRange */]: _lt("Labels are invalid"),
6674
6741
  // SCORECARD CHART ERRORS
6675
- [34 /* CommandResult.InvalidScorecardKeyValue */]: _lt("The key value is invalid"),
6676
- [35 /* CommandResult.InvalidScorecardBaseline */]: _lt("The baseline value is invalid"),
6742
+ [35 /* CommandResult.InvalidScorecardKeyValue */]: _lt("The key value is invalid"),
6743
+ [36 /* CommandResult.InvalidScorecardBaseline */]: _lt("The baseline value is invalid"),
6677
6744
  // GAUGE CHART ERRORS
6678
- [36 /* CommandResult.InvalidGaugeDataRange */]: _lt("The data range is invalid"),
6679
- [37 /* CommandResult.EmptyGaugeRangeMin */]: _lt("A minimum range limit value is needed"),
6680
- [38 /* CommandResult.GaugeRangeMinNaN */]: _lt("The minimum range limit value must be a number"),
6681
- [39 /* CommandResult.EmptyGaugeRangeMax */]: _lt("A maximum range limit value is needed"),
6682
- [40 /* CommandResult.GaugeRangeMaxNaN */]: _lt("The maximum range limit value must be a number"),
6683
- [41 /* CommandResult.GaugeRangeMinBiggerThanRangeMax */]: _lt("Minimum range limit must be smaller than maximum range limit"),
6684
- [42 /* CommandResult.GaugeLowerInflectionPointNaN */]: _lt("The lower inflection point value must be a number"),
6685
- [43 /* CommandResult.GaugeUpperInflectionPointNaN */]: _lt("The upper inflection point value must be a number"),
6745
+ [37 /* CommandResult.InvalidGaugeDataRange */]: _lt("The data range is invalid"),
6746
+ [38 /* CommandResult.EmptyGaugeRangeMin */]: _lt("A minimum range limit value is needed"),
6747
+ [39 /* CommandResult.GaugeRangeMinNaN */]: _lt("The minimum range limit value must be a number"),
6748
+ [40 /* CommandResult.EmptyGaugeRangeMax */]: _lt("A maximum range limit value is needed"),
6749
+ [41 /* CommandResult.GaugeRangeMaxNaN */]: _lt("The maximum range limit value must be a number"),
6750
+ [42 /* CommandResult.GaugeRangeMinBiggerThanRangeMax */]: _lt("Minimum range limit must be smaller than maximum range limit"),
6751
+ [43 /* CommandResult.GaugeLowerInflectionPointNaN */]: _lt("The lower inflection point value must be a number"),
6752
+ [44 /* CommandResult.GaugeUpperInflectionPointNaN */]: _lt("The upper inflection point value must be a number"),
6686
6753
  },
6687
6754
  };
6688
6755
  const CustomCurrencyTerms = {
@@ -6692,9 +6759,9 @@ const MergeErrorMessage = _lt("Merged cells are preventing this operation. Unmer
6692
6759
  const SplitToColumnsTerms = {
6693
6760
  Errors: {
6694
6761
  Unexpected: _lt("Cannot split the selection for an unknown reason"),
6695
- [91 /* CommandResult.NoSplitSeparatorInSelection */]: _lt("There is no match for the selected separator in the selection"),
6696
- [88 /* CommandResult.MoreThanOneColumnSelected */]: _lt("Only a selection from a single column can be split"),
6697
- [90 /* CommandResult.SplitWillOverwriteContent */]: _lt("Splitting will overwrite existing content"),
6762
+ [92 /* CommandResult.NoSplitSeparatorInSelection */]: _lt("There is no match for the selected separator in the selection"),
6763
+ [89 /* CommandResult.MoreThanOneColumnSelected */]: _lt("Only a selection from a single column can be split"),
6764
+ [91 /* CommandResult.SplitWillOverwriteContent */]: _lt("Splitting will overwrite existing content"),
6698
6765
  },
6699
6766
  };
6700
6767
 
@@ -6997,7 +7064,7 @@ class BarChart extends AbstractChart {
6997
7064
  return undefined;
6998
7065
  const dataSets = this.dataSets
6999
7066
  .map((ds) => toExcelDataset(this.getters, ds))
7000
- .filter((ds) => ds.range !== ""); // && range !== INCORRECT_RANGE_STRING ? show incorrect #ref ?
7067
+ .filter((ds) => ds.range !== "" && ds.range !== INCORRECT_RANGE_STRING);
7001
7068
  const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
7002
7069
  return {
7003
7070
  ...this.getDefinition(),
@@ -7098,7 +7165,7 @@ function createBarChartRuntime(chart, getters) {
7098
7165
 
7099
7166
  function isDataRangeValid(definition) {
7100
7167
  return definition.dataRange && !rangeReference.test(definition.dataRange)
7101
- ? 36 /* CommandResult.InvalidGaugeDataRange */
7168
+ ? 37 /* CommandResult.InvalidGaugeDataRange */
7102
7169
  : 0 /* CommandResult.Success */;
7103
7170
  }
7104
7171
  function checkRangeLimits(check, batchValidations) {
@@ -7130,7 +7197,7 @@ function checkInflectionPointsValue(check, batchValidations) {
7130
7197
  function checkRangeMinBiggerThanRangeMax(definition) {
7131
7198
  if (definition.sectionRule) {
7132
7199
  if (Number(definition.sectionRule.rangeMin) >= Number(definition.sectionRule.rangeMax)) {
7133
- return 41 /* CommandResult.GaugeRangeMinBiggerThanRangeMax */;
7200
+ return 42 /* CommandResult.GaugeRangeMinBiggerThanRangeMax */;
7134
7201
  }
7135
7202
  }
7136
7203
  return 0 /* CommandResult.Success */;
@@ -7139,9 +7206,9 @@ function checkEmpty(value, valueName) {
7139
7206
  if (value === "") {
7140
7207
  switch (valueName) {
7141
7208
  case "rangeMin":
7142
- return 37 /* CommandResult.EmptyGaugeRangeMin */;
7209
+ return 38 /* CommandResult.EmptyGaugeRangeMin */;
7143
7210
  case "rangeMax":
7144
- return 39 /* CommandResult.EmptyGaugeRangeMax */;
7211
+ return 40 /* CommandResult.EmptyGaugeRangeMax */;
7145
7212
  }
7146
7213
  }
7147
7214
  return 0 /* CommandResult.Success */;
@@ -7150,13 +7217,13 @@ function checkNaN(value, valueName) {
7150
7217
  if (isNaN(value)) {
7151
7218
  switch (valueName) {
7152
7219
  case "rangeMin":
7153
- return 38 /* CommandResult.GaugeRangeMinNaN */;
7220
+ return 39 /* CommandResult.GaugeRangeMinNaN */;
7154
7221
  case "rangeMax":
7155
- return 40 /* CommandResult.GaugeRangeMaxNaN */;
7222
+ return 41 /* CommandResult.GaugeRangeMaxNaN */;
7156
7223
  case "lowerInflectionPointValue":
7157
- return 42 /* CommandResult.GaugeLowerInflectionPointNaN */;
7224
+ return 43 /* CommandResult.GaugeLowerInflectionPointNaN */;
7158
7225
  case "upperInflectionPointValue":
7159
- return 43 /* CommandResult.GaugeUpperInflectionPointNaN */;
7226
+ return 44 /* CommandResult.GaugeUpperInflectionPointNaN */;
7160
7227
  }
7161
7228
  }
7162
7229
  return 0 /* CommandResult.Success */;
@@ -7581,7 +7648,7 @@ class LineChart extends AbstractChart {
7581
7648
  return undefined;
7582
7649
  const dataSets = this.dataSets
7583
7650
  .map((ds) => toExcelDataset(this.getters, ds))
7584
- .filter((ds) => ds.range !== ""); // && range !== INCORRECT_RANGE_STRING ? show incorrect #ref ?
7651
+ .filter((ds) => ds.range !== "" && ds.range !== INCORRECT_RANGE_STRING);
7585
7652
  const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
7586
7653
  return {
7587
7654
  ...this.getDefinition(),
@@ -7866,7 +7933,7 @@ class PieChart extends AbstractChart {
7866
7933
  return undefined;
7867
7934
  const dataSets = this.dataSets
7868
7935
  .map((ds) => toExcelDataset(this.getters, ds))
7869
- .filter((ds) => ds.range !== ""); // && range !== INCORRECT_RANGE_STRING ? show incorrect #ref ?
7936
+ .filter((ds) => ds.range !== "" && ds.range !== INCORRECT_RANGE_STRING);
7870
7937
  const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
7871
7938
  return {
7872
7939
  ...this.getDefinition(),
@@ -7946,12 +8013,12 @@ function createPieChartRuntime(chart, getters) {
7946
8013
 
7947
8014
  function checkKeyValue(definition) {
7948
8015
  return definition.keyValue && !rangeReference.test(definition.keyValue)
7949
- ? 34 /* CommandResult.InvalidScorecardKeyValue */
8016
+ ? 35 /* CommandResult.InvalidScorecardKeyValue */
7950
8017
  : 0 /* CommandResult.Success */;
7951
8018
  }
7952
8019
  function checkBaseline(definition) {
7953
8020
  return definition.baseline && !rangeReference.test(definition.baseline)
7954
- ? 35 /* CommandResult.InvalidScorecardBaseline */
8021
+ ? 36 /* CommandResult.InvalidScorecardBaseline */
7955
8022
  : 0 /* CommandResult.Success */;
7956
8023
  }
7957
8024
  class ScorecardChart extends AbstractChart {
@@ -8457,7 +8524,7 @@ const AddMergeInteractiveContent = {
8457
8524
  };
8458
8525
  function interactiveAddMerge(env, sheetId, target) {
8459
8526
  const result = env.model.dispatch("ADD_MERGE", { sheetId, target });
8460
- if (result.isCancelledBecause(80 /* CommandResult.MergeInFilter */)) {
8527
+ if (result.isCancelledBecause(81 /* CommandResult.MergeInFilter */)) {
8461
8528
  env.raiseError(AddMergeInteractiveContent.MergeInFilter);
8462
8529
  }
8463
8530
  else if (result.isCancelledBecause(3 /* CommandResult.MergeIsDestructive */)) {
@@ -8707,7 +8774,7 @@ function interactiveSortSelection(env, sheetId, anchor, zone, sortDirection) {
8707
8774
  });
8708
8775
  }
8709
8776
  }
8710
- if (result.isCancelledBecause(63 /* CommandResult.InvalidSortZone */)) {
8777
+ if (result.isCancelledBecause(64 /* CommandResult.InvalidSortZone */)) {
8711
8778
  const { col, row } = anchor;
8712
8779
  env.model.selection.selectZone({ cell: { col, row }, zone });
8713
8780
  env.raiseError(_lt("Cannot sort. To sort, select only cells or only merges that have the same size."));
@@ -8730,13 +8797,13 @@ const AddFilterInteractiveContent = {
8730
8797
  };
8731
8798
  function interactiveAddFilter(env, sheetId, target) {
8732
8799
  const result = env.model.dispatch("CREATE_FILTER_TABLE", { target, sheetId });
8733
- if (result.isCancelledBecause(78 /* CommandResult.FilterOverlap */)) {
8800
+ if (result.isCancelledBecause(79 /* CommandResult.FilterOverlap */)) {
8734
8801
  env.raiseError(AddFilterInteractiveContent.filterOverlap);
8735
8802
  }
8736
- else if (result.isCancelledBecause(80 /* CommandResult.MergeInFilter */)) {
8803
+ else if (result.isCancelledBecause(81 /* CommandResult.MergeInFilter */)) {
8737
8804
  env.raiseError(AddFilterInteractiveContent.mergeInFilter);
8738
8805
  }
8739
- else if (result.isCancelledBecause(81 /* CommandResult.NonContinuousTargets */)) {
8806
+ else if (result.isCancelledBecause(82 /* CommandResult.NonContinuousTargets */)) {
8740
8807
  env.raiseError(AddFilterInteractiveContent.nonContinuousTargets);
8741
8808
  }
8742
8809
  }
@@ -8758,7 +8825,7 @@ function handlePasteResult(env, result) {
8758
8825
  else if (result.reasons.includes(22 /* CommandResult.WrongFigurePasteOption */)) {
8759
8826
  env.raiseError(PasteInteractiveContent.wrongFigurePasteOption);
8760
8827
  }
8761
- else if (result.reasons.includes(75 /* CommandResult.FrozenPaneOverlap */)) {
8828
+ else if (result.reasons.includes(76 /* CommandResult.FrozenPaneOverlap */)) {
8762
8829
  env.raiseError(PasteInteractiveContent.frozenPaneOverlap);
8763
8830
  }
8764
8831
  }
@@ -9598,6 +9665,9 @@ function arg(definition, description = "") {
9598
9665
  function makeArg(str, description) {
9599
9666
  let parts = str.match(ARG_REGEXP);
9600
9667
  let name = parts[1].trim();
9668
+ if (!name) {
9669
+ throw new Error(`Function argument definition is missing a name: '${str}'.`);
9670
+ }
9601
9671
  let types = [];
9602
9672
  let isOptional = false;
9603
9673
  let isRepeating = false;
@@ -12051,7 +12121,7 @@ const DATE = {
12051
12121
  if (_year < 1900) {
12052
12122
  _year += 1900;
12053
12123
  }
12054
- const jsDate = new Date(_year, _month - 1, _day);
12124
+ const jsDate = new DateTime(_year, _month - 1, _day);
12055
12125
  const result = jsDateToRoundNumber(jsDate);
12056
12126
  assert(() => result >= 0, _lt(`The function [[FUNCTION_NAME]] result must be greater than or equal 01/01/1900.`));
12057
12127
  return result;
@@ -12094,7 +12164,7 @@ const DATEDIF = {
12094
12164
  // See: https://support.microsoft.com/en-us/office/datedif-function-25dba1a4-2812-480b-84dd-8b32a451b35c
12095
12165
  let days = jsEndDate.getDate() - jsStartDate.getDate();
12096
12166
  if (days < 0) {
12097
- const monthBeforeEndMonth = new Date(jsEndDate.getFullYear(), jsEndDate.getMonth() - 1, 1);
12167
+ const monthBeforeEndMonth = new DateTime(jsEndDate.getFullYear(), jsEndDate.getMonth() - 1, 1);
12098
12168
  const daysInMonthBeforeEndMonth = getDaysInMonth(monthBeforeEndMonth);
12099
12169
  days = daysInMonthBeforeEndMonth - Math.abs(days);
12100
12170
  }
@@ -12103,7 +12173,7 @@ const DATEDIF = {
12103
12173
  if (areTwoDatesWithinOneYear(_startDate, _endDate)) {
12104
12174
  return getTimeDifferenceInWholeDays(jsStartDate, jsEndDate);
12105
12175
  }
12106
- const endDateWithinOneYear = new Date(jsStartDate.getFullYear(), jsEndDate.getMonth(), jsEndDate.getDate());
12176
+ const endDateWithinOneYear = new DateTime(jsStartDate.getFullYear(), jsEndDate.getMonth(), jsEndDate.getDate());
12107
12177
  let days = getTimeDifferenceInWholeDays(jsStartDate, endDateWithinOneYear);
12108
12178
  if (days < 0) {
12109
12179
  endDateWithinOneYear.setFullYear(jsStartDate.getFullYear() + 1);
@@ -12216,7 +12286,7 @@ const EOMONTH = {
12216
12286
  const _months = Math.trunc(toNumber(months));
12217
12287
  const yStart = _startDate.getFullYear();
12218
12288
  const mStart = _startDate.getMonth();
12219
- const jsDate = new Date(yStart, mStart + _months + 1, 0);
12289
+ const jsDate = new DateTime(yStart, mStart + _months + 1, 0);
12220
12290
  return jsDateToRoundNumber(jsDate);
12221
12291
  },
12222
12292
  isExported: true,
@@ -12253,17 +12323,17 @@ const ISOWEEKNUM = {
12253
12323
  // The first week of the year is the week that contains the first
12254
12324
  // Thursday of the year.
12255
12325
  let firstThursday = 1;
12256
- while (new Date(y, 0, firstThursday).getDay() !== 4) {
12326
+ while (new DateTime(y, 0, firstThursday).getDay() !== 4) {
12257
12327
  firstThursday += 1;
12258
12328
  }
12259
- const firstDayOfFirstWeek = new Date(y, 0, firstThursday - 3);
12329
+ const firstDayOfFirstWeek = new DateTime(y, 0, firstThursday - 3);
12260
12330
  // The last week of the year is the week that contains the last Thursday of
12261
12331
  // the year.
12262
12332
  let lastThursday = 31;
12263
- while (new Date(y, 11, lastThursday).getDay() !== 4) {
12333
+ while (new DateTime(y, 11, lastThursday).getDay() !== 4) {
12264
12334
  lastThursday -= 1;
12265
12335
  }
12266
- const lastDayOfLastWeek = new Date(y, 11, lastThursday + 3);
12336
+ const lastDayOfLastWeek = new DateTime(y, 11, lastThursday + 3);
12267
12337
  // B - If our date > lastDayOfLastWeek then it's in the weeks of the year after
12268
12338
  // If our date < firstDayOfFirstWeek then it's in the weeks of the year before
12269
12339
  let offsetYear;
@@ -12289,17 +12359,17 @@ const ISOWEEKNUM = {
12289
12359
  case 1:
12290
12360
  // firstDay is the 1st day of the 1st week of the year after
12291
12361
  // firstDay = lastDayOfLastWeek + 1 Day
12292
- firstDay = new Date(y, 11, lastThursday + 3 + 1);
12362
+ firstDay = new DateTime(y, 11, lastThursday + 3 + 1);
12293
12363
  break;
12294
12364
  case -1:
12295
12365
  // firstDay is the 1st day of the 1st week of the previous year.
12296
12366
  // The first week of the previous year is the week that contains the
12297
12367
  // first Thursday of the previous year.
12298
12368
  let firstThursdayPreviousYear = 1;
12299
- while (new Date(y - 1, 0, firstThursdayPreviousYear).getDay() !== 4) {
12369
+ while (new DateTime(y - 1, 0, firstThursdayPreviousYear).getDay() !== 4) {
12300
12370
  firstThursdayPreviousYear += 1;
12301
12371
  }
12302
- firstDay = new Date(y - 1, 0, firstThursdayPreviousYear - 3);
12372
+ firstDay = new DateTime(y - 1, 0, firstThursdayPreviousYear - 3);
12303
12373
  break;
12304
12374
  }
12305
12375
  const diff = (_date.getTime() - firstDay.getTime()) / MS_PER_DAY;
@@ -12434,8 +12504,8 @@ const NETWORKDAYS_INTL = {
12434
12504
  });
12435
12505
  }
12436
12506
  const invertDate = _startDate.getTime() > _endDate.getTime();
12437
- const stopDate = new Date((invertDate ? _startDate : _endDate).getTime());
12438
- let stepDate = new Date((invertDate ? _endDate : _startDate).getTime());
12507
+ const stopDate = DateTime.fromTimestamp((invertDate ? _startDate : _endDate).getTime());
12508
+ let stepDate = DateTime.fromTimestamp((invertDate ? _endDate : _startDate).getTime());
12439
12509
  const timeStopDate = stopDate.getTime();
12440
12510
  let timeStepDate = stepDate.getTime();
12441
12511
  let netWorkingDay = 0;
@@ -12459,8 +12529,7 @@ const NOW = {
12459
12529
  returns: ["DATE"],
12460
12530
  computeFormat: () => "m/d/yyyy hh:mm:ss",
12461
12531
  compute: function () {
12462
- let today = new Date();
12463
- today.setMilliseconds(0);
12532
+ let today = DateTime.now();
12464
12533
  const delta = today.getTime() - INITIAL_1900_DAY.getTime();
12465
12534
  const time = today.getHours() / 24 + today.getMinutes() / 1440 + today.getSeconds() / 86400;
12466
12535
  return Math.floor(delta / MS_PER_DAY) + time;
@@ -12530,8 +12599,8 @@ const TODAY = {
12530
12599
  returns: ["DATE"],
12531
12600
  computeFormat: () => "m/d/yyyy",
12532
12601
  compute: function () {
12533
- const today = new Date();
12534
- const jsDate = new Date(today.getFullYear(), today.getMonth(), today.getDate());
12602
+ const today = DateTime.now();
12603
+ const jsDate = new DateTime(today.getFullYear(), today.getMonth(), today.getDate());
12535
12604
  return jsDateToRoundNumber(jsDate);
12536
12605
  },
12537
12606
  isExported: true,
@@ -12586,10 +12655,10 @@ const WEEKNUM = {
12586
12655
  }
12587
12656
  const y = _date.getFullYear();
12588
12657
  let dayStart = 1;
12589
- let startDayOfFirstWeek = new Date(y, 0, dayStart);
12658
+ let startDayOfFirstWeek = new DateTime(y, 0, dayStart);
12590
12659
  while (startDayOfFirstWeek.getDay() !== startDayOfWeek) {
12591
12660
  dayStart += 1;
12592
- startDayOfFirstWeek = new Date(y, 0, dayStart);
12661
+ startDayOfFirstWeek = new DateTime(y, 0, dayStart);
12593
12662
  }
12594
12663
  const dif = (_date.getTime() - startDayOfFirstWeek.getTime()) / MS_PER_DAY;
12595
12664
  if (dif < 0) {
@@ -12643,7 +12712,7 @@ const WORKDAY_INTL = {
12643
12712
  timesHoliday.add(holiday.getTime());
12644
12713
  });
12645
12714
  }
12646
- let stepDate = new Date(_startDate.getTime());
12715
+ let stepDate = DateTime.fromTimestamp(_startDate.getTime());
12647
12716
  let timeStepDate = stepDate.getTime();
12648
12717
  const unitDay = Math.sign(_numDays);
12649
12718
  let stepDay = Math.abs(_numDays);
@@ -12705,7 +12774,7 @@ const MONTH_START = {
12705
12774
  const _startDate = toJsDate(date);
12706
12775
  const yStart = _startDate.getFullYear();
12707
12776
  const mStart = _startDate.getMonth();
12708
- const jsDate = new Date(yStart, mStart, 1);
12777
+ const jsDate = new DateTime(yStart, mStart, 1);
12709
12778
  return jsDateToRoundNumber(jsDate);
12710
12779
  },
12711
12780
  };
@@ -12743,7 +12812,7 @@ const QUARTER_START = {
12743
12812
  compute: function (date) {
12744
12813
  const quarter = QUARTER.compute(date);
12745
12814
  const year = YEAR.compute(date);
12746
- const jsDate = new Date(year, (quarter - 1) * 3, 1);
12815
+ const jsDate = new DateTime(year, (quarter - 1) * 3, 1);
12747
12816
  return jsDateToRoundNumber(jsDate);
12748
12817
  },
12749
12818
  };
@@ -12758,7 +12827,7 @@ const QUARTER_END = {
12758
12827
  compute: function (date) {
12759
12828
  const quarter = QUARTER.compute(date);
12760
12829
  const year = YEAR.compute(date);
12761
- const jsDate = new Date(year, quarter * 3, 0);
12830
+ const jsDate = new DateTime(year, quarter * 3, 0);
12762
12831
  return jsDateToRoundNumber(jsDate);
12763
12832
  },
12764
12833
  };
@@ -12772,7 +12841,7 @@ const YEAR_START = {
12772
12841
  computeFormat: () => "m/d/yyyy",
12773
12842
  compute: function (date) {
12774
12843
  const year = YEAR.compute(date);
12775
- const jsDate = new Date(year, 0, 1);
12844
+ const jsDate = new DateTime(year, 0, 1);
12776
12845
  return jsDateToRoundNumber(jsDate);
12777
12846
  },
12778
12847
  };
@@ -12786,7 +12855,7 @@ const YEAR_END = {
12786
12855
  computeFormat: () => "m/d/yyyy",
12787
12856
  compute: function (date) {
12788
12857
  const year = YEAR.compute(date);
12789
- const jsDate = new Date(year + 1, 0, 0);
12858
+ const jsDate = new DateTime(year + 1, 0, 0);
12790
12859
  return jsDateToRoundNumber(jsDate);
12791
12860
  },
12792
12861
  };
@@ -12834,8 +12903,8 @@ const DEFAULT_DELTA_ARG = 0;
12834
12903
  const DELTA = {
12835
12904
  description: _lt("Compare two numeric values, returning 1 if they're equal."),
12836
12905
  args: [
12837
- arg(" (number)", _lt("The first number to compare.")),
12838
- arg(` (number, default=${DEFAULT_DELTA_ARG})`, _lt("The second number to compare.")),
12906
+ arg("number1 (number)", _lt("The first number to compare.")),
12907
+ arg(`number2 (number, default=${DEFAULT_DELTA_ARG})`, _lt("The second number to compare.")),
12839
12908
  ],
12840
12909
  returns: ["NUMBER"],
12841
12910
  compute: function (number1, number2 = DEFAULT_DELTA_ARG) {
@@ -12921,7 +12990,7 @@ function assertDeprecationFactorStrictlyPositive(factor) {
12921
12990
  function assertSettlementLessThanOneYearBeforeMaturity(settlement, maturity) {
12922
12991
  const startDate = toJsDate(settlement);
12923
12992
  const endDate = toJsDate(maturity);
12924
- const startDatePlusOneYear = new Date(startDate);
12993
+ const startDatePlusOneYear = toJsDate(settlement);
12925
12994
  startDatePlusOneYear.setFullYear(startDate.getFullYear() + 1);
12926
12995
  assert(() => endDate.getTime() <= startDatePlusOneYear.getTime(), _lt("The settlement date (%s) must at most one year after the maturity date (%s).", settlement.toString(), maturity.toString()));
12927
12996
  }
@@ -13056,7 +13125,7 @@ const AMORLINC = {
13056
13125
  arg("salvage (number)", _lt("The value of the asset at the end of depreciation.")),
13057
13126
  arg("period (number)", _lt("The single period within life for which to calculate depreciation.")),
13058
13127
  arg("rate (number)", _lt("The deprecation rate.")),
13059
- arg(" (number, optional)", _lt("An indicator of what day count method to use.")),
13128
+ arg("day_count_convention (number, optional)", _lt("An indicator of what day count method to use.")),
13060
13129
  ],
13061
13130
  returns: ["NUMBER"],
13062
13131
  compute: function (cost, purchaseDate, firstPeriodEnd, salvage, period, rate, dayCountConvention = DEFAULT_DAY_COUNT_CONVENTION) {
@@ -16039,8 +16108,8 @@ const MID = {
16039
16108
  description: _lt("A segment of a string."),
16040
16109
  args: [
16041
16110
  arg("text (string)", _lt("The string to extract a segment from.")),
16042
- arg(" (number)", _lt("The index from the left of string from which to begin extracting. The first character in string has the index 1.")),
16043
- arg(" (number)", _lt("The length of the segment to extract.")),
16111
+ arg("starting_at (number)", _lt("The index from the left of string from which to begin extracting. The first character in string has the index 1.")),
16112
+ arg("extract_length (number)", _lt("The length of the segment to extract.")),
16044
16113
  ],
16045
16114
  returns: ["STRING"],
16046
16115
  compute: function (text, starting_at, extract_length) {
@@ -16914,7 +16983,7 @@ function interactiveFreezeColumnsRows(env, dimension, base) {
16914
16983
  const sheetId = env.model.getters.getActiveSheetId();
16915
16984
  const cmd = dimension === "COL" ? "FREEZE_COLUMNS" : "FREEZE_ROWS";
16916
16985
  const result = env.model.dispatch(cmd, { sheetId, quantity: base });
16917
- if (result.isCancelledBecause(65 /* CommandResult.MergeOverlap */)) {
16986
+ if (result.isCancelledBecause(66 /* CommandResult.MergeOverlap */)) {
16918
16987
  env.raiseError(MergeErrorMessage);
16919
16988
  }
16920
16989
  }
@@ -17709,10 +17778,10 @@ const arrowMap = {
17709
17778
  function updateSelectionWithArrowKeys(ev, selection) {
17710
17779
  const direction = arrowMap[ev.key];
17711
17780
  if (ev.shiftKey) {
17712
- selection.resizeAnchorZone(direction, ev.ctrlKey ? "end" : 1);
17781
+ selection.resizeAnchorZone(direction, isCtrlKey(ev) ? "end" : 1);
17713
17782
  }
17714
17783
  else {
17715
- selection.moveAnchorCell(direction, ev.ctrlKey ? "end" : 1);
17784
+ selection.moveAnchorCell(direction, isCtrlKey(ev) ? "end" : 1);
17716
17785
  }
17717
17786
  }
17718
17787
 
@@ -17937,10 +18006,10 @@ class LineBarPieConfigPanel extends Component {
17937
18006
  return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
17938
18007
  }
17939
18008
  get isDatasetInvalid() {
17940
- return !!this.state.datasetDispatchResult?.isCancelledBecause(32 /* CommandResult.InvalidDataSet */);
18009
+ return !!this.state.datasetDispatchResult?.isCancelledBecause(33 /* CommandResult.InvalidDataSet */);
17941
18010
  }
17942
18011
  get isLabelInvalid() {
17943
- return !!this.state.labelsDispatchResult?.isCancelledBecause(33 /* CommandResult.InvalidLabelRange */);
18012
+ return !!this.state.labelsDispatchResult?.isCancelledBecause(34 /* CommandResult.InvalidLabelRange */);
17944
18013
  }
17945
18014
  onUpdateDataSetsHaveTitle(ev) {
17946
18015
  this.props.updateChart(this.props.figureId, {
@@ -18382,7 +18451,7 @@ class GaugeChartConfigPanel extends Component {
18382
18451
  return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
18383
18452
  }
18384
18453
  get isDataRangeInvalid() {
18385
- return !!this.state.dataRangeDispatchResult?.isCancelledBecause(36 /* CommandResult.InvalidGaugeDataRange */);
18454
+ return !!this.state.dataRangeDispatchResult?.isCancelledBecause(37 /* CommandResult.InvalidGaugeDataRange */);
18386
18455
  }
18387
18456
  onDataRangeChanged(ranges) {
18388
18457
  this.dataRange = ranges[0];
@@ -18456,25 +18525,25 @@ class GaugeChartDesignPanel extends Component {
18456
18525
  });
18457
18526
  }
18458
18527
  isRangeMinInvalid() {
18459
- return !!(this.state.sectionRuleDispatchResult?.isCancelledBecause(37 /* CommandResult.EmptyGaugeRangeMin */) ||
18460
- this.state.sectionRuleDispatchResult?.isCancelledBecause(38 /* CommandResult.GaugeRangeMinNaN */) ||
18461
- this.state.sectionRuleDispatchResult?.isCancelledBecause(41 /* CommandResult.GaugeRangeMinBiggerThanRangeMax */));
18528
+ return !!(this.state.sectionRuleDispatchResult?.isCancelledBecause(38 /* CommandResult.EmptyGaugeRangeMin */) ||
18529
+ this.state.sectionRuleDispatchResult?.isCancelledBecause(39 /* CommandResult.GaugeRangeMinNaN */) ||
18530
+ this.state.sectionRuleDispatchResult?.isCancelledBecause(42 /* CommandResult.GaugeRangeMinBiggerThanRangeMax */));
18462
18531
  }
18463
18532
  isRangeMaxInvalid() {
18464
- return !!(this.state.sectionRuleDispatchResult?.isCancelledBecause(39 /* CommandResult.EmptyGaugeRangeMax */) ||
18465
- this.state.sectionRuleDispatchResult?.isCancelledBecause(40 /* CommandResult.GaugeRangeMaxNaN */) ||
18466
- this.state.sectionRuleDispatchResult?.isCancelledBecause(41 /* CommandResult.GaugeRangeMinBiggerThanRangeMax */));
18533
+ return !!(this.state.sectionRuleDispatchResult?.isCancelledBecause(40 /* CommandResult.EmptyGaugeRangeMax */) ||
18534
+ this.state.sectionRuleDispatchResult?.isCancelledBecause(41 /* CommandResult.GaugeRangeMaxNaN */) ||
18535
+ this.state.sectionRuleDispatchResult?.isCancelledBecause(42 /* CommandResult.GaugeRangeMinBiggerThanRangeMax */));
18467
18536
  }
18468
18537
  // ---------------------------------------------------------------------------
18469
18538
  // COLOR_SECTION_TEMPLATE
18470
18539
  // ---------------------------------------------------------------------------
18471
18540
  get isLowerInflectionPointInvalid() {
18472
- return !!(this.state.sectionRuleDispatchResult?.isCancelledBecause(42 /* CommandResult.GaugeLowerInflectionPointNaN */) ||
18473
- this.state.sectionRuleDispatchResult?.isCancelledBecause(44 /* CommandResult.GaugeLowerBiggerThanUpper */));
18541
+ return !!(this.state.sectionRuleDispatchResult?.isCancelledBecause(43 /* CommandResult.GaugeLowerInflectionPointNaN */) ||
18542
+ this.state.sectionRuleDispatchResult?.isCancelledBecause(45 /* CommandResult.GaugeLowerBiggerThanUpper */));
18474
18543
  }
18475
18544
  get isUpperInflectionPointInvalid() {
18476
- return !!(this.state.sectionRuleDispatchResult?.isCancelledBecause(43 /* CommandResult.GaugeUpperInflectionPointNaN */) ||
18477
- this.state.sectionRuleDispatchResult?.isCancelledBecause(44 /* CommandResult.GaugeLowerBiggerThanUpper */));
18545
+ return !!(this.state.sectionRuleDispatchResult?.isCancelledBecause(44 /* CommandResult.GaugeUpperInflectionPointNaN */) ||
18546
+ this.state.sectionRuleDispatchResult?.isCancelledBecause(45 /* CommandResult.GaugeLowerBiggerThanUpper */));
18478
18547
  }
18479
18548
  updateInflectionPointValue(attr, ev) {
18480
18549
  const sectionRule = deepCopy(this.props.definition.sectionRule);
@@ -18582,10 +18651,10 @@ class ScorecardChartConfigPanel extends Component {
18582
18651
  return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
18583
18652
  }
18584
18653
  get isKeyValueInvalid() {
18585
- return !!this.state.keyValueDispatchResult?.isCancelledBecause(34 /* CommandResult.InvalidScorecardKeyValue */);
18654
+ return !!this.state.keyValueDispatchResult?.isCancelledBecause(35 /* CommandResult.InvalidScorecardKeyValue */);
18586
18655
  }
18587
18656
  get isBaselineInvalid() {
18588
- return !!this.state.keyValueDispatchResult?.isCancelledBecause(35 /* CommandResult.InvalidScorecardBaseline */);
18657
+ return !!this.state.keyValueDispatchResult?.isCancelledBecause(36 /* CommandResult.InvalidScorecardBaseline */);
18589
18658
  }
18590
18659
  onKeyValueRangeChanged(ranges) {
18591
18660
  this.keyValue = ranges[0];
@@ -19445,10 +19514,10 @@ class ConditionalFormattingPanel extends Component {
19445
19514
  * Cell Is Rule
19446
19515
  ****************************************************************************/
19447
19516
  get isValue1Invalid() {
19448
- return !!this.state.errors?.includes(51 /* CommandResult.FirstArgMissing */);
19517
+ return !!this.state.errors?.includes(52 /* CommandResult.FirstArgMissing */);
19449
19518
  }
19450
19519
  get isValue2Invalid() {
19451
- return !!this.state.errors?.includes(52 /* CommandResult.SecondArgMissing */);
19520
+ return !!this.state.errors?.includes(53 /* CommandResult.SecondArgMissing */);
19452
19521
  }
19453
19522
  toggleStyle(tool) {
19454
19523
  const style = this.state.rules.cellIs.style;
@@ -19465,17 +19534,17 @@ class ConditionalFormattingPanel extends Component {
19465
19534
  isValueInvalid(threshold) {
19466
19535
  switch (threshold) {
19467
19536
  case "minimum":
19468
- return (this.state.errors.includes(58 /* CommandResult.MinInvalidFormula */) ||
19469
- this.state.errors.includes(50 /* CommandResult.MinBiggerThanMid */) ||
19470
- this.state.errors.includes(47 /* CommandResult.MinBiggerThanMax */) ||
19471
- this.state.errors.includes(53 /* CommandResult.MinNaN */));
19537
+ return (this.state.errors.includes(59 /* CommandResult.MinInvalidFormula */) ||
19538
+ this.state.errors.includes(51 /* CommandResult.MinBiggerThanMid */) ||
19539
+ this.state.errors.includes(48 /* CommandResult.MinBiggerThanMax */) ||
19540
+ this.state.errors.includes(54 /* CommandResult.MinNaN */));
19472
19541
  case "midpoint":
19473
- return (this.state.errors.includes(59 /* CommandResult.MidInvalidFormula */) ||
19474
- this.state.errors.includes(54 /* CommandResult.MidNaN */) ||
19475
- this.state.errors.includes(49 /* CommandResult.MidBiggerThanMax */));
19542
+ return (this.state.errors.includes(60 /* CommandResult.MidInvalidFormula */) ||
19543
+ this.state.errors.includes(55 /* CommandResult.MidNaN */) ||
19544
+ this.state.errors.includes(50 /* CommandResult.MidBiggerThanMax */));
19476
19545
  case "maximum":
19477
- return (this.state.errors.includes(60 /* CommandResult.MaxInvalidFormula */) ||
19478
- this.state.errors.includes(55 /* CommandResult.MaxNaN */));
19546
+ return (this.state.errors.includes(61 /* CommandResult.MaxInvalidFormula */) ||
19547
+ this.state.errors.includes(56 /* CommandResult.MaxNaN */));
19479
19548
  default:
19480
19549
  return false;
19481
19550
  }
@@ -19523,13 +19592,13 @@ class ConditionalFormattingPanel extends Component {
19523
19592
  isInflectionPointInvalid(inflectionPoint) {
19524
19593
  switch (inflectionPoint) {
19525
19594
  case "lowerInflectionPoint":
19526
- return (this.state.errors.includes(57 /* CommandResult.ValueLowerInflectionNaN */) ||
19527
- this.state.errors.includes(62 /* CommandResult.ValueLowerInvalidFormula */) ||
19528
- this.state.errors.includes(48 /* CommandResult.LowerBiggerThanUpper */));
19595
+ return (this.state.errors.includes(58 /* CommandResult.ValueLowerInflectionNaN */) ||
19596
+ this.state.errors.includes(63 /* CommandResult.ValueLowerInvalidFormula */) ||
19597
+ this.state.errors.includes(49 /* CommandResult.LowerBiggerThanUpper */));
19529
19598
  case "upperInflectionPoint":
19530
- return (this.state.errors.includes(56 /* CommandResult.ValueUpperInflectionNaN */) ||
19531
- this.state.errors.includes(61 /* CommandResult.ValueUpperInvalidFormula */) ||
19532
- this.state.errors.includes(48 /* CommandResult.LowerBiggerThanUpper */));
19599
+ return (this.state.errors.includes(57 /* CommandResult.ValueUpperInflectionNaN */) ||
19600
+ this.state.errors.includes(62 /* CommandResult.ValueUpperInvalidFormula */) ||
19601
+ this.state.errors.includes(49 /* CommandResult.LowerBiggerThanUpper */));
19533
19602
  default:
19534
19603
  return true;
19535
19604
  }
@@ -19840,7 +19909,7 @@ const SplitToColumnsInteractiveContent = {
19840
19909
  };
19841
19910
  function interactiveSplitToColumns(env, separator, addNewColumns) {
19842
19911
  let result = env.model.dispatch("SPLIT_TEXT_INTO_COLUMNS", { separator, addNewColumns });
19843
- if (result.isCancelledBecause(90 /* CommandResult.SplitWillOverwriteContent */)) {
19912
+ if (result.isCancelledBecause(91 /* CommandResult.SplitWillOverwriteContent */)) {
19844
19913
  env.askConfirmation(SplitToColumnsInteractiveContent.SplitIsDestructive, () => {
19845
19914
  result = env.model.dispatch("SPLIT_TEXT_INTO_COLUMNS", {
19846
19915
  separator,
@@ -19903,8 +19972,8 @@ class SplitIntoColumnsPanel extends Component {
19903
19972
  const errors = new Set();
19904
19973
  for (const reason of cancelledReasons) {
19905
19974
  switch (reason) {
19906
- case 90 /* CommandResult.SplitWillOverwriteContent */:
19907
- case 89 /* CommandResult.EmptySplitSeparator */:
19975
+ case 91 /* CommandResult.SplitWillOverwriteContent */:
19976
+ case 90 /* CommandResult.EmptySplitSeparator */:
19908
19977
  break;
19909
19978
  default:
19910
19979
  errors.add(SplitToColumnsTerms.Errors[reason] || SplitToColumnsTerms.Errors.Unexpected);
@@ -19919,8 +19988,8 @@ class SplitIntoColumnsPanel extends Component {
19919
19988
  addNewColumns: this.state.addNewColumns,
19920
19989
  force: false,
19921
19990
  }).reasons;
19922
- if (cancelledReasons.includes(90 /* CommandResult.SplitWillOverwriteContent */)) {
19923
- warnings.push(SplitToColumnsTerms.Errors[90 /* CommandResult.SplitWillOverwriteContent */]);
19991
+ if (cancelledReasons.includes(91 /* CommandResult.SplitWillOverwriteContent */)) {
19992
+ warnings.push(SplitToColumnsTerms.Errors[91 /* CommandResult.SplitWillOverwriteContent */]);
19924
19993
  }
19925
19994
  return warnings;
19926
19995
  }
@@ -22409,7 +22478,10 @@ class GridOverlay extends Component {
22409
22478
  return;
22410
22479
  }
22411
22480
  const [col, row] = this.getCartesianCoordinates(ev);
22412
- this.props.onCellClicked(col, row, { shiftKey: ev.shiftKey, ctrlKey: ev.ctrlKey });
22481
+ this.props.onCellClicked(col, row, {
22482
+ expandZone: ev.shiftKey,
22483
+ addZone: isCtrlKey(ev),
22484
+ });
22413
22485
  }
22414
22486
  onDoubleClick(ev) {
22415
22487
  const [col, row] = this.getCartesianCoordinates(ev);
@@ -22482,6 +22554,7 @@ class AbstractResizer extends Component {
22482
22554
  draggerShadowThickness: 0,
22483
22555
  delta: 0,
22484
22556
  base: 0,
22557
+ position: "before",
22485
22558
  });
22486
22559
  _computeHandleDisplay(ev) {
22487
22560
  const position = this._getEvOffset(ev);
@@ -22606,11 +22679,13 @@ class AbstractResizer extends Component {
22606
22679
  this.state.draggerLinePosition = dimensions.start;
22607
22680
  this.state.draggerShadowPosition = dimensions.start;
22608
22681
  this.state.base = elementIndex;
22682
+ this.state.position = "before";
22609
22683
  }
22610
22684
  else if (this._getSelectedZoneEnd() < elementIndex) {
22611
22685
  this.state.draggerLinePosition = dimensions.end;
22612
22686
  this.state.draggerShadowPosition = dimensions.end - this.state.draggerShadowThickness;
22613
- this.state.base = elementIndex + 1;
22687
+ this.state.base = elementIndex;
22688
+ this.state.position = "after";
22614
22689
  }
22615
22690
  else {
22616
22691
  this.state.draggerLinePosition = startDimensions.start;
@@ -22634,7 +22709,7 @@ class AbstractResizer extends Component {
22634
22709
  this._increaseSelection(index);
22635
22710
  }
22636
22711
  else {
22637
- this._selectElement(index, ev.ctrlKey);
22712
+ this._selectElement(index, isCtrlKey(ev));
22638
22713
  }
22639
22714
  this.lastSelectedElementIndex = index;
22640
22715
  const mouseMoveSelect = (col, row) => {
@@ -22647,7 +22722,7 @@ class AbstractResizer extends Component {
22647
22722
  const mouseUpSelect = () => {
22648
22723
  this.state.isSelecting = false;
22649
22724
  this.lastSelectedElementIndex = null;
22650
- this.env.model.dispatch(ev.ctrlKey ? "PREPARE_SELECTION_INPUT_EXPANSION" : "STOP_SELECTION_INPUT");
22725
+ this.env.model.dispatch(isCtrlKey(ev) ? "PREPARE_SELECTION_INPUT_EXPANSION" : "STOP_SELECTION_INPUT");
22651
22726
  this._computeGrabDisplay(ev);
22652
22727
  };
22653
22728
  dragAndDropBeyondTheViewport(this.env, mouseMoveSelect, mouseUpSelect);
@@ -22793,13 +22868,14 @@ class ColResizer extends AbstractResizer {
22793
22868
  dimension: "COL",
22794
22869
  base: this.state.base,
22795
22870
  elements,
22871
+ position: this.state.position,
22796
22872
  });
22797
22873
  if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
22798
22874
  this.env.raiseError(MergeErrorMessage);
22799
22875
  }
22800
22876
  }
22801
- _selectElement(index, ctrlKey) {
22802
- this.env.model.selection.selectColumn(index, ctrlKey ? "newAnchor" : "overrideSelection");
22877
+ _selectElement(index, addDistinctHeader) {
22878
+ this.env.model.selection.selectColumn(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
22803
22879
  }
22804
22880
  _increaseSelection(index) {
22805
22881
  this.env.model.selection.selectColumn(index, "updateAnchor");
@@ -22966,13 +23042,14 @@ class RowResizer extends AbstractResizer {
22966
23042
  dimension: "ROW",
22967
23043
  base: this.state.base,
22968
23044
  elements,
23045
+ position: this.state.position,
22969
23046
  });
22970
23047
  if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
22971
23048
  this.env.raiseError(MergeErrorMessage);
22972
23049
  }
22973
23050
  }
22974
- _selectElement(index, ctrlKey) {
22975
- this.env.model.selection.selectRow(index, ctrlKey ? "newAnchor" : "overrideSelection");
23051
+ _selectElement(index, addDistinctHeader) {
23052
+ this.env.model.selection.selectRow(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
22976
23053
  }
22977
23054
  _increaseSelection(index) {
22978
23055
  this.env.model.selection.selectRow(index, "updateAnchor");
@@ -23073,8 +23150,8 @@ function useWheelHandler(handler) {
23073
23150
  return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
23074
23151
  }
23075
23152
  const onMouseWheel = (ev) => {
23076
- const deltaX = normalize(ev.shiftKey ? ev.deltaY : ev.deltaX, ev.deltaMode);
23077
- const deltaY = normalize(ev.shiftKey ? ev.deltaX : ev.deltaY, ev.deltaMode);
23153
+ const deltaX = normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode);
23154
+ const deltaY = normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode);
23078
23155
  handler(deltaX, deltaY);
23079
23156
  };
23080
23157
  return onMouseWheel;
@@ -23776,8 +23853,8 @@ class Grid extends Component {
23776
23853
  // ---------------------------------------------------------------------------
23777
23854
  // Zone selection with mouse
23778
23855
  // ---------------------------------------------------------------------------
23779
- onCellClicked(col, row, { ctrlKey, shiftKey }) {
23780
- if (ctrlKey) {
23856
+ onCellClicked(col, row, { addZone, expandZone }) {
23857
+ if (addZone) {
23781
23858
  this.env.model.dispatch("PREPARE_SELECTION_INPUT_EXPANSION");
23782
23859
  }
23783
23860
  if (this.env.model.getters.hasOpenedPopover()) {
@@ -23786,10 +23863,10 @@ class Grid extends Component {
23786
23863
  if (this.env.model.getters.getEditionMode() === "editing") {
23787
23864
  this.env.model.dispatch("STOP_EDITION");
23788
23865
  }
23789
- if (shiftKey) {
23866
+ if (expandZone) {
23790
23867
  this.env.model.selection.setAnchorCorner(col, row);
23791
23868
  }
23792
- else if (ctrlKey) {
23869
+ else if (addZone) {
23793
23870
  this.env.model.selection.addCellToSelection(col, row);
23794
23871
  }
23795
23872
  else {
@@ -23851,9 +23928,7 @@ class Grid extends Component {
23851
23928
  return;
23852
23929
  }
23853
23930
  let keyDownString = "";
23854
- if (ev.ctrlKey)
23855
- keyDownString += "CTRL+";
23856
- if (ev.metaKey)
23931
+ if (isCtrlKey(ev))
23857
23932
  keyDownString += "CTRL+";
23858
23933
  if (ev.altKey)
23859
23934
  keyDownString += "ALT+";
@@ -25761,7 +25836,7 @@ const machine = {
25761
25836
  SPACE: goTo(State.RightRef),
25762
25837
  NUMBER: goTo(State.Found),
25763
25838
  REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
25764
- SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
25839
+ SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
25765
25840
  },
25766
25841
  [State.RightColumnRef]: {
25767
25842
  SPACE: goTo(State.RightColumnRef),
@@ -25772,6 +25847,7 @@ const machine = {
25772
25847
  SPACE: goTo(State.RightRowRef),
25773
25848
  NUMBER: goTo(State.Found),
25774
25849
  REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
25850
+ SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
25775
25851
  },
25776
25852
  [State.Found]: {},
25777
25853
  };
@@ -29439,7 +29515,7 @@ class BordersPlugin extends CorePlugin {
29439
29515
  const currentBorder = this.getCellBorder(cmd);
29440
29516
  const areAllNewBordersUndefined = !cmd.border?.bottom && !cmd.border?.left && !cmd.border?.right && !cmd.border?.top;
29441
29517
  if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
29442
- return 93 /* CommandResult.NoChanges */;
29518
+ return 94 /* CommandResult.NoChanges */;
29443
29519
  }
29444
29520
  return 0 /* CommandResult.Success */;
29445
29521
  }
@@ -29479,7 +29555,7 @@ class BordersPlugin extends CorePlugin {
29479
29555
  */
29480
29556
  function getBorderId(border) {
29481
29557
  for (let [key, value] of Object.entries(borders)) {
29482
- if (stringify(value) === stringify(border)) {
29558
+ if (deepEquals(value, border)) {
29483
29559
  return parseInt(key, 10);
29484
29560
  }
29485
29561
  }
@@ -29684,6 +29760,10 @@ class CellPlugin extends CorePlugin {
29684
29760
  format: cell.format ? getItemId(cell.format, formats) : undefined,
29685
29761
  content: cell.content || undefined,
29686
29762
  };
29763
+ // if there is a formula but no dependencies (maybe because the cell is in error), no need to recompute the formula text
29764
+ if (cell.isFormula && cell.dependencies.length) {
29765
+ cells[xc].content = this.buildFormulaContent(_sheet.id, cell, cell.dependencies, true);
29766
+ }
29687
29767
  }
29688
29768
  _sheet.cells = cells;
29689
29769
  }
@@ -29718,13 +29798,13 @@ class CellPlugin extends CorePlugin {
29718
29798
  /*
29719
29799
  * Reconstructs the original formula string based on a normalized form and its dependencies
29720
29800
  */
29721
- buildFormulaContent(sheetId, cell, dependencies) {
29801
+ buildFormulaContent(sheetId, cell, dependencies, useFixedZone = false) {
29722
29802
  const ranges = dependencies || cell.dependencies;
29723
29803
  let rangeIndex = 0;
29724
29804
  return concat(cell.compiledFormula.tokens.map((token) => {
29725
29805
  if (token.type === "REFERENCE") {
29726
29806
  const range = ranges[rangeIndex++];
29727
- return this.getters.getRangeString(range, sheetId);
29807
+ return this.getters.getRangeString(range, sheetId, useFixedZone);
29728
29808
  }
29729
29809
  return token.value;
29730
29810
  }));
@@ -29961,9 +30041,9 @@ class CellPlugin extends CorePlugin {
29961
30041
  checkUselessClearCell(cmd) {
29962
30042
  const cell = this.getters.getCell(cmd);
29963
30043
  if (!cell)
29964
- return 93 /* CommandResult.NoChanges */;
30044
+ return 94 /* CommandResult.NoChanges */;
29965
30045
  if (!cell.content && !cell.style && !cell.format) {
29966
- return 93 /* CommandResult.NoChanges */;
30046
+ return 94 /* CommandResult.NoChanges */;
29967
30047
  }
29968
30048
  return 0 /* CommandResult.Success */;
29969
30049
  }
@@ -30163,13 +30243,13 @@ class ChartPlugin extends CorePlugin {
30163
30243
  }
30164
30244
  checkChartDuplicate(cmd) {
30165
30245
  return this.getters.getFigureSheetId(cmd.id)
30166
- ? 84 /* CommandResult.DuplicatedChartId */
30246
+ ? 85 /* CommandResult.DuplicatedChartId */
30167
30247
  : 0 /* CommandResult.Success */;
30168
30248
  }
30169
30249
  checkChartExists(cmd) {
30170
30250
  return this.getters.getFigureSheetId(cmd.id)
30171
30251
  ? 0 /* CommandResult.Success */
30172
- : 85 /* CommandResult.ChartDoesNotExist */;
30252
+ : 86 /* CommandResult.ChartDoesNotExist */;
30173
30253
  }
30174
30254
  }
30175
30255
 
@@ -30274,7 +30354,13 @@ class ConditionalFormatPlugin extends CorePlugin {
30274
30354
  }
30275
30355
  }
30276
30356
  exportForExcel(data) {
30277
- this.export(data);
30357
+ if (data.sheets) {
30358
+ for (let sheet of data.sheets) {
30359
+ if (this.cfRules[sheet.id]) {
30360
+ sheet.conditionalFormats = this.cfRules[sheet.id].map((rule) => this.mapToConditionalFormat(sheet.id, rule, { useFixedReference: true }));
30361
+ }
30362
+ }
30363
+ }
30278
30364
  }
30279
30365
  // ---------------------------------------------------------------------------
30280
30366
  // Getters
@@ -30323,11 +30409,11 @@ class ConditionalFormatPlugin extends CorePlugin {
30323
30409
  // ---------------------------------------------------------------------------
30324
30410
  // Private
30325
30411
  // ---------------------------------------------------------------------------
30326
- mapToConditionalFormat(sheetId, cf) {
30412
+ mapToConditionalFormat(sheetId, cf, options = { useFixedReference: false }) {
30327
30413
  return {
30328
30414
  ...cf,
30329
30415
  ranges: cf.ranges.map((range) => {
30330
- return this.getters.getRangeString(range, sheetId);
30416
+ return this.getters.getRangeString(range, sheetId, options.useFixedReference);
30331
30417
  }),
30332
30418
  };
30333
30419
  }
@@ -30360,10 +30446,10 @@ class ConditionalFormatPlugin extends CorePlugin {
30360
30446
  return 27 /* CommandResult.InvalidSheetId */;
30361
30447
  const ruleIndex = this.cfRules[sheetId].findIndex((cf) => cf.id === cfId);
30362
30448
  if (ruleIndex === -1)
30363
- return 71 /* CommandResult.InvalidConditionalFormatId */;
30449
+ return 72 /* CommandResult.InvalidConditionalFormatId */;
30364
30450
  const cfIndex2 = direction === "up" ? ruleIndex - 1 : ruleIndex + 1;
30365
30451
  if (cfIndex2 < 0 || cfIndex2 >= this.cfRules[sheetId].length) {
30366
- return 71 /* CommandResult.InvalidConditionalFormatId */;
30452
+ return 72 /* CommandResult.InvalidConditionalFormatId */;
30367
30453
  }
30368
30454
  return 0 /* CommandResult.Success */;
30369
30455
  }
@@ -30404,10 +30490,10 @@ class ConditionalFormatPlugin extends CorePlugin {
30404
30490
  const errors = [];
30405
30491
  const isEmpty = (value) => value === undefined || value === "";
30406
30492
  if (expectedNumber >= 1 && isEmpty(rule.values[0])) {
30407
- errors.push(51 /* CommandResult.FirstArgMissing */);
30493
+ errors.push(52 /* CommandResult.FirstArgMissing */);
30408
30494
  }
30409
30495
  if (expectedNumber >= 2 && isEmpty(rule.values[1])) {
30410
- errors.push(52 /* CommandResult.SecondArgMissing */);
30496
+ errors.push(53 /* CommandResult.SecondArgMissing */);
30411
30497
  }
30412
30498
  return errors.length ? errors : 0 /* CommandResult.Success */;
30413
30499
  }
@@ -30419,15 +30505,15 @@ class ConditionalFormatPlugin extends CorePlugin {
30419
30505
  (threshold.value === "" || isNaN(threshold.value))) {
30420
30506
  switch (thresholdName) {
30421
30507
  case "min":
30422
- return 53 /* CommandResult.MinNaN */;
30508
+ return 54 /* CommandResult.MinNaN */;
30423
30509
  case "max":
30424
- return 55 /* CommandResult.MaxNaN */;
30510
+ return 56 /* CommandResult.MaxNaN */;
30425
30511
  case "mid":
30426
- return 54 /* CommandResult.MidNaN */;
30512
+ return 55 /* CommandResult.MidNaN */;
30427
30513
  case "upperInflectionPoint":
30428
- return 56 /* CommandResult.ValueUpperInflectionNaN */;
30514
+ return 57 /* CommandResult.ValueUpperInflectionNaN */;
30429
30515
  case "lowerInflectionPoint":
30430
- return 57 /* CommandResult.ValueLowerInflectionNaN */;
30516
+ return 58 /* CommandResult.ValueLowerInflectionNaN */;
30431
30517
  }
30432
30518
  }
30433
30519
  return 0 /* CommandResult.Success */;
@@ -30441,15 +30527,15 @@ class ConditionalFormatPlugin extends CorePlugin {
30441
30527
  catch (error) {
30442
30528
  switch (thresholdName) {
30443
30529
  case "min":
30444
- return 58 /* CommandResult.MinInvalidFormula */;
30530
+ return 59 /* CommandResult.MinInvalidFormula */;
30445
30531
  case "max":
30446
- return 60 /* CommandResult.MaxInvalidFormula */;
30532
+ return 61 /* CommandResult.MaxInvalidFormula */;
30447
30533
  case "mid":
30448
- return 59 /* CommandResult.MidInvalidFormula */;
30534
+ return 60 /* CommandResult.MidInvalidFormula */;
30449
30535
  case "upperInflectionPoint":
30450
- return 61 /* CommandResult.ValueUpperInvalidFormula */;
30536
+ return 62 /* CommandResult.ValueUpperInvalidFormula */;
30451
30537
  case "lowerInflectionPoint":
30452
- return 62 /* CommandResult.ValueLowerInvalidFormula */;
30538
+ return 63 /* CommandResult.ValueLowerInvalidFormula */;
30453
30539
  }
30454
30540
  }
30455
30541
  return 0 /* CommandResult.Success */;
@@ -30466,7 +30552,7 @@ class ConditionalFormatPlugin extends CorePlugin {
30466
30552
  if (["number", "percentage", "percentile"].includes(rule.lowerInflectionPoint.type) &&
30467
30553
  rule.lowerInflectionPoint.type === rule.upperInflectionPoint.type &&
30468
30554
  Number(minValue) > Number(maxValue)) {
30469
- return 48 /* CommandResult.LowerBiggerThanUpper */;
30555
+ return 49 /* CommandResult.LowerBiggerThanUpper */;
30470
30556
  }
30471
30557
  return 0 /* CommandResult.Success */;
30472
30558
  }
@@ -30476,7 +30562,7 @@ class ConditionalFormatPlugin extends CorePlugin {
30476
30562
  if (["number", "percentage", "percentile"].includes(rule.minimum.type) &&
30477
30563
  rule.minimum.type === rule.maximum.type &&
30478
30564
  stringToNumber(minValue) >= stringToNumber(maxValue)) {
30479
- return 47 /* CommandResult.MinBiggerThanMax */;
30565
+ return 48 /* CommandResult.MinBiggerThanMax */;
30480
30566
  }
30481
30567
  return 0 /* CommandResult.Success */;
30482
30568
  }
@@ -30487,7 +30573,7 @@ class ConditionalFormatPlugin extends CorePlugin {
30487
30573
  ["number", "percentage", "percentile"].includes(rule.midpoint.type) &&
30488
30574
  rule.midpoint.type === rule.maximum.type &&
30489
30575
  stringToNumber(midValue) >= stringToNumber(maxValue)) {
30490
- return 49 /* CommandResult.MidBiggerThanMax */;
30576
+ return 50 /* CommandResult.MidBiggerThanMax */;
30491
30577
  }
30492
30578
  return 0 /* CommandResult.Success */;
30493
30579
  }
@@ -30498,7 +30584,7 @@ class ConditionalFormatPlugin extends CorePlugin {
30498
30584
  ["number", "percentage", "percentile"].includes(rule.midpoint.type) &&
30499
30585
  rule.minimum.type === rule.midpoint.type &&
30500
30586
  stringToNumber(minValue) >= stringToNumber(midValue)) {
30501
- return 50 /* CommandResult.MinBiggerThanMid */;
30587
+ return 51 /* CommandResult.MinBiggerThanMid */;
30502
30588
  }
30503
30589
  return 0 /* CommandResult.Success */;
30504
30590
  }
@@ -30628,13 +30714,13 @@ class FigurePlugin extends CorePlugin {
30628
30714
  }
30629
30715
  checkFigureExists(sheetId, figureId) {
30630
30716
  if (this.figures[sheetId]?.[figureId] === undefined) {
30631
- return 70 /* CommandResult.FigureDoesNotExist */;
30717
+ return 71 /* CommandResult.FigureDoesNotExist */;
30632
30718
  }
30633
30719
  return 0 /* CommandResult.Success */;
30634
30720
  }
30635
30721
  checkFigureDuplicate(figureId) {
30636
30722
  if (Object.values(this.figures).find((sheet) => sheet?.[figureId])) {
30637
- return 82 /* CommandResult.DuplicatedFigureId */;
30723
+ return 83 /* CommandResult.DuplicatedFigureId */;
30638
30724
  }
30639
30725
  return 0 /* CommandResult.Success */;
30640
30726
  }
@@ -30744,12 +30830,12 @@ class FiltersPlugin extends CorePlugin {
30744
30830
  switch (cmd.type) {
30745
30831
  case "CREATE_FILTER_TABLE":
30746
30832
  if (!areZonesContinuous(...cmd.target)) {
30747
- return 81 /* CommandResult.NonContinuousTargets */;
30833
+ return 82 /* CommandResult.NonContinuousTargets */;
30748
30834
  }
30749
30835
  const zone = union(...cmd.target);
30750
30836
  const checkFilterOverlap = () => {
30751
30837
  if (this.getFilterTables(cmd.sheetId).some((filter) => overlap(filter.zone, zone))) {
30752
- return 78 /* CommandResult.FilterOverlap */;
30838
+ return 79 /* CommandResult.FilterOverlap */;
30753
30839
  }
30754
30840
  return 0 /* CommandResult.Success */;
30755
30841
  };
@@ -30757,7 +30843,7 @@ class FiltersPlugin extends CorePlugin {
30757
30843
  const mergesInTarget = this.getters.getMergesInZone(cmd.sheetId, zone);
30758
30844
  for (let merge of mergesInTarget) {
30759
30845
  if (overlap(zone, merge)) {
30760
- return 80 /* CommandResult.MergeInFilter */;
30846
+ return 81 /* CommandResult.MergeInFilter */;
30761
30847
  }
30762
30848
  }
30763
30849
  return 0 /* CommandResult.Success */;
@@ -30767,7 +30853,7 @@ class FiltersPlugin extends CorePlugin {
30767
30853
  for (let merge of cmd.target) {
30768
30854
  for (let filterTable of this.getFilterTables(cmd.sheetId)) {
30769
30855
  if (overlap(filterTable.zone, merge)) {
30770
- return 80 /* CommandResult.MergeInFilter */;
30856
+ return 81 /* CommandResult.MergeInFilter */;
30771
30857
  }
30772
30858
  }
30773
30859
  }
@@ -31252,10 +31338,10 @@ class HeaderVisibilityPlugin extends CorePlugin {
31252
31338
  : this.getters.getNumberRows(cmd.sheetId);
31253
31339
  const hiddenElements = new Set((hiddenGroup || []).flat().concat(cmd.elements));
31254
31340
  if (hiddenElements.size >= elements) {
31255
- return 66 /* CommandResult.TooManyHiddenElements */;
31341
+ return 67 /* CommandResult.TooManyHiddenElements */;
31256
31342
  }
31257
31343
  else if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
31258
- return 86 /* CommandResult.InvalidHeaderIndex */;
31344
+ return 87 /* CommandResult.InvalidHeaderIndex */;
31259
31345
  }
31260
31346
  else {
31261
31347
  return 0 /* CommandResult.Success */;
@@ -31798,7 +31884,7 @@ class MergePlugin extends CorePlugin {
31798
31884
  for (const zone of target) {
31799
31885
  for (const zone2 of target) {
31800
31886
  if (zone !== zone2 && overlap(zone, zone2)) {
31801
- return 65 /* CommandResult.MergeOverlap */;
31887
+ return 66 /* CommandResult.MergeOverlap */;
31802
31888
  }
31803
31889
  }
31804
31890
  }
@@ -31812,7 +31898,7 @@ class MergePlugin extends CorePlugin {
31812
31898
  for (const zone of target) {
31813
31899
  if ((zone.left < xSplit && zone.right >= xSplit) ||
31814
31900
  (zone.top < ySplit && zone.bottom >= ySplit)) {
31815
- return 75 /* CommandResult.FrozenPaneOverlap */;
31901
+ return 76 /* CommandResult.FrozenPaneOverlap */;
31816
31902
  }
31817
31903
  }
31818
31904
  return 0 /* CommandResult.Success */;
@@ -32270,8 +32356,9 @@ class RangeAdapter {
32270
32356
  *
32271
32357
  * @param range the range (received from getRangeFromXC or getRangeFromZone)
32272
32358
  * @param forSheetId the id of the sheet where the range string is supposed to be used.
32359
+ * @param [useFixedZone=false] if true, the range will be returned with fixed row and column
32273
32360
  */
32274
- getRangeString(range, forSheetId) {
32361
+ getRangeString(range, forSheetId, useFixedZone = false) {
32275
32362
  if (!range) {
32276
32363
  return INCORRECT_RANGE_STRING;
32277
32364
  }
@@ -32298,7 +32385,7 @@ class RangeAdapter {
32298
32385
  if (prefixSheet && !sheetName) {
32299
32386
  return INCORRECT_RANGE_STRING;
32300
32387
  }
32301
- let rangeString = this.getRangePartString(rangeImpl, 0);
32388
+ let rangeString = this.getRangePartString(rangeImpl, 0, useFixedZone);
32302
32389
  if (rangeImpl.parts && rangeImpl.parts.length === 2) {
32303
32390
  // this if converts A2:A2 into A2 except if any part of the original range had fixed row or column (with $)
32304
32391
  if (rangeImpl.zone.top !== rangeImpl.zone.bottom ||
@@ -32308,7 +32395,7 @@ class RangeAdapter {
32308
32395
  rangeImpl.parts[1].rowFixed ||
32309
32396
  rangeImpl.parts[1].colFixed) {
32310
32397
  rangeString += ":";
32311
- rangeString += this.getRangePartString(rangeImpl, 1);
32398
+ rangeString += this.getRangePartString(rangeImpl, 1, useFixedZone);
32312
32399
  }
32313
32400
  }
32314
32401
  return `${prefixSheet ? sheetName + "!" : ""}${rangeString}`;
@@ -32338,13 +32425,13 @@ class RangeAdapter {
32338
32425
  /**
32339
32426
  * Get a Xc string that represent a part of a range
32340
32427
  */
32341
- getRangePartString(range, part) {
32342
- const colFixed = range.parts && range.parts[part].colFixed ? "$" : "";
32428
+ getRangePartString(range, part, useFixedZone = false) {
32429
+ const colFixed = range.parts && range.parts[part]?.colFixed ? "$" : "";
32343
32430
  const col = part === 0 ? numberToLetters(range.zone.left) : numberToLetters(range.zone.right);
32344
- const rowFixed = range.parts && range.parts[part].rowFixed ? "$" : "";
32431
+ const rowFixed = range.parts && range.parts[part]?.rowFixed ? "$" : "";
32345
32432
  const row = part === 0 ? String(range.zone.top + 1) : String(range.zone.bottom + 1);
32346
32433
  let str = "";
32347
- if (range.isFullCol) {
32434
+ if (range.isFullCol && !useFixedZone) {
32348
32435
  if (part === 0 && range.unboundedZone.hasHeader) {
32349
32436
  str = colFixed + col + rowFixed + row;
32350
32437
  }
@@ -32352,7 +32439,7 @@ class RangeAdapter {
32352
32439
  str = colFixed + col;
32353
32440
  }
32354
32441
  }
32355
- else if (range.isFullRow) {
32442
+ else if (range.isFullRow && !useFixedZone) {
32356
32443
  if (part === 0 && range.unboundedZone.hasHeader) {
32357
32444
  str = colFixed + col + rowFixed + row;
32358
32445
  }
@@ -32447,11 +32534,11 @@ class SheetPlugin extends CorePlugin {
32447
32534
  const elements = cmd.dimension === "COL"
32448
32535
  ? this.getNumberCols(cmd.sheetId)
32449
32536
  : this.getNumberRows(cmd.sheetId);
32450
- if (cmd.base < 0 || cmd.base > elements) {
32451
- return 86 /* CommandResult.InvalidHeaderIndex */;
32537
+ if (cmd.base < 0 || cmd.base >= elements) {
32538
+ return 87 /* CommandResult.InvalidHeaderIndex */;
32452
32539
  }
32453
32540
  else if (cmd.quantity <= 0) {
32454
- return 87 /* CommandResult.InvalidQuantity */;
32541
+ return 88 /* CommandResult.InvalidQuantity */;
32455
32542
  }
32456
32543
  return 0 /* CommandResult.Success */;
32457
32544
  case "REMOVE_COLUMNS_ROWS": {
@@ -32459,7 +32546,7 @@ class SheetPlugin extends CorePlugin {
32459
32546
  ? this.getNumberCols(cmd.sheetId)
32460
32547
  : this.getNumberRows(cmd.sheetId);
32461
32548
  if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
32462
- return 86 /* CommandResult.InvalidHeaderIndex */;
32549
+ return 87 /* CommandResult.InvalidHeaderIndex */;
32463
32550
  }
32464
32551
  else if (this.checkElementsIncludeAllNonFrozenHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
32465
32552
  return 8 /* CommandResult.NotEnoughElements */;
@@ -32925,18 +33012,18 @@ class SheetPlugin extends CorePlugin {
32925
33012
  checkRowFreezeQuantity(cmd) {
32926
33013
  return cmd.quantity >= 1 && cmd.quantity < this.getNumberRows(cmd.sheetId)
32927
33014
  ? 0 /* CommandResult.Success */
32928
- : 74 /* CommandResult.InvalidFreezeQuantity */;
33015
+ : 75 /* CommandResult.InvalidFreezeQuantity */;
32929
33016
  }
32930
33017
  checkColFreezeQuantity(cmd) {
32931
33018
  return cmd.quantity >= 1 && cmd.quantity < this.getNumberCols(cmd.sheetId)
32932
33019
  ? 0 /* CommandResult.Success */
32933
- : 74 /* CommandResult.InvalidFreezeQuantity */;
33020
+ : 75 /* CommandResult.InvalidFreezeQuantity */;
32934
33021
  }
32935
33022
  checkRowFreezeOverlapMerge(cmd) {
32936
33023
  const merges = this.getters.getMerges(cmd.sheetId);
32937
33024
  for (let merge of merges) {
32938
33025
  if (merge.top < cmd.quantity && cmd.quantity <= merge.bottom) {
32939
- return 65 /* CommandResult.MergeOverlap */;
33026
+ return 66 /* CommandResult.MergeOverlap */;
32940
33027
  }
32941
33028
  }
32942
33029
  return 0 /* CommandResult.Success */;
@@ -32945,7 +33032,7 @@ class SheetPlugin extends CorePlugin {
32945
33032
  const merges = this.getters.getMerges(cmd.sheetId);
32946
33033
  for (let merge of merges) {
32947
33034
  if (merge.left < cmd.quantity && cmd.quantity <= merge.right) {
32948
- return 65 /* CommandResult.MergeOverlap */;
33035
+ return 66 /* CommandResult.MergeOverlap */;
32949
33036
  }
32950
33037
  }
32951
33038
  return 0 /* CommandResult.Success */;
@@ -33480,13 +33567,18 @@ class EvaluationPlugin extends UIPlugin {
33480
33567
  // Getters
33481
33568
  // ---------------------------------------------------------------------------
33482
33569
  evaluateFormula(formulaString, sheetId = this.getters.getActiveSheetId()) {
33483
- const compiledFormula = compile(formulaString);
33484
- const params = this.getCompilationParameters((cell) => this.getEvaluatedCell(this.getters.getCellPosition(cell.id)));
33485
- const ranges = [];
33486
- for (let xc of compiledFormula.dependencies) {
33487
- ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
33570
+ try {
33571
+ const compiledFormula = compile(formulaString);
33572
+ const params = this.getCompilationParameters((cell) => this.getEvaluatedCell(this.getters.getCellPosition(cell.id)));
33573
+ const ranges = [];
33574
+ for (let xc of compiledFormula.dependencies) {
33575
+ ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
33576
+ }
33577
+ return compiledFormula.execute(ranges, ...params).value;
33578
+ }
33579
+ catch (error) {
33580
+ return error instanceof EvaluationError ? error.errorType : CellErrorType.GenericError;
33488
33581
  }
33489
- return compiledFormula.execute(ranges, ...params).value;
33490
33582
  }
33491
33583
  /**
33492
33584
  * Return the value of each cell in the range as they are displayed in the grid.
@@ -33671,10 +33763,8 @@ class EvaluationPlugin extends UIPlugin {
33671
33763
  * that are actually present in the grid.
33672
33764
  */
33673
33765
  function range(range) {
33766
+ assertRangeValid(range);
33674
33767
  const sheetId = range.sheetId;
33675
- if (!isZoneValid(range.zone)) {
33676
- throw new InvalidReferenceError();
33677
- }
33678
33768
  // Performance issue: Avoid fetching data on positions that are out of the spreadsheet
33679
33769
  // e.g. A1:ZZZ9999 in a sheet with 10 cols and 10 rows should ignore everything past J10 and return a 10x10 array
33680
33770
  const sheetZone = getters.getSheetZone(sheetId);
@@ -33709,23 +33799,26 @@ class EvaluationPlugin extends UIPlugin {
33709
33799
  * The `compute` of the formula's function must process it completely
33710
33800
  */
33711
33801
  function refFn(range, isMeta, functionName, paramNumber) {
33802
+ assertRangeValid(range);
33712
33803
  if (isMeta) {
33713
33804
  // Use zoneToXc of zone instead of getRangeString to avoid sending unbounded ranges
33714
33805
  return { value: zoneToXc(range.zone) };
33715
33806
  }
33716
- if (!isZoneValid(range.zone)) {
33717
- throw new InvalidReferenceError();
33718
- }
33719
33807
  // if the formula definition could have accepted a range, we would pass through the _range function and not here
33720
33808
  if (range.zone.bottom !== range.zone.top || range.zone.left !== range.zone.right) {
33721
33809
  throw new Error(paramNumber
33722
33810
  ? _lt("Function %s expects the parameter %s to be a single value or a single cell reference, not a range.", functionName.toString(), paramNumber.toString())
33723
33811
  : _lt("Function %s expects its parameters to be single values or single cell references, not ranges.", functionName.toString()));
33724
33812
  }
33813
+ return readCell(range);
33814
+ }
33815
+ function assertRangeValid(range) {
33816
+ if (!isZoneValid(range.zone)) {
33817
+ throw new InvalidReferenceError();
33818
+ }
33725
33819
  if (range.invalidSheetName) {
33726
33820
  throw new Error(_lt("Invalid sheet name: %s", range.invalidSheetName));
33727
33821
  }
33728
- return readCell(range);
33729
33822
  }
33730
33823
  return [refFn, range, evalContext];
33731
33824
  }
@@ -33911,39 +34004,34 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
33911
34004
  this.computedIcons[sheetId] = {};
33912
34005
  const computedStyle = this.computedStyles[sheetId];
33913
34006
  for (let cf of this.getters.getConditionalFormats(sheetId).reverse()) {
33914
- try {
33915
- switch (cf.rule.type) {
33916
- case "ColorScaleRule":
33917
- for (let range of cf.ranges) {
33918
- this.applyColorScale(range, cf.rule);
33919
- }
33920
- break;
33921
- case "IconSetRule":
33922
- for (let range of cf.ranges) {
33923
- this.applyIcon(range, cf.rule);
33924
- }
33925
- break;
33926
- default:
33927
- for (let ref of cf.ranges) {
33928
- const zone = this.getters.getRangeFromSheetXC(sheetId, ref).zone;
33929
- for (let row = zone.top; row <= zone.bottom; row++) {
33930
- for (let col = zone.left; col <= zone.right; col++) {
33931
- const pr = this.rulePredicate[cf.rule.type];
33932
- let cell = this.getters.getEvaluatedCell({ sheetId, col, row });
33933
- if (pr && pr(cell, cf.rule)) {
33934
- if (!computedStyle[col])
33935
- computedStyle[col] = [];
33936
- // we must combine all the properties of all the CF rules applied to the given cell
33937
- computedStyle[col][row] = Object.assign(computedStyle[col]?.[row] || {}, cf.rule.style);
33938
- }
34007
+ switch (cf.rule.type) {
34008
+ case "ColorScaleRule":
34009
+ for (let range of cf.ranges) {
34010
+ this.applyColorScale(range, cf.rule);
34011
+ }
34012
+ break;
34013
+ case "IconSetRule":
34014
+ for (let range of cf.ranges) {
34015
+ this.applyIcon(range, cf.rule);
34016
+ }
34017
+ break;
34018
+ default:
34019
+ for (let ref of cf.ranges) {
34020
+ const zone = this.getters.getRangeFromSheetXC(sheetId, ref).zone;
34021
+ for (let row = zone.top; row <= zone.bottom; row++) {
34022
+ for (let col = zone.left; col <= zone.right; col++) {
34023
+ const pr = this.rulePredicate[cf.rule.type];
34024
+ let cell = this.getters.getEvaluatedCell({ sheetId, col, row });
34025
+ if (pr && pr(cell, cf.rule)) {
34026
+ if (!computedStyle[col])
34027
+ computedStyle[col] = [];
34028
+ // we must combine all the properties of all the CF rules applied to the given cell
34029
+ computedStyle[col][row] = Object.assign(computedStyle[col]?.[row] || {}, cf.rule.style);
33939
34030
  }
33940
34031
  }
33941
34032
  }
33942
- break;
33943
- }
33944
- }
33945
- catch (_) {
33946
- // we don't care about the errors within the evaluation of a rule
34033
+ }
34034
+ break;
33947
34035
  }
33948
34036
  }
33949
34037
  }
@@ -33968,7 +34056,7 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
33968
34056
  return percentile(rangeValues, Number(threshold.value) / 100, true);
33969
34057
  case "formula":
33970
34058
  const value = threshold.value && this.getters.evaluateFormula(threshold.value);
33971
- return !(value instanceof Promise) ? value : null;
34059
+ return typeof value === "number" ? value : null;
33972
34060
  default:
33973
34061
  return null;
33974
34062
  }
@@ -34215,7 +34303,7 @@ class FilterEvaluationPlugin extends UIPlugin {
34215
34303
  switch (cmd.type) {
34216
34304
  case "UPDATE_FILTER":
34217
34305
  if (!this.getters.getFilterId(cmd)) {
34218
- return 79 /* CommandResult.FilterNotFound */;
34306
+ return 80 /* CommandResult.FilterNotFound */;
34219
34307
  }
34220
34308
  break;
34221
34309
  }
@@ -35185,7 +35273,7 @@ class SheetViewPlugin extends UIPlugin {
35185
35273
  }
35186
35274
  checkPositiveDimension(cmd) {
35187
35275
  if (cmd.width < 0 || cmd.height < 0) {
35188
- return 68 /* CommandResult.InvalidViewportSize */;
35276
+ return 69 /* CommandResult.InvalidViewportSize */;
35189
35277
  }
35190
35278
  return 0 /* CommandResult.Success */;
35191
35279
  }
@@ -35195,7 +35283,7 @@ class SheetViewPlugin extends UIPlugin {
35195
35283
  cmd.gridOffsetY === this.gridOffsetY &&
35196
35284
  cmd.width === width &&
35197
35285
  cmd.height === height) {
35198
- return 76 /* CommandResult.ValuesNotChanged */;
35286
+ return 77 /* CommandResult.ValuesNotChanged */;
35199
35287
  }
35200
35288
  return 0 /* CommandResult.Success */;
35201
35289
  }
@@ -35203,7 +35291,7 @@ class SheetViewPlugin extends UIPlugin {
35203
35291
  const pane = this.getMainInternalViewport(this.getters.getActiveSheetId());
35204
35292
  if ((!pane.canScrollHorizontally && offsetX > 0) ||
35205
35293
  (!pane.canScrollVertically && offsetY > 0)) {
35206
- return 69 /* CommandResult.InvalidScrollingDirection */;
35294
+ return 70 /* CommandResult.InvalidScrollingDirection */;
35207
35295
  }
35208
35296
  return 0 /* CommandResult.Success */;
35209
35297
  }
@@ -35458,7 +35546,7 @@ class AutofillPlugin extends UIPlugin {
35458
35546
  if (this.lastCellSelected.col !== undefined && this.lastCellSelected.row !== undefined) {
35459
35547
  return 0 /* CommandResult.Success */;
35460
35548
  }
35461
- return 45 /* CommandResult.InvalidAutofillSelection */;
35549
+ return 46 /* CommandResult.InvalidAutofillSelection */;
35462
35550
  case "AUTOFILL_AUTO":
35463
35551
  const zone = this.getters.getSelectedZone();
35464
35552
  return zone.top === zone.bottom
@@ -35617,19 +35705,21 @@ class AutofillPlugin extends UIPlugin {
35617
35705
  let col = zone.left;
35618
35706
  let row = zone.bottom;
35619
35707
  if (col > 0) {
35620
- let left = this.getters.getEvaluatedCell({ sheetId, col: col - 1, row });
35621
- while (left.type !== CellValueType.empty) {
35708
+ let leftPosition = { sheetId, col: col - 1, row };
35709
+ while (this.getters.getEvaluatedCell(leftPosition).type !== CellValueType.empty ||
35710
+ this.getters.getCell(leftPosition)?.content) {
35622
35711
  row += 1;
35623
- left = this.getters.getEvaluatedCell({ sheetId, col: col - 1, row });
35712
+ leftPosition = { sheetId, col: col - 1, row };
35624
35713
  }
35625
35714
  }
35626
35715
  if (row === zone.bottom) {
35627
35716
  col = zone.right;
35628
35717
  if (col <= this.getters.getNumberCols(sheetId)) {
35629
- let right = this.getters.getEvaluatedCell({ sheetId, col: col + 1, row });
35630
- while (right.type !== CellValueType.empty) {
35718
+ let rightPosition = { sheetId, col: col + 1, row };
35719
+ while (this.getters.getEvaluatedCell(rightPosition).type !== CellValueType.empty ||
35720
+ this.getters.getCell(rightPosition)?.content) {
35631
35721
  row += 1;
35632
- right = this.getters.getEvaluatedCell({ sheetId, col: col + 1, row });
35722
+ rightPosition = { sheetId, col: col + 1, row };
35633
35723
  }
35634
35724
  }
35635
35725
  }
@@ -36060,7 +36150,7 @@ class CellPopoverPlugin extends UIPlugin {
36060
36150
  cellPopoverRegistry.get(cmd.popoverType);
36061
36151
  }
36062
36152
  catch (error) {
36063
- return 72 /* CommandResult.InvalidCellPopover */;
36153
+ return 73 /* CommandResult.InvalidCellPopover */;
36064
36154
  }
36065
36155
  return 0 /* CommandResult.Success */;
36066
36156
  default:
@@ -38196,21 +38286,6 @@ class SelectionInputPlugin extends UIPlugin {
38196
38286
  // ---------------------------------------------------------------------------
38197
38287
  // Command Handling
38198
38288
  // ---------------------------------------------------------------------------
38199
- allowDispatch(cmd) {
38200
- switch (cmd.type) {
38201
- case "ADD_EMPTY_RANGE":
38202
- if (this.inputHasSingleRange && this.ranges.length === 1) {
38203
- return 30 /* CommandResult.MaximumRangesReached */;
38204
- }
38205
- break;
38206
- case "CHANGE_RANGE":
38207
- if (this.inputHasSingleRange && cmd.value.split(",").length > 1) {
38208
- return 30 /* CommandResult.MaximumRangesReached */;
38209
- }
38210
- break;
38211
- }
38212
- return 0 /* CommandResult.Success */;
38213
- }
38214
38289
  handleEvent(event) {
38215
38290
  const xc = zoneToXc(event.anchor.zone);
38216
38291
  const inputSheetId = this.activeSheet;
@@ -38426,6 +38501,15 @@ class SelectionInputsManagerPlugin extends UIPlugin {
38426
38501
  // Command Handling
38427
38502
  // ---------------------------------------------------------------------------
38428
38503
  allowDispatch(cmd) {
38504
+ switch (cmd.type) {
38505
+ case "FOCUS_RANGE":
38506
+ case "CHANGE_RANGE":
38507
+ case "ADD_EMPTY_RANGE":
38508
+ case "REMOVE_RANGE":
38509
+ if (!this.inputs[cmd.id]) {
38510
+ return 31 /* CommandResult.InvalidInputId */;
38511
+ }
38512
+ }
38429
38513
  switch (cmd.type) {
38430
38514
  case "FOCUS_RANGE":
38431
38515
  const index = this.currentInput?.getIndex(cmd.rangeId);
@@ -38433,9 +38517,19 @@ class SelectionInputsManagerPlugin extends UIPlugin {
38433
38517
  return 29 /* CommandResult.InputAlreadyFocused */;
38434
38518
  }
38435
38519
  break;
38436
- }
38437
- if (this.currentInput) {
38438
- return this.currentInput.allowDispatch(cmd);
38520
+ case "ADD_EMPTY_RANGE":
38521
+ const input = this.inputs[cmd.id];
38522
+ if (input.inputHasSingleRange && input.ranges.length === 1) {
38523
+ return 30 /* CommandResult.MaximumRangesReached */;
38524
+ }
38525
+ break;
38526
+ case "CHANGE_RANGE": {
38527
+ const input = this.inputs[cmd.id];
38528
+ if (input.inputHasSingleRange && cmd.value.split(",").length > 1) {
38529
+ return 30 /* CommandResult.MaximumRangesReached */;
38530
+ }
38531
+ break;
38532
+ }
38439
38533
  }
38440
38534
  return 0 /* CommandResult.Success */;
38441
38535
  }
@@ -38559,7 +38653,7 @@ class SortPlugin extends UIPlugin {
38559
38653
  /*Test the presence of single cells*/
38560
38654
  const singleCells = positions(zone).some(({ col, row }) => !this.getters.isInMerge({ sheetId, col, row }));
38561
38655
  if (singleCells) {
38562
- return 63 /* CommandResult.InvalidSortZone */;
38656
+ return 64 /* CommandResult.InvalidSortZone */;
38563
38657
  }
38564
38658
  return 0 /* CommandResult.Success */;
38565
38659
  }
@@ -38578,7 +38672,7 @@ class SortPlugin extends UIPlugin {
38578
38672
  ];
38579
38673
  return widthCurrent === widthFirst && heightCurrent === heightFirst;
38580
38674
  })) {
38581
- return 63 /* CommandResult.InvalidSortZone */;
38675
+ return 64 /* CommandResult.InvalidSortZone */;
38582
38676
  }
38583
38677
  return 0 /* CommandResult.Success */;
38584
38678
  }
@@ -39081,7 +39175,7 @@ class SheetUIPlugin extends UIPlugin {
39081
39175
  const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.tryGetActiveSheetId();
39082
39176
  const zones = this.getters.getCommandZones(cmd);
39083
39177
  if (!sheetId && zones.length > 0) {
39084
- return 92 /* CommandResult.NoActiveSheet */;
39178
+ return 93 /* CommandResult.NoActiveSheet */;
39085
39179
  }
39086
39180
  if (sheetId && zones.length > 0) {
39087
39181
  return this.getters.checkZonesExistInSheet(sheetId, zones);
@@ -39563,13 +39657,13 @@ class SplitToColumnsPlugin extends UIPlugin {
39563
39657
  }
39564
39658
  checkSingleColSelected() {
39565
39659
  if (!this.getters.isSingleColSelected()) {
39566
- return 88 /* CommandResult.MoreThanOneColumnSelected */;
39660
+ return 89 /* CommandResult.MoreThanOneColumnSelected */;
39567
39661
  }
39568
39662
  return 0 /* CommandResult.Success */;
39569
39663
  }
39570
39664
  checkNonEmptySelector(cmd) {
39571
39665
  if (cmd.separator === "") {
39572
- return 89 /* CommandResult.EmptySplitSeparator */;
39666
+ return 90 /* CommandResult.EmptySplitSeparator */;
39573
39667
  }
39574
39668
  return 0 /* CommandResult.Success */;
39575
39669
  }
@@ -39580,7 +39674,7 @@ class SplitToColumnsPlugin extends UIPlugin {
39580
39674
  const selection = this.getters.getSelectedZones()[0];
39581
39675
  const splitted = this.getSplittedCols(selection, cmd.separator);
39582
39676
  if (this.willSplittedColsOverwriteContent(selection, splitted)) {
39583
- return 90 /* CommandResult.SplitWillOverwriteContent */;
39677
+ return 91 /* CommandResult.SplitWillOverwriteContent */;
39584
39678
  }
39585
39679
  return 0 /* CommandResult.Success */;
39586
39680
  }
@@ -39591,7 +39685,7 @@ class SplitToColumnsPlugin extends UIPlugin {
39591
39685
  return 0 /* CommandResult.Success */;
39592
39686
  }
39593
39687
  }
39594
- return 91 /* CommandResult.NoSplitSeparatorInSelection */;
39688
+ return 92 /* CommandResult.NoSplitSeparatorInSelection */;
39595
39689
  }
39596
39690
  }
39597
39691
 
@@ -39738,7 +39832,7 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
39738
39832
  for (const zone of this.getPasteZones(target)) {
39739
39833
  if ((zone.left < xSplit && zone.right >= xSplit) ||
39740
39834
  (zone.top < ySplit && zone.bottom >= ySplit)) {
39741
- return 75 /* CommandResult.FrozenPaneOverlap */;
39835
+ return 76 /* CommandResult.FrozenPaneOverlap */;
39742
39836
  }
39743
39837
  }
39744
39838
  return 0 /* CommandResult.Success */;
@@ -40132,7 +40226,7 @@ class ClipboardFigureState {
40132
40226
  }
40133
40227
  isPasteAllowed(target, option) {
40134
40228
  if (target.length === 0) {
40135
- return 73 /* CommandResult.EmptyTarget */;
40229
+ return 74 /* CommandResult.EmptyTarget */;
40136
40230
  }
40137
40231
  if (option?.pasteOption !== undefined) {
40138
40232
  return 22 /* CommandResult.WrongFigurePasteOption */;
@@ -40577,6 +40671,10 @@ function setXcToReferenceType(xc, referenceType) {
40577
40671
  return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
40578
40672
  case "colrow":
40579
40673
  indexOfNumber = xc.search(/[0-9]/);
40674
+ if (indexOfNumber === -1 || indexOfNumber === 0) {
40675
+ // no row number (eg. A) or no column (eg. 1)
40676
+ return "$" + xc;
40677
+ }
40580
40678
  xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
40581
40679
  return "$" + xc;
40582
40680
  case "none":
@@ -40869,7 +40967,7 @@ class EditionPlugin extends UIPlugin {
40869
40967
  validateSelection(length, start, end) {
40870
40968
  return start >= 0 && start <= length && end >= 0 && end <= length
40871
40969
  ? 0 /* CommandResult.Success */
40872
- : 46 /* CommandResult.WrongComposerSelection */;
40970
+ : 47 /* CommandResult.WrongComposerSelection */;
40873
40971
  }
40874
40972
  onColumnsRemoved(cmd) {
40875
40973
  if (cmd.elements.includes(this.col) && this.mode !== "inactive") {
@@ -41180,9 +41278,10 @@ class EditionPlugin extends UIPlugin {
41180
41278
  */
41181
41279
  getReferencedRanges() {
41182
41280
  const editionSheetId = this.getters.getCurrentEditedCell().sheetId;
41183
- return this.currentTokens
41281
+ const referenceRanges = this.currentTokens
41184
41282
  .filter((token) => token.type === "REFERENCE")
41185
41283
  .map((token) => this.getters.getRangeFromSheetXC(editionSheetId, token.value));
41284
+ return referenceRanges.filter((range) => !range.invalidSheetName && !range.invalidXc);
41186
41285
  }
41187
41286
  /**
41188
41287
  * Function used to determine when composer selection can start.
@@ -41758,7 +41857,7 @@ class GridSelectionPlugin extends UIPlugin {
41758
41857
  sheetId: cmd.sheetId,
41759
41858
  base: cmd.base,
41760
41859
  quantity: thickness,
41761
- position: "before",
41860
+ position: cmd.position,
41762
41861
  });
41763
41862
  const isCol = cmd.dimension === "COL";
41764
41863
  const start = cmd.elements[0];
@@ -41775,12 +41874,13 @@ class GridSelectionPlugin extends UIPlugin {
41775
41874
  },
41776
41875
  ];
41777
41876
  const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
41877
+ const base = isBasedBefore ? cmd.base : cmd.base + 1;
41778
41878
  const pasteTarget = [
41779
41879
  {
41780
- left: isCol ? cmd.base : 0,
41781
- right: isCol ? cmd.base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
41782
- top: !isCol ? cmd.base : 0,
41783
- bottom: !isCol ? cmd.base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
41880
+ left: isCol ? base : 0,
41881
+ right: isCol ? base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
41882
+ top: !isCol ? base : 0,
41883
+ bottom: !isCol ? base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
41784
41884
  },
41785
41885
  ];
41786
41886
  state.paste(pasteTarget, { selectTarget: true });
@@ -41817,6 +41917,11 @@ class GridSelectionPlugin extends UIPlugin {
41817
41917
  doesElementsHaveCommonMerges(id, cmd.base - 1, cmd.base)) {
41818
41918
  return 2 /* CommandResult.WillRemoveExistingMerge */;
41819
41919
  }
41920
+ const headers = [cmd.base, ...cmd.elements];
41921
+ const maxHeaderValue = isCol ? this.getters.getNumberCols(id) : this.getters.getNumberRows(id);
41922
+ if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
41923
+ return 87 /* CommandResult.InvalidHeaderIndex */;
41924
+ }
41820
41925
  return 0 /* CommandResult.Success */;
41821
41926
  }
41822
41927
  //-------------------------------------------
@@ -44098,7 +44203,7 @@ class Spreadsheet extends Component {
44098
44203
  }
44099
44204
  onKeydown(ev) {
44100
44205
  let keyDownString = "";
44101
- if (ev.ctrlKey || ev.metaKey) {
44206
+ if (isCtrlKey(ev)) {
44102
44207
  keyDownString += "CTRL+";
44103
44208
  }
44104
44209
  keyDownString += ev.key.toUpperCase();
@@ -45164,7 +45269,7 @@ class SelectionStreamProcessorImpl {
45164
45269
  */
45165
45270
  moveAnchorCell(direction, step = 1) {
45166
45271
  if (step !== "end" && step <= 0) {
45167
- return new DispatchResult(83 /* CommandResult.InvalidSelectionStep */);
45272
+ return new DispatchResult(84 /* CommandResult.InvalidSelectionStep */);
45168
45273
  }
45169
45274
  const { col, row } = this.getNextAvailablePosition(direction, step);
45170
45275
  return this.selectCell(col, row);
@@ -45210,7 +45315,7 @@ class SelectionStreamProcessorImpl {
45210
45315
  */
45211
45316
  resizeAnchorZone(direction, step = 1) {
45212
45317
  if (step !== "end" && step <= 0) {
45213
- return new DispatchResult(83 /* CommandResult.InvalidSelectionStep */);
45318
+ return new DispatchResult(84 /* CommandResult.InvalidSelectionStep */);
45214
45319
  }
45215
45320
  const sheetId = this.getters.getActiveSheetId();
45216
45321
  const anchor = this.anchor;
@@ -46037,12 +46142,7 @@ function addFormula(cell) {
46037
46142
  attrs.push(["t", "str"]);
46038
46143
  cycle = escapeXml /*xml*/ `<v>${cell.value}</v>`;
46039
46144
  }
46040
- node = escapeXml /*xml*/ `
46041
- <f>
46042
- ${XlsxFormula}
46043
- </f>
46044
- ${cycle}
46045
- `;
46145
+ node = escapeXml /*xml*/ `<f> ${XlsxFormula} </f> ${cycle}`;
46046
46146
  return { attrs, node };
46047
46147
  }
46048
46148
  else {
@@ -46864,11 +46964,10 @@ function addRows(construct, data, sheet) {
46864
46964
  ({ attrs: additionalAttrs, node: cellNode } = addContent(cell.content, construct.sharedStrings, isTableHeader));
46865
46965
  }
46866
46966
  attributes.push(...additionalAttrs);
46867
- cellNodes.push(escapeXml /*xml*/ `
46868
- <c ${formatAttributes(attributes)}>
46869
- ${cellNode}
46870
- </c>
46871
- `);
46967
+ // prettier-ignore
46968
+ cellNodes.push(escapeXml /*xml*/ `<c ${formatAttributes(attributes)}>
46969
+ ${cellNode}
46970
+ </c>`);
46872
46971
  }
46873
46972
  }
46874
46973
  if (cellNodes.length || row.size !== DEFAULT_CELL_HEIGHT || row.isHidden) {
@@ -47553,10 +47652,10 @@ class Model extends EventBus {
47553
47652
  const command = createCommand(type, payload);
47554
47653
  let status = this.status;
47555
47654
  if (this.getters.isReadonly() && !canExecuteInReadonly(command)) {
47556
- return new DispatchResult(67 /* CommandResult.Readonly */);
47655
+ return new DispatchResult(68 /* CommandResult.Readonly */);
47557
47656
  }
47558
47657
  if (!this.session.canApplyOptimisticUpdate()) {
47559
- return new DispatchResult(64 /* CommandResult.WaitingSessionConfirmation */);
47658
+ return new DispatchResult(65 /* CommandResult.WaitingSessionConfirmation */);
47560
47659
  }
47561
47660
  switch (status) {
47562
47661
  case 0 /* Status.Ready */:
@@ -47807,6 +47906,6 @@ function addFunction(functionName, functionDescription) {
47807
47906
  export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateEvaluationCommands, links, load, parse, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
47808
47907
 
47809
47908
 
47810
- __info__.version = '16.3.18';
47811
- __info__.date = '2023-11-24T13:10:15.278Z';
47812
- __info__.hash = '45f745e';
47909
+ __info__.version = '16.3.24';
47910
+ __info__.date = '2024-02-02T13:45:48.440Z';
47911
+ __info__.hash = '0bf5f45';