@univerjs/engine-formula 1.0.4 → 1.2.0

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.
Files changed (33) hide show
  1. package/lib/cjs/{en-US-DrAfIiBE.js → en-US-BYMYuEpp.js} +15 -15
  2. package/lib/cjs/facade.js +3 -18
  3. package/lib/cjs/index.js +500 -166
  4. package/lib/cjs/locale/en-US.js +1 -1
  5. package/lib/cjs/locale/fa-IR.js +1 -1
  6. package/lib/cjs/locale/zh-HK.js +1 -1
  7. package/lib/cjs/locale/zh-TW.js +1 -1
  8. package/lib/cjs/{zh-TW-CvMudVQy.js → zh-TW-B5pYt-NJ.js} +15 -15
  9. package/lib/es/facade.js +3 -18
  10. package/lib/es/index.js +474 -140
  11. package/lib/facade.js +3 -18
  12. package/lib/index.js +474 -140
  13. package/lib/types/basics/common.d.ts +8 -2
  14. package/lib/types/commands/mutations/set-formula-calculation.mutation.d.ts +2 -1
  15. package/lib/types/config/config.d.ts +0 -2
  16. package/lib/types/engine/dependency/dependency-groups.d.ts +21 -0
  17. package/lib/types/engine/dependency/dependency-tree.d.ts +1 -0
  18. package/lib/types/engine/dependency/formula-dependency.d.ts +1 -1
  19. package/lib/types/engine/reference-object/base-reference-object.d.ts +2 -1
  20. package/lib/types/engine/value-object/array-value-object.d.ts +10 -1
  21. package/lib/types/facade/f-formula.d.ts +0 -13
  22. package/lib/types/functions/lookup/xlookup/index.d.ts +2 -4
  23. package/lib/types/index.d.ts +4 -2
  24. package/lib/types/models/formula-data.model.d.ts +5 -0
  25. package/lib/types/services/active-dirty-manager.service.d.ts +1 -0
  26. package/lib/types/services/calculate-formula.service.d.ts +34 -2
  27. package/lib/types/services/current-data.service.d.ts +4 -2
  28. package/lib/types/services/formula-calculation-trigger.service.d.ts +5 -0
  29. package/lib/types/services/formula-changeset-calculation.service.d.ts +34 -0
  30. package/lib/types/services/runtime.service.d.ts +36 -2
  31. package/lib/umd/facade.js +1 -1
  32. package/lib/umd/index.js +4 -4
  33. package/package.json +6 -6
package/lib/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import IntervalTree from "@flatten-js/interval-tree";
2
- import { AbsoluteRefType, AsyncLock, BooleanNumber, BuildTextUtils, CellValueType, CommandType, DataStreamTreeTokenType, DateSystem, Disposable, DisposableCollection, EXCEL_1904_OFFSET, ICommandService, IConfigService, IUniverInstanceService, Inject, Injector, LRUMap, LifecycleService, LifecycleStages, LocaleService, LocaleType, MAX_COLUMN_COUNT, MAX_ROW_COUNT, ObjectMatrix, Optional, Plugin, RANGE_TYPE, RTree, Rectangle, RichTextBuilder, Styles, Tools, UniverInstanceType, cellToRange, columnLabelToNumber, createBaseFormulaTableNameMap, createIdentifier, excelDateSerial, excelDateTimePartsToSerial, excelDateTimeSerial, excelSerialToDate, excelSerialToDateTime, excelSerialToDateTimeParts, generateRandomId, getBaseFormulaTableName, getDateSystemMaxSerial, getNumfmtParseValueFilter, hashAlgorithm, isFormulaId, isFormulaString, isNodeEnv, isNullCell, isRealNum, isTextFormat, isValidRange, merge, moveRangeByOffset, numfmt, regexp, requestImmediateMacroTask, sortRules, toDisposable, touchDependencies } from "@univerjs/core";
2
+ import { AbsoluteRefType, AsyncLock, BooleanNumber, BuildTextUtils, CellValueType, CommandType, DataStreamTreeTokenType, DateSystem, Disposable, DisposableCollection, EXCEL_1904_OFFSET, ICommandService, IConfigService, IUniverInstanceService, Inject, Injector, LRUMap, LifecycleService, LifecycleStages, LocaleService, LocaleType, MAX_COLUMN_COUNT, MAX_ROW_COUNT, ObjectMatrix, Optional, Plugin, RANGE_TYPE, RTree, Rectangle, RichTextBuilder, Styles, Tools, UniverInstanceType, cellToRange, columnLabelToNumber, createBaseFormulaTableNameMap, createIdentifier, excelDateSerial, excelDateTimePartsToSerial, excelDateTimeSerial, excelSerialToDate, excelSerialToDateTime, excelSerialToDateTimeParts, generateRandomId, getBaseFormulaTableName, getDateSystemMaxSerial, getNumfmtParseValueFilter, hashAlgorithm, isFormulaId, isFormulaString, isNodeEnv, isNullCell, isRealNum, isTextFormat, isValidRange, merge, moveRangeByOffset, normalizeWorkbookCalculationSettings, numfmt, regexp, requestImmediateMacroTask, sortRules, toDisposable, touchDependencies } from "@univerjs/core";
3
3
  import { BehaviorSubject, Observable, Subject, combineLatest, distinctUntilChanged, filter, map, shareReplay, take } from "rxjs";
4
4
  import Decimal from "decimal.js";
5
5
  import { DataSyncPrimaryController } from "@univerjs/rpc";
@@ -328,7 +328,7 @@ function getSearchModeValue(searchModeValue) {
328
328
  }
329
329
 
330
330
  //#endregion
