@odoo/o-spreadsheet 19.4.12 → 19.4.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 19.4.12
6
- * @date 2026-09-10T05:38:01.898Z
7
- * @hash cdb63b4
5
+ * @version 19.4.14
6
+ * @date 2026-10-01T07:47:35.933Z
7
+ * @hash 67c7fe5
8
8
  */
9
9
 
10
10
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
@@ -450,6 +450,9 @@ const DEFAULT_CHART_BACKGROUND_COLOR = "#FFFFFF";
450
450
  const CHART_WATERFALL_POSITIVE_COLOR = "#4EA7F2";
451
451
  const CHART_WATERFALL_NEGATIVE_COLOR = "#EA6175";
452
452
  const CHART_WATERFALL_SUBTOTAL_COLOR = "#AAAAAA";
453
+ const MIN_BUBBLE_RADIUS = 10;
454
+ const DEFAULT_BUBBLE_RADIUS = 2;
455
+ const MAX_BUBBLE_RADIUS = 30;
453
456
  const GRAY_900 = "#111827";
454
457
  const GRAY_400 = "#ced4da";
455
458
  const GRAY_300 = "#D8DADD";
@@ -457,12 +460,19 @@ const GRAY_200 = "#E7E9ED";
457
460
  const TEXT_BODY = "#374151";
458
461
  const TEXT_BODY_MUTED = "#374151C2";
459
462
  const ACTION_COLOR = HIGHLIGHT_COLOR$1;
463
+ const CHART_PADDING = 20;
464
+ const CHART_PADDING_BOTTOM = 10;
465
+ const CHART_PADDING_TOP = 15;
460
466
  const CHART_TITLE_FONT_SIZE = 16;
467
+ const CHART_AXIS_TITLE_FONT_SIZE = 12;
468
+ const MASTER_CHART_HEIGHT = 60;
469
+ const CHART_COLORSCALE_WIDTH = 70;
461
470
  const DEFAULT_CHART_COLOR_SCALE = {
462
471
  minColor: "#FFF5EB",
463
472
  midColor: "#FD8D3C",
464
473
  maxColor: "#7F2704"
465
474
  };
475
+ const SCORECARD_CHART_TITLE_FONT_SIZE = 14;
466
476
  const PIVOT_TOKEN_COLOR = "#F28C28";
