@odoo/o-spreadsheet 19.2.0-alpha.3 → 19.2.0-alpha.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.
@@ -3,8 +3,8 @@
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
5
  * @version 19.1.0-alpha.3
6
- * @date 2026-01-14T10:01:30.535Z
7
- * @hash e5cbf18
6
+ * @date 2026-01-21T11:07:49.673Z
7
+ * @hash fa080c2
8
8
  */
9
9
 
10
10
  class FunctionCodeBuilder {
@@ -2544,7 +2544,11 @@ function evaluatePredicate(value = "", criterion, locale) {
2544
2544
  if (operator === "<>" || operator === "=") {
2545
2545
  let result;
2546
2546
  if (typeof value === typeof operand) {
2547
- if (typeof value === "string" && typeof operand === "string") {
2547
+ if (value === "" && operand === "") {
2548
+ // fast path to avoid regex evaluation
2549
+ result = true;
2550
+ }
2551
+ else if (typeof value === "string" && typeof operand === "string") {
2548
2552
  result = wildcardToRegExp(operand).test(value);
2549
2553
  }
2550
2554
  else {
@@ -2898,7 +2902,16 @@ function createComputeFunction(descr) {
2898
2902
  }
2899
2903
  acceptToVectorize.push(!argDefinition.acceptMatrix);
2900
2904
  }
2901
- return applyVectorization(errorHandlingCompute.bind(this), args, acceptToVectorize);
2905
+ return replaceErrorPlaceholderInResult(applyVectorization(errorHandlingCompute.bind(this), args, acceptToVectorize));
2906
+ }
2907
+ function replaceErrorPlaceholderInResult(result) {
2908
+ if (!isMatrix(result)) {
2909
+ replaceFunctionNamePlaceholder(result, descr.name);
2910
+ }
2911
+ else {
2912
+ matrixForEach(result, (result) => replaceFunctionNamePlaceholder(result, descr.name));
2913
+ }
2914
+ return result;
2902
2915
  }
2903
2916
  function errorHandlingCompute(...args) {
2904
2917
  for (let i = 0; i < args.length; i++) {
@@ -2927,13 +2940,12 @@ function createComputeFunction(descr) {
2927
2940
  const result = descr.compute.apply(this, args);
2928
2941
  if (!isMatrix(result)) {
2929
2942
  if (typeof result === "object" && result !== null && "value" in result) {
2930
- replaceFunctionNamePlaceholder(result, descr.name);
2931
2943
  return result;
2932
2944
  }
2945
+ descr.name;
2933
2946
  return { value: result };
2934
2947
  }
2935
2948
  if (typeof result[0][0] === "object" && result[0][0] !== null && "value" in result[0][0]) {
2936
- matrixForEach(result, (result) => replaceFunctionNamePlaceholder(result, descr.name));
2937
2949
  return result;
2938
2950
  }
2939
2951
  return matrixMap(result, (row) => ({ value: row }));
@@ -3916,9 +3928,14 @@ function formatLargeNumber(arg, unit, locale) {
3916
3928
  else if (value < 1e11) {
3917
3929
  return createLargeNumberFormat(format, 2, "m");
3918
3930
  }
3919
- return createLargeNumberFormat(format, 3, "b");
3931
+ else if (value < 1e14) {
3932
+ return createLargeNumberFormat(format, 3, "b");
3933
+ }
3934
+ else {
3935
+ return "0.00e";
3936
+ }
3920
3937
  }
3921
- function createLargeNumberFormat(format, magnitude, postFix, locale) {
3938
+ function createLargeNumberFormat(format, magnitude, postFix) {
3922
3939
  const multiPartFormat = parseFormat(format || "#,##0");
3923
3940
  const roundedInternalFormat = {
3924
3941
  positive: _createLargeNumberFormat(multiPartFormat.positive, magnitude, postFix),
@@ -18036,7 +18053,7 @@ function getApplyRangeChangeRemoveColRow(cmd) {
18036
18053
  const groups = groupConsecutive(elements);
18037
18054
  return (range) => {
18038
18055
  if (range.sheetId !== cmd.sheetId) {
18039
- return { changeType: "NONE" };
18056
+ return { changeType: "NONE", range };
18040
18057
  }
18041
18058
  let newRange = range;
18042
18059
  let changeType = "NONE";
@@ -18063,10 +18080,7 @@ function getApplyRangeChangeRemoveColRow(cmd) {
18063
18080
  newRange = createAdaptedRange(newRange, dimension, changeType, -(max - min + 1));
18064
18081
  }
18065
18082
  }
18066
- if (changeType !== "NONE") {
18067
- return { changeType, range: newRange };
18068
- }
18069
- return { changeType: "NONE" };
18083
+ return { changeType, range: newRange };
18070
18084
  };
18071
18085
  }
18072
18086
  function getApplyRangeChangeAddColRow(cmd) {
@@ -18075,7 +18089,7 @@ function getApplyRangeChangeAddColRow(cmd) {
18075
18089
  const dimension = cmd.dimension === "COL" ? "columns" : "rows";
18076
18090
  return (range) => {
18077
18091
  if (range.sheetId !== cmd.sheetId) {
18078
- return { changeType: "NONE" };
18092
+ return { changeType: "NONE", range };
18079
18093
  }
18080
18094
  if (cmd.position === "after") {
18081
18095
  if (range.zone[start] <= cmd.base && cmd.base < range.zone[end]) {
@@ -18105,13 +18119,13 @@ function getApplyRangeChangeAddColRow(cmd) {
18105
18119
  };
18106
18120
  }
18107
18121
  }
18108
- return { changeType: "NONE" };
18122
+ return { changeType: "NONE", range };
18109
18123
  };
18110
18124
  }
18111
18125
  function getApplyRangeChangeDeleteSheet(cmd) {
18112
18126
  return (range) => {
18113
18127
  if (range.sheetId !== cmd.sheetId && range.invalidSheetName !== cmd.sheetName) {
18114
- return { changeType: "NONE" };
18128
+ return { changeType: "NONE", range };
18115
18129
  }
18116
18130
  const invalidSheetName = cmd.sheetName;
18117
18131
  range = {
@@ -18138,14 +18152,14 @@ function getApplyRangeChangeRenameSheet(cmd) {
18138
18152
  const newRange = { ...range, sheetId, invalidSheetName };
18139
18153
  return { changeType: "CHANGE", range: newRange };
18140
18154
  }
18141
- return { changeType: "NONE" };
18155
+ return { changeType: "NONE", range };
18142
18156
  };
18143
18157
  }
18144
18158
  function getApplyRangeChangeMoveRange(cmd) {
18145
18159
  const originZone = cmd.target[0];
18146
18160
  return (range) => {
18147
18161
  if (range.sheetId !== cmd.sheetId || !isZoneInside(range.zone, originZone)) {
18148
- return { changeType: "NONE" };
18162
+ return { changeType: "NONE", range };
18149
18163
  }
18150
18164
  const targetSheetId = cmd.targetSheetId;
18151
18165
  const offsetX = cmd.col - originZone.left;
@@ -20077,7 +20091,7 @@ function adaptFormulaStringRanges(defaultSheetId, formula, applyChange) {
20077
20091
  continue;
20078
20092
  }
20079
20093
  const sheetXC = tokens[tokenIdx].value;
20080
- const newSheetXC = adaptStringRange(defaultSheetId, sheetXC, applyChange);
20094
+ const newSheetXC = adaptStringRange(defaultSheetId, sheetXC, applyChange).range;
20081
20095
  if (sheetXC !== newSheetXC) {
20082
20096
  tokens[tokenIdx] = {
20083
20097
  value: newSheetXC,
@@ -20087,23 +20101,30 @@ function adaptFormulaStringRanges(defaultSheetId, formula, applyChange) {
20087
20101
  }
20088
20102
  return concat(tokens.map((token) => token.value));
20089
20103
  }
20090
- function adaptStringRange(defaultSheetId, sheetXC, applyChange) {
20104
+ function adaptStringRange(defaultSheetId, sheetXC, rangeAdapter) {
20091
20105
  const sheetName = splitReference(sheetXC).sheetName;
20092
20106
  if (sheetName
20093
- ? !isSheetNameEqual(sheetName, applyChange.sheetName.old)
20094
- : defaultSheetId !== applyChange.sheetId) {
20095
- return sheetXC;
20107
+ ? !isSheetNameEqual(sheetName, rangeAdapter.sheetName.old)
20108
+ : defaultSheetId !== rangeAdapter.sheetId) {
20109
+ return { changeType: "NONE", range: sheetXC };
20096
20110
  }
20097
- const sheetId = sheetName ? applyChange.sheetId : defaultSheetId;
20111
+ const sheetId = sheetName ? rangeAdapter.sheetId : defaultSheetId;
20098
20112
  const range = getRange(sheetXC, sheetId);
20099
20113
  if (range.invalidXc) {
20100
- return sheetXC;
20114
+ return { changeType: "NONE", range: sheetXC };
20101
20115
  }
20102
- const change = applyChange.applyChange(range);
20116
+ const change = rangeAdapter.applyChange(range);
20103
20117
  if (change.changeType === "NONE" || change.changeType === "REMOVE") {
20104
- return sheetXC;
20118
+ return { changeType: change.changeType, range: sheetXC };
20105
20119
  }
20106
- return getRangeString(change.range, defaultSheetId, getSheetNameGetter(applyChange));
20120
+ const rangeStr = getRangeString(change.range, defaultSheetId, getSheetNameGetter(rangeAdapter));
20121
+ if (rangeStr === CellErrorType.InvalidReference) {
20122
+ return { changeType: "REMOVE", range: rangeStr };
20123
+ }
20124
+ return {
20125
+ changeType: change.changeType,
20126
+ range: rangeStr,
20127
+ };
20107
20128
  }
20108
20129
  function getSheetNameGetter(applyChange) {
20109
20130
  return (sheetId) => {
@@ -20318,7 +20339,7 @@ function addConditionalFormatCommandAdaptRange(cmd, applyChange) {
20318
20339
  cmd.cf.rule = {
20319
20340
  ...rule,
20320
20341
  rangeValues: rule.rangeValues
20321
- ? adaptStringRange(cmd.sheetId, rule.rangeValues, applyChange)
20342
+ ? adaptStringRange(cmd.sheetId, rule.rangeValues, applyChange).range
20322
20343
  : undefined,
20323
20344
  };
20324
20345
  }
@@ -22811,6 +22832,413 @@ function hexaToInt(hex) {
22811
22832
  */
22812
22833
  const DEFAULT_SYSTEM_COLOR = "FF000000";
22813
22834
 
22835
+ const globalReverseLookup$1 = new WeakMap();
22836
+ const globalIdCounter = new WeakMap();
22837
+ /**
22838
+ * Get the id of the given item (its key in the given dictionary).
22839
+ * If the given item does not exist in the dictionary, it creates one with a new id.
22840
+ */
22841
+ function getItemId(item, itemsDic) {
22842
+ if (!globalReverseLookup$1.has(itemsDic)) {
22843
+ globalReverseLookup$1.set(itemsDic, new Map());
22844
+ globalIdCounter.set(itemsDic, 0);
22845
+ }
22846
+ const reverseLookup = globalReverseLookup$1.get(itemsDic);
22847
+ const canonical = getCanonicalRepresentation(item);
22848
+ if (reverseLookup.has(canonical)) {
22849
+ const id = reverseLookup.get(canonical);
22850
+ itemsDic[id] = item;
22851
+ return id;
22852
+ }
22853
+ // Generate new Id if the item didn't exist in the dictionary
22854
+ const newId = globalIdCounter.get(itemsDic) + 1;
22855
+ reverseLookup.set(canonical, newId);
22856
+ globalIdCounter.set(itemsDic, newId);
22857
+ itemsDic[newId] = item;
22858
+ return newId;
22859
+ }
22860
+ function groupItemIdsByZones(positionsByItemId) {
22861
+ const result = {};
22862
+ for (const itemId in positionsByItemId) {
22863
+ const zones = recomputeZones(positionsByItemId[itemId].map(positionToZone));
22864
+ for (const zone of zones) {
22865
+ result[zoneToXc(zone)] = Number(itemId);
22866
+ }
22867
+ }
22868
+ return result;
22869
+ }
22870
+ function* iterateItemIdsPositions(sheetId, itemIdsByZones) {
22871
+ for (const zoneXc in itemIdsByZones) {
22872
+ const zone = toZone(zoneXc);
22873
+ const itemId = itemIdsByZones[zoneXc];
22874
+ for (let row = zone.top; row <= zone.bottom; row++) {
22875
+ for (let col = zone.left; col <= zone.right; col++) {
22876
+ const position = { sheetId, col, row };
22877
+ yield [position, itemId];
22878
+ }
22879
+ }
22880
+ }
22881
+ }
22882
+ function getCanonicalRepresentation(item) {
22883
+ if (item === null) {
22884
+ return "null";
22885
+ }
22886
+ if (item === undefined) {
22887
+ return "undefined";
22888
+ }
22889
+ if (typeof item !== "object") {
22890
+ return String(item);
22891
+ }
22892
+ if (Array.isArray(item)) {
22893
+ const len = item.length;
22894
+ let result = "[";
22895
+ for (let i = 0; i < len; i++) {
22896
+ if (i > 0) {
22897
+ result += ",";
22898
+ }
22899
+ result += getCanonicalRepresentation(item[i]);
22900
+ }
22901
+ return result + "]";
22902
+ }
22903
+ const keys = Object.keys(item).sort();
22904
+ let repr = "{";
22905
+ for (const key of keys) {
22906
+ if (item[key] !== undefined) {
22907
+ repr += `"${key}":${getCanonicalRepresentation(item[key])},`;
22908
+ }
22909
+ }
22910
+ repr += "}";
22911
+ return repr;
22912
+ }
22913
+
22914
+ // -------------------------------------
22915
+ // CF HELPERS
22916
+ // -------------------------------------
22917
+ /**
22918
+ * Convert the conditional formatting o-spreadsheet operator to
22919
+ * the corresponding excel operator.
22920
+ * */
22921
+ function convertOperator(operator) {
22922
+ switch (operator) {
22923
+ case "isNotEmpty":
22924
+ return "notContainsBlanks";
22925
+ case "isEmpty":
22926
+ return "containsBlanks";
22927
+ case "notContainsText":
22928
+ return "notContainsBlanks";
22929
+ case "containsText":
22930
+ return "containsText";
22931
+ case "beginsWithText":
22932
+ return "beginsWith";
22933
+ case "endsWithText":
22934
+ return "endsWith";
22935
+ case "isGreaterThan":
22936
+ return "greaterThan";
22937
+ case "isGreaterOrEqualTo":
22938
+ return "greaterThanOrEqual";
22939
+ case "isLessThan":
22940
+ return "lessThan";
22941
+ case "isLessOrEqualTo":
22942
+ return "lessThanOrEqual";
22943
+ case "isBetween":
22944
+ return "between";
22945
+ case "isNotBetween":
22946
+ return "notBetween";
22947
+ case "isEqual":
22948
+ return "equal";
22949
+ case "isNotEqual":
22950
+ return "notEqual";
22951
+ case "customFormula":
22952
+ return "";
22953
+ case "dateIs":
22954
+ return "";
22955
+ case "dateIsBefore":
22956
+ return "lessThan";
22957
+ case "dateIsAfter":
22958
+ return "greaterThan";
22959
+ case "dateIsOnOrAfter":
22960
+ return "greaterThanOrEqual";
22961
+ case "dateIsOnOrBefore":
22962
+ return "lessThanOrEqual";
22963
+ case "top10":
22964
+ return "top10";
22965
+ }
22966
+ }
22967
+ // -------------------------------------
22968
+ // WORKSHEET HELPERS
22969
+ // -------------------------------------
22970
+ function getCellType(value) {
22971
+ switch (typeof value) {
22972
+ case "boolean":
22973
+ return "b";
22974
+ case "string":
22975
+ return "str";
22976
+ case "number":
22977
+ return "n";
22978
+ default:
22979
+ return undefined;
22980
+ }
22981
+ }
22982
+ function convertHeightToExcel(height) {
22983
+ return Math.round(HEIGHT_FACTOR * height * 100) / 100;
22984
+ }
22985
+ function convertWidthToExcel(width) {
22986
+ return Math.round(WIDTH_FACTOR * width * 100) / 100;
22987
+ }
22988
+ function convertHeightFromExcel(height) {
22989
+ if (!height) {
22990
+ return height;
22991
+ }
22992
+ return Math.round((height / HEIGHT_FACTOR) * 100) / 100;
22993
+ }
22994
+ function convertWidthFromExcel(width) {
22995
+ if (!width) {
22996
+ return width;
22997
+ }
22998
+ return Math.round((width / WIDTH_FACTOR) * 100) / 100;
22999
+ }
23000
+ function extractStyle(data, content, styleId, formatId, borderId) {
23001
+ const style = styleId ? data.styles[styleId] : {};
23002
+ const format = formatId ? data.formats[formatId] : undefined;
23003
+ const styles = {
23004
+ font: {
23005
+ size: style?.fontSize || DEFAULT_FONT_SIZE,
23006
+ color: { rgb: style?.textColor ? style.textColor : "000000" },
23007
+ family: 2,
23008
+ name: "Arial",
23009
+ },
23010
+ fill: style?.fillColor
23011
+ ? {
23012
+ fgColor: { rgb: style.fillColor },
23013
+ }
23014
+ : { reservedAttribute: "none" },
23015
+ numFmt: format ? { format: format, id: 0 /* id not used for export */ } : undefined,
23016
+ border: borderId || 0,
23017
+ alignment: {
23018
+ horizontal: style.align,
23019
+ vertical: style.verticalAlign
23020
+ ? V_ALIGNMENT_EXPORT_CONVERSION_MAP[style.verticalAlign]
23021
+ : undefined,
23022
+ wrapText: style.wrapping === "wrap" || content?.includes(NEWLINE) ? true : undefined,
23023
+ textRotation: style.rotation ? rotationToXLSX(style.rotation) : undefined,
23024
+ shrinkToFit: style.wrapping === "clip" ? true : undefined,
23025
+ },
23026
+ };
23027
+ styles.font["strike"] = !!style?.strikethrough || undefined;
23028
+ styles.font["underline"] = !!style?.underline || undefined;
23029
+ styles.font["bold"] = !!style?.bold || undefined;
23030
+ styles.font["italic"] = !!style?.italic || undefined;
23031
+ return styles;
23032
+ }
23033
+ function rotationToXLSX(rad) {
23034
+ let deg = Math.round((-rad / Math.PI) * 180) % 180;
23035
+ if (deg > 90) {
23036
+ deg -= 180;
23037
+ }
23038
+ else if (deg < -90) {
23039
+ deg += 180;
23040
+ }
23041
+ if (deg >= 0) {
23042
+ return deg;
23043
+ }
23044
+ else {
23045
+ return 90 - deg;
23046
+ }
23047
+ }
23048
+ function rotationFromXLSX(deg) {
23049
+ if (deg <= 90) {
23050
+ return -(deg / 180) * Math.PI;
23051
+ }
23052
+ else {
23053
+ return (-(90 - deg) / 180) * Math.PI;
23054
+ }
23055
+ }
23056
+ function normalizeStyle(construct, styles) {
23057
+ // Normalize this
23058
+ const numFmtId = convertFormat(styles["numFmt"], construct.numFmts);
23059
+ const style = {
23060
+ fontId: pushElement(styles.font, construct.fonts),
23061
+ fillId: pushElement(styles.fill, construct.fills),
23062
+ borderId: styles.border,
23063
+ numFmtId,
23064
+ alignment: {
23065
+ vertical: styles.alignment.vertical,
23066
+ horizontal: styles.alignment.horizontal,
23067
+ wrapText: styles.alignment.wrapText,
23068
+ textRotation: styles.alignment.textRotation,
23069
+ shrinkToFit: styles.alignment.shrinkToFit,
23070
+ },
23071
+ };
23072
+ return pushElement(style, construct.styles);
23073
+ }
23074
+ function convertFormat(format, numFmtStructure) {
23075
+ if (!format) {
23076
+ return 0;
23077
+ }
23078
+ let formatId = XLSX_FORMAT_MAP[format.format];
23079
+ if (!formatId) {
23080
+ formatId = pushElement(format, numFmtStructure) + FIRST_NUMFMT_ID;
23081
+ }
23082
+ return formatId;
23083
+ }
23084
+ /**
23085
+ * Add a relation to the given file and return its id.
23086
+ */
23087
+ function addRelsToFile(relsFiles, path, rel) {
23088
+ const relsFile = relsFiles.find((file) => file.path === path);
23089
+ // the id is a one-based int casted as string
23090
+ let id;
23091
+ if (!relsFile) {
23092
+ id = "rId1";
23093
+ relsFiles.push({ path, rels: [{ ...rel, id }] });
23094
+ }
23095
+ else {
23096
+ id = `rId${(relsFile.rels.length + 1).toString()}`;
23097
+ relsFile.rels.push({
23098
+ ...rel,
23099
+ id,
23100
+ });
23101
+ }
23102
+ return id;
23103
+ }
23104
+ const globalReverseLookup = new WeakMap();
23105
+ function pushElement(property, propertyList) {
23106
+ let reverseLookup = globalReverseLookup.get(propertyList);
23107
+ if (!reverseLookup) {
23108
+ reverseLookup = new Map();
23109
+ for (let i = 0; i < propertyList.length; i++) {
23110
+ const canonical = getCanonicalRepresentation(propertyList[i]);
23111
+ reverseLookup.set(canonical, i);
23112
+ }
23113
+ globalReverseLookup.set(propertyList, reverseLookup);
23114
+ }
23115
+ const canonical = getCanonicalRepresentation(property);
23116
+ if (reverseLookup.has(canonical)) {
23117
+ return reverseLookup.get(canonical);
23118
+ }
23119
+ const maxId = propertyList.length;
23120
+ propertyList.push(property);
23121
+ reverseLookup.set(canonical, maxId);
23122
+ return maxId;
23123
+ }
23124
+ /**
23125
+ * Convert a chart o-spreadsheet id to a xlsx id which
23126
+ * are unsigned integers (starting from 1).
23127
+ */
23128
+ function convertChartId(chartId, construct) {
23129
+ const xlsxId = construct.chartIds.findIndex((id) => id === chartId);
23130
+ if (xlsxId === -1) {
23131
+ construct.chartIds.push(chartId);
23132
+ return construct.chartIds.length;
23133
+ }
23134
+ return xlsxId + 1;
23135
+ }
23136
+ const imageIds = [];
23137
+ /**
23138
+ * Convert a image o-spreadsheet id to a xlsx id which
23139
+ * are unsigned integers (starting from 1).
23140
+ */
23141
+ function convertImageId(imageId) {
23142
+ const xlsxId = imageIds.findIndex((id) => id === imageId);
23143
+ if (xlsxId === -1) {
23144
+ imageIds.push(imageId);
23145
+ return imageIds.length;
23146
+ }
23147
+ return xlsxId + 1;
23148
+ }
23149
+ /**
23150
+ * Convert a value expressed in dot to EMU.
23151
+ * EMU = English Metrical Unit
23152
+ * There are 914400 EMU per inch.
23153
+ *
23154
+ * /!\ A value expressed in EMU cannot be fractional.
23155
+ * See https://docs.microsoft.com/en-us/windows/win32/vml/msdn-online-vml-units#other-units-of-measurement
23156
+ */
23157
+ function convertDotValueToEMU(value) {
23158
+ const DPI = 96;
23159
+ return Math.round((value * 914400) / DPI);
23160
+ }
23161
+ function getRangeSize(reference, defaultSheetIndex, data) {
23162
+ let xc = reference;
23163
+ let sheetName = undefined;
23164
+ ({ xc, sheetName } = splitReference(reference));
23165
+ let rangeSheetIndex;
23166
+ if (sheetName) {
23167
+ const index = data.sheets.findIndex((sheet) => isSheetNameEqual(sheet.name, sheetName));
23168
+ if (index < 0) {
23169
+ throw new Error("Unable to find a sheet with the name " + sheetName);
23170
+ }
23171
+ rangeSheetIndex = index;
23172
+ }
23173
+ else {
23174
+ rangeSheetIndex = Number(defaultSheetIndex);
23175
+ }
23176
+ const zone = toUnboundedZone(xc);
23177
+ if (zone.right === undefined) {
23178
+ zone.right = data.sheets[rangeSheetIndex].colNumber;
23179
+ }
23180
+ if (zone.bottom === undefined) {
23181
+ zone.bottom = data.sheets[rangeSheetIndex].rowNumber;
23182
+ }
23183
+ return (zone.right - zone.left + 1) * (zone.bottom - zone.top + 1);
23184
+ }
23185
+ function convertEMUToDotValue(value) {
23186
+ const DPI = 96;
23187
+ return Math.round((value * DPI) / 914400);
23188
+ }
23189
+ /**
23190
+ * Get the position of the start of a column in Excel (in px).
23191
+ */
23192
+ function getColPosition(colIndex, sheetData) {
23193
+ let position = 0;
23194
+ for (let i = 0; i < colIndex; i++) {
23195
+ const colAtIndex = sheetData.cols.find((col) => i >= col.min && i <= col.max);
23196
+ if (colAtIndex?.width) {
23197
+ position += colAtIndex.width;
23198
+ }
23199
+ else if (sheetData.sheetFormat?.defaultColWidth) {
23200
+ position += sheetData.sheetFormat.defaultColWidth;
23201
+ }
23202
+ else {
23203
+ position += EXCEL_DEFAULT_COL_WIDTH;
23204
+ }
23205
+ }
23206
+ return position / WIDTH_FACTOR;
23207
+ }
23208
+ /**
23209
+ * Get the position of the start of a row in Excel (in px).
23210
+ */
23211
+ function getRowPosition(rowIndex, sheetData) {
23212
+ let position = 0;
23213
+ for (let i = 0; i < rowIndex; i++) {
23214
+ const rowAtIndex = sheetData.rows.find((row) => row.index - 1 === i);
23215
+ if (rowAtIndex?.height) {
23216
+ position += rowAtIndex.height;
23217
+ }
23218
+ else if (sheetData.sheetFormat?.defaultRowHeight) {
23219
+ position += sheetData.sheetFormat.defaultRowHeight;
23220
+ }
23221
+ else {
23222
+ position += EXCEL_DEFAULT_ROW_HEIGHT;
23223
+ }
23224
+ }
23225
+ return position / HEIGHT_FACTOR;
23226
+ }
23227
+ /**
23228
+ * Convert the o-spreadsheet data validation decimal
23229
+ * criterion type to the corresponding excel operator.
23230
+ */
23231
+ function convertDecimalCriterionTypeToExcelOperator(operator) {
23232
+ return Object.keys(XLSX_DV_DECIMAL_OPERATOR_MAPPING).find((key) => XLSX_DV_DECIMAL_OPERATOR_MAPPING[key] === operator);
23233
+ }
23234
+ /**
23235
+ * Convert the o-spreadsheet data validation date
23236
+ * criterion type to the corresponding excel operator.
23237
+ */
23238
+ function convertDateCriterionTypeToExcelOperator(operator) {
23239
+ return Object.keys(XLSX_DV_DATE_OPERATOR_TO_DV_TYPE_MAPPING).find((key) => XLSX_DV_DATE_OPERATOR_TO_DV_TYPE_MAPPING[key] === operator);
23240
+ }
23241
+
22814
23242
  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;
22815
23243
  /**
22816
23244
  * Convert excel format to o_spreadsheet format
@@ -22911,6 +23339,9 @@ function convertStyle(styleStruct, warningManager) {
22911
23339
  align: styleStruct.alignment?.horizontal
22912
23340
  ? H_ALIGNMENT_CONVERSION_MAP[styleStruct.alignment.horizontal]
22913
23341
  : undefined,
23342
+ rotation: styleStruct.alignment?.textRotation
23343
+ ? rotationFromXLSX(styleStruct.alignment.textRotation)
23344
+ : undefined,
22914
23345
  // 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
22915
23346
  fillColor: styleStruct.fillStyle?.patternType === "solid"
22916
23347
  ? convertColor(styleStruct.fillStyle?.fgColor)
@@ -23232,386 +23663,6 @@ function addCfConversionWarnings(cf, dxfs, warningManager) {
23232
23663
  }
23233
23664
  }
23234
23665
 
23235
- const globalReverseLookup$1 = new WeakMap();
23236
- const globalIdCounter = new WeakMap();
23237
- /**
23238
- * Get the id of the given item (its key in the given dictionary).
23239
- * If the given item does not exist in the dictionary, it creates one with a new id.
23240
- */
23241
- function getItemId(item, itemsDic) {
23242
- if (!globalReverseLookup$1.has(itemsDic)) {
23243
- globalReverseLookup$1.set(itemsDic, new Map());
23244
- globalIdCounter.set(itemsDic, 0);
23245
- }
23246
- const reverseLookup = globalReverseLookup$1.get(itemsDic);
23247
- const canonical = getCanonicalRepresentation(item);
23248
- if (reverseLookup.has(canonical)) {
23249
- const id = reverseLookup.get(canonical);
23250
- itemsDic[id] = item;
23251
- return id;
23252
- }
23253
- // Generate new Id if the item didn't exist in the dictionary
23254
- const newId = globalIdCounter.get(itemsDic) + 1;
23255
- reverseLookup.set(canonical, newId);
23256
- globalIdCounter.set(itemsDic, newId);
23257
- itemsDic[newId] = item;
23258
- return newId;
23259
- }
23260
- function groupItemIdsByZones(positionsByItemId) {
23261
- const result = {};
23262
- for (const itemId in positionsByItemId) {
23263
- const zones = recomputeZones(positionsByItemId[itemId].map(positionToZone));
23264
- for (const zone of zones) {
23265
- result[zoneToXc(zone)] = Number(itemId);
23266
- }
23267
- }
23268
- return result;
23269
- }
23270
- function* iterateItemIdsPositions(sheetId, itemIdsByZones) {
23271
- for (const zoneXc in itemIdsByZones) {
23272
- const zone = toZone(zoneXc);
23273
- const itemId = itemIdsByZones[zoneXc];
23274
- for (let row = zone.top; row <= zone.bottom; row++) {
23275
- for (let col = zone.left; col <= zone.right; col++) {
23276
- const position = { sheetId, col, row };
23277
- yield [position, itemId];
23278
- }
23279
- }
23280
- }
23281
- }
23282
- function getCanonicalRepresentation(item) {
23283
- if (item === null) {
23284
- return "null";
23285
- }
23286
- if (item === undefined) {
23287
- return "undefined";
23288
- }
23289
- if (typeof item !== "object") {
23290
- return String(item);
23291
- }
23292
- if (Array.isArray(item)) {
23293
- const len = item.length;
23294
- let result = "[";
23295
- for (let i = 0; i < len; i++) {
23296
- if (i > 0) {
23297
- result += ",";
23298
- }
23299
- result += getCanonicalRepresentation(item[i]);
23300
- }
23301
- return result + "]";
23302
- }
23303
- const keys = Object.keys(item).sort();
23304
- let repr = "{";
23305
- for (const key of keys) {
23306
- if (item[key] !== undefined) {
23307
- repr += `"${key}":${getCanonicalRepresentation(item[key])},`;
23308
- }
23309
- }
23310
- repr += "}";
23311
- return repr;
23312
- }
23313
-
23314
- // -------------------------------------
23315
- // CF HELPERS
23316
- // -------------------------------------
23317
- /**
23318
- * Convert the conditional formatting o-spreadsheet operator to
23319
- * the corresponding excel operator.
23320
- * */
23321
- function convertOperator(operator) {
23322
- switch (operator) {
23323
- case "isNotEmpty":
23324
- return "notContainsBlanks";
23325
- case "isEmpty":
23326
- return "containsBlanks";
23327
- case "notContainsText":
23328
- return "notContainsBlanks";
23329
- case "containsText":
23330
- return "containsText";
23331
- case "beginsWithText":
23332
- return "beginsWith";
23333
- case "endsWithText":
23334
- return "endsWith";
23335
- case "isGreaterThan":
23336
- return "greaterThan";
23337
- case "isGreaterOrEqualTo":
23338
- return "greaterThanOrEqual";
23339
- case "isLessThan":
23340
- return "lessThan";
23341
- case "isLessOrEqualTo":
23342
- return "lessThanOrEqual";
23343
- case "isBetween":
23344
- return "between";
23345
- case "isNotBetween":
23346
- return "notBetween";
23347
- case "isEqual":
23348
- return "equal";
23349
- case "isNotEqual":
23350
- return "notEqual";
23351
- case "customFormula":
23352
- return "";
23353
- case "dateIs":
23354
- return "";
23355
- case "dateIsBefore":
23356
- return "lessThan";
23357
- case "dateIsAfter":
23358
- return "greaterThan";
23359
- case "dateIsOnOrAfter":
23360
- return "greaterThanOrEqual";
23361
- case "dateIsOnOrBefore":
23362
- return "lessThanOrEqual";
23363
- case "top10":
23364
- return "top10";
23365
- }
23366
- }
23367
- // -------------------------------------
23368
- // WORKSHEET HELPERS
23369
- // -------------------------------------
23370
- function getCellType(value) {
23371
- switch (typeof value) {
23372
- case "boolean":
23373
- return "b";
23374
- case "string":
23375
- return "str";
23376
- case "number":
23377
- return "n";
23378
- default:
23379
- return undefined;
23380
- }
23381
- }
23382
- function convertHeightToExcel(height) {
23383
- return Math.round(HEIGHT_FACTOR * height * 100) / 100;
23384
- }
23385
- function convertWidthToExcel(width) {
23386
- return Math.round(WIDTH_FACTOR * width * 100) / 100;
23387
- }
23388
- function convertHeightFromExcel(height) {
23389
- if (!height) {
23390
- return height;
23391
- }
23392
- return Math.round((height / HEIGHT_FACTOR) * 100) / 100;
23393
- }
23394
- function convertWidthFromExcel(width) {
23395
- if (!width) {
23396
- return width;
23397
- }
23398
- return Math.round((width / WIDTH_FACTOR) * 100) / 100;
23399
- }
23400
- function extractStyle(data, content, styleId, formatId, borderId) {
23401
- const style = styleId ? data.styles[styleId] : {};
23402
- const format = formatId ? data.formats[formatId] : undefined;
23403
- const styles = {
23404
- font: {
23405
- size: style?.fontSize || DEFAULT_FONT_SIZE,
23406
- color: { rgb: style?.textColor ? style.textColor : "000000" },
23407
- family: 2,
23408
- name: "Arial",
23409
- },
23410
- fill: style?.fillColor
23411
- ? {
23412
- fgColor: { rgb: style.fillColor },
23413
- }
23414
- : { reservedAttribute: "none" },
23415
- numFmt: format ? { format: format, id: 0 /* id not used for export */ } : undefined,
23416
- border: borderId || 0,
23417
- alignment: {
23418
- horizontal: style.align,
23419
- vertical: style.verticalAlign
23420
- ? V_ALIGNMENT_EXPORT_CONVERSION_MAP[style.verticalAlign]
23421
- : undefined,
23422
- wrapText: style.wrapping === "wrap" || content?.includes(NEWLINE) ? true : undefined,
23423
- },
23424
- };
23425
- styles.font["strike"] = !!style?.strikethrough || undefined;
23426
- styles.font["underline"] = !!style?.underline || undefined;
23427
- styles.font["bold"] = !!style?.bold || undefined;
23428
- styles.font["italic"] = !!style?.italic || undefined;
23429
- return styles;
23430
- }
23431
- function normalizeStyle(construct, styles) {
23432
- // Normalize this
23433
- const numFmtId = convertFormat(styles["numFmt"], construct.numFmts);
23434
- const style = {
23435
- fontId: pushElement(styles.font, construct.fonts),
23436
- fillId: pushElement(styles.fill, construct.fills),
23437
- borderId: styles.border,
23438
- numFmtId,
23439
- alignment: {
23440
- vertical: styles.alignment.vertical,
23441
- horizontal: styles.alignment.horizontal,
23442
- wrapText: styles.alignment.wrapText,
23443
- },
23444
- };
23445
- return pushElement(style, construct.styles);
23446
- }
23447
- function convertFormat(format, numFmtStructure) {
23448
- if (!format) {
23449
- return 0;
23450
- }
23451
- let formatId = XLSX_FORMAT_MAP[format.format];
23452
- if (!formatId) {
23453
- formatId = pushElement(format, numFmtStructure) + FIRST_NUMFMT_ID;
23454
- }
23455
- return formatId;
23456
- }
23457
- /**
23458
- * Add a relation to the given file and return its id.
23459
- */
23460
- function addRelsToFile(relsFiles, path, rel) {
23461
- const relsFile = relsFiles.find((file) => file.path === path);
23462
- // the id is a one-based int casted as string
23463
- let id;
23464
- if (!relsFile) {
23465
- id = "rId1";
23466
- relsFiles.push({ path, rels: [{ ...rel, id }] });
23467
- }
23468
- else {
23469
- id = `rId${(relsFile.rels.length + 1).toString()}`;
23470
- relsFile.rels.push({
23471
- ...rel,
23472
- id,
23473
- });
23474
- }
23475
- return id;
23476
- }
23477
- const globalReverseLookup = new WeakMap();
23478
- function pushElement(property, propertyList) {
23479
- let reverseLookup = globalReverseLookup.get(propertyList);
23480
- if (!reverseLookup) {
23481
- reverseLookup = new Map();
23482
- for (let i = 0; i < propertyList.length; i++) {
23483
- const canonical = getCanonicalRepresentation(propertyList[i]);
23484
- reverseLookup.set(canonical, i);
23485
- }
23486
- globalReverseLookup.set(propertyList, reverseLookup);
23487
- }
23488
- const canonical = getCanonicalRepresentation(property);
23489
- if (reverseLookup.has(canonical)) {
23490
- return reverseLookup.get(canonical);
23491
- }
23492
- const maxId = propertyList.length;
23493
- propertyList.push(property);
23494
- reverseLookup.set(canonical, maxId);
23495
- return maxId;
23496
- }
23497
- /**
23498
- * Convert a chart o-spreadsheet id to a xlsx id which
23499
- * are unsigned integers (starting from 1).
23500
- */
23501
- function convertChartId(chartId, construct) {
23502
- const xlsxId = construct.chartIds.findIndex((id) => id === chartId);
23503
- if (xlsxId === -1) {
23504
- construct.chartIds.push(chartId);
23505
- return construct.chartIds.length;
23506
- }
23507
- return xlsxId + 1;
23508
- }
23509
- const imageIds = [];
23510
- /**
23511
- * Convert a image o-spreadsheet id to a xlsx id which
23512
- * are unsigned integers (starting from 1).
23513
- */
23514
- function convertImageId(imageId) {
23515
- const xlsxId = imageIds.findIndex((id) => id === imageId);
23516
- if (xlsxId === -1) {
23517
- imageIds.push(imageId);
23518
- return imageIds.length;
23519
- }
23520
- return xlsxId + 1;
23521
- }
23522
- /**
23523
- * Convert a value expressed in dot to EMU.
23524
- * EMU = English Metrical Unit
23525
- * There are 914400 EMU per inch.
23526
- *
23527
- * /!\ A value expressed in EMU cannot be fractional.
23528
- * See https://docs.microsoft.com/en-us/windows/win32/vml/msdn-online-vml-units#other-units-of-measurement
23529
- */
23530
- function convertDotValueToEMU(value) {
23531
- const DPI = 96;
23532
- return Math.round((value * 914400) / DPI);
23533
- }
23534
- function getRangeSize(reference, defaultSheetIndex, data) {
23535
- let xc = reference;
23536
- let sheetName = undefined;
23537
- ({ xc, sheetName } = splitReference(reference));
23538
- let rangeSheetIndex;
23539
- if (sheetName) {
23540
- const index = data.sheets.findIndex((sheet) => isSheetNameEqual(sheet.name, sheetName));
23541
- if (index < 0) {
23542
- throw new Error("Unable to find a sheet with the name " + sheetName);
23543
- }
23544
- rangeSheetIndex = index;
23545
- }
23546
- else {
23547
- rangeSheetIndex = Number(defaultSheetIndex);
23548
- }
23549
- const zone = toUnboundedZone(xc);
23550
- if (zone.right === undefined) {
23551
- zone.right = data.sheets[rangeSheetIndex].colNumber;
23552
- }
23553
- if (zone.bottom === undefined) {
23554
- zone.bottom = data.sheets[rangeSheetIndex].rowNumber;
23555
- }
23556
- return (zone.right - zone.left + 1) * (zone.bottom - zone.top + 1);
23557
- }
23558
- function convertEMUToDotValue(value) {
23559
- const DPI = 96;
23560
- return Math.round((value * DPI) / 914400);
23561
- }
23562
- /**
23563
- * Get the position of the start of a column in Excel (in px).
23564
- */
23565
- function getColPosition(colIndex, sheetData) {
23566
- let position = 0;
23567
- for (let i = 0; i < colIndex; i++) {
23568
- const colAtIndex = sheetData.cols.find((col) => i >= col.min && i <= col.max);
23569
- if (colAtIndex?.width) {
23570
- position += colAtIndex.width;
23571
- }
23572
- else if (sheetData.sheetFormat?.defaultColWidth) {
23573
- position += sheetData.sheetFormat.defaultColWidth;
23574
- }
23575
- else {
23576
- position += EXCEL_DEFAULT_COL_WIDTH;
23577
- }
23578
- }
23579
- return position / WIDTH_FACTOR;
23580
- }
23581
- /**
23582
- * Get the position of the start of a row in Excel (in px).
23583
- */
23584
- function getRowPosition(rowIndex, sheetData) {
23585
- let position = 0;
23586
- for (let i = 0; i < rowIndex; i++) {
23587
- const rowAtIndex = sheetData.rows.find((row) => row.index - 1 === i);
23588
- if (rowAtIndex?.height) {
23589
- position += rowAtIndex.height;
23590
- }
23591
- else if (sheetData.sheetFormat?.defaultRowHeight) {
23592
- position += sheetData.sheetFormat.defaultRowHeight;
23593
- }
23594
- else {
23595
- position += EXCEL_DEFAULT_ROW_HEIGHT;
23596
- }
23597
- }
23598
- return position / HEIGHT_FACTOR;
23599
- }
23600
- /**
23601
- * Convert the o-spreadsheet data validation decimal
23602
- * criterion type to the corresponding excel operator.
23603
- */
23604
- function convertDecimalCriterionTypeToExcelOperator(operator) {
23605
- return Object.keys(XLSX_DV_DECIMAL_OPERATOR_MAPPING).find((key) => XLSX_DV_DECIMAL_OPERATOR_MAPPING[key] === operator);
23606
- }
23607
- /**
23608
- * Convert the o-spreadsheet data validation date
23609
- * criterion type to the corresponding excel operator.
23610
- */
23611
- function convertDateCriterionTypeToExcelOperator(operator) {
23612
- return Object.keys(XLSX_DV_DATE_OPERATOR_TO_DV_TYPE_MAPPING).find((key) => XLSX_DV_DATE_OPERATOR_TO_DV_TYPE_MAPPING[key] === operator);
23613
- }
23614
-
23615
23666
  function convertFigures(sheetData) {
23616
23667
  let id = 1;
23617
23668
  return sheetData.figures
@@ -23701,6 +23752,7 @@ function convertChartData(chartData) {
23701
23752
  horizontal: chartData.horizontal,
23702
23753
  isDoughnut: chartData.isDoughnut,
23703
23754
  pieHolePercentage: chartData.pieHolePercentage,
23755
+ showValues: chartData.showValues,
23704
23756
  };
23705
23757
  try {
23706
23758
  const ChartClass = chartRegistry.get(chartData.type);
@@ -25429,6 +25481,8 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
25429
25481
  const chartHoleSize = this.extractChildAttr(rootChartElement, "c:holeSize", "val", {
25430
25482
  default: "0",
25431
25483
  }).asNum();
25484
+ const showValueNodes = this.querySelectorAll(rootChartElement, "c:chart c:showVal");
25485
+ const showValues = [...showValueNodes].some((el) => el.attributes.getNamedItem("val")?.value === "1");
25432
25486
  return {
25433
25487
  title: { text: chartTitle },
25434
25488
  type: CHART_TYPE_CONVERSION_MAP[chartType],
@@ -25445,6 +25499,7 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
25445
25499
  horizontal: chartDirection === "bar",
25446
25500
  isDoughnut: chartHoleSize > 0,
25447
25501
  pieHolePercentage: chartHoleSize,
25502
+ showValues,
25448
25503
  };
25449
25504
  })[0];
25450
25505
  }
@@ -25463,6 +25518,8 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
25463
25518
  const barChartGrouping = this.extractChildAttr(chartElement, "c:grouping", "val", {
25464
25519
  default: "clustered",
25465
25520
  }).asString();
25521
+ const showValueNodes = this.querySelectorAll(chartElement, "c:chart c:showVal");
25522
+ const showValues = [...showValueNodes].some((el) => el.attributes.getNamedItem("val")?.value === "1");
25466
25523
  return {
25467
25524
  title: { text: chartTitle },
25468
25525
  type: "combo",
@@ -25479,6 +25536,7 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
25479
25536
  }).asString()],
25480
25537
  stacked: barChartGrouping === "stacked",
25481
25538
  fontColor: "000000",
25539
+ showValues,
25482
25540
  };
25483
25541
  }
25484
25542
  extractChartDatasets(chartElements, chartType) {
@@ -27714,7 +27772,7 @@ class CorePlugin extends BasePlugin {
27714
27772
  * @param sheetId an sheetId to adapt either range of that sheet specifically, or ranges pointing to that sheet
27715
27773
  * @param sheetName couple of old and new sheet names to adapt ranges pointing to that sheet
27716
27774
  */
27717
- adaptRanges(applyChange, sheetId, sheetName) { }
27775
+ adaptRanges(rangeAdapterFunctions, sheetId, sheetName) { }
27718
27776
  }
27719
27777
 
27720
27778
  class BordersPlugin extends CorePlugin {
@@ -27789,7 +27847,7 @@ class BordersPlugin extends CorePlugin {
27789
27847
  }
27790
27848
  }
27791
27849
  }
27792
- adaptRanges(applyChange, sheetId) {
27850
+ adaptRanges({ applyChange }, sheetId) {
27793
27851
  const newBorders = [];
27794
27852
  for (const border of this.borders[sheetId] ?? []) {
27795
27853
  const change = applyChange(this.getters.getRangeFromZone(sheetId, border.zone));
@@ -28276,7 +28334,7 @@ class CellPlugin extends CorePlugin {
28276
28334
  ];
28277
28335
  nextId = 1;
28278
28336
  cells = {};
28279
- adaptRanges(applyChange, sheetId, sheetName) {
28337
+ adaptRanges({ applyChange }, sheetId, sheetName) {
28280
28338
  for (const sheet of Object.keys(this.cells)) {
28281
28339
  for (const cell of Object.values(this.cells[sheet] || {})) {
28282
28340
  if (cell.isFormula) {
@@ -28479,8 +28537,8 @@ class CellPlugin extends CorePlugin {
28479
28537
  for (const _sheet of data.sheets) {
28480
28538
  const positionsByFormat = [];
28481
28539
  const cells = {};
28482
- const positions = Object.keys(this.cells[_sheet.id] || {})
28483
- .map((cellId) => this.getters.getCellPosition(cellId))
28540
+ const positions = Object.values(this.cells[_sheet.id] || {})
28541
+ .map((cell) => this.getters.getCellPosition(cell.id))
28484
28542
  .sort((a, b) => (a.col === b.col ? a.row - b.row : a.col - b.col));
28485
28543
  for (const position of positions) {
28486
28544
  const cell = this.getters.getCell(position);
@@ -28500,7 +28558,7 @@ class CellPlugin extends CorePlugin {
28500
28558
  data.formats = formats;
28501
28559
  }
28502
28560
  importCell(sheetId, content, format) {
28503
- const cellId = this.getNextUid();
28561
+ const cellId = this.getNextCellId();
28504
28562
  return this.createCell(cellId, content || "", format, sheetId);
28505
28563
  }
28506
28564
  exportForExcel(data) {
@@ -28527,7 +28585,7 @@ class CellPlugin extends CorePlugin {
28527
28585
  // GETTERS
28528
28586
  // ---------------------------------------------------------------------------
28529
28587
  getCells(sheetId) {
28530
- return this.cells[sheetId] || {};
28588
+ return Object.values(this.cells[sheetId] || {});
28531
28589
  }
28532
28590
  /**
28533
28591
  * get a cell by ID. Used in evaluation when evaluating an async cell, we need to be able to find it back after
@@ -28643,8 +28701,8 @@ class CellPlugin extends CorePlugin {
28643
28701
  }
28644
28702
  return format;
28645
28703
  }
28646
- getNextUid() {
28647
- const id = this.nextId.toString();
28704
+ getNextCellId() {
28705
+ const id = this.nextId;
28648
28706
  this.history.update("nextId", this.nextId + 1);
28649
28707
  return id;
28650
28708
  }
@@ -28675,7 +28733,7 @@ class CellPlugin extends CorePlugin {
28675
28733
  }
28676
28734
  return;
28677
28735
  }
28678
- const cellId = before?.id || this.getNextUid();
28736
+ const cellId = before?.id || this.getNextCellId();
28679
28737
  const cell = this.createCell(cellId, afterContent, format, sheetId);
28680
28738
  this.history.update("cells", sheetId, cell.id, cell);
28681
28739
  this.dispatch("UPDATE_CELL_POSITION", { cellId: cell.id, col, row, sheetId });
@@ -28839,12 +28897,12 @@ class ChartPlugin extends CorePlugin {
28839
28897
  charts = {};
28840
28898
  createChart = chartFactory(this.getters);
28841
28899
  validateChartDefinition = (cmd) => validateChartDefinition(this, cmd.definition);
28842
- adaptRanges(applyChange, sheetId, adaptSheetName) {
28900
+ adaptRanges(rangeAdapters) {
28843
28901
  for (const [chartId, chart] of Object.entries(this.charts)) {
28844
28902
  if (!chart) {
28845
28903
  continue;
28846
28904
  }
28847
- const newChart = chart.chart.updateRanges(applyChange, sheetId, adaptSheetName);
28905
+ const newChart = chart.chart.updateRanges(rangeAdapters);
28848
28906
  this.history.update("charts", chartId, newChart ? { figureId: chart.figureId, chart: newChart } : undefined);
28849
28907
  }
28850
28908
  }
@@ -29735,7 +29793,7 @@ class ConditionalFormatPlugin extends CorePlugin {
29735
29793
  "getAdaptedCfRanges",
29736
29794
  ];
29737
29795
  cfRules = {};
29738
- adaptCFFormulas(applyChange) {
29796
+ adaptCFFormulas({ applyChange, adaptFormulaString }) {
29739
29797
  for (const sheetId in this.cfRules) {
29740
29798
  for (const rule of this.cfRules[sheetId]) {
29741
29799
  if (rule.rule.type === "DataBarRule" && rule.rule.rangeValues) {
@@ -29759,7 +29817,7 @@ class ConditionalFormatPlugin extends CorePlugin {
29759
29817
  for (let i = 0; i < rule.rule.values.length; i++) {
29760
29818
  this.history.update("cfRules", sheetId, this.cfRules[sheetId].indexOf(rule), "rule",
29761
29819
  //@ts-expect-error
29762
- "values", i, this.getters.adaptFormulaStringDependencies(sheetId, rule.rule.values[i], applyChange));
29820
+ "values", i, adaptFormulaString(sheetId, rule.rule.values[i]));
29763
29821
  }
29764
29822
  }
29765
29823
  else if (rule.rule.type === "IconSetRule") {
@@ -29767,7 +29825,7 @@ class ConditionalFormatPlugin extends CorePlugin {
29767
29825
  if (rule.rule[inflectionPoint].type === "formula") {
29768
29826
  this.history.update("cfRules", sheetId, this.cfRules[sheetId].indexOf(rule), "rule",
29769
29827
  //@ts-expect-error
29770
- inflectionPoint, "value", this.getters.adaptFormulaStringDependencies(sheetId, rule.rule[inflectionPoint].value, applyChange));
29828
+ inflectionPoint, "value", adaptFormulaString(sheetId, rule.rule[inflectionPoint].value));
29771
29829
  }
29772
29830
  }
29773
29831
  }
@@ -29777,14 +29835,14 @@ class ConditionalFormatPlugin extends CorePlugin {
29777
29835
  if (ruleValue?.type === "formula" && ruleValue?.value) {
29778
29836
  this.history.update("cfRules", sheetId, this.cfRules[sheetId].indexOf(rule), "rule",
29779
29837
  //@ts-expect-error
29780
- value, "value", this.getters.adaptFormulaStringDependencies(sheetId, ruleValue.value, applyChange));
29838
+ value, "value", adaptFormulaString(sheetId, ruleValue.value));
29781
29839
  }
29782
29840
  }
29783
29841
  }
29784
29842
  }
29785
29843
  }
29786
29844
  }
29787
- adaptCFRanges(sheetId, applyChange) {
29845
+ adaptCFRanges(sheetId, { applyChange }) {
29788
29846
  for (const rule of this.cfRules[sheetId]) {
29789
29847
  for (const range of rule.ranges) {
29790
29848
  const change = applyChange(range);
@@ -29808,12 +29866,12 @@ class ConditionalFormatPlugin extends CorePlugin {
29808
29866
  }
29809
29867
  }
29810
29868
  }
29811
- adaptRanges(applyChange, sheetId) {
29869
+ adaptRanges(rangeAdapters, sheetId) {
29812
29870
  const sheetIds = sheetId ? [sheetId] : Object.keys(this.cfRules);
29813
29871
  for (const sheetId of sheetIds) {
29814
- this.adaptCFRanges(sheetId, applyChange);
29872
+ this.adaptCFRanges(sheetId, rangeAdapters);
29815
29873
  }
29816
- this.adaptCFFormulas(applyChange);
29874
+ this.adaptCFFormulas(rangeAdapters);
29817
29875
  }
29818
29876
  // ---------------------------------------------------------------------------
29819
29877
  // Command Handling
@@ -30194,23 +30252,23 @@ class DataValidationPlugin extends CorePlugin {
30194
30252
  "getValidationRuleForCell",
30195
30253
  ];
30196
30254
  rules = {};
30197
- adaptRanges(applyChange, sheetId) {
30198
- this.adaptDVRanges(sheetId, applyChange);
30199
- this.adaptDVFormulas(applyChange);
30255
+ adaptRanges(rangeAdapters, sheetId) {
30256
+ this.adaptDVRanges(sheetId, rangeAdapters);
30257
+ this.adaptDVFormulas(rangeAdapters);
30200
30258
  }
30201
- adaptDVFormulas(applyChange) {
30259
+ adaptDVFormulas({ adaptFormulaString }) {
30202
30260
  for (const sheetId in this.rules) {
30203
30261
  const rules = this.rules[sheetId];
30204
30262
  for (let ruleIndex = rules.length - 1; ruleIndex >= 0; ruleIndex--) {
30205
30263
  const rule = this.rules[sheetId][ruleIndex];
30206
30264
  for (let valueIndex = 0; valueIndex < rule.criterion.values.length; valueIndex++) {
30207
- const value = this.getters.adaptFormulaStringDependencies(sheetId, rule.criterion.values[valueIndex], applyChange);
30265
+ const value = adaptFormulaString(sheetId, rule.criterion.values[valueIndex]);
30208
30266
  this.history.update("rules", sheetId, ruleIndex, "criterion", "values", valueIndex, value);
30209
30267
  }
30210
30268
  }
30211
30269
  }
30212
30270
  }
30213
- adaptDVRanges(sheetId, applyChange) {
30271
+ adaptDVRanges(sheetId, { applyChange }) {
30214
30272
  const rules = this.rules[sheetId];
30215
30273
  for (let ruleIndex = rules.length - 1; ruleIndex >= 0; ruleIndex--) {
30216
30274
  const rule = this.rules[sheetId][ruleIndex];
@@ -30485,7 +30543,7 @@ class FigurePlugin extends CorePlugin {
30485
30543
  // ---------------------------------------------------------------------------
30486
30544
  // Command Handling
30487
30545
  // ---------------------------------------------------------------------------
30488
- adaptRanges(applyChange, sheetId) {
30546
+ adaptRanges({ applyChange }, sheetId) {
30489
30547
  for (const figure of this.getFigures(sheetId)) {
30490
30548
  const change = applyChange(this.getters.getRangeFromZone(sheetId, {
30491
30549
  left: figure.col,
@@ -31725,8 +31783,8 @@ class MergePlugin extends CorePlugin {
31725
31783
  break;
31726
31784
  }
31727
31785
  }
31728
- adaptRanges(applyChange, sheetId) {
31729
- this.applyRangeChangeOnSheet(sheetId, applyChange);
31786
+ adaptRanges(rangeAdapters, sheetId) {
31787
+ this.applyRangeChangeOnSheet(sheetId, rangeAdapters);
31730
31788
  }
31731
31789
  // ---------------------------------------------------------------------------
31732
31790
  // Getters
@@ -32009,7 +32067,7 @@ class MergePlugin extends CorePlugin {
32009
32067
  /**
32010
32068
  * Apply a range change on merges of a particular sheet.
32011
32069
  */
32012
- applyRangeChangeOnSheet(sheetId, applyChange) {
32070
+ applyRangeChangeOnSheet(sheetId, { applyChange }) {
32013
32071
  const merges = Object.entries(this.merges[sheetId] || {});
32014
32072
  for (const [mergeId, range] of merges) {
32015
32073
  if (range) {
@@ -33647,8 +33705,6 @@ function adaptPivotRange(range, applyChange) {
33647
33705
  }
33648
33706
  const change = applyChange(range);
33649
33707
  switch (change.changeType) {
33650
- case "NONE":
33651
- return range;
33652
33708
  case "REMOVE":
33653
33709
  return undefined;
33654
33710
  default:
@@ -33757,7 +33813,7 @@ class PivotCorePlugin extends CorePlugin {
33757
33813
  }
33758
33814
  }
33759
33815
  }
33760
- adaptRanges(applyChange) {
33816
+ adaptRanges({ applyChange, adaptFormulaString }) {
33761
33817
  for (const pivotId in this.pivots) {
33762
33818
  const definition = deepCopy(this.pivots[pivotId]?.definition);
33763
33819
  if (!definition) {
@@ -33777,19 +33833,13 @@ class PivotCorePlugin extends CorePlugin {
33777
33833
  continue;
33778
33834
  }
33779
33835
  const sheetId = measure.computedBy.sheetId;
33780
- const compiledFormula = this.compiledMeasureFormulas[pivotId][measureId].formula;
33781
- const newDependencies = [];
33782
- for (const range of compiledFormula.dependencies) {
33783
- const change = applyChange(range);
33784
- if (change.changeType === "NONE") {
33785
- newDependencies.push(range);
33786
- }
33787
- else {
33788
- newDependencies.push(change.range);
33789
- }
33790
- }
33791
- const newFormulaString = this.getters.getFormulaString(sheetId, compiledFormula.tokens, newDependencies);
33836
+ const { formula: compiledFormula, dependencies: indirectDependencies } = this.compiledMeasureFormulas[pivotId][measureId];
33837
+ // adapt direct dependencies
33838
+ this.history.update("compiledMeasureFormulas", pivotId, measureId, "formula", "dependencies", compiledFormula.dependencies.map((range) => applyChange(range).range));
33839
+ // adapt all dependencies (including indirect)
33840
+ this.history.update("compiledMeasureFormulas", pivotId, measure.id, "dependencies", indirectDependencies.map((range) => applyChange(range).range));
33792
33841
  const oldFormulaString = measure.computedBy.formula;
33842
+ const newFormulaString = adaptFormulaString(sheetId, oldFormulaString);
33793
33843
  if (newFormulaString !== oldFormulaString) {
33794
33844
  this.replaceMeasureFormula(pivotId, measure, newFormulaString);
33795
33845
  }
@@ -33951,7 +34001,6 @@ class PivotCorePlugin extends CorePlugin {
33951
34001
  formula: newFormulaString,
33952
34002
  sheetId: measure.computedBy.sheetId,
33953
34003
  });
33954
- this.compileCalculatedMeasures(pivotId, pivot.definition.measures);
33955
34004
  }
33956
34005
  checkSortedColumnInMeasures(definition) {
33957
34006
  const measures = definition.measures.map((measure) => measure.id);
@@ -34044,7 +34093,7 @@ class SettingsPlugin extends CorePlugin {
34044
34093
  }
34045
34094
  changeCellsDateFormatWithLocale(oldLocale, newLocale) {
34046
34095
  for (const sheetId of this.getters.getSheetIds()) {
34047
- for (const [cellId, cell] of Object.entries(this.getters.getCells(sheetId))) {
34096
+ for (const cell of this.getters.getCells(sheetId)) {
34048
34097
  let formatToApply;
34049
34098
  if (cell.format === oldLocale.dateFormat) {
34050
34099
  formatToApply = newLocale.dateFormat;
@@ -34056,7 +34105,7 @@ class SettingsPlugin extends CorePlugin {
34056
34105
  formatToApply = getDateTimeFormat(newLocale);
34057
34106
  }
34058
34107
  if (formatToApply) {
34059
- const { col, row, sheetId } = this.getters.getCellPosition(cellId);
34108
+ const { col, row, sheetId } = this.getters.getCellPosition(cell.id);
34060
34109
  this.dispatch("UPDATE_CELL", {
34061
34110
  col,
34062
34111
  row,
@@ -34090,7 +34139,7 @@ class SheetPlugin extends CorePlugin {
34090
34139
  "getCell",
34091
34140
  "getCellPosition",
34092
34141
  "getColsZone",
34093
- "getRowCells",
34142
+ "getRowCellIds",
34094
34143
  "getRowsZone",
34095
34144
  "getNumberCols",
34096
34145
  "getNumberRows",
@@ -34390,7 +34439,7 @@ class SheetPlugin extends CorePlugin {
34390
34439
  right: end,
34391
34440
  };
34392
34441
  }
34393
- getRowCells(sheetId, row) {
34442
+ getRowCellIds(sheetId, row) {
34394
34443
  return Object.values(this.getSheet(sheetId).rows[row]?.cells).filter(isDefined);
34395
34444
  }
34396
34445
  getRowsZone(sheetId, start, end) {
@@ -34687,7 +34736,7 @@ class SheetPlugin extends CorePlugin {
34687
34736
  orderedSheetIds.splice(currentIndex + 1, 0, newSheet.id);
34688
34737
  this.history.update("orderedSheetIds", orderedSheetIds);
34689
34738
  this.history.update("sheets", Object.assign({}, this.sheets, { [newSheet.id]: newSheet }));
34690
- for (const cell of Object.values(this.getters.getCells(fromId))) {
34739
+ for (const cell of this.getters.getCells(fromId)) {
34691
34740
  const { sheetId, col, row } = this.getCellPosition(cell.id);
34692
34741
  const style = this.getters.getCellStyle({ sheetId, col, row });
34693
34742
  this.dispatch("UPDATE_CELL", {
@@ -35046,7 +35095,7 @@ class StylePlugin extends CorePlugin {
35046
35095
  break;
35047
35096
  }
35048
35097
  }
35049
- adaptRanges(applyChange, sheetId) {
35098
+ adaptRanges({ applyChange }, sheetId) {
35050
35099
  const newStyles = [];
35051
35100
  for (const style of this.styles[sheetId] ?? []) {
35052
35101
  const change = applyChange(this.getters.getRangeFromZone(sheetId, style.zone));
@@ -36045,7 +36094,7 @@ class TablePlugin extends CorePlugin {
36045
36094
  static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
36046
36095
  tables = {};
36047
36096
  nextTableId = 1;
36048
- adaptRanges(applyChange, sheetId) {
36097
+ adaptRanges({ applyChange }, sheetId) {
36049
36098
  for (const table of this.getCoreTables(sheetId)) {
36050
36099
  this.applyRangeChangeOnTable(sheetId, table, applyChange);
36051
36100
  }
@@ -37911,11 +37960,16 @@ class SpreadingRelation {
37911
37960
  return this.arrayFormulasToResults.get(formulasPosition);
37912
37961
  }
37913
37962
  /**
37914
- * Remove a node, also remove it from other nodes adjacency list
37963
+ * Remove a spreading relation for a given array formula position
37964
+ * and its result zone
37915
37965
  */
37916
37966
  removeNode(position) {
37967
+ const resultZone = this.arrayFormulasToResults.get(position);
37968
+ if (!resultZone) {
37969
+ return;
37970
+ }
37917
37971
  this.resultsToArrayFormulas.remove({
37918
- boundingBox: { sheetId: position.sheetId, zone: positionToZone(position) },
37972
+ boundingBox: { sheetId: position.sheetId, zone: resultZone },
37919
37973
  data: position,
37920
37974
  });
37921
37975
  this.arrayFormulasToResults.delete(position);
@@ -38069,9 +38123,7 @@ class Evaluator {
38069
38123
  this.formulaDependencies = lazy(() => {
38070
38124
  const rTreeItems = [];
38071
38125
  for (const sheetId of this.getters.getSheetIds()) {
38072
- const cells = this.getters.getCells(sheetId);
38073
- for (const cellId in cells) {
38074
- const cell = cells[cellId];
38126
+ for (const cell of this.getters.getCells(sheetId)) {
38075
38127
  if (cell.isFormula) {
38076
38128
  const directDependencies = cell.compiledFormula.dependencies;
38077
38129
  for (const range of directDependencies) {
@@ -38081,7 +38133,7 @@ class Evaluator {
38081
38133
  rTreeItems.push({
38082
38134
  data: {
38083
38135
  sheetId,
38084
- zone: positionToZone(this.getters.getCellPosition(cellId)),
38136
+ zone: positionToZone(this.getters.getCellPosition(cell.id)),
38085
38137
  },
38086
38138
  boundingBox: { sheetId: range.sheetId, zone: range.zone },
38087
38139
  });
@@ -38242,6 +38294,10 @@ class Evaluator {
38242
38294
  // empty matrix
38243
38295
  return createEvaluatedCell({ value: 0 }, this.getters.getLocale(), cellData);
38244
38296
  }
38297
+ if (nbRows === 1 && nbColumns === 1) {
38298
+ // single value matrix
38299
+ return createEvaluatedCell(validateNumberValue(formulaReturn[0][0]), this.getters.getLocale(), cellData);
38300
+ }
38245
38301
  const resultZone = {
38246
38302
  top: formulaPosition.row,
38247
38303
  bottom: formulaPosition.row + nbRows - 1,
@@ -38760,11 +38816,20 @@ function getCanvas(width = 100, height = 100) {
38760
38816
  /**
38761
38817
  * Get the default height of the cell given its style.
38762
38818
  */
38763
- function getDefaultCellHeight(ctx, cell, style, colSize) {
38819
+ function getDefaultCellHeight(ctx, cell, style, locale, colSize) {
38764
38820
  if (!cell || (!cell.isFormula && !cell.content)) {
38765
38821
  return DEFAULT_CELL_HEIGHT;
38766
38822
  }
38767
- const content = cell.isFormula ? "" : cell.content;
38823
+ let content = "";
38824
+ try {
38825
+ if (!cell.isFormula) {
38826
+ const localeFormat = { format: cell.format, locale };
38827
+ content = formatValue(parseLiteral(cell.content, locale), localeFormat);
38828
+ }
38829
+ }
38830
+ catch {
38831
+ content = CellErrorType.GenericError;
38832
+ }
38768
38833
  return getCellContentHeight(ctx, content, style, colSize);
38769
38834
  }
38770
38835
  function getCellContentHeight(ctx, content, style, colSize) {
@@ -40386,15 +40451,15 @@ async function chartToImageUrl(runtime, figure, type) {
40386
40451
  if (!extensionsLoaded) {
40387
40452
  registerChartJSExtensions();
40388
40453
  }
40389
- if (!globalThis.Chart.registry.controllers.get(type)) {
40390
- console.log(`Chart of type "${type}" is not registered in Chart.js library.`);
40454
+ const config = deepCopy(runtime.chartJsConfig);
40455
+ config.plugins = [backgroundColorChartJSPlugin];
40456
+ if (!globalThis.Chart.registry.controllers.get(config.type)) {
40457
+ console.log(`Chart of type "${config.type}" is not registered in Chart.js library.`);
40391
40458
  if (!extensionsLoaded) {
40392
40459
  unregisterChartJsExtensions();
40393
40460
  }
40394
40461
  return imageUrl;
40395
40462
  }
40396
- const config = deepCopy(runtime.chartJsConfig);
40397
- config.plugins = [backgroundColorChartJSPlugin];
40398
40463
  const chart = new globalThis.Chart(canvas, config);
40399
40464
  try {
40400
40465
  imageUrl = await canvasToObjectUrl(canvas);
@@ -41070,12 +41135,10 @@ class FormulaTrackerPlugin extends CoreViewPlugin {
41070
41135
  this.trackedCells[formula] = {};
41071
41136
  }
41072
41137
  for (const sheetId of this.getters.getSheetIds()) {
41073
- const cells = this.getters.getCells(sheetId);
41074
- for (const cellId in cells) {
41075
- const cell = cells[cellId];
41138
+ for (const cell of this.getters.getCells(sheetId)) {
41076
41139
  for (const formula of trackedFormulas) {
41077
41140
  if (doesCellContainFunction(cell, formula)) {
41078
- this.history.update("trackedCells", formula, cell.id, true);
41141
+ this.history.update("trackedCells", formula, cell.id, cell.id);
41079
41142
  }
41080
41143
  }
41081
41144
  }
@@ -41094,7 +41157,7 @@ class FormulaTrackerPlugin extends CoreViewPlugin {
41094
41157
  }
41095
41158
  for (const formula of trackedFormulas) {
41096
41159
  if (doesCellContainFunction(cell, formula)) {
41097
- this.history.update("trackedCells", formula, cell.id, true);
41160
+ this.history.update("trackedCells", formula, cell.id, cell.id);
41098
41161
  }
41099
41162
  else if (this.trackedCells[formula][cell.id]) {
41100
41163
  this.history.update("trackedCells", formula, cell.id, undefined);
@@ -41105,7 +41168,9 @@ class FormulaTrackerPlugin extends CoreViewPlugin {
41105
41168
  }
41106
41169
  }
41107
41170
  getCellsWithTrackedFormula(formula) {
41108
- return Object.keys(this.trackedCells[formula] || {}).filter((cellId) => this.trackedCells[formula][cellId] && this.getters.tryGetCellPosition(cellId));
41171
+ return Object.values(this.trackedCells[formula] || {}).filter((cellId) => cellId !== undefined &&
41172
+ this.trackedCells[formula][cellId] &&
41173
+ this.getters.tryGetCellPosition(cellId));
41109
41174
  }
41110
41175
  }
41111
41176
 
@@ -41133,6 +41198,7 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
41133
41198
  handle(cmd) {
41134
41199
  switch (cmd.type) {
41135
41200
  case "START":
41201
+ case "UPDATE_LOCALE":
41136
41202
  for (const sheetId of this.getters.getSheetIds()) {
41137
41203
  this.initializeSheet(sheetId);
41138
41204
  }
@@ -41270,7 +41336,7 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
41270
41336
  const cell = this.getters.getCell(position);
41271
41337
  const style = this.getters.getCellStyle(position);
41272
41338
  const colSize = this.getters.getColSize(position.sheetId, position.col);
41273
- return getDefaultCellHeight(this.ctx, cell, style, colSize);
41339
+ return getDefaultCellHeight(this.ctx, cell, style, this.getters.getLocale(), colSize);
41274
41340
  }
41275
41341
  isInMultiRowMerge(position) {
41276
41342
  const merge = this.getters.getMerge(position);
@@ -41284,7 +41350,7 @@ class HeaderSizeUIPlugin extends CoreViewPlugin {
41284
41350
  if (userRowSize !== undefined) {
41285
41351
  return undefined;
41286
41352
  }
41287
- const cellIds = this.getters.getRowCells(sheetId, row);
41353
+ const cellIds = this.getters.getRowCellIds(sheetId, row);
41288
41354
  let maxHeight = 0;
41289
41355
  let tallestCell = undefined;
41290
41356
  for (let i = 0; i < cellIds.length; i++) {
@@ -42218,8 +42284,8 @@ class PivotUIPlugin extends CoreViewPlugin {
42218
42284
  }
42219
42285
  const unusedPivots = new Set(this.getters.getPivotIds());
42220
42286
  for (const sheetId of this.getters.getSheetIds()) {
42221
- for (const cellId in this.getters.getCells(sheetId)) {
42222
- const position = this.getters.getCellPosition(cellId);
42287
+ for (const cell of this.getters.getCells(sheetId)) {
42288
+ const position = this.getters.getCellPosition(cell.id);
42223
42289
  const pivotId = this.getPivotIdFromPosition(position);
42224
42290
  if (pivotId) {
42225
42291
  unusedPivots.delete(pivotId);
@@ -48731,7 +48797,7 @@ const coreViewsPluginRegistry = new Registry$1()
48731
48797
  .add("cell_icon", CellIconPlugin)
48732
48798
  .add("formula_tracker", FormulaTrackerPlugin);
48733
48799
 
48734
- class RangeAdapter {
48800
+ class RangeAdapterPlugin {
48735
48801
  getters;
48736
48802
  providers = [];
48737
48803
  isAdaptingRanges = false;
@@ -48739,7 +48805,6 @@ class RangeAdapter {
48739
48805
  this.getters = getters;
48740
48806
  }
48741
48807
  static getters = [
48742
- "adaptFormulaStringDependencies",
48743
48808
  "copyFormulaStringForSheet",
48744
48809
  "extendRange",
48745
48810
  "getRangeString",
@@ -48770,8 +48835,8 @@ class RangeAdapter {
48770
48835
  throw new Error("Plugins cannot dispatch commands during adaptRanges phase");
48771
48836
  }
48772
48837
  const rangeAdapter = getRangeAdapter(cmd);
48773
- if (rangeAdapter?.applyChange) {
48774
- this.executeOnAllRanges(rangeAdapter.applyChange, rangeAdapter.sheetId, rangeAdapter.sheetName);
48838
+ if (rangeAdapter) {
48839
+ this.executeOnAllRanges(rangeAdapter);
48775
48840
  }
48776
48841
  }
48777
48842
  finalize() { }
@@ -48790,11 +48855,15 @@ class RangeAdapter {
48790
48855
  return result;
48791
48856
  };
48792
48857
  }
48793
- executeOnAllRanges(adaptRange, sheetId, sheetName) {
48858
+ executeOnAllRanges(rangeAdapter) {
48794
48859
  this.isAdaptingRanges = true;
48795
- const func = this.verifyRangeRemoved(adaptRange);
48860
+ const adapterFunctions = {
48861
+ applyChange: this.verifyRangeRemoved(rangeAdapter.applyChange),
48862
+ adaptRangeString: (defaultSheetId, sheetXC) => adaptStringRange(defaultSheetId, sheetXC, rangeAdapter),
48863
+ adaptFormulaString: (defaultSheetId, formula) => adaptFormulaStringRanges(defaultSheetId, formula, rangeAdapter),
48864
+ };
48796
48865
  for (const provider of this.providers) {
48797
- provider(func, sheetId, sheetName);
48866
+ provider(adapterFunctions, rangeAdapter.sheetId, rangeAdapter.sheetName);
48798
48867
  }
48799
48868
  this.isAdaptingRanges = false;
48800
48869
  }
@@ -48962,18 +49031,6 @@ class RangeAdapter {
48962
49031
  const unionOfZones = unionUnboundedZones(...zones);
48963
49032
  return this.getRangeFromZone(ranges[0].sheetId, unionOfZones);
48964
49033
  }
48965
- adaptFormulaStringDependencies(sheetId, formula, applyChange) {
48966
- if (!formula.startsWith("=")) {
48967
- return formula;
48968
- }
48969
- const compiledFormula = compile(formula);
48970
- const updatedDependencies = compiledFormula.dependencies.map((dep) => {
48971
- const range = this.getters.getRangeFromSheetXC(sheetId, dep);
48972
- const changedRange = applyChange(range);
48973
- return changedRange.changeType === "NONE" ? range : changedRange.range;
48974
- });
48975
- return this.getters.getFormulaString(sheetId, compiledFormula.tokens, updatedDependencies);
48976
- }
48977
49034
  /**
48978
49035
  * Copy a formula string to another sheet.
48979
49036
  *
@@ -49957,6 +50014,7 @@ function addBarChart(chart) {
49957
50014
  <c:order val="${dsIndex}"/>
49958
50015
  ${extractTrendline(dataset.trend, color)}
49959
50016
  ${extractDataSetLabel(dataset.label)}
50017
+ ${insertDataLabels({ showValues: chart.showValues })}
49960
50018
  ${dataShapeProperty}
49961
50019
  ${chart.labelRange ? escapeXml /*xml*/ `<c:cat>${stringRef(chart.labelRange)}</c:cat>` : ""} <!-- x-coordinate values -->
49962
50020
  <c:val> <!-- x-coordinate values -->
@@ -49984,6 +50042,7 @@ function addBarChart(chart) {
49984
50042
  <!-- each data marker in the series does not have a different color -->
49985
50043
  <c:varyColors val="0"/>
49986
50044
  ${joinXmlNodes(leftDataSetsNodes)}
50045
+ ${insertDataLabels({ showValues: chart.showValues })}
49987
50046
  <c:axId val="${catAxId}" />
49988
50047
  <c:axId val="${valAxId}" />
49989
50048
  </c:barChart>
@@ -50032,6 +50091,7 @@ function addComboChart(chart) {
50032
50091
  <c:order val="0"/>
50033
50092
  ${extractTrendline(dataSet.trend, firstColor)}
50034
50093
  ${extractDataSetLabel(dataSet.label)}
50094
+ ${insertDataLabels({ showValues: chart.showValues })}
50035
50095
  ${shapeProperty({
50036
50096
  backgroundColor: firstColor,
50037
50097
  line: { color: firstColor },
@@ -50064,6 +50124,7 @@ function addComboChart(chart) {
50064
50124
  </c:marker>
50065
50125
  ${extractTrendline(dataSet.trend, color)}
50066
50126
  ${extractDataSetLabel(dataSet.label)}
50127
+ ${insertDataLabels({ showValues: chart.showValues })}
50067
50128
  ${dataShapeProperty}
50068
50129
  ${chart.labelRange ? escapeXml `<c:cat>${stringRef(chart.labelRange)}</c:cat>` : ""}
50069
50130
  <!-- x-coordinate values -->
@@ -50089,6 +50150,7 @@ function addComboChart(chart) {
50089
50150
  <!-- each data marker in the series does not have a different color -->
50090
50151
  <c:varyColors val="0"/>
50091
50152
  ${barDataSetNode}
50153
+ ${insertDataLabels({ showValues: chart.showValues })}
50092
50154
  <c:axId val="${useRightAxisForBarSerie ? secondaryCatAxId : catAxId}" />
50093
50155
  <c:axId val="${useRightAxisForBarSerie ? secondaryValAxId : valAxId}" />
50094
50156
  </c:barChart>
@@ -50098,6 +50160,7 @@ function addComboChart(chart) {
50098
50160
  <c:grouping val="standard"/>
50099
50161
  <!-- each data marker in the series does not have a different color -->
50100
50162
  <c:varyColors val="0"/>
50163
+ ${insertDataLabels({ showValues: chart.showValues })}
50101
50164
  ${joinXmlNodes(leftDataSetsNodes)}
50102
50165
  <c:axId val="${catAxId}" />
50103
50166
  <c:axId val="${valAxId}" />
@@ -50110,6 +50173,7 @@ function addComboChart(chart) {
50110
50173
  <c:grouping val="standard"/>
50111
50174
  <!-- each data marker in the series does not have a different color -->
50112
50175
  <c:varyColors val="0"/>
50176
+ ${insertDataLabels({ showValues: chart.showValues })}
50113
50177
  ${joinXmlNodes(rightDataSetsNodes)}
50114
50178
  <c:axId val="${secondaryCatAxId}" />
50115
50179
  <c:axId val="${secondaryValAxId}" />
@@ -50148,6 +50212,7 @@ function addPyramidChart(chart) {
50148
50212
  <c:order val="0"/>
50149
50213
  <c:invertIfNegative val="0" />
50150
50214
  ${extractDataSetLabel(leftDataSet.label)}
50215
+ ${insertDataLabels({ showValues: chart.showValues })}
50151
50216
  ${shapeProperty({
50152
50217
  backgroundColor: firstColor,
50153
50218
  line: { color: firstColor },
@@ -50165,6 +50230,7 @@ function addPyramidChart(chart) {
50165
50230
  <c:order val="1"/>
50166
50231
  <c:invertIfNegative val="0" />
50167
50232
  ${extractDataSetLabel(rightDataSet.label)}
50233
+ ${insertDataLabels({ showValues: chart.showValues })}
50168
50234
  ${shapeProperty({
50169
50235
  backgroundColor: secondColor,
50170
50236
  line: { color: secondColor },
@@ -50182,6 +50248,7 @@ function addPyramidChart(chart) {
50182
50248
  <c:grouping val="clustered"/>
50183
50249
  <c:varyColors val="0" />
50184
50250
  ${leftBarDataSetNode}
50251
+ ${insertDataLabels({ showValues: chart.showValues })}
50185
50252
  <c:gapWidth val="50" />
50186
50253
  <c:axId val="${catAxId}" />
50187
50254
  <c:axId val="${valAxId}" />
@@ -50191,6 +50258,7 @@ function addPyramidChart(chart) {
50191
50258
  <c:grouping val="clustered"/>
50192
50259
  <c:varyColors val="0" />
50193
50260
  ${rightBarDataSetNode}
50261
+ ${insertDataLabels({ showValues: chart.showValues })}
50194
50262
  <c:gapWidth val="50" />
50195
50263
  <c:axId val="${secondaryCatAxId}" />
50196
50264
  <c:axId val="${secondaryValAxId}" />
@@ -50244,6 +50312,7 @@ function addLineChart(chart) {
50244
50312
  </c:marker>
50245
50313
  ${extractTrendline(dataset.trend, color)}
50246
50314
  ${extractDataSetLabel(dataset.label)}
50315
+ ${insertDataLabels({ showValues: chart.showValues })}
50247
50316
  ${dataShapeProperty}
50248
50317
  ${chart.labelRange ? escapeXml `<c:cat>${stringRef(chart.labelRange)}</c:cat>` : ""} <!-- x-coordinate values -->
50249
50318
  <c:val> <!-- x-coordinate values -->
@@ -50267,6 +50336,7 @@ function addLineChart(chart) {
50267
50336
  <!-- each data marker in the series does not have a different color -->
50268
50337
  <c:varyColors val="0"/>
50269
50338
  ${joinXmlNodes(leftDataSetsNodes)}
50339
+ ${insertDataLabels({ showValues: chart.showValues })}
50270
50340
  <c:axId val="${catAxId}" />
50271
50341
  <c:axId val="${valAxId}" />
50272
50342
  </c:lineChart>
@@ -50281,6 +50351,7 @@ function addLineChart(chart) {
50281
50351
  <!-- each data marker in the series does not have a different color -->
50282
50352
  <c:varyColors val="0"/>
50283
50353
  ${joinXmlNodes(rightDataSetsNodes)}
50354
+ ${insertDataLabels({ showValues: chart.showValues })}
50284
50355
  <c:axId val="${catAxId + 1}" />
50285
50356
  <c:axId val="${valAxId + 1}" />
50286
50357
  </c:lineChart>
@@ -50316,6 +50387,7 @@ function addScatterChart(chart) {
50316
50387
  </c:marker>
50317
50388
  ${extractTrendline(dataset.trend, color)}
50318
50389
  ${extractDataSetLabel(dataset.label)}
50390
+ ${insertDataLabels({ showValues: chart.showValues })}
50319
50391
  ${chart.labelRange
50320
50392
  ? escapeXml /*xml*/ `<c:xVal> <!-- x-coordinate values -->
50321
50393
  ${numberRef(chart.labelRange)}
@@ -50341,6 +50413,7 @@ function addScatterChart(chart) {
50341
50413
  <c:varyColors val="0"/>
50342
50414
  <c:scatterStyle val="lineMarker"/>
50343
50415
  ${joinXmlNodes(leftDataSetsNodes)}
50416
+ ${insertDataLabels({ showValues: chart.showValues })}
50344
50417
  <c:axId val="${catAxId}" />
50345
50418
  <c:axId val="${valAxId}" />
50346
50419
  </c:scatterChart>
@@ -50355,6 +50428,7 @@ function addScatterChart(chart) {
50355
50428
  <c:varyColors val="0"/>
50356
50429
  <c:scatterStyle val="lineMarker"/>
50357
50430
  ${joinXmlNodes(rightDataSetsNodes)}
50431
+ ${insertDataLabels({ showValues: chart.showValues })}
50358
50432
  <c:axId val="${catAxId + 1}" />
50359
50433
  <c:axId val="${valAxId + 1}" />
50360
50434
  </c:scatterChart>
@@ -50387,6 +50461,7 @@ function addRadarChart(chart) {
50387
50461
  ${shapeProperty({ backgroundColor: color, line: { color } })}
50388
50462
  </c:marker>
50389
50463
  ${extractDataSetLabel(dataset.label)}
50464
+ ${insertDataLabels({ showValues: chart.showValues })}
50390
50465
  ${dataShapeProperty}
50391
50466
  ${chart.labelRange ? escapeXml `<c:cat>${stringRef(chart.labelRange)}</c:cat>` : ""} <!-- x-coordinate values -->
50392
50467
  <c:val> <!-- x-coordinate values -->
@@ -50402,6 +50477,7 @@ function addRadarChart(chart) {
50402
50477
  <c:radarStyle val="marker"/>
50403
50478
  <c:varyColors val="0"/>
50404
50479
  ${joinXmlNodes(dataSetsNodes)}
50480
+ ${insertDataLabels({ showValues: chart.showValues })}
50405
50481
  <c:axId val="${catAxId}" />
50406
50482
  <c:axId val="${valAxId}" />
50407
50483
  </c:radarChart>
@@ -50437,7 +50513,7 @@ function addDoughnutChart(chart, chartSheetIndex, data) {
50437
50513
  <c:order val="${dsIndex}"/>
50438
50514
  ${extractDataSetLabel(dataset.label)}
50439
50515
  ${joinXmlNodes(dataPoints)}
50440
- ${insertDataLabels({ showLeaderLines: true })}
50516
+ ${insertDataLabels({ showLeaderLines: true, showValues: chart.showValues })}
50441
50517
  ${chart.labelRange ? escapeXml `<c:cat>${stringRef(chart.labelRange)}</c:cat>` : ""}
50442
50518
  <c:val>
50443
50519
  ${numberRef(dataset.range)}
@@ -50449,22 +50525,25 @@ function addDoughnutChart(chart, chartSheetIndex, data) {
50449
50525
  <c:doughnutChart>
50450
50526
  <c:varyColors val="1" />
50451
50527
  <c:holeSize val="${chart.pieHolePercentage ?? (chart.isDoughnut ? DEFAULT_DOUGHNUT_CHART_HOLE_SIZE : 0)}" />
50452
- ${insertDataLabels()}
50453
50528
  ${joinXmlNodes(dataSetsNodes)}
50529
+ ${insertDataLabels({ showValues: chart.showValues })}
50454
50530
  </c:doughnutChart>
50455
50531
  `;
50456
50532
  }
50457
- function insertDataLabels({ showLeaderLines } = { showLeaderLines: false }) {
50533
+ function insertDataLabels({ showLeaderLines, showValues } = {
50534
+ showLeaderLines: false,
50535
+ showValues: false,
50536
+ }) {
50458
50537
  return escapeXml /*xml*/ `
50459
- <dLbls>
50538
+ <c:dLbls>
50460
50539
  <c:showLegendKey val="0"/>
50461
- <c:showVal val="0"/>
50540
+ <c:showVal val="${showValues ? "1" : "0"}"/>
50462
50541
  <c:showCatName val="0"/>
50463
50542
  <c:showSerName val="0"/>
50464
50543
  <c:showPercent val="0"/>
50465
50544
  <c:showBubbleSize val="0"/>
50466
50545
  <c:showLeaderLines val="${showLeaderLines ? "1" : "0"}"/>
50467
- </dLbls>
50546
+ </c:dLbls>
50468
50547
  `;
50469
50548
  }
50470
50549
  function addAx(position, axisName, axId, crossAxId, title, defaultFontColor, deleteAxis = 0, orientation = "minMax", crossPosition, tickLabelPosition = "nextTo", maxValue, majorUnit, format = "General") {
@@ -51426,6 +51505,12 @@ function addStyles(styles) {
51426
51505
  if (style.alignment && style.alignment.wrapText) {
51427
51506
  alignAttrs.push(["wrapText", "1"]);
51428
51507
  }
51508
+ if (style.alignment && style.alignment.textRotation) {
51509
+ alignAttrs.push(["textRotation", style.alignment.textRotation]);
51510
+ }
51511
+ if (style.alignment && style.alignment.shrinkToFit) {
51512
+ alignAttrs.push(["shrinkToFit", "1"]);
51513
+ }
51429
51514
  if (alignAttrs.length > 0) {
51430
51515
  attributes.push(["applyAlignment", "1"]); // for Libre Office
51431
51516
  styleNodes.push(escapeXml /*xml*/ `<xf ${formatAttributes(attributes)}><alignment ${formatAttributes(alignAttrs)} /></xf> `);
@@ -52224,7 +52309,7 @@ class Model extends EventBus {
52224
52309
  this.config = this.setupConfig(config);
52225
52310
  this.session = this.setupSession(workbookData.revisionId);
52226
52311
  this.coreGetters = {};
52227
- this.range = new RangeAdapter(this.coreGetters);
52312
+ this.range = new RangeAdapterPlugin(this.coreGetters);
52228
52313
  this.coreGetters.getRangeString = this.range.getRangeString.bind(this.range);
52229
52314
  this.coreGetters.getRangeFromSheetXC = this.range.getRangeFromSheetXC.bind(this.range);
52230
52315
  this.coreGetters.createAdaptedRanges = this.range.createAdaptedRanges.bind(this.range);
@@ -52238,8 +52323,6 @@ class Model extends EventBus {
52238
52323
  this.coreGetters.extendRange = this.range.extendRange.bind(this.range);
52239
52324
  this.coreGetters.getRangesUnion = this.range.getRangesUnion.bind(this.range);
52240
52325
  this.coreGetters.removeRangesSheetPrefix = this.range.removeRangesSheetPrefix.bind(this.range);
52241
- this.coreGetters.adaptFormulaStringDependencies =
52242
- this.range.adaptFormulaStringDependencies.bind(this.range);
52243
52326
  this.coreGetters.copyFormulaStringForSheet = this.range.copyFormulaStringForSheet.bind(this.range);
52244
52327
  this.getters = {
52245
52328
  isReadonly: () => this.config.mode === "readonly" || this.config.mode === "dashboard",
@@ -52710,5 +52793,5 @@ export { BadExpressionError, BasePlugin, CellErrorType, CircularDependencyError,
52710
52793
 
52711
52794
 
52712
52795
  __info__.version = "19.1.0-alpha.3";
52713
- __info__.date = "2026-01-14T10:01:30.535Z";
52714
- __info__.hash = "e5cbf18";
52796
+ __info__.date = "2026-01-21T11:07:49.673Z";
52797
+ __info__.hash = "fa080c2";