331
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/typeof.js
331
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/typeof.js
332
332
  function _typeof(o) {
333
333
  "@babel/helpers - typeof";
334
334
  return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
@@ -339,7 +339,7 @@ function _typeof(o) {
339
339
  }
340
340
 
341
341
  //#endregion
342
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/toPrimitive.js
342
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/toPrimitive.js
343
343
  function toPrimitive(t, r) {
344
344
  if ("object" != _typeof(t) || !t) return t;
345
345
  var e = t[Symbol.toPrimitive];
@@ -352,14 +352,14 @@ function toPrimitive(t, r) {
352
352
  }
353
353
 
354
354
  //#endregion
355
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/toPropertyKey.js
355
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/toPropertyKey.js
356
356
  function toPropertyKey(t) {
357
357
  var i = toPrimitive(t, "string");
358
358
  return "symbol" == _typeof(i) ? i : i + "";
359
359
  }
360
360
 
361
361
  //#endregion
362
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/defineProperty.js
362
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/defineProperty.js
363
363
  function _defineProperty(e, r, t) {
364
364
  return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
365
365
  value: t,
@@ -1186,7 +1186,7 @@ function splitTableStructuredRef(ref) {
1186
1186
  }
1187
1187
 
1188
1188
  //#endregion
1189
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorateParam.js
1189
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/decorateParam.js
1190
1190
  function __decorateParam(paramIndex, decorator) {
1191
1191
  return function(target, key) {
1192
1192
  decorator(target, key, paramIndex);
@@ -1194,7 +1194,7 @@ function __decorateParam(paramIndex, decorator) {
1194
1194
  }
1195
1195
 
1196
1196
  //#endregion
1197
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorate.js
1197
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/decorate.js
1198
1198
  function __decorate(decorators, target, key, desc) {
1199
1199
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1200
1200
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -1672,8 +1672,6 @@ const SetSuperTableOptionMutation = {
1672
1672
  //#endregion
1673
1673
  //#region src/config/config.ts
1674
1674
  const ENGINE_FORMULA_PLUGIN_CONFIG_KEY = "engine-formula.config";
1675
- const DEFAULT_CYCLE_REFERENCE_COUNT = 1;
1676
- const ENGINE_FORMULA_CYCLE_REFERENCE_COUNT = "CYCLE_REFERENCE_COUNT";
1677
1675
  const ENGINE_FORMULA_RETURN_DEPENDENCY_TREE = "RETURN_DEPENDENCY_TREE";
1678
1676
  const configSymbol = Symbol(ENGINE_FORMULA_PLUGIN_CONFIG_KEY);
1679
1677
  const defaultPluginConfig = {};
@@ -3094,9 +3092,8 @@ var LexerTreeBuilder = class extends Disposable {
3094
3092
  const isCacheable = !/\b(?:LET|LAMBDA)\s*\(/iu.test(formulaString);
3095
3093
  const cacheKey = injectDefinedNameParam == null ? formulaString : `${injectDefinedNameParam.unitId ?? ""}\0${injectDefinedNameParam.sheetId ?? ""}\0${injectDefinedNameParam.refOffsetX}\0${injectDefinedNameParam.refOffsetY}\0${formulaString}`;
3096
3094
  if (transformSuffix === true && isCacheable) {
3097
- var _this$_simpleCheckDef;
3098
3095
  const lexerNode = FormulaLexerNodeCache.get(cacheKey);
3099
- const simpleCheckDefinedNameResult = injectDefinedNameParam && ((_this$_simpleCheckDef = this._simpleCheckDefinedName) === null || _this$_simpleCheckDef === void 0 ? void 0 : _this$_simpleCheckDef.call(this, formulaString, injectDefinedNameParam));
3096
+ const simpleCheckDefinedNameResult = injectDefinedNameParam && this._simpleCheckDefinedName(formulaString, injectDefinedNameParam, lexerNode);
3100
3097
  if (lexerNode && !simpleCheckDefinedNameResult) return lexerNode;
3101
3098
  }
3102
3099
  this._resetCurrentLexerNode();
@@ -3163,13 +3160,13 @@ var LexerTreeBuilder = class extends Disposable {
3163
3160
  const definedNameToken = token.trim();
3164
3161
  const definedContent = getValueByName(unitId, definedNameToken, sheetId);
3165
3162
  if (definedContent) {
3163
+ definedNames.push(definedContent.name);
3166
3164
  const refOffsetX = definedContent.localSheetId === "AllDefaultWorkbook" ? param.refOffsetX - 1 : param.refOffsetX;
3167
3165
  const refString = definedContent.formulaOrRefString.startsWith("=") ? definedContent.formulaOrRefString : this._moveDefinedNameRefOffset(definedContent.formulaOrRefString, refOffsetX, param.refOffsetY);
3168
3166
  const nestedDefinedNameParam = this._handleNestedDefinedName(refString, param);
3169
3167
  if (nestedDefinedNameParam == null || typeof nestedDefinedNameParam !== "object") {
3170
3168
  sequenceString += nestedDefinedNameParam || "#NAME?";
3171
3169
  hasDefinedName = true;
3172
- definedNames.push(definedNameToken);
3173
3170
  } else if (typeof nestedDefinedNameParam === "object") {
3174
3171
  const { sequenceString: nestedSequenceString, definedNames: nestedDefinedNames } = nestedDefinedNameParam;
3175
3172
  sequenceString += nestedSequenceString;
@@ -3234,7 +3231,7 @@ var LexerTreeBuilder = class extends Disposable {
3234
3231
  if (state === "#VALUE!" || sequenceArray.length === 0) return state;
3235
3232
  return this._handleDefinedName(sequenceArray, param);
3236
3233
  }
3237
- _simpleCheckDefinedName(formulaString, injectDefinedNameParam) {
3234
+ _simpleCheckDefinedName(formulaString, injectDefinedNameParam, lexerNode) {
3238
3235
  const { getDirtyDefinedNameMap, unitId } = injectDefinedNameParam;
3239
3236
  const definedNameMap = getDirtyDefinedNameMap();
3240
3237
  const executeUnitId = unitId;
@@ -3242,7 +3239,7 @@ var LexerTreeBuilder = class extends Disposable {
3242
3239
  const names = Object.keys(definedNameMap[executeUnitId]);
3243
3240
  for (let i = 0, len = names.length; i < len; i++) {
3244
3241
  const name = names[i];
3245
- if (formulaString.indexOf(name) > -1) return true;
3242
+ if (formulaString.indexOf(name) > -1 || (lexerNode === null || lexerNode === void 0 ? void 0 : lexerNode.getDefinedNames().includes(name))) return true;
3246
3243
  }
3247
3244
  }
3248
3245
  return false;
@@ -4301,18 +4298,43 @@ let FormulaDataModel = class FormulaDataModel extends Disposable {
4301
4298
  super();
4302
4299
  this._univerInstanceService = _univerInstanceService;
4303
4300
  this._lexerTreeBuilder = _lexerTreeBuilder;
4301
+ _defineProperty(this, "_circularReferences", /* @__PURE__ */ new Map());
4304
4302
  _defineProperty(this, "_formulaIdMapData", Object.create(null));
4305
4303
  _defineProperty(this, "_arrayFormulaRange", Object.create(null));
4306
4304
  _defineProperty(this, "_arrayFormulaCellData", Object.create(null));
4307
4305
  _defineProperty(this, "_unitImageFormulaData", Object.create(null));
4306
+ this.disposeWithMe(this._univerInstanceService.getTypeOfUnitDisposed$(UniverInstanceType.UNIVER_SHEET).subscribe((workbook) => {
4307
+ for (const [key, cell] of this._circularReferences) if (cell.unitId === workbook.getUnitId()) this._circularReferences.delete(key);
4308
+ }));
4308
4309
  }
4309
4310
  dispose() {
4310
4311
  super.dispose();
4312
+ this._circularReferences.clear();
4311
4313
  this._formulaIdMapData = Object.create(null);
4312
4314
  this._arrayFormulaRange = Object.create(null);
4313
4315
  this._arrayFormulaCellData = Object.create(null);
4314
4316
  this._unitImageFormulaData = Object.create(null);
4315
4317
  }
4318
+ setCircularReferences(cells) {
4319
+ this._circularReferences.clear();
4320
+ for (const cell of cells) this._circularReferences.set(JSON.stringify([
4321
+ cell.unitId,
4322
+ cell.sheetId,
4323
+ cell.row,
4324
+ cell.column
4325
+ ]), { ...cell });
4326
+ }
4327
+ getCircularReferences(unitId) {
4328
+ return Array.from(this._circularReferences.values()).filter((cell) => cell.unitId === unitId).map((cell) => ({ ...cell }));
4329
+ }
4330
+ isCircularReference(unitId, sheetId, row, column) {
4331
+ return this._circularReferences.has(JSON.stringify([
4332
+ unitId,
4333
+ sheetId,
4334
+ row,
4335
+ column
4336
+ ]));
4337
+ }
4316
4338
  clearPreviousArrayFormulaCellData(clearArrayFormulaCellData) {
4317
4339
  Object.keys(clearArrayFormulaCellData).forEach((unitId) => {
4318
4340
  const clearSheetData = clearArrayFormulaCellData[unitId];
@@ -5151,6 +5173,7 @@ let FormulaCurrentConfigService = class FormulaCurrentConfigService extends Disp
5151
5173
  this._localeService = _localeService;
5152
5174
  this._formulaDataModel = _formulaDataModel;
5153
5175
  this._sheetRowFilteredService = _sheetRowFilteredService;
5176
+ _defineProperty(this, "_dirtyIterationUnits", []);
5154
5177
  _defineProperty(this, "_unitData", Object.create(null));
5155
5178
  _defineProperty(this, "_unitStylesData", Object.create(null));
5156
5179
  _defineProperty(this, "_arrayFormulaCellData", Object.create(null));
@@ -5331,6 +5354,7 @@ let FormulaCurrentConfigService = class FormulaCurrentConfigService extends Disp
5331
5354
  }
5332
5355
  if (config.rowData) this._applyUnitRowData(config.rowData);
5333
5356
  this._formulaData = config.formulaData;
5357
+ this._dirtyIterationUnits = config.dirtyIterationUnits ?? [];
5334
5358
  this._arrayFormulaCellData = convertUnitDataToRuntime(config.arrayFormulaCellData);
5335
5359
  this._arrayFormulaRange = config.arrayFormulaRange;
5336
5360
  this._forceCalculate = config.forceCalculate;
@@ -5358,6 +5382,7 @@ let FormulaCurrentConfigService = class FormulaCurrentConfigService extends Disp
5358
5382
  }
5359
5383
  getDirtyData() {
5360
5384
  return {
5385
+ dirtyIterationUnits: this._dirtyIterationUnits,
5361
5386
  forceCalculation: this._forceCalculate,
5362
5387
  dirtyRanges: this._dirtyRanges,
5363
5388
  dirtyNameMap: this._dirtyNameMap,
@@ -5370,6 +5395,7 @@ let FormulaCurrentConfigService = class FormulaCurrentConfigService extends Disp
5370
5395
  };
5371
5396
  }
5372
5397
  loadDirtyRangesAndExcludedCell(dirtyRanges, excludedCell) {
5398
+ this._dirtyIterationUnits = [];
5373
5399
  this._dirtyRanges = dirtyRanges;
5374
5400
  this._excludedCell = excludedCell;
5375
5401
  /**
@@ -8697,7 +8723,7 @@ var ArrayValueObject = class ArrayValueObject extends BaseValueObject {
8697
8723
  const row = [];
8698
8724
  for (let c = 0; c < columnArrayCount; c++) {
8699
8725
  const cellRaw = columnArray[c].trim();
8700
- row.push(ValueObjectFactory.create(cellRaw, false, dateSystem));
8726
+ row.push(ValueObjectFactory.createNumberLiteral(cellRaw, dateSystem) ?? ValueObjectFactory.create(cellRaw, false, dateSystem));
8701
8727
  }
8702
8728
  result.push(row);
8703
8729
  }
@@ -8722,6 +8748,7 @@ var ArrayValueObject = class ArrayValueObject extends BaseValueObject {
8722
8748
  return ArrayValueObject.create(arrayValueObjectData, this.getDateSystem());
8723
8749
  }
8724
8750
  };
8751
+ const NUMBER_LITERAL_REGEX = /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i;
8725
8752
  var ValueObjectFactory = class {
8726
8753
  static create(rawValue, isIgnoreNumberPattern = false, dateSystem = DateSystem.Date1900) {
8727
8754
  if (rawValue == null) return NullValueObject.create();
@@ -8743,6 +8770,19 @@ var ValueObjectFactory = class {
8743
8770
  if (typeof rawValue === "number") return createNumberValueObjectByRawValue(rawValue).withDateSystem(dateSystem);
8744
8771
  return ErrorValueObject.create("#VALUE!");
8745
8772
  }
8773
+ /**
8774
+ * Create a number from a number literal written in formula source, such as `12.50`, `.5`, `007` or `1E3`.
8775
+ * Unlike cell text, where "000123456" must stay a string, a number literal in a formula is always a number.
8776
+ *
8777
+ * @param token The unquoted token from the formula source.
8778
+ * @param dateSystem The workbook date system.
8779
+ * @returns The number value object, a NUM error on overflow, or null when the token is not a number literal.
8780
+ */
8781
+ static createNumberLiteral(token, dateSystem = DateSystem.Date1900) {
8782
+ const tokenTrim = token.trim();
8783
+ if (!NUMBER_LITERAL_REGEX.test(tokenTrim)) return null;
8784
+ return createNumberValueObjectByRawValue(Number(tokenTrim)).withDateSystem(dateSystem);
8785
+ }
8746
8786
  };
8747
8787
  function isStringWrappedByDoubleQuotes(input) {
8748
8788
  const trimmedInput = input.trim();
@@ -9118,6 +9158,16 @@ var BaseReferenceObject = class extends ObjectClassType {
9118
9158
  getRuntimeFeatureCellValue(row, column) {
9119
9159
  return getRuntimeFeatureCell(row, column, this.getSheetId(), this.getUnitId(), this._runtimeFeatureCellData);
9120
9160
  }
9161
+ isCellBlank(row, column) {
9162
+ var _this$getCurrentActiv5, _this$getCurrentRunti, _this$getCurrentActiv6, _this$getCurrentRunti2;
9163
+ const cell = this.getCellData(row, column);
9164
+ if (!isNullCell(cell)) return false;
9165
+ const originalCell = (_this$getCurrentActiv5 = this.getCurrentActiveSheetData()) === null || _this$getCurrentActiv5 === void 0 ? void 0 : _this$getCurrentActiv5.cellData.getValue(row, column);
9166
+ if (isFormulaString(originalCell === null || originalCell === void 0 ? void 0 : originalCell.f) || isFormulaId(originalCell === null || originalCell === void 0 ? void 0 : originalCell.si)) return false;
9167
+ if (!cell) return true;
9168
+ if (cell === ((_this$getCurrentRunti = this.getCurrentRuntimeActiveArrayFormulaCellData()) === null || _this$getCurrentRunti === void 0 ? void 0 : _this$getCurrentRunti.getValue(row, column)) || cell === ((_this$getCurrentActiv6 = this.getCurrentActiveArrayFormulaCellData()) === null || _this$getCurrentActiv6 === void 0 ? void 0 : _this$getCurrentActiv6.getValue(row, column)) || cell === this.getRuntimeFeatureCellValue(row, column)) return false;
9169
+ return originalCell != null || cell !== ((_this$getCurrentRunti2 = this.getCurrentRuntimeSheetData()) === null || _this$getCurrentRunti2 === void 0 ? void 0 : _this$getCurrentRunti2.getValue(row, column));
9170
+ }
9121
9171
  getCellByPosition(rowRaw, columnRaw) {
9122
9172
  const range = this.getRangePosition();
9123
9173
  const row = rowRaw ?? range.startRow;
@@ -10029,11 +10079,14 @@ let FormulaExecutedStateType = /* @__PURE__ */ function(FormulaExecutedStateType
10029
10079
  return FormulaExecutedStateType;
10030
10080
  }({});
10031
10081
  let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10032
- constructor(_currentConfigService, _hyperlinkEngineFormulaService) {
10082
+ constructor(_currentConfigService, _hyperlinkEngineFormulaService, _univerInstanceService) {
10033
10083
  super();
10034
10084
  this._currentConfigService = _currentConfigService;
10035
10085
  this._hyperlinkEngineFormulaService = _hyperlinkEngineFormulaService;
10086
+ this._univerInstanceService = _univerInstanceService;
10036
10087
  _defineProperty(this, "_formulaExecuteStage", 0);
10088
+ _defineProperty(this, "_circularReferences", /* @__PURE__ */ new Map());
10089
+ _defineProperty(this, "_pendingCircularReferences", /* @__PURE__ */ new Map());
10037
10090
  _defineProperty(this, "_stopState", false);
10038
10091
  _defineProperty(this, "_externalReferenceUnavailable", false);
10039
10092
  _defineProperty(this, "_currentRow", -1);
@@ -10063,6 +10116,9 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10063
10116
  _defineProperty(this, "_formulaCycleIndex", 0);
10064
10117
  _defineProperty(this, "_isCycleDependency", false);
10065
10118
  _defineProperty(this, "_dependencyTreeModelData", []);
10119
+ this.disposeWithMe(this._univerInstanceService.getTypeOfUnitDisposed$(UniverInstanceType.UNIVER_SHEET).subscribe((workbook) => {
10120
+ for (const references of [this._circularReferences, this._pendingCircularReferences]) for (const [key, cell] of references) if (cell.unitId === workbook.getUnitId()) references.delete(key);
10121
+ }));
10066
10122
  }
10067
10123
  get currentRow() {
10068
10124
  return this._currentRow;
@@ -10087,6 +10143,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10087
10143
  dispose() {
10088
10144
  super.dispose();
10089
10145
  this.reset();
10146
+ this._circularReferences.clear();
10147
+ this._pendingCircularReferences.clear();
10090
10148
  this._runtimeFeatureCellData = Object.create(null);
10091
10149
  this._runtimeFeatureRange = Object.create(null);
10092
10150
  this.clearReferenceAndNumberformatCache();
@@ -10180,8 +10238,60 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10180
10238
  clearStringToNumberPatternCache();
10181
10239
  clearReferenceToRangeCache();
10182
10240
  }
10241
+ beginCircularReferences() {
10242
+ this._pendingCircularReferences = new Map(this._circularReferences);
10243
+ const formulaData = this._currentConfigService.getFormulaData();
10244
+ for (const [key, cell] of this._pendingCircularReferences) {
10245
+ var _formulaData$cell$uni;
10246
+ if (!((_formulaData$cell$uni = formulaData[cell.unitId]) === null || _formulaData$cell$uni === void 0 || (_formulaData$cell$uni = _formulaData$cell$uni[cell.sheetId]) === null || _formulaData$cell$uni === void 0 || (_formulaData$cell$uni = _formulaData$cell$uni[cell.row]) === null || _formulaData$cell$uni === void 0 ? void 0 : _formulaData$cell$uni[cell.column])) this._pendingCircularReferences.delete(key);
10247
+ }
10248
+ }
10249
+ clearCircularReferenceCells(cells) {
10250
+ if (this._pendingCircularReferences.size === 0) return;
10251
+ for (const cell of cells) {
10252
+ this._pendingCircularReferences.delete(JSON.stringify([
10253
+ cell.unitId,
10254
+ cell.subUnitId,
10255
+ cell.row,
10256
+ cell.column
10257
+ ]));
10258
+ if (this._pendingCircularReferences.size === 0) return;
10259
+ }
10260
+ }
10261
+ recordCircularReferences(cells) {
10262
+ for (const cell of cells) {
10263
+ if (cell.row < 0 || cell.column < 0) continue;
10264
+ this._pendingCircularReferences.set(JSON.stringify([
10265
+ cell.unitId,
10266
+ cell.sheetId,
10267
+ cell.row,
10268
+ cell.column
10269
+ ]), { ...cell });
10270
+ }
10271
+ }
10272
+ completeCircularReferences() {
10273
+ if (!this.isStopExecution()) this._circularReferences = new Map(this._pendingCircularReferences);
10274
+ }
10275
+ preserveCurrentCellData() {
10276
+ var _this$_currentConfigS;
10277
+ const unitId = this.currentUnitId;
10278
+ const sheetId = this.currentSubUnitId;
10279
+ const cell = (_this$_currentConfigS = this._currentConfigService.getUnitData()[unitId]) === null || _this$_currentConfigS === void 0 || (_this$_currentConfigS = _this$_currentConfigS[sheetId]) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS.cellData.getValue(this.currentRow, this.currentColumn);
10280
+ if ((cell === null || cell === void 0 ? void 0 : cell.v) != null) return;
10281
+ const sheets = this._runtimeData[unitId] ??= {};
10282
+ (sheets[sheetId] ??= new ObjectMatrix()).setValue(this.currentRow, this.currentColumn, {
10283
+ v: (cell === null || cell === void 0 ? void 0 : cell.v) ?? 0,
10284
+ t: (cell === null || cell === void 0 ? void 0 : cell.v) == null ? CellValueType.NUMBER : cell.t
10285
+ });
10286
+ if (this._currentSourceFormula) {
10287
+ const formulas = this._sourceFormulaData[unitId] ??= {};
10288
+ const sheet = formulas[sheetId] ??= {};
10289
+ const row = sheet[this.currentRow] ??= {};
10290
+ row[this.currentColumn] = { ...this._currentSourceFormula };
10291
+ }
10292
+ }
10183
10293
  setCurrent(row, column, rowCount, columnCount, sheetId, unitId) {
10184
- var _this$_currentConfigS, _this$_currentConfigS2;
10294
+ var _this$_currentConfigS2, _this$_currentConfigS3;
10185
10295
  this._externalReferenceUnavailable = false;
10186
10296
  this._currentRow = row;
10187
10297
  this._currentColumn = column;
@@ -10189,8 +10299,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10189
10299
  this._currentColumnCount = columnCount;
10190
10300
  this._currentSubUnitId = sheetId;
10191
10301
  this._currentUnitId = unitId;
10192
- const cell = (_this$_currentConfigS = this._currentConfigService.getUnitData()[unitId]) === null || _this$_currentConfigS === void 0 || (_this$_currentConfigS = _this$_currentConfigS[sheetId]) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS.cellData.getValue(row, column);
10193
- const formula = (_this$_currentConfigS2 = this._currentConfigService.getFormulaData()[unitId]) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[sheetId]) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[row]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2[column];
10302
+ const cell = (_this$_currentConfigS2 = this._currentConfigService.getUnitData()[unitId]) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[sheetId]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2.cellData.getValue(row, column);
10303
+ const formula = (_this$_currentConfigS3 = this._currentConfigService.getFormulaData()[unitId]) === null || _this$_currentConfigS3 === void 0 || (_this$_currentConfigS3 = _this$_currentConfigS3[sheetId]) === null || _this$_currentConfigS3 === void 0 || (_this$_currentConfigS3 = _this$_currentConfigS3[row]) === null || _this$_currentConfigS3 === void 0 ? void 0 : _this$_currentConfigS3[column];
10194
10304
  if (formula) {
10195
10305
  const isSharedFollower = (formula.x ?? 0) !== 0 || (formula.y ?? 0) !== 0;
10196
10306
  this._currentSourceFormula = {
@@ -10251,9 +10361,9 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10251
10361
  }
10252
10362
  setRuntimeData(functionVariant) {
10253
10363
  if (this._externalReferenceUnavailable) {
10254
- var _this$_currentConfigS3, _this$_currentConfigS4;
10255
- const cell = (_this$_currentConfigS3 = this._currentConfigService.getUnitData()[this._currentUnitId]) === null || _this$_currentConfigS3 === void 0 || (_this$_currentConfigS3 = _this$_currentConfigS3[this._currentSubUnitId]) === null || _this$_currentConfigS3 === void 0 ? void 0 : _this$_currentConfigS3.cellData.getValue(this._currentRow, this._currentColumn);
10256
- const formula = (_this$_currentConfigS4 = this._currentConfigService.getFormulaData()[this._currentUnitId]) === null || _this$_currentConfigS4 === void 0 || (_this$_currentConfigS4 = _this$_currentConfigS4[this._currentSubUnitId]) === null || _this$_currentConfigS4 === void 0 || (_this$_currentConfigS4 = _this$_currentConfigS4[this._currentRow]) === null || _this$_currentConfigS4 === void 0 || (_this$_currentConfigS4 = _this$_currentConfigS4[this._currentColumn]) === null || _this$_currentConfigS4 === void 0 ? void 0 : _this$_currentConfigS4.f;
10364
+ var _this$_currentConfigS4, _this$_currentConfigS5;
10365
+ const cell = (_this$_currentConfigS4 = this._currentConfigService.getUnitData()[this._currentUnitId]) === null || _this$_currentConfigS4 === void 0 || (_this$_currentConfigS4 = _this$_currentConfigS4[this._currentSubUnitId]) === null || _this$_currentConfigS4 === void 0 ? void 0 : _this$_currentConfigS4.cellData.getValue(this._currentRow, this._currentColumn);
10366
+ const formula = (_this$_currentConfigS5 = this._currentConfigService.getFormulaData()[this._currentUnitId]) === null || _this$_currentConfigS5 === void 0 || (_this$_currentConfigS5 = _this$_currentConfigS5[this._currentSubUnitId]) === null || _this$_currentConfigS5 === void 0 || (_this$_currentConfigS5 = _this$_currentConfigS5[this._currentRow]) === null || _this$_currentConfigS5 === void 0 || (_this$_currentConfigS5 = _this$_currentConfigS5[this._currentColumn]) === null || _this$_currentConfigS5 === void 0 ? void 0 : _this$_currentConfigS5.f;
10257
10367
  if ((cell === null || cell === void 0 ? void 0 : cell.f) && cell.v != null && (formula == null || formula === cell.f)) return;
10258
10368
  }
10259
10369
  const row = this._currentRow;
@@ -10312,7 +10422,7 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10312
10422
  const hasDataInArrayFormulaRange = this._checkIfArrayFormulaRangeHasData(unitId, sheetId, row, column, arrayRange);
10313
10423
  const isArrayFormulaExceeded = this._checkIfArrayFormulaExceeded(rowCount, columnCount, arrayRange);
10314
10424
  if (hasDataInArrayFormulaRange || isArrayFormulaExceeded) {
10315
- var _this$_currentConfigS5;
10425
+ var _this$_currentConfigS6;
10316
10426
  const errorObject = this._getValueObjectOfRuntimeData(ErrorValueObject.create("#SPILL!"));
10317
10427
  sheetData.setValue(row, column, errorObject);
10318
10428
  clearArrayUnitData.setValue(row, column, errorObject);
@@ -10323,7 +10433,7 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10323
10433
  */
10324
10434
  const unitData = this._currentConfigService.getUnitData();
10325
10435
  const arrayData = this._currentConfigService.getArrayFormulaCellData();
10326
- const previousArrayFormulaRange = (_this$_currentConfigS5 = this._currentConfigService.getArrayFormulaRange()[unitId]) === null || _this$_currentConfigS5 === void 0 || (_this$_currentConfigS5 = _this$_currentConfigS5[sheetId]) === null || _this$_currentConfigS5 === void 0 || (_this$_currentConfigS5 = _this$_currentConfigS5[row]) === null || _this$_currentConfigS5 === void 0 ? void 0 : _this$_currentConfigS5[column];
10436
+ const previousArrayFormulaRange = (_this$_currentConfigS6 = this._currentConfigService.getArrayFormulaRange()[unitId]) === null || _this$_currentConfigS6 === void 0 || (_this$_currentConfigS6 = _this$_currentConfigS6[sheetId]) === null || _this$_currentConfigS6 === void 0 || (_this$_currentConfigS6 = _this$_currentConfigS6[row]) === null || _this$_currentConfigS6 === void 0 ? void 0 : _this$_currentConfigS6[column];
10327
10437
  objectValueRefOrArray.iterator((_, rowIndex, columnIndex) => {
10328
10438
  var _unitData$unitId, _arrayData$unitId;
10329
10439
  const currentRow = rowIndex - startRow + row;
@@ -10440,6 +10550,7 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10440
10550
  getAllRuntimeData() {
10441
10551
  return {
10442
10552
  unitData: this.getUnitData(),
10553
+ circularReferences: Array.from(this._circularReferences.values(), (cell) => ({ ...cell })),
10443
10554
  sourceFormulaData: this._sourceFormulaData,
10444
10555
  arrayFormulaRange: this.getUnitArrayFormula(),
10445
10556
  arrayFormulaEmbedded: this.getUnitArrayFormulaEmbeddedMap(),
@@ -10460,6 +10571,7 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10460
10571
  totalArrayFormulasToCalculate: this.getTotalArrayFormulasToCalculate(),
10461
10572
  completedArrayFormulasCount: this.getCompletedArrayFormulasCount(),
10462
10573
  stage: this.getFormulaExecuteStage(),
10574
+ circularReferences: Array.from(this._circularReferences.values(), (cell) => ({ ...cell })),
10463
10575
  formulaCycleIndex: this.getFormulaCycleIndex()
10464
10576
  };
10465
10577
  }
@@ -10467,11 +10579,11 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10467
10579
  FORMULA_REF_TO_ARRAY_CACHE.clear();
10468
10580
  }
10469
10581
  _checkIfArrayFormulaRangeHasData(formulaUnitId, formulaSheetId, formulaRow, formulaColumn, arrayRange) {
10470
- var _this$_currentConfigS6;
10582
+ var _this$_currentConfigS7;
10471
10583
  const { startRow, startColumn, endRow, endColumn } = arrayRange;
10472
10584
  const unitData = this._currentConfigService.getUnitData();
10473
10585
  const arrayData = this._currentConfigService.getArrayFormulaCellData();
10474
- const previousArrayFormulaRange = (_this$_currentConfigS6 = this._currentConfigService.getArrayFormulaRange()[formulaUnitId]) === null || _this$_currentConfigS6 === void 0 || (_this$_currentConfigS6 = _this$_currentConfigS6[formulaSheetId]) === null || _this$_currentConfigS6 === void 0 || (_this$_currentConfigS6 = _this$_currentConfigS6[formulaRow]) === null || _this$_currentConfigS6 === void 0 ? void 0 : _this$_currentConfigS6[formulaColumn];
10586
+ const previousArrayFormulaRange = (_this$_currentConfigS7 = this._currentConfigService.getArrayFormulaRange()[formulaUnitId]) === null || _this$_currentConfigS7 === void 0 || (_this$_currentConfigS7 = _this$_currentConfigS7[formulaSheetId]) === null || _this$_currentConfigS7 === void 0 || (_this$_currentConfigS7 = _this$_currentConfigS7[formulaRow]) === null || _this$_currentConfigS7 === void 0 ? void 0 : _this$_currentConfigS7[formulaColumn];
10475
10587
  for (let r = startRow; r <= endRow; r++) for (let c = startColumn; c <= endColumn; c++) {
10476
10588
  var _this$_runtimeData, _arrayData$formulaUni, _unitData$formulaUnit;
10477
10589
  if (r === formulaRow && formulaColumn === c) continue;
@@ -10507,8 +10619,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10507
10619
  * @returns
10508
10620
  */
10509
10621
  _isInOtherArrayFormulaRange(formulaUnitId, formulaSheetId, formulaRow, formulaColumn, r, c) {
10510
- var _this$_currentConfigS7;
10511
- const arrayFormulaRange = (_this$_currentConfigS7 = this._currentConfigService.getArrayFormulaRange()[formulaUnitId]) === null || _this$_currentConfigS7 === void 0 ? void 0 : _this$_currentConfigS7[formulaSheetId];
10622
+ var _this$_currentConfigS8;
10623
+ const arrayFormulaRange = (_this$_currentConfigS8 = this._currentConfigService.getArrayFormulaRange()[formulaUnitId]) === null || _this$_currentConfigS8 === void 0 ? void 0 : _this$_currentConfigS8[formulaSheetId];
10512
10624
  if (arrayFormulaRange == null) return false;
10513
10625
  let isCellOverlapping = false;
10514
10626
  new ObjectMatrix(arrayFormulaRange).forValue((rangeRow, rangeCol, range) => {
@@ -10521,8 +10633,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10521
10633
  return isCellOverlapping;
10522
10634
  }
10523
10635
  _isCurrentSingleCellArrayFormulaRange(unitId, sheetId, row, column) {
10524
- var _this$_currentConfigS8;
10525
- const range = (_this$_currentConfigS8 = this._currentConfigService.getArrayFormulaRange()[unitId]) === null || _this$_currentConfigS8 === void 0 || (_this$_currentConfigS8 = _this$_currentConfigS8[sheetId]) === null || _this$_currentConfigS8 === void 0 || (_this$_currentConfigS8 = _this$_currentConfigS8[row]) === null || _this$_currentConfigS8 === void 0 ? void 0 : _this$_currentConfigS8[column];
10636
+ var _this$_currentConfigS9;
10637
+ const range = (_this$_currentConfigS9 = this._currentConfigService.getArrayFormulaRange()[unitId]) === null || _this$_currentConfigS9 === void 0 || (_this$_currentConfigS9 = _this$_currentConfigS9[sheetId]) === null || _this$_currentConfigS9 === void 0 || (_this$_currentConfigS9 = _this$_currentConfigS9[row]) === null || _this$_currentConfigS9 === void 0 ? void 0 : _this$_currentConfigS9[column];
10526
10638
  return range != null && range.startRow === range.endRow && range.startColumn === range.endColumn;
10527
10639
  }
10528
10640
  _isInArrayFormulaRange(range, r, c) {
@@ -10546,7 +10658,11 @@ let FormulaRuntimeService = class FormulaRuntimeService extends Disposable {
10546
10658
  return isInDirtyRange(dirtyRanges, unitId, sheetId, row, column);
10547
10659
  }
10548
10660
  };
10549
- FormulaRuntimeService = __decorate([__decorateParam(0, IFormulaCurrentConfigService), __decorateParam(1, IHyperlinkEngineFormulaService)], FormulaRuntimeService);
10661
+ FormulaRuntimeService = __decorate([
10662
+ __decorateParam(0, IFormulaCurrentConfigService),
10663
+ __decorateParam(1, IHyperlinkEngineFormulaService),
10664
+ __decorateParam(2, IUniverInstanceService)
10665
+ ], FormulaRuntimeService);
10550
10666
  const IFormulaRuntimeService = createIdentifier("univer.formula.runtime.service");
10551
10667
 
10552
10668
  //#endregion
@@ -12732,6 +12848,21 @@ UnionNodeFactory = __decorate([__decorateParam(0, IFunctionService), __decorateP
12732
12848
 
12733
12849
  //#endregion
12734
12850
  //#region src/engine/ast-node/value-node.ts
12851
+ /**
12852
+ * Copyright 2023-present DreamNum Co., Ltd.
12853
+ *
12854
+ * Licensed under the Apache License, Version 2.0 (the "License");
12855
+ * you may not use this file except in compliance with the License.
12856
+ * You may obtain a copy of the License at
12857
+ *
12858
+ * http://www.apache.org/licenses/LICENSE-2.0
12859
+ *
12860
+ * Unless required by applicable law or agreed to in writing, software
12861
+ * distributed under the License is distributed on an "AS IS" BASIS,
12862
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12863
+ * See the License for the specific language governing permissions and
12864
+ * limitations under the License.
12865
+ */
12735
12866
  var ValueNode = class extends BaseAstNode {
12736
12867
  constructor(operatorString) {
12737
12868
  super(operatorString);
@@ -12746,6 +12877,11 @@ var ValueNode = class extends BaseAstNode {
12746
12877
  this.setValue(StringValueObject.create(tokenTrim.slice(1, -1).replace(/""/g, "\"")).withDateSystem(dateSystem));
12747
12878
  return;
12748
12879
  }
12880
+ const numberLiteral = ValueObjectFactory.createNumberLiteral(tokenTrim, dateSystem);
12881
+ if (numberLiteral) {
12882
+ this.setValue(numberLiteral);
12883
+ return;
12884
+ }
12749
12885
  const parent = this.getParent();
12750
12886
  let isIgnoreNumberPattern = true;
12751
12887
  if ((parent === null || parent === void 0 ? void 0 : parent.nodeType) === 4) {
@@ -13550,6 +13686,90 @@ var OtherFormulaManagerService = class extends Disposable {
13550
13686
  };
13551
13687
  const IOtherFormulaManagerService = createIdentifier("univer.formula.other-formula-manager.service");
13552
13688
 
13689
+ //#endregion
13690
+ //#region src/engine/dependency/dependency-groups.ts
13691
+ /**
13692
+ * Copyright 2023-present DreamNum Co., Ltd.
13693
+ *
13694
+ * Licensed under the Apache License, Version 2.0 (the "License");
13695
+ * you may not use this file except in compliance with the License.
13696
+ * You may obtain a copy of the License at
13697
+ *
13698
+ * http://www.apache.org/licenses/LICENSE-2.0
13699
+ *
13700
+ * Unless required by applicable law or agreed to in writing, software
13701
+ * distributed under the License is distributed on an "AS IS" BASIS,
13702
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13703
+ * See the License for the specific language governing permissions and
13704
+ * limitations under the License.
13705
+ */
13706
+ /**
13707
+ * Returns strongly connected components in dependency order: precedents before their dependents.
13708
+ * Mutually dependent nodes stay together so only their group needs iterative calculation.
13709
+ * Uses iterative Kosaraju traversal to avoid overflowing the call stack on large dependency graphs.
13710
+ */
13711
+ function getDependencyGroups(nodes, getId, getDependents) {
13712
+ const byId = new Map(nodes.map((node) => [getId(node), node]));
13713
+ const edges = /* @__PURE__ */ new Map();
13714
+ const reverse = /* @__PURE__ */ new Map();
13715
+ for (const node of nodes) {
13716
+ const id = getId(node);
13717
+ const dependents = Array.from(getDependents(node)).filter((dependent) => byId.has(dependent));
13718
+ edges.set(id, dependents);
13719
+ for (const dependent of dependents) {
13720
+ const incoming = reverse.get(dependent) ?? [];
13721
+ incoming.push(id);
13722
+ reverse.set(dependent, incoming);
13723
+ }
13724
+ }
13725
+ const visited = /* @__PURE__ */ new Set();
13726
+ const order = [];
13727
+ for (const id of byId.keys()) {
13728
+ if (visited.has(id)) continue;
13729
+ visited.add(id);
13730
+ const stack = [{
13731
+ id,
13732
+ next: 0
13733
+ }];
13734
+ while (stack.length) {
13735
+ const frame = stack[stack.length - 1];
13736
+ const children = edges.get(frame.id);
13737
+ if (frame.next === children.length) {
13738
+ order.push(frame.id);
13739
+ stack.pop();
13740
+ continue;
13741
+ }
13742
+ const child = children[frame.next++];
13743
+ if (!visited.has(child)) {
13744
+ visited.add(child);
13745
+ stack.push({
13746
+ id: child,
13747
+ next: 0
13748
+ });
13749
+ }
13750
+ }
13751
+ }
13752
+ visited.clear();
13753
+ const groups = [];
13754
+ for (let i = order.length - 1; i >= 0; i--) {
13755
+ const id = order[i];
13756
+ if (visited.has(id)) continue;
13757
+ const group = [];
13758
+ const stack = [id];
13759
+ visited.add(id);
13760
+ while (stack.length) {
13761
+ const current = stack.pop();
13762
+ group.push(byId.get(current));
13763
+ for (const parent of reverse.get(current) ?? []) if (!visited.has(parent)) {
13764
+ visited.add(parent);
13765
+ stack.push(parent);
13766
+ }
13767
+ }
13768
+ groups.push(group);
13769
+ }
13770
+ return groups;
13771
+ }
13772
+
13553
13773
  //#endregion
13554
13774
  //#region src/engine/dependency/dependency-tree.ts
13555
13775
  let FormulaDependencyTreeType = /* @__PURE__ */ function(FormulaDependencyTreeType) {
@@ -13562,6 +13782,7 @@ var FormulaDependencyTreeCalculator = class {
13562
13782
  constructor() {
13563
13783
  _defineProperty(this, "_state", 0);
13564
13784
  _defineProperty(this, "type", 0);
13785
+ _defineProperty(this, "cycleGroup", void 0);
13565
13786
  _defineProperty(this, "treeId", void 0);
13566
13787
  _defineProperty(this, "children", /* @__PURE__ */ new Set());
13567
13788
  _defineProperty(this, "parents", /* @__PURE__ */ new Set());
@@ -13983,7 +14204,28 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends Dispos
13983
14204
  await this._generateTreeList(formulaData, otherFormulaData, unitData);
13984
14205
  this._dependencyManagerService.openKdTree();
13985
14206
  const updateTreeList = this._getUpdateTreeListAndMakeDependency();
13986
- const finalTreeList = this._calculateRunList(updateTreeList);
14207
+ const runList = this._calculateRunList(updateTreeList);
14208
+ const selfReferences = /* @__PURE__ */ new Set();
14209
+ const groups = getDependencyGroups(runList, (tree) => tree.treeId, (tree) => {
14210
+ const dependents = this._dependencyManagerService.searchDependency(tree.toRTreeItem());
14211
+ const addressDependents = this._dependencyRTreeCacheForAddressFunction.bulkSearch(tree.toRTreeItem());
14212
+ for (const dependent of addressDependents) dependents.add(dependent);
14213
+ if (dependents.has(tree.treeId)) selfReferences.add(tree.treeId);
14214
+ return dependents;
14215
+ });
14216
+ this._runtimeService.clearCircularReferenceCells(runList);
14217
+ for (const group of groups) {
14218
+ const cyclic = group.length > 1 || selfReferences.has(group[0].treeId);
14219
+ const groupId = cyclic ? group.map((tree) => tree.treeId).sort((a, b) => a - b).join(",") : void 0;
14220
+ for (const tree of group) {
14221
+ tree.cycleGroup = groupId;
14222
+ if (cyclic) {
14223
+ var _this$_runtimeService;
14224
+ (_this$_runtimeService = this._runtimeService.getUnitData()[tree.unitId]) === null || _this$_runtimeService === void 0 || (_this$_runtimeService = _this$_runtimeService[tree.subUnitId]) === null || _this$_runtimeService === void 0 || _this$_runtimeService.realDeleteValue(tree.row, tree.column);
14225
+ }
14226
+ }
14227
+ }
14228
+ const finalTreeList = groups.flat().reverse();
13987
14229
  if (this._checkIsCycleDependency(finalTreeList)) this._runtimeService.enableCycleDependency();
13988
14230
  if (isCalculateTreeModel) this._runtimeService.setDependencyTreeModelData(this._getAllDependencyJson(Array.from(this._dependencyTreeCache.values())));
13989
14231
  this._dependencyTreeCache.clear();
@@ -13992,41 +14234,8 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends Dispos
13992
14234
  this._runtimeService.clearArrayObjectCache();
13993
14235
  return Promise.resolve(finalTreeList);
13994
14236
  }
13995
- _isCyclicUtilMap(treeId, colorMap) {
13996
- const WHITE = 0;
13997
- const GRAY = 1;
13998
- const BLACK = 2;
13999
- const stack = [treeId];
14000
- while (stack.length > 0) {
14001
- const currentTreeId = stack[stack.length - 1];
14002
- if ((colorMap.get(currentTreeId) || WHITE) === WHITE) {
14003
- colorMap.set(currentTreeId, GRAY);
14004
- const node = this._dependencyTreeCache.get(currentTreeId);
14005
- if (node == null) {
14006
- colorMap.set(currentTreeId, BLACK);
14007
- stack.pop();
14008
- continue;
14009
- }
14010
- const parents = this._dependencyManagerService.searchDependency(node.toRTreeItem());
14011
- for (const parentTreeId of parents) {
14012
- const parentColor = colorMap.get(parentTreeId) || WHITE;
14013
- if (parentColor === GRAY) return true;
14014
- else if (parentColor === WHITE) stack.push(parentTreeId);
14015
- }
14016
- } else {
14017
- colorMap.set(currentTreeId, BLACK);
14018
- stack.pop();
14019
- }
14020
- }
14021
- return false;
14022
- }
14023
14237
  _checkIsCycleDependency(treeList) {
14024
- const colorMap = /* @__PURE__ */ new Map();
14025
- for (const tree of treeList) if (!colorMap.has(tree.treeId)) {
14026
- if (this._isCyclicUtilMap(tree.treeId, colorMap)) return true;
14027
- }
14028
- colorMap.clear();
14029
- return false;
14238
+ return treeList.some((tree) => tree.cycleGroup != null);
14030
14239
  }
14031
14240
  _getFeatureFormulaTree(featureId, treeId, params) {
14032
14241
  const { unitId, subUnitId, dependencyRanges, getDirtyData } = params;
@@ -14410,11 +14619,17 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends Dispos
14410
14619
  if (node.nodeType === 12 && node.getToken() === "#") return true;
14411
14620
  return false;
14412
14621
  }
14622
+ _isStaticReference(node) {
14623
+ return node.nodeType === 1 || node.nodeType === 10 && node.getChildren().every((child) => this._isStaticReference(child));
14624
+ }
14413
14625
  _nodeTraversalRef(node, result) {
14414
14626
  const children = node.getChildren();
14415
14627
  const childrenCount = children.length;
14628
+ const token = node.getToken();
14629
+ const readsReferenceMetadata = node.nodeType === 4 && (token === "ROW" || token === "ROWS" || token === "COLUMN" || token === "COLUMNS");
14416
14630
  for (let i = 0; i < childrenCount; i++) {
14417
14631
  const item = children[i];
14632
+ if (readsReferenceMetadata && this._isStaticReference(item)) continue;
14418
14633
  if (this._isPreCalculateNode(item)) {
14419
14634
  result.push(item);
14420
14635
  if (item.nodeType === 10) {
@@ -14658,9 +14873,10 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends Dispos
14658
14873
  * @param tree
14659
14874
  */
14660
14875
  _includeTree(tree, node) {
14661
- var _this$_currentConfigS, _this$_currentConfigS2;
14876
+ var _this$_currentConfigS, _this$_currentConfigS2, _this$_currentConfigS3;
14662
14877
  const unitId = tree.unitId;
14663
14878
  const subUnitId = tree.subUnitId;
14879
+ if ((_this$_currentConfigS = this._currentConfigService.getDirtyData().dirtyIterationUnits) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS.includes(unitId)) return true;
14664
14880
  /**
14665
14881
  * RAND, RANDBETWEEN, NOW, TODAY are volatile functions that are marked dirty and recalculated every time a calculation occurs.
14666
14882
  */
@@ -14668,13 +14884,13 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends Dispos
14668
14884
  if (this._includeTreeFeature(tree) === true) return true;
14669
14885
  if (this._includeOtherFormula(tree) === true) return true;
14670
14886
  if (includeDefinedName(tree, node, this._currentConfigService) === true) return true;
14671
- const excludedCell = (_this$_currentConfigS = this._currentConfigService.getExcludedRange()) === null || _this$_currentConfigS === void 0 || (_this$_currentConfigS = _this$_currentConfigS[unitId]) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS[subUnitId];
14887
+ const excludedCell = (_this$_currentConfigS2 = this._currentConfigService.getExcludedRange()) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[unitId]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2[subUnitId];
14672
14888
  if ((excludedCell === null || excludedCell === void 0 ? void 0 : excludedCell.getValue(tree.row, tree.column)) != null) return false;
14673
14889
  /**
14674
14890
  * When a worksheet is inserted or deleted,
14675
14891
  * the formulas within it need to be calculated.
14676
14892
  */
14677
- if (((_this$_currentConfigS2 = this._currentConfigService.getDirtyNameMap()[unitId]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2[subUnitId]) != null) return true;
14893
+ if (((_this$_currentConfigS3 = this._currentConfigService.getDirtyNameMap()[unitId]) === null || _this$_currentConfigS3 === void 0 ? void 0 : _this$_currentConfigS3[subUnitId]) != null) return true;
14678
14894
  if (!this._updateRangeFlattenCache.has(unitId)) return false;
14679
14895
  const sheetRangeMap = this._updateRangeFlattenCache.get(unitId);
14680
14896
  if (!sheetRangeMap.has(subUnitId)) return false;
@@ -14837,6 +15053,105 @@ FormulaDependencyGenerator = __decorate([
14837
15053
  const DEFAULT_INTERVAL_COUNT = 500;
14838
15054
  const ICalculateFormulaService = createIdentifier("engine-formula.calculate-formula.service");
14839
15055
  let CalculateFormulaService = class CalculateFormulaService extends Disposable {
15056
+ _loadCalculationSettings(settings) {
15057
+ this._workbookCalculationSettings = settings ?? {};
15058
+ this._normalizedCalculationSettings.clear();
15059
+ }
15060
+ _getCalculationSettings(unitId) {
15061
+ let settings = this._normalizedCalculationSettings.get(unitId);
15062
+ if (settings == null) {
15063
+ settings = normalizeWorkbookCalculationSettings(this._workbookCalculationSettings[unitId]);
15064
+ this._normalizedCalculationSettings.set(unitId, settings);
15065
+ }
15066
+ return settings;
15067
+ }
15068
+ _getIterationCell(tree) {
15069
+ var _this$_runtimeService, _this$_currentConfigS;
15070
+ const cell = ((_this$_runtimeService = this._runtimeService.getUnitData()[tree.unitId]) === null || _this$_runtimeService === void 0 || (_this$_runtimeService = _this$_runtimeService[tree.subUnitId]) === null || _this$_runtimeService === void 0 ? void 0 : _this$_runtimeService.getValue(tree.row, tree.column)) ?? ((_this$_currentConfigS = this._currentConfigService.getUnitData()[tree.unitId]) === null || _this$_currentConfigS === void 0 || (_this$_currentConfigS = _this$_currentConfigS[tree.subUnitId]) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS.cellData.getValue(tree.row, tree.column)) ?? { v: 0 };
15071
+ return cell.v == null ? {
15072
+ v: 0,
15073
+ t: CellValueType.NUMBER
15074
+ } : cell;
15075
+ }
15076
+ async *_iterateCalculationGroup(group, groupId) {
15077
+ const settings = group.map((item) => this._getCalculationSettings(item.unitId));
15078
+ if (group.every((item, i) => {
15079
+ var _this$_currentConfigS2;
15080
+ const cell = (_this$_currentConfigS2 = this._currentConfigService.getUnitData()[item.unitId]) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[item.subUnitId]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2.cellData.getValue(item.row, item.column);
15081
+ const formula = (item.formula ?? (cell === null || cell === void 0 ? void 0 : cell.f) ?? "").toUpperCase();
15082
+ const requiresRecalculation = formula.includes(`${"INDEX"}(`) && !(formula.includes(`${"LOOKUP"}(`) && !formula.includes(`${"XLOOKUP"}(`));
15083
+ return settings[i].iterativeCalculation && this._preserveCircularUnits.has(item.unitId) && (cell === null || cell === void 0 ? void 0 : cell.v) != null && !requiresRecalculation;
15084
+ })) {
15085
+ for (const tree of group) yield {
15086
+ tree,
15087
+ preserve: true,
15088
+ iteration: 0
15089
+ };
15090
+ this._runtimeService.recordCircularReferences(group.map((item) => ({
15091
+ unitId: item.unitId,
15092
+ sheetId: item.subUnitId,
15093
+ row: item.row,
15094
+ column: item.column,
15095
+ groupId,
15096
+ iterations: 0
15097
+ })));
15098
+ return;
15099
+ }
15100
+ const limit = settings.reduce((limit, setting) => Math.max(limit, setting.iterativeCalculation ? setting.maxIterations : 0), 1);
15101
+ let converged = false;
15102
+ let iterations = 0;
15103
+ const beforeValues = [];
15104
+ const beforeTypes = [];
15105
+ for (let iteration = 0; iteration < limit; iteration++) {
15106
+ for (let i = 0; i < group.length; i++) if (settings[i].iterativeCalculation) {
15107
+ const before = this._getIterationCell(group[i]);
15108
+ beforeValues[i] = before.v;
15109
+ beforeTypes[i] = before.t;
15110
+ }
15111
+ for (let i = 0; i < group.length; i++) if (iteration < (settings[i].iterativeCalculation ? settings[i].maxIterations : 1)) {
15112
+ FORMULA_REF_TO_ARRAY_CACHE.clear();
15113
+ yield {
15114
+ tree: group[i],
15115
+ preserve: !settings[i].iterativeCalculation,
15116
+ iteration
15117
+ };
15118
+ }
15119
+ iterations = iteration + 1;
15120
+ converged = group.every((item, i) => {
15121
+ if (!settings[i].iterativeCalculation) return true;
15122
+ const after = this._getIterationCell(item);
15123
+ const previousValue = beforeValues[i];
15124
+ return typeof after.v === "number" && typeof previousValue === "number" && (after.t == null || after.t === CellValueType.NUMBER) && (beforeTypes[i] == null || beforeTypes[i] === CellValueType.NUMBER) ? Number.isFinite(after.v) && Math.abs(after.v - previousValue) <= settings[i].maxChange : after.t === beforeTypes[i] && after.v === previousValue;
15125
+ });
15126
+ if (converged) break;
15127
+ }
15128
+ FORMULA_REF_TO_ARRAY_CACHE.clear();
15129
+ this._runtimeService.recordCircularReferences(group.map((item, i) => ({
15130
+ unitId: item.unitId,
15131
+ sheetId: item.subUnitId,
15132
+ row: item.row,
15133
+ column: item.column,
15134
+ groupId,
15135
+ iterations: settings[i].iterativeCalculation ? Math.min(iterations, settings[i].maxIterations) : 0,
15136
+ converged: settings[i].iterativeCalculation ? converged : void 0
15137
+ })));
15138
+ }
15139
+ async *_getCalculationSteps(trees) {
15140
+ while (trees.length) {
15141
+ const tree = trees.pop();
15142
+ if (tree.cycleGroup == null) {
15143
+ yield {
15144
+ tree,
15145
+ preserve: false,
15146
+ iteration: 0
15147
+ };
15148
+ continue;
15149
+ }
15150
+ const group = [tree];
15151
+ while (trees.length && trees[trees.length - 1].cycleGroup === tree.cycleGroup) group.push(trees.pop());
15152
+ yield* this._iterateCalculationGroup(group, tree.cycleGroup);
15153
+ }
15154
+ }
14840
15155
  constructor(_configService, _lexer, _currentConfigService, _runtimeService, _formulaDependencyGenerator, _interpreter, _astTreeBuilder) {
14841
15156
  super();
14842
15157
  this._configService = _configService;
@@ -14852,6 +15167,9 @@ let CalculateFormulaService = class CalculateFormulaService extends Disposable {
14852
15167
  _defineProperty(this, "executionCompleteListener$", this._executionCompleteListener$.asObservable());
14853
15168
  _defineProperty(this, "_executeLock", new AsyncLock());
14854
15169
  _defineProperty(this, "_isCalculateTreeModel", false);
15170
+ _defineProperty(this, "_workbookCalculationSettings", {});
15171
+ _defineProperty(this, "_preserveCircularUnits", /* @__PURE__ */ new Set());
15172
+ _defineProperty(this, "_normalizedCalculationSettings", /* @__PURE__ */ new Map());
14855
15173
  }
14856
15174
  dispose() {
14857
15175
  super.dispose();
@@ -14887,15 +15205,12 @@ let CalculateFormulaService = class CalculateFormulaService extends Disposable {
14887
15205
  this._executionInProgressListener$.next(this._runtimeService.getRuntimeState());
14888
15206
  this._currentConfigService.load(formulaDatasetConfig);
14889
15207
  this._runtimeService.reset();
14890
- const cycleReferenceCount = formulaDatasetConfig.maxIteration || 1;
15208
+ this._loadCalculationSettings(formulaDatasetConfig.calculationSettings);
15209
+ this._preserveCircularUnits = new Set(formulaDatasetConfig.preserveCircularUnits);
15210
+ this._runtimeService.beginCircularReferences();
14891
15211
  this._isCalculateTreeModel = formulaDatasetConfig.isCalculateTreeModel || false;
14892
- for (let i = 0; i < cycleReferenceCount; i++) {
14893
- this._runtimeService.setFormulaCycleIndex(i);
14894
- const executed = await this._executeStep();
14895
- FORMULA_REF_TO_ARRAY_CACHE.clear();
14896
- const isCycleDependency = this._runtimeService.isCycleDependency();
14897
- if (!executed || !isCycleDependency) break;
14898
- }
15212
+ await this._executeStep();
15213
+ this._runtimeService.completeCircularReferences();
14899
15214
  this._runtimeService.setFormulaExecuteStage(8);
14900
15215
  this._executionInProgressListener$.next(this._runtimeService.getRuntimeState());
14901
15216
  this._executionCompleteListener$.next(this._runtimeService.getAllRuntimeData());
@@ -14976,15 +15291,9 @@ let CalculateFormulaService = class CalculateFormulaService extends Disposable {
14976
15291
  const intervalCount = (config === null || config === void 0 ? void 0 : config.intervalCount) || 500;
14977
15292
  let i = 0;
14978
15293
  const treeCount = treeList.length;
14979
- while (treeList.length > 0) {
14980
- const tree = treeList.pop();
15294
+ for await (const { tree, preserve, iteration } of this._getCalculationSteps(treeList)) {
15295
+ this._runtimeService.setFormulaCycleIndex(iteration);
14981
15296
  this._runtimeService.setCurrent(tree.row, tree.column, tree.rowCount, tree.columnCount, tree.subUnitId, tree.unitId);
14982
- const node = generateAstNode(tree.unitId, tree.formula, this._lexer, this._astTreeBuilder, this._currentConfigService, tree.subUnitId, tree.column, tree.row);
14983
- const nodeData = {
14984
- node,
14985
- refOffsetX: tree.refOffsetX,
14986
- refOffsetY: tree.refOffsetY
14987
- };
14988
15297
  const getDirtyData = tree.getDirtyData;
14989
15298
  if (i % intervalCount === 0) {
14990
15299
  /**
@@ -15002,12 +15311,23 @@ let CalculateFormulaService = class CalculateFormulaService extends Disposable {
15002
15311
  this._runtimeService.setCompletedFormulasCount(i + 1);
15003
15312
  }
15004
15313
  this._executionInProgressListener$.next(this._runtimeService.getRuntimeState());
15005
- if (this._runtimeService.isStopExecution() || nodeData == null && getDirtyData == null) {
15314
+ if (this._runtimeService.isStopExecution()) {
15006
15315
  this._runtimeService.setFormulaExecuteStage(0);
15007
15316
  this._runtimeService.markedAsStopFunctionsExecuted();
15008
15317
  return;
15009
15318
  }
15010
15319
  }
15320
+ if (preserve) {
15321
+ this._runtimeService.preserveCurrentCellData();
15322
+ i++;
15323
+ continue;
15324
+ }
15325
+ const node = generateAstNode(tree.unitId, tree.formula, this._lexer, this._astTreeBuilder, this._currentConfigService, tree.subUnitId, tree.column, tree.row);
15326
+ const nodeData = {
15327
+ node,
15328
+ refOffsetX: tree.refOffsetX,
15329
+ refOffsetY: tree.refOffsetY
15330
+ };
15011
15331
  let value;
15012
15332
  if (getDirtyData != null && tree.featureId != null) {
15013
15333
  /**
@@ -15183,11 +15503,12 @@ let CalculateController = class CalculateController extends Disposable {
15183
15503
  }));
15184
15504
  }
15185
15505
  async _calculate(formulaDirtyData) {
15186
- const { forceCalculation: forceCalculate = false, dirtyRanges = [], dirtyNameMap = {}, dirtyDefinedNameMap = {}, dirtySuperTableMap = {}, dirtyUnitFeatureMap = {}, dirtyUnitOtherFormulaMap = {}, clearDependencyTreeCache = {}, maxIteration = 1, rowData, externalReferences, isCalculateTreeModel = false } = formulaDirtyData;
15506
+ const { dirtyIterationUnits, forceCalculation: forceCalculate = false, dirtyRanges = [], dirtyNameMap = {}, dirtyDefinedNameMap = {}, dirtySuperTableMap = {}, dirtyUnitFeatureMap = {}, dirtyUnitOtherFormulaMap = {}, clearDependencyTreeCache = {}, calculationSettings, rowData, externalReferences, isCalculateTreeModel = false } = formulaDirtyData;
15187
15507
  const formulaData = this._formulaDataModel.getFormulaData();
15188
15508
  const arrayFormulaCellData = this._formulaDataModel.getArrayFormulaCellData();
15189
15509
  const arrayFormulaRange = this._formulaDataModel.getArrayFormulaRange();
15190
15510
  this._calculateFormulaService.execute({
15511
+ dirtyIterationUnits,
15191
15512
  formulaData,
15192
15513
  arrayFormulaCellData,
15193
15514
  arrayFormulaRange,
@@ -15199,7 +15520,7 @@ let CalculateController = class CalculateController extends Disposable {
15199
15520
  dirtyUnitFeatureMap,
15200
15521
  dirtyUnitOtherFormulaMap,
15201
15522
  clearDependencyTreeCache,
15202
- maxIteration,
15523
+ calculationSettings,
15203
15524
  isCalculateTreeModel,
15204
15525
  rowData,
15205
15526
  externalReferences
@@ -15247,7 +15568,10 @@ let CalculateController = class CalculateController extends Disposable {
15247
15568
  break;
15248
15569
  case 0:
15249
15570
  }
15250
- this._commandService.executeCommand(SetFormulaCalculationNotificationMutation.id, { functionsExecutedState }, { onlyLocal: true });
15571
+ this._commandService.executeCommand(SetFormulaCalculationNotificationMutation.id, {
15572
+ functionsExecutedState,
15573
+ circularReferences: data.circularReferences
15574
+ }, { onlyLocal: true });
15251
15575
  });
15252
15576
  /**
15253
15577
  * Assignment operation after formula calculation.
@@ -21325,13 +21649,13 @@ const weekendNumberMap = {
21325
21649
  17: [6]
21326
21650
  };
21327
21651
  function isValidWeekend(weekend) {
21328
- if (typeof weekend === "string" && /^[0|1]{7}/.test(weekend)) return true;
21652
+ if (typeof weekend === "string") return weekend.length === 7 && /^[01]{7}$/.test(weekend);
21329
21653
  if (weekendNumberMap[Number(weekend)]) return true;
21330
21654
  return false;
21331
21655
  }
21332
21656
  function getWeekendArray(weekend) {
21333
21657
  if (!isValidWeekend(weekend)) return [];
21334
- if (typeof weekend === "string" && /^[0|1]{7}/.test(weekend)) {
21658
+ if (typeof weekend === "string") {
21335
21659
  const result = [];
21336
21660
  for (let i = 1; i <= weekend.length; i++) if (`${weekend[i - 1]}` === "1") {
21337
21661
  if (i === weekend.length) result.push(0);
@@ -29767,7 +30091,8 @@ var Isblank = class extends BaseFunction {
29767
30091
  }
29768
30092
  calculate(value) {
29769
30093
  if (value instanceof BaseReferenceObject) {
29770
- const array = value.toArrayValueObject(false).mapValue((valueObject) => BooleanValueObject.create(valueObject.isNull()));
30094
+ const { startRow, startColumn } = value.getRangePosition();
30095
+ const array = value.toArrayValueObject(false).mapValue((valueObject, row, column) => BooleanValueObject.create(!valueObject.isError() && value.isCellBlank(startRow + row, startColumn + column)));
29771
30096
  return array.getRowCount() === 1 && array.getColumnCount() === 1 ? array.getFirstCell() : array;
29772
30097
  }
29773
30098
  if (value.isNull()) return BooleanValueObject.create(true);
@@ -32706,7 +33031,7 @@ var Sort = class extends BaseFunction {
32706
33031
  _getResult(array, sortIndexValue, sortOrderValue, byColValue, arrayRowCount, arrayColumnCount) {
32707
33032
  if (!byColValue) {
32708
33033
  if (sortIndexValue > arrayColumnCount) return ErrorValueObject.create("#VALUE!");
32709
- const arrayValue = array.getArrayValue();
33034
+ const arrayValue = array.getArrayValue().slice();
32710
33035
  arrayValue.sort(this._sort(sortIndexValue - 1, sortOrderValue));
32711
33036
  return ArrayValueObject.create({
32712
33037
  calculateValueList: arrayValue,
@@ -33334,7 +33659,7 @@ var Unique = class extends BaseFunction {
33334
33659
  const valueObject = item.valueObject;
33335
33660
  let value = valueObject.getValue();
33336
33661
  if (valueObject.isNull()) value = null;
33337
- else if (valueObject.isString() && isRealNum(value)) value = +value;
33662
+ else if (valueObject.isString()) value = isRealNum(value) ? +value : normalizeTextForComparison(value);
33338
33663
  if (!valueMap.has(value)) valueMap.set(value, [r]);
33339
33664
  else {
33340
33665
  const valueMapItem = valueMap.get(value);
@@ -33638,30 +33963,18 @@ var Xlookup = class extends BaseFunction {
33638
33963
  else resultArray = returnArray.slice(void 0, [0, 1]);
33639
33964
  if (resultArray == null) return ErrorValueObject.create("#N/A");
33640
33965
  return lookupValue.map((value) => {
33641
- const checkErrorCombination = this._checkErrorCombination(matchModeValue, searchModeValue);
33642
- if (checkErrorCombination) return checkErrorCombination;
33643
- const result = this._handleSingleObject(value, lookupArray, resultArray, matchModeValue, searchModeValue);
33644
- if (result.isError()) return ifNotFound;
33645
- return this._blankResultAsZero(result);
33966
+ return this._getLookupResult(value, lookupArray, resultArray, ifNotFound, matchModeValue, searchModeValue);
33646
33967
  });
33647
33968
  }
33648
33969
  const _lookupValue = lookupValue.isArray() ? lookupValue.get(0, 0) : lookupValue;
33649
- if (columnCountLookup === columnCountReturn && rowCountLookup === rowCountReturn) {
33650
- const checkErrorCombination = this._checkErrorCombination(matchModeValue, searchModeValue);
33651
- if (checkErrorCombination) return checkErrorCombination;
33652
- const result = this._handleSingleObject(_lookupValue, lookupArray, returnArray, matchModeValue, searchModeValue);
33653
- if (result.isError()) return ifNotFound;
33654
- return this._blankResultAsZero(result);
33655
- }
33970
+ if (columnCountLookup === columnCountReturn && rowCountLookup === rowCountReturn) return this._getLookupResult(_lookupValue, lookupArray, returnArray, ifNotFound, matchModeValue, searchModeValue);
33656
33971
  let axis = 0;
33657
33972
  /**
33658
33973
  * 0 for rows
33659
33974
  * 1 for columns
33660
33975
  */
33661
33976
  if (columnCountLookup === columnCountReturn) axis = 1;
33662
- const resultArray = this._handleExpandObject(_lookupValue, lookupArray, returnArray, matchModeValue, searchModeValue, axis);
33663
- if (resultArray == null) return ErrorValueObject.create("#N/A");
33664
- return resultArray;
33977
+ return this._getLookupResult(_lookupValue, lookupArray, returnArray, ifNotFound, matchModeValue, searchModeValue, axis);
33665
33978
  }
33666
33979
  _legacyImplicitLookupValue(lookupValue) {
33667
33980
  if (!lookupValue.isArray()) return lookupValue;
@@ -33689,35 +34002,37 @@ var Xlookup = class extends BaseFunction {
33689
34002
  if (rowIndex < 0 || rowIndex >= rowCount || columnIndex < 0 || columnIndex >= columnCount) return ErrorValueObject.create("#VALUE!");
33690
34003
  return array.get(rowIndex, columnIndex) || ErrorValueObject.create("#VALUE!");
33691
34004
  }
33692
- _handleExpandObject(value, searchArray, resultArray, matchModeValue, searchModeValue, axis = 0) {
34005
+ _getLookupResult(value, searchArray, resultArray, ifNotFound, matchModeValue, searchModeValue, axis) {
34006
+ if (value.isError()) return value;
34007
+ const checkErrorCombination = this._checkErrorCombination(matchModeValue, searchModeValue);
34008
+ if (checkErrorCombination) return checkErrorCombination;
34009
+ const position = this._findPosition(value, searchArray, matchModeValue, searchModeValue);
34010
+ if (position == null) return ifNotFound;
34011
+ if (axis === 0) return resultArray.slice([position.row, position.row + 1]) ?? ErrorValueObject.create("#N/A");
34012
+ if (axis === 1) return resultArray.slice(void 0, [position.column, position.column + 1]) ?? ErrorValueObject.create("#N/A");
34013
+ const result = resultArray.get(position.row, position.column) ?? NullValueObject.create();
34014
+ return this._blankResultAsZero(result);
34015
+ }
34016
+ _findPosition(value, searchArray, matchModeValue, searchModeValue) {
33693
34017
  if ((searchModeValue === 2 || searchModeValue === -2) && matchModeValue !== 2) {
33694
34018
  const searchType = getSearchModeValue(searchModeValue);
33695
34019
  const matchType = getMatchModeValue(matchModeValue);
33696
- return this.binarySearchExpand(value, searchArray, resultArray, axis, searchType, matchType);
34020
+ const rowOrColumn = searchArray.binarySearch(value, searchType, matchType);
34021
+ if (rowOrColumn == null) return null;
34022
+ return searchArray.getRowCount() === 1 ? {
34023
+ row: 0,
34024
+ column: rowOrColumn
34025
+ } : {
34026
+ row: rowOrColumn,
34027
+ column: 0
34028
+ };
33697
34029
  }
33698
- if (matchModeValue === 2) return this.fuzzySearchExpand(value, searchArray, resultArray, searchModeValue !== -1, axis);
33699
- if (matchModeValue === -1 || matchModeValue === 1) return this.orderSearchExpand(value, searchArray, resultArray, matchModeValue === 1 ? 2 : 1, searchModeValue === -1, axis, true);
33700
- return this._exactSearchExpand(value, searchArray, resultArray, searchModeValue !== -1, axis);
33701
- }
33702
- _handleSingleObject(value, searchArray, resultArray, matchModeValue, searchModeValue) {
33703
- if ((searchModeValue === 2 || searchModeValue === -2) && matchModeValue !== 2) {
33704
- const searchType = getSearchModeValue(searchModeValue);
33705
- const matchType = getMatchModeValue(matchModeValue);
33706
- return this.binarySearch(value, searchArray, resultArray, searchType, matchType);
34030
+ if (matchModeValue === 2) {
34031
+ const matches = searchArray.compare(value, "=");
34032
+ return searchModeValue === -1 ? matches.getLastTruePosition() : matches.getFirstTruePosition();
33707
34033
  }
33708
- if (matchModeValue === 2) return this.fuzzySearch(value, searchArray, resultArray, searchModeValue !== -1);
33709
- if (matchModeValue === -1 || matchModeValue === 1) return this.orderSearch(value, searchArray, resultArray, matchModeValue === 1 ? 2 : 1, searchModeValue === -1, true);
33710
- return this._exactSearch(value, searchArray, resultArray, searchModeValue !== -1);
33711
- }
33712
- _exactSearch(value, searchArray, resultArray, isFirst) {
33713
- const position = this._findExactPosition(value, searchArray, isFirst);
33714
- if (position == null) return ErrorValueObject.create("#N/A");
33715
- return resultArray.get(position.row, position.column) ?? ErrorValueObject.create("#N/A");
33716
- }
33717
- _exactSearchExpand(value, searchArray, resultArray, isFirst, axis) {
33718
- const position = this._findExactPosition(value, searchArray, isFirst);
33719
- if (position == null) return ErrorValueObject.create("#N/A");
33720
- return axis === 0 ? resultArray.slice([position.row, position.row + 1]) ?? ErrorValueObject.create("#N/A") : resultArray.slice(void 0, [position.column, position.column + 1]) ?? ErrorValueObject.create("#N/A");
34034
+ if (matchModeValue === -1 || matchModeValue === 1) return searchArray.orderSearch(value, matchModeValue === 1 ? 2 : 1, searchModeValue === -1, false, true);
34035
+ return this._findExactPosition(value, searchArray, searchModeValue !== -1);
33721
34036
  }
33722
34037
  _findExactPosition(value, searchArray, isFirst) {
33723
34038
  let position;
@@ -37176,7 +37491,7 @@ var Average = class extends BaseFunction {
37176
37491
  _legacyImplicitDerivedArray(variant) {
37177
37492
  if (!variant.isArray()) return variant;
37178
37493
  const array = variant;
37179
- if (array.usesInvertedIndexCache()) return variant;
37494
+ if (array.usesInvertedIndexCache() || !array.usesLegacyImplicitForAggregate()) return variant;
37180
37495
  const startRow = array.getCurrentRow();
37181
37496
  const startColumn = array.getCurrentColumn();
37182
37497
  if (startRow < 0 || startColumn < 0) return variant;
@@ -41795,7 +42110,7 @@ var Proper = class extends BaseFunction {
41795
42110
  }
41796
42111
  _handleSingleObject(text) {
41797
42112
  if (text.isError() || text.isNull() || text.isBoolean() || text.isNumber()) return text;
41798
- const result = text.getValue().toLocaleString().toLocaleLowerCase().replace(/(^|\b|\W|\d|_)[a-z]/g, (txt) => txt.toLocaleUpperCase());
42113
+ const result = text.getValue().toLocaleString().toLocaleLowerCase().replace(/(^|[^\p{L}])(\p{L})/gu, (_, before, letter) => before + letter.toLocaleUpperCase());
41799
42114
  return StringValueObject.create(result);
41800
42115
  }
41801
42116
  };
@@ -43744,7 +44059,7 @@ function getObjectValue(result, isUseStrip = false) {
43744
44059
  //#endregion
43745
44060
  //#region package.json
43746
44061
  var name = "@univerjs/engine-formula";
43747
- var version = "1.0.4";
44062
+ var version = "1.2.0";
43748
44063
 
43749
44064
  //#endregion
43750
44065
  //#region src/services/global-computing-status.service.ts
@@ -43830,6 +44145,7 @@ let FormulaCalculationTriggerService = class FormulaCalculationTriggerService ex
43830
44145
  _defineProperty(this, "_executionInProgress", false);
43831
44146
  _defineProperty(this, "_hasPendingCalculation", false);
43832
44147
  _defineProperty(this, "_stopRequested", false);
44148
+ _defineProperty(this, "_suppressed", false);
43833
44149
  this._registerGenericDirtyConversions();
43834
44150
  this._initialize();
43835
44151
  }
@@ -43838,6 +44154,16 @@ let FormulaCalculationTriggerService = class FormulaCalculationTriggerService ex
43838
44154
  this._started = true;
43839
44155
  this._scheduleFlush();
43840
44156
  }
44157
+ /** Snapshot reconstruction calculates these synchronous mutations in its isolated runtime. */
44158
+ runWithoutTriggering(operation) {
44159
+ const previous = this._suppressed;
44160
+ this._suppressed = true;
44161
+ try {
44162
+ return operation();
44163
+ } finally {
44164
+ this._suppressed = previous;
44165
+ }
44166
+ }
43841
44167
  dispose() {
43842
44168
  clearTimeout(this._timer);
43843
44169
  this._waitingCommandQueue = [];
@@ -43857,7 +44183,7 @@ let FormulaCalculationTriggerService = class FormulaCalculationTriggerService ex
43857
44183
  return;
43858
44184
  }
43859
44185
  const conversion = this._activeDirtyManagerService.get(command.id);
43860
- if (!conversion) return;
44186
+ if (!conversion || this._suppressed) return;
43861
44187
  if (((_conversion$shouldTri = conversion.shouldTrigger) === null || _conversion$shouldTri === void 0 ? void 0 : _conversion$shouldTri.call(conversion, command, options)) === false) return;
43862
44188
  this._waitingCommandQueue.push(command);
43863
44189
  this._scheduleFlush();
@@ -43946,6 +44272,8 @@ function mergeDirtyData(left, right) {
43946
44272
  return result;
43947
44273
  }
43948
44274
  function appendDirtyData(target, source, rangeKeys) {
44275
+ var _source$dirtyIteratio;
44276
+ if ((_source$dirtyIteratio = source.dirtyIterationUnits) === null || _source$dirtyIteratio === void 0 ? void 0 : _source$dirtyIteratio.length) target.dirtyIterationUnits = Array.from(/* @__PURE__ */ new Set([...target.dirtyIterationUnits ?? [], ...source.dirtyIterationUnits]));
43949
44277
  mergeDirtyRanges(target.dirtyRanges, source.dirtyRanges ?? [], rangeKeys);
43950
44278
  mergeDirtyUnitStringMap(target.dirtyNameMap, source.dirtyNameMap);
43951
44279
  mergeDirtyUnitStringMap(target.dirtyDefinedNameMap, source.dirtyDefinedNameMap);
@@ -43989,7 +44317,8 @@ function mergeDirtyUnitNestedMap(target, right) {
43989
44317
  });
43990
44318
  }
43991
44319
  function hasDirtyData(dirtyData) {
43992
- return dirtyData.forceCalculation || dirtyData.dirtyRanges.length > 0 || hasNestedValue(dirtyData.dirtyNameMap) || hasNestedValue(dirtyData.dirtyDefinedNameMap) || hasNestedValue(dirtyData.dirtySuperTableMap) || hasNestedValue(dirtyData.dirtyUnitFeatureMap) || hasNestedValue(dirtyData.dirtyUnitOtherFormulaMap) || hasNestedValue(dirtyData.clearDependencyTreeCache);
44320
+ var _dirtyData$dirtyItera;
44321
+ return dirtyData.forceCalculation || Boolean((_dirtyData$dirtyItera = dirtyData.dirtyIterationUnits) === null || _dirtyData$dirtyItera === void 0 ? void 0 : _dirtyData$dirtyItera.length) || dirtyData.dirtyRanges.length > 0 || hasNestedValue(dirtyData.dirtyNameMap) || hasNestedValue(dirtyData.dirtyDefinedNameMap) || hasNestedValue(dirtyData.dirtySuperTableMap) || hasNestedValue(dirtyData.dirtyUnitFeatureMap) || hasNestedValue(dirtyData.dirtyUnitOtherFormulaMap) || hasNestedValue(dirtyData.clearDependencyTreeCache);
43993
44322
  }
43994
44323
  function hasNestedValue(value) {
43995
44324
  if (value == null) return false;
@@ -43997,7 +44326,8 @@ function hasNestedValue(value) {
43997
44326
  return Object.values(value).some(hasNestedValue);
43998
44327
  }
43999
44328
  function dirtyDataIntersects(left, right) {
44000
- if (left.forceCalculation || right.forceCalculation) return true;
44329
+ var _left$dirtyIterationU, _right$dirtyIteration;
44330
+ if (left.forceCalculation || right.forceCalculation || ((_left$dirtyIterationU = left.dirtyIterationUnits) === null || _left$dirtyIterationU === void 0 ? void 0 : _left$dirtyIterationU.length) || ((_right$dirtyIteration = right.dirtyIterationUnits) === null || _right$dirtyIteration === void 0 ? void 0 : _right$dirtyIteration.length)) return true;
44001
44331
  if (left.dirtyRanges.some((leftRange) => right.dirtyRanges.some((rightRange) => leftRange.unitId === rightRange.unitId && leftRange.sheetId === rightRange.sheetId && Rectangle.intersects(leftRange.range, rightRange.range))) || clearedSheetIntersects(left, right) || clearedSheetIntersects(right, left)) return true;
44002
44332
  return [
44003
44333
  [left.dirtyNameMap, right.dirtyNameMap],
@@ -57446,4 +57776,8 @@ _defineProperty(UniverFormulaEnginePlugin, "version", version);
57446
57776
  UniverFormulaEnginePlugin = __decorate([__decorateParam(1, Inject(Injector)), __decorateParam(2, IConfigService)], UniverFormulaEnginePlugin);
57447
57777
 
57448
57778
  //#endregion
57449
- export { ALL_IMPLEMENTED_FUNCTIONS, ALL_IMPLEMENTED_FUNCTIONS_SET, ActiveDirtyManagerService, ArrayValueObject, AstRootNodeFactory, AstTreeBuilder, AsyncArrayObject, AsyncCustomFunction, AsyncObject, BaseFunction, BaseReferenceObject, BaseValueObject, BooleanValue, BooleanValueObject, CELL_INVERTED_INDEX_CACHE, CalculateController, CalculateFormulaService, CustomFunction, DEFAULT_CYCLE_REFERENCE_COUNT, DEFAULT_INTERVAL_COUNT, DEFAULT_TOKEN_LAMBDA_FUNCTION_NAME, DEFAULT_TOKEN_LET_FUNCTION_NAME, DEFAULT_TOKEN_TYPE_LAMBDA_PARAMETER, DEFAULT_TOKEN_TYPE_PARAMETER, DEFAULT_TOKEN_TYPE_ROOT, DefinedNamesService, DependencyManagerBaseService, DependencyManagerService, DescriptionService, ENGINE_FORMULA_CYCLE_REFERENCE_COUNT, ENGINE_FORMULA_PLUGIN_CONFIG_KEY, ENGINE_FORMULA_RETURN_DEPENDENCY_TREE, ERROR_TYPE_SET, ErrorType, ErrorValueObject, FORMULA_REF_TO_ARRAY_CACHE, FUNCTION_LIST, FUNCTION_LIST_ARRAY, FUNCTION_LIST_COMPATIBILITY, FUNCTION_LIST_CUBE, FUNCTION_LIST_DATABASE, FUNCTION_LIST_DATE, FUNCTION_LIST_ENGINEERING, FUNCTION_LIST_FINANCIAL, FUNCTION_LIST_INFORMATION, FUNCTION_LIST_LOGICAL, FUNCTION_LIST_LOOKUP, FUNCTION_LIST_MATH, FUNCTION_LIST_STATISTICAL, FUNCTION_LIST_TEXT, FUNCTION_LIST_UNIVER, FUNCTION_LIST_WEB, FUNCTION_NAMES_ARRAY, FUNCTION_NAMES_COMPATIBILITY, FUNCTION_NAMES_CUBE, FUNCTION_NAMES_DATABASE, FUNCTION_NAMES_DATE, FUNCTION_NAMES_ENGINEERING, FUNCTION_NAMES_FINANCIAL, FUNCTION_NAMES_INFORMATION, FUNCTION_NAMES_LOGICAL, FUNCTION_NAMES_LOOKUP, FUNCTION_NAMES_MATH, FUNCTION_NAMES_STATISTICAL, FUNCTION_NAMES_TEXT, FUNCTION_NAMES_UNIVER, FUNCTION_NAMES_WEB, FeatureCalculationManagerService, FormulaCalculationSessionController, FormulaCalculationSessionService, FormulaCalculationTriggerService, FormulaCurrentConfigService, FormulaDataModel, FormulaDependencyGenerator, FormulaDependencyTree, FormulaDependencyTreeModel, FormulaDependencyTreeType, FormulaDependencyTreeVirtual, FormulaExecuteStageType, FormulaExecutedStateType, FormulaResultApplicationType, FormulaResultStatus, FormulaRuntimeService, FormulaUnitReferenceResolver, FunctionNodeFactory, FunctionService, FunctionType, GlobalComputingStatusService, HyperlinkEngineFormulaService, IActiveDirtyManagerService, ICalculateFormulaService, IDefinedNamesService, IDependencyManagerService, IDescriptionService, IFeatureCalculationManagerService, IFormulaCurrentConfigService, IFormulaDependencyGenerator, IFormulaExternalReferenceDataLoader, IFormulaRuntimeService, IFormulaUnitReferenceResolver, IFunctionService, IHyperlinkEngineFormulaService, IOtherFormulaManagerService, IRegisterFunctionService, ISheetRowFilteredService, ISuperTableService, Interpreter, LambdaNodeFactory, LambdaParameterNodeFactory, LambdaValueObjectObject, Lexer, LexerNode, LexerTreeBuilder, NEW_EXCEL_FUNCTIONS, NoopFormulaExternalReferenceDataLoader, NullValueObject, NumberValueObject, OPERATOR_TOKEN_SET, OperatorNodeFactory, OtherFormulaBizType, OtherFormulaManagerService, OtherFormulaMarkDirty, PrefixNodeFactory, RangeReferenceObject, ReferenceNodeFactory, RegisterFunctionMutation, RegisterFunctionService, RegisterOtherFormulaService, RemoveDefinedNameMutation, RemoveFeatureCalculationMutation, RemoveOtherFormulaMutation, RemoveSuperTableMutation, SUFFIX_TOKEN_SET, SetArrayFormulaDataMutation, SetCellFormulaDependencyCalculationMutation, SetCellFormulaDependencyCalculationResultMutation, SetDefinedNameMutation, SetDefinedNameMutationFactory, SetFeatureCalculationMutation, SetFormulaCalculationNotificationMutation, SetFormulaCalculationResultMutation, SetFormulaCalculationStartMutation, SetFormulaCalculationStopMutation, SetFormulaDataMutation, SetFormulaDependencyCalculationMutation, SetFormulaDependencyCalculationResultMutation, SetFormulaStringBatchCalculationMutation, SetFormulaStringBatchCalculationResultMutation, SetImageFormulaDataMutation, SetOtherFormulaMutation, SetQueryFormulaDependencyAllMutation, SetQueryFormulaDependencyAllResultMutation, SetQueryFormulaDependencyMutation, SetQueryFormulaDependencyResultMutation, SetSuperTableMutation, SetSuperTableOptionMutation, SetTriggerFormulaCalculationStartMutation, SheetRowFilteredService, StringValueObject, SuffixNodeFactory, SuperTableActiveDirtyController, SuperTableService, UnionNodeFactory, UniverFormulaEnginePlugin, ValueNodeFactory, ValueObjectFactory, buildFormulaTextRuns, compareToken, convertUnitDataToRuntime, deserializeRangeForR1C1, deserializeRangeWithSheet, deserializeRangeWithSheetWithCache, extractFormulaError, findFormulaStructuredReferences, functionArray, functionCompatibility, functionCube, functionDatabase, functionDate, functionEngineering, functionFinancial, functionInformation, functionLogical, functionLookup, functionMath, functionMeta, functionStatistical, functionText, functionUniver, functionWeb, generateAstNode, generateExecuteAstNodeData, generateParam, generateRandomDependencyTreeId, generateStringWithSequence, getAbsoluteRefTypeWitString, getAbsoluteRefTypeWithSingleString, getFormulaHighlightDataStream, getFormulaReferenceIndex, getFormulaReplaceResult, getFormulaSequenceCharacterAtOffset, getFormulaSequenceNodeIndex, getFunctionName, getObjectValue, getRangeWithRefsString, handleNumfmtInCell, handleRefStringInfo, includeFormulaLexerToken, isFormulaLexerToken, isFormulaReferenceAddingContext, isFormulaReferenceAddingTextContext, isInDirtyRange, isReferenceString, isReferenceStringWithEffectiveColumn, isReferenceStrings, matchRefDrawToken, matchToken, needsQuoting, normalizeFormulaUnitName, normalizeSheetName, operatorToken, prefixToken, quoteSheetName, refactorFormulaUnitQualifier, resolveFormulaReferenceEditingContext, searchFormulaFunctions, sequenceNodeType, serializeRange, serializeRangeToRefString, serializeRangeWithSheet, serializeRangeWithSpreadsheet, singleReferenceToGrid, splitTableStructuredRef, strip, stripErrorMargin, unquoteSheetName };
57779
+ //#region src/services/formula-changeset-calculation.service.ts
57780
+ const IFormulaChangesetCalculationService = createIdentifier("engine-formula.changeset-calculation.service");
57781
+
57782
+ //#endregion
57783
+ export { ALL_IMPLEMENTED_FUNCTIONS, ALL_IMPLEMENTED_FUNCTIONS_SET, ActiveDirtyManagerService, ArrayValueObject, AstRootNodeFactory, AstTreeBuilder, AsyncArrayObject, AsyncCustomFunction, AsyncObject, BaseFunction, BaseReferenceObject, BaseValueObject, BooleanValue, BooleanValueObject, CELL_INVERTED_INDEX_CACHE, CalculateController, CalculateFormulaService, CustomFunction, DEFAULT_INTERVAL_COUNT, DEFAULT_TOKEN_LAMBDA_FUNCTION_NAME, DEFAULT_TOKEN_LET_FUNCTION_NAME, DEFAULT_TOKEN_TYPE_LAMBDA_PARAMETER, DEFAULT_TOKEN_TYPE_PARAMETER, DEFAULT_TOKEN_TYPE_ROOT, DefinedNamesService, DependencyManagerBaseService, DependencyManagerService, DescriptionService, ENGINE_FORMULA_PLUGIN_CONFIG_KEY, ENGINE_FORMULA_RETURN_DEPENDENCY_TREE, ERROR_TYPE_SET, ErrorType, ErrorValueObject, FORMULA_REF_TO_ARRAY_CACHE, FUNCTION_LIST, FUNCTION_LIST_ARRAY, FUNCTION_LIST_COMPATIBILITY, FUNCTION_LIST_CUBE, FUNCTION_LIST_DATABASE, FUNCTION_LIST_DATE, FUNCTION_LIST_ENGINEERING, FUNCTION_LIST_FINANCIAL, FUNCTION_LIST_INFORMATION, FUNCTION_LIST_LOGICAL, FUNCTION_LIST_LOOKUP, FUNCTION_LIST_MATH, FUNCTION_LIST_STATISTICAL, FUNCTION_LIST_TEXT, FUNCTION_LIST_UNIVER, FUNCTION_LIST_WEB, FUNCTION_NAMES_ARRAY, FUNCTION_NAMES_COMPATIBILITY, FUNCTION_NAMES_CUBE, FUNCTION_NAMES_DATABASE, FUNCTION_NAMES_DATE, FUNCTION_NAMES_ENGINEERING, FUNCTION_NAMES_FINANCIAL, FUNCTION_NAMES_INFORMATION, FUNCTION_NAMES_LOGICAL, FUNCTION_NAMES_LOOKUP, FUNCTION_NAMES_MATH, FUNCTION_NAMES_STATISTICAL, FUNCTION_NAMES_TEXT, FUNCTION_NAMES_UNIVER, FUNCTION_NAMES_WEB, FeatureCalculationManagerService, FormulaCalculationSessionController, FormulaCalculationSessionService, FormulaCalculationTriggerService, FormulaCurrentConfigService, FormulaDataModel, FormulaDependencyGenerator, FormulaDependencyTree, FormulaDependencyTreeModel, FormulaDependencyTreeType, FormulaDependencyTreeVirtual, FormulaExecuteStageType, FormulaExecutedStateType, FormulaResultApplicationType, FormulaResultStatus, FormulaRuntimeService, FormulaUnitReferenceResolver, FunctionNodeFactory, FunctionService, FunctionType, GlobalComputingStatusService, HyperlinkEngineFormulaService, IActiveDirtyManagerService, ICalculateFormulaService, IDefinedNamesService, IDependencyManagerService, IDescriptionService, IFeatureCalculationManagerService, IFormulaChangesetCalculationService, IFormulaCurrentConfigService, IFormulaDependencyGenerator, IFormulaExternalReferenceDataLoader, IFormulaRuntimeService, IFormulaUnitReferenceResolver, IFunctionService, IHyperlinkEngineFormulaService, IOtherFormulaManagerService, IRegisterFunctionService, ISheetRowFilteredService, ISuperTableService, Interpreter, LambdaNodeFactory, LambdaParameterNodeFactory, LambdaValueObjectObject, Lexer, LexerNode, LexerTreeBuilder, NEW_EXCEL_FUNCTIONS, NoopFormulaExternalReferenceDataLoader, NullValueObject, NumberValueObject, OPERATOR_TOKEN_SET, OperatorNodeFactory, OtherFormulaBizType, OtherFormulaManagerService, OtherFormulaMarkDirty, PrefixNodeFactory, RangeReferenceObject, ReferenceNodeFactory, RegisterFunctionMutation, RegisterFunctionService, RegisterOtherFormulaService, RemoveDefinedNameMutation, RemoveFeatureCalculationMutation, RemoveOtherFormulaMutation, RemoveSuperTableMutation, SUFFIX_TOKEN_SET, SetArrayFormulaDataMutation, SetCellFormulaDependencyCalculationMutation, SetCellFormulaDependencyCalculationResultMutation, SetDefinedNameMutation, SetDefinedNameMutationFactory, SetFeatureCalculationMutation, SetFormulaCalculationNotificationMutation, SetFormulaCalculationResultMutation, SetFormulaCalculationStartMutation, SetFormulaCalculationStopMutation, SetFormulaDataMutation, SetFormulaDependencyCalculationMutation, SetFormulaDependencyCalculationResultMutation, SetFormulaStringBatchCalculationMutation, SetFormulaStringBatchCalculationResultMutation, SetImageFormulaDataMutation, SetOtherFormulaMutation, SetQueryFormulaDependencyAllMutation, SetQueryFormulaDependencyAllResultMutation, SetQueryFormulaDependencyMutation, SetQueryFormulaDependencyResultMutation, SetSuperTableMutation, SetSuperTableOptionMutation, SetTriggerFormulaCalculationStartMutation, SheetRowFilteredService, StringValueObject, SuffixNodeFactory, SuperTableActiveDirtyController, SuperTableService, UnionNodeFactory, UniverFormulaEnginePlugin, ValueNodeFactory, ValueObjectFactory, buildFormulaTextRuns, compareToken, convertUnitDataToRuntime, deserializeRangeForR1C1, deserializeRangeWithSheet, deserializeRangeWithSheetWithCache, extractFormulaError, findFormulaStructuredReferences, functionArray, functionCompatibility, functionCube, functionDatabase, functionDate, functionEngineering, functionFinancial, functionInformation, functionLogical, functionLookup, functionMath, functionMeta, functionStatistical, functionText, functionUniver, functionWeb, generateAstNode, generateExecuteAstNodeData, generateParam, generateRandomDependencyTreeId, generateStringWithSequence, getAbsoluteRefTypeWitString, getAbsoluteRefTypeWithSingleString, getFormulaHighlightDataStream, getFormulaReferenceIndex, getFormulaReplaceResult, getFormulaSequenceCharacterAtOffset, getFormulaSequenceNodeIndex, getFunctionName, getObjectValue, getRangeWithRefsString, handleNumfmtInCell, handleRefStringInfo, includeFormulaLexerToken, isFormulaLexerToken, isFormulaReferenceAddingContext, isFormulaReferenceAddingTextContext, isInDirtyRange, isReferenceString, isReferenceStringWithEffectiveColumn, isReferenceStrings, matchRefDrawToken, matchToken, mergeDirtyData, needsQuoting, normalizeFormulaUnitName, normalizeSheetName, operatorToken, prefixToken, quoteSheetName, refactorFormulaUnitQualifier, resolveFormulaReferenceEditingContext, searchFormulaFunctions, sequenceNodeType, serializeRange, serializeRangeToRefString, serializeRangeWithSheet, serializeRangeWithSpreadsheet, singleReferenceToGrid, splitTableStructuredRef, strip, stripErrorMargin, unquoteSheetName };