467
477
  const COLOR_PICKER_DEFAULTS = [
468
478
  "#000000",
@@ -546,8 +556,32 @@ const COLOR_PICKER_DEFAULTS = [
546
556
  "#20124D",
547
557
  "#4C1130"
548
558
  ];
559
+ const MIN_ROW_HEIGHT = 10;
560
+ const MIN_COL_WIDTH = 5;
561
+ const HEADER_HEIGHT = 26;
562
+ const HEADER_WIDTH = 48;
563
+ const DESKTOP_TOPBAR_TOOLBAR_HEIGHT = 34;
564
+ const DESKTOP_BOTTOMBAR_HEIGHT = 36;
565
+ const DEFAULT_CELL_WIDTH = 96;
549
566
  const DEFAULT_CELL_HEIGHT = 23;
550
- const FOOTER_HEIGHT = 2 * 23;
567
+ const SCROLLBAR_WIDTH = 15;
568
+ const AUTOFILL_EDGE_LENGTH = 8;
569
+ const ICON_EDGE_LENGTH = 18;
570
+ const MIN_CF_ICON_MARGIN = 4;
571
+ const MIN_CELL_TEXT_MARGIN = 4;
572
+ const PADDING_AUTORESIZE_VERTICAL = 3;
573
+ const PADDING_AUTORESIZE_HORIZONTAL = MIN_CELL_TEXT_MARGIN;
574
+ const GROUP_LAYER_WIDTH = 21;
575
+ const GRID_ICON_MARGIN = 2;
576
+ const GRID_ICON_EDGE_LENGTH = 17;
577
+ const FOOTER_HEIGHT = 2 * DEFAULT_CELL_HEIGHT;
578
+ const DATA_VALIDATION_CHIP_MARGIN = 5;
579
+ const MOBILE_WIDTH_BREAKPOINT = 768;
580
+ const MENU_WIDTH = 250;
581
+ const MENU_VERTICAL_PADDING = 6;
582
+ const DESKTOP_MENU_ITEM_HEIGHT = 26;
583
+ const MIN_ZOOM_LEVEL = .5;
584
+ const MAX_ZOOM_LEVEL = 2;
551
585
  const ZOOM_VALUES = [
552
586
  50,
553
587
  75,
@@ -577,20 +611,34 @@ const DEFAULT_NUMBER_STYLE = {
577
611
  };
578
612
  const DEFAULT_VERTICAL_ALIGN = DEFAULT_STYLE.verticalAlign;
579
613
  const DEFAULT_WRAPPING_MODE = DEFAULT_STYLE.wrapping;
614
+ const DEFAULT_FONT_WEIGHT = "400";
580
615
  const DEFAULT_FONT_SIZE = DEFAULT_STYLE.fontSize;
616
+ const HEADER_FONT_SIZE = 11;
581
617
  const DEFAULT_FONT = "'Roboto', arial, 'Liberation Sans'";
582
618
  const DEFAULT_BORDER_DESC = {
583
619
  style: "thin",
584
620
  color: "#000000"
585
621
  };
622
+ const MAX_HISTORY_STEPS = 99;
586
623
  const DEFAULT_REVISION_ID = "START_REVISION";
624
+ const DEFAULT_FIGURE_HEIGHT = 335;
625
+ const DEFAULT_FIGURE_WIDTH = 536;
626
+ const FIGURE_BORDER_WIDTH = 1;
627
+ const MIN_FIG_SIZE = 80;
628
+ const MAX_CHAR_LABEL = 20;
629
+ const FIGURE_ID_SPLITTER = "??";
587
630
  const DEFAULT_GAUGE_LOWER_COLOR = "#EA6175";
588
631
  const DEFAULT_GAUGE_MIDDLE_COLOR = "#FFD86D";
589
632
  const DEFAULT_GAUGE_UPPER_COLOR = "#43C5B1";
590
633
  const DEFAULT_SCORECARD_BASELINE_MODE = "difference";
591
634
  const DEFAULT_SCORECARD_BASELINE_COLOR_UP = "#43C5B1";
592
635
  const DEFAULT_SCORECARD_BASELINE_COLOR_DOWN = "#EA6175";
636
+ const DEFAULT_SCORECARD_KEY_VALUE_FONT_SIZE = 32;
637
+ const DEFAULT_SCORECARD_BASELINE_FONT_SIZE = 16;
593
638
  const LINE_FILL_TRANSPARENCY = .4;
639
+ const LINE_DATA_POINT_RADIUS = 3;
640
+ const DEFAULT_WINDOW_SIZE = 2;
641
+ const MESSAGE_VERSION = 1;
594
642
  const FORBIDDEN_SHEETNAME_CHARS = [
595
643
  "'",
596
644
  "*",
@@ -601,6 +649,7 @@ const FORBIDDEN_SHEETNAME_CHARS = [
601
649
  "]"
602
650
  ];
603
651
  const FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX = /'|\*|\?|\/|\\|\[|\]/;
652
+ const FORMULA_REF_IDENTIFIER = "|";
604
653
  let DEFAULT_SHEETVIEW_SIZE = 0;
605
654
  /**
606
655
  * The viewport dimensions are usually set by one of the components
@@ -615,6 +664,7 @@ function setDefaultSheetViewSize(size) {
615
664
  DEFAULT_SHEETVIEW_SIZE = size;
616
665
  }
617
666
  const MAXIMAL_FREEZABLE_RATIO = .85;
667
+ const NEWLINE = "\n";
618
668
  const FONT_SIZES = [
619
669
  6,
620
670
  7,
@@ -640,6 +690,8 @@ const PIVOT_STATIC_TABLE_CONFIG = {
640
690
  automaticAutofill: false
641
691
  };
642
692
  const PIVOT_INSERT_TABLE_STYLE_ID = "PivotTableStyleMedium12";
693
+ const PIVOT_INDENT = 15;
694
+ const PIVOT_COLLAPSE_ICON_SIZE = 12;
643
695
  const PIVOT_MAX_NUMBER_OF_CELLS = 5e5;
644
696
  const DEFAULT_CURRENCY = {
645
697
  symbol: "$",
@@ -649,7 +701,7 @@ const DEFAULT_CURRENCY = {
649
701
  name: "Dollar"
650
702
  };
651
703
  const DEFAULT_CAROUSEL_TITLE_STYLE = {
652
- fontSize: 16,
704
+ fontSize: CHART_TITLE_FONT_SIZE,
653
705
  color: TEXT_BODY
654
706
  };
655
707
  const DEFAULT_TOKEN_COLOR = "light-dark(#000000, #ffffff)";
@@ -666,6 +718,7 @@ const tokenColors = {
666
718
  ARG_SEPARATOR: functionColor,
667
719
  ORPHAN_RIGHT_PAREN: "#ff0000"
668
720
  };
721
+ const DRAG_THRESHOLD = 5;
669
722
 
670
723
  //#endregion
671
724
  //#region src/types/misc.ts
@@ -1072,7 +1125,7 @@ const whiteSpaceCharacters = specialWhiteSpaceSpecialCharacters.concat([" "]);
1072
1125
  */
1073
1126
  function replaceNewLines(text) {
1074
1127
  if (!text) return "";
1075
- return text.replace(newLineRegexp, "\n");
1128
+ return text.replace(newLineRegexp, NEWLINE);
1076
1129
  }
1077
1130
  /**
1078
1131
  * Determine if the numbers are consecutive.
@@ -1340,7 +1393,7 @@ function toCartesian(xc) {
1340
1393
  consumeSpaces(chars);
1341
1394
  const col = letterPart - 1;
1342
1395
  const row = num - 1;
1343
- if (!chars.isOver() || col > MAX_COL || row > 9999998) throw new Error(`Invalid cell description: ${xc}`);
1396
+ if (!chars.isOver() || col > MAX_COL || row > MAX_ROW) throw new Error(`Invalid cell description: ${xc}`);
1344
1397
  return {
1345
1398
  col,
1346
1399
  row
@@ -1751,7 +1804,7 @@ function toUnboundedZone(xc) {
1751
1804
  const orderedZone = reorderZone(toZoneWithoutBoundaryChanges(xc));
1752
1805
  const bottom = orderedZone.bottom;
1753
1806
  const right = orderedZone.right;
1754
- if (bottom !== void 0 && bottom > 9999998 || right !== void 0 && right > MAX_COL) throw new Error(`Range string out of bounds: ${xc}`);
1807
+ if (bottom !== void 0 && bottom > MAX_ROW || right !== void 0 && right > MAX_COL) throw new Error(`Range string out of bounds: ${xc}`);
1755
1808
  if (bottom === void 0 && right === void 0) throw new Error("Wrong zone xc. The zone cannot be at the same time a full column and a full row");
1756
1809
  return orderedZone;
1757
1810
  }
@@ -1912,7 +1965,7 @@ function intersection(z1, z2) {
1912
1965
  return {
1913
1966
  top: Math.max(z1.top, z2.top),
1914
1967
  left: Math.max(z1.left, z2.left),
1915
- bottom: Math.min(z1.bottom ?? 9999998, z2.bottom),
1968
+ bottom: Math.min(z1.bottom ?? MAX_ROW, z2.bottom),
1916
1969
  right: Math.min(z1.right ?? MAX_COL, z2.right)
1917
1970
  };
1918
1971
  }
@@ -4743,7 +4796,7 @@ function parseNumberFormatTokens(tokens) {
4743
4796
  switch (token.type) {
4744
4797
  case "DIGIT":
4745
4798
  if (parsedPart === integerPart) parsedPart.push(token);
4746
- else if (numberOfDecimalsDigits < 20) {
4799
+ else if (numberOfDecimalsDigits < MAX_DECIMAL_PLACES) {
4747
4800
  parsedPart.push(token);
4748
4801
  numberOfDecimalsDigits++;
4749
4802
  }
@@ -5047,7 +5100,7 @@ function applyIntegerFormat(integerDigits, internalFormat, thousandsSeparator, h
5047
5100
  if (digitType === "0") digit = digit || "0";
5048
5101
  if (!digit) return;
5049
5102
  const digitIndex = integerDigits.length - 1 - indexInIntegerString;
5050
- const groups = getIndexesOfDigitsWithThousandSeparator(locale.digitGrouping || "[3,0]");
5103
+ const groups = getIndexesOfDigitsWithThousandSeparator(locale.digitGrouping || DEFAULT_LOCALE_DIGIT_GROUPING);
5051
5104
  if (thousandsSeparator && groups.has(digitIndex - 1)) formattedInteger = digit + thousandsSeparator + formattedInteger;
5052
5105
  else formattedInteger = digit + formattedInteger;
5053
5106
  }
@@ -5107,7 +5160,7 @@ const numberRepresentation = [];
5107
5160
  * exceed in the decimal part, in which case digits are rounded.
5108
5161
  *
5109
5162
  **/
5110
- function splitNumber(value, maxDecimals = 20) {
5163
+ function splitNumber(value, maxDecimals = MAX_DECIMAL_PLACES) {
5111
5164
  const asString = value.toString();
5112
5165
  if (asString.includes("e")) return splitNumberIntl(value, maxDecimals);
5113
5166
  if (Number.isInteger(value)) return {
@@ -5176,7 +5229,7 @@ function limitDecimalDigits(decimalDigits, maxDecimals) {
5176
5229
  * Supports numbers with a lot of digits that are transformed to scientific notation by
5177
5230
  * number.toString(), but is slow.
5178
5231
  */
5179
- function splitNumberIntl(value, maxDecimals = 20) {
5232
+ function splitNumberIntl(value, maxDecimals = MAX_DECIMAL_PLACES) {
5180
5233
  let formatter = numberRepresentation[maxDecimals];
5181
5234
  if (!formatter) {
5182
5235
  formatter = new Intl.NumberFormat("en-US", {
@@ -6144,11 +6197,11 @@ function tokenize(str, locale = DEFAULT_LOCALE) {
6144
6197
  return result;
6145
6198
  }
6146
6199
  function tokenizeDebugger(chars) {
6147
- if (chars.current === "?") {
6200
+ if (chars.current === DEBUGGER_CHAR) {
6148
6201
  chars.shift();
6149
6202
  return {
6150
6203
  type: "DEBUGGER",
6151
- value: "?"
6204
+ value: DEBUGGER_CHAR
6152
6205
  };
6153
6206
  }
6154
6207
  return null;
@@ -6307,13 +6360,13 @@ function tokenizeSimpleSpace(chars) {
6307
6360
  }
6308
6361
  function tokenizeNewLine(chars) {
6309
6362
  let length = 0;
6310
- while (chars.current === "\n") {
6363
+ while (chars.current === NEWLINE) {
6311
6364
  length++;
6312
6365
  chars.shift();
6313
6366
  }
6314
6367
  if (length) return {
6315
6368
  type: "SPACE",
6316
- value: "\n".repeat(length)
6369
+ value: NEWLINE.repeat(length)
6317
6370
  };
6318
6371
  return null;
6319
6372
  }
@@ -8451,7 +8504,7 @@ function addOrigin(cell, origin) {
8451
8504
  //#endregion
8452
8505
  //#region src/helpers/text_helper.ts
8453
8506
  function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
8454
- return numberOfLines * (textLineHeight + 4) - 4;
8507
+ return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
8455
8508
  }
8456
8509
  function getCanvas(width = 100, height = 100) {
8457
8510
  return new OffscreenCanvas(width, height).getContext("2d");
@@ -8460,7 +8513,7 @@ function getCanvas(width = 100, height = 100) {
8460
8513
  * Get the default height of the cell given its style.
8461
8514
  */
8462
8515
  function getDefaultCellHeight(ctx, cell, locale, colSize) {
8463
- if (!cell || !cell.isFormula && !cell.content) return 23;
8516
+ if (!cell || !cell.isFormula && !cell.content) return DEFAULT_CELL_HEIGHT;
8464
8517
  let content = "";
8465
8518
  try {
8466
8519
  if (!cell.isFormula) {
@@ -8476,7 +8529,7 @@ function getDefaultCellHeight(ctx, cell, locale, colSize) {
8476
8529
  return getCellContentHeight(ctx, content, cell.style, colSize);
8477
8530
  }
8478
8531
  function getCellContentHeight(ctx, content, style, colSize) {
8479
- return computeMultilineTextSize(ctx, splitTextToWidth(ctx, content, style, style?.wrapping === "wrap" ? colSize - 2 * 4 : void 0), style).height + 2 * 3;
8532
+ return computeMultilineTextSize(ctx, splitTextToWidth(ctx, content, style, style?.wrapping === "wrap" ? colSize - 2 * MIN_CELL_TEXT_MARGIN : void 0), style).height + 2 * PADDING_AUTORESIZE_VERTICAL;
8480
8533
  }
8481
8534
  function getDefaultContextFont(fontSize, bold = false, italic = false) {
8482
8535
  return `${italic ? "italic" : ""} ${bold ? "bold" : ""} ${fontSize}px ${DEFAULT_FONT}`;
@@ -8542,7 +8595,7 @@ function fontSizeInPixels(fontSize) {
8542
8595
  return Math.round(fontSize * 96 / 72);
8543
8596
  }
8544
8597
  function computeTextFont(style, fontUnit = "pt") {
8545
- return `${style.italic ? "italic " : ""}${style.bold ? "bold" : "400"} ${(fontUnit === "pt" ? computeTextFontSizeInPixels(style) : style.fontSize) ?? DEFAULT_FONT_SIZE}px ${DEFAULT_FONT}`;
8598
+ return `${style.italic ? "italic " : ""}${style.bold ? "bold" : DEFAULT_FONT_WEIGHT} ${(fontUnit === "pt" ? computeTextFontSizeInPixels(style) : style.fontSize) ?? DEFAULT_FONT_SIZE}px ${DEFAULT_FONT}`;
8546
8599
  }
8547
8600
  function computeTextFontSizeInPixels(style) {
8548
8601
  return fontSizeInPixels(style?.fontSize || DEFAULT_FONT_SIZE);
@@ -8566,7 +8619,7 @@ function splitTextToWidth(ctx, text, style, width) {
8566
8619
  if (!style) style = {};
8567
8620
  if (isMarkdownLink(text)) text = parseMarkdownLink(text).label;
8568
8621
  const brokenText = [];
8569
- const lines = text.includes("\n") ? text.split("\n") : [text];
8622
+ const lines = text.includes(NEWLINE) ? text.split(NEWLINE) : [text];
8570
8623
  for (const line of lines) {
8571
8624
  const words = line.includes(" ") ? line.split(" ") : [line];
8572
8625
  if (!width) {
@@ -8732,7 +8785,7 @@ function computeRotationPosition(rect, style) {
8732
8785
  let { x, y } = rect;
8733
8786
  const cos = Math.cos(-style.rotation);
8734
8787
  const sin = Math.sin(-style.rotation);
8735
- const width = rect.textWidth - 2 * 4;
8788
+ const width = rect.textWidth - 2 * MIN_CELL_TEXT_MARGIN;
8736
8789
  const height = rect.textHeight;
8737
8790
  const center = style.align === "center";
8738
8791
  const rotateTowardCellCenter = style.align === "left" === sin < 0;
@@ -8782,7 +8835,7 @@ const chartColorScalePlugin = {
8782
8835
  ctx.miterLimit = 1;
8783
8836
  const gradientHeight = (chart.chartArea.bottom - chart.chartArea.top) / 2;
8784
8837
  const gradientWidth = 10;
8785
- const gradientX = options.position === "left" ? 20 : ctx.canvas.width - 70;
8838
+ const gradientX = options.position === "left" ? CHART_PADDING : ctx.canvas.width - CHART_COLORSCALE_WIDTH;
8786
8839
  const gradientY = chart.chartArea.top;
8787
8840
  const gradient = ctx.createLinearGradient(0, gradientY + gradientHeight, 0, gradientY);
8788
8841
  const step = 1 / (options.colorScale.length - 1);
@@ -8792,7 +8845,7 @@ const chartColorScalePlugin = {
8792
8845
  ctx.fillStyle = gradient;
8793
8846
  ctx.fillRect(gradientX, gradientY, gradientWidth, gradientHeight);
8794
8847
  ctx.fillStyle = options.fontColor ?? "black";
8795
- ctx.font = getDefaultContextFont(12);
8848
+ ctx.font = getDefaultContextFont(CHART_AXIS_TITLE_FONT_SIZE);
8796
8849
  ctx.textAlign = "left";
8797
8850
  let minValue = Math.round(options.minValue * 100) / 100;
8798
8851
  let maxValue = Math.round(options.maxValue * 100) / 100;
@@ -9062,6 +9115,12 @@ const WIDTH_FACTOR = .143;
9062
9115
  const EXCEL_DEFAULT_COL_WIDTH = 8.43;
9063
9116
  /** unit : points */
9064
9117
  const EXCEL_DEFAULT_ROW_HEIGHT = 12.75;
9118
+ const EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS = 30;
9119
+ const EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS = 100;
9120
+ /** The possible values for the XLSX polynomial trendline order are defined by the ST_Order simple type (§21.2.3.29) */
9121
+ const MAX_XLSX_POLYNOMIAL_DEGREE = 6;
9122
+ const FIRST_NUMFMT_ID = 164;
9123
+ const DEFAULT_DOUGHNUT_CHART_HOLE_SIZE = 50;
9065
9124
  const FORCE_DEFAULT_ARGS_FUNCTIONS = {
9066
9125
  FLOOR: [{
9067
9126
  type: "NUMBER",
@@ -10064,8 +10123,8 @@ function toExcelDataset(getters, dataSetStyles, ds) {
10064
10123
  if (dataSetStyle.trend?.type) trend = {
10065
10124
  type: dataSetStyle.trend.type === "polynomial" && dataSetStyle.trend.order === 1 ? "linear" : SPREADSHEET_TO_EXCEL_TRENDLINE_TYPE_MAPPING[dataSetStyle.trend.type],
10066
10125
  color: dataSetStyle.trend.color,
10067
- order: dataSetStyle.trend.order ? Math.min(dataSetStyle.trend.order, 6) : void 0,
10068
- window: dataSetStyle.trend.window || 2
10126
+ order: dataSetStyle.trend.order ? Math.min(dataSetStyle.trend.order, MAX_XLSX_POLYNOMIAL_DEGREE) : void 0,
10127
+ window: dataSetStyle.trend.window || DEFAULT_WINDOW_SIZE
10069
10128
  };
10070
10129
  return {
10071
10130
  label,
@@ -10171,13 +10230,13 @@ function getPieColors(colors, dataSetsValues) {
10171
10230
  for (let i = 0; i <= maxLength; i++) pieColors.push(colors.next());
10172
10231
  return pieColors;
10173
10232
  }
10174
- function truncateLabel(label, maxLen = 20) {
10233
+ function truncateLabel(label, maxLen = MAX_CHAR_LABEL) {
10175
10234
  if (!label) return "";
10176
10235
  if (label.length > maxLen) return label.substring(0, maxLen) + "…";
10177
10236
  return label;
10178
10237
  }
10179
10238
  function isTrendLineAxis(axisID) {
10180
- return axisID === "x1" || axisID === "xMovingAverage";
10239
+ return axisID === TREND_LINE_XAXIS_ID || axisID === MOVING_AVERAGE_TREND_LINE_XAXIS_ID;
10181
10240
  }
10182
10241
  function getChartBackgroundColor({ background }, getters) {
10183
10242
  const defaultColor = getters.getSpreadsheetTheme().backgroundColor;
@@ -10535,7 +10594,7 @@ function getBarChartScales(definition, args) {
10535
10594
  scales = removeFalsyAttributes(scales);
10536
10595
  if (trendDatasets && trendDatasets.length && trendDatasets.some(isDefined)) {
10537
10596
  const maxLength = Math.max(...trendDatasets.map((trendDataset) => trendDataset?.length || 0));
10538
- scales["x1"] = {
10597
+ scales[TREND_LINE_XAXIS_ID] = {
10539
10598
  ...scales.x,
10540
10599
  labels: Array(maxLength).fill(""),
10541
10600
  offset: false,
@@ -10646,7 +10705,7 @@ function getLineChartScales(definition, args) {
10646
10705
  });
10647
10706
  }
10648
10707
  if (trendDatasets && trendDatasets.length && trendDatasets.some(isDefined)) {
10649
- scales["x1"] = {
10708
+ scales[TREND_LINE_XAXIS_ID] = {
10650
10709
  ...scales.x,
10651
10710
  display: false
10652
10711
  };
@@ -10656,9 +10715,9 @@ function getLineChartScales(definition, args) {
10656
10715
  };
10657
10716
  if (axisType === "category" || axisType === "time") {
10658
10717
  const maxLength = Math.max(...trendDatasets.map((trendDataset) => trendDataset?.length || 0));
10659
- scales["x1"]["type"] = "category";
10660
- scales["x1"]["labels"] = range(0, maxLength).map((x) => x.toString());
10661
- scales["x1"]["offset"] = false;
10718
+ scales[TREND_LINE_XAXIS_ID]["type"] = "category";
10719
+ scales[TREND_LINE_XAXIS_ID]["labels"] = range(0, maxLength).map((x) => x.toString());
10720
+ scales[TREND_LINE_XAXIS_ID]["offset"] = false;
10662
10721
  scales[MOVING_AVERAGE_TREND_LINE_XAXIS_ID]["type"] = "category";
10663
10722
  scales[MOVING_AVERAGE_TREND_LINE_XAXIS_ID]["offset"] = false;
10664
10723
  }
@@ -10831,7 +10890,7 @@ function getChartAxisTitleRuntime(design) {
10831
10890
  font: {
10832
10891
  style: italic ? "italic" : "normal",
10833
10892
  weight: bold ? "bold" : "normal",
10834
- size: design.title.fontSize ?? 12
10893
+ size: design.title.fontSize ?? CHART_AXIS_TITLE_FONT_SIZE
10835
10894
  },
10836
10895
  align: align === "left" ? "start" : align === "right" ? "end" : "center"
10837
10896
  };
@@ -10919,16 +10978,16 @@ function getLegendMargin(definition) {
10919
10978
  switch (definition.legendPosition) {
10920
10979
  case "top":
10921
10980
  case "right": return {
10922
- top: !!definition.title.text ? 15 + 30 : 15,
10923
- left: 20,
10924
- right: 20
10981
+ top: !!definition.title.text ? CHART_PADDING_TOP + 30 : CHART_PADDING_TOP,
10982
+ left: CHART_PADDING,
10983
+ right: CHART_PADDING
10925
10984
  };
10926
10985
  case "bottom":
10927
10986
  case "left":
10928
10987
  case "none": return {
10929
- left: 20,
10930
- right: 20,
10931
- bottom: 10
10988
+ left: CHART_PADDING,
10989
+ right: CHART_PADDING,
10990
+ bottom: CHART_PADDING_BOTTOM
10932
10991
  };
10933
10992
  }
10934
10993
  }
@@ -10997,7 +11056,7 @@ function getBarChartTotalLineDataset(definition, dataSetsValues) {
10997
11056
  order: -1,
10998
11057
  tension: 0,
10999
11058
  fill: false,
11000
- pointRadius: 3,
11059
+ pointRadius: LINE_DATA_POINT_RADIUS,
11001
11060
  borderWidth: 2,
11002
11061
  backgroundColor: color,
11003
11062
  borderColor: color,
@@ -11016,7 +11075,7 @@ function getCalendarChartDatasetAndLabels(definition, args) {
11016
11075
  for (const dataSetValues of dataSetsValues) dataSets.push({
11017
11076
  label: dataSetValues.label,
11018
11077
  data: dataSetValues.data.map((v) => 1),
11019
- backgroundColor: dataSetValues.data.map((v) => isNumberResult(v) ? colorMap(v.value) : definition.missingValueColor || "#00000000"),
11078
+ backgroundColor: dataSetValues.data.map((v) => isNumberResult(v) ? colorMap(v.value) : definition.missingValueColor || COLOR_TRANSPARENT),
11020
11079
  borderColor: definition.background || background,
11021
11080
  borderSkipped: false,
11022
11081
  borderWidth: 1,
@@ -11031,9 +11090,9 @@ function getCalendarChartDatasetAndLabels(definition, args) {
11031
11090
  }
11032
11091
  function getWaterfallDatasetAndLabels(definition, args) {
11033
11092
  const { dataSetsValues, labels } = args;
11034
- const negativeColor = definition.negativeValuesColor || "#EA6175";
11035
- const positiveColor = definition.positiveValuesColor || "#4EA7F2";
11036
- const subTotalColor = definition.subTotalValuesColor || "#AAAAAA";
11093
+ const negativeColor = definition.negativeValuesColor || CHART_WATERFALL_NEGATIVE_COLOR;
11094
+ const positiveColor = definition.positiveValuesColor || CHART_WATERFALL_POSITIVE_COLOR;
11095
+ const subTotalColor = definition.subTotalValuesColor || CHART_WATERFALL_SUBTOTAL_COLOR;
11037
11096
  const backgroundColor = [];
11038
11097
  const datasetValues = [];
11039
11098
  const dataset = {
@@ -11097,7 +11156,7 @@ function getLineChartDatasets(definition, args) {
11097
11156
  backgroundColor: areaChart ? setColorAlpha(color, LINE_FILL_TRANSPARENCY) : color,
11098
11157
  pointBackgroundColor: color,
11099
11158
  fill: areaChart ? getFillingMode(index, stackedChart) : false,
11100
- pointRadius: definition.hideDataMarkers ? 0 : 3,
11159
+ pointRadius: definition.hideDataMarkers ? 0 : LINE_DATA_POINT_RADIUS,
11101
11160
  yAxisID: dataSetStyle?.yAxisId || "y"
11102
11161
  };
11103
11162
  dataSets.push(dataset);
@@ -11152,12 +11211,12 @@ function computeBubbleRadii(sizeValues) {
11152
11211
  const finiteSizes = sizeValues.filter((value) => Number.isFinite(value) && value > 0);
11153
11212
  const min = finiteSizes.length ? Math.min(...finiteSizes) : 0;
11154
11213
  const range = (finiteSizes.length ? Math.max(...finiteSizes) : 0) - min;
11155
- if (!finiteSizes.length) return sizeValues.map(() => 2);
11214
+ if (!finiteSizes.length) return sizeValues.map(() => DEFAULT_BUBBLE_RADIUS);
11156
11215
  return sizeValues.map((value) => {
11157
11216
  if (value === void 0 || !Number.isFinite(value) || value < 0) return 0;
11158
- if (value === 0) return 2;
11159
- if (range === 0) return 10;
11160
- return 10 + clip((value - min) / range, 0, 1) * (30 - 10);
11217
+ if (value === 0) return DEFAULT_BUBBLE_RADIUS;
11218
+ if (range === 0) return MIN_BUBBLE_RADIUS;
11219
+ return MIN_BUBBLE_RADIUS + clip((value - min) / range, 0, 1) * (MAX_BUBBLE_RADIUS - MIN_BUBBLE_RADIUS);
11161
11220
  });
11162
11221
  }
11163
11222
  function getPieChartDatasets(definition, args) {
@@ -11200,7 +11259,7 @@ function getComboChartDatasets(definition, args) {
11200
11259
  xAxisID: "x",
11201
11260
  type,
11202
11261
  order: type === "bar" ? dataSetsValues.length + index : index,
11203
- pointRadius: definition.hideDataMarkers ? 0 : 3
11262
+ pointRadius: definition.hideDataMarkers ? 0 : LINE_DATA_POINT_RADIUS
11204
11263
  };
11205
11264
  if (dataset.type === "bar") {
11206
11265
  dataset.barPercentage = .9;
@@ -11232,7 +11291,7 @@ function getRadarChartDatasets(definition, args) {
11232
11291
  borderColor,
11233
11292
  backgroundColor: borderColor,
11234
11293
  pointBackgroundColor: borderColor,
11235
- pointRadius: definition.hideDataMarkers ? 0 : 3
11294
+ pointRadius: definition.hideDataMarkers ? 0 : LINE_DATA_POINT_RADIUS
11236
11295
  };
11237
11296
  if (fill) {
11238
11297
  dataset.backgroundColor = setColorAlpha(borderColor, LINE_FILL_TRANSPARENCY);
@@ -11318,12 +11377,12 @@ function getSunburstChartDatasets(definition, args) {
11318
11377
  data: data[i],
11319
11378
  borderColor: (ctx) => {
11320
11379
  const data = ctx.type === "data" ? ctx.raw : void 0;
11321
- if (!data || data.label === "nullValue") return COLOR_TRANSPARENT;
11380
+ if (!data || data.label === GHOST_SUNBURST_VALUE) return COLOR_TRANSPARENT;
11322
11381
  return definition.background || background;
11323
11382
  },
11324
11383
  backgroundColor: (ctx) => {
11325
11384
  const data = ctx.type === "data" ? ctx.raw : void 0;
11326
- if (!data || data.label === "nullValue") return COLOR_TRANSPARENT;
11385
+ if (!data || data.label === GHOST_SUNBURST_VALUE) return COLOR_TRANSPARENT;
11327
11386
  const rootGroup = data.groups[0];
11328
11387
  return groupColors.find((groupColor) => groupColor.label === rootGroup)?.color;
11329
11388
  },
@@ -11464,7 +11523,7 @@ function getTrendingLineDataSet(dataset, config, data) {
11464
11523
  const borderColor = config.color || lightenColor(rgbaToHex(defaultBorderColor), .5);
11465
11524
  return {
11466
11525
  type: "line",
11467
- xAxisID: config.type === "trailingMovingAverage" ? MOVING_AVERAGE_TREND_LINE_XAXIS_ID : "x1",
11526
+ xAxisID: config.type === "trailingMovingAverage" ? MOVING_AVERAGE_TREND_LINE_XAXIS_ID : TREND_LINE_XAXIS_ID,
11468
11527
  yAxisID: dataset.yAxisID,
11469
11528
  label: dataset.label ? _t("Trend line for %s", dataset.label) : "",
11470
11529
  data,
@@ -11577,7 +11636,7 @@ const sunburstHoverPlugin = {
11577
11636
  for (const metaSet of chart.getSortedVisibleDatasetMetas()) for (const arcElement of metaSet.data) {
11578
11637
  const context = arcElement["$context"];
11579
11638
  const { datasetIndex, index, dataset, raw } = context;
11580
- if (raw.label === "nullValue") continue;
11639
+ if (raw.label === GHOST_SUNBURST_VALUE) continue;
11581
11640
  const originalBackgroundColor = typeof dataset.backgroundColor === "function" ? dataset.backgroundColor(context) : dataset.backgroundColor;
11582
11641
  if (activeDataPoints.length && !activeDataPoints.some((el) => el.datasetIndex === datasetIndex && el.index === index)) arcElement.options.backgroundColor = lightenColor(originalBackgroundColor, .5);
11583
11642
  else arcElement.options.backgroundColor = originalBackgroundColor;
@@ -11605,7 +11664,7 @@ function drawSunburstChartValues(chart, options, ctx) {
11605
11664
  const lineHeight = fontSize + Y_PADDING;
11606
11665
  for (const dataset of chart._metasets) for (let i = 0; i < dataset._dataset.data.length; i++) {
11607
11666
  const rawData = dataset._dataset.data[i];
11608
- if (rawData.label === "nullValue") continue;
11667
+ if (rawData.label === GHOST_SUNBURST_VALUE) continue;
11609
11668
  const valuesToDisplay = [options.showLabels ? rawData.label : void 0, options.showValues ? options.callback(rawData.value, "y") : void 0].filter(isDefined);
11610
11669
  const arc = dataset.data[i];
11611
11670
  let { startAngle, endAngle, innerRadius, outerRadius, circumference } = arc;
@@ -12134,7 +12193,7 @@ function drawScoreChart(structure, canvas, zoom = 1) {
12134
12193
  canvas.width = dpr * structure.canvas.width * zoom;
12135
12194
  canvas.height = dpr * structure.canvas.height * zoom;
12136
12195
  ctx.scale(dpr * zoom, dpr * zoom);
12137
- const availableWidth = structure.canvas.width - 20;
12196
+ const availableWidth = structure.canvas.width - CHART_PADDING;
12138
12197
  ctx.fillStyle = structure.canvas.backgroundColor;
12139
12198
  ctx.fillRect(0, 0, structure.canvas.width, structure.canvas.height);
12140
12199
  if (structure.title) {
@@ -12242,16 +12301,16 @@ var ScorecardChartConfigBuilder = class {
12242
12301
  x = (this.width - titleWidth) / 2;
12243
12302
  break;
12244
12303
  case "right":
12245
- x = this.width - titleWidth - 20;
12304
+ x = this.width - titleWidth - CHART_PADDING;
12246
12305
  break;
12247
- default: x = 20;
12306
+ default: x = CHART_PADDING;
12248
12307
  }
12249
12308
  structure.title = {
12250
12309
  text: this.title,
12251
12310
  style: style.title,
12252
12311
  position: {
12253
12312
  x,
12254
- y: 10 + titleHeight / 2
12313
+ y: CHART_PADDING_BOTTOM + titleHeight / 2
12255
12314
  }
12256
12315
  };
12257
12316
  }
@@ -12262,10 +12321,10 @@ var ScorecardChartConfigBuilder = class {
12262
12321
  let baselineX;
12263
12322
  switch (this.runtime.baselineStyle?.align) {
12264
12323
  case "right":
12265
- baselineX = this.width - 20 - baselineDescrWidth - baselineWidth;
12324
+ baselineX = this.width - CHART_PADDING - baselineDescrWidth - baselineWidth;
12266
12325
  break;
12267
12326
  case "left":
12268
- baselineX = 20 + baselineArrowSize;
12327
+ baselineX = CHART_PADDING + baselineArrowSize;
12269
12328
  break;
12270
12329
  default: baselineX = (this.width - baselineWidth - baselineDescrWidth + baselineArrowSize) / 2;
12271
12330
  }
@@ -12275,7 +12334,7 @@ var ScorecardChartConfigBuilder = class {
12275
12334
  style: style.baselineValue,
12276
12335
  position: {
12277
12336
  x: baselineX,
12278
- y: this.keyValue ? this.height * (1 - BOTTOM_PADDING_RATIO * (this.runtime.progressBar ? 1 : 2)) : this.height - (this.height - titleHeight - baselineHeight) / 2 - 10
12337
+ y: this.keyValue ? this.height * (1 - BOTTOM_PADDING_RATIO * (this.runtime.progressBar ? 1 : 2)) : this.height - (this.height - titleHeight - baselineHeight) / 2 - CHART_PADDING_BOTTOM
12279
12338
  }
12280
12339
  };
12281
12340
  if (style.baselineArrow && !this.runtime.progressBar) structure.baselineArrow = {
@@ -12303,12 +12362,12 @@ var ScorecardChartConfigBuilder = class {
12303
12362
  progressBarHeight = this.height * .05;
12304
12363
  structure.progressBar = {
12305
12364
  position: {
12306
- x: 2 * 20,
12365
+ x: 2 * CHART_PADDING,
12307
12366
  y: this.height * (1 - 2 * BOTTOM_PADDING_RATIO) - baselineHeight - progressBarHeight
12308
12367
  },
12309
12368
  dimension: {
12310
12369
  height: progressBarHeight,
12311
- width: this.width - 4 * 20
12370
+ width: this.width - 4 * CHART_PADDING
12312
12371
  },
12313
12372
  value: this.runtime.progressBar.value,
12314
12373
  style: {
@@ -12322,10 +12381,10 @@ var ScorecardChartConfigBuilder = class {
12322
12381
  let keyX;
12323
12382
  switch (this.runtime.keyValueStyle?.align) {
12324
12383
  case "right":
12325
- keyX = this.width - 20 - keyDescrWidth - keyWidth;
12384
+ keyX = this.width - CHART_PADDING - keyDescrWidth - keyWidth;
12326
12385
  break;
12327
12386
  case "left":
12328
- keyX = 20;
12387
+ keyX = CHART_PADDING;
12329
12388
  break;
12330
12389
  default: keyX = (this.width - keyWidth - keyDescrWidth) / 2;
12331
12390
  }
@@ -12333,8 +12392,8 @@ var ScorecardChartConfigBuilder = class {
12333
12392
  text: this.keyValue,
12334
12393
  style: style.keyValue,
12335
12394
  position: {
12336
- x: Math.max(20, keyX),
12337
- y: this.height * (.5 - BOTTOM_PADDING_RATIO * 2) + 10 / 2 + (titleHeight + keyHeight / 2) / 2
12395
+ x: Math.max(CHART_PADDING, keyX),
12396
+ y: this.height * (.5 - BOTTOM_PADDING_RATIO * 2) + CHART_PADDING_BOTTOM / 2 + (titleHeight + keyHeight / 2) / 2
12338
12397
  }
12339
12398
  };
12340
12399
  if (structure.key && this.keyDescr) {
@@ -12391,14 +12450,14 @@ var ScorecardChartConfigBuilder = class {
12391
12450
  };
12392
12451
  }
12393
12452
  getTextStyles() {
12394
- const keyValueFontSize = this.runtime.keyValueStyle?.fontSize ?? 32;
12453
+ const keyValueFontSize = this.runtime.keyValueStyle?.fontSize ?? DEFAULT_SCORECARD_KEY_VALUE_FONT_SIZE;
12395
12454
  const keyValueDescrFontSize = Math.floor(.9 * keyValueFontSize);
12396
- let baselineValueFontSize = this.runtime.baselineStyle?.fontSize ?? 16;
12455
+ let baselineValueFontSize = this.runtime.baselineStyle?.fontSize ?? DEFAULT_SCORECARD_BASELINE_FONT_SIZE;
12397
12456
  const baselineDescrFontSize = Math.floor(.9 * baselineValueFontSize);
12398
12457
  if (this.runtime.progressBar) baselineValueFontSize /= 1.5;
12399
12458
  return {
12400
12459
  title: {
12401
- font: getDefaultContextFont(this.runtime.title.fontSize ?? 14, this.runtime.title.bold, this.runtime.title.italic),
12460
+ font: getDefaultContextFont(this.runtime.title.fontSize ?? SCORECARD_CHART_TITLE_FONT_SIZE, this.runtime.title.bold, this.runtime.title.italic),
12402
12461
  color: this.runtime.title.color ?? this.secondaryFontColor
12403
12462
  },
12404
12463
  keyValue: {
@@ -12653,35 +12712,35 @@ function getGaugeRenderingConfig(boundingRect, runtime, ctx) {
12653
12712
  x: boundingRect.width / 2,
12654
12713
  y: gaugeRect.y + gaugeRect.height - gaugeRect.height / 12
12655
12714
  };
12656
- let gaugeValueFontSize = 80;
12715
+ let gaugeValueFontSize = GAUGE_DEFAULT_VALUE_FONT_SIZE;
12657
12716
  if (gaugeRect.height < 300) gaugeValueFontSize = gaugeValueFontSize * (gaugeRect.height / 300);
12658
12717
  const maxTextWidth = gaugeRect.width / 2;
12659
12718
  const gaugeLabel = runtime.gaugeValue?.label || "-";
12660
12719
  if (computeTextWidth(ctx, gaugeLabel, { fontSize: gaugeValueFontSize }, "px") > maxTextWidth) gaugeValueFontSize = getFontSizeMatchingWidth(maxTextWidth, gaugeValueFontSize, (fontSize) => computeTextWidth(ctx, gaugeLabel, { fontSize }, "px"));
12661
12720
  const minLabelPosition = {
12662
12721
  x: gaugeRect.x + gaugeArcWidth / 2,
12663
- y: gaugeRect.y + gaugeRect.height + 12
12722
+ y: gaugeRect.y + gaugeRect.height + GAUGE_LABELS_FONT_SIZE
12664
12723
  };
12665
12724
  const maxLabelPosition = {
12666
12725
  x: gaugeRect.x + gaugeRect.width - gaugeArcWidth / 2,
12667
- y: gaugeRect.y + gaugeRect.height + 12
12726
+ y: gaugeRect.y + gaugeRect.height + GAUGE_LABELS_FONT_SIZE
12668
12727
  };
12669
12728
  const textColor = chartMutedFontColor(runtime.background);
12670
12729
  const inflectionValues = getInflectionValues(runtime, gaugeRect, textColor, ctx);
12671
12730
  let x = 0, titleWidth = 0, titleHeight = 0;
12672
12731
  if (runtime.title.text) ({width: titleWidth, height: titleHeight} = computeTextDimension(ctx, runtime.title.text, {
12673
- fontSize: 16,
12732
+ fontSize: CHART_TITLE_FONT_SIZE,
12674
12733
  ...runtime.title
12675
12734
  }, "px"));
12676
12735
  switch (runtime.title.align) {
12677
12736
  case "right":
12678
- x = boundingRect.width - titleWidth - 20;
12737
+ x = boundingRect.width - titleWidth - CHART_PADDING;
12679
12738
  break;
12680
12739
  case "center":
12681
12740
  x = (boundingRect.width - titleWidth) / 2;
12682
12741
  break;
12683
12742
  default:
12684
- x = 20;
12743
+ x = CHART_PADDING;
12685
12744
  break;
12686
12745
  }
12687
12746
  return {
@@ -12689,10 +12748,10 @@ function getGaugeRenderingConfig(boundingRect, runtime, ctx) {
12689
12748
  height: boundingRect.height,
12690
12749
  title: {
12691
12750
  label: runtime.title.text ?? "",
12692
- fontSize: runtime.title.fontSize ?? 16,
12751
+ fontSize: runtime.title.fontSize ?? CHART_TITLE_FONT_SIZE,
12693
12752
  textPosition: {
12694
12753
  x,
12695
- y: 15 + titleHeight / 2
12754
+ y: CHART_PADDING_TOP + titleHeight / 2
12696
12755
  },
12697
12756
  color: runtime.title.color ?? textColor,
12698
12757
  bold: runtime.title.bold,
@@ -12715,13 +12774,13 @@ function getGaugeRenderingConfig(boundingRect, runtime, ctx) {
12715
12774
  minLabel: {
12716
12775
  label: runtime.minValue.label,
12717
12776
  textPosition: minLabelPosition,
12718
- fontSize: 12,
12777
+ fontSize: GAUGE_LABELS_FONT_SIZE,
12719
12778
  color: textColor
12720
12779
  },
12721
12780
  maxLabel: {
12722
12781
  label: runtime.maxValue.label,
12723
12782
  textPosition: maxLabelPosition,
12724
- fontSize: 12,
12783
+ fontSize: GAUGE_LABELS_FONT_SIZE,
12725
12784
  color: textColor
12726
12785
  }
12727
12786
  };
@@ -12731,9 +12790,9 @@ function getGaugeRenderingConfig(boundingRect, runtime, ctx) {
12731
12790
  * space for the title and labels.
12732
12791
  */
12733
12792
  function getGaugeRect(boundingRect, title) {
12734
- const titleHeight = title ? 25 : 0;
12735
- const drawHeight = boundingRect.height - 20 - titleHeight - 10;
12736
- const drawWidth = boundingRect.width - 30 * 2;
12793
+ const titleHeight = title ? GAUGE_TITLE_SECTION_HEIGHT : 0;
12794
+ const drawHeight = boundingRect.height - GAUGE_PADDING_BOTTOM - titleHeight - GAUGE_PADDING_TOP;
12795
+ const drawWidth = boundingRect.width - GAUGE_PADDING_SIDE * 2;
12737
12796
  let gaugeWidth;
12738
12797
  let gaugeHeight;
12739
12798
  if (drawWidth > 2 * drawHeight) {
@@ -12744,8 +12803,8 @@ function getGaugeRect(boundingRect, title) {
12744
12803
  gaugeHeight = drawWidth / 2;
12745
12804
  }
12746
12805
  return {
12747
- x: 30 + (drawWidth - gaugeWidth) / 2,
12748
- y: titleHeight + 10 + (drawHeight - gaugeHeight) / 2,
12806
+ x: GAUGE_PADDING_SIDE + (drawWidth - gaugeWidth) / 2,
12807
+ y: titleHeight + GAUGE_PADDING_TOP + (drawHeight - gaugeHeight) / 2,
12749
12808
  width: gaugeWidth,
12750
12809
  height: gaugeHeight
12751
12810
  };
@@ -12762,20 +12821,20 @@ function getInflectionValues(runtime, gaugeRect, textColor, ctx) {
12762
12821
  x: gaugeRect.x + gaugeRect.width / 2,
12763
12822
  y: gaugeRect.y + gaugeRect.height
12764
12823
  };
12765
- const textStyle = { fontSize: 12 };
12824
+ const textStyle = { fontSize: GAUGE_LABELS_FONT_SIZE };
12766
12825
  const inflectionValues = [];
12767
12826
  const inflectionValuesTextRects = [];
12768
12827
  for (const inflectionValue of runtime.inflectionValues) {
12769
12828
  const percentage = (inflectionValue.value - minValue.value) / (maxValue.value - minValue.value);
12770
12829
  const labelWidth = computeTextWidth(ctx, inflectionValue.label, textStyle, "px");
12771
12830
  const angle = Math.PI - Math.PI * percentage;
12772
- const textRect = getRectangleTangentToCircle(angle, gaugeRect.height + GAUGE_INFLECTION_LABEL_BOTTOM_MARGIN, gaugeCircleCenter.x, gaugeCircleCenter.y, labelWidth + 2, 12);
12773
- const offset = inflectionValuesTextRects.some((rect) => doRectanglesIntersect(rect, textRect)) ? 12 : 0;
12831
+ const textRect = getRectangleTangentToCircle(angle, gaugeRect.height + GAUGE_INFLECTION_LABEL_BOTTOM_MARGIN, gaugeCircleCenter.x, gaugeCircleCenter.y, labelWidth + 2, GAUGE_LABELS_FONT_SIZE);
12832
+ const offset = inflectionValuesTextRects.some((rect) => doRectanglesIntersect(rect, textRect)) ? GAUGE_LABELS_FONT_SIZE : 0;
12774
12833
  inflectionValuesTextRects.push(textRect);
12775
12834
  inflectionValues.push({
12776
12835
  rotation: angle,
12777
12836
  label: inflectionValue.label,
12778
- fontSize: 12,
12837
+ fontSize: GAUGE_LABELS_FONT_SIZE,
12779
12838
  color: textColor,
12780
12839
  offset
12781
12840
  });
@@ -13387,7 +13446,7 @@ function getElementMargins(el) {
13387
13446
 
13388
13447
  //#endregion
13389
13448
  //#region src/components/figures/chart/chartJs/zoomable_chart/zoomable_chart_store.ts
13390
- const TREND_LINE_AXES_IDS = ["x1", MOVING_AVERAGE_TREND_LINE_XAXIS_ID];
13449
+ const TREND_LINE_AXES_IDS = [TREND_LINE_XAXIS_ID, MOVING_AVERAGE_TREND_LINE_XAXIS_ID];
13391
13450
  const ZOOMABLE_AXIS_IDS = ["x", ...TREND_LINE_AXES_IDS];
13392
13451
  var ZoomableChartStore = class extends SpreadsheetStore {
13393
13452
  mutators = [
@@ -13503,7 +13562,7 @@ var ZoomableChartJsComponent = class extends ChartJsComponent {
13503
13562
  this.removeEventListeners();
13504
13563
  }
13505
13564
  get containerStyle() {
13506
- return cssPropertiesToCss({ height: this.sliceable ? `calc(100% - ${60}px)` : "100%" });
13565
+ return cssPropertiesToCss({ height: this.sliceable ? `calc(100% - ${MASTER_CHART_HEIGHT}px)` : "100%" });
13507
13566
  }
13508
13567
  get masterChartContainerStyle() {
13509
13568
  const runtime = this.env.model.getters.getChartRuntime(this.props.chartId);
@@ -13654,7 +13713,7 @@ var ZoomableChartJsComponent = class extends ChartJsComponent {
13654
13713
  updateTrendingLineAxes() {
13655
13714
  this.store.updateTrendLineConfiguration(this.chartId);
13656
13715
  const limits = this.store.currentAxesLimits[this.chartId];
13657
- for (const axisId of ["x1", MOVING_AVERAGE_TREND_LINE_XAXIS_ID]) {
13716
+ for (const axisId of [TREND_LINE_XAXIS_ID, MOVING_AVERAGE_TREND_LINE_XAXIS_ID]) {
13658
13717
  if (!this.chart?.config?.options?.scales?.[axisId] || !limits?.[axisId]) continue;
13659
13718
  this.chart.config.options.scales[axisId].min = limits[axisId].min;
13660
13719
  this.chart.config.options.scales[axisId].max = limits[axisId].max;
@@ -14837,7 +14896,7 @@ var MenuPopover = class MenuPopover extends Component {
14837
14896
  onClickMenu: this.onClickMenu.bind(this),
14838
14897
  onMouseEnter: this.onMenuItemMouseEnter.bind(this),
14839
14898
  onMouseLeave: this.onMouseLeave.bind(this),
14840
- width: this.props.width || 250,
14899
+ width: this.props.width || MENU_WIDTH,
14841
14900
  onScroll: this.onScroll.bind(this),
14842
14901
  onKeyDown: this.onKeydown.bind(this),
14843
14902
  hoveredMenuId,
@@ -14856,11 +14915,11 @@ var MenuPopover = class MenuPopover extends Component {
14856
14915
  anchorRect: {
14857
14916
  x: this.props.anchorRect.x,
14858
14917
  y: this.props.anchorRect.y,
14859
- width: isRoot ? this.props.anchorRect.width : this.props.width || 250,
14860
- height: isRoot ? this.props.anchorRect.height : 26
14918
+ width: isRoot ? this.props.anchorRect.width : this.props.width || MENU_WIDTH,
14919
+ height: isRoot ? this.props.anchorRect.height : DESKTOP_MENU_ITEM_HEIGHT
14861
14920
  },
14862
14921
  positioning: this.props.popoverPositioning,
14863
- verticalOffset: isRoot ? 0 : 6,
14922
+ verticalOffset: isRoot ? 0 : MENU_VERTICAL_PADDING,
14864
14923
  onPopoverHidden: () => this.closeSubMenu(),
14865
14924
  onPopoverMoved: () => this.closeSubMenu(),
14866
14925
  maxHeight: this.props.maxHeight
@@ -14917,8 +14976,8 @@ var MenuPopover = class MenuPopover extends Component {
14917
14976
  this.subMenu.anchorRect = {
14918
14977
  x: getElBoundingRect(this.menuRef()).x,
14919
14978
  y: y - (this.subMenu.scrollOffset || 0),
14920
- width: this.props.width || 250,
14921
- height: 26
14979
+ width: this.props.width || MENU_WIDTH,
14980
+ height: DESKTOP_MENU_ITEM_HEIGHT
14922
14981
  };
14923
14982
  this.subMenu.menuItems = menu.children(this.env);
14924
14983
  this.subMenu.isOpen = true;
@@ -17022,7 +17081,7 @@ function extractStyle(data, content, styleId, formatId, borderId) {
17022
17081
  alignment: {
17023
17082
  horizontal: style.align === "default" ? void 0 : style.align,
17024
17083
  vertical: style.verticalAlign ? V_ALIGNMENT_EXPORT_CONVERSION_MAP[style.verticalAlign] : void 0,
17025
- wrapText: style.wrapping === "wrap" || content?.includes("\n") ? true : void 0,
17084
+ wrapText: style.wrapping === "wrap" || content?.includes(NEWLINE) ? true : void 0,
17026
17085
  textRotation: style.rotation ? rotationToXLSX(style.rotation) : void 0,
17027
17086
  shrinkToFit: style.wrapping === "clip" ? true : void 0
17028
17087
  }
@@ -17063,7 +17122,7 @@ function normalizeStyle(construct, styles) {
17063
17122
  function convertFormat(format, numFmtStructure) {
17064
17123
  if (!format) return 0;
17065
17124
  let formatId = XLSX_FORMAT_MAP[format.format];
17066
- if (!formatId) formatId = pushElement(format, numFmtStructure) + 164;
17125
+ if (!formatId) formatId = pushElement(format, numFmtStructure) + FIRST_NUMFMT_ID;
17067
17126
  return formatId;
17068
17127
  }
17069
17128
  /**
@@ -17324,7 +17383,7 @@ function getCaretDownSvg(color) {
17324
17383
  width: 512,
17325
17384
  height: 512,
17326
17385
  paths: [{
17327
- fillColor: color.textColor || "#374151C2",
17386
+ fillColor: color.textColor || TEXT_BODY_MUTED,
17328
17387
  path: CARET_DOWN_PATH
17329
17388
  }]
17330
17389
  };
@@ -17335,7 +17394,7 @@ function getCaretUpSvg(color) {
17335
17394
  width: 512,
17336
17395
  height: 512,
17337
17396
  paths: [{
17338
- fillColor: color.textColor || "#374151C2",
17397
+ fillColor: color.textColor || TEXT_BODY_MUTED,
17339
17398
  path: CARET_UP_PATH
17340
17399
  }]
17341
17400
  };
@@ -17346,7 +17405,7 @@ function getHoveredCaretDownSvg(color) {
17346
17405
  width: 512,
17347
17406
  height: 512,
17348
17407
  paths: [{
17349
- fillColor: color.textColor || "#374151C2",
17408
+ fillColor: color.textColor || TEXT_BODY_MUTED,
17350
17409
  path: HOVERED_CARET_DOWN_PATH
17351
17410
  }, {
17352
17411
  fillColor: color.fillColor || "#fff",
@@ -18240,14 +18299,14 @@ function convertExcelTrendline(trend) {
18240
18299
  type: trend.type === "linear" ? "polynomial" : EXCEL_TO_SPREADSHEET_TRENDLINE_TYPE_MAPPING[trend.type],
18241
18300
  order: trend.type === "linear" ? 1 : trend.order,
18242
18301
  color: trend.color,
18243
- window: trend.window || 2,
18302
+ window: trend.window || DEFAULT_WINDOW_SIZE,
18244
18303
  display: true
18245
18304
  };
18246
18305
  }
18247
18306
  function convertAnchor(XLSXanchor) {
18248
18307
  const offset = {
18249
- x: convertEMUToDotValue(XLSXanchor.colOffset) - 1,
18250
- y: convertEMUToDotValue(XLSXanchor.rowOffset) - 1
18308
+ x: convertEMUToDotValue(XLSXanchor.colOffset) - FIGURE_BORDER_WIDTH,
18309
+ y: convertEMUToDotValue(XLSXanchor.rowOffset) - FIGURE_BORDER_WIDTH
18251
18310
  };
18252
18311
  return {
18253
18312
  col: XLSXanchor.col,
@@ -18520,8 +18579,8 @@ function getSheetDims(sheet) {
18520
18579
  dims[0] = Math.max(dims[0], fig.anchors[fig.anchors.length - 1]?.col ?? 0);
18521
18580
  dims[1] = Math.max(dims[1], fig.anchors[fig.anchors.length - 1]?.row ?? 0);
18522
18581
  }
18523
- dims[0] = Math.max(dims[0] + 5, 30);
18524
- dims[1] = Math.max(dims[1] + 5, 100);
18582
+ dims[0] = Math.max(dims[0] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_COLS);
18583
+ dims[1] = Math.max(dims[1] + 5, EXCEL_IMPORT_DEFAULT_NUMBER_OF_ROWS);
18525
18584
  return dims;
18526
18585
  }
18527
18586
  /**
@@ -19705,7 +19764,7 @@ var XlsxBaseExtractor = class {
19705
19764
  rgb = this.getThemeColor(themeIndex, theme.clrScheme);
19706
19765
  } else {
19707
19766
  rgb = this.extractAttr(colorElement, "rgb")?.asString();
19708
- rgb = rgb === "FF000000" ? void 0 : rgb;
19767
+ rgb = rgb === DEFAULT_SYSTEM_COLOR ? void 0 : rgb;
19709
19768
  }
19710
19769
  return {
19711
19770
  rgb: rgb || defaultColor,
@@ -20967,7 +21026,7 @@ function getPathsOfContent(contentType, xmls) {
20967
21026
  * Get the corresponding relationship file for a given xml file in a XLSX directory.
20968
21027
  */
20969
21028
  function getRelationFile(file, xmls) {
20970
- if (file === "[Content_Types].xml") return "_rels/.rels";
21029
+ if (file === CONTENT_TYPES_FILE) return "_rels/.rels";
20971
21030
  let relsFile = "";
20972
21031
  const pathParts = file.split("/");
20973
21032
  for (let i = 0; i < pathParts.length - 1; i++) relsFile += pathParts[i] + "/";
@@ -21412,7 +21471,7 @@ function predictLinearValues(Y, X, newX, computeIntercept) {
21412
21471
  });
21413
21472
  return newY.length === newX.length ? newY : transposeMatrix(newY);
21414
21473
  }
21415
- function getMovingAverageValues(dataset, labels, windowSize = 2) {
21474
+ function getMovingAverageValues(dataset, labels, windowSize = DEFAULT_WINDOW_SIZE) {
21416
21475
  const values = [];
21417
21476
  for (let i = 0; i < windowSize - 1; i++) values.push({
21418
21477
  x: labels[i],
@@ -22094,7 +22153,7 @@ function normalizeV9(formula) {
22094
22153
  if (token.type === "REFERENCE" && cellReference.test(token.value)) {
22095
22154
  const value = token.value.trim();
22096
22155
  if (!dependencies.includes(value)) dependencies.push(value);
22097
- return `${"|"}${dependencies.indexOf(value)}${"|"}`;
22156
+ return `${FORMULA_REF_IDENTIFIER}${dependencies.indexOf(value)}${FORMULA_REF_IDENTIFIER}`;
22098
22157
  } else return token.value;
22099
22158
  })),
22100
22159
  dependencies
@@ -22290,7 +22349,7 @@ migrationStepRegistry.add("0.1", { migrate(data) {
22290
22349
  if (cell.formula) {
22291
22350
  let { text, dependencies } = cell.formula;
22292
22351
  for (const [index, d] of Object.entries(dependencies)) {
22293
- const stringPosition = `\\${"|"}${index}\\${"|"}`;
22352
+ const stringPosition = `\\${FORMULA_REF_IDENTIFIER}${index}\\${FORMULA_REF_IDENTIFIER}`;
22294
22353
  text = text.replace(new RegExp(stringPosition, "g"), d);
22295
22354
  }
22296
22355
  cell.content = text;
@@ -23847,8 +23906,8 @@ const CREATE_CHART = (env) => {
23847
23906
  zones = getters.getSelectedZones();
23848
23907
  }
23849
23908
  const size = {
23850
- width: 536,
23851
- height: 335
23909
+ width: DEFAULT_FIGURE_WIDTH,
23910
+ height: DEFAULT_FIGURE_HEIGHT
23852
23911
  };
23853
23912
  const { col, row, offset } = centerFigurePosition(getters, size);
23854
23913
  if (env.model.dispatch("CREATE_CHART", {
@@ -23870,8 +23929,8 @@ const CREATE_CAROUSEL = (env) => {
23870
23929
  const figureId = UuidGenerator.smallUuid();
23871
23930
  const sheetId = getters.getActiveSheetId();
23872
23931
  const size = {
23873
- width: 536,
23874
- height: 335
23932
+ width: DEFAULT_FIGURE_WIDTH,
23933
+ height: DEFAULT_FIGURE_HEIGHT
23875
23934
  };
23876
23935
  const { col, row, offset } = centerFigurePosition(getters, size);
23877
23936
  if (env.model.dispatch("CREATE_CAROUSEL", {
@@ -23921,7 +23980,7 @@ const REINSERT_STATIC_PIVOT_CHILDREN = (env) => env.model.getters.getPivotIds().
23921
23980
  execute: (env) => {
23922
23981
  const zone = env.model.getters.getSelectedZone();
23923
23982
  const table = env.model.getters.getPivot(pivotId).getExpandedTableStructure();
23924
- if (table.numberOfCells > 5e5) {
23983
+ if (table.numberOfCells > PIVOT_MAX_NUMBER_OF_CELLS) {
23925
23984
  env.notifyUser({
23926
23985
  type: "warning",
23927
23986
  text: getPivotTooBigErrorMessage(table.numberOfCells, env.model.getters.getLocale()),
@@ -24889,7 +24948,7 @@ var ColorPicker = class extends Component {
24889
24948
  }
24890
24949
  get sliderStyle() {
24891
24950
  const hue = this.state.currentHslaColor?.h || 0;
24892
- return cssPropertiesToCss({ "margin-left": `${clip(Math.round(hue / 360 * INNER_GRADIENT_WIDTH), 1, INNER_GRADIENT_WIDTH) - 18 / 2}px` });
24951
+ return cssPropertiesToCss({ "margin-left": `${clip(Math.round(hue / 360 * INNER_GRADIENT_WIDTH), 1, INNER_GRADIENT_WIDTH) - ICON_EDGE_LENGTH / 2}px` });
24893
24952
  }
24894
24953
  get pointerStyle() {
24895
24954
  const { s, l } = this.state.currentHslaColor || {
@@ -25056,6 +25115,11 @@ var NumberEditor = class extends Component {
25056
25115
  rootEditorRef = (0, _odoo_owl.signal)(null);
25057
25116
  valueListRef = (0, _odoo_owl.signal)(null);
25058
25117
  DOMFocusableElementStore;
25118
+ /**
25119
+ * Skips the change event triggered when moving focus out of the input.
25120
+ * The value has already been committed by `onInputKeydown`.
25121
+ */
25122
+ skipNextInputChange = false;
25059
25123
  setup() {
25060
25124
  this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
25061
25125
  useExternalListener(window, "click", this.onExternalClick, { capture: true });
@@ -25090,11 +25154,14 @@ var NumberEditor = class extends Component {
25090
25154
  this.dropdown.isOpen = false;
25091
25155
  }
25092
25156
  setValue(valueStr) {
25093
- const value = clip(Math.floor(parseFloat(valueStr)), this.props.min, this.props.max);
25157
+ const value = clip(Math.round(parseFloat(valueStr)), this.props.min, this.props.max);
25158
+ if (isNaN(value)) return;
25094
25159
  this.props.onValueChange(value);
25095
25160
  this.closeList();
25161
+ return value;
25096
25162
  }
25097
25163
  setValueFromInput(ev) {
25164
+ if (this.skipNextInputChange) return;
25098
25165
  this.setValue(ev.target.value);
25099
25166
  }
25100
25167
  setValueFromList(valueStr) {
@@ -25108,19 +25175,26 @@ var NumberEditor = class extends Component {
25108
25175
  ev.target.select();
25109
25176
  }
25110
25177
  onInputKeydown(ev) {
25111
- if (ev.key === "Enter" || ev.key === "Escape") {
25112
- this.closeList();
25113
- const target = ev.target;
25114
- if (ev.key === "Escape") target.value = `${this.props.currentValue}`;
25115
- this.props.onToggle?.();
25116
- }
25117
- if (ev.key === "Tab") {
25118
- ev.preventDefault();
25119
- ev.stopPropagation();
25120
- this.closeList();
25121
- this.DOMFocusableElementStore.focus();
25122
- return;
25178
+ const target = ev.target;
25179
+ switch (ev.key) {
25180
+ case "Enter":
25181
+ case "Tab": {
25182
+ ev.preventDefault();
25183
+ ev.stopPropagation();
25184
+ const value = this.setValue(target.value);
25185
+ if (value === void 0) return;
25186
+ target.value = `${value}`;
25187
+ break;
25188
+ }
25189
+ case "Escape":
25190
+ target.value = `${this.props.currentValue}`;
25191
+ this.closeList();
25192
+ break;
25193
+ default: return;
25123
25194
  }
25195
+ this.skipNextInputChange = true;
25196
+ this.DOMFocusableElementStore.focus();
25197
+ this.skipNextInputChange = false;
25124
25198
  }
25125
25199
  };
25126
25200
 
@@ -25685,7 +25759,7 @@ function isNavigablePosition(getters, position) {
25685
25759
  function drawHighlight(renderingContext, highlight, rect) {
25686
25760
  const { x, y, width, height } = rect;
25687
25761
  if (width < 0 || height < 0) return;
25688
- const color = highlight.color || "#017E84";
25762
+ const color = highlight.color || HIGHLIGHT_COLOR$1;
25689
25763
  const { ctx } = renderingContext;
25690
25764
  ctx.save();
25691
25765
  if (!highlight.noBorder) {
@@ -26623,7 +26697,7 @@ var AxisDesignEditor = class extends Component {
26623
26697
  axesList: types.ArrayOf()
26624
26698
  });
26625
26699
  state = (0, _odoo_owl.proxy)({ currentAxis: "x" });
26626
- defaultFontSize = 12;
26700
+ defaultFontSize = CHART_AXIS_TITLE_FONT_SIZE;
26627
26701
  get axisTitleStyle() {
26628
26702
  return this.props.definition.axesDesign?.[this.state.currentAxis]?.title ?? {};
26629
26703
  }
@@ -26854,7 +26928,7 @@ var GeneralDesignEditor = class extends Component {
26854
26928
  definition: types.ChartDefinition(),
26855
26929
  canUpdateChart: types.function(),
26856
26930
  updateChart: types.function(),
26857
- defaultChartTitleFontSize: types.number().optional(16)
26931
+ defaultChartTitleFontSize: types.number().optional(CHART_TITLE_FONT_SIZE)
26858
26932
  });
26859
26933
  state;
26860
26934
  setup() {
@@ -27122,11 +27196,11 @@ var SeriesWithAxisDesignEditor = class extends Component {
27122
27196
  return Math.min(10, runtime.chartJsConfig.data.datasets[index].data.length - 1);
27123
27197
  }
27124
27198
  get defaultWindowSize() {
27125
- return 2;
27199
+ return DEFAULT_WINDOW_SIZE;
27126
27200
  }
27127
27201
  onChangeMovingAverageWindow(dataSetId, value) {
27128
- let window = parseInt(value) || 2;
27129
- if (window <= 1) window = 2;
27202
+ let window = parseInt(value) || DEFAULT_WINDOW_SIZE;
27203
+ if (window <= 1) window = DEFAULT_WINDOW_SIZE;
27130
27204
  this.updateTrendLineValue(dataSetId, { window });
27131
27205
  }
27132
27206
  getDataSeriesColor(dataSetId) {
@@ -28265,19 +28339,19 @@ function getTopPaddingForDashboard(definition, getters) {
28265
28339
  //#region src/helpers/figures/charts/runtime/chartjs_layout.ts
28266
28340
  function getChartLayout(definition, args) {
28267
28341
  return { padding: {
28268
- left: 20,
28269
- right: 20,
28270
- top: Math.max(15, args.topPadding || 0),
28271
- bottom: 10
28342
+ left: CHART_PADDING,
28343
+ right: CHART_PADDING,
28344
+ top: Math.max(CHART_PADDING_TOP, args.topPadding || 0),
28345
+ bottom: CHART_PADDING_BOTTOM
28272
28346
  } };
28273
28347
  }
28274
28348
  function getCalendarChartLayout(definition, args) {
28275
28349
  const legendPosition = definition.legendPosition;
28276
28350
  return { padding: {
28277
- left: 20 + (legendPosition === "left" ? 70 : 0),
28278
- right: 20 + (legendPosition === "right" ? 70 : 0),
28279
- top: Math.max(15, args.topPadding || 0),
28280
- bottom: 10
28351
+ left: CHART_PADDING + (legendPosition === "left" ? CHART_COLORSCALE_WIDTH : 0),
28352
+ right: CHART_PADDING + (legendPosition === "right" ? CHART_COLORSCALE_WIDTH : 0),
28353
+ top: Math.max(CHART_PADDING_TOP, args.topPadding || 0),
28354
+ bottom: CHART_PADDING_BOTTOM
28281
28355
  } };
28282
28356
  }
28283
28357
 
@@ -28479,9 +28553,9 @@ function getComboChartLegend(definition, args) {
28479
28553
  }
28480
28554
  function getWaterfallChartLegend(definition, args) {
28481
28555
  const fontColor = chartFontColor(definition.background);
28482
- const negativeColor = definition.negativeValuesColor || "#EA6175";
28483
- const positiveColor = definition.positiveValuesColor || "#4EA7F2";
28484
- const subTotalColor = definition.subTotalValuesColor || "#AAAAAA";
28556
+ const negativeColor = definition.negativeValuesColor || CHART_WATERFALL_NEGATIVE_COLOR;
28557
+ const positiveColor = definition.positiveValuesColor || CHART_WATERFALL_POSITIVE_COLOR;
28558
+ const subTotalColor = definition.subTotalValuesColor || CHART_WATERFALL_SUBTOTAL_COLOR;
28485
28559
  return {
28486
28560
  ...getLegendDisplayOptions(definition),
28487
28561
  labels: {
@@ -28807,11 +28881,11 @@ function getChartTitle({ title, legendPosition, background }, getters) {
28807
28881
  color: title?.color ?? fontColor,
28808
28882
  align: title.align === "center" ? "center" : title.align === "right" ? "end" : "start",
28809
28883
  font: {
28810
- size: title.fontSize ?? 16,
28884
+ size: title.fontSize ?? CHART_TITLE_FONT_SIZE,
28811
28885
  weight: title.bold ? "bold" : "normal",
28812
28886
  style: title.italic ? "italic" : "normal"
28813
28887
  },
28814
- padding: { bottom: legendPosition === "top" ? 0 : 20 }
28888
+ padding: { bottom: legendPosition === "top" ? 0 : CHART_PADDING }
28815
28889
  };
28816
28890
  }
28817
28891
 
@@ -29226,7 +29300,7 @@ const BarChart = {
29226
29300
  getDefinitionForExcel(getters, definition, { dataSets, labelRange }) {
29227
29301
  return {
29228
29302
  ...definition,
29229
- backgroundColor: toXlsxHexColor(definition.background || "#FFFFFF"),
29303
+ backgroundColor: toXlsxHexColor(definition.background || DEFAULT_CHART_BACKGROUND_COLOR),
29230
29304
  fontColor: toXlsxHexColor(chartFontColor(definition.background)),
29231
29305
  dataSets,
29232
29306
  labelRange,
@@ -29589,7 +29663,7 @@ const LineChart = {
29589
29663
  getDefinitionForExcel(getters, definition, { dataSets, labelRange }) {
29590
29664
  return {
29591
29665
  ...definition,
29592
- backgroundColor: toXlsxHexColor(definition.background || "#FFFFFF"),
29666
+ backgroundColor: toXlsxHexColor(definition.background || DEFAULT_CHART_BACKGROUND_COLOR),
29593
29667
  fontColor: toXlsxHexColor(chartFontColor(definition.background)),
29594
29668
  dataSets,
29595
29669
  labelRange,
@@ -29671,7 +29745,7 @@ const PieChart = {
29671
29745
  getDefinitionForExcel(getters, definition, { dataSets, labelRange }) {
29672
29746
  return {
29673
29747
  ...definition,
29674
- backgroundColor: toXlsxHexColor(definition.background || "#FFFFFF"),
29748
+ backgroundColor: toXlsxHexColor(definition.background || DEFAULT_CHART_BACKGROUND_COLOR),
29675
29749
  fontColor: toXlsxHexColor(chartFontColor(definition.background)),
29676
29750
  dataSets,
29677
29751
  labelRange
@@ -29793,7 +29867,7 @@ var helpers_index_exports$1 = /* @__PURE__ */ __exportAll({
29793
29867
  PieChart: () => PieChart,
29794
29868
  SPREADSHEET_TO_EXCEL_TRENDLINE_TYPE_MAPPING: () => SPREADSHEET_TO_EXCEL_TRENDLINE_TYPE_MAPPING,
29795
29869
  ScorecardChart: () => ScorecardChart$1,
29796
- TREND_LINE_XAXIS_ID: () => "x1",
29870
+ TREND_LINE_XAXIS_ID: () => TREND_LINE_XAXIS_ID,
29797
29871
  WaterfallChart: () => WaterfallChart,
29798
29872
  adaptChartRange: () => adaptChartRange,
29799
29873
  chartFontColor: () => chartFontColor,
@@ -30671,12 +30745,12 @@ var ContentEditableHelper = class {
30671
30745
  for (let current = it.next(); !current.done; current = it.next()) {
30672
30746
  if (current.value.nodeName === "P" || current.value.nodeName === "DIV" && current.value !== this.el) {
30673
30747
  if (isFirstParagraph) isFirstParagraph = false;
30674
- else text += "\n";
30748
+ else text += NEWLINE;
30675
30749
  emptyParagraph = isEmptyParagraph(current.value);
30676
30750
  continue;
30677
30751
  }
30678
30752
  if (!current.value.hasChildNodes()) {
30679
- if (current.value.nodeName === "BR" && !emptyParagraph) text += "\n";
30753
+ if (current.value.nodeName === "BR" && !emptyParagraph) text += NEWLINE;
30680
30754
  text += current.value.textContent;
30681
30755
  }
30682
30756
  }
@@ -30870,7 +30944,7 @@ var Composer = class extends Component {
30870
30944
  if (cellX + ASSISTANT_WIDTH > this.props.delimitation.width) assistantStyle.right = `0px`;
30871
30945
  } else {
30872
30946
  assistantStyle["max-height"] = `${this.spreadsheetRect.height - composerRect.bottom - 1}px`;
30873
- if (composerRect.left + ASSISTANT_WIDTH + 15 + CLOSE_ICON_RADIUS > this.spreadsheetRect.width) assistantStyle.right = `${CLOSE_ICON_RADIUS}px`;
30947
+ if (composerRect.left + ASSISTANT_WIDTH + SCROLLBAR_WIDTH + CLOSE_ICON_RADIUS > this.spreadsheetRect.width) assistantStyle.right = `${CLOSE_ICON_RADIUS}px`;
30874
30948
  }
30875
30949
  return assistantStyle;
30876
30950
  }
@@ -30968,7 +31042,7 @@ var Composer = class extends Component {
30968
31042
  const start = Math.min(selection.start, selection.end);
30969
31043
  const end = Math.max(selection.start, selection.end);
30970
31044
  this.props.composerStore.stopComposerRangeSelection();
30971
- this.props.composerStore.setCurrentContent(content.slice(0, start) + "\n" + content.slice(end), {
31045
+ this.props.composerStore.setCurrentContent(content.slice(0, start) + NEWLINE + content.slice(end), {
30972
31046
  start: start + 1,
30973
31047
  end: start + 1
30974
31048
  });
@@ -31147,7 +31221,7 @@ var Composer = class extends Component {
31147
31221
  const { end, start } = this.props.composerStore.composerSelection;
31148
31222
  for (let index = 0; index < tokens.length; index++) {
31149
31223
  const token = tokens[index];
31150
- let color = token.color || "light-dark(#000000, #ffffff)";
31224
+ let color = token.color || DEFAULT_TOKEN_COLOR;
31151
31225
  if (token.isBlurred) color = setColorAlpha(color, .5);
31152
31226
  const classes = [];
31153
31227
  if (token.type === "REFERENCE" && this.props.composerStore.tokenAtCursor === token && this.props.composerStore.editionMode === "selecting") classes.push("text-decoration-underline");
@@ -31178,8 +31252,8 @@ var Composer = class extends Component {
31178
31252
  splitHtmlContentIntoLines(contents) {
31179
31253
  const contentSplitInLines = [];
31180
31254
  let currentLine = [];
31181
- for (const content of contents) if (content.value.includes("\n")) {
31182
- const lines = content.value.split("\n");
31255
+ for (const content of contents) if (content.value.includes(NEWLINE)) {
31256
+ const lines = content.value.split(NEWLINE);
31183
31257
  const lastLine = lines.pop();
31184
31258
  for (const line of lines) {
31185
31259
  currentLine.push({
@@ -32077,11 +32151,11 @@ var AbstractComposerStore = class extends SpreadsheetStore {
32077
32151
  getTokenColor(token) {
32078
32152
  if (token.type === "REFERENCE") {
32079
32153
  const { xc, sheetName } = splitReference(token.value);
32080
- return this.rangeXCColor(xc, sheetName) || "light-dark(#000000, #ffffff)";
32154
+ return this.rangeXCColor(xc, sheetName) || DEFAULT_TOKEN_COLOR;
32081
32155
  }
32082
32156
  if (token.type === "SYMBOL") {
32083
32157
  const namedRange = this.getters.getNamedRange(token.value);
32084
- if (namedRange) return this.rangeColor(namedRange.range) || "light-dark(#000000, #ffffff)";
32158
+ if (namedRange) return this.rangeColor(namedRange.range) || DEFAULT_TOKEN_COLOR;
32085
32159
  const upperCaseValue = token.value.toUpperCase();
32086
32160
  if (upperCaseValue === "TRUE" || upperCaseValue === "FALSE") return tokenColors.NUMBER;
32087
32161
  if (upperCaseValue in functionRegistry.content) return tokenColors.FUNCTION;
@@ -32089,7 +32163,7 @@ var AbstractComposerStore = class extends SpreadsheetStore {
32089
32163
  if (["LEFT_PAREN", "RIGHT_PAREN"].includes(token.type)) {
32090
32164
  if (token.parenthesesCode === "") return tokenColors.ORPHAN_RIGHT_PAREN;
32091
32165
  }
32092
- return tokenColors[token.type] || "light-dark(#000000, #ffffff)";
32166
+ return tokenColors[token.type] || DEFAULT_TOKEN_COLOR;
32093
32167
  }
32094
32168
  rangeXCColor(xc, sheetName) {
32095
32169
  const refSheet = sheetName ? this.model.getters.getSheetIdByName(sheetName) : this.sheetId;
@@ -32808,7 +32882,7 @@ var PieChartDesignPanel = class extends Component {
32808
32882
  });
32809
32883
  }
32810
32884
  get defaultHoleSize() {
32811
- return 50;
32885
+ return DEFAULT_DOUGHNUT_CHART_HOLE_SIZE;
32812
32886
  }
32813
32887
  updateEditedValues(selectedIndex) {
32814
32888
  this.state.index = parseInt(selectedIndex);
@@ -32980,7 +33054,7 @@ var ScorecardChartDesignPanel = class extends Component {
32980
33054
  return this.props.definition.baselineMode === "progress" ? _t("Progress bar colors") : _t("Baseline colors");
32981
33055
  }
32982
33056
  get defaultScorecardTitleFontSize() {
32983
- return 14;
33057
+ return SCORECARD_CHART_TITLE_FONT_SIZE;
32984
33058
  }
32985
33059
  translate(term) {
32986
33060
  return this.env.model.getters.dynamicTranslate(term);
@@ -33001,14 +33075,14 @@ var ScorecardChartDesignPanel = class extends Component {
33001
33075
  get keyStyle() {
33002
33076
  return {
33003
33077
  align: "center",
33004
- fontSize: 32,
33078
+ fontSize: DEFAULT_SCORECARD_KEY_VALUE_FONT_SIZE,
33005
33079
  ...this.props.definition.keyDescr
33006
33080
  };
33007
33081
  }
33008
33082
  get baselineStyle() {
33009
33083
  return {
33010
33084
  align: "center",
33011
- fontSize: 16,
33085
+ fontSize: DEFAULT_SCORECARD_BASELINE_FONT_SIZE,
33012
33086
  ...this.props.definition.baselineDescr
33013
33087
  };
33014
33088
  }
@@ -33251,13 +33325,13 @@ var WaterfallChartDesignPanel = class extends Component {
33251
33325
  }];
33252
33326
  }
33253
33327
  get positiveValuesColor() {
33254
- return this.props.definition.positiveValuesColor || "#4EA7F2";
33328
+ return this.props.definition.positiveValuesColor || CHART_WATERFALL_POSITIVE_COLOR;
33255
33329
  }
33256
33330
  get negativeValuesColor() {
33257
- return this.props.definition.negativeValuesColor || "#EA6175";
33331
+ return this.props.definition.negativeValuesColor || CHART_WATERFALL_NEGATIVE_COLOR;
33258
33332
  }
33259
33333
  get subTotalValuesColor() {
33260
- return this.props.definition.subTotalValuesColor || "#AAAAAA";
33334
+ return this.props.definition.subTotalValuesColor || CHART_WATERFALL_SUBTOTAL_COLOR;
33261
33335
  }
33262
33336
  updateVerticalAxisPosition(value) {
33263
33337
  this.props.updateChart(this.props.chartId, { verticalAxisPosition: value });
@@ -35598,7 +35672,7 @@ var ConditionalFormattingEditorStore = class extends SpreadsheetStore {
35598
35672
  get previewGradient() {
35599
35673
  const rule = this.state.rules.colorScale;
35600
35674
  const minColor = colorNumberToHex(rule.minimum.color);
35601
- const midColor = colorNumberToHex(rule.midpoint?.color || 11982760);
35675
+ const midColor = colorNumberToHex(rule.midpoint?.color || DEFAULT_COLOR_SCALE_MIDPOINT_COLOR);
35602
35676
  const maxColor = colorNumberToHex(rule.maximum.color);
35603
35677
  const baseString = "linear-gradient(to right, ";
35604
35678
  return cssPropertiesToCss({
@@ -37874,7 +37948,7 @@ var PivotMeasureDisplayPanelStore = class extends SpreadsheetStore {
37874
37948
  return {
37875
37949
  type: measureDisplayType,
37876
37950
  fieldNameWithGranularity,
37877
- value: value ?? "(previous)"
37951
+ value: value ?? PREVIOUS_VALUE
37878
37952
  };
37879
37953
  }
37880
37954
  }
@@ -39378,6 +39452,117 @@ function isValueFiltered(getters, sheetId, data, filter, preComputedCriterion) {
39378
39452
  return false;
39379
39453
  }
39380
39454
 
39455
+ //#endregion
39456
+ //#region src/helpers/pivot/spreadsheet_pivot/data_entries_index_spreadsheet_pivot.ts
39457
+ const EMPTY_DATA_ENTRIES = [];
39458
+ /**
39459
+ * Index of the data entries of a spreadsheet pivot, used to retrieve the
39460
+ * entries matching a pivot domain without scanning all the entries.
39461
+ *
39462
+ * Starting with the row dimensions, one can descend either in the
39463
+ * next row dimension (`rowChildren`) or in the first column dimension
39464
+ * (`colChildren`).
39465
+ *
39466
+ * e.g. with the rows ["continent", "city"] and the columns ["team"]
39467
+ *
39468
+ * root -> all the entries
39469
+ * ├── (col) Team 1 -> [team=Team 1]
39470
+ * ├── (col) Team 2 -> [team=Team 2]
39471
+ * ├── (row) Europe -> [continent=Europe]
39472
+ * │ ├── (col) Team 1 -> [continent=Europe, team=Team 1]
39473
+ * │ ├── (row) Brussels -> [continent=Europe, city=Brussels]
39474
+ * │ │ └── (col) Team 1 -> [continent=Europe, city=Brussels, team=Team 1]
39475
+ * │ └── (row) Paris
39476
+ * │ └── ...
39477
+ * └── (row) North America
39478
+ * └── ...
39479
+ *
39480
+ * Each entry is inserted once per couple (row prefix, column prefix) it belongs
39481
+ * to, which is exactly the number of pivot cells it contributes to.
39482
+ */
39483
+ var PivotDataEntriesIndex = class {
39484
+ rowDimensions;
39485
+ colDimensions;
39486
+ root = createIndexNode();
39487
+ constructor(dataEntries, rowDimensions, colDimensions) {
39488
+ this.rowDimensions = rowDimensions;
39489
+ this.colDimensions = colDimensions;
39490
+ for (const entry of dataEntries) this.addEntry(entry);
39491
+ }
39492
+ /**
39493
+ * Get the data entries matching the given domain.
39494
+ */
39495
+ getDataEntries(domain) {
39496
+ const rowKeys = [];
39497
+ const colKeys = [];
39498
+ for (const domainNode of domain) {
39499
+ const rowDimension = this.rowDimensions[rowKeys.length];
39500
+ if (rowDimension?.nameWithGranularity === domainNode.field) {
39501
+ rowKeys.push(toGroupKey(domainNode.value, rowDimension));
39502
+ continue;
39503
+ }
39504
+ const colDimension = this.colDimensions[colKeys.length];
39505
+ if (colDimension?.nameWithGranularity !== domainNode.field) throw new EvaluationError(_t("Dimension %s does not exist", domainNode.field));
39506
+ colKeys.push(toGroupKey(domainNode.value, colDimension));
39507
+ }
39508
+ let node = this.root;
39509
+ for (const key of rowKeys) {
39510
+ node = node.rowChildren?.get(key);
39511
+ if (!node) return EMPTY_DATA_ENTRIES;
39512
+ }
39513
+ for (const key of colKeys) {
39514
+ node = node.colChildren?.get(key);
39515
+ if (!node) return EMPTY_DATA_ENTRIES;
39516
+ }
39517
+ return node.entries;
39518
+ }
39519
+ addEntry(entry) {
39520
+ let rowNode = this.root;
39521
+ this.addEntryToColumns(rowNode, entry);
39522
+ for (const dimension of this.rowDimensions) {
39523
+ rowNode = getOrCreateChild(rowNode, "rowChildren", getEntryGroupKey(entry, dimension));
39524
+ this.addEntryToColumns(rowNode, entry);
39525
+ }
39526
+ }
39527
+ /**
39528
+ * Add the entry to the given row node, and to each of its column prefixes.
39529
+ */
39530
+ addEntryToColumns(rowNode, entry) {
39531
+ rowNode.entries.push(entry);
39532
+ let node = rowNode;
39533
+ for (const dimension of this.colDimensions) {
39534
+ node = getOrCreateChild(node, "colChildren", getEntryGroupKey(entry, dimension));
39535
+ node.entries.push(entry);
39536
+ }
39537
+ }
39538
+ };
39539
+ function createIndexNode() {
39540
+ return {
39541
+ entries: [],
39542
+ rowChildren: void 0,
39543
+ colChildren: void 0
39544
+ };
39545
+ }
39546
+ function getOrCreateChild(node, axis, key) {
39547
+ let children = node[axis];
39548
+ if (!children) {
39549
+ children = /* @__PURE__ */ new Map();
39550
+ node[axis] = children;
39551
+ }
39552
+ let child = children.get(key);
39553
+ if (!child) {
39554
+ child = createIndexNode();
39555
+ children.set(key, child);
39556
+ }
39557
+ return child;
39558
+ }
39559
+ function getEntryGroupKey(entry, dimension) {
39560
+ return toGroupKey(entry[dimension.nameWithGranularity]?.value, dimension);
39561
+ }
39562
+ function toGroupKey(value, dimension) {
39563
+ return dimension.type === "char" ? String(value) : value;
39564
+ }
39565
+
39381
39566
  //#endregion
39382
39567
  //#region src/helpers/pivot/pivot_domain_helpers.ts
39383
39568
  function getDomainOfParentRow(pivot, domain) {
@@ -39483,7 +39668,7 @@ function getPreviousOrNextValueDomain(pivot, domain, fieldNameWithGranularity, d
39483
39668
  if (value === void 0) return;
39484
39669
  const valueIndex = values.indexOf(value);
39485
39670
  if (value === void 0 || valueIndex === -1) return;
39486
- return replaceFieldValueInDomain(domain, fieldNameWithGranularity, values[clip(valueIndex + (direction === "(previous)" ? -1 : 1), 0, values.length - 1)]);
39671
+ return replaceFieldValueInDomain(domain, fieldNameWithGranularity, values[clip(valueIndex + (direction === PREVIOUS_VALUE ? -1 : 1), 0, values.length - 1)]);
39487
39672
  }
39488
39673
  function domainToString(domain) {
39489
39674
  return domain ? domain.map(domainNodeToString).join(", ") : "";
@@ -40139,6 +40324,11 @@ var SpreadsheetPivot = class {
40139
40324
  */
40140
40325
  filteredDataEntries = [];
40141
40326
  /**
40327
+ * This index is used to retrieve the data entries matching a pivot domain
40328
+ * without scanning all the data entries.
40329
+ */
40330
+ dataEntriesIndex = lazy(() => new PivotDataEntriesIndex([], [], []));
40331
+ /**
40142
40332
  * This object contains the pivot table structure. It is created from the
40143
40333
  * data entries and the pivot definition.
40144
40334
  */
@@ -40173,6 +40363,7 @@ var SpreadsheetPivot = class {
40173
40363
  this.filteredDataEntries = this.loadFilteredDataEntries(this.unfilteredDataEntries);
40174
40364
  }
40175
40365
  if (type >= 1) {
40366
+ this.dataEntriesIndex = lazy(() => new PivotDataEntriesIndex(this.filteredDataEntries, this.definition.rows, this.definition.columns));
40176
40367
  this.collapsedTable = void 0;
40177
40368
  this.expandedTable = void 0;
40178
40369
  }
@@ -40250,14 +40441,14 @@ var SpreadsheetPivot = class {
40250
40441
  const lastNode = domain.at(-1);
40251
40442
  if (!lastNode) return { value: _t("Total") };
40252
40443
  const dimension = this.getDimension(lastNode.field);
40253
- const finalCell = this.filterDataEntriesFromDomain(this.filteredDataEntries, domain)[0]?.[dimension.nameWithGranularity];
40254
40444
  if (dimension.type === "datetime") return pivotTimeAdapter(dimension.granularity || "month").toValueAndFormat(lastNode.value, this.getters.getLocale());
40445
+ const finalCell = this.getDataEntriesFromDomain(domain)[0]?.[dimension.nameWithGranularity];
40255
40446
  if (!finalCell) return { value: "" };
40256
40447
  if (finalCell.value === null) return { value: _t("(Undefined)") };
40257
40448
  return finalCell;
40258
40449
  }
40259
40450
  getPivotCellValueAndFormat(measureId, domain) {
40260
- const dataEntries = this.filterDataEntriesFromDomain(this.filteredDataEntries, domain);
40451
+ const dataEntries = this.getDataEntriesFromDomain(domain);
40261
40452
  if (dataEntries.length === 0) return { value: "" };
40262
40453
  const measure = this.getMeasure(measureId);
40263
40454
  const allValues = dataEntries.map((value) => value[measure.fieldName]).filter(isDefined);
@@ -40367,17 +40558,8 @@ var SpreadsheetPivot = class {
40367
40558
  if (!type) throw new Error(`Field ${fieldName} does not exist`);
40368
40559
  return type;
40369
40560
  }
40370
- filterDataEntriesFromDomain(dataEntries, domain) {
40371
- return domain.reduce((current, acc) => this.filterDataEntriesFromDomainNode(current, acc), dataEntries);
40372
- }
40373
- filterDataEntriesFromDomainNode(dataEntries, domain) {
40374
- const { field, value, type } = domain;
40375
- const { nameWithGranularity } = this.getDimension(field);
40376
- return dataEntries.filter((entry) => {
40377
- const cellValue = entry[nameWithGranularity]?.value;
40378
- if (type === "char") return String(cellValue) === String(value);
40379
- return cellValue === value;
40380
- });
40561
+ getDataEntriesFromDomain(domain) {
40562
+ return this.dataEntriesIndex().getDataEntries(domain);
40381
40563
  }
40382
40564
  getDimension(nameWithGranularity) {
40383
40565
  return this.definition.getDimension(nameWithGranularity);
@@ -40771,7 +40953,7 @@ var PivotSidePanelStore = class extends SpreadsheetStore {
40771
40953
  }
40772
40954
  const pivot = this.getters.getPivot(this.pivotId);
40773
40955
  const numberOfCells = pivot.isValid() ? pivot.getExpandedTableStructure().numberOfCells : 0;
40774
- if (!this.alreadyNotifiedForPivotSize && numberOfCells > 5e5) {
40956
+ if (!this.alreadyNotifiedForPivotSize && numberOfCells > PIVOT_MAX_NUMBER_OF_CELLS) {
40775
40957
  this.alreadyNotifiedForPivotSize = true;
40776
40958
  this.notification.notifyUser({
40777
40959
  type: "warning",
@@ -42633,7 +42815,7 @@ const SEPARATORS = [
42633
42815
  },
42634
42816
  {
42635
42817
  label: _t("Line Break"),
42636
- value: "\n"
42818
+ value: NEWLINE
42637
42819
  }
42638
42820
  ];
42639
42821
  var SplitIntoColumnsPanel = class extends Component {
@@ -43178,7 +43360,7 @@ var SidePanelStore = class extends SpreadsheetStore {
43178
43360
  const newPanelInfo = {
43179
43361
  currentPanelProps,
43180
43362
  componentTag,
43181
- size: 350
43363
+ size: DEFAULT_SIDE_PANEL_SIZE
43182
43364
  };
43183
43365
  const state = this.computeState(newPanelInfo);
43184
43366
  if (!state.isOpen) return;
@@ -43186,8 +43368,8 @@ var SidePanelStore = class extends SpreadsheetStore {
43186
43368
  this._openPanel("mainPanel", newPanelInfo, state);
43187
43369
  return;
43188
43370
  }
43189
- const nonCollapsedPanelSize = this.mainPanel.isCollapsed ? 350 : this.mainPanel.size;
43190
- if (!this.secondaryPanel && nonCollapsedPanelSize + 350 > this.availableWidth) {
43371
+ const nonCollapsedPanelSize = this.mainPanel.isCollapsed ? DEFAULT_SIDE_PANEL_SIZE : this.mainPanel.size;
43372
+ if (!this.secondaryPanel && nonCollapsedPanelSize + DEFAULT_SIDE_PANEL_SIZE > this.availableWidth) {
43191
43373
  this.get(NotificationStore).notifyUser({
43192
43374
  sticky: false,
43193
43375
  type: "warning",
@@ -43201,7 +43383,7 @@ var SidePanelStore = class extends SpreadsheetStore {
43201
43383
  const newPanelInfo = {
43202
43384
  currentPanelProps,
43203
43385
  componentTag,
43204
- size: 350
43386
+ size: DEFAULT_SIDE_PANEL_SIZE
43205
43387
  };
43206
43388
  const state = this.computeState(newPanelInfo);
43207
43389
  if (!state.isOpen) return;
@@ -43230,7 +43412,7 @@ var SidePanelStore = class extends SpreadsheetStore {
43230
43412
  this[panel] = {
43231
43413
  currentPanelProps: state.props ?? {},
43232
43414
  componentTag: newPanel.componentTag,
43233
- size: currentPanel?.size || 350,
43415
+ size: currentPanel?.size || DEFAULT_SIDE_PANEL_SIZE,
43234
43416
  isCollapsed: currentPanel?.isCollapsed || false,
43235
43417
  isPinned: currentPanel && "isPinned" in currentPanel ? currentPanel.isPinned : false
43236
43418
  };
@@ -43260,19 +43442,19 @@ var SidePanelStore = class extends SpreadsheetStore {
43260
43442
  changePanelSize(panel, size) {
43261
43443
  const panelInfo = this[panel];
43262
43444
  if (!panelInfo || "isCollapsed" in panelInfo && panelInfo.isCollapsed) return;
43263
- size = Math.max(size, 350);
43445
+ size = Math.max(size, DEFAULT_SIDE_PANEL_SIZE);
43264
43446
  let otherPanelSize = panel === "mainPanel" ? this.secondaryPanel?.size || 0 : this.mainPanel?.size || 0;
43265
43447
  if (size > this.availableWidth - otherPanelSize) {
43266
43448
  if (panel === "mainPanel" && this.secondaryPanel) {
43267
- this.secondaryPanel.size = Math.max(this.availableWidth - size, 350);
43449
+ this.secondaryPanel.size = Math.max(this.availableWidth - size, DEFAULT_SIDE_PANEL_SIZE);
43268
43450
  otherPanelSize = this.secondaryPanel.size;
43269
43451
  }
43270
- size = Math.max(this.availableWidth - otherPanelSize, 350);
43452
+ size = Math.max(this.availableWidth - otherPanelSize, DEFAULT_SIDE_PANEL_SIZE);
43271
43453
  }
43272
43454
  panelInfo.size = size;
43273
43455
  }
43274
43456
  resetPanelSize(panel) {
43275
- if (this[panel]) this[panel].size = 350;
43457
+ if (this[panel]) this[panel].size = DEFAULT_SIDE_PANEL_SIZE;
43276
43458
  }
43277
43459
  togglePinPanel() {
43278
43460
  if (!this.mainPanel) return;
@@ -43288,10 +43470,10 @@ var SidePanelStore = class extends SpreadsheetStore {
43288
43470
  if (!panelInfo) return;
43289
43471
  if (panelInfo.isCollapsed) {
43290
43472
  panelInfo.isCollapsed = false;
43291
- this.changePanelSize(panel, 350);
43473
+ this.changePanelSize(panel, DEFAULT_SIDE_PANEL_SIZE);
43292
43474
  } else {
43293
43475
  panelInfo.isCollapsed = true;
43294
- panelInfo.size = 45;
43476
+ panelInfo.size = COLLAPSED_SIDE_PANEL_SIZE;
43295
43477
  }
43296
43478
  }
43297
43479
  computeState({ componentTag, currentPanelProps: initialPanelProps }) {
@@ -43306,12 +43488,12 @@ var SidePanelStore = class extends SpreadsheetStore {
43306
43488
  } : state;
43307
43489
  }
43308
43490
  changeSpreadsheetWidth(width) {
43309
- this.availableWidth = width - 150;
43310
- if (this.secondaryPanel && width - this.totalPanelSize < 150) {
43491
+ this.availableWidth = width - MIN_SHEET_VIEW_WIDTH;
43492
+ if (this.secondaryPanel && width - this.totalPanelSize < MIN_SHEET_VIEW_WIDTH) {
43311
43493
  this.secondaryPanel?.currentPanelProps.onCloseSidePanel?.();
43312
43494
  this.secondaryPanel = void 0;
43313
43495
  }
43314
- if (this.mainPanel && width - this.totalPanelSize < 150) this.mainPanel.size = Math.max(width - 150, 350);
43496
+ if (this.mainPanel && width - this.totalPanelSize < MIN_SHEET_VIEW_WIDTH) this.mainPanel.size = Math.max(width - MIN_SHEET_VIEW_WIDTH, DEFAULT_SIDE_PANEL_SIZE);
43315
43497
  }
43316
43498
  };
43317
43499
 
@@ -45074,7 +45256,7 @@ const MIN_DELAY = 20;
45074
45256
  * Returns a timeout delay in milliseconds.
45075
45257
  */
45076
45258
  function scrollDelay(value) {
45077
- return 20 + (140 - 20) * Math.exp(-.035 * (value - 1));
45259
+ return MIN_DELAY + (MAX_DELAY - MIN_DELAY) * Math.exp(-.035 * (value - 1));
45078
45260
  }
45079
45261
 
45080
45262
  //#endregion
@@ -45118,7 +45300,7 @@ function useDragAndDropBeyondTheViewport(env) {
45118
45300
  let { scrollX, scrollY } = getters.getActiveSheetScrollInfo();
45119
45301
  const { xSplit, ySplit } = getters.getPaneDivisions(sheetId);
45120
45302
  let canEdgeScroll = false;
45121
- let timeoutDelay = 140;
45303
+ let timeoutDelay = MAX_DELAY;
45122
45304
  const x = zoomedMouseEvent.clientX - position.x;
45123
45305
  let colIndex = getters.getColIndex(x);
45124
45306
  if (scrollDirection !== "vertical") {
@@ -45514,7 +45696,7 @@ function fits(width, linkedString) {
45514
45696
  return true;
45515
45697
  }
45516
45698
  function astToDoc(ast) {
45517
- const debugPrefix = ast.debug ? `${"?"}` : "";
45699
+ const debugPrefix = ast.debug ? `${DEBUGGER_CHAR}` : "";
45518
45700
  switch (ast.type) {
45519
45701
  case "NUMBER": return debugPrefix + String(ast.value);
45520
45702
  case "STRING": return debugPrefix + `"${ast.value}"`;
@@ -45593,7 +45775,7 @@ function wrapInBraces(doc) {
45593
45775
  * Converts an ast formula to the corresponding string
45594
45776
  */
45595
45777
  function astToFormula(ast) {
45596
- const debugPrefix = ast.debug ? `${"?"}` : "";
45778
+ const debugPrefix = ast.debug ? `${DEBUGGER_CHAR}` : "";
45597
45779
  switch (ast.type) {
45598
45780
  case "FUNCALL":
45599
45781
  const args = ast.args.map((arg) => astToFormula(arg));
@@ -46288,19 +46470,19 @@ function getAxis(getters, figureUI, dnd, axisType) {
46288
46470
  position = y;
46289
46471
  break;
46290
46472
  case "bottom":
46291
- position = y + figureUI.height - 1;
46473
+ position = y + figureUI.height - FIGURE_BORDER_WIDTH;
46292
46474
  break;
46293
46475
  case "vCenter":
46294
- position = y + Math.floor(figureUI.height / 2) - 1;
46476
+ position = y + Math.floor(figureUI.height / 2) - FIGURE_BORDER_WIDTH;
46295
46477
  break;
46296
46478
  case "left":
46297
46479
  position = x;
46298
46480
  break;
46299
46481
  case "right":
46300
- position = x + figureUI.width - 1;
46482
+ position = x + figureUI.width - FIGURE_BORDER_WIDTH;
46301
46483
  break;
46302
46484
  case "hCenter":
46303
- position = x + Math.floor(figureUI.width / 2) - 1;
46485
+ position = x + Math.floor(figureUI.width / 2) - FIGURE_BORDER_WIDTH;
46304
46486
  break;
46305
46487
  }
46306
46488
  return {
@@ -46531,7 +46713,7 @@ var FiguresContainer = class extends Component {
46531
46713
  };
46532
46714
  const offsetX = Math.abs(currentMousePosition.x - initialMousePosition.x);
46533
46715
  const offsetY = Math.abs(currentMousePosition.y - initialMousePosition.y);
46534
- if (!hasStartedDnd && offsetX < 5 && offsetY < 5) return;
46716
+ if (!hasStartedDnd && offsetX < DRAG_THRESHOLD && offsetY < DRAG_THRESHOLD) return;
46535
46717
  hasStartedDnd = true;
46536
46718
  const selectedFigures = dragFigureForMove(currentMousePosition, initialMousePosition, initialFigures, maxDimensions, initialScrollPosition, getters.getActiveSheetScrollInfo());
46537
46719
  const draggedFigure = selectedFigures.find((f) => f.id === draggedFigureId);
@@ -46600,7 +46782,7 @@ var FiguresContainer = class extends Component {
46600
46782
  ev.stopPropagation();
46601
46783
  const initialScrollPosition = this.env.model.getters.getActiveSheetScrollInfo();
46602
46784
  const keepRatio = figureRegistry.get(figureUI.tag).keepRatio || false;
46603
- const minFigSize = figureRegistry.get(figureUI.tag).minFigSize || 80;
46785
+ const minFigSize = figureRegistry.get(figureUI.tag).minFigSize || MIN_FIG_SIZE;
46604
46786
  const zoom = this.env.model.getters.getViewportZoomLevel();
46605
46787
  const sheetId = this.env.model.getters.getActiveSheetId();
46606
46788
  const initialMousePosition = {
@@ -46738,8 +46920,8 @@ var GridAddRowsFooter = class extends Component {
46738
46920
  const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
46739
46921
  const { y, height } = this.env.model.getters.getMainViewportRect();
46740
46922
  return cssPropertiesToCss({
46741
- top: `${y + height - scrollY - 46}px`,
46742
- height: `${46}px`
46923
+ top: `${y + height - scrollY - FOOTER_HEIGHT}px`,
46924
+ height: `${FOOTER_HEIGHT}px`
46743
46925
  });
46744
46926
  }
46745
46927
  get errorMessages() {
@@ -47149,7 +47331,7 @@ var GridOverlay = class extends Component {
47149
47331
  get isFooterVisible() {
47150
47332
  const { y } = this.env.model.getters.getMainViewportCoordinates();
47151
47333
  const { height } = this.env.model.getters.getSheetViewDimension();
47152
- return !this.env.model.getters.isReadonly() && height - y > 46;
47334
+ return !this.env.model.getters.isReadonly() && height - y > FOOTER_HEIGHT;
47153
47335
  }
47154
47336
  };
47155
47337
 
@@ -47203,7 +47385,7 @@ var UnhideRowHeaders = class extends Component {
47203
47385
  row: hiddenIndex
47204
47386
  }));
47205
47387
  return cssPropertiesToCss({
47206
- top: rect.y + rect.height - 26 - this.props.offset + "px",
47388
+ top: rect.y + rect.height - HEADER_HEIGHT - this.props.offset + "px",
47207
47389
  "margin-right": "1px"
47208
47390
  });
47209
47391
  }
@@ -47212,7 +47394,7 @@ var UnhideRowHeaders = class extends Component {
47212
47394
  top: this.env.model.getters.getRect(positionToZone({
47213
47395
  col: 0,
47214
47396
  row: hiddenIndex
47215
- })).y - 26 - this.props.offset + "px",
47397
+ })).y - HEADER_HEIGHT - this.props.offset + "px",
47216
47398
  "margin-right": "1px"
47217
47399
  });
47218
47400
  }
@@ -47245,13 +47427,13 @@ var UnhideColumnHeaders = class extends Component {
47245
47427
  col: hiddenIndex,
47246
47428
  row: 0
47247
47429
  }));
47248
- return cssPropertiesToCss({ left: rect.x + rect.width - 48 - this.props.offset + "px" });
47430
+ return cssPropertiesToCss({ left: rect.x + rect.width - HEADER_WIDTH - this.props.offset + "px" });
47249
47431
  }
47250
47432
  getUnhideNextButtonStyle(hiddenIndex) {
47251
47433
  return cssPropertiesToCss({ left: this.env.model.getters.getRect(positionToZone({
47252
47434
  col: hiddenIndex,
47253
47435
  row: 0
47254
- })).x - 48 - this.props.offset + "px" });
47436
+ })).x - HEADER_WIDTH - this.props.offset + "px" });
47255
47437
  }
47256
47438
  unhide(hiddenElements) {
47257
47439
  this.env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
@@ -47474,7 +47656,7 @@ var ColResizer = class extends AbstractResizer {
47474
47656
  super.setup();
47475
47657
  this.PADDING = 15;
47476
47658
  this.MAX_SIZE_MARGIN = 90;
47477
- this.MIN_ELEMENT_SIZE = 5;
47659
+ this.MIN_ELEMENT_SIZE = MIN_COL_WIDTH;
47478
47660
  }
47479
47661
  get sheetId() {
47480
47662
  return this.env.model.getters.getActiveSheetId();
@@ -47608,7 +47790,7 @@ var RowResizer = class extends AbstractResizer {
47608
47790
  super.setup();
47609
47791
  this.PADDING = 5;
47610
47792
  this.MAX_SIZE_MARGIN = 60;
47611
- this.MIN_ELEMENT_SIZE = 10;
47793
+ this.MIN_ELEMENT_SIZE = MIN_ROW_HEIGHT;
47612
47794
  }
47613
47795
  get sheetId() {
47614
47796
  return this.env.model.getters.getActiveSheetId();
@@ -48044,7 +48226,7 @@ var GridRenderer = class extends DisposableStore {
48044
48226
  x,
48045
48227
  y
48046
48228
  }, style.underline, style.strikethrough);
48047
- y += 4 + box.content.fontSizePx;
48229
+ y += MIN_CELL_TEXT_MARGIN + box.content.fontSizePx;
48048
48230
  }
48049
48231
  if (style.rotation) ctx.restore();
48050
48232
  if (box.clipRect) ctx.restore();
@@ -48092,14 +48274,14 @@ var GridRenderer = class extends DisposableStore {
48092
48274
  const activeCols = renderingContext.activeCols;
48093
48275
  const activeRows = renderingContext.activeRows;
48094
48276
  const theme = this.getters.getSpreadsheetTheme();
48095
- ctx.font = `400 ${11}px ${DEFAULT_FONT}`;
48277
+ ctx.font = `400 ${HEADER_FONT_SIZE}px ${DEFAULT_FONT}`;
48096
48278
  ctx.textAlign = "center";
48097
48279
  ctx.textBaseline = "middle";
48098
48280
  ctx.lineWidth = thinLineWidth;
48099
48281
  ctx.strokeStyle = theme.headerTextColor;
48100
48282
  ctx.fillStyle = this.getters.getSpreadsheetTheme().backgroundColor;
48101
- ctx.fillRect(0, 0, 48, height);
48102
- ctx.fillRect(0, 0, width, 26);
48283
+ ctx.fillRect(0, 0, HEADER_WIDTH, height);
48284
+ ctx.fillRect(0, 0, width, HEADER_HEIGHT);
48103
48285
  for (const col of visibleCols) {
48104
48286
  const colZone = {
48105
48287
  left: col,
@@ -48113,7 +48295,7 @@ var GridRenderer = class extends DisposableStore {
48113
48295
  if (isColActive) ctx.fillStyle = theme.headerActiveBackgroundColor;
48114
48296
  else if (isColSelected) ctx.fillStyle = theme.headerSelectedBackgroundColor;
48115
48297
  else ctx.fillStyle = theme.headerBackgroundColor;
48116
- ctx.fillRect(x, 0, width, 26);
48298
+ ctx.fillRect(x, 0, width, HEADER_HEIGHT);
48117
48299
  }
48118
48300
  for (const row of visibleRows) {
48119
48301
  const rowZone = {
@@ -48128,13 +48310,13 @@ var GridRenderer = class extends DisposableStore {
48128
48310
  if (isRowActive) ctx.fillStyle = theme.headerActiveBackgroundColor;
48129
48311
  else if (isRowSelected) ctx.fillStyle = theme.headerSelectedBackgroundColor;
48130
48312
  else ctx.fillStyle = theme.headerBackgroundColor;
48131
- ctx.fillRect(0, y, 48, height);
48313
+ ctx.fillRect(0, y, HEADER_WIDTH, height);
48132
48314
  }
48133
48315
  ctx.beginPath();
48134
- ctx.moveTo(48, 0);
48135
- ctx.lineTo(48, height);
48136
- ctx.moveTo(0, 26);
48137
- ctx.lineTo(width, 26);
48316
+ ctx.moveTo(HEADER_WIDTH, 0);
48317
+ ctx.lineTo(HEADER_WIDTH, height);
48318
+ ctx.moveTo(0, HEADER_HEIGHT);
48319
+ ctx.lineTo(width, HEADER_HEIGHT);
48138
48320
  ctx.strokeStyle = theme.headerBorderColor;
48139
48321
  ctx.stroke();
48140
48322
  for (const col of visibleCols) {
@@ -48150,13 +48332,13 @@ var GridRenderer = class extends DisposableStore {
48150
48332
  const { x, width } = viewports.getVisibleRect(sheetId, zone);
48151
48333
  ctx.save();
48152
48334
  ctx.beginPath();
48153
- ctx.rect(x, 0, width, 26);
48335
+ ctx.rect(x, 0, width, HEADER_HEIGHT);
48154
48336
  ctx.clip();
48155
- ctx.fillText(colName, colStart + colSize / 2, 26 / 2);
48337
+ ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
48156
48338
  ctx.restore();
48157
48339
  ctx.beginPath();
48158
48340
  ctx.moveTo(colStart + colSize, 0);
48159
- ctx.lineTo(colStart + colSize, 26);
48341
+ ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
48160
48342
  ctx.stroke();
48161
48343
  }
48162
48344
  for (const row of visibleRows) {
@@ -48171,13 +48353,13 @@ var GridRenderer = class extends DisposableStore {
48171
48353
  const { y, height } = viewports.getVisibleRect(sheetId, zone);
48172
48354
  ctx.save();
48173
48355
  ctx.beginPath();
48174
- ctx.rect(0, y, 48, height);
48356
+ ctx.rect(0, y, HEADER_WIDTH, height);
48175
48357
  ctx.clip();
48176
- ctx.fillText(String(row + 1), 48 / 2, rowStart + rowSize / 2);
48358
+ ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
48177
48359
  ctx.restore();
48178
48360
  ctx.beginPath();
48179
48361
  ctx.moveTo(0, rowStart + rowSize);
48180
- ctx.lineTo(48, rowStart + rowSize);
48362
+ ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
48181
48363
  ctx.stroke();
48182
48364
  }
48183
48365
  }
@@ -48320,7 +48502,7 @@ var GridRenderer = class extends DisposableStore {
48320
48502
  /** Content */
48321
48503
  const wrapping = style.wrapping || "overflow";
48322
48504
  const wrapText = wrapping === "wrap" && !showFormula;
48323
- const availableWidth = width - 2 * 4;
48505
+ const availableWidth = width - 2 * MIN_CELL_TEXT_MARGIN;
48324
48506
  const maxWidth = style.align ? 0 : availableWidth;
48325
48507
  const wrapWidth = wrapText ? availableWidth : void 0;
48326
48508
  const multiLineText = this.getters.getCellMultiLineText(position, {
@@ -48332,18 +48514,18 @@ var GridRenderer = class extends DisposableStore {
48332
48514
  align: "left",
48333
48515
  rotation: 0
48334
48516
  };
48335
- const textWidth = Math.max(...multiLineText.map((line) => this.getters.getTextWidth(line, noRotatationStyle))) + 4;
48517
+ const textWidth = Math.max(...multiLineText.map((line) => this.getters.getTextWidth(line, noRotatationStyle))) + MIN_CELL_TEXT_MARGIN;
48336
48518
  const contentSize = this.getters.getMultilineTextSize(multiLineText, style);
48337
- const chipMargin = chipStyle ? 5 : 0;
48519
+ const chipMargin = chipStyle ? DATA_VALIDATION_CHIP_MARGIN : 0;
48338
48520
  const leftMargin = (box.icons.left ? box.icons.left.size + box.icons.left.margin : 0) + chipMargin;
48339
48521
  const rightMargin = (box.icons.right ? box.icons.right.size + box.icons.right.margin : 0) + chipMargin;
48340
- const contentWidth = leftMargin + contentSize.width + rightMargin + 4;
48522
+ const contentWidth = leftMargin + contentSize.width + rightMargin + MIN_CELL_TEXT_MARGIN;
48341
48523
  const align = this.computeCellAlignment(position, contentWidth > width);
48342
48524
  const numberOfLines = multiLineText.length;
48343
48525
  const contentY = Math.round(this.getters.computeTextYCoordinate(box, fontSizePX, style.verticalAlign, numberOfLines));
48344
48526
  let contentX = box.x;
48345
- if (align === "left") contentX += 4 + leftMargin;
48346
- else if (align === "right") contentX += box.width - 4 - rightMargin;
48527
+ if (align === "left") contentX += MIN_CELL_TEXT_MARGIN + leftMargin;
48528
+ else if (align === "right") contentX += box.width - MIN_CELL_TEXT_MARGIN - rightMargin;
48347
48529
  else contentX += box.width / 2;
48348
48530
  contentX = Math.round(contentX);
48349
48531
  const textHeight = computeTextLinesHeight(fontSizePX, numberOfLines);
@@ -48359,7 +48541,7 @@ var GridRenderer = class extends DisposableStore {
48359
48541
  };
48360
48542
  if (chipStyle?.fillColor) {
48361
48543
  const chipMarginLeft = leftMargin;
48362
- const chipMarginRight = 5;
48544
+ const chipMarginRight = DATA_VALIDATION_CHIP_MARGIN;
48363
48545
  box.chip = {
48364
48546
  color: chipStyle.fillColor,
48365
48547
  width: box.width - chipMarginLeft - chipMarginRight,
@@ -48522,7 +48704,7 @@ var GridRenderer = class extends DisposableStore {
48522
48704
  continue;
48523
48705
  }
48524
48706
  const elapsedTime = timeStamp - animation.startTime;
48525
- const progress = Math.min(1, elapsedTime / 200);
48707
+ const progress = Math.min(1, elapsedTime / CELL_ANIMATION_DURATION);
48526
48708
  if (progress >= 1) this.animations.delete(boxId);
48527
48709
  animation.progress = progress;
48528
48710
  }
@@ -48647,7 +48829,7 @@ function useTouchHandlers(ref, { updateScroll, canMoveUp, canMoveDown, getZoom,
48647
48829
  resetTimeout = setTimeout(() => {
48648
48830
  velocityX = 0;
48649
48831
  velocityY = 0;
48650
- }, 100);
48832
+ }, resetTimeoutDuration);
48651
48833
  updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
48652
48834
  }
48653
48835
  function onTouchEnd(ev) {
@@ -48716,7 +48898,7 @@ function computeDistance(ev1, ev2) {
48716
48898
  //#region src/components/helpers/wheel_hook.ts
48717
48899
  function useWheelHandler(handler) {
48718
48900
  function normalize(val, deltaMode) {
48719
- return val * (deltaMode === 0 ? 1 : 23);
48901
+ return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
48720
48902
  }
48721
48903
  const onMouseWheel = (ev) => {
48722
48904
  handler(normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode), normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode));
@@ -48826,14 +49008,14 @@ var Corner = class extends Component {
48826
49008
  return cssPropertiesToCss(css);
48827
49009
  }
48828
49010
  getHandlerEdgeLength() {
48829
- return this.env.isMobile() ? MOBILE_HANDLER_WIDTH : 8;
49011
+ return this.env.isMobile() ? MOBILE_HANDLER_WIDTH : AUTOFILL_EDGE_LENGTH;
48830
49012
  }
48831
49013
  get buttonLook() {
48832
49014
  const css = {
48833
49015
  "background-color": this.props.color,
48834
49016
  cursor: `${this.props.orientation}-resize`
48835
49017
  };
48836
- if (this.env.isMobile()) css["border-radius"] = `${8 / 2}px`;
49018
+ if (this.env.isMobile()) css["border-radius"] = `${AUTOFILL_EDGE_LENGTH / 2}px`;
48837
49019
  return cssPropertiesToCss(css);
48838
49020
  }
48839
49021
  onMouseDown(ev) {
@@ -49231,8 +49413,8 @@ var Grid = class extends Component {
49231
49413
  exposeFocus: types.function(),
49232
49414
  getGridSize: types.function()
49233
49415
  });
49234
- HEADER_HEIGHT = 26;
49235
- HEADER_WIDTH = 48;
49416
+ HEADER_HEIGHT = HEADER_HEIGHT;
49417
+ HEADER_WIDTH = HEADER_WIDTH;
49236
49418
  menuState;
49237
49419
  gridRef = (0, _odoo_owl.signal)(null);
49238
49420
  canvasRef = (0, _odoo_owl.signal)(null);
@@ -49303,10 +49485,10 @@ var Grid = class extends Component {
49303
49485
  get gridOverlayDimensions() {
49304
49486
  const scrollbarWidth = this.env.model.getters.getScrollBarWidth();
49305
49487
  return cssPropertiesToCss({
49306
- top: `${26}px`,
49307
- left: `${48}px`,
49308
- height: `calc(100% - ${26 + scrollbarWidth}px)`,
49309
- width: `calc(100% - ${48 + scrollbarWidth}px)`
49488
+ top: `${HEADER_HEIGHT}px`,
49489
+ left: `${HEADER_WIDTH}px`,
49490
+ height: `calc(100% - ${HEADER_HEIGHT + scrollbarWidth}px)`,
49491
+ width: `calc(100% - ${HEADER_WIDTH + scrollbarWidth}px)`
49310
49492
  });
49311
49493
  }
49312
49494
  onClosePopover() {
@@ -49522,8 +49704,8 @@ var Grid = class extends Component {
49522
49704
  const zone = this.env.model.getters.getSelectedZone();
49523
49705
  const rect = this.env.model.getters.getVisibleRect(zone);
49524
49706
  return {
49525
- x: rect.x + rect.width - 8 / 2,
49526
- y: rect.y + rect.height - 8 / 2
49707
+ x: rect.x + rect.width - AUTOFILL_EDGE_LENGTH / 2,
49708
+ y: rect.y + rect.height - AUTOFILL_EDGE_LENGTH / 2
49527
49709
  };
49528
49710
  }
49529
49711
  get isAutofillVisible() {
@@ -49540,10 +49722,10 @@ var Grid = class extends Component {
49540
49722
  onGridResized() {
49541
49723
  const { height, width } = this.props.getGridSize();
49542
49724
  this.env.model.dispatch("RESIZE_SHEETVIEW", {
49543
- width: width - 48,
49544
- height: height - 26,
49545
- gridOffsetX: 48,
49546
- gridOffsetY: 26
49725
+ width: width - HEADER_WIDTH,
49726
+ height: height - HEADER_HEIGHT,
49727
+ gridOffsetX: HEADER_WIDTH,
49728
+ gridOffsetY: HEADER_HEIGHT
49547
49729
  });
49548
49730
  }
49549
49731
  moveCanvas(deltaX, deltaY) {
@@ -49889,7 +50071,7 @@ var ClickableCellSortIcon = class extends Component {
49889
50071
  return cssPropertiesToCss({
49890
50072
  height: `${size}px`,
49891
50073
  width: `${size}px`,
49892
- color: cellStyle.textColor || "#374151C2",
50074
+ color: cellStyle.textColor || TEXT_BODY_MUTED,
49893
50075
  "background-color": this.getBackgroundColor(cellStyle)
49894
50076
  });
49895
50077
  }
@@ -50742,8 +50924,8 @@ var CarouselPlugin = class extends CorePlugin {
50742
50924
  case "DUPLICATE_SHEET": {
50743
50925
  const sheetFiguresFrom = this.getters.getFigures(cmd.sheetId);
50744
50926
  for (const fig of sheetFiguresFrom) if (fig.tag === "carousel") {
50745
- const figureIdBase = fig.id.split("??").pop();
50746
- const duplicatedFigureId = `${cmd.sheetIdTo}${"??"}${figureIdBase}`;
50927
+ const figureIdBase = fig.id.split(FIGURE_ID_SPLITTER).pop();
50928
+ const duplicatedFigureId = `${cmd.sheetIdTo}${FIGURE_ID_SPLITTER}${figureIdBase}`;
50747
50929
  const carousel = this.getCarousel(fig.id);
50748
50930
  if (carousel) {
50749
50931
  const size = {
@@ -50759,8 +50941,8 @@ var CarouselPlugin = class extends CorePlugin {
50759
50941
  size,
50760
50942
  definition: { items: carousel.items.map((item) => {
50761
50943
  if (item.type === "carouselDataView") return { ...item };
50762
- const chartIdBase = item.chartId.split("??").pop();
50763
- const newChartId = `${cmd.sheetIdTo}${"??"}${chartIdBase}`;
50944
+ const chartIdBase = item.chartId.split(FIGURE_ID_SPLITTER).pop();
50945
+ const newChartId = `${cmd.sheetIdTo}${FIGURE_ID_SPLITTER}${chartIdBase}`;
50764
50946
  return {
50765
50947
  ...item,
50766
50948
  chartId: newChartId
@@ -50834,12 +51016,12 @@ var Squisher = class {
50834
51016
  * with references (unless they contain a sheet name that contains the separator). */
50835
51017
  buildResult(numbers, strings, references) {
50836
51018
  const res = {};
50837
- if (numbers.length) res.N = numbers.join("|");
51019
+ if (numbers.length) res.N = numbers.join(SEPARATOR);
50838
51020
  if (strings.length) res.S = strings;
50839
51021
  if (references.length) {
50840
51022
  let referencePattern;
50841
- if (references.some((x) => x.includes("|"))) referencePattern = references;
50842
- else referencePattern = references.join("|");
51023
+ if (references.some((x) => x.includes(SEPARATOR))) referencePattern = references;
51024
+ else referencePattern = references.join(SEPARATOR);
50843
51025
  res.R = referencePattern;
50844
51026
  }
50845
51027
  return res;
@@ -50972,7 +51154,7 @@ var Squisher = class {
50972
51154
  }
50973
51155
  squishOneReference(reference, previousReferences, index, forSheetId) {
50974
51156
  const previousReference = previousReferences[index];
50975
- if (deepEquals(previousReference, reference)) return "=";
51157
+ if (deepEquals(previousReference, reference)) return NO_CHANGE;
50976
51158
  if (previousReference.sheetId !== reference.sheetId || previousReference.prefixSheet !== reference.prefixSheet || previousReference.invalidSheetName !== reference.invalidSheetName || previousReference.invalidXc !== reference.invalidXc || previousReference.parts.length !== reference.parts.length) {
50977
51159
  previousReferences[index] = deepCopy(reference);
50978
51160
  return getRangeString(reference, forSheetId, this.getters.getSheetName, this.rangeToStringOptions);
@@ -51006,7 +51188,7 @@ var Squisher = class {
51006
51188
  * - "=" meaning no change as string
51007
51189
  * */
51008
51190
  squishNumbers(numbers) {
51009
- const result = numbers.map((x) => "=");
51191
+ const result = numbers.map((x) => NO_CHANGE);
51010
51192
  for (let i = 0; i < numbers.length; i++) {
51011
51193
  const previousValue = this.baseFormula.literalValues.numbers[i].value;
51012
51194
  const currentValue = numbers[i].value;
@@ -51020,7 +51202,7 @@ var Squisher = class {
51020
51202
  return result;
51021
51203
  }
51022
51204
  squishStrings(strings) {
51023
- const result = strings.map((x) => "=");
51205
+ const result = strings.map((x) => NO_CHANGE);
51024
51206
  for (let i = 0; i < strings.length; i++) {
51025
51207
  const str = strings[i].value;
51026
51208
  if (str !== this.previousStrings[i]) {
@@ -51293,16 +51475,16 @@ var Unsquisher = class {
51293
51475
  strings: [],
51294
51476
  dependencies: []
51295
51477
  };
51296
- if (squishedFormula.N !== void 0 && squishedFormula.N.length > 0) current.numbers = squishedFormula.N.split("|").map(this.adjustNumbers);
51478
+ if (squishedFormula.N !== void 0 && squishedFormula.N.length > 0) current.numbers = squishedFormula.N.split(SEPARATOR).map(this.adjustNumbers);
51297
51479
  else current.numbers = this.previousFormula.literalValues.numbers;
51298
51480
  if (squishedFormula.S !== void 0 && squishedFormula.S.length > 0) current.strings = squishedFormula.S.map(this.adjustStrings);
51299
51481
  else current.strings = this.previousFormula.literalValues.strings;
51300
51482
  if (squishedFormula.R !== void 0 && this.previousFormula) {
51301
51483
  let references;
51302
51484
  if (typeof squishedFormula.R !== "string") references = squishedFormula.R;
51303
- else references = squishedFormula.R.split("|");
51485
+ else references = squishedFormula.R.split(SEPARATOR);
51304
51486
  current.dependencies = references.map((refStr, index) => {
51305
- if (refStr === "=") return { ...this.alreadyAppliedReferenceOffset[index] };
51487
+ if (refStr === NO_CHANGE) return { ...this.alreadyAppliedReferenceOffset[index] };
51306
51488
  else if (refStr.startsWith("+") || refStr.startsWith("-")) {
51307
51489
  const offset = parseInt(refStr.slice(2), 10);
51308
51490
  const sign = refStr[0] === "+" ? 1 : -1;
@@ -51338,14 +51520,14 @@ var Unsquisher = class {
51338
51520
  throw new Error("Invalid squished element or no previous cell to unsquish against");
51339
51521
  }
51340
51522
  adjustStrings = (str, index) => {
51341
- if (str === "=") return { value: this.previousString[index] };
51523
+ if (str === NO_CHANGE) return { value: this.previousString[index] };
51342
51524
  else {
51343
51525
  this.previousString[index] = str;
51344
51526
  return { value: str };
51345
51527
  }
51346
51528
  };
51347
51529
  adjustNumbers = (numStr, index) => {
51348
- if (numStr === "=") return { value: this.alreadyAppliedNumberOffset[index] };
51530
+ if (numStr === NO_CHANGE) return { value: this.alreadyAppliedNumberOffset[index] };
51349
51531
  else {
51350
51532
  const currentOffset = parseFloat(numStr.slice(1));
51351
51533
  const adjustedOffset = (this.alreadyAppliedNumberOffset[index] || 0) + currentOffset;
@@ -51768,10 +51950,10 @@ var ChartPlugin = class extends CorePlugin {
51768
51950
  if (!chart || !figureId) continue;
51769
51951
  const fig = this.getters.getFigure(cmd.sheetId, figureId);
51770
51952
  if (!fig) continue;
51771
- const figureIdBase = figureId.split("??").pop();
51772
- const duplicatedFigureId = `${cmd.sheetIdTo}${"??"}${figureIdBase}`;
51773
- const chartIdBase = chartId.split("??").pop();
51774
- const duplicatedChartId = `${cmd.sheetIdTo}${"??"}${chartIdBase}`;
51953
+ const figureIdBase = figureId.split(FIGURE_ID_SPLITTER).pop();
51954
+ const duplicatedFigureId = `${cmd.sheetIdTo}${FIGURE_ID_SPLITTER}${figureIdBase}`;
51955
+ const chartIdBase = chartId.split(FIGURE_ID_SPLITTER).pop();
51956
+ const duplicatedChartId = `${cmd.sheetIdTo}${FIGURE_ID_SPLITTER}${chartIdBase}`;
51775
51957
  const definition = chart.duplicateInDuplicatedSheet(cmd.sheetId, cmd.sheetIdTo);
51776
51958
  this.dispatch("CREATE_CHART", {
51777
51959
  figureId: duplicatedFigureId,
@@ -51880,8 +52062,8 @@ var ChartPlugin = class extends CorePlugin {
51880
52062
  * Add a figure with tag chart with the given id at the given position
51881
52063
  */
51882
52064
  addFigure(figureId, sheetId, col, row, offset, size = {
51883
- width: 536,
51884
- height: 335
52065
+ width: DEFAULT_FIGURE_WIDTH,
52066
+ height: DEFAULT_FIGURE_HEIGHT
51885
52067
  }) {
51886
52068
  this.dispatch("CREATE_FIGURE", {
51887
52069
  sheetId,
@@ -53132,8 +53314,8 @@ var FigurePlugin = class extends CorePlugin {
53132
53314
  const figureId = figure.id;
53133
53315
  const fig = this.figures[cmd.sheetId]?.[figureId];
53134
53316
  if (!fig) continue;
53135
- const figureIdBase = figureId.split("??").pop();
53136
- const duplicatedFigureId = `${cmd.sheetIdTo}${"??"}${figureIdBase}`;
53317
+ const figureIdBase = figureId.split(FIGURE_ID_SPLITTER).pop();
53318
+ const duplicatedFigureId = `${cmd.sheetIdTo}${FIGURE_ID_SPLITTER}${figureIdBase}`;
53137
53319
  this.dispatch("CREATE_FIGURE", {
53138
53320
  figureId: duplicatedFigureId,
53139
53321
  ...fig,
@@ -53171,11 +53353,11 @@ var FigurePlugin = class extends CorePlugin {
53171
53353
  const numHeader = this.getters.getNumberRows(sheetId);
53172
53354
  const remainingSize = new Array(numHeader + 1);
53173
53355
  remainingSize[numHeader] = 0;
53174
- for (let i = numHeader - 1; i >= 0; i--) remainingSize[i] = remainingSize[i + 1] + (this.getters.getUserRowSize(sheetId, i) ?? 23);
53356
+ for (let i = numHeader - 1; i >= 0; i--) remainingSize[i] = remainingSize[i + 1] + (this.getters.getUserRowSize(sheetId, i) ?? DEFAULT_CELL_HEIGHT);
53175
53357
  for (const figure of this.getFigures(sheetId)) if (figure.offset.y + figure.height > remainingSize[figure.row]) {
53176
53358
  let y = figure.offset.y;
53177
53359
  let row = figure.row;
53178
- for (let row_size = this.getters.getUserRowSize(sheetId, row) ?? 23; row_size < y; row_size = this.getters.getUserRowSize(sheetId, row) ?? 23) {
53360
+ for (let row_size = this.getters.getUserRowSize(sheetId, row) ?? DEFAULT_CELL_HEIGHT; row_size < y; row_size = this.getters.getUserRowSize(sheetId, row) ?? DEFAULT_CELL_HEIGHT) {
53179
53361
  row += 1;
53180
53362
  y -= row_size;
53181
53363
  }
@@ -53200,7 +53382,7 @@ var FigurePlugin = class extends CorePlugin {
53200
53382
  let rowNum, colNum;
53201
53383
  let { col, row } = figure;
53202
53384
  const offset = { ...figure.offset };
53203
- for (rowNum = numberOfRows; availableHeight < figure.height && rowNum > 0; rowNum--) availableHeight += this.getters.getUserRowSize(sheetId, rowNum - 1) ?? 23;
53385
+ for (rowNum = numberOfRows; availableHeight < figure.height && rowNum > 0; rowNum--) availableHeight += this.getters.getUserRowSize(sheetId, rowNum - 1) ?? DEFAULT_CELL_HEIGHT;
53204
53386
  if (row > rowNum) {
53205
53387
  row = rowNum;
53206
53388
  offset.y = Math.max(availableHeight - figure.height, 0);
@@ -53681,7 +53863,7 @@ var HeaderSizePlugin = class extends CorePlugin {
53681
53863
  }
53682
53864
  }
53683
53865
  getColSize(sheetId, index) {
53684
- return Math.round(this.sizes[sheetId]?.["COL"][index] || 96);
53866
+ return Math.round(this.sizes[sheetId]?.["COL"][index] || DEFAULT_CELL_WIDTH);
53685
53867
  }
53686
53868
  getUserRowSize(sheetId, index) {
53687
53869
  const rowSize = this.sizes[sheetId]?.["ROW"][index];
@@ -53714,7 +53896,7 @@ var HeaderSizePlugin = class extends CorePlugin {
53714
53896
  if (sheet.rows === void 0) sheet.rows = {};
53715
53897
  for (const row of range(0, this.getters.getNumberRows(sheet.id))) if (exportDefaults || this.sizes[sheet.id]["ROW"][row]) sheet.rows[row] = {
53716
53898
  ...sheet.rows[row],
53717
- size: this.getUserRowSize(sheet.id, row) ?? 23
53899
+ size: this.getUserRowSize(sheet.id, row) ?? DEFAULT_CELL_HEIGHT
53718
53900
  };
53719
53901
  if (sheet.cols === void 0) sheet.cols = {};
53720
53902
  for (const col of range(0, this.getters.getNumberCols(sheet.id))) if (exportDefaults || this.sizes[sheet.id]["COL"][col]) sheet.cols[col] = {
@@ -53895,8 +54077,8 @@ var ImagePlugin = class extends CorePlugin {
53895
54077
  case "DUPLICATE_SHEET": {
53896
54078
  const sheetFiguresFrom = this.getters.getFigures(cmd.sheetId);
53897
54079
  for (const fig of sheetFiguresFrom) if (fig.tag === "image") {
53898
- const figureIdBase = fig.id.split("??").pop();
53899
- const duplicatedFigureId = `${cmd.sheetIdTo}${"??"}${figureIdBase}`;
54080
+ const figureIdBase = fig.id.split(FIGURE_ID_SPLITTER).pop();
54081
+ const duplicatedFigureId = `${cmd.sheetIdTo}${FIGURE_ID_SPLITTER}${figureIdBase}`;
53900
54082
  const image = this.getImage(fig.id);
53901
54083
  if (image) {
53902
54084
  const size = {
@@ -57777,8 +57959,8 @@ iconsOnCellRegistry.add("data_validation_checkbox", (getters, position) => {
57777
57959
  hoverSvg,
57778
57960
  priority: 2,
57779
57961
  horizontalAlign: "center",
57780
- size: 17,
57781
- margin: 2,
57962
+ size: GRID_ICON_EDGE_LENGTH,
57963
+ margin: GRID_ICON_MARGIN,
57782
57964
  position,
57783
57965
  type: "data_validation_checkbox",
57784
57966
  onClick: (position, env) => {
@@ -57825,7 +58007,7 @@ iconsOnCellRegistry.add("conditional_formatting", (getters, position) => {
57825
58007
  priority: 1,
57826
58008
  horizontalAlign: "left",
57827
58009
  size: computeTextFontSizeInPixels(style),
57828
- margin: 4,
58010
+ margin: MIN_CF_ICON_MARGIN,
57829
58011
  position
57830
58012
  };
57831
58013
  }
@@ -57840,13 +58022,13 @@ iconsOnCellRegistry.add("pivot_collapse", (getters, position) => {
57840
58022
  const fields = pivotCell.dimension === "COL" ? definition.columns : definition.rows;
57841
58023
  const hasIcon = !isDashboard && !getters.shouldShowFormulas() && pivotCell.domain.length !== fields.length;
57842
58024
  const isCollapsed = (definition.collapsedDomains?.[pivotCell.dimension] ?? []).some((domain) => deepEquals(domain, pivotCell.domain));
57843
- const indent = pivotCell.dimension === "ROW" ? (pivotCell.domain.length - 1) * 15 : 0;
58025
+ const indent = pivotCell.dimension === "ROW" ? (pivotCell.domain.length - 1) * PIVOT_INDENT : 0;
57844
58026
  return {
57845
58027
  type: "pivot_collapse",
57846
58028
  priority: 4,
57847
58029
  horizontalAlign: "left",
57848
- size: hasIcon || !isDashboard && pivotCell.dimension === "ROW" && definition.rows.length > 1 ? 12 : 0,
57849
- margin: hasIcon ? 2 * 2 + indent : indent,
58030
+ size: hasIcon || !isDashboard && pivotCell.dimension === "ROW" && definition.rows.length > 1 ? PIVOT_COLLAPSE_ICON_SIZE : 0,
58031
+ margin: hasIcon ? GRID_ICON_MARGIN * 2 + indent : indent,
57850
58032
  svg: hasIcon ? getPivotIconSvg(isCollapsed, false) : void 0,
57851
58033
  hoverSvg: hasIcon ? getPivotIconSvg(isCollapsed, true) : void 0,
57852
58034
  position,
@@ -58823,7 +59005,7 @@ var EvaluationDataValidationPlugin = class extends CoreViewPlugin {
58823
59005
  return this.getDataValidationStyle(position);
58824
59006
  }
58825
59007
  getDataValidationChipStyle(position) {
58826
- if (this.hasChip(position)) return this.getDataValidationStyle(position) ?? { fillColor: "#E7E9ED" };
59008
+ if (this.hasChip(position)) return this.getDataValidationStyle(position) ?? { fillColor: GRAY_200 };
58827
59009
  }
58828
59010
  getInvalidDataValidationMessage(cellPosition) {
58829
59011
  const validationResult = this.getValidationResultForCell(cellPosition);
@@ -59052,7 +59234,7 @@ var HeaderSizeUIPlugin = class extends CoreViewPlugin {
59052
59234
  }
59053
59235
  }
59054
59236
  getRowSize(sheetId, row) {
59055
- return Math.round(this.getters.getUserRowSize(sheetId, row) ?? this.tallestCellInRow[sheetId][row]?.size ?? 23);
59237
+ return Math.round(this.getters.getUserRowSize(sheetId, row) ?? this.tallestCellInRow[sheetId][row]?.size ?? DEFAULT_CELL_HEIGHT);
59056
59238
  }
59057
59239
  getMaxAnchorOffset(sheetId, height, width) {
59058
59240
  let { numberOfRows: row, numberOfCols: col } = this.getters.getSheetSize(sheetId);
@@ -59089,8 +59271,8 @@ var HeaderSizeUIPlugin = class extends CoreViewPlugin {
59089
59271
  col,
59090
59272
  row
59091
59273
  });
59092
- if (updatedCellHeight <= 23) return;
59093
- if (!tallestCellInRow && updatedCellHeight > 23 || tallestCellInRow && updatedCellHeight > tallestCellInRow.size) {
59274
+ if (updatedCellHeight <= DEFAULT_CELL_HEIGHT) return;
59275
+ if (!tallestCellInRow && updatedCellHeight > DEFAULT_CELL_HEIGHT || tallestCellInRow && updatedCellHeight > tallestCellInRow.size) {
59094
59276
  const newTallestCell = {
59095
59277
  cell: {
59096
59278
  sheetId,
@@ -59115,7 +59297,7 @@ var HeaderSizeUIPlugin = class extends CoreViewPlugin {
59115
59297
  * merge, or the height of the cell computed based on its style/content.
59116
59298
  */
59117
59299
  getCellHeight(position) {
59118
- if (this.isInMultiRowMerge(position)) return 23;
59300
+ if (this.isInMultiRowMerge(position)) return DEFAULT_CELL_HEIGHT;
59119
59301
  const cell = this.getters.getCell(position);
59120
59302
  const colSize = this.getters.getColSize(position.sheetId, position.col);
59121
59303
  return getDefaultCellHeight(this.ctx, cell, this.getters.getLocale(), colSize);
@@ -59137,7 +59319,7 @@ var HeaderSizeUIPlugin = class extends CoreViewPlugin {
59137
59319
  if (!cell) continue;
59138
59320
  const position = this.getters.getCellPosition(cell.id);
59139
59321
  const cellHeight = this.getCellHeight(position);
59140
- if (cellHeight > maxHeight && cellHeight > 23) {
59322
+ if (cellHeight > maxHeight && cellHeight > DEFAULT_CELL_HEIGHT) {
59141
59323
  maxHeight = cellHeight;
59142
59324
  tallestCell = {
59143
59325
  cell: position,
@@ -59145,7 +59327,7 @@ var HeaderSizeUIPlugin = class extends CoreViewPlugin {
59145
59327
  };
59146
59328
  }
59147
59329
  }
59148
- if (tallestCell && tallestCell.size > 23) return tallestCell;
59330
+ if (tallestCell && tallestCell.size > DEFAULT_CELL_HEIGHT) return tallestCell;
59149
59331
  }
59150
59332
  };
59151
59333
 
@@ -59589,14 +59771,14 @@ function pivot_presentation_default(PivotClass) {
59589
59771
  * @returns the value of the cell in the pivot with the new domain, or "sameValue" if the domain is the same
59590
59772
  */
59591
59773
  getComparisonValue(measure, domain, fieldNameWithGranularity, valueToCompare) {
59592
- const comparedDomain = valueToCompare === "(previous)" || valueToCompare === "(next)" ? getPreviousOrNextValueDomain(this, domain, fieldNameWithGranularity, valueToCompare) : replaceFieldValueInDomain(domain, fieldNameWithGranularity, valueToCompare);
59774
+ const comparedDomain = valueToCompare === PREVIOUS_VALUE || valueToCompare === NEXT_VALUE ? getPreviousOrNextValueDomain(this, domain, fieldNameWithGranularity, valueToCompare) : replaceFieldValueInDomain(domain, fieldNameWithGranularity, valueToCompare);
59593
59775
  if (deepEquals(comparedDomain, domain)) return "sameValue";
59594
59776
  if (!comparedDomain || !isDomainIsInPivot(this, comparedDomain)) throw new NotAvailableError();
59595
59777
  const comparedValue = this._getPivotCellValueAndFormat(measure.id, comparedDomain);
59596
59778
  return this.strictMeasureValueToNumber(comparedValue);
59597
59779
  }
59598
59780
  getPivotValueCells(measureId) {
59599
- return this.getCollapsedTableStructure().getPivotCells().map((col) => col.filter((cell) => cell.type === "VALUE" && cell.measure === measureId)).filter((col) => col.length > 0);
59781
+ return this.getExpandedTableStructure().getPivotCells().map((col) => col.filter((cell) => cell.type === "VALUE" && cell.measure === measureId)).filter((col) => col.length > 0);
59600
59782
  }
59601
59783
  measureValueToNumber(result) {
59602
59784
  if (typeof result.value === "number") return result.value;
@@ -62106,7 +62288,7 @@ var Session = class extends EventBus {
62106
62288
  this.trigger("new-local-state-update", { id: revision.id });
62107
62289
  this.sendUpdateMessage({
62108
62290
  type: "REMOTE_REVISION",
62109
- version: 1,
62291
+ version: MESSAGE_VERSION,
62110
62292
  serverRevisionId: this.serverRevisionId,
62111
62293
  nextRevisionId: revision.id,
62112
62294
  clientId: revision.clientId,
@@ -62117,7 +62299,7 @@ var Session = class extends EventBus {
62117
62299
  this.waitingUndoRedoAck = true;
62118
62300
  this.sendUpdateMessage({
62119
62301
  type: "REVISION_UNDONE",
62120
- version: 1,
62302
+ version: MESSAGE_VERSION,
62121
62303
  serverRevisionId: this.serverRevisionId,
62122
62304
  nextRevisionId: UuidGenerator.uuidv4(),
62123
62305
  undoneRevisionId: revisionId
@@ -62127,7 +62309,7 @@ var Session = class extends EventBus {
62127
62309
  this.waitingUndoRedoAck = true;
62128
62310
  this.sendUpdateMessage({
62129
62311
  type: "REVISION_REDONE",
62130
- version: 1,
62312
+ version: MESSAGE_VERSION,
62131
62313
  serverRevisionId: this.serverRevisionId,
62132
62314
  nextRevisionId: UuidGenerator.uuidv4(),
62133
62315
  redoneRevisionId: revisionId
@@ -62168,7 +62350,7 @@ var Session = class extends EventBus {
62168
62350
  await this.sendToTransport({
62169
62351
  type: "CLIENT_LEFT",
62170
62352
  clientId: this.clientId,
62171
- version: 1
62353
+ version: MESSAGE_VERSION
62172
62354
  });
62173
62355
  }
62174
62356
  /**
@@ -62185,7 +62367,7 @@ var Session = class extends EventBus {
62185
62367
  ...data,
62186
62368
  revisionId: snapshotId
62187
62369
  },
62188
- version: 1
62370
+ version: MESSAGE_VERSION
62189
62371
  });
62190
62372
  }
62191
62373
  getCurrentClient() {
@@ -62229,7 +62411,7 @@ var Session = class extends EventBus {
62229
62411
  };
62230
62412
  this.sendToTransport({
62231
62413
  type,
62232
- version: 1,
62414
+ version: MESSAGE_VERSION,
62233
62415
  client: {
62234
62416
  ...client,
62235
62417
  position
@@ -62309,7 +62491,7 @@ var Session = class extends EventBus {
62309
62491
  const { position } = client;
62310
62492
  if (position) this.sendToTransport({
62311
62493
  type: "CLIENT_MOVED",
62312
- version: 1,
62494
+ version: MESSAGE_VERSION,
62313
62495
  client: {
62314
62496
  ...client,
62315
62497
  position
@@ -63667,7 +63849,7 @@ var HistoryPlugin = class extends UIPlugin {
63667
63849
  onNewLocalStateUpdate({ id }) {
63668
63850
  this.undoStack.push(id);
63669
63851
  this.redoStack = [];
63670
- if (this.undoStack.length > 99) this.undoStack.shift();
63852
+ if (this.undoStack.length > MAX_HISTORY_STEPS) this.undoStack.shift();
63671
63853
  }
63672
63854
  /**
63673
63855
  * Fetch the last revision which is not empty and not a repeated command
@@ -63963,7 +64145,7 @@ var SplitToColumnsPlugin = class extends UIPlugin {
63963
64145
  }
63964
64146
  getAutoSeparatorForString(str) {
63965
64147
  const separators = [
63966
- "\n",
64148
+ NEWLINE,
63967
64149
  ";",
63968
64150
  ",",
63969
64151
  " ",
@@ -64322,9 +64504,9 @@ var SheetUIPlugin = class extends UIPlugin {
64322
64504
  contentWidth += computeMultilineTextSize(this.ctx, multiLineText, style).width;
64323
64505
  }
64324
64506
  for (const icon of this.getters.getCellIcons(position)) contentWidth += icon.margin + icon.size;
64325
- if (this.getters.getDataValidationChipStyle(position)) contentWidth += 5 * 2;
64507
+ if (this.getters.getDataValidationChipStyle(position)) contentWidth += DATA_VALIDATION_CHIP_MARGIN * 2;
64326
64508
  if (contentWidth === 0) return 0;
64327
- contentWidth += 2 * 4;
64509
+ contentWidth += 2 * PADDING_AUTORESIZE_HORIZONTAL;
64328
64510
  if (style.wrapping === "wrap") {
64329
64511
  const colWidth = this.getters.getColSize(position.sheetId, position.col);
64330
64512
  return Math.min(colWidth, contentWidth);
@@ -64375,11 +64557,11 @@ var SheetUIPlugin = class extends UIPlugin {
64375
64557
  computeTextYCoordinate(cellRect, textLineHeight, verticalAlign = DEFAULT_VERTICAL_ALIGN, numberOfLines = 1) {
64376
64558
  const y = cellRect.y + 1;
64377
64559
  const textHeight = computeTextLinesHeight(textLineHeight, numberOfLines);
64378
- if (cellRect.height > textHeight + 4 * 2) {
64560
+ if (cellRect.height > textHeight + MIN_CELL_TEXT_MARGIN * 2) {
64379
64561
  if (verticalAlign === "middle") return Math.ceil(y + (cellRect.height - textHeight) / 2);
64380
- if (verticalAlign === "bottom") return y + cellRect.height - textHeight - 4;
64562
+ if (verticalAlign === "bottom") return y + cellRect.height - textHeight - MIN_CELL_TEXT_MARGIN;
64381
64563
  }
64382
- return y + 4;
64564
+ return y + MIN_CELL_TEXT_MARGIN;
64383
64565
  }
64384
64566
  /**
64385
64567
  * Expands the given zone until bordered by empty cells or reached the sheet boundaries.
@@ -64484,11 +64666,11 @@ var SheetUIPlugin = class extends UIPlugin {
64484
64666
  if (cell.isFormula || this.getters.getArrayFormulaSpreadingOn(position)) {
64485
64667
  const content = this.getters.getEvaluatedCell(position).formattedValue;
64486
64668
  const evaluatedSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
64487
- if (evaluatedSize > evaluatedRowSize && evaluatedSize > 23) evaluatedRowSize = evaluatedSize;
64669
+ if (evaluatedSize > evaluatedRowSize && evaluatedSize > DEFAULT_CELL_HEIGHT) evaluatedRowSize = evaluatedSize;
64488
64670
  } else {
64489
64671
  const content = cell.content;
64490
64672
  const dynamicRowSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
64491
- if (dynamicRowSize >= evaluatedRowSize && dynamicRowSize > 23) evaluatedRowSize = 0;
64673
+ if (dynamicRowSize >= evaluatedRowSize && dynamicRowSize > DEFAULT_CELL_HEIGHT) evaluatedRowSize = 0;
64492
64674
  }
64493
64675
  }
64494
64676
  rowSizes.push(evaluatedRowSize || null);
@@ -65189,7 +65371,7 @@ var ClipboardPlugin = class extends UIPlugin {
65189
65371
  const imageUrl = this.getters.getImage(figureId).path;
65190
65372
  file = await this.fileStore?.getFile(imageUrl);
65191
65373
  if (file.type !== "image/png") {
65192
- if (file.size > 5242880) {
65374
+ if (file.size > MAX_FILE_SIZE) {
65193
65375
  this.ui.notifyUI({
65194
65376
  text: _t("The file you are trying to copy is too large (>%sMB).\nIt will not be added to your OS clipboard.\nYou can download it directly instead.", Math.round(MAX_FILE_SIZE / (1024 * 1024))),
65195
65377
  sticky: false,
@@ -66362,7 +66544,7 @@ var InternalViewport = class {
66362
66544
  let height = lastRowEnd - this.offsetCorrectionY;
66363
66545
  if (this.canScrollVertically) {
66364
66546
  height = Math.max(height, this.viewportHeight);
66365
- if (lastRowEnd + 46 > height && !this.getters.isReadonly() && this.viewportHeight > 46) height += 46;
66547
+ if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly() && this.viewportHeight > FOOTER_HEIGHT) height += FOOTER_HEIGHT;
66366
66548
  }
66367
66549
  return {
66368
66550
  width,
@@ -66714,7 +66896,7 @@ var ViewportCollection = class {
66714
66896
  return this.getSubViewports(sheetId).some((pane) => pane.isZoneVisible(zone));
66715
66897
  }
66716
66898
  getScrollBarWidth() {
66717
- return 15 / this.zoomLevel;
66899
+ return SCROLLBAR_WIDTH / this.zoomLevel;
66718
66900
  }
66719
66901
  getEdgeScrollCol(sheetId, x, previousX, startingX) {
66720
66902
  let canEdgeScroll = false;
@@ -67241,7 +67423,7 @@ var SheetViewPlugin = class extends UIPlugin {
67241
67423
  return this.chainValidations(() => this.viewports.checkScrollingDirection(sheetId, cmd), () => this.viewports.checkIfViewportsWillChange(sheetId, cmd))(cmd);
67242
67424
  }
67243
67425
  case "RESIZE_SHEETVIEW": return this.chainValidations(() => this.viewports.checkValuesAreDifferent(cmd), () => this.viewports.checkPositiveDimension(cmd))(cmd);
67244
- case "SET_ZOOM": if (cmd.zoom > 2 || cmd.zoom < .5) return "InvalidZoomLevel";
67426
+ case "SET_ZOOM": if (isNaN(cmd.zoom) || cmd.zoom > MAX_ZOOM_LEVEL || cmd.zoom < MIN_ZOOM_LEVEL) return "InvalidZoomLevel";
67245
67427
  else return "Success";
67246
67428
  default: return "Success";
67247
67429
  }
@@ -67445,7 +67627,7 @@ var SheetViewPlugin = class extends UIPlugin {
67445
67627
  return this.viewports.isVisibleInViewport(cellPosition);
67446
67628
  }
67447
67629
  getScrollBarWidth() {
67448
- return 15 / this.viewports.getZoomLevel();
67630
+ return SCROLLBAR_WIDTH / this.viewports.getZoomLevel();
67449
67631
  }
67450
67632
  getEdgeScrollCol(x, previousX, startingX) {
67451
67633
  const sheetId = this.getters.getActiveSheetId();
@@ -69692,16 +69874,16 @@ var RowGroup = class extends AbstractHeaderGroup {
69692
69874
  const startCoordinates = this.env.model.getters.getRowDimensions(sheetId, startRow).start;
69693
69875
  const endCoordinates = this.env.model.getters.getRowDimensions(sheetId, endRow).end;
69694
69876
  let groupHeaderY = 0;
69695
- let groupHeaderHeight = 26;
69877
+ let groupHeaderHeight = HEADER_HEIGHT;
69696
69878
  if (startRow !== 0) {
69697
69879
  const headerRowDims = this.env.model.getters.getRowDimensions(sheetId, startRow - 1);
69698
- groupHeaderY = 26 + headerRowDims.start;
69880
+ groupHeaderY = HEADER_HEIGHT + headerRowDims.start;
69699
69881
  groupHeaderHeight = headerRowDims.end - headerRowDims.start;
69700
69882
  }
69701
69883
  const headerRect = {
69702
69884
  x: this.props.layerOffset,
69703
69885
  y: groupHeaderY,
69704
- width: 21,
69886
+ width: GROUP_LAYER_WIDTH,
69705
69887
  height: groupHeaderHeight
69706
69888
  };
69707
69889
  return {
@@ -69709,7 +69891,7 @@ var RowGroup = class extends AbstractHeaderGroup {
69709
69891
  groupRect: {
69710
69892
  x: this.props.layerOffset,
69711
69893
  y: headerRect.y,
69712
- width: 21,
69894
+ width: GROUP_LAYER_WIDTH,
69713
69895
  height: headerRect.height + (endCoordinates - startCoordinates)
69714
69896
  },
69715
69897
  isEndHidden: this.env.model.getters.isRowHidden(sheetId, endRow)
@@ -69742,17 +69924,17 @@ var ColGroup = class extends AbstractHeaderGroup {
69742
69924
  const startCoordinates = this.env.model.getters.getColDimensions(sheetId, startCol).start;
69743
69925
  const endCoordinates = this.env.model.getters.getColDimensions(sheetId, endCol).end;
69744
69926
  let groupHeaderX = 0;
69745
- let groupHeaderWidth = 48;
69927
+ let groupHeaderWidth = HEADER_WIDTH;
69746
69928
  if (startCol !== 0) {
69747
69929
  const headerRowDims = this.env.model.getters.getColDimensions(sheetId, startCol - 1);
69748
- groupHeaderX = 48 + headerRowDims.start;
69930
+ groupHeaderX = HEADER_WIDTH + headerRowDims.start;
69749
69931
  groupHeaderWidth = headerRowDims.end - headerRowDims.start;
69750
69932
  }
69751
69933
  const headerRect = {
69752
69934
  x: groupHeaderX,
69753
69935
  y: this.props.layerOffset,
69754
69936
  width: groupHeaderWidth,
69755
- height: 21
69937
+ height: GROUP_LAYER_WIDTH
69756
69938
  };
69757
69939
  return {
69758
69940
  headerRect,
@@ -69760,7 +69942,7 @@ var ColGroup = class extends AbstractHeaderGroup {
69760
69942
  x: headerRect.x,
69761
69943
  y: this.props.layerOffset,
69762
69944
  width: headerRect.width + (endCoordinates - startCoordinates),
69763
- height: 21
69945
+ height: GROUP_LAYER_WIDTH
69764
69946
  },
69765
69947
  isEndHidden: this.env.model.getters.isColHidden(sheetId, endCol)
69766
69948
  };
@@ -69786,7 +69968,7 @@ var HeaderGroupContainer = class extends Component {
69786
69968
  menuItems: []
69787
69969
  });
69788
69970
  getLayerOffset(layerIndex) {
69789
- return layerIndex * 21;
69971
+ return layerIndex * GROUP_LAYER_WIDTH;
69790
69972
  }
69791
69973
  onContextMenu(event) {
69792
69974
  const sheetId = this.env.model.getters.getActiveSheetId();
@@ -69834,8 +70016,8 @@ var HeaderGroupContainer = class extends Component {
69834
70016
  get frozenPaneContainerSize() {
69835
70017
  if (!this.hasFrozenPane) return 0;
69836
70018
  const viewportCoordinates = this.env.model.getters.getMainViewportCoordinates();
69837
- if (this.props.dimension === "COL") return 48 + viewportCoordinates.x;
69838
- else return 26 + viewportCoordinates.y;
70019
+ if (this.props.dimension === "COL") return HEADER_WIDTH + viewportCoordinates.x;
70020
+ else return HEADER_HEIGHT + viewportCoordinates.y;
69839
70021
  }
69840
70022
  };
69841
70023
 
@@ -69844,7 +70026,7 @@ var HeaderGroupContainer = class extends Component {
69844
70026
  function useScreenWidth() {
69845
70027
  const spreadsheetRect = useSpreadsheetRect();
69846
70028
  return { get isSmall() {
69847
- return spreadsheetRect.width < 768;
70029
+ return spreadsheetRect.width < MOBILE_WIDTH_BREAKPOINT;
69848
70030
  } };
69849
70031
  }
69850
70032
 
@@ -70635,7 +70817,7 @@ var TopBarComposer = class extends Component {
70635
70817
  "line-height": "24px"
70636
70818
  };
70637
70819
  if (this.env.model.getters.isCurrentSheetLocked()) style["pointer-events"] = "none";
70638
- style.height = this.focus === "inactive" ? `${34}px` : "fit-content";
70820
+ style.height = this.focus === "inactive" ? `${DESKTOP_TOPBAR_TOOLBAR_HEIGHT}px` : "fit-content";
70639
70821
  return cssPropertiesToCss(style);
70640
70822
  }
70641
70823
  onFocus(selection) {
@@ -71289,14 +71471,17 @@ var ToolBarZoom = class extends Component {
71289
71471
  props = (0, _odoo_owl.useProps)({ class: types.string() });
71290
71472
  topBarToolStore;
71291
71473
  valueList = ZOOM_VALUES;
71474
+ minZoom = MIN_ZOOM_LEVEL * 100;
71475
+ maxZoom = MAX_ZOOM_LEVEL * 100;
71292
71476
  setup() {
71293
71477
  this.topBarToolStore = useToolBarDropdownStore();
71294
71478
  }
71295
- get currentFontSize() {
71296
- return (this.env.model.getters.getViewportZoomLevel() || 1) * 100;
71479
+ getZoomLevel() {
71480
+ const zoom = this.env.model.getters.getViewportZoomLevel() || 1;
71481
+ return Math.round(zoom * 100);
71297
71482
  }
71298
- setZoom(fontSize) {
71299
- this.env.model.dispatch("SET_ZOOM", { zoom: fontSize / 100 });
71483
+ setZoom(zoomPercentage) {
71484
+ this.env.model.dispatch("SET_ZOOM", { zoom: zoomPercentage / 100 });
71300
71485
  }
71301
71486
  toggle() {
71302
71487
  if (this.topBarToolStore.isActive) this.topBarToolStore.closeDropdowns();
@@ -71830,7 +72015,7 @@ var Spreadsheet = class extends Component {
71830
72015
  else {
71831
72016
  if (this.env.model.getters.isDashboard()) properties["grid-template-rows"] = `auto`;
71832
72017
  else properties["grid-template-rows"] = `min-content auto min-content`;
71833
- properties["grid-template-columns"] = `auto ${this.sidePanel.mainPanel ? `${this.sidePanel.totalPanelSize || 350}px` : "auto"}`;
72018
+ properties["grid-template-columns"] = `auto ${this.sidePanel.mainPanel ? `${this.sidePanel.totalPanelSize || DEFAULT_SIDE_PANEL_SIZE}px` : "auto"}`;
71834
72019
  }
71835
72020
  return cssPropertiesToCss(properties);
71836
72021
  }
@@ -71936,7 +72121,7 @@ var Spreadsheet = class extends Component {
71936
72121
  checkViewportSize() {
71937
72122
  const { xRatio, yRatio } = this.env.model.getters.getFrozenSheetViewRatio(this.env.model.getters.getActiveSheetId());
71938
72123
  if (!isFinite(xRatio) || !isFinite(yRatio)) return;
71939
- if (yRatio > .85 || xRatio > .85) {
72124
+ if (yRatio > MAXIMAL_FREEZABLE_RATIO || xRatio > MAXIMAL_FREEZABLE_RATIO) {
71940
72125
  if (this.isViewportTooSmall) return;
71941
72126
  this.notificationStore.notifyUser({
71942
72127
  text: _t("The current window is too small to display this sheet properly. Consider resizing your browser window or adjusting frozen rows and columns."),
@@ -71954,8 +72139,8 @@ var Spreadsheet = class extends Component {
71954
72139
  return this.env.model.getters.getSheetViewDimension().height;
71955
72140
  }
71956
72141
  get gridContainerStyle() {
71957
- const gridColSize = 21 * this.rowLayers.length;
71958
- const gridRowSize = 21 * this.colLayers.length;
72142
+ const gridColSize = GROUP_LAYER_WIDTH * this.rowLayers.length;
72143
+ const gridRowSize = GROUP_LAYER_WIDTH * this.colLayers.length;
71959
72144
  const zoom = this.env.model.getters.getViewportZoomLevel();
71960
72145
  return cssPropertiesToCss({
71961
72146
  "grid-template-columns": `${gridColSize ? gridColSize + 2 : 0}px auto`,
@@ -73911,7 +74096,7 @@ function createChart(chart, chartSheetIndex, data) {
73911
74096
  let title = escapeXml``;
73912
74097
  if (chart.data.title?.text) {
73913
74098
  const titleColor = chart.data.title.color ? toXlsxHexColor(chart.data.title.color) : toXlsxHexColor(chartMutedFontColor(chart.data.backgroundColor));
73914
- const fontSize = chart.data.title.fontSize ?? 16;
74099
+ const fontSize = chart.data.title.fontSize ?? CHART_TITLE_FONT_SIZE;
73915
74100
  title = escapeXml`
73916
74101
  <c:title>
73917
74102
  ${insertText(chart.data.title.text, titleColor, fontSize, chart.data.title)}
@@ -74002,7 +74187,7 @@ function lineAttributes(params) {
74002
74187
  </a:ln>
74003
74188
  `;
74004
74189
  }
74005
- function insertText(text, fontColor = "000000", fontsize = 16, style = {}) {
74190
+ function insertText(text, fontColor = "000000", fontsize = CHART_TITLE_FONT_SIZE, style = {}) {
74006
74191
  return escapeXml`
74007
74192
  <c:tx>
74008
74193
  <c:rich>
@@ -74583,7 +74768,7 @@ function addDoughnutChart(chart, chartSheetIndex, data) {
74583
74768
  return escapeXml`
74584
74769
  <c:doughnutChart>
74585
74770
  <c:varyColors val="1" />
74586
- <c:holeSize val="${chart.pieHolePercentage ?? (chart.isDoughnut ? 50 : 0)}" />
74771
+ <c:holeSize val="${chart.pieHolePercentage ?? (chart.isDoughnut ? DEFAULT_DOUGHNUT_CHART_HOLE_SIZE : 0)}" />
74587
74772
  ${joinXmlNodes(dataSetsNodes)}
74588
74773
  ${insertDataLabels({ showValues: chart.showValues })}
74589
74774
  </c:doughnutChart>
@@ -74607,7 +74792,7 @@ function insertDataLabels({ showLeaderLines, showValues } = {
74607
74792
  }
74608
74793
  function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, deleteAxis = 0, orientation = "minMax", crossPosition, tickLabelPosition = "nextTo", maxValue, majorUnit, format = "General") {
74609
74794
  const color = title?.color ? toXlsxHexColor(title.color) : defaultFontColor;
74610
- const fontSize = title?.fontSize ?? 12;
74795
+ const fontSize = title?.fontSize ?? CHART_AXIS_TITLE_FONT_SIZE;
74611
74796
  const crossBetweenEl = axisName === "c:valAx" ? escapeXml`<c:crossBetween val="between" />` : "";
74612
74797
  const maxValueEl = maxValue ? escapeXml`<c:max val="${maxValue}" />` : "";
74613
74798
  const minValueEl = maxValue ? escapeXml`<c:min val="${-maxValue}" />` : "";
@@ -75235,12 +75420,12 @@ function figureCoordinates(headers, anchor, offset) {
75235
75420
  let currentPosition = 0;
75236
75421
  for (const [headerIndex, header] of headers.slice(anchor).entries()) if (currentPosition <= offset && offset < currentPosition + header.size) return {
75237
75422
  index: anchor + headerIndex,
75238
- offset: convertDotValueToEMU(offset - currentPosition + 1)
75423
+ offset: convertDotValueToEMU(offset - currentPosition + FIGURE_BORDER_WIDTH)
75239
75424
  };
75240
75425
  else if (headerIndex < headers.length - 1) currentPosition += header.size;
75241
75426
  return {
75242
75427
  index: headers.length - 1,
75243
- offset: convertDotValueToEMU(offset - currentPosition + 1)
75428
+ offset: convertDotValueToEMU(offset - currentPosition + FIGURE_BORDER_WIDTH)
75244
75429
  };
75245
75430
  }
75246
75431
  function createChartDrawing(figure, sheet, chartRelId, construct) {
@@ -75346,7 +75531,7 @@ function addSheetProtection(sheet) {
75346
75531
  function addNumberFormats(numFmts) {
75347
75532
  const numFmtNodes = [];
75348
75533
  for (const [index, numFmt] of Object.entries(numFmts)) {
75349
- const numFmtAttrs = [["numFmtId", parseInt(index) + 164], ["formatCode", numFmt.format]];
75534
+ const numFmtAttrs = [["numFmtId", parseInt(index) + FIRST_NUMFMT_ID], ["formatCode", numFmt.format]];
75350
75535
  numFmtNodes.push(escapeXml`
75351
75536
  <numFmt ${formatAttributes(numFmtAttrs)}/>
75352
75537
  `);
@@ -75582,7 +75767,7 @@ function addColumns(construct, data, sheet) {
75582
75767
  const attributes = [
75583
75768
  ["min", parseInt(id) + 1],
75584
75769
  ["max", parseInt(id) + 1],
75585
- ["width", convertWidthToExcel(col.size || 96)],
75770
+ ["width", convertWidthToExcel(col.size || DEFAULT_CELL_WIDTH)],
75586
75771
  ["customWidth", 1],
75587
75772
  ["hidden", col.isHidden ? 1 : 0]
75588
75773
  ];
@@ -75608,7 +75793,7 @@ function addRows(construct, data, sheet) {
75608
75793
  for (let r = 0; r < sheet.rowNumber; r++) {
75609
75794
  const rowAttrs = [["r", r + 1]];
75610
75795
  const row = sheet.rows[r] || {};
75611
- if (row.size && row.size !== 23) rowAttrs.push(["ht", convertHeightToExcel(row.size)], ["customHeight", 1]);
75796
+ if (row.size && row.size !== DEFAULT_CELL_HEIGHT) rowAttrs.push(["ht", convertHeightToExcel(row.size)], ["customHeight", 1]);
75612
75797
  if (row.isHidden) rowAttrs.push(["hidden", 1]);
75613
75798
  if (row.outlineLevel) rowAttrs.push(["outlineLevel", row.outlineLevel]);
75614
75799
  if (row.collapsed) rowAttrs.push(["collapsed", 1]);
@@ -75659,7 +75844,7 @@ function addRows(construct, data, sheet) {
75659
75844
  </c>`);
75660
75845
  }
75661
75846
  }
75662
- if (cellNodes.length || row.size !== 23 || row.isHidden || row.outlineLevel || row.collapsed || rowStyle || rowFormat) rowNodes.push(escapeXml`
75847
+ if (cellNodes.length || row.size !== DEFAULT_CELL_HEIGHT || row.isHidden || row.outlineLevel || row.collapsed || rowStyle || rowFormat) rowNodes.push(escapeXml`
75663
75848
  <row ${formatAttributes(rowAttrs)}>
75664
75849
  ${joinXmlNodes(cellNodes)}
75665
75850
  </row>
@@ -75849,7 +76034,7 @@ function createWorksheets(data, construct) {
75849
76034
  let currentTableIndex = 1;
75850
76035
  for (const [sheetIndex, sheet] of Object.entries(data.sheets)) {
75851
76036
  const namespaces = [["xmlns", NAMESPACE["worksheet"]], ["xmlns:r", RELATIONSHIP_NSR]];
75852
- const sheetFormatAttributes = [["defaultRowHeight", convertHeightToExcel(23)], ["defaultColWidth", convertWidthToExcel(96)]];
76037
+ const sheetFormatAttributes = [["defaultRowHeight", convertHeightToExcel(DEFAULT_CELL_HEIGHT)], ["defaultColWidth", convertWidthToExcel(DEFAULT_CELL_WIDTH)]];
75853
76038
  const tablesNode = createTablesForSheet(sheet, sheetIndex, currentTableIndex, construct, files);
75854
76039
  currentTableIndex += sheet.tables.length;
75855
76040
  let drawingNode = escapeXml``;
@@ -76551,7 +76736,7 @@ var Model = class Model extends EventBus {
76551
76736
  _exportData(shouldSquish) {
76552
76737
  let data = createEmptyWorkbookData();
76553
76738
  for (const handler of this.handlers) if (handler instanceof CorePlugin) handler.export(data, shouldSquish);
76554
- data.revisionId = this.session.getRevisionId() || "START_REVISION";
76739
+ data.revisionId = this.session.getRevisionId() || DEFAULT_REVISION_ID;
76555
76740
  data = deepCopy(data);
76556
76741
  return data;
76557
76742
  }
@@ -77951,7 +78136,7 @@ var LinkDisplay = class extends Component {
77951
78136
  col,
77952
78137
  row
77953
78138
  });
77954
- const textColor = style?.textColor === "#017E84" ? void 0 : style?.textColor;
78139
+ const textColor = style?.textColor === LINK_COLOR ? void 0 : style?.textColor;
77955
78140
  this.env.model.dispatch("UPDATE_CELL", {
77956
78141
  col,
77957
78142
  row,
@@ -78465,8 +78650,8 @@ autoCompleteProviders.add("dataValidation", {
78465
78650
  text: value.value,
78466
78651
  htmlContent: [{
78467
78652
  value: value.label,
78468
- color: chipTextColor(color || "#E7E9ED"),
78469
- backgroundColor: color || "#E7E9ED",
78653
+ color: chipTextColor(color || GRAY_200),
78654
+ backgroundColor: color || GRAY_200,
78470
78655
  classes: ["badge rounded-pill fs-6 fw-normal w-100 mt-1 text-start"]
78471
78656
  }],
78472
78657
  fuzzySearchKey: value.label
@@ -79009,7 +79194,7 @@ const BubbleChart = {
79009
79194
  legend: getBubbleChartLegend(definition, chartData),
79010
79195
  tooltip: getBubbleChartTooltip(definition, chartData),
79011
79196
  chartShowValuesPlugin: getChartShowValues(definition, chartData),
79012
- background: { color: definition.background }
79197
+ background: { color: chartData.background }
79013
79198
  }
79014
79199
  }
79015
79200
  } };
@@ -79120,7 +79305,7 @@ const ComboChart = {
79120
79305
  getDefinitionForExcel(getters, definition, { dataSets, labelRange }) {
79121
79306
  return {
79122
79307
  ...definition,
79123
- backgroundColor: toXlsxHexColor(definition.background || "#FFFFFF"),
79308
+ backgroundColor: toXlsxHexColor(definition.background || DEFAULT_CHART_BACKGROUND_COLOR),
79124
79309
  fontColor: toXlsxHexColor(chartFontColor(definition.background)),
79125
79310
  dataSets,
79126
79311
  labelRange,
@@ -79365,7 +79550,7 @@ const PyramidChart = {
79365
79550
  return {
79366
79551
  ...definition,
79367
79552
  horizontal: true,
79368
- backgroundColor: toXlsxHexColor(definition.background || "#FFFFFF"),
79553
+ backgroundColor: toXlsxHexColor(definition.background || DEFAULT_CHART_BACKGROUND_COLOR),
79369
79554
  fontColor: toXlsxHexColor(chartFontColor(definition.background)),
79370
79555
  dataSets,
79371
79556
  labelRange,
@@ -79449,7 +79634,7 @@ const RadarChart = {
79449
79634
  getDefinitionForExcel(getters, definition, { dataSets, labelRange }) {
79450
79635
  return {
79451
79636
  ...definition,
79452
- backgroundColor: toXlsxHexColor(definition.background || "#FFFFFF"),
79637
+ backgroundColor: toXlsxHexColor(definition.background || DEFAULT_CHART_BACKGROUND_COLOR),
79453
79638
  fontColor: toXlsxHexColor(chartFontColor(definition.background)),
79454
79639
  dataSets,
79455
79640
  labelRange
@@ -79528,7 +79713,7 @@ const ScatterChart = {
79528
79713
  getDefinitionForExcel(getters, definition, { dataSets, labelRange }) {
79529
79714
  return {
79530
79715
  ...definition,
79531
- backgroundColor: toXlsxHexColor(definition.background || "#FFFFFF"),
79716
+ backgroundColor: toXlsxHexColor(definition.background || DEFAULT_CHART_BACKGROUND_COLOR),
79532
79717
  fontColor: toXlsxHexColor(chartFontColor(definition.background)),
79533
79718
  dataSets,
79534
79719
  labelRange,
@@ -79935,8 +80120,8 @@ iconsOnCellRegistry.add("filter_icon", (getters, position) => {
79935
80120
  hoverSvg: getDataFilterIcon(isFilterActive, isHighContrast, true),
79936
80121
  priority: 3,
79937
80122
  horizontalAlign: "right",
79938
- size: 17,
79939
- margin: 2,
80123
+ size: GRID_ICON_EDGE_LENGTH,
80124
+ margin: GRID_ICON_MARGIN,
79940
80125
  position,
79941
80126
  onClick: (position, env) => {
79942
80127
  const cellPopovers = env.getStore(CellPopoverStore);
@@ -85968,7 +86153,7 @@ const PIVOT = {
85968
86153
  const error = pivot.assertIsValid({ throwOnError: false });
85969
86154
  if (error) return error;
85970
86155
  const table = pivot.getCollapsedTableStructure();
85971
- if (table.numberOfCells > 5e5) return new EvaluationError(getPivotTooBigErrorMessage(table.numberOfCells, this.locale));
86156
+ if (table.numberOfCells > PIVOT_MAX_NUMBER_OF_CELLS) return new EvaluationError(getPivotTooBigErrorMessage(table.numberOfCells, this.locale));
85972
86157
  const cells = table.getPivotCells(pivotStyle);
85973
86158
  const pivotTitle = this.getters.getPivotName(pivotId);
85974
86159
  const { numberOfCols, numberOfRows } = table.getPivotTableDimensions(pivotStyle);
@@ -87666,14 +87851,14 @@ for (const category of categories) {
87666
87851
  */
87667
87852
  const __info__ = {};
87668
87853
  const SPREADSHEET_DIMENSIONS = {
87669
- MIN_ROW_HEIGHT: 10,
87670
- MIN_COL_WIDTH: 5,
87671
- HEADER_HEIGHT: 26,
87672
- HEADER_WIDTH: 48,
87673
- DESKTOP_BOTTOMBAR_HEIGHT: 36,
87674
- DEFAULT_CELL_WIDTH: 96,
87675
- DEFAULT_CELL_HEIGHT: 23,
87676
- SCROLLBAR_WIDTH: 15
87854
+ MIN_ROW_HEIGHT,
87855
+ MIN_COL_WIDTH,
87856
+ HEADER_HEIGHT,
87857
+ HEADER_WIDTH,
87858
+ DESKTOP_BOTTOMBAR_HEIGHT,
87859
+ DEFAULT_CELL_WIDTH,
87860
+ DEFAULT_CELL_HEIGHT,
87861
+ SCROLLBAR_WIDTH
87677
87862
  };
87678
87863
  const registries = {
87679
87864
  autoCompleteProviders,
@@ -87913,9 +88098,9 @@ const constants = {
87913
88098
  PIVOT_STATIC_TABLE_CONFIG,
87914
88099
  PIVOT_INSERT_TABLE_STYLE_ID,
87915
88100
  ChartTerms,
87916
- FIGURE_ID_SPLITTER: "??",
87917
- GRID_ICON_EDGE_LENGTH: 17,
87918
- GRID_ICON_MARGIN: 2,
88101
+ FIGURE_ID_SPLITTER,
88102
+ GRID_ICON_EDGE_LENGTH,
88103
+ GRID_ICON_MARGIN,
87919
88104
  CHART_TYPES,
87920
88105
  DARK_MODE_FILTER_STRING
87921
88106
  };
@@ -88021,6 +88206,6 @@ exports.stores = stores;
88021
88206
  exports.tokenColors = tokenColors;
88022
88207
  exports.tokenize = tokenize;
88023
88208
 
88024
- __info__.version = "19.4.12";
88025
- __info__.date = "2026-09-10T05:38:01.898Z";
88026
- __info__.hash = "cdb63b4";
88209
+ __info__.version = "19.4.14";
88210
+ __info__.date = "2026-10-01T07:47:35.933Z";
88211
+ __info__.hash = "67c7fe5";