@odoo/o-spreadsheet 19.1.2 → 19.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 19.1.2
6
- * @date 2026-01-07T16:21:36.757Z
7
- * @hash febc3e9
5
+ * @version 19.1.4
6
+ * @date 2026-01-21T11:07:17.372Z
7
+ * @hash ceae12a
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, useExternalListener, onWillUpdateProps, onWillStart, onWillPatch, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -178,6 +178,7 @@ const DEFAULT_STYLE = {
178
178
  textColor: "",
179
179
  rotation: 0,
180
180
  };
181
+ const ROTATION_EPSILON = 0.001;
181
182
  const DEFAULT_VERTICAL_ALIGN = DEFAULT_STYLE.verticalAlign;
182
183
  const DEFAULT_WRAPPING_MODE = DEFAULT_STYLE.wrapping;
183
184
  // Fonts
@@ -3840,7 +3841,11 @@ function evaluatePredicate(value = "", criterion, locale) {
3840
3841
  if (operator === "<>" || operator === "=") {
3841
3842
  let result;
3842
3843
  if (typeof value === typeof operand) {
3843
- if (typeof value === "string" && typeof operand === "string") {
3844
+ if (value === "" && operand === "") {
3845
+ // fast path to avoid regex evaluation
3846
+ result = true;
3847
+ }
3848
+ else if (typeof value === "string" && typeof operand === "string") {
3844
3849
  result = wildcardToRegExp(operand).test(value);
3845
3850
  }
3846
3851
  else {
@@ -4194,7 +4199,16 @@ function createComputeFunction(descr) {
4194
4199
  }
4195
4200
  acceptToVectorize.push(!argDefinition.acceptMatrix);
4196
4201
  }
4197
- return applyVectorization(errorHandlingCompute.bind(this), args, acceptToVectorize);
4202
+ return replaceErrorPlaceholderInResult(applyVectorization(errorHandlingCompute.bind(this), args, acceptToVectorize));
4203
+ }
4204
+ function replaceErrorPlaceholderInResult(result) {
4205
+ if (!isMatrix(result)) {
4206
+ replaceFunctionNamePlaceholder(result, descr.name);
4207
+ }
4208
+ else {
4209
+ matrixForEach(result, (result) => replaceFunctionNamePlaceholder(result, descr.name));
4210
+ }
4211
+ return result;
4198
4212
  }
4199
4213
  function errorHandlingCompute(...args) {
4200
4214
  for (let i = 0; i < args.length; i++) {
@@ -4223,13 +4237,12 @@ function createComputeFunction(descr) {
4223
4237
  const result = descr.compute.apply(this, args);
4224
4238
  if (!isMatrix(result)) {
4225
4239
  if (typeof result === "object" && result !== null && "value" in result) {
4226
- replaceFunctionNamePlaceholder(result, descr.name);
4227
4240
  return result;
4228
4241
  }
4242
+ descr.name;
4229
4243
  return { value: result };
4230
4244
  }
4231
4245
  if (typeof result[0][0] === "object" && result[0][0] !== null && "value" in result[0][0]) {
4232
- matrixForEach(result, (result) => replaceFunctionNamePlaceholder(result, descr.name));
4233
4246
  return result;
4234
4247
  }
4235
4248
  return matrixMap(result, (row) => ({ value: row }));
@@ -15491,9 +15504,10 @@ function assertDomainLength(domain) {
15491
15504
  throw new EvaluationError(_t("Function PIVOT takes an even number of arguments."));
15492
15505
  }
15493
15506
  }
15494
- function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
15507
+ function addPivotDependencies(evalContext, pivotId, forMeasures) {
15495
15508
  //TODO This function can be very costly when used with PIVOT.VALUE and PIVOT.HEADER
15496
15509
  const dependencies = [];
15510
+ const coreDefinition = evalContext.getters.getPivotCoreDefinition(pivotId);
15497
15511
  if (coreDefinition.type === "SPREADSHEET" && coreDefinition.dataSet) {
15498
15512
  const { sheetId, zone } = coreDefinition.dataSet;
15499
15513
  const xc = zoneToXc(zone);
@@ -15510,8 +15524,7 @@ function addPivotDependencies(evalContext, coreDefinition, forMeasures) {
15510
15524
  }
15511
15525
  for (const measure of forMeasures) {
15512
15526
  if (measure.computedBy) {
15513
- const formula = evalContext.getters.getMeasureCompiledFormula(measure);
15514
- dependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
15527
+ dependencies.push(...evalContext.getters.getMeasureFullDependencies(pivotId, measure));
15515
15528
  }
15516
15529
  }
15517
15530
  const originPosition = evalContext.__originCellPosition;
@@ -16008,7 +16021,7 @@ const PIVOT_VALUE = {
16008
16021
  assertDomainLength(domainArgs);
16009
16022
  const pivot = this.getters.getPivot(pivotId);
16010
16023
  const coreDefinition = this.getters.getPivotCoreDefinition(pivotId);
16011
- addPivotDependencies(this, coreDefinition, coreDefinition.measures.filter((m) => m.id === _measure));
16024
+ addPivotDependencies(this, pivotId, coreDefinition.measures.filter((m) => m.id === _measure));
16012
16025
  pivot.init({ reload: pivot.needsReevaluation });
16013
16026
  const error = pivot.assertIsValid({ throwOnError: false });
16014
16027
  if (error) {
@@ -16041,8 +16054,7 @@ const PIVOT_HEADER = {
16041
16054
  const _pivotId = getPivotId(_pivotFormulaId, this.getters);
16042
16055
  assertDomainLength(domainArgs);
16043
16056
  const pivot = this.getters.getPivot(_pivotId);
16044
- const coreDefinition = this.getters.getPivotCoreDefinition(_pivotId);
16045
- addPivotDependencies(this, coreDefinition, []);
16057
+ addPivotDependencies(this, _pivotId, []);
16046
16058
  pivot.init({ reload: pivot.needsReevaluation });
16047
16059
  const error = pivot.assertIsValid({ throwOnError: false });
16048
16060
  if (error) {
@@ -16094,7 +16106,7 @@ const PIVOT = {
16094
16106
  if (pivotStyle.numberOfColumns < 0) {
16095
16107
  return new EvaluationError(_t("The number of columns must be positive."));
16096
16108
  }
16097
- addPivotDependencies(this, coreDefinition, coreDefinition.measures);
16109
+ addPivotDependencies(this, pivotId, coreDefinition.measures);
16098
16110
  pivot.init({ reload: pivot.needsReevaluation });
16099
16111
  const error = pivot.assertIsValid({ throwOnError: false });
16100
16112
  if (error) {
@@ -18341,7 +18353,8 @@ function createAction(item) {
18341
18353
  return children
18342
18354
  .map((child) => (typeof child === "function" ? child(env) : child))
18343
18355
  .flat()
18344
- .map(createAction);
18356
+ .map(createAction)
18357
+ .sort((a, b) => a.sequence - b.sequence);
18345
18358
  }
18346
18359
  : () => [],
18347
18360
  isReadonlyAllowed: item.isReadonlyAllowed || false,
@@ -20002,7 +20015,7 @@ function getApplyRangeChangeRemoveColRow(cmd) {
20002
20015
  const groups = groupConsecutive(elements);
20003
20016
  return (range) => {
20004
20017
  if (range.sheetId !== cmd.sheetId) {
20005
- return { changeType: "NONE" };
20018
+ return { changeType: "NONE", range };
20006
20019
  }
20007
20020
  let newRange = range;
20008
20021
  let changeType = "NONE";
@@ -20029,10 +20042,7 @@ function getApplyRangeChangeRemoveColRow(cmd) {
20029
20042
  newRange = createAdaptedRange(newRange, dimension, changeType, -(max - min + 1));
20030
20043
  }
20031
20044
  }
20032
- if (changeType !== "NONE") {
20033
- return { changeType, range: newRange };
20034
- }
20035
- return { changeType: "NONE" };
20045
+ return { changeType, range: newRange };
20036
20046
  };
20037
20047
  }
20038
20048
  function getApplyRangeChangeAddColRow(cmd) {
@@ -20041,7 +20051,7 @@ function getApplyRangeChangeAddColRow(cmd) {
20041
20051
  const dimension = cmd.dimension === "COL" ? "columns" : "rows";
20042
20052
  return (range) => {
20043
20053
  if (range.sheetId !== cmd.sheetId) {
20044
- return { changeType: "NONE" };
20054
+ return { changeType: "NONE", range };
20045
20055
  }
20046
20056
  if (cmd.position === "after") {
20047
20057
  if (range.zone[start] <= cmd.base && cmd.base < range.zone[end]) {
@@ -20071,13 +20081,13 @@ function getApplyRangeChangeAddColRow(cmd) {
20071
20081
  };
20072
20082
  }
20073
20083
  }
20074
- return { changeType: "NONE" };
20084
+ return { changeType: "NONE", range };
20075
20085
  };
20076
20086
  }
20077
20087
  function getApplyRangeChangeDeleteSheet(cmd) {
20078
20088
  return (range) => {
20079
20089
  if (range.sheetId !== cmd.sheetId && range.invalidSheetName !== cmd.sheetName) {
20080
- return { changeType: "NONE" };
20090
+ return { changeType: "NONE", range };
20081
20091
  }
20082
20092
  const invalidSheetName = cmd.sheetName;
20083
20093
  range = {
@@ -20104,14 +20114,14 @@ function getApplyRangeChangeRenameSheet(cmd) {
20104
20114
  const newRange = { ...range, sheetId, invalidSheetName };
20105
20115
  return { changeType: "CHANGE", range: newRange };
20106
20116
  }
20107
- return { changeType: "NONE" };
20117
+ return { changeType: "NONE", range };
20108
20118
  };
20109
20119
  }
20110
20120
  function getApplyRangeChangeMoveRange(cmd) {
20111
20121
  const originZone = cmd.target[0];
20112
20122
  return (range) => {
20113
20123
  if (range.sheetId !== cmd.sheetId || !isZoneInside(range.zone, originZone)) {
20114
- return { changeType: "NONE" };
20124
+ return { changeType: "NONE", range };
20115
20125
  }
20116
20126
  const targetSheetId = cmd.targetSheetId;
20117
20127
  const offsetX = cmd.col - originZone.left;
@@ -20232,11 +20242,20 @@ function getCanvas$1(width = 100, height = 100) {
20232
20242
  /**
20233
20243
  * Get the default height of the cell given its style.
20234
20244
  */
20235
- function getDefaultCellHeight(ctx, cell, style, colSize) {
20245
+ function getDefaultCellHeight(ctx, cell, style, locale, colSize) {
20236
20246
  if (!cell || (!cell.isFormula && !cell.content)) {
20237
20247
  return DEFAULT_CELL_HEIGHT;
20238
20248
  }
20239
- const content = cell.isFormula ? "" : cell.content;
20249
+ let content = "";
20250
+ try {
20251
+ if (!cell.isFormula) {
20252
+ const localeFormat = { format: cell.format, locale };
20253
+ content = formatValue(parseLiteral(cell.content, locale), localeFormat);
20254
+ }
20255
+ }
20256
+ catch {
20257
+ content = CellErrorType.GenericError;
20258
+ }
20240
20259
  return getCellContentHeight(ctx, content, style, colSize);
20241
20260
  }
20242
20261
  function getCellContentHeight(ctx, content, style, colSize) {
@@ -20553,7 +20572,7 @@ function computeRotationPosition(rect, style) {
20553
20572
  let { x, y } = rect; // top-left when align=left and top-right when align=right, top-center when align=center
20554
20573
  const cos = Math.cos(-style.rotation);
20555
20574
  const sin = Math.sin(-style.rotation);
20556
- const width = rect.textWidth - MIN_CELL_TEXT_MARGIN;
20575
+ const width = rect.textWidth - 2 * MIN_CELL_TEXT_MARGIN;
20557
20576
  const height = rect.textHeight;
20558
20577
  const center = style.align === "center";
20559
20578
  const rotateTowardCellCenter = (style.align === "left") === sin < 0;
@@ -20587,6 +20606,13 @@ function computeRotationPosition(rect, style) {
20587
20606
  else {
20588
20607
  if (center) {
20589
20608
  x -= sh / 2;
20609
+ y -= height / 2;
20610
+ if (rotateTowardCellCenter) {
20611
+ y += sh;
20612
+ }
20613
+ else {
20614
+ y -= sh;
20615
+ }
20590
20616
  }
20591
20617
  else if (rotateTowardCellCenter) {
20592
20618
  x -= sh;
@@ -21096,7 +21122,7 @@ function adaptFormulaStringRanges(defaultSheetId, formula, applyChange) {
21096
21122
  continue;
21097
21123
  }
21098
21124
  const sheetXC = tokens[tokenIdx].value;
21099
- const newSheetXC = adaptStringRange(defaultSheetId, sheetXC, applyChange);
21125
+ const newSheetXC = adaptStringRange(defaultSheetId, sheetXC, applyChange).range;
21100
21126
  if (sheetXC !== newSheetXC) {
21101
21127
  tokens[tokenIdx] = {
21102
21128
  value: newSheetXC,
@@ -21106,23 +21132,30 @@ function adaptFormulaStringRanges(defaultSheetId, formula, applyChange) {
21106
21132
  }
21107
21133
  return concat$1(tokens.map((token) => token.value));
21108
21134
  }
21109
- function adaptStringRange(defaultSheetId, sheetXC, applyChange) {
21135
+ function adaptStringRange(defaultSheetId, sheetXC, rangeAdapter) {
21110
21136
  const sheetName = splitReference(sheetXC).sheetName;
21111
21137
  if (sheetName
21112
- ? !isSheetNameEqual(sheetName, applyChange.sheetName.old)
21113
- : defaultSheetId !== applyChange.sheetId) {
21114
- return sheetXC;
21138
+ ? !isSheetNameEqual(sheetName, rangeAdapter.sheetName.old)
21139
+ : defaultSheetId !== rangeAdapter.sheetId) {
21140
+ return { changeType: "NONE", range: sheetXC };
21115
21141
  }
21116
- const sheetId = sheetName ? applyChange.sheetId : defaultSheetId;
21142
+ const sheetId = sheetName ? rangeAdapter.sheetId : defaultSheetId;
21117
21143
  const range = getRange(sheetXC, sheetId);
21118
21144
  if (range.invalidXc) {
21119
- return sheetXC;
21145
+ return { changeType: "NONE", range: sheetXC };
21120
21146
  }
21121
- const change = applyChange.applyChange(range);
21147
+ const change = rangeAdapter.applyChange(range);
21122
21148
  if (change.changeType === "NONE" || change.changeType === "REMOVE") {
21123
- return sheetXC;
21149
+ return { changeType: change.changeType, range: sheetXC };
21150
+ }
21151
+ const rangeStr = getRangeString(change.range, defaultSheetId, getSheetNameGetter(rangeAdapter));
21152
+ if (rangeStr === CellErrorType.InvalidReference) {
21153
+ return { changeType: "REMOVE", range: rangeStr };
21124
21154
  }
21125
- return getRangeString(change.range, defaultSheetId, getSheetNameGetter(applyChange));
21155
+ return {
21156
+ changeType: change.changeType,
21157
+ range: rangeStr,
21158
+ };
21126
21159
  }
21127
21160
  function getSheetNameGetter(applyChange) {
21128
21161
  return (sheetId) => {
@@ -21227,8 +21260,6 @@ function adaptChartRange(range, applyChange) {
21227
21260
  }
21228
21261
  const change = applyChange(range);
21229
21262
  switch (change.changeType) {
21230
- case "NONE":
21231
- return range;
21232
21263
  case "REMOVE":
21233
21264
  return undefined;
21234
21265
  default:
@@ -21380,16 +21411,16 @@ function toExcelLabelRange(getters, labelRange, shouldRemoveFirstLabel) {
21380
21411
  function transformChartDefinitionWithDataSetsWithZone(chartSheetId, definition, applyChange) {
21381
21412
  let labelRange;
21382
21413
  if (definition.labelRange) {
21383
- const adaptedRange = adaptStringRange(chartSheetId, definition.labelRange, applyChange);
21384
- if (adaptedRange !== CellErrorType.InvalidReference) {
21414
+ const { changeType, range: adaptedRange } = adaptStringRange(chartSheetId, definition.labelRange, applyChange);
21415
+ if (changeType !== "REMOVE") {
21385
21416
  labelRange = adaptedRange;
21386
21417
  }
21387
21418
  }
21388
21419
  const dataSets = [];
21389
21420
  for (const dataSet of definition.dataSets) {
21390
21421
  const newDataSet = { ...dataSet };
21391
- const adaptedRange = adaptStringRange(chartSheetId, dataSet.dataRange, applyChange);
21392
- if (adaptedRange !== CellErrorType.InvalidReference) {
21422
+ const { changeType, range: adaptedRange } = adaptStringRange(chartSheetId, dataSet.dataRange, applyChange);
21423
+ if (changeType !== "REMOVE") {
21393
21424
  newDataSet.dataRange = adaptedRange;
21394
21425
  dataSets.push(newDataSet);
21395
21426
  }
@@ -31883,7 +31914,7 @@ function addConditionalFormatCommandAdaptRange(cmd, applyChange) {
31883
31914
  cmd.cf.rule = {
31884
31915
  ...rule,
31885
31916
  rangeValues: rule.rangeValues
31886
- ? adaptStringRange(cmd.sheetId, rule.rangeValues, applyChange)
31917
+ ? adaptStringRange(cmd.sheetId, rule.rangeValues, applyChange).range
31887
31918
  : undefined,
31888
31919
  };
31889
31920
  }
@@ -34399,6 +34430,330 @@ function hexaToInt(hex) {
34399
34430
  */
34400
34431
  const DEFAULT_SYSTEM_COLOR = "FF000000";
34401
34432
 
34433
+ // -------------------------------------
34434
+ // CF HELPERS
34435
+ // -------------------------------------
34436
+ /**
34437
+ * Convert the conditional formatting o-spreadsheet operator to
34438
+ * the corresponding excel operator.
34439
+ * */
34440
+ function convertOperator(operator) {
34441
+ switch (operator) {
34442
+ case "isNotEmpty":
34443
+ return "notContainsBlanks";
34444
+ case "isEmpty":
34445
+ return "containsBlanks";
34446
+ case "notContainsText":
34447
+ return "notContainsBlanks";
34448
+ case "containsText":
34449
+ return "containsText";
34450
+ case "beginsWithText":
34451
+ return "beginsWith";
34452
+ case "endsWithText":
34453
+ return "endsWith";
34454
+ case "isGreaterThan":
34455
+ return "greaterThan";
34456
+ case "isGreaterOrEqualTo":
34457
+ return "greaterThanOrEqual";
34458
+ case "isLessThan":
34459
+ return "lessThan";
34460
+ case "isLessOrEqualTo":
34461
+ return "lessThanOrEqual";
34462
+ case "isBetween":
34463
+ return "between";
34464
+ case "isNotBetween":
34465
+ return "notBetween";
34466
+ case "isEqual":
34467
+ return "equal";
34468
+ case "isNotEqual":
34469
+ return "notEqual";
34470
+ case "customFormula":
34471
+ return "";
34472
+ case "dateIs":
34473
+ return "";
34474
+ case "dateIsBefore":
34475
+ return "lessThan";
34476
+ case "dateIsAfter":
34477
+ return "greaterThan";
34478
+ case "dateIsOnOrAfter":
34479
+ return "greaterThanOrEqual";
34480
+ case "dateIsOnOrBefore":
34481
+ return "lessThanOrEqual";
34482
+ }
34483
+ }
34484
+ // -------------------------------------
34485
+ // WORKSHEET HELPERS
34486
+ // -------------------------------------
34487
+ function getCellType(value) {
34488
+ switch (typeof value) {
34489
+ case "boolean":
34490
+ return "b";
34491
+ case "string":
34492
+ return "str";
34493
+ case "number":
34494
+ return "n";
34495
+ default:
34496
+ return undefined;
34497
+ }
34498
+ }
34499
+ function convertHeightToExcel(height) {
34500
+ return Math.round(HEIGHT_FACTOR * height * 100) / 100;
34501
+ }
34502
+ function convertWidthToExcel(width) {
34503
+ return Math.round(WIDTH_FACTOR * width * 100) / 100;
34504
+ }
34505
+ function convertHeightFromExcel(height) {
34506
+ if (!height)
34507
+ return height;
34508
+ return Math.round((height / HEIGHT_FACTOR) * 100) / 100;
34509
+ }
34510
+ function convertWidthFromExcel(width) {
34511
+ if (!width)
34512
+ return width;
34513
+ return Math.round((width / WIDTH_FACTOR) * 100) / 100;
34514
+ }
34515
+ function extractStyle(data, content, styleId, formatId, borderId) {
34516
+ const style = styleId ? data.styles[styleId] : {};
34517
+ const format = formatId ? data.formats[formatId] : undefined;
34518
+ const styles = {
34519
+ font: {
34520
+ size: style?.fontSize || DEFAULT_FONT_SIZE,
34521
+ color: { rgb: style?.textColor ? style.textColor : "000000" },
34522
+ family: 2,
34523
+ name: "Arial",
34524
+ },
34525
+ fill: style?.fillColor
34526
+ ? {
34527
+ fgColor: { rgb: style.fillColor },
34528
+ }
34529
+ : { reservedAttribute: "none" },
34530
+ numFmt: format ? { format: format, id: 0 /* id not used for export */ } : undefined,
34531
+ border: borderId || 0,
34532
+ alignment: {
34533
+ horizontal: style.align,
34534
+ vertical: style.verticalAlign
34535
+ ? V_ALIGNMENT_EXPORT_CONVERSION_MAP[style.verticalAlign]
34536
+ : undefined,
34537
+ wrapText: style.wrapping === "wrap" || content?.includes(NEWLINE) ? true : undefined,
34538
+ textRotation: style.rotation ? rotationToXLSX(style.rotation) : undefined,
34539
+ shrinkToFit: style.wrapping === "clip" ? true : undefined,
34540
+ },
34541
+ };
34542
+ styles.font["strike"] = !!style?.strikethrough || undefined;
34543
+ styles.font["underline"] = !!style?.underline || undefined;
34544
+ styles.font["bold"] = !!style?.bold || undefined;
34545
+ styles.font["italic"] = !!style?.italic || undefined;
34546
+ return styles;
34547
+ }
34548
+ function rotationToXLSX(rad) {
34549
+ let deg = Math.round((-rad / Math.PI) * 180) % 180;
34550
+ if (deg > 90) {
34551
+ deg -= 180;
34552
+ }
34553
+ else if (deg < -90) {
34554
+ deg += 180;
34555
+ }
34556
+ if (deg >= 0) {
34557
+ return deg;
34558
+ }
34559
+ else {
34560
+ return 90 - deg;
34561
+ }
34562
+ }
34563
+ function rotationFromXLSX(deg) {
34564
+ if (deg <= 90) {
34565
+ return -(deg / 180) * Math.PI;
34566
+ }
34567
+ else {
34568
+ return (-(90 - deg) / 180) * Math.PI;
34569
+ }
34570
+ }
34571
+ function normalizeStyle(construct, styles) {
34572
+ // Normalize this
34573
+ const numFmtId = convertFormat(styles["numFmt"], construct.numFmts);
34574
+ const style = {
34575
+ fontId: pushElement(styles.font, construct.fonts),
34576
+ fillId: pushElement(styles.fill, construct.fills),
34577
+ borderId: styles.border,
34578
+ numFmtId,
34579
+ alignment: {
34580
+ vertical: styles.alignment.vertical,
34581
+ horizontal: styles.alignment.horizontal,
34582
+ wrapText: styles.alignment.wrapText,
34583
+ textRotation: styles.alignment.textRotation,
34584
+ shrinkToFit: styles.alignment.shrinkToFit,
34585
+ },
34586
+ };
34587
+ return pushElement(style, construct.styles);
34588
+ }
34589
+ function convertFormat(format, numFmtStructure) {
34590
+ if (!format) {
34591
+ return 0;
34592
+ }
34593
+ let formatId = XLSX_FORMAT_MAP[format.format];
34594
+ if (!formatId) {
34595
+ formatId = pushElement(format, numFmtStructure) + FIRST_NUMFMT_ID;
34596
+ }
34597
+ return formatId;
34598
+ }
34599
+ /**
34600
+ * Add a relation to the given file and return its id.
34601
+ */
34602
+ function addRelsToFile(relsFiles, path, rel) {
34603
+ const relsFile = relsFiles.find((file) => file.path === path);
34604
+ // the id is a one-based int casted as string
34605
+ let id;
34606
+ if (!relsFile) {
34607
+ id = "rId1";
34608
+ relsFiles.push({ path, rels: [{ ...rel, id }] });
34609
+ }
34610
+ else {
34611
+ id = `rId${(relsFile.rels.length + 1).toString()}`;
34612
+ relsFile.rels.push({
34613
+ ...rel,
34614
+ id,
34615
+ });
34616
+ }
34617
+ return id;
34618
+ }
34619
+ const globalReverseLookup = new WeakMap();
34620
+ function pushElement(property, propertyList) {
34621
+ let reverseLookup = globalReverseLookup.get(propertyList);
34622
+ if (!reverseLookup) {
34623
+ reverseLookup = new Map();
34624
+ for (let i = 0; i < propertyList.length; i++) {
34625
+ const canonical = getCanonicalRepresentation(propertyList[i]);
34626
+ reverseLookup.set(canonical, i);
34627
+ }
34628
+ globalReverseLookup.set(propertyList, reverseLookup);
34629
+ }
34630
+ const canonical = getCanonicalRepresentation(property);
34631
+ if (reverseLookup.has(canonical)) {
34632
+ return reverseLookup.get(canonical);
34633
+ }
34634
+ const maxId = propertyList.length;
34635
+ propertyList.push(property);
34636
+ reverseLookup.set(canonical, maxId);
34637
+ return maxId;
34638
+ }
34639
+ /**
34640
+ * Convert a chart o-spreadsheet id to a xlsx id which
34641
+ * are unsigned integers (starting from 1).
34642
+ */
34643
+ function convertChartId(chartId, construct) {
34644
+ const xlsxId = construct.chartIds.findIndex((id) => id === chartId);
34645
+ if (xlsxId === -1) {
34646
+ construct.chartIds.push(chartId);
34647
+ return construct.chartIds.length;
34648
+ }
34649
+ return xlsxId + 1;
34650
+ }
34651
+ const imageIds = [];
34652
+ /**
34653
+ * Convert a image o-spreadsheet id to a xlsx id which
34654
+ * are unsigned integers (starting from 1).
34655
+ */
34656
+ function convertImageId(imageId) {
34657
+ const xlsxId = imageIds.findIndex((id) => id === imageId);
34658
+ if (xlsxId === -1) {
34659
+ imageIds.push(imageId);
34660
+ return imageIds.length;
34661
+ }
34662
+ return xlsxId + 1;
34663
+ }
34664
+ /**
34665
+ * Convert a value expressed in dot to EMU.
34666
+ * EMU = English Metrical Unit
34667
+ * There are 914400 EMU per inch.
34668
+ *
34669
+ * /!\ A value expressed in EMU cannot be fractional.
34670
+ * See https://docs.microsoft.com/en-us/windows/win32/vml/msdn-online-vml-units#other-units-of-measurement
34671
+ */
34672
+ function convertDotValueToEMU(value) {
34673
+ const DPI = 96;
34674
+ return Math.round((value * 914400) / DPI);
34675
+ }
34676
+ function getRangeSize(reference, defaultSheetIndex, data) {
34677
+ let xc = reference;
34678
+ let sheetName = undefined;
34679
+ ({ xc, sheetName } = splitReference(reference));
34680
+ let rangeSheetIndex;
34681
+ if (sheetName) {
34682
+ const index = data.sheets.findIndex((sheet) => isSheetNameEqual(sheet.name, sheetName));
34683
+ if (index < 0) {
34684
+ throw new Error("Unable to find a sheet with the name " + sheetName);
34685
+ }
34686
+ rangeSheetIndex = index;
34687
+ }
34688
+ else {
34689
+ rangeSheetIndex = Number(defaultSheetIndex);
34690
+ }
34691
+ const zone = toUnboundedZone(xc);
34692
+ if (zone.right === undefined) {
34693
+ zone.right = data.sheets[rangeSheetIndex].colNumber;
34694
+ }
34695
+ if (zone.bottom === undefined) {
34696
+ zone.bottom = data.sheets[rangeSheetIndex].rowNumber;
34697
+ }
34698
+ return (zone.right - zone.left + 1) * (zone.bottom - zone.top + 1);
34699
+ }
34700
+ function convertEMUToDotValue(value) {
34701
+ const DPI = 96;
34702
+ return Math.round((value * DPI) / 914400);
34703
+ }
34704
+ /**
34705
+ * Get the position of the start of a column in Excel (in px).
34706
+ */
34707
+ function getColPosition(colIndex, sheetData) {
34708
+ let position = 0;
34709
+ for (let i = 0; i < colIndex; i++) {
34710
+ const colAtIndex = sheetData.cols.find((col) => i >= col.min && i <= col.max);
34711
+ if (colAtIndex?.width) {
34712
+ position += colAtIndex.width;
34713
+ }
34714
+ else if (sheetData.sheetFormat?.defaultColWidth) {
34715
+ position += sheetData.sheetFormat.defaultColWidth;
34716
+ }
34717
+ else {
34718
+ position += EXCEL_DEFAULT_COL_WIDTH;
34719
+ }
34720
+ }
34721
+ return position / WIDTH_FACTOR;
34722
+ }
34723
+ /**
34724
+ * Get the position of the start of a row in Excel (in px).
34725
+ */
34726
+ function getRowPosition(rowIndex, sheetData) {
34727
+ let position = 0;
34728
+ for (let i = 0; i < rowIndex; i++) {
34729
+ const rowAtIndex = sheetData.rows.find((row) => row.index - 1 === i);
34730
+ if (rowAtIndex?.height) {
34731
+ position += rowAtIndex.height;
34732
+ }
34733
+ else if (sheetData.sheetFormat?.defaultRowHeight) {
34734
+ position += sheetData.sheetFormat.defaultRowHeight;
34735
+ }
34736
+ else {
34737
+ position += EXCEL_DEFAULT_ROW_HEIGHT;
34738
+ }
34739
+ }
34740
+ return position / HEIGHT_FACTOR;
34741
+ }
34742
+ /**
34743
+ * Convert the o-spreadsheet data validation decimal
34744
+ * criterion type to the corresponding excel operator.
34745
+ */
34746
+ function convertDecimalCriterionTypeToExcelOperator(operator) {
34747
+ return Object.keys(XLSX_DV_DECIMAL_OPERATOR_MAPPING).find((key) => XLSX_DV_DECIMAL_OPERATOR_MAPPING[key] === operator);
34748
+ }
34749
+ /**
34750
+ * Convert the o-spreadsheet data validation date
34751
+ * criterion type to the corresponding excel operator.
34752
+ */
34753
+ function convertDateCriterionTypeToExcelOperator(operator) {
34754
+ return Object.keys(XLSX_DV_DATE_OPERATOR_TO_DV_TYPE_MAPPING).find((key) => XLSX_DV_DATE_OPERATOR_TO_DV_TYPE_MAPPING[key] === operator);
34755
+ }
34756
+
34402
34757
  const XLSX_DATE_FORMAT_REGEX = /^(yy|yyyy|m{1,5}|d{1,4}|h{1,2}|s{1,2}|am\/pm|a\/m|\s|-|\/|\.|:)+$/i;
34403
34758
  /**
34404
34759
  * Convert excel format to o_spreadsheet format
@@ -34498,6 +34853,9 @@ function convertStyle(styleStruct, warningManager) {
34498
34853
  align: styleStruct.alignment?.horizontal
34499
34854
  ? H_ALIGNMENT_CONVERSION_MAP[styleStruct.alignment.horizontal]
34500
34855
  : undefined,
34856
+ rotation: styleStruct.alignment?.textRotation
34857
+ ? rotationFromXLSX(styleStruct.alignment.textRotation)
34858
+ : undefined,
34501
34859
  // In xlsx fills, bgColor is the color of the fill, and fgColor is the color of the pattern above the background, except in solid fills
34502
34860
  fillColor: styleStruct.fillStyle?.patternType === "solid"
34503
34861
  ? convertColor(styleStruct.fillStyle?.fgColor)
@@ -34797,303 +35155,6 @@ function addCfConversionWarnings(cf, dxfs, warningManager) {
34797
35155
  }
34798
35156
  }
34799
35157
 
34800
- // -------------------------------------
34801
- // CF HELPERS
34802
- // -------------------------------------
34803
- /**
34804
- * Convert the conditional formatting o-spreadsheet operator to
34805
- * the corresponding excel operator.
34806
- * */
34807
- function convertOperator(operator) {
34808
- switch (operator) {
34809
- case "isNotEmpty":
34810
- return "notContainsBlanks";
34811
- case "isEmpty":
34812
- return "containsBlanks";
34813
- case "notContainsText":
34814
- return "notContainsBlanks";
34815
- case "containsText":
34816
- return "containsText";
34817
- case "beginsWithText":
34818
- return "beginsWith";
34819
- case "endsWithText":
34820
- return "endsWith";
34821
- case "isGreaterThan":
34822
- return "greaterThan";
34823
- case "isGreaterOrEqualTo":
34824
- return "greaterThanOrEqual";
34825
- case "isLessThan":
34826
- return "lessThan";
34827
- case "isLessOrEqualTo":
34828
- return "lessThanOrEqual";
34829
- case "isBetween":
34830
- return "between";
34831
- case "isNotBetween":
34832
- return "notBetween";
34833
- case "isEqual":
34834
- return "equal";
34835
- case "isNotEqual":
34836
- return "notEqual";
34837
- case "customFormula":
34838
- return "";
34839
- case "dateIs":
34840
- return "";
34841
- case "dateIsBefore":
34842
- return "lessThan";
34843
- case "dateIsAfter":
34844
- return "greaterThan";
34845
- case "dateIsOnOrAfter":
34846
- return "greaterThanOrEqual";
34847
- case "dateIsOnOrBefore":
34848
- return "lessThanOrEqual";
34849
- }
34850
- }
34851
- // -------------------------------------
34852
- // WORKSHEET HELPERS
34853
- // -------------------------------------
34854
- function getCellType(value) {
34855
- switch (typeof value) {
34856
- case "boolean":
34857
- return "b";
34858
- case "string":
34859
- return "str";
34860
- case "number":
34861
- return "n";
34862
- default:
34863
- return undefined;
34864
- }
34865
- }
34866
- function convertHeightToExcel(height) {
34867
- return Math.round(HEIGHT_FACTOR * height * 100) / 100;
34868
- }
34869
- function convertWidthToExcel(width) {
34870
- return Math.round(WIDTH_FACTOR * width * 100) / 100;
34871
- }
34872
- function convertHeightFromExcel(height) {
34873
- if (!height)
34874
- return height;
34875
- return Math.round((height / HEIGHT_FACTOR) * 100) / 100;
34876
- }
34877
- function convertWidthFromExcel(width) {
34878
- if (!width)
34879
- return width;
34880
- return Math.round((width / WIDTH_FACTOR) * 100) / 100;
34881
- }
34882
- function extractStyle(data, content, styleId, formatId, borderId) {
34883
- const style = styleId ? data.styles[styleId] : {};
34884
- const format = formatId ? data.formats[formatId] : undefined;
34885
- const styles = {
34886
- font: {
34887
- size: style?.fontSize || DEFAULT_FONT_SIZE,
34888
- color: { rgb: style?.textColor ? style.textColor : "000000" },
34889
- family: 2,
34890
- name: "Arial",
34891
- },
34892
- fill: style?.fillColor
34893
- ? {
34894
- fgColor: { rgb: style.fillColor },
34895
- }
34896
- : { reservedAttribute: "none" },
34897
- numFmt: format ? { format: format, id: 0 /* id not used for export */ } : undefined,
34898
- border: borderId || 0,
34899
- alignment: {
34900
- horizontal: style.align,
34901
- vertical: style.verticalAlign
34902
- ? V_ALIGNMENT_EXPORT_CONVERSION_MAP[style.verticalAlign]
34903
- : undefined,
34904
- wrapText: style.wrapping === "wrap" || content?.includes(NEWLINE) ? true : undefined,
34905
- },
34906
- };
34907
- styles.font["strike"] = !!style?.strikethrough || undefined;
34908
- styles.font["underline"] = !!style?.underline || undefined;
34909
- styles.font["bold"] = !!style?.bold || undefined;
34910
- styles.font["italic"] = !!style?.italic || undefined;
34911
- return styles;
34912
- }
34913
- function normalizeStyle(construct, styles) {
34914
- // Normalize this
34915
- const numFmtId = convertFormat(styles["numFmt"], construct.numFmts);
34916
- const style = {
34917
- fontId: pushElement(styles.font, construct.fonts),
34918
- fillId: pushElement(styles.fill, construct.fills),
34919
- borderId: styles.border,
34920
- numFmtId,
34921
- alignment: {
34922
- vertical: styles.alignment.vertical,
34923
- horizontal: styles.alignment.horizontal,
34924
- wrapText: styles.alignment.wrapText,
34925
- },
34926
- };
34927
- return pushElement(style, construct.styles);
34928
- }
34929
- function convertFormat(format, numFmtStructure) {
34930
- if (!format) {
34931
- return 0;
34932
- }
34933
- let formatId = XLSX_FORMAT_MAP[format.format];
34934
- if (!formatId) {
34935
- formatId = pushElement(format, numFmtStructure) + FIRST_NUMFMT_ID;
34936
- }
34937
- return formatId;
34938
- }
34939
- /**
34940
- * Add a relation to the given file and return its id.
34941
- */
34942
- function addRelsToFile(relsFiles, path, rel) {
34943
- const relsFile = relsFiles.find((file) => file.path === path);
34944
- // the id is a one-based int casted as string
34945
- let id;
34946
- if (!relsFile) {
34947
- id = "rId1";
34948
- relsFiles.push({ path, rels: [{ ...rel, id }] });
34949
- }
34950
- else {
34951
- id = `rId${(relsFile.rels.length + 1).toString()}`;
34952
- relsFile.rels.push({
34953
- ...rel,
34954
- id,
34955
- });
34956
- }
34957
- return id;
34958
- }
34959
- const globalReverseLookup = new WeakMap();
34960
- function pushElement(property, propertyList) {
34961
- let reverseLookup = globalReverseLookup.get(propertyList);
34962
- if (!reverseLookup) {
34963
- reverseLookup = new Map();
34964
- for (let i = 0; i < propertyList.length; i++) {
34965
- const canonical = getCanonicalRepresentation(propertyList[i]);
34966
- reverseLookup.set(canonical, i);
34967
- }
34968
- globalReverseLookup.set(propertyList, reverseLookup);
34969
- }
34970
- const canonical = getCanonicalRepresentation(property);
34971
- if (reverseLookup.has(canonical)) {
34972
- return reverseLookup.get(canonical);
34973
- }
34974
- const maxId = propertyList.length;
34975
- propertyList.push(property);
34976
- reverseLookup.set(canonical, maxId);
34977
- return maxId;
34978
- }
34979
- /**
34980
- * Convert a chart o-spreadsheet id to a xlsx id which
34981
- * are unsigned integers (starting from 1).
34982
- */
34983
- function convertChartId(chartId, construct) {
34984
- const xlsxId = construct.chartIds.findIndex((id) => id === chartId);
34985
- if (xlsxId === -1) {
34986
- construct.chartIds.push(chartId);
34987
- return construct.chartIds.length;
34988
- }
34989
- return xlsxId + 1;
34990
- }
34991
- const imageIds = [];
34992
- /**
34993
- * Convert a image o-spreadsheet id to a xlsx id which
34994
- * are unsigned integers (starting from 1).
34995
- */
34996
- function convertImageId(imageId) {
34997
- const xlsxId = imageIds.findIndex((id) => id === imageId);
34998
- if (xlsxId === -1) {
34999
- imageIds.push(imageId);
35000
- return imageIds.length;
35001
- }
35002
- return xlsxId + 1;
35003
- }
35004
- /**
35005
- * Convert a value expressed in dot to EMU.
35006
- * EMU = English Metrical Unit
35007
- * There are 914400 EMU per inch.
35008
- *
35009
- * /!\ A value expressed in EMU cannot be fractional.
35010
- * See https://docs.microsoft.com/en-us/windows/win32/vml/msdn-online-vml-units#other-units-of-measurement
35011
- */
35012
- function convertDotValueToEMU(value) {
35013
- const DPI = 96;
35014
- return Math.round((value * 914400) / DPI);
35015
- }
35016
- function getRangeSize(reference, defaultSheetIndex, data) {
35017
- let xc = reference;
35018
- let sheetName = undefined;
35019
- ({ xc, sheetName } = splitReference(reference));
35020
- let rangeSheetIndex;
35021
- if (sheetName) {
35022
- const index = data.sheets.findIndex((sheet) => isSheetNameEqual(sheet.name, sheetName));
35023
- if (index < 0) {
35024
- throw new Error("Unable to find a sheet with the name " + sheetName);
35025
- }
35026
- rangeSheetIndex = index;
35027
- }
35028
- else {
35029
- rangeSheetIndex = Number(defaultSheetIndex);
35030
- }
35031
- const zone = toUnboundedZone(xc);
35032
- if (zone.right === undefined) {
35033
- zone.right = data.sheets[rangeSheetIndex].colNumber;
35034
- }
35035
- if (zone.bottom === undefined) {
35036
- zone.bottom = data.sheets[rangeSheetIndex].rowNumber;
35037
- }
35038
- return (zone.right - zone.left + 1) * (zone.bottom - zone.top + 1);
35039
- }
35040
- function convertEMUToDotValue(value) {
35041
- const DPI = 96;
35042
- return Math.round((value * DPI) / 914400);
35043
- }
35044
- /**
35045
- * Get the position of the start of a column in Excel (in px).
35046
- */
35047
- function getColPosition(colIndex, sheetData) {
35048
- let position = 0;
35049
- for (let i = 0; i < colIndex; i++) {
35050
- const colAtIndex = sheetData.cols.find((col) => i >= col.min && i <= col.max);
35051
- if (colAtIndex?.width) {
35052
- position += colAtIndex.width;
35053
- }
35054
- else if (sheetData.sheetFormat?.defaultColWidth) {
35055
- position += sheetData.sheetFormat.defaultColWidth;
35056
- }
35057
- else {
35058
- position += EXCEL_DEFAULT_COL_WIDTH;
35059
- }
35060
- }
35061
- return position / WIDTH_FACTOR;
35062
- }
35063
- /**
35064
- * Get the position of the start of a row in Excel (in px).
35065
- */
35066
- function getRowPosition(rowIndex, sheetData) {
35067
- let position = 0;
35068
- for (let i = 0; i < rowIndex; i++) {
35069
- const rowAtIndex = sheetData.rows.find((row) => row.index - 1 === i);
35070
- if (rowAtIndex?.height) {
35071
- position += rowAtIndex.height;
35072
- }
35073
- else if (sheetData.sheetFormat?.defaultRowHeight) {
35074
- position += sheetData.sheetFormat.defaultRowHeight;
35075
- }
35076
- else {
35077
- position += EXCEL_DEFAULT_ROW_HEIGHT;
35078
- }
35079
- }
35080
- return position / HEIGHT_FACTOR;
35081
- }
35082
- /**
35083
- * Convert the o-spreadsheet data validation decimal
35084
- * criterion type to the corresponding excel operator.
35085
- */
35086
- function convertDecimalCriterionTypeToExcelOperator(operator) {
35087
- return Object.keys(XLSX_DV_DECIMAL_OPERATOR_MAPPING).find((key) => XLSX_DV_DECIMAL_OPERATOR_MAPPING[key] === operator);
35088
- }
35089
- /**
35090
- * Convert the o-spreadsheet data validation date
35091
- * criterion type to the corresponding excel operator.
35092
- */
35093
- function convertDateCriterionTypeToExcelOperator(operator) {
35094
- return Object.keys(XLSX_DV_DATE_OPERATOR_TO_DV_TYPE_MAPPING).find((key) => XLSX_DV_DATE_OPERATOR_TO_DV_TYPE_MAPPING[key] === operator);
35095
- }
35096
-
35097
35158
  function convertFigures(sheetData) {
35098
35159
  let id = 1;
35099
35160
  return sheetData.figures
@@ -38808,7 +38869,7 @@ class CorePlugin extends BasePlugin {
38808
38869
  * @param sheetId an sheetId to adapt either range of that sheet specifically, or ranges pointing to that sheet
38809
38870
  * @param sheetName couple of old and new sheet names to adapt ranges pointing to that sheet
38810
38871
  */
38811
- adaptRanges(applyChange, sheetId, sheetName) { }
38872
+ adaptRanges(rangeAdapterFunctions, sheetId, sheetName) { }
38812
38873
  }
38813
38874
 
38814
38875
  class BordersPlugin extends CorePlugin {
@@ -38882,7 +38943,7 @@ class BordersPlugin extends CorePlugin {
38882
38943
  }
38883
38944
  }
38884
38945
  }
38885
- adaptRanges(applyChange, sheetId) {
38946
+ adaptRanges({ applyChange }, sheetId) {
38886
38947
  const newBorders = [];
38887
38948
  for (const border of this.borders[sheetId] ?? []) {
38888
38949
  const change = applyChange(this.getters.getRangeFromZone(sheetId, border.zone));
@@ -39363,7 +39424,7 @@ class CellPlugin extends CorePlugin {
39363
39424
  ];
39364
39425
  nextId = 1;
39365
39426
  cells = {};
39366
- adaptRanges(applyChange, sheetId, sheetName) {
39427
+ adaptRanges({ applyChange }, sheetId, sheetName) {
39367
39428
  for (const sheet of Object.keys(this.cells)) {
39368
39429
  for (const cell of Object.values(this.cells[sheet] || {})) {
39369
39430
  if (cell.isFormula) {
@@ -39924,12 +39985,12 @@ class ChartPlugin extends CorePlugin {
39924
39985
  charts = {};
39925
39986
  createChart = chartFactory(this.getters);
39926
39987
  validateChartDefinition = (cmd) => validateChartDefinition(this, cmd.definition);
39927
- adaptRanges(applyChange, sheetId, adaptSheetName) {
39988
+ adaptRanges(rangeAdapters) {
39928
39989
  for (const [chartId, chart] of Object.entries(this.charts)) {
39929
39990
  if (!chart) {
39930
39991
  continue;
39931
39992
  }
39932
- const newChart = chart.chart.updateRanges(applyChange, sheetId, adaptSheetName);
39993
+ const newChart = chart.chart.updateRanges(rangeAdapters);
39933
39994
  this.history.update("charts", chartId, newChart ? { figureId: chart.figureId, chart: newChart } : undefined);
39934
39995
  }
39935
39996
  }
@@ -40750,7 +40811,7 @@ class ConditionalFormatPlugin extends CorePlugin {
40750
40811
  "getAdaptedCfRanges",
40751
40812
  ];
40752
40813
  cfRules = {};
40753
- adaptCFFormulas(applyChange) {
40814
+ adaptCFFormulas({ applyChange, adaptFormulaString }) {
40754
40815
  for (const sheetId in this.cfRules) {
40755
40816
  for (const rule of this.cfRules[sheetId]) {
40756
40817
  if (rule.rule.type === "DataBarRule" && rule.rule.rangeValues) {
@@ -40774,7 +40835,7 @@ class ConditionalFormatPlugin extends CorePlugin {
40774
40835
  for (let i = 0; i < rule.rule.values.length; i++) {
40775
40836
  this.history.update("cfRules", sheetId, this.cfRules[sheetId].indexOf(rule), "rule",
40776
40837
  //@ts-expect-error
40777
- "values", i, this.getters.adaptFormulaStringDependencies(sheetId, rule.rule.values[i], applyChange));
40838
+ "values", i, adaptFormulaString(sheetId, rule.rule.values[i]));
40778
40839
  }
40779
40840
  }
40780
40841
  else if (rule.rule.type === "IconSetRule") {
@@ -40782,7 +40843,7 @@ class ConditionalFormatPlugin extends CorePlugin {
40782
40843
  if (rule.rule[inflectionPoint].type === "formula") {
40783
40844
  this.history.update("cfRules", sheetId, this.cfRules[sheetId].indexOf(rule), "rule",
40784
40845
  //@ts-expect-error
40785
- inflectionPoint, "value", this.getters.adaptFormulaStringDependencies(sheetId, rule.rule[inflectionPoint].value, applyChange));
40846
+ inflectionPoint, "value", adaptFormulaString(sheetId, rule.rule[inflectionPoint].value));
40786
40847
  }
40787
40848
  }
40788
40849
  }
@@ -40792,14 +40853,14 @@ class ConditionalFormatPlugin extends CorePlugin {
40792
40853
  if (ruleValue?.type === "formula" && ruleValue?.value) {
40793
40854
  this.history.update("cfRules", sheetId, this.cfRules[sheetId].indexOf(rule), "rule",
40794
40855
  //@ts-expect-error
40795
- value, "value", this.getters.adaptFormulaStringDependencies(sheetId, ruleValue.value, applyChange));
40856
+ value, "value", adaptFormulaString(sheetId, ruleValue.value));
40796
40857
  }
40797
40858
  }
40798
40859
  }
40799
40860
  }
40800
40861
  }
40801
40862
  }
40802
- adaptCFRanges(sheetId, applyChange) {
40863
+ adaptCFRanges(sheetId, { applyChange }) {
40803
40864
  for (const rule of this.cfRules[sheetId]) {
40804
40865
  for (const range of rule.ranges) {
40805
40866
  const change = applyChange(range);
@@ -40823,12 +40884,12 @@ class ConditionalFormatPlugin extends CorePlugin {
40823
40884
  }
40824
40885
  }
40825
40886
  }
40826
- adaptRanges(applyChange, sheetId) {
40887
+ adaptRanges(rangeAdapters, sheetId) {
40827
40888
  const sheetIds = sheetId ? [sheetId] : Object.keys(this.cfRules);
40828
40889
  for (const sheetId of sheetIds) {
40829
- this.adaptCFRanges(sheetId, applyChange);
40890
+ this.adaptCFRanges(sheetId, rangeAdapters);
40830
40891
  }
40831
- this.adaptCFFormulas(applyChange);
40892
+ this.adaptCFFormulas(rangeAdapters);
40832
40893
  }
40833
40894
  // ---------------------------------------------------------------------------
40834
40895
  // Command Handling
@@ -41205,23 +41266,23 @@ class DataValidationPlugin extends CorePlugin {
41205
41266
  "getValidationRuleForCell",
41206
41267
  ];
41207
41268
  rules = {};
41208
- adaptRanges(applyChange, sheetId) {
41209
- this.adaptDVRanges(sheetId, applyChange);
41210
- this.adaptDVFormulas(applyChange);
41269
+ adaptRanges(rangeAdapters, sheetId) {
41270
+ this.adaptDVRanges(sheetId, rangeAdapters);
41271
+ this.adaptDVFormulas(rangeAdapters);
41211
41272
  }
41212
- adaptDVFormulas(applyChange) {
41273
+ adaptDVFormulas({ adaptFormulaString }) {
41213
41274
  for (const sheetId in this.rules) {
41214
41275
  const rules = this.rules[sheetId];
41215
41276
  for (let ruleIndex = rules.length - 1; ruleIndex >= 0; ruleIndex--) {
41216
41277
  const rule = this.rules[sheetId][ruleIndex];
41217
41278
  for (let valueIndex = 0; valueIndex < rule.criterion.values.length; valueIndex++) {
41218
- const value = this.getters.adaptFormulaStringDependencies(sheetId, rule.criterion.values[valueIndex], applyChange);
41279
+ const value = adaptFormulaString(sheetId, rule.criterion.values[valueIndex]);
41219
41280
  this.history.update("rules", sheetId, ruleIndex, "criterion", "values", valueIndex, value);
41220
41281
  }
41221
41282
  }
41222
41283
  }
41223
41284
  }
41224
- adaptDVRanges(sheetId, applyChange) {
41285
+ adaptDVRanges(sheetId, { applyChange }) {
41225
41286
  const rules = this.rules[sheetId];
41226
41287
  for (let ruleIndex = rules.length - 1; ruleIndex >= 0; ruleIndex--) {
41227
41288
  const rule = this.rules[sheetId][ruleIndex];
@@ -41495,7 +41556,7 @@ class FigurePlugin extends CorePlugin {
41495
41556
  // ---------------------------------------------------------------------------
41496
41557
  // Command Handling
41497
41558
  // ---------------------------------------------------------------------------
41498
- adaptRanges(applyChange, sheetId) {
41559
+ adaptRanges({ applyChange }, sheetId) {
41499
41560
  for (const figure of this.getFigures(sheetId)) {
41500
41561
  const change = applyChange(this.getters.getRangeFromZone(sheetId, {
41501
41562
  left: figure.col,
@@ -42735,8 +42796,8 @@ class MergePlugin extends CorePlugin {
42735
42796
  break;
42736
42797
  }
42737
42798
  }
42738
- adaptRanges(applyChange, sheetId) {
42739
- this.applyRangeChangeOnSheet(sheetId, applyChange);
42799
+ adaptRanges(rangeAdapters, sheetId) {
42800
+ this.applyRangeChangeOnSheet(sheetId, rangeAdapters);
42740
42801
  }
42741
42802
  // ---------------------------------------------------------------------------
42742
42803
  // Getters
@@ -43036,7 +43097,7 @@ class MergePlugin extends CorePlugin {
43036
43097
  /**
43037
43098
  * Apply a range change on merges of a particular sheet.
43038
43099
  */
43039
- applyRangeChangeOnSheet(sheetId, applyChange) {
43100
+ applyRangeChangeOnSheet(sheetId, { applyChange }) {
43040
43101
  const merges = Object.entries(this.merges[sheetId] || {});
43041
43102
  for (const [mergeId, range] of merges) {
43042
43103
  if (range) {
@@ -44655,8 +44716,6 @@ function adaptPivotRange(range, applyChange) {
44655
44716
  }
44656
44717
  const change = applyChange(range);
44657
44718
  switch (change.changeType) {
44658
- case "NONE":
44659
- return range;
44660
44719
  case "REMOVE":
44661
44720
  return undefined;
44662
44721
  default:
@@ -44674,6 +44733,7 @@ class PivotCorePlugin extends CorePlugin {
44674
44733
  "getMeasureCompiledFormula",
44675
44734
  "getPivotName",
44676
44735
  "isExistingPivot",
44736
+ "getMeasureFullDependencies",
44677
44737
  ];
44678
44738
  nextFormulaId = 1;
44679
44739
  pivots = {};
@@ -44759,12 +44819,12 @@ class PivotCorePlugin extends CorePlugin {
44759
44819
  }
44760
44820
  case "UPDATE_PIVOT": {
44761
44821
  this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
44762
- this.compileCalculatedMeasures(cmd.pivot.measures);
44822
+ this.compileCalculatedMeasures(cmd.pivotId, cmd.pivot.measures);
44763
44823
  break;
44764
44824
  }
44765
44825
  }
44766
44826
  }
44767
- adaptRanges(applyChange) {
44827
+ adaptRanges({ applyChange, adaptFormulaString }) {
44768
44828
  for (const pivotId in this.pivots) {
44769
44829
  const definition = deepCopy(this.pivots[pivotId]?.definition);
44770
44830
  if (!definition) {
@@ -44777,22 +44837,22 @@ class PivotCorePlugin extends CorePlugin {
44777
44837
  this.history.update("pivots", pivotId, "definition", newDefinition);
44778
44838
  }
44779
44839
  }
44780
- for (const sheetId in this.compiledMeasureFormulas) {
44781
- for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
44782
- const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
44783
- const newDependencies = [];
44784
- for (const range of compiledFormula.dependencies) {
44785
- const change = applyChange(range);
44786
- if (change.changeType === "NONE") {
44787
- newDependencies.push(range);
44788
- }
44789
- else {
44790
- newDependencies.push(change.range);
44791
- }
44840
+ for (const pivotId in this.compiledMeasureFormulas) {
44841
+ for (const measureId in this.compiledMeasureFormulas[pivotId]) {
44842
+ const measure = this.pivots[pivotId]?.definition.measures.find((m) => m.id === measureId);
44843
+ if (!measure || !measure.computedBy) {
44844
+ continue;
44792
44845
  }
44793
- const newFormulaString = this.getters.getFormulaString(sheetId, compiledFormula.tokens, newDependencies);
44794
- if (newFormulaString !== formulaString) {
44795
- this.replaceMeasureFormula(sheetId, formulaString, newFormulaString);
44846
+ const sheetId = measure.computedBy.sheetId;
44847
+ const { formula: compiledFormula, dependencies: indirectDependencies } = this.compiledMeasureFormulas[pivotId][measureId];
44848
+ // adapt direct dependencies
44849
+ this.history.update("compiledMeasureFormulas", pivotId, measureId, "formula", "dependencies", compiledFormula.dependencies.map((range) => applyChange(range).range));
44850
+ // adapt all dependencies (including indirect)
44851
+ this.history.update("compiledMeasureFormulas", pivotId, measure.id, "dependencies", indirectDependencies.map((range) => applyChange(range).range));
44852
+ const oldFormulaString = measure.computedBy.formula;
44853
+ const newFormulaString = adaptFormulaString(sheetId, oldFormulaString);
44854
+ if (newFormulaString !== oldFormulaString) {
44855
+ this.replaceMeasureFormula(pivotId, measure, newFormulaString);
44796
44856
  }
44797
44857
  }
44798
44858
  }
@@ -44830,31 +44890,60 @@ class PivotCorePlugin extends CorePlugin {
44830
44890
  isExistingPivot(pivotId) {
44831
44891
  return pivotId in this.pivots;
44832
44892
  }
44833
- getMeasureCompiledFormula(measure) {
44893
+ getMeasureCompiledFormula(pivotId, measure) {
44834
44894
  if (!measure.computedBy) {
44835
44895
  throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
44836
44896
  }
44837
- const sheetId = measure.computedBy.sheetId;
44838
- return this.compiledMeasureFormulas[sheetId][measure.computedBy.formula];
44897
+ return this.compiledMeasureFormulas[pivotId][measure.id].formula;
44898
+ }
44899
+ getMeasureFullDependencies(pivotId, measure) {
44900
+ if (!measure.computedBy) {
44901
+ throw new Error(`Measure ${measure.fieldName} is not computed by formula`);
44902
+ }
44903
+ return this.compiledMeasureFormulas[pivotId][measure.id].dependencies;
44839
44904
  }
44840
44905
  // -------------------------------------------------------------------------
44841
44906
  // Private
44842
44907
  // -------------------------------------------------------------------------
44843
44908
  addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
44844
44909
  this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
44845
- this.compileCalculatedMeasures(pivot.measures);
44910
+ this.compileCalculatedMeasures(pivotId, pivot.measures);
44846
44911
  this.history.update("formulaIds", formulaId, pivotId);
44847
44912
  this.history.update("nextFormulaId", this.nextFormulaId + 1);
44848
44913
  }
44849
- compileCalculatedMeasures(measures) {
44914
+ compileCalculatedMeasures(pivotId, measures) {
44850
44915
  for (const measure of measures) {
44851
44916
  if (measure.computedBy) {
44852
- const sheetId = measure.computedBy.sheetId;
44853
44917
  const compiledFormula = this.compileMeasureFormula(measure.computedBy.sheetId, measure.computedBy.formula);
44854
- this.history.update("compiledMeasureFormulas", sheetId, measure.computedBy.formula, compiledFormula);
44918
+ this.history.update("compiledMeasureFormulas", pivotId, measure.id, "formula", compiledFormula);
44919
+ }
44920
+ }
44921
+ for (const measure of measures) {
44922
+ if (measure.computedBy) {
44923
+ const dependencies = this.computeMeasureFullDependencies(pivotId, measure);
44924
+ this.history.update("compiledMeasureFormulas", pivotId, measure.id, "dependencies", dependencies);
44855
44925
  }
44856
44926
  }
44857
44927
  }
44928
+ computeMeasureFullDependencies(pivotId, measure, exploredMeasures = new Set()) {
44929
+ const rangeDependencies = [];
44930
+ const definition = this.getPivotCoreDefinition(pivotId);
44931
+ const formula = this.getMeasureCompiledFormula(pivotId, measure);
44932
+ exploredMeasures.add(measure.id);
44933
+ for (const token of formula.tokens) {
44934
+ if (token.type !== "SYMBOL") {
44935
+ continue;
44936
+ }
44937
+ const otherMeasure = definition.measures.find((measureCandidate) => getCanonicalSymbolName(measureCandidate.id) === token.value &&
44938
+ measure.id !== measureCandidate.id);
44939
+ if (!otherMeasure || exploredMeasures.has(otherMeasure.id) || !otherMeasure.computedBy) {
44940
+ continue;
44941
+ }
44942
+ rangeDependencies.push(...this.computeMeasureFullDependencies(pivotId, otherMeasure, exploredMeasures));
44943
+ }
44944
+ rangeDependencies.push(...formula.dependencies.filter((range) => !range.invalidXc));
44945
+ return rangeDependencies;
44946
+ }
44858
44947
  insertPivot(position, formulaId, table) {
44859
44948
  this.resizeSheet(position.sheetId, position, table);
44860
44949
  const pivotCells = table.getPivotCells();
@@ -44913,21 +45002,16 @@ class PivotCorePlugin extends CorePlugin {
44913
45002
  dependencies: rangeDependencies,
44914
45003
  };
44915
45004
  }
44916
- replaceMeasureFormula(sheetId, formulaString, newFormulaString) {
44917
- this.history.update("compiledMeasureFormulas", sheetId, formulaString, undefined);
44918
- this.history.update("compiledMeasureFormulas", sheetId, newFormulaString, this.compileMeasureFormula(sheetId, newFormulaString));
44919
- for (const pivotId in this.pivots) {
44920
- const pivot = this.pivots[pivotId];
44921
- if (!pivot) {
44922
- continue;
44923
- }
44924
- for (const measure of pivot.definition.measures) {
44925
- if (measure.computedBy?.formula === formulaString) {
44926
- const measureIndex = pivot.definition.measures.indexOf(measure);
44927
- this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", { formula: newFormulaString, sheetId });
44928
- }
44929
- }
45005
+ replaceMeasureFormula(pivotId, measure, newFormulaString) {
45006
+ const pivot = this.pivots[pivotId];
45007
+ if (!pivot) {
45008
+ return;
44930
45009
  }
45010
+ const measureIndex = pivot.definition.measures.indexOf(measure);
45011
+ this.history.update("pivots", pivotId, "definition", "measures", measureIndex, "computedBy", {
45012
+ formula: newFormulaString,
45013
+ sheetId: measure.computedBy.sheetId,
45014
+ });
44931
45015
  }
44932
45016
  checkSortedColumnInMeasures(definition) {
44933
45017
  const measures = definition.measures.map((measure) => measure.id);
@@ -45988,7 +46072,7 @@ class StylePlugin extends CorePlugin {
45988
46072
  case "UPDATE_CELL":
45989
46073
  if (cmd.style !== undefined) {
45990
46074
  if (cmd.style !== null) {
45991
- this.setStyles(cmd.sheetId, [positionToZone(cmd)], cmd.style);
46075
+ this.setStyles(cmd.sheetId, [positionToZone(cmd)], cmd.style, { force: true });
45992
46076
  }
45993
46077
  else {
45994
46078
  this.clearStyle(cmd.sheetId, [positionToZone(cmd)]);
@@ -46014,7 +46098,7 @@ class StylePlugin extends CorePlugin {
46014
46098
  break;
46015
46099
  }
46016
46100
  }
46017
- adaptRanges(applyChange, sheetId) {
46101
+ adaptRanges({ applyChange }, sheetId) {
46018
46102
  const newStyles = [];
46019
46103
  for (const style of this.styles[sheetId] ?? []) {
46020
46104
  const change = applyChange(this.getters.getRangeFromZone(sheetId, style.zone));
@@ -46056,16 +46140,22 @@ class StylePlugin extends CorePlugin {
46056
46140
  }
46057
46141
  }
46058
46142
  styleIsDefault(style) {
46059
- return deepEquals(this.removeDefaultStyleValues(style), {});
46143
+ for (const key in style) {
46144
+ if (DEFAULT_STYLE_NO_ALIGN[key] !== style[key]) {
46145
+ return false;
46146
+ }
46147
+ }
46148
+ return true;
46060
46149
  }
46061
46150
  removeDefaultStyleValues(style) {
46062
46151
  const cleanedStyle = { ...style };
46063
- for (const property in DEFAULT_STYLE_NO_ALIGN) {
46064
- if (cleanedStyle[property] === DEFAULT_STYLE_NO_ALIGN[property]) {
46152
+ for (const property in style) {
46153
+ if (cleanedStyle[property] === undefined ||
46154
+ cleanedStyle[property] === DEFAULT_STYLE_NO_ALIGN[property]) {
46065
46155
  delete cleanedStyle[property];
46066
46156
  }
46067
46157
  }
46068
- return cleanedStyle;
46158
+ return Object.keys(cleanedStyle).length > 0 ? cleanedStyle : undefined;
46069
46159
  }
46070
46160
  onMerge(sheetId, zone) {
46071
46161
  this.setStyle(sheetId, zone, this.getCellStyle({ sheetId, col: zone.left, row: zone.top }), {
@@ -46101,13 +46191,13 @@ class StylePlugin extends CorePlugin {
46101
46191
  }
46102
46192
  editingZone = recomputeZones(editingZone, [inter]);
46103
46193
  }
46194
+ style = this.removeDefaultStyleValues(style);
46104
46195
  if (style) {
46105
- const newStyle = this.removeDefaultStyleValues(style);
46106
46196
  styles.push(...editingZone.map((zone) => {
46107
- return { zone, style: newStyle };
46197
+ return { zone, style };
46108
46198
  }));
46109
46199
  }
46110
- this.history.update("styles", sheetId, styles.filter((zoneStyle) => !this.styleIsDefault(zoneStyle.style)));
46200
+ this.history.update("styles", sheetId, styles);
46111
46201
  }
46112
46202
  clearStyle(sheetId, zones) {
46113
46203
  this.setStyles(sheetId, zones, undefined, { force: true });
@@ -46521,7 +46611,7 @@ class TablePlugin extends CorePlugin {
46521
46611
  static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
46522
46612
  tables = {};
46523
46613
  nextTableId = 1;
46524
- adaptRanges(applyChange, sheetId) {
46614
+ adaptRanges({ applyChange }, sheetId) {
46525
46615
  for (const table of this.getCoreTables(sheetId)) {
46526
46616
  this.applyRangeChangeOnTable(sheetId, table, applyChange);
46527
46617
  }
@@ -48353,11 +48443,16 @@ class SpreadingRelation {
48353
48443
  return this.arrayFormulasToResults.get(formulasPosition);
48354
48444
  }
48355
48445
  /**
48356
- * Remove a node, also remove it from other nodes adjacency list
48446
+ * Remove a spreading relation for a given array formula position
48447
+ * and its result zone
48357
48448
  */
48358
48449
  removeNode(position) {
48450
+ const resultZone = this.arrayFormulasToResults.get(position);
48451
+ if (!resultZone) {
48452
+ return;
48453
+ }
48359
48454
  this.resultsToArrayFormulas.remove({
48360
- boundingBox: { sheetId: position.sheetId, zone: positionToZone(position) },
48455
+ boundingBox: { sheetId: position.sheetId, zone: resultZone },
48361
48456
  data: position,
48362
48457
  });
48363
48458
  this.arrayFormulasToResults.delete(position);
@@ -48684,6 +48779,10 @@ class Evaluator {
48684
48779
  // empty matrix
48685
48780
  return createEvaluatedCell({ value: 0 }, this.getters.getLocale(), cellData);
48686
48781
  }
48782
+ if (nbRows === 1 && nbColumns === 1) {
48783
+ // single value matrix
48784
+ return createEvaluatedCell(validateNumberValue(formulaReturn[0][0]), this.getters.getLocale(), cellData);
48785
+ }
48687
48786
  const resultZone = {
48688
48787
  top: formulaPosition.row,
48689
48788
  bottom: formulaPosition.row + nbRows - 1,
@@ -50289,14 +50388,14 @@ let ScorecardChart$1 = class ScorecardChart extends AbstractChart {
50289
50388
  let baseline;
50290
50389
  let keyValue;
50291
50390
  if (definition.baseline) {
50292
- const adaptedRange = adaptStringRange(chartSheetId, definition.baseline, applyChange);
50293
- if (adaptedRange !== CellErrorType.InvalidReference) {
50391
+ const { changeType, range: adaptedRange } = adaptStringRange(chartSheetId, definition.baseline, applyChange);
50392
+ if (changeType !== "REMOVE") {
50294
50393
  baseline = adaptedRange;
50295
50394
  }
50296
50395
  }
50297
50396
  if (definition.keyValue) {
50298
- const adaptedRange = adaptStringRange(chartSheetId, definition.keyValue, applyChange);
50299
- if (adaptedRange !== CellErrorType.InvalidReference) {
50397
+ const { changeType, range: adaptedRange } = adaptStringRange(chartSheetId, definition.keyValue, applyChange);
50398
+ if (changeType !== "REMOVE") {
50300
50399
  keyValue = adaptedRange;
50301
50400
  }
50302
50401
  }
@@ -50353,7 +50452,7 @@ let ScorecardChart$1 = class ScorecardChart extends AbstractChart {
50353
50452
  // This kind of graph is not exportable in Excel
50354
50453
  return undefined;
50355
50454
  }
50356
- updateRanges(applyChange) {
50455
+ updateRanges({ applyChange }) {
50357
50456
  const baseline = adaptChartRange(this.baseline, applyChange);
50358
50457
  const keyValue = adaptChartRange(this.keyValue, applyChange);
50359
50458
  if (this.baseline === baseline && this.keyValue === keyValue) {
@@ -50806,15 +50905,15 @@ async function chartToImageUrl(runtime, figure, type) {
50806
50905
  if (!extensionsLoaded) {
50807
50906
  registerChartJSExtensions();
50808
50907
  }
50809
- if (!globalThis.Chart.registry.controllers.get(type)) {
50810
- console.log(`Chart of type "${type}" is not registered in Chart.js library.`);
50908
+ const config = deepCopy(runtime.chartJsConfig);
50909
+ config.plugins = [backgroundColorChartJSPlugin];
50910
+ if (!globalThis.Chart.registry.controllers.get(config.type)) {
50911
+ console.log(`Chart of type "${config.type}" is not registered in Chart.js library.`);
50811
50912
  if (!extensionsLoaded) {
50812
50913
  unregisterChartJsExtensions();
50813
50914
  }
50814
50915
  return imageUrl;
50815
50916
  }
50816
- const config = deepCopy(runtime.chartJsConfig);
50817
- config.plugins = [backgroundColorChartJSPlugin];
50818
50917
  const chart = new globalThis.Chart(canvas, config);
50819
50918
  try {
50820
50919
  imageUrl = await canvasToObjectUrl(canvas);
@@ -50854,15 +50953,15 @@ async function chartToImageFile(runtime, figure, type) {
50854
50953
  if (!extensionsLoaded) {
50855
50954
  registerChartJSExtensions();
50856
50955
  }
50857
- if (!globalThis.Chart.registry.controllers.get(type)) {
50858
- console.log(`Chart of type "${type}" is not registered in Chart.js library.`);
50956
+ const config = deepCopy(runtime.chartJsConfig);
50957
+ config.plugins = [backgroundColorChartJSPlugin];
50958
+ if (!globalThis.Chart.registry.controllers.get(config.type)) {
50959
+ console.log(`Chart of type "${config.type}" is not registered in Chart.js library.`);
50859
50960
  if (!extensionsLoaded) {
50860
50961
  unregisterChartJsExtensions();
50861
50962
  }
50862
50963
  return chartBlob;
50863
50964
  }
50864
- const config = deepCopy(runtime.chartJsConfig);
50865
- config.plugins = [backgroundColorChartJSPlugin];
50866
50965
  const chart = new globalThis.Chart(canvas, config);
50867
50966
  try {
50868
50967
  chartBlob = await canvasToBlob(canvas);
@@ -51527,6 +51626,7 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
51527
51626
  handle(cmd) {
51528
51627
  switch (cmd.type) {
51529
51628
  case "START":
51629
+ case "UPDATE_LOCALE":
51530
51630
  for (const sheetId of this.getters.getSheetIds()) {
51531
51631
  this.initializeSheet(sheetId);
51532
51632
  }
@@ -51664,7 +51764,7 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
51664
51764
  const cell = this.getters.getCell(position);
51665
51765
  const style = this.getters.getCellStyle(position);
51666
51766
  const colSize = this.getters.getColSize(position.sheetId, position.col);
51667
- return getDefaultCellHeight(this.ctx, cell, style, colSize);
51767
+ return getDefaultCellHeight(this.ctx, cell, style, this.getters.getLocale(), colSize);
51668
51768
  }
51669
51769
  isInMultiRowMerge(position) {
51670
51770
  const merge = this.getters.getMerge(position);
@@ -52036,14 +52136,16 @@ const PERCENT_FORMAT = "0.00%";
52036
52136
  function withPivotPresentationLayer (PivotClass) {
52037
52137
  class PivotPresentationLayer extends PivotClass {
52038
52138
  getters;
52139
+ pivotId;
52039
52140
  cache = {};
52040
52141
  rankAsc = {};
52041
52142
  rankDesc = {};
52042
52143
  runningTotal = {};
52043
52144
  runningTotalInPercent = {};
52044
- constructor(custom, params) {
52145
+ constructor(pivotId, custom, params) {
52045
52146
  super(custom, params);
52046
52147
  this.getters = params.getters;
52148
+ this.pivotId = pivotId;
52047
52149
  }
52048
52150
  markAsDirtyForEvaluation() {
52049
52151
  this.cache = {};
@@ -52093,7 +52195,7 @@ function withPivotPresentationLayer (PivotClass) {
52093
52195
  return handleError(error, measure.aggregator.toUpperCase());
52094
52196
  }
52095
52197
  }
52096
- const formula = this.getters.getMeasureCompiledFormula(measure);
52198
+ const formula = this.getters.getMeasureCompiledFormula(this.pivotId, measure);
52097
52199
  const getSymbolValue = (symbolName) => {
52098
52200
  const { columns, rows } = this.definition;
52099
52201
  if (columns.find((col) => col.nameWithGranularity === symbolName)) {
@@ -52840,7 +52942,7 @@ class PivotUIPlugin extends CoreViewPlugin {
52840
52942
  const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
52841
52943
  if (!(pivotId in this.pivots)) {
52842
52944
  const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
52843
- this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
52945
+ this.pivots[pivotId] = new Pivot(pivotId, this.custom, { definition, getters: this.getters });
52844
52946
  }
52845
52947
  else if (recreate) {
52846
52948
  this.pivots[pivotId].onDefinitionChange(definition);
@@ -59254,7 +59356,7 @@ const coreViewsPluginRegistry = new Registry$2()
59254
59356
  .add("pivot_ui", PivotUIPlugin)
59255
59357
  .add("cell_icon", CellIconPlugin);
59256
59358
 
59257
- class RangeAdapter {
59359
+ class RangeAdapterPlugin {
59258
59360
  getters;
59259
59361
  providers = [];
59260
59362
  isAdaptingRanges = false;
@@ -59262,7 +59364,6 @@ class RangeAdapter {
59262
59364
  this.getters = getters;
59263
59365
  }
59264
59366
  static getters = [
59265
- "adaptFormulaStringDependencies",
59266
59367
  "copyFormulaStringForSheet",
59267
59368
  "extendRange",
59268
59369
  "getRangeString",
@@ -59293,8 +59394,8 @@ class RangeAdapter {
59293
59394
  throw new Error("Plugins cannot dispatch commands during adaptRanges phase");
59294
59395
  }
59295
59396
  const rangeAdapter = getRangeAdapter(cmd);
59296
- if (rangeAdapter?.applyChange) {
59297
- this.executeOnAllRanges(rangeAdapter.applyChange, rangeAdapter.sheetId, rangeAdapter.sheetName);
59397
+ if (rangeAdapter) {
59398
+ this.executeOnAllRanges(rangeAdapter);
59298
59399
  }
59299
59400
  }
59300
59401
  finalize() { }
@@ -59313,11 +59414,15 @@ class RangeAdapter {
59313
59414
  return result;
59314
59415
  };
59315
59416
  }
59316
- executeOnAllRanges(adaptRange, sheetId, sheetName) {
59417
+ executeOnAllRanges(rangeAdapter) {
59317
59418
  this.isAdaptingRanges = true;
59318
- const func = this.verifyRangeRemoved(adaptRange);
59419
+ const adapterFunctions = {
59420
+ applyChange: this.verifyRangeRemoved(rangeAdapter.applyChange),
59421
+ adaptRangeString: (defaultSheetId, sheetXC) => adaptStringRange(defaultSheetId, sheetXC, rangeAdapter),
59422
+ adaptFormulaString: (defaultSheetId, formula) => adaptFormulaStringRanges(defaultSheetId, formula, rangeAdapter),
59423
+ };
59319
59424
  for (const provider of this.providers) {
59320
- provider(func, sheetId, sheetName);
59425
+ provider(adapterFunctions, rangeAdapter.sheetId, rangeAdapter.sheetName);
59321
59426
  }
59322
59427
  this.isAdaptingRanges = false;
59323
59428
  }
@@ -59485,18 +59590,6 @@ class RangeAdapter {
59485
59590
  const unionOfZones = unionUnboundedZones(...zones);
59486
59591
  return this.getRangeFromZone(ranges[0].sheetId, unionOfZones);
59487
59592
  }
59488
- adaptFormulaStringDependencies(sheetId, formula, applyChange) {
59489
- if (!formula.startsWith("=")) {
59490
- return formula;
59491
- }
59492
- const compiledFormula = compile(formula);
59493
- const updatedDependencies = compiledFormula.dependencies.map((dep) => {
59494
- const range = this.getters.getRangeFromSheetXC(sheetId, dep);
59495
- const changedRange = applyChange(range);
59496
- return changedRange.changeType === "NONE" ? range : changedRange.range;
59497
- });
59498
- return this.getters.getFormulaString(sheetId, compiledFormula.tokens, updatedDependencies);
59499
- }
59500
59593
  /**
59501
59594
  * Copy a formula string to another sheet.
59502
59595
  *
@@ -61938,6 +62031,12 @@ function addStyles(styles) {
61938
62031
  if (style.alignment && style.alignment.wrapText) {
61939
62032
  alignAttrs.push(["wrapText", "1"]);
61940
62033
  }
62034
+ if (style.alignment && style.alignment.textRotation) {
62035
+ alignAttrs.push(["textRotation", style.alignment.textRotation]);
62036
+ }
62037
+ if (style.alignment && style.alignment.shrinkToFit) {
62038
+ alignAttrs.push(["shrinkToFit", "1"]);
62039
+ }
61941
62040
  if (alignAttrs.length > 0) {
61942
62041
  attributes.push(["applyAlignment", "1"]); // for Libre Office
61943
62042
  styleNodes.push(escapeXml /*xml*/ `<xf ${formatAttributes(attributes)}><alignment ${formatAttributes(alignAttrs)} /></xf> `);
@@ -62732,7 +62831,7 @@ class Model extends EventBus {
62732
62831
  this.config = this.setupConfig(config);
62733
62832
  this.session = this.setupSession(workbookData.revisionId);
62734
62833
  this.coreGetters = {};
62735
- this.range = new RangeAdapter(this.coreGetters);
62834
+ this.range = new RangeAdapterPlugin(this.coreGetters);
62736
62835
  this.coreGetters.getRangeString = this.range.getRangeString.bind(this.range);
62737
62836
  this.coreGetters.getRangeFromSheetXC = this.range.getRangeFromSheetXC.bind(this.range);
62738
62837
  this.coreGetters.createAdaptedRanges = this.range.createAdaptedRanges.bind(this.range);
@@ -62746,8 +62845,6 @@ class Model extends EventBus {
62746
62845
  this.coreGetters.extendRange = this.range.extendRange.bind(this.range);
62747
62846
  this.coreGetters.getRangesUnion = this.range.getRangesUnion.bind(this.range);
62748
62847
  this.coreGetters.removeRangesSheetPrefix = this.range.removeRangesSheetPrefix.bind(this.range);
62749
- this.coreGetters.adaptFormulaStringDependencies =
62750
- this.range.adaptFormulaStringDependencies.bind(this.range);
62751
62848
  this.coreGetters.copyFormulaStringForSheet = this.range.copyFormulaStringForSheet.bind(this.range);
62752
62849
  this.getters = {
62753
62850
  isReadonly: () => this.config.mode === "readonly" || this.config.mode === "dashboard",
@@ -66875,7 +66972,7 @@ class BarChart extends AbstractChart {
66875
66972
  verticalAxis: getDefinedAxis(definition),
66876
66973
  };
66877
66974
  }
66878
- updateRanges(applyChange) {
66975
+ updateRanges({ applyChange }) {
66879
66976
  const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
66880
66977
  if (!isStale) {
66881
66978
  return this;
@@ -66986,8 +67083,8 @@ class GaugeChart extends AbstractChart {
66986
67083
  static transformDefinition(chartSheetId, definition, applyChange) {
66987
67084
  let dataRange;
66988
67085
  if (definition.dataRange) {
66989
- const adaptedRange = adaptStringRange(chartSheetId, definition.dataRange, applyChange);
66990
- if (adaptedRange !== CellErrorType.InvalidReference) {
67086
+ const { changeType, range: adaptedRange } = adaptStringRange(chartSheetId, definition.dataRange, applyChange);
67087
+ if (changeType !== "REMOVE") {
66991
67088
  dataRange = adaptedRange;
66992
67089
  }
66993
67090
  }
@@ -67064,13 +67161,9 @@ class GaugeChart extends AbstractChart {
67064
67161
  : undefined,
67065
67162
  };
67066
67163
  }
67067
- updateRanges(applyChange, sheetId, adaptSheetName) {
67164
+ updateRanges({ applyChange, adaptFormulaString }) {
67068
67165
  const dataRange = adaptChartRange(this.dataRange, applyChange);
67069
- const adaptFormula = (formula) => adaptFormulaStringRanges(this.sheetId, formula, {
67070
- applyChange,
67071
- sheetId,
67072
- sheetName: adaptSheetName,
67073
- });
67166
+ const adaptFormula = (formula) => adaptFormulaString(this.sheetId, formula);
67074
67167
  const sectionRule = adaptSectionRuleFormulas(this.sectionRule, adaptFormula);
67075
67168
  const definition = this.getDefinitionWithSpecificRanges(dataRange, sectionRule);
67076
67169
  return new GaugeChart(definition, this.sheetId, this.getters);
@@ -67312,7 +67405,7 @@ class LineChart extends AbstractChart {
67312
67405
  : undefined,
67313
67406
  };
67314
67407
  }
67315
- updateRanges(applyChange) {
67408
+ updateRanges({ applyChange }) {
67316
67409
  const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
67317
67410
  if (!isStale) {
67318
67411
  return this;
@@ -67469,7 +67562,7 @@ class PieChart extends AbstractChart {
67469
67562
  labelRange,
67470
67563
  };
67471
67564
  }
67472
- updateRanges(applyChange) {
67565
+ updateRanges({ applyChange }) {
67473
67566
  const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
67474
67567
  if (!isStale) {
67475
67568
  return this;
@@ -67634,7 +67727,7 @@ class WaterfallChart extends AbstractChart {
67634
67727
  // TODO: implement export excel
67635
67728
  return undefined;
67636
67729
  }
67637
- updateRanges(applyChange) {
67730
+ updateRanges({ applyChange }) {
67638
67731
  const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
67639
67732
  if (!isStale) {
67640
67733
  return this;
@@ -72010,7 +72103,6 @@ class AbstractComposerStore extends SpreadsheetStore {
72010
72103
  });
72011
72104
  }
72012
72105
  handleEvent(event) {
72013
- this.hideHelp();
72014
72106
  const sheetId = this.getters.getActiveSheetId();
72015
72107
  let unboundedZone;
72016
72108
  if (event.options.unbounded) {
@@ -72238,7 +72330,7 @@ class AbstractComposerStore extends SpreadsheetStore {
72238
72330
  }
72239
72331
  captureSelection(zone, col, row) {
72240
72332
  this.model.selection.capture(this, {
72241
- cell: { col: col ?? zone.left, row: row ?? zone.right },
72333
+ cell: { col: col ?? zone.left, row: row ?? zone.top },
72242
72334
  zone,
72243
72335
  }, {
72244
72336
  handleEvent: this.handleEvent.bind(this),
@@ -72332,6 +72424,7 @@ class AbstractComposerStore extends SpreadsheetStore {
72332
72424
  this.colorIndexByRange = {};
72333
72425
  this.hoveredTokens = [];
72334
72426
  this.hoveredContentEvaluation = "";
72427
+ this.hideHelp();
72335
72428
  }
72336
72429
  /**
72337
72430
  * Reset the current content to the active cell content
@@ -77961,35 +78054,46 @@ const formatRotation = {
77961
78054
  name: _t("Rotation"),
77962
78055
  icon: (env) => getRotationIcon(env),
77963
78056
  };
78057
+ function setRotation(env, rotation) {
78058
+ rotation = Math.trunc(rotation / ROTATION_EPSILON) * ROTATION_EPSILON;
78059
+ setStyle(env, { rotation });
78060
+ }
78061
+ function currentRotationEqual(env, rotation) {
78062
+ const current = env.model.getters.getCurrentStyle().rotation;
78063
+ if (current === undefined) {
78064
+ return rotation === 0;
78065
+ }
78066
+ return Math.abs(current - rotation) < ROTATION_EPSILON;
78067
+ }
77964
78068
  const formatNoRotation = {
77965
78069
  name: _t("No rotation"),
77966
78070
  execute: (env) => setStyle(env, { rotation: 0 }),
77967
78071
  icon: "o-spreadsheet-Icon.ROTATION-0",
77968
- isActive: (env) => env.model.getters.getCurrentStyle().rotation === 0,
78072
+ isActive: (env) => currentRotationEqual(env, 0),
77969
78073
  };
77970
78074
  const formatRotation45 = {
77971
78075
  name: _t("45° rotation"),
77972
- execute: (env) => setStyle(env, { rotation: Math.PI / 4 }),
78076
+ execute: (env) => setRotation(env, Math.PI / 4),
77973
78077
  icon: "o-spreadsheet-Icon.ROTATION-45",
77974
- isActive: (env) => env.model.getters.getCurrentStyle().rotation === Math.PI / 4,
78078
+ isActive: (env) => currentRotationEqual(env, Math.PI / 4),
77975
78079
  };
77976
78080
  const formatRotation90 = {
77977
78081
  name: _t("90° rotation"),
77978
- execute: (env) => setStyle(env, { rotation: Math.PI / 2 }),
78082
+ execute: (env) => setRotation(env, Math.PI / 2),
77979
78083
  icon: "o-spreadsheet-Icon.ROTATION-90",
77980
- isActive: (env) => env.model.getters.getCurrentStyle().rotation === Math.PI / 2,
78084
+ isActive: (env) => currentRotationEqual(env, Math.PI / 2),
77981
78085
  };
77982
78086
  const formatRotation270 = {
77983
78087
  name: _t("-90° rotation"),
77984
- execute: (env) => setStyle(env, { rotation: -Math.PI / 2 }),
78088
+ execute: (env) => setRotation(env, -Math.PI / 2),
77985
78089
  icon: "o-spreadsheet-Icon.ROTATION-270",
77986
- isActive: (env) => env.model.getters.getCurrentStyle().rotation === -Math.PI / 2,
78090
+ isActive: (env) => currentRotationEqual(env, -Math.PI / 2),
77987
78091
  };
77988
78092
  const formatRotation315 = {
77989
78093
  name: _t("-45° rotation"),
77990
- execute: (env) => setStyle(env, { rotation: -Math.PI / 4 }),
78094
+ execute: (env) => setRotation(env, -Math.PI / 4),
77991
78095
  icon: "o-spreadsheet-Icon.ROTATION-315",
77992
- isActive: (env) => env.model.getters.getCurrentStyle().rotation === -Math.PI / 4,
78096
+ isActive: (env) => currentRotationEqual(env, -Math.PI / 4),
77993
78097
  };
77994
78098
  const formatStrikethrough = {
77995
78099
  name: _t("Strikethrough"),
@@ -78155,10 +78259,6 @@ function getWrappingMode(env) {
78155
78259
  }
78156
78260
  return DEFAULT_WRAPPING_MODE;
78157
78261
  }
78158
- function getRotation(env) {
78159
- const style = env.model.getters.getCurrentStyle();
78160
- return style.rotation ?? 0;
78161
- }
78162
78262
  function getHorizontalAlignmentIcon(env) {
78163
78263
  const horizontalAlign = getHorizontalAlign(env);
78164
78264
  switch (horizontalAlign) {
@@ -78193,19 +78293,19 @@ function getWrapModeIcon(env) {
78193
78293
  }
78194
78294
  }
78195
78295
  function getRotationIcon(env) {
78196
- const rotation = getRotation(env);
78197
- switch (rotation) {
78198
- case Math.PI / 2:
78199
- return "o-spreadsheet-Icon.ROTATION-90";
78200
- case -Math.PI / 2:
78201
- return "o-spreadsheet-Icon.ROTATION-270";
78202
- case Math.PI / 4:
78203
- return "o-spreadsheet-Icon.ROTATION-45";
78204
- case -Math.PI / 4:
78205
- return "o-spreadsheet-Icon.ROTATION-315";
78206
- default:
78207
- return "o-spreadsheet-Icon.ROTATION-0";
78296
+ if (currentRotationEqual(env, Math.PI / 2)) {
78297
+ return "o-spreadsheet-Icon.ROTATION-90";
78208
78298
  }
78299
+ else if (currentRotationEqual(env, -Math.PI / 2)) {
78300
+ return "o-spreadsheet-Icon.ROTATION-270";
78301
+ }
78302
+ else if (currentRotationEqual(env, Math.PI / 4)) {
78303
+ return "o-spreadsheet-Icon.ROTATION-45";
78304
+ }
78305
+ else if (currentRotationEqual(env, -Math.PI / 4)) {
78306
+ return "o-spreadsheet-Icon.ROTATION-315";
78307
+ }
78308
+ return "o-spreadsheet-Icon.ROTATION-0";
78209
78309
  }
78210
78310
 
78211
78311
  const colMenuRegistry = new MenuItemRegistry();
@@ -84351,7 +84451,7 @@ class GaugeChartConfigPanel extends Component {
84351
84451
  });
84352
84452
  dataRange = this.props.definition.dataRange;
84353
84453
  get configurationErrorMessages() {
84354
- const cancelledReasons = [...(this.state.dataRangeDispatchResult?.reasons || [])];
84454
+ const cancelledReasons = [...(this.state.dataRangeDispatchResult?.reasons || [])].filter((reason) => reason !== "NoChanges" /* CommandResult.NoChanges */);
84355
84455
  return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
84356
84456
  }
84357
84457
  get isDataRangeInvalid() {
@@ -84393,7 +84493,7 @@ class GaugeChartDesignPanel extends Component {
84393
84493
  });
84394
84494
  }
84395
84495
  get designErrorMessages() {
84396
- const cancelledReasons = [...(this.state.sectionRuleCancelledReasons || [])];
84496
+ const cancelledReasons = [...(this.state.sectionRuleCancelledReasons || [])].filter((reason) => reason !== "NoChanges" /* CommandResult.NoChanges */);
84397
84497
  return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
84398
84498
  }
84399
84499
  get isRangeMinInvalid() {
@@ -84769,7 +84869,7 @@ class ScatterChart extends AbstractChart {
84769
84869
  : undefined,
84770
84870
  };
84771
84871
  }
84772
- updateRanges(applyChange) {
84872
+ updateRanges({ applyChange }) {
84773
84873
  const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
84774
84874
  if (!isStale) {
84775
84875
  return this;
@@ -84874,7 +84974,7 @@ class ScorecardChartConfigPanel extends Component {
84874
84974
  const cancelledReasons = [
84875
84975
  ...(this.state.keyValueDispatchResult?.reasons || []),
84876
84976
  ...(this.state.baselineDispatchResult?.reasons || []),
84877
- ];
84977
+ ].filter((reason) => reason !== "NoChanges" /* CommandResult.NoChanges */);
84878
84978
  return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
84879
84979
  }
84880
84980
  get isKeyValueInvalid() {
@@ -86417,6 +86517,12 @@ class FindAndReplaceStore extends SpreadsheetStore {
86417
86517
  case "ACTIVATE_SHEET":
86418
86518
  this.isSearchDirty = true;
86419
86519
  this.shouldFinalizeUpdateSelection = true;
86520
+ if (this.searchOptions.specificRange) {
86521
+ this.searchOptions.specificRange = {
86522
+ ...this.searchOptions.specificRange,
86523
+ sheetId: this.getters.getActiveSheetId(),
86524
+ };
86525
+ }
86420
86526
  break;
86421
86527
  case "REPLACE_SEARCH":
86422
86528
  for (const match of cmd.matches) {
@@ -86803,9 +86909,20 @@ class FindAndReplacePanel extends Component {
86803
86909
  const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
86804
86910
  this.store.updateSearchOptions({ specificRange });
86805
86911
  }
86912
+ get specificRange() {
86913
+ const range = this.store.searchOptions.specificRange;
86914
+ return range ? this.env.model.getters.getRangeString(range, "forceSheetReference") : "";
86915
+ }
86806
86916
  get pendingSearch() {
86807
86917
  return this.updateSearchContent.isDebouncePending();
86808
86918
  }
86919
+ get selectionInputKey() {
86920
+ // Selections input are made to work with objects linked to a sheet id. They store the active sheet id at their creation,
86921
+ // and have specific behaviour linked to it (eg. go back to the initial sheet after confirmation).
86922
+ // We don't want all those behaviors here, so we force the recreation of the component when the active sheet changes.
86923
+ // The only drawback is that the input loses focus when changing sheet.
86924
+ return this.env.model.getters.getActiveSheetId();
86925
+ }
86809
86926
  }
86810
86927
 
86811
86928
  /**
@@ -95371,7 +95488,7 @@ class CalendarChart extends AbstractChart {
95371
95488
  getDefinitionForExcel() {
95372
95489
  return undefined;
95373
95490
  }
95374
- updateRanges(applyChange) {
95491
+ updateRanges({ applyChange }) {
95375
95492
  const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
95376
95493
  if (!isStale) {
95377
95494
  return this;
@@ -95499,7 +95616,7 @@ class ComboChart extends AbstractChart {
95499
95616
  verticalAxis: getDefinedAxis(definition),
95500
95617
  };
95501
95618
  }
95502
- updateRanges(applyChange) {
95619
+ updateRanges({ applyChange }) {
95503
95620
  const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
95504
95621
  if (!isStale) {
95505
95622
  return this;
@@ -95675,7 +95792,7 @@ class FunnelChart extends AbstractChart {
95675
95792
  getDefinitionForExcel() {
95676
95793
  return undefined;
95677
95794
  }
95678
- updateRanges(applyChange) {
95795
+ updateRanges({ applyChange }) {
95679
95796
  const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
95680
95797
  if (!isStale) {
95681
95798
  return this;
@@ -95806,7 +95923,7 @@ class GeoChart extends AbstractChart {
95806
95923
  getDefinitionForExcel() {
95807
95924
  return undefined;
95808
95925
  }
95809
- updateRanges(applyChange) {
95926
+ updateRanges({ applyChange }) {
95810
95927
  const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
95811
95928
  if (!isStale) {
95812
95929
  return this;
@@ -95957,7 +96074,7 @@ class PyramidChart extends AbstractChart {
95957
96074
  maxValue,
95958
96075
  };
95959
96076
  }
95960
- updateRanges(applyChange) {
96077
+ updateRanges({ applyChange }) {
95961
96078
  const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
95962
96079
  if (!isStale) {
95963
96080
  return this;
@@ -96107,7 +96224,7 @@ class RadarChart extends AbstractChart {
96107
96224
  labelRange,
96108
96225
  };
96109
96226
  }
96110
- updateRanges(applyChange) {
96227
+ updateRanges({ applyChange }) {
96111
96228
  const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
96112
96229
  if (!isStale) {
96113
96230
  return this;
@@ -96244,7 +96361,7 @@ class SunburstChart extends AbstractChart {
96244
96361
  getDefinitionForExcel() {
96245
96362
  return undefined;
96246
96363
  }
96247
- updateRanges(applyChange) {
96364
+ updateRanges({ applyChange }) {
96248
96365
  const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
96249
96366
  if (!isStale) {
96250
96367
  return this;
@@ -96394,7 +96511,7 @@ class TreeMapChart extends AbstractChart {
96394
96511
  getDefinitionForExcel() {
96395
96512
  return undefined;
96396
96513
  }
96397
- updateRanges(applyChange) {
96514
+ updateRanges({ applyChange }) {
96398
96515
  const { dataSets, labelRange, isStale } = updateChartRangesWithDataSets(this.getters, applyChange, this.dataSets, this.labelRange);
96399
96516
  if (!isStale) {
96400
96517
  return this;
@@ -97930,6 +98047,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
97930
98047
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CorePlugin, CoreViewPlugin, DEFAULT_LOCALE, DEFAULT_LOCALES, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry$1 as Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, categories, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, createAutocompleteArgumentsProvider, findCellInNewZone, functionCache, getCaretDownSvg, getCaretUpSvg, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse$1 as parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
97931
98048
 
97932
98049
 
97933
- __info__.version = "19.1.2";
97934
- __info__.date = "2026-01-07T16:21:36.757Z";
97935
- __info__.hash = "febc3e9";
98050
+ __info__.version = "19.1.4";
98051
+ __info__.date = "2026-01-21T11:07:17.372Z";
98052
+ __info__.hash = "ceae12a";