@pixerate/editor 0.24.0 → 0.25.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 (133) hide show
  1. package/README.md +71 -1
  2. package/THIRD_PARTY_NOTICES.md +29 -0
  3. package/dist/agent/index.cjs +10 -9
  4. package/dist/agent/index.cjs.map +1 -1
  5. package/dist/agent/index.d.cts +1 -1
  6. package/dist/agent/index.d.ts +1 -1
  7. package/dist/agent/index.js +4 -3
  8. package/dist/agent/index.js.map +1 -1
  9. package/dist/canvas/index.cjs +3173 -340
  10. package/dist/canvas/index.cjs.map +1 -1
  11. package/dist/canvas/index.d.cts +617 -4
  12. package/dist/canvas/index.d.ts +617 -4
  13. package/dist/canvas/index.js +3105 -272
  14. package/dist/canvas/index.js.map +1 -1
  15. package/dist/chunk-4BVP64JJ.cjs +1406 -0
  16. package/dist/chunk-4BVP64JJ.cjs.map +1 -0
  17. package/dist/{chunk-XNORY7M6.cjs → chunk-7WISYZFO.cjs} +105 -50
  18. package/dist/chunk-7WISYZFO.cjs.map +1 -0
  19. package/dist/{chunk-OLZJXL4R.cjs → chunk-AL6JMGWW.cjs} +59 -25
  20. package/dist/chunk-AL6JMGWW.cjs.map +1 -0
  21. package/dist/chunk-BVP3TSLH.cjs +69 -0
  22. package/dist/chunk-BVP3TSLH.cjs.map +1 -0
  23. package/dist/{chunk-MCSJFWAO.cjs → chunk-C7P22VIP.cjs} +670 -96
  24. package/dist/chunk-C7P22VIP.cjs.map +1 -0
  25. package/dist/{chunk-PGNZKFQS.js → chunk-ECCCYKGL.js} +76 -21
  26. package/dist/chunk-ECCCYKGL.js.map +1 -0
  27. package/dist/{chunk-3CN2WD3X.js → chunk-FH6F67DN.js} +646 -72
  28. package/dist/chunk-FH6F67DN.js.map +1 -0
  29. package/dist/chunk-HRMEDT2L.js +1406 -0
  30. package/dist/chunk-HRMEDT2L.js.map +1 -0
  31. package/dist/{chunk-ITBSKI26.js → chunk-IXHSYOVY.js} +941 -9
  32. package/dist/chunk-IXHSYOVY.js.map +1 -0
  33. package/dist/{chunk-FODNLX5N.js → chunk-NAXVVS5I.js} +38 -4
  34. package/dist/chunk-NAXVVS5I.js.map +1 -0
  35. package/dist/chunk-O5RYH2PG.js +69 -0
  36. package/dist/chunk-O5RYH2PG.js.map +1 -0
  37. package/dist/{chunk-SBCZ6RN5.cjs → chunk-PO6A6QQH.cjs} +1039 -107
  38. package/dist/chunk-PO6A6QQH.cjs.map +1 -0
  39. package/dist/{chunk-3LV6RRPH.js → chunk-QGYDWPRM.js} +2 -2
  40. package/dist/{chunk-U5KWZU4X.js → chunk-RR7F5GUM.js} +2632 -129
  41. package/dist/chunk-RR7F5GUM.js.map +1 -0
  42. package/dist/{chunk-5S3Z4PPF.js → chunk-UAKDG62Z.js} +232 -25
  43. package/dist/chunk-UAKDG62Z.js.map +1 -0
  44. package/dist/{chunk-SML64VJG.cjs → chunk-V3CHHWOE.cjs} +4 -4
  45. package/dist/{chunk-SML64VJG.cjs.map → chunk-V3CHHWOE.cjs.map} +1 -1
  46. package/dist/chunk-WSQKHXW7.cjs +5726 -0
  47. package/dist/chunk-WSQKHXW7.cjs.map +1 -0
  48. package/dist/{chunk-D27YFC46.cjs → chunk-X4N4WUKB.cjs} +267 -60
  49. package/dist/chunk-X4N4WUKB.cjs.map +1 -0
  50. package/dist/commands/index.cjs +74 -1
  51. package/dist/commands/index.cjs.map +1 -1
  52. package/dist/commands/index.d.cts +34 -1
  53. package/dist/commands/index.d.ts +34 -1
  54. package/dist/commands/index.js +73 -0
  55. package/dist/commands/index.js.map +1 -1
  56. package/dist/compare/index.cjs +3 -3
  57. package/dist/compare/index.d.cts +1 -1
  58. package/dist/compare/index.d.ts +1 -1
  59. package/dist/compare/index.js +2 -2
  60. package/dist/controller-BIJiNoVs.d.cts +1842 -0
  61. package/dist/controller-BIJiNoVs.d.ts +1842 -0
  62. package/dist/{documents-BQjzJNe2.d.ts → documents-CHT1U5Vs.d.ts} +10 -0
  63. package/dist/{documents-KRTPhvst.d.cts → documents-Gp7wb0Me.d.cts} +10 -0
  64. package/dist/extensions/index.cjs +53 -6
  65. package/dist/extensions/index.cjs.map +1 -1
  66. package/dist/extensions/index.d.cts +12 -4
  67. package/dist/extensions/index.d.ts +12 -4
  68. package/dist/extensions/index.js +53 -6
  69. package/dist/generation/index.cjs +1013 -69
  70. package/dist/generation/index.cjs.map +1 -1
  71. package/dist/generation/index.d.cts +474 -13
  72. package/dist/generation/index.d.ts +474 -13
  73. package/dist/generation/index.js +976 -32
  74. package/dist/generation/index.js.map +1 -1
  75. package/dist/image-editor/index.cjs +3385 -1275
  76. package/dist/image-editor/index.cjs.map +1 -1
  77. package/dist/image-editor/index.d.cts +693 -128
  78. package/dist/image-editor/index.d.ts +693 -128
  79. package/dist/image-editor/index.js +3325 -1215
  80. package/dist/image-editor/index.js.map +1 -1
  81. package/dist/{index-fJrlkJCd.d.ts → index-7a6bHTLy.d.ts} +494 -5
  82. package/dist/{index-BhJBSm2d.d.cts → index-Csd5qI8u.d.cts} +494 -5
  83. package/dist/index.cjs +1491 -45
  84. package/dist/index.cjs.map +1 -1
  85. package/dist/index.d.cts +110 -19
  86. package/dist/index.d.ts +110 -19
  87. package/dist/index.js +1464 -18
  88. package/dist/index.js.map +1 -1
  89. package/dist/mention-text-CDnCFd3c.d.cts +53 -0
  90. package/dist/mention-text-CDnCFd3c.d.ts +53 -0
  91. package/dist/model-C1zApQM8.d.cts +219 -0
  92. package/dist/model-C1zApQM8.d.ts +219 -0
  93. package/dist/persistence/index.d.cts +3 -120
  94. package/dist/persistence/index.d.ts +3 -120
  95. package/dist/{registry-GJI4gToU.d.cts → registry-CEgwXED1.d.cts} +12 -1
  96. package/dist/{registry-GJI4gToU.d.ts → registry-CEgwXED1.d.ts} +12 -1
  97. package/dist/serializers/index.cjs +12 -4
  98. package/dist/serializers/index.cjs.map +1 -1
  99. package/dist/serializers/index.d.cts +39 -12
  100. package/dist/serializers/index.d.ts +39 -12
  101. package/dist/serializers/index.js +12 -4
  102. package/dist/spreadsheet/index.cjs +127 -3
  103. package/dist/spreadsheet/index.cjs.map +1 -1
  104. package/dist/spreadsheet/index.d.cts +431 -11
  105. package/dist/spreadsheet/index.d.ts +431 -11
  106. package/dist/spreadsheet/index.js +127 -3
  107. package/dist/storage-BpFfspHm.d.cts +120 -0
  108. package/dist/storage-BpFfspHm.d.ts +120 -0
  109. package/dist/tokens/index.cjs +115 -0
  110. package/dist/tokens/index.cjs.map +1 -0
  111. package/dist/tokens/index.d.cts +212 -0
  112. package/dist/tokens/index.d.ts +212 -0
  113. package/dist/tokens/index.js +115 -0
  114. package/dist/tokens/index.js.map +1 -0
  115. package/dist/{track-changes-BK5sVf4_.d.cts → track-changes-D_VAPELi.d.cts} +95 -11
  116. package/dist/{track-changes-CDjCrwKe.d.ts → track-changes-Db_fGEvx.d.ts} +95 -11
  117. package/package.json +6 -1
  118. package/dist/chunk-3CN2WD3X.js.map +0 -1
  119. package/dist/chunk-5S3Z4PPF.js.map +0 -1
  120. package/dist/chunk-D27YFC46.cjs.map +0 -1
  121. package/dist/chunk-FODNLX5N.js.map +0 -1
  122. package/dist/chunk-ITBSKI26.js.map +0 -1
  123. package/dist/chunk-MA2F5KHF.cjs +0 -3223
  124. package/dist/chunk-MA2F5KHF.cjs.map +0 -1
  125. package/dist/chunk-MCSJFWAO.cjs.map +0 -1
  126. package/dist/chunk-OLZJXL4R.cjs.map +0 -1
  127. package/dist/chunk-PGNZKFQS.js.map +0 -1
  128. package/dist/chunk-SBCZ6RN5.cjs.map +0 -1
  129. package/dist/chunk-U5KWZU4X.js.map +0 -1
  130. package/dist/chunk-XNORY7M6.cjs.map +0 -1
  131. package/dist/controller-BhLLAoi8.d.cts +0 -1000
  132. package/dist/controller-BhLLAoi8.d.ts +0 -1000
  133. /package/dist/{chunk-3LV6RRPH.js.map → chunk-QGYDWPRM.js.map} +0 -0
@@ -0,0 +1,1842 @@
1
+ /**
2
+ * Conditional formatting rule model.
3
+ *
4
+ * Portions ported from gridcraft/crates/model/src/features.rs (MIT OR
5
+ * Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.
6
+ */
7
+
8
+ /** Comparison of a cell value with one value (or two for `between` / `notBetween`). */
9
+ type ConditionalFormatOperator = 'between' | 'notBetween' | 'equal' | 'notEqual' | 'greaterThan' | 'lessThan' | 'greaterThanOrEqual' | 'lessThanOrEqual';
10
+ /**
11
+ * The look a matching rule adds to a cell. Colours are CSS colours, ideally
12
+ * `#rrggbb`. Only the parts that are set apply, so several rules can combine
13
+ * (a fill from one, bold from another).
14
+ */
15
+ interface ConditionalFormatStyle {
16
+ fill?: string;
17
+ color?: string;
18
+ bold?: boolean;
19
+ italic?: boolean;
20
+ underline?: boolean;
21
+ strikethrough?: boolean;
22
+ }
23
+ /**
24
+ * An anchor of a colour scale, data bar or icon set: the lowest / highest
25
+ * number in the range, a fixed number, a percent of the min..max span, a
26
+ * percentile of the values, or a formula (written for the range's top-left
27
+ * cell, like formula rules).
28
+ */
29
+ type ConditionalFormatValue = {
30
+ type: 'min';
31
+ } | {
32
+ type: 'max';
33
+ } | {
34
+ type: 'number';
35
+ value: number;
36
+ } | {
37
+ type: 'percent';
38
+ value: number;
39
+ } | {
40
+ type: 'percentile';
41
+ value: number;
42
+ } | {
43
+ type: 'formula';
44
+ formula: string;
45
+ };
46
+ /** `dates occurring` periods (weeks start on Sunday, as in Excel's US locale). */
47
+ type ConditionalFormatTimePeriod = 'yesterday' | 'today' | 'tomorrow' | 'last7Days' | 'lastWeek' | 'thisWeek' | 'nextWeek' | 'lastMonth' | 'thisMonth' | 'nextMonth';
48
+ /** Built-in icon sets (the number of icons is the leading digit). */
49
+ type ConditionalFormatIconSet = '3Arrows' | '3ArrowsGray' | '3TrafficLights1' | '3Flags' | '3Symbols' | '3Stars' | '4Arrows' | '4Rating' | '4TrafficLights' | '5Arrows' | '5Rating' | '5Quarters';
50
+ /** The condition of a rule: what it checks and the look it gives. */
51
+ type ConditionalFormatCondition = {
52
+ /**
53
+ * Cell value compared with `value` (and `value2` for between). A value
54
+ * starting with `=` is a formula, relative to the range's top-left
55
+ * cell; anything else is typed input (`10`, `5%`, `3/4/2026`, `Done`).
56
+ */
57
+ type: 'cellIs';
58
+ operator: ConditionalFormatOperator;
59
+ value: string;
60
+ value2?: string;
61
+ style: ConditionalFormatStyle;
62
+ } | {
63
+ /** A formula written for the range's top-left cell: `=$B2>100` formats whole rows. */
64
+ type: 'expression';
65
+ formula: string;
66
+ style: ConditionalFormatStyle;
67
+ } | {
68
+ /** Case-insensitive text tests on the cell's value as text. */
69
+ type: 'containsText' | 'notContainsText' | 'beginsWith' | 'endsWith';
70
+ text: string;
71
+ style: ConditionalFormatStyle;
72
+ } | {
73
+ type: 'blanks' | 'noBlanks' | 'errors' | 'noErrors' | 'duplicate' | 'unique';
74
+ style: ConditionalFormatStyle;
75
+ } | {
76
+ /** Top/bottom `rank` values, or `rank` percent of them. */
77
+ type: 'top10';
78
+ bottom?: boolean;
79
+ percent?: boolean;
80
+ rank: number;
81
+ style: ConditionalFormatStyle;
82
+ } | {
83
+ /** Above (or below) the average, optionally by `stdDev` standard deviations. */
84
+ type: 'aboveAverage';
85
+ below?: boolean;
86
+ equal?: boolean;
87
+ stdDev?: number;
88
+ style: ConditionalFormatStyle;
89
+ } | {
90
+ type: 'timePeriod';
91
+ period: ConditionalFormatTimePeriod;
92
+ style: ConditionalFormatStyle;
93
+ } | {
94
+ /** Two or three stops (low, [mid,] high) with colours; the fill blends between them. */
95
+ type: 'colorScale';
96
+ stops: Array<{
97
+ value: ConditionalFormatValue;
98
+ color: string;
99
+ }>;
100
+ } | {
101
+ type: 'dataBar';
102
+ min?: ConditionalFormatValue;
103
+ max?: ConditionalFormatValue;
104
+ color?: string;
105
+ gradient?: boolean;
106
+ showValue?: boolean;
107
+ } | {
108
+ type: 'iconSet';
109
+ set?: ConditionalFormatIconSet;
110
+ /**
111
+ * One threshold per icon, the first being the lower bound (as in
112
+ * files), or one fewer (the lower bound left out). Default: even
113
+ * percent steps (0, 33, 67 for three icons).
114
+ */
115
+ thresholds?: ConditionalFormatValue[];
116
+ reverse?: boolean;
117
+ showValue?: boolean;
118
+ };
119
+ type ConditionalFormatType = ConditionalFormatCondition['type'];
120
+ /**
121
+ * A conditional format: a condition applied to one or more ranges. Rules
122
+ * are kept in priority order (the first rule has the highest priority).
123
+ * Ranges are 0-based and belong to the sheet that stores the rule.
124
+ */
125
+ type ConditionalFormatRule = ConditionalFormatCondition & {
126
+ id: string;
127
+ ranges: CellRange[];
128
+ /** When this rule matches a cell, lower-priority rules are not applied to it. */
129
+ stopIfTrue?: boolean;
130
+ };
131
+ /** A rule to add: the id is generated when left out. */
132
+ type NewConditionalFormatRule = ConditionalFormatCondition & {
133
+ id?: string;
134
+ ranges: CellRange[];
135
+ stopIfTrue?: boolean;
136
+ };
137
+ /** The conditional look of one cell, combined from every rule that applies. */
138
+ interface ConditionalCellFormat {
139
+ fill?: string;
140
+ color?: string;
141
+ bold?: boolean;
142
+ italic?: boolean;
143
+ underline?: boolean;
144
+ strikethrough?: boolean;
145
+ /** Data bar: `fraction` (0..1) of the cell width. */
146
+ dataBar?: {
147
+ fraction: number;
148
+ color: string;
149
+ gradient: boolean;
150
+ };
151
+ /** Icon of an icon set: `index` 0 is the lowest icon; `id` is `"<set>:<index>"`. */
152
+ icon?: {
153
+ set: ConditionalFormatIconSet;
154
+ index: number;
155
+ id: string;
156
+ };
157
+ /** A data bar or icon set with `showValue: false`: show the bar / icon only. */
158
+ hideValue?: boolean;
159
+ }
160
+ /** Per-cell results of evaluating the conditional formats of a sheet. */
161
+ interface ConditionalFormatOverlay {
162
+ /** The conditional look of (row, col), or undefined when no rule applies. */
163
+ get(row: number, col: number): ConditionalCellFormat | undefined;
164
+ /** Number of cells with a conditional look. */
165
+ readonly size: number;
166
+ /** Every formatted cell. */
167
+ entries(): IterableIterator<[{
168
+ row: number;
169
+ col: number;
170
+ }, ConditionalCellFormat]>;
171
+ }
172
+ /** What evaluation needs to know about a sheet. Rows and columns are 0-based. */
173
+ interface ConditionalFormatSheet {
174
+ rowCount: number;
175
+ colCount: number;
176
+ /** The cell's value: number, text (dates are ISO text), boolean, error code or ''. */
177
+ getValue(row: number, col: number): unknown;
178
+ /**
179
+ * Evaluates a formula (with a leading `=`) as if it were in (row, col).
180
+ * Without it, formula rules never match and formula anchors count as 0.
181
+ */
182
+ evaluateFormula?(formula: string, row: number, col: number): unknown;
183
+ /** The current date, for `timePeriod` rules (default: now). */
184
+ today?(): Date;
185
+ }
186
+
187
+ /**
188
+ * Data validation rule model.
189
+ *
190
+ * Portions ported from gridcraft/crates/model/src/features.rs (MIT OR
191
+ * Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.
192
+ */
193
+
194
+ /** What a validated cell may hold. `any` only shows the input message. */
195
+ type DataValidationType = 'any' | 'whole' | 'decimal' | 'list' | 'date' | 'time' | 'textLength' | 'custom';
196
+ type DataValidationOperator = 'between' | 'notBetween' | 'equal' | 'notEqual' | 'greaterThan' | 'lessThan' | 'greaterThanOrEqual' | 'lessThanOrEqual';
197
+ /**
198
+ * How invalid input is handled: `stop` rejects it; `warning` asks whether to
199
+ * keep it (Yes keeps, No returns to editing, Cancel discards); `information`
200
+ * tells and keeps it unless cancelled.
201
+ */
202
+ type DataValidationErrorStyle = 'stop' | 'warning' | 'information';
203
+ interface DataValidationRule {
204
+ id: string;
205
+ /** Cells the rule applies to (0-based, on the sheet that stores the rule). */
206
+ ranges: CellRange[];
207
+ type: DataValidationType;
208
+ /** For whole, decimal, date, time and text length (default `between`). */
209
+ operator?: DataValidationOperator;
210
+ /**
211
+ * First value: a number, date (`2026-01-31`, `1/31/2026`), time (`9:00`)
212
+ * or a formula (`=B1`, relative to the range's top-left cell). For `list`,
213
+ * comma-separated items (`Low,Medium,High`) or a range / formula
214
+ * (`=$H$1:$H$5`). For `custom`, a formula that must be TRUE; it sees the
215
+ * value being entered.
216
+ */
217
+ formula1?: string;
218
+ /** Second value, for `between` / `notBetween`. */
219
+ formula2?: string;
220
+ /** Blank input is always valid (default true). */
221
+ ignoreBlank?: boolean;
222
+ /** Show a dropdown arrow on list cells (default true). */
223
+ inCellDropdown?: boolean;
224
+ inputTitle?: string;
225
+ /** Shown while a cell of the rule is selected. */
226
+ inputMessage?: string;
227
+ /** Default true. */
228
+ showInputMessage?: boolean;
229
+ errorTitle?: string;
230
+ errorMessage?: string;
231
+ /** Default `stop`. */
232
+ errorStyle?: DataValidationErrorStyle;
233
+ /** When false, any input is accepted (the rule still drives dropdowns and circles). Default true. */
234
+ showErrorAlert?: boolean;
235
+ }
236
+ /** A rule to add: the id is generated when left out. */
237
+ type NewDataValidationRule = Omit<DataValidationRule, 'id'> & {
238
+ id?: string;
239
+ };
240
+ /** The outcome of checking input against a cell's validation. */
241
+ interface DataValidationResult {
242
+ valid: boolean;
243
+ /** The rule that applied, if any. */
244
+ rule?: DataValidationRule;
245
+ /** For invalid input: how to alert. */
246
+ errorStyle?: DataValidationErrorStyle;
247
+ /** Alert title and message (defaults filled in). */
248
+ title?: string;
249
+ message?: string;
250
+ }
251
+ /** What validation needs to know about a sheet. Rows and columns are 0-based. */
252
+ interface DataValidationSheet {
253
+ rowCount: number;
254
+ colCount: number;
255
+ getValue(row: number, col: number): unknown;
256
+ /** Typed input of a cell (`raw`), used by `findInvalidCells`. Formulas are checked through their value. */
257
+ getInput?(row: number, col: number): string;
258
+ /**
259
+ * Evaluates a formula (with a leading `=`) as if it were in (row, col).
260
+ * `entered`, when given, is the value being typed into that cell: the
261
+ * formula must see it instead of the cell's current value.
262
+ */
263
+ evaluateFormula?(formula: string, row: number, col: number, entered?: {
264
+ row: number;
265
+ col: number;
266
+ value: unknown;
267
+ }): unknown;
268
+ }
269
+
270
+ type CellFormat = 'text' | 'number' | 'currency' | 'percentage' | 'date' | 'badge' | 'status' | 'assignee';
271
+ type ColumnType = 'bound' | 'freeform' | 'formula';
272
+ interface ColumnBinding {
273
+ dataSource: string;
274
+ field: string;
275
+ }
276
+ interface SpreadsheetColumn {
277
+ id: string;
278
+ key: string;
279
+ title: string;
280
+ width?: number;
281
+ type: ColumnType;
282
+ binding?: ColumnBinding;
283
+ formula?: string;
284
+ format?: CellFormat;
285
+ /**
286
+ * Number format code for the column's cells (e.g. `#,##0.00`,
287
+ * `"$"#,##0.00;[Red]("$"#,##0.00)`, `m/d/yyyy`). Cells without an explicit
288
+ * code of their own use it instead of the automatic one chosen for typed
289
+ * input. See `SpreadsheetController.setColumnNumberFormat`.
290
+ */
291
+ numberFormat?: string;
292
+ readOnly?: boolean;
293
+ hidden?: boolean;
294
+ }
295
+ type RowType = 'record' | 'freeform';
296
+ interface SpreadsheetRow {
297
+ id: string;
298
+ index: number;
299
+ height?: number;
300
+ recordId?: string;
301
+ type: RowType;
302
+ hidden?: boolean;
303
+ }
304
+ interface CellCoordinate {
305
+ row: number;
306
+ col: number;
307
+ rowId?: string;
308
+ colId?: string;
309
+ }
310
+ interface CellRange {
311
+ startRow: number;
312
+ startCol: number;
313
+ endRow: number;
314
+ endCol: number;
315
+ }
316
+ interface CellData {
317
+ raw: string;
318
+ /**
319
+ * Evaluated value. Typed (non-formula) input is parsed: `"120"` → 120,
320
+ * `"TRUE"` → true, `"3/4/2026"` → `"2026-03-04"` (dates are ISO text),
321
+ * `"10:30"` → 0.4375 (a time alone is a fraction of a day); `'120` forces
322
+ * the text `"120"`. Formulas store their result.
323
+ */
324
+ value: any;
325
+ error?: string;
326
+ /** Why the formula failed, e.g. `Argument 2 of SUMIF must be a range.` Set alongside `error`. */
327
+ errorMessage?: string;
328
+ format?: CellFormat;
329
+ /**
330
+ * Excel number format code used to display the value (see
331
+ * `formatCellDisplay`). Set explicitly (`explicitNumberFormat`), inherited
332
+ * from the column's `numberFormat`, or chosen automatically for typed input,
333
+ * e.g. `"$"#,##0.00` for `$1,200.50`, `0%` for `10%`, `#,##0` for `1,234`,
334
+ * `m/d/yyyy` for `3/4/2026`, `h:mm` for `10:30`. Absent for General.
335
+ */
336
+ numberFormat?: string;
337
+ /**
338
+ * True when `numberFormat` was set explicitly (`setCellNumberFormat`):
339
+ * typing into the cell keeps it instead of choosing an automatic format.
340
+ */
341
+ explicitNumberFormat?: boolean;
342
+ readOnly?: boolean;
343
+ /**
344
+ * Set (only) on cells showing a value spilled from a dynamic array: the
345
+ * anchor cell holding the formula, e.g. `A1`. Spilled cells keep an empty
346
+ * `raw` and are never stored in the document.
347
+ */
348
+ spillAnchor?: string;
349
+ }
350
+ /** A dynamic array spilled from its anchor cell (the cell holding the formula). */
351
+ interface SpreadsheetSpill {
352
+ /** Anchor cell key, e.g. `A1`. */
353
+ key: string;
354
+ anchor: {
355
+ row: number;
356
+ col: number;
357
+ };
358
+ /** Every cell the array covers, anchor included. */
359
+ range: CellRange;
360
+ /** The anchor's formula. */
361
+ formula: string;
362
+ }
363
+ interface SpreadsheetDocument {
364
+ id: string;
365
+ name: string;
366
+ columns: SpreadsheetColumn[];
367
+ rows: SpreadsheetRow[];
368
+ cells: Record<string, Record<string, CellData>>;
369
+ createdAt?: number;
370
+ updatedAt?: number;
371
+ table?: SpreadsheetTableSettings;
372
+ }
373
+ type SortDirection = 'asc' | 'desc';
374
+ interface SortKey {
375
+ colId: string;
376
+ direction?: SortDirection;
377
+ }
378
+ type FilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'greaterThan' | 'greaterThanOrEqual' | 'lessThan' | 'lessThanOrEqual' | 'between' | 'isBlank' | 'isNotBlank' | 'oneOf';
379
+ interface FilterRule {
380
+ id: string;
381
+ colId: string;
382
+ operator: FilterOperator;
383
+ value?: string | number;
384
+ value2?: string | number;
385
+ values?: string[];
386
+ }
387
+ interface SpreadsheetFilterState {
388
+ enabled: boolean;
389
+ rules: FilterRule[];
390
+ }
391
+ type GroupAggregate = 'sum' | 'count' | 'average' | 'min' | 'max';
392
+ interface GroupSummary {
393
+ colId: string;
394
+ aggregate: GroupAggregate;
395
+ }
396
+ interface SpreadsheetGrouping {
397
+ colId: string;
398
+ summaries: GroupSummary[];
399
+ collapsed: string[];
400
+ }
401
+ interface SpreadsheetTableSettings {
402
+ headerRowCount?: number;
403
+ footerRowCount?: number;
404
+ headerColumnCount?: number;
405
+ frozenRowCount?: number;
406
+ frozenColumnCount?: number;
407
+ merges?: CellRange[];
408
+ filter?: SpreadsheetFilterState;
409
+ grouping?: SpreadsheetGrouping;
410
+ /**
411
+ * Conditional formats of this sheet, highest priority first. Kept with the
412
+ * other per-sheet table state (undoable through document snapshots).
413
+ */
414
+ conditionalFormats?: ConditionalFormatRule[];
415
+ /** Data validation rules of this sheet; a cell uses the first rule containing it. */
416
+ dataValidations?: DataValidationRule[];
417
+ }
418
+ interface SpreadsheetDataSourceField {
419
+ key: string;
420
+ label: string;
421
+ type: 'string' | 'number' | 'date' | 'boolean' | 'enum';
422
+ options?: Array<{
423
+ key: string;
424
+ label: string;
425
+ color?: string;
426
+ }>;
427
+ }
428
+ interface SpreadsheetDataSource {
429
+ id: string;
430
+ name: string;
431
+ getRecords(): Array<{
432
+ id: string;
433
+ [key: string]: any;
434
+ }>;
435
+ getFields(): SpreadsheetDataSourceField[];
436
+ updateRecord(recordId: string, field: string, value: any): Promise<void> | void;
437
+ }
438
+ /**
439
+ * A defined name (Formulas › Name Manager): a range, constant, formula or
440
+ * LAMBDA that formulas can use by name, e.g. `=Price*(1+Rate)`,
441
+ * `=SUM(Sales)`, `=Double(4)`.
442
+ */
443
+ interface SpreadsheetDefinedName {
444
+ /** The name, e.g. `Rate`. Unique per scope, compared case-insensitively. */
445
+ name: string;
446
+ /**
447
+ * What the name refers to, as a formula: `=Data!$A$2:$A$20`, `=0.07`,
448
+ * `=Rate*2` or `=LAMBDA(x, x*2)`. Unqualified references refer to the
449
+ * name's sheet (sheet scope) or to the sheet of the formula using it.
450
+ */
451
+ refersTo: string;
452
+ /** Id of the sheet for a sheet-scoped name; unset for workbook scope. */
453
+ sheetId?: string;
454
+ comment?: string;
455
+ }
456
+ /**
457
+ * A workbook: several sheets plus defined names. A `SpreadsheetController`
458
+ * created from a single document is a workbook with one sheet.
459
+ */
460
+ interface SpreadsheetWorkbook {
461
+ /** The sheets in tab order. A sheet's `name` is its tab name (unique, case-insensitively). */
462
+ sheets: SpreadsheetDocument[];
463
+ /** Id of the sheet shown (default: the first). */
464
+ activeSheetId?: string;
465
+ names?: SpreadsheetDefinedName[];
466
+ }
467
+ /** A sheet tab: what sheet-tab bars render. */
468
+ interface SpreadsheetSheetInfo {
469
+ id: string;
470
+ name: string;
471
+ /** Position in tab order (0-based). */
472
+ index: number;
473
+ active: boolean;
474
+ }
475
+
476
+ type FormulaTokenType = 'NUMBER' | 'STRING' | 'BOOLEAN' | 'ERROR' | 'CELL_REF' | 'RANGE' | 'SPILL_REF' | 'PROPERTY_REF' | 'IDENTIFIER' | 'OPERATOR' | 'LPAREN' | 'RPAREN' | 'COMMA' | 'EOF';
477
+ interface FormulaToken {
478
+ type: FormulaTokenType;
479
+ value: string;
480
+ /** Offset of the token in the formula (for a sheet-qualified reference, of its sheet prefix). */
481
+ position: number;
482
+ /** Offset just past the token. */
483
+ end?: number;
484
+ /**
485
+ * Sheet of a sheet-qualified reference or name (`Sheet2!A1`, `'My Sheet'!A1:B2`,
486
+ * `Data!Rate`), unquoted. Unset for references to the formula's own sheet.
487
+ */
488
+ sheet?: string;
489
+ /** Last sheet of a 3-D reference (`Sheet1:Sheet3!A1`). */
490
+ sheetEnd?: string;
491
+ /** Offset where the reference itself starts, after the sheet prefix and `!`. */
492
+ refStart?: number;
493
+ }
494
+ declare function tokenizeFormula(formula: string): FormulaToken[];
495
+
496
+ /** Row number used for the open end of whole-column ranges such as `A:A`. */
497
+ declare const WHOLE_COLUMN_END_ROW = 1048576;
498
+ type ASTNode = LiteralNode | CellRefNode | RangeNode | SpillRefNode | NameNode | PropertyRefNode | BinaryOpNode | UnaryOpNode | FunctionCallNode | InvokeNode | MissingNode;
499
+ /**
500
+ * Sheet qualification of a reference: `Sheet2!A1` has `sheet: 'Sheet2'`;
501
+ * a 3-D reference `Sheet1:Sheet3!A1` also has `sheetEnd: 'Sheet3'`. Unset
502
+ * for references to the formula's own sheet.
503
+ */
504
+ interface SheetQualifier {
505
+ sheet?: string;
506
+ sheetEnd?: string;
507
+ }
508
+ interface LiteralNode {
509
+ type: 'Literal';
510
+ value: number | string | boolean;
511
+ }
512
+ interface CellRefNode extends SheetQualifier {
513
+ type: 'CellRef';
514
+ ref: string;
515
+ col: string;
516
+ row: number;
517
+ }
518
+ interface RangeNode extends SheetQualifier {
519
+ type: 'Range';
520
+ raw: string;
521
+ startCol: string;
522
+ startRow: number;
523
+ endCol: string;
524
+ endRow: number;
525
+ }
526
+ /** `A1#`: the whole spill range of the dynamic array anchored at A1. */
527
+ interface SpillRefNode extends SheetQualifier {
528
+ type: 'SpillRef';
529
+ /** Anchor cell, e.g. `A1`. */
530
+ ref: string;
531
+ col: string;
532
+ row: number;
533
+ }
534
+ /**
535
+ * A bare name: a LET or LAMBDA variable, a defined name (`Rate`,
536
+ * `Data!Rate` with `sheet`), or `#NAME?` when nothing defines it.
537
+ */
538
+ interface NameNode {
539
+ type: 'Name';
540
+ name: string;
541
+ /** Sheet of a sheet-qualified name (`Data!Rate`). */
542
+ sheet?: string;
543
+ }
544
+ interface PropertyRefNode {
545
+ type: 'PropertyRef';
546
+ property: string;
547
+ }
548
+ interface BinaryOpNode {
549
+ type: 'BinaryOp';
550
+ op: string;
551
+ left: ASTNode;
552
+ right: ASTNode;
553
+ }
554
+ interface UnaryOpNode {
555
+ type: 'UnaryOp';
556
+ op: string;
557
+ argument: ASTNode;
558
+ }
559
+ interface FunctionCallNode {
560
+ type: 'FunctionCall';
561
+ name: string;
562
+ args: ASTNode[];
563
+ }
564
+ /**
565
+ * A call of a computed function: `LAMBDA(x, x+1)(2)` or `(f)(2)`. Calls of a
566
+ * named function, defined name or variable (`F(2)`) are `FunctionCall`s.
567
+ */
568
+ interface InvokeNode {
569
+ type: 'Invoke';
570
+ callee: ASTNode;
571
+ args: ASTNode[];
572
+ }
573
+ /** An argument left empty, as in `IF(A1,,1)` or `LAMBDA(x, y, x)(1,)`. */
574
+ interface MissingNode {
575
+ type: 'Missing';
576
+ }
577
+ declare function parseCellReference(ref: string): {
578
+ col: string;
579
+ row: number;
580
+ };
581
+ declare function parseRange(rangeStr: string): RangeNode;
582
+ declare class FormulaParser {
583
+ private tokens;
584
+ private current;
585
+ constructor(tokens: FormulaToken[]);
586
+ parse(): ASTNode;
587
+ private expression;
588
+ private comparison;
589
+ private concatenation;
590
+ private addition;
591
+ private multiplication;
592
+ private exponentiation;
593
+ private unary;
594
+ /** Arguments after `(` up to and including `)`. Empty positions are `Missing`. */
595
+ private argumentList;
596
+ private primary;
597
+ private match;
598
+ private matchOperator;
599
+ private check;
600
+ private advance;
601
+ private isAtEnd;
602
+ private peek;
603
+ private previous;
604
+ private consume;
605
+ }
606
+ declare function parseFormula(formula: string): ASTNode;
607
+
608
+ /** Spreadsheet error values. They propagate through operators and functions. */
609
+ declare const FORMULA_ERRORS: Set<string>;
610
+ type FormulaErrorCode = '#DIV/0!' | '#VALUE!' | '#REF!' | '#NAME?' | '#N/A' | '#NUM!' | '#CYCLE!' | '#ERROR!' | '#SPILL!' | '#CALC!';
611
+ declare function isFormulaError(value: unknown): value is string;
612
+ /**
613
+ * Number to text as Excel converts it in `&` and General display: up to 15
614
+ * significant digits, scientific for very large or very small magnitudes.
615
+ */
616
+ declare function numberToText(n: number): string;
617
+ /**
618
+ * Compares numbers the way Excel does: both are rounded to 15 significant
619
+ * digits first, so binary noise such as `0.1+0.2` versus `0.3` counts as equal.
620
+ */
621
+ declare function compareNumbers(a: number, b: number): number;
622
+ /**
623
+ * Excel's comparison for the `=`, `<>`, `<`… operators: numbers < text <
624
+ * booleans < errors, numbers compared at 15 significant digits, text
625
+ * case-insensitively. A blank acts as 0, "" or FALSE depending on the other
626
+ * side. Dates are ISO text: two ISO dates compare chronologically
627
+ * ("2026-1-5" is before "2026-01-10"), and an ISO date against a number
628
+ * compares as its serial number.
629
+ */
630
+ declare function compareValues(left: unknown, right: unknown): number;
631
+ /**
632
+ * Sort order (ascending): numbers, text, booleans, errors, then blanks last.
633
+ * Errors are equal to each other, so sorting keeps their order.
634
+ */
635
+ declare function sortCompareValues(left: unknown, right: unknown): number;
636
+ declare function colNameToIndex(col: string): number;
637
+ declare function indexToColName(index: number): string;
638
+ /**
639
+ * A rectangular block of values. `values` is column-major (the order in which
640
+ * `EvaluationContext.resolveRange` returns cells): `values[col * rows + row]`.
641
+ */
642
+ interface FormulaRange {
643
+ rows: number;
644
+ cols: number;
645
+ values: any[];
646
+ }
647
+
648
+ /** What a defined name refers to, as returned by `EvaluationContext.resolveName`. */
649
+ interface FormulaNameDefinition {
650
+ /** Formula text (`=Sheet1!$A$1:$A$9`, `=0.07`, `=LAMBDA(x, x*2)`) or a parsed formula. */
651
+ formula: string | ASTNode;
652
+ /** Sheet that unqualified references in the formula refer to (a sheet-scoped name's sheet). */
653
+ sheet?: string;
654
+ /** A key identifying the name (for cycle detection), e.g. `Data!RATE`. Defaults to the name. */
655
+ key?: string;
656
+ }
657
+ interface EvaluationContext {
658
+ /**
659
+ * Value of a cell. `sheet` is set for sheet-qualified references
660
+ * (`Sheet2!A1`); undefined means the formula's own sheet. Return `#REF!`
661
+ * for a sheet that doesn't exist.
662
+ */
663
+ resolveCell?: (col: string, row: number, sheet?: string) => any;
664
+ /**
665
+ * Values of a rectangular range, column by column (all rows of the first
666
+ * column, then the next column). Lookup functions rely on this order.
667
+ * `sheet` as in `resolveCell`; return an error code for a missing sheet.
668
+ */
669
+ resolveRange?: (startCol: string, startRow: number, endCol: string, endRow: number, sheet?: string) => any[] | string;
670
+ resolveProperty?: (property: string) => any;
671
+ /**
672
+ * The spilled array anchored at a cell, for `A1#` references: its shape and
673
+ * values (column-major, like `resolveRange`), or an error code (e.g.
674
+ * `#REF!` when the cell holds no array).
675
+ */
676
+ resolveSpill?: (col: string, row: number, sheet?: string) => FormulaRange | string;
677
+ /**
678
+ * The sheets of a 3-D reference (`Sheet1:Sheet3!A1`), from `first` to
679
+ * `last` in tab order, or an error code when either sheet is missing.
680
+ */
681
+ resolveSheetSpan?: (first: string, last: string) => string[] | string;
682
+ /**
683
+ * A defined name (`Rate`, `Data!Rate`), or null when none is visible.
684
+ * `sheet` is the qualifying sheet, or the sheet whose names apply (when a
685
+ * sheet-scoped name refers to another name); undefined means the formula's
686
+ * own sheet. Sheet-scoped names come before workbook-scoped ones.
687
+ */
688
+ resolveName?: (name: string, sheet?: string) => FormulaNameDefinition | null;
689
+ /**
690
+ * The cell holding the formula being evaluated, used by the implicit
691
+ * intersection operator (`=@A:A` reads the cell in the formula's row).
692
+ */
693
+ getFormulaCell?: () => {
694
+ col: string;
695
+ row: number;
696
+ } | null;
697
+ }
698
+ /** A human-readable reason for an error value. */
699
+ interface FormulaDiagnostic {
700
+ code: FormulaErrorCode;
701
+ message: string;
702
+ }
703
+ interface FormulaEvaluationResult {
704
+ /** The computed value; an error code such as `#VALUE!` when the formula fails. */
705
+ value: any;
706
+ /** The error code when `value` is an error. */
707
+ error?: FormulaErrorCode;
708
+ /** Why the formula failed, e.g. `Argument 2 of SUMIF must be a range.` */
709
+ message?: string;
710
+ /**
711
+ * Set when the formula returned an array of more than one value (a
712
+ * dynamic array). `value` is then its top-left value; a spreadsheet spills
713
+ * the whole array into the cells below and to the right.
714
+ */
715
+ array?: FormulaRange;
716
+ }
717
+ /** Generic explanation of an error code, used when no specific reason was recorded. */
718
+ declare function describeFormulaError(code: string): string;
719
+ /** Largest array a formula may build (SEQUENCE, RANDARRAY, broadcasting). */
720
+ declare const MAX_FORMULA_ARRAY_SIZE = 1000000;
721
+ declare class FormulaEvaluator {
722
+ private context;
723
+ private diagnostics;
724
+ private env;
725
+ private defaultSheet;
726
+ private lambdaDepth;
727
+ private nameStack;
728
+ private parsedNames;
729
+ constructor(context?: EvaluationContext);
730
+ /**
731
+ * Evaluates a formula. Errors in the formula are returned as error values
732
+ * (`#VALUE!` etc.); malformed formulas and missing resolvers throw.
733
+ */
734
+ evaluate(astOrFormula: ASTNode | string): any;
735
+ /**
736
+ * Evaluates a formula and explains errors. Never throws: malformed formulas
737
+ * return `#ERROR!` with the parser's message. A result with several values
738
+ * (a range or a dynamic array) is returned in `array`, with its top-left
739
+ * value as `value`; a one-value array is just that value.
740
+ */
741
+ evaluateWithDiagnostics(astOrFormula: ASTNode | string): FormulaEvaluationResult;
742
+ /** Records why an error happened and returns the error code. */
743
+ private fail;
744
+ private evaluateNode;
745
+ private unary;
746
+ /** A binary operator on two single values. */
747
+ private binary;
748
+ /**
749
+ * Dates are ISO text: date +/- days is a date, date - date is a number of
750
+ * days (fractional when times are involved).
751
+ */
752
+ private dateArithmetic;
753
+ /**
754
+ * `@` (implicit intersection): a range reference reads the cell in the
755
+ * formula's row (one column) or column (one row); arrays give their
756
+ * top-left value.
757
+ */
758
+ private implicitIntersection;
759
+ private evaluateSpillRef;
760
+ private evaluateRange;
761
+ private callFunction;
762
+ private finishCall;
763
+ private lazyArguments;
764
+ /**
765
+ * Applies a scalar function element by element when it receives arrays
766
+ * (`=LEN(A1:A3)`, `=IF(A1:A3>1, "y", "n")`). Arguments typed `range` are
767
+ * passed whole. Returns undefined when no trigger argument is a
768
+ * multi-value array.
769
+ */
770
+ private liftOverArrays;
771
+ /** A bare name: a variable, a defined name, or #NAME?. */
772
+ private evaluateName;
773
+ private lookupDefinedName;
774
+ /**
775
+ * Evaluates a defined name's formula, outside any LET/LAMBDA variables, with
776
+ * unqualified references pointing at the name's sheet (for sheet-scoped
777
+ * names).
778
+ */
779
+ private evaluateDefinedName;
780
+ /** A 3-D reference (`Sheet1:Sheet3!A1`, `Sheet1:Sheet3!A1:B2`): every sheet's values, in tab order. */
781
+ private evaluate3d;
782
+ /** Calls a lambda with argument expressions, evaluated in the caller's scope. */
783
+ private invokeLambda;
784
+ /** Calls a lambda with argument values (`omitted`: positions left out, for ISOMITTED). */
785
+ private invokeWithValues;
786
+ private evaluateSpecialForm;
787
+ /** LET(name1, value1, [name2, value2, ...], calculation). */
788
+ private evaluateLet;
789
+ /** LAMBDA([parameter1, ...], calculation): a function value closing over the current variables. */
790
+ private evaluateLambda;
791
+ /**
792
+ * The function argument of a LAMBDA helper: a lambda, or a built-in
793
+ * function given by name (`BYROW(A1:C3, SUM)`) unless a variable or defined
794
+ * name has that name. Returns an error string when it is neither.
795
+ */
796
+ private lambdaArgument;
797
+ /** Calls a built-in function with already evaluated arguments. */
798
+ private callBuiltinWithValues;
799
+ /** Checks a lambda takes `count` parameters (native functions take any count). */
800
+ private checkArity;
801
+ /** MAP(array1, [array2, ...], lambda): calls the lambda with each element. */
802
+ private evaluateMap;
803
+ /**
804
+ * REDUCE([initial_value], array, lambda) / SCAN(...): folds the array row
805
+ * by row with lambda(accumulator, value). SCAN returns every intermediate
806
+ * value, in the array's shape.
807
+ */
808
+ private evaluateReduce;
809
+ /** BYROW(array, lambda) / BYCOL(array, lambda): one result per row (a column) or per column (a row). */
810
+ private evaluateByLine;
811
+ /** MAKEARRAY(rows, columns, lambda): lambda(row, column) for every 1-based position. */
812
+ private evaluateMakeArray;
813
+ private createContext;
814
+ }
815
+
816
+ interface CellDep {
817
+ col: string;
818
+ /** Row number; 0 for a whole-column dependency (`A:A`). */
819
+ row: number;
820
+ /** Sheet of a sheet-qualified reference (`Sheet2!A1`); unset for the formula's own sheet. */
821
+ sheet?: string;
822
+ /** Last sheet of a 3-D reference (`Sheet1:Sheet3!A1`). */
823
+ sheetEnd?: string;
824
+ }
825
+ /** A name used by a formula: a defined name, LET/LAMBDA variable or (with `call`) a function. */
826
+ interface NameDep {
827
+ /** Upper-case name. */
828
+ name: string;
829
+ /** Sheet of a sheet-qualified name (`Data!Rate`). */
830
+ sheet?: string;
831
+ /** Used as a function (`Double(4)`). */
832
+ call: boolean;
833
+ }
834
+ /**
835
+ * Names a formula uses (bare names and calls), for dependencies on defined
836
+ * names. LET/LAMBDA variables are included; callers ignore names that are
837
+ * not defined.
838
+ */
839
+ declare function extractNameDependencies(node: ASTNode): NameDep[];
840
+ /**
841
+ * Dependency key for "every cell in column `col`", used by whole-column ranges
842
+ * (`A:A`) instead of expanding a million cell keys.
843
+ */
844
+ declare const columnDependencyKey: (col: string) => string;
845
+ declare function extractCellDependencies(node: ASTNode): CellDep[];
846
+ declare class DependencyGraph {
847
+ private dependencies;
848
+ private dependents;
849
+ private spillDependencies;
850
+ private spillDependents;
851
+ private spillEdges;
852
+ /**
853
+ * Sets the cells `cellKey` depends on directly (keys such as `B2`, or a
854
+ * column key from `columnDependencyKey`), replacing its previous
855
+ * dependencies. Used by spreadsheets whose keys carry more than A1 text
856
+ * (e.g. sheet-qualified keys); `setCellFormula` derives them from a formula.
857
+ */
858
+ setCellDependencies(cellKey: string, dependencyKeys: Iterable<string>): void;
859
+ setCellFormula(cellKey: string, formulaStr: string | null): void;
860
+ /** Removes every registered formula and dependency. */
861
+ clear(): void;
862
+ /**
863
+ * Records the dynamic-array edges of the anchor `anchorKey`, replacing its
864
+ * previous ones: every key in `spilledKeys` (cells holding its spilled
865
+ * values) depends on the anchor, and the anchor depends on every key in
866
+ * `blockingKeys` (cells that stop it spilling). Pass empty lists to remove
867
+ * the anchor's edges.
868
+ */
869
+ setSpillEdges(anchorKey: string, spilledKeys: Iterable<string>, blockingKeys?: Iterable<string>): void;
870
+ /** The spilled cells registered for `anchorKey` by `setSpillEdges`. */
871
+ getSpilledKeys(anchorKey: string): string[];
872
+ /** Formula dependencies plus dynamic-array (spill) dependencies of a cell. */
873
+ getDependencies(cellKey: string): string[];
874
+ /** Cells depending on `cellKey`, through formulas or spills. */
875
+ getDependents(cellKey: string): string[];
876
+ /**
877
+ * Detects if there is a cycle containing cellKey.
878
+ */
879
+ hasCycle(cellKey: string): boolean;
880
+ /**
881
+ * Returns cells affected by updating cellKey in topological order.
882
+ */
883
+ getEvaluationOrder(startCellKey: string): {
884
+ order: string[];
885
+ hasCycle: boolean;
886
+ };
887
+ /**
888
+ * Plans a recalculation over `cellKeys` (and, with `includeDependents`, every
889
+ * cell that transitively depends on them). Returns the keys in evaluation
890
+ * order (dependencies first) and the set of keys that are part of a cycle,
891
+ * which must be marked `#CYCLE!` instead of evaluated. Every member of a
892
+ * cycle is reported, not just the cell that closed it.
893
+ */
894
+ getEvaluationPlan(cellKeys: Iterable<string>, options?: {
895
+ includeDependents?: boolean;
896
+ }): {
897
+ order: string[];
898
+ cyclic: Set<string>;
899
+ };
900
+ }
901
+
902
+ /**
903
+ * A row or column insertion/deletion. `index` is the 0-based position of the
904
+ * inserted or deleted row/column.
905
+ */
906
+ interface StructuralChange {
907
+ axis: 'row' | 'col';
908
+ index: number;
909
+ type: 'insert' | 'delete';
910
+ }
911
+ /**
912
+ * Rewrites the cell and range references in `formula` after a row or column
913
+ * is inserted or deleted, the way spreadsheet apps do: references after the
914
+ * change shift, ranges grow or shrink, and references to a deleted row/column
915
+ * become `#REF!`. Absolute (`$`) markers are kept. String literals, property
916
+ * references and function names are left untouched.
917
+ */
918
+ declare function shiftFormulaReferences(formula: string, change: StructuralChange, options?: FormulaReferenceFilter): string;
919
+ /**
920
+ * Limits a rewrite to some references, e.g. only those pointing at the sheet
921
+ * that changed: `appliesTo(sheet)` gets the reference's sheet (undefined for
922
+ * the formula's own sheet) and, for 3-D references, the last sheet.
923
+ */
924
+ interface FormulaReferenceFilter {
925
+ appliesTo?: (sheet: string | undefined, sheetEnd: string | undefined) => boolean;
926
+ }
927
+ /** Where a reference passed to a `mapFormulaReferences` callback points. */
928
+ interface FormulaReferenceInfo {
929
+ /** Sheet of a qualified reference (`Sheet2!A1`), unquoted; undefined for the formula's own sheet. */
930
+ sheet?: string;
931
+ /** Last sheet of a 3-D reference. */
932
+ sheetEnd?: string;
933
+ }
934
+ /**
935
+ * Calls `rewrite` with the source text of every cell or range reference in
936
+ * `formula` (e.g. `"$A1"`, `"B2:C10"`, `"A:A"`) and splices in its result.
937
+ * For a spill reference (`A1#`) it receives the anchor (`"A1"`) and the `#`
938
+ * is kept, unless the rewrite returns `#REF!`. A sheet prefix (`Sheet2!`,
939
+ * `'My Sheet'!`) is not part of the text: `info` says which sheet the
940
+ * reference points at, and the prefix is kept unless the rewrite returns
941
+ * `#REF!`. String literals, property references and function names (e.g.
942
+ * `LOG10(`) are skipped. Formulas that fail to tokenize are returned unchanged.
943
+ */
944
+ declare function mapFormulaReferences(formula: string, rewrite: (reference: string, info: FormulaReferenceInfo) => string): string;
945
+ /**
946
+ * Moves a formula by (`rowOffset`, `colOffset`), as copy/paste and autofill
947
+ * do: relative row/column parts shift, `$`-absolute parts stay. A reference
948
+ * pushed above row 1 or left of column A becomes `#REF!`.
949
+ */
950
+ declare function offsetFormulaReferences(formula: string, rowOffset: number, colOffset: number): string;
951
+ /** A 0-based cell position. */
952
+ interface CellPosition {
953
+ row: number;
954
+ col: number;
955
+ }
956
+ /**
957
+ * Rewrites references when cells *move* (sort, transpose): references follow
958
+ * the cell they point at, whether relative or absolute. `moveCell` returns a
959
+ * cell's new position, or null when it did not move. A range is remapped only
960
+ * when its cells moved together as a rectangle of the same size (e.g. a
961
+ * one-row range inside a sorted row, or a range inside a transposed block);
962
+ * otherwise it is kept, since it still covers the same rows and columns.
963
+ */
964
+ declare function remapFormulaReferences(formula: string, moveCell: (position: CellPosition) => CellPosition | null, options?: FormulaReferenceFilter): string;
965
+ /**
966
+ * Whether a sheet name must be quoted in a formula (`'My Sheet'!A1`): names
967
+ * with spaces or punctuation, starting with a digit, or that look like a
968
+ * cell reference (`A1`, `R1C1`) or a boolean.
969
+ */
970
+ declare function sheetNameNeedsQuotes(name: string): boolean;
971
+ /** A sheet name as written in formulas: `Data`, `'My Sheet'`, `'Bob''s'`. */
972
+ declare function quoteSheetName(name: string): string;
973
+ /** The prefix of a reference to `sheet` (or the 3-D span `sheet:sheetEnd`), with `!`. */
974
+ declare function formatSheetPrefix(sheet: string, sheetEnd?: string): string;
975
+ /**
976
+ * Rewrites references to the sheet `oldName` (cell, range, spill and 3-D
977
+ * references, and sheet-qualified names such as `Old!Rate`) after it is
978
+ * renamed to `newName`, quoting the new name when needed.
979
+ */
980
+ declare function renameSheetInFormula(formula: string, oldName: string, newName: string): string;
981
+ /**
982
+ * Rewrites a formula after the sheet `name` is deleted: references to it
983
+ * become `#REF!`. `order` lists the sheet names before the deletion, in tab
984
+ * order: a 3-D reference losing an end sheet shrinks to the neighbouring
985
+ * sheet, as in Excel (`Sheet1:Sheet3!A1` without Sheet1 is `Sheet2:Sheet3!A1`).
986
+ */
987
+ declare function deleteSheetInFormula(formula: string, name: string, order?: readonly string[]): string;
988
+ /**
989
+ * Renames uses of the defined name `oldName` (`Rate`, `Rate*2`, `Double(4)`,
990
+ * `Data!Rate`) to `newName`. `appliesTo(sheet)` decides, for a
991
+ * sheet-qualified use, whether that sheet's name is the renamed one; unset,
992
+ * every use is renamed. With `qualifiedOnly`, unqualified uses are kept (the
993
+ * formula is on a sheet where the name means something else).
994
+ */
995
+ declare function renameNameInFormula(formula: string, oldName: string, newName: string, options?: {
996
+ appliesTo?: (sheet: string) => boolean;
997
+ qualifiedOnly?: boolean;
998
+ }): string;
999
+ /** Upper-case names used in a formula (bare names, calls and sheet-qualified names). */
1000
+ declare function formulaIdentifiers(formula: string): Array<{
1001
+ name: string;
1002
+ sheet?: string;
1003
+ call: boolean;
1004
+ }>;
1005
+
1006
+ declare class DataSourceBinder {
1007
+ private dataSources;
1008
+ register(dataSource: SpreadsheetDataSource): void;
1009
+ unregister(dataSourceId: string): void;
1010
+ getDataSource(id: string): SpreadsheetDataSource | undefined;
1011
+ /**
1012
+ * Generates or reconciles spreadsheet rows from a primary data source.
1013
+ */
1014
+ syncRows(currentRows: SpreadsheetRow[], dataSourceId: string): SpreadsheetRow[];
1015
+ /**
1016
+ * Resolves a record's bound field value.
1017
+ */
1018
+ resolveBoundValue(dataSourceId: string, recordId: string, field: string): any;
1019
+ /**
1020
+ * Dispatches an update to the underlying data source.
1021
+ */
1022
+ commitBoundValue(dataSourceId: string, recordId: string, field: string, value: any): Promise<void>;
1023
+ }
1024
+
1025
+ /**
1026
+ * Spreadsheet clipboard formats. Copying writes three representations:
1027
+ *
1028
+ * - `text/plain`: TSV of the displayed values (pastes into any app)
1029
+ * - `text/html`: an HTML `<table>` (pastes into docs, mail, other sheets)
1030
+ * - `application/x.pixerate.spreadsheet+json`: raw inputs and formulas, so a
1031
+ * paste into a pixerate spreadsheet is lossless; formulas are re-based to
1032
+ * the paste position like a spreadsheet copy/paste
1033
+ *
1034
+ * Pasting prefers the custom format, then an HTML table, then TSV. All
1035
+ * functions here are pure and DOM-free.
1036
+ */
1037
+
1038
+ declare const SPREADSHEET_CLIPBOARD_MIME = "application/x.pixerate.spreadsheet+json";
1039
+ interface SpreadsheetClipboardCell {
1040
+ raw: string;
1041
+ value: unknown;
1042
+ /** Display text for `text/plain` and `text/html` (e.g. `10%` for 0.1); defaults to the value as text. Not stored in the JSON payload. */
1043
+ text?: string;
1044
+ }
1045
+ interface SpreadsheetClipboardPayload {
1046
+ type: 'pixerate-spreadsheet';
1047
+ version: 1;
1048
+ /** Position of the copied block's top-left cell, used to re-base formulas. */
1049
+ origin: CellPosition;
1050
+ cells: SpreadsheetClipboardCell[][];
1051
+ }
1052
+ /** MIME type -> data, as written to `DataTransfer.setData`. */
1053
+ type SpreadsheetClipboardData = Record<string, string>;
1054
+ /** Anything clipboard data can be read from: a `DataTransfer` or a plain record. */
1055
+ type SpreadsheetClipboardSource = {
1056
+ getData(format: string): string;
1057
+ } | Record<string, string | undefined>;
1058
+ interface ParsedSpreadsheetClipboard {
1059
+ format: 'internal' | 'html' | 'text';
1060
+ /** Raw inputs to write, row by row. */
1061
+ rows: string[][];
1062
+ /** For internal pastes: where the block was copied from. */
1063
+ origin?: CellPosition;
1064
+ }
1065
+ /** Serializes displayed values as an HTML table. Line breaks become `<br>`. */
1066
+ declare function serializeHtmlTable(values: ReadonlyArray<ReadonlyArray<unknown>>): string;
1067
+ /**
1068
+ * Extracts cell texts from the first `<table>` in `html` (as written by
1069
+ * spreadsheet apps and browsers). `colspan`/`rowspan` cells are expanded with
1070
+ * blank cells so positions line up. Returns null when there is no table.
1071
+ */
1072
+ declare function parseHtmlTable(html: string): string[][] | null;
1073
+ /** Builds the three clipboard representations of a copied block. */
1074
+ declare function createSpreadsheetClipboardData(cells: SpreadsheetClipboardCell[][], origin: CellPosition): SpreadsheetClipboardData;
1075
+ /**
1076
+ * Reads clipboard data, preferring the lossless internal format, then an
1077
+ * HTML table, then TSV text. Returns null when there is nothing to paste.
1078
+ */
1079
+ declare function readSpreadsheetClipboard(source: SpreadsheetClipboardSource): ParsedSpreadsheetClipboard | null;
1080
+ /**
1081
+ * Moves formulas copied from `origin` so they keep their relative references
1082
+ * when pasted at `target`. Non-formula inputs are returned unchanged.
1083
+ */
1084
+ declare function rebaseClipboardRows(rows: string[][], origin: CellPosition, target: CellPosition): string[][];
1085
+
1086
+ /**
1087
+ * The render model of a spreadsheet: which rows and columns are shown, in
1088
+ * which order, with group header rows, frozen (sticky) offsets and merged
1089
+ * cell spans. Filters, hidden rows/columns and collapsed groups only affect
1090
+ * this view; the document keeps every row.
1091
+ */
1092
+
1093
+ declare const DEFAULT_ROW_HEIGHT = 32;
1094
+ declare const DEFAULT_COLUMN_WIDTH = 130;
1095
+ type SpreadsheetRowSection = 'header' | 'body' | 'footer';
1096
+ interface SpreadsheetRowGroup {
1097
+ key: string;
1098
+ label: string;
1099
+ rowIndices: number[];
1100
+ collapsed: boolean;
1101
+ summaries: Record<string, number | null>;
1102
+ }
1103
+ type SpreadsheetViewRow = {
1104
+ kind: 'row';
1105
+ row: SpreadsheetRow;
1106
+ index: number;
1107
+ section: SpreadsheetRowSection;
1108
+ frozen: boolean;
1109
+ stickyTop: number;
1110
+ groupKey?: string;
1111
+ } | {
1112
+ kind: 'group';
1113
+ group: SpreadsheetRowGroup;
1114
+ };
1115
+ interface SpreadsheetViewColumn {
1116
+ column: SpreadsheetColumn;
1117
+ index: number;
1118
+ header: boolean;
1119
+ frozen: boolean;
1120
+ stickyLeft: number;
1121
+ }
1122
+ interface SpreadsheetCellSpan {
1123
+ rowSpan: number;
1124
+ colSpan: number;
1125
+ /** The cell whose content is shown (a merge's top-left cell). */
1126
+ source: CellPosition;
1127
+ merge?: CellRange;
1128
+ }
1129
+ interface SpreadsheetViewModel {
1130
+ rows: SpreadsheetViewRow[];
1131
+ columns: SpreadsheetViewColumn[];
1132
+ groups: SpreadsheetRowGroup[];
1133
+ /** Visible document row indices in display order (for keyboard navigation). */
1134
+ rowOrder: number[];
1135
+ /** Visible document column indices in display order. */
1136
+ columnOrder: number[];
1137
+ filteredOutCount: number;
1138
+ hiddenRowCount: number;
1139
+ hiddenColumnCount: number;
1140
+ /**
1141
+ * Span of the cell rendered at (row, col): `{ rowSpan: 1, colSpan: 1 }` for
1142
+ * an ordinary cell, the visible extent for a merge's first visible cell, and
1143
+ * null for cells covered by a merge (render nothing).
1144
+ */
1145
+ getCellSpan(row: number, col: number): SpreadsheetCellSpan | null;
1146
+ }
1147
+ type CellValueReader = (rowIndex: number, colIndex: number) => unknown;
1148
+ /** Header and footer row counts, clamped so they never overlap. */
1149
+ declare function getTableSections(doc: SpreadsheetDocument): {
1150
+ headerRows: number;
1151
+ footerRows: number;
1152
+ };
1153
+ declare function getRowSection(doc: SpreadsheetDocument, rowIndex: number): SpreadsheetRowSection;
1154
+ /** Whether a body row passes the active filters. Header/footer rows always do. */
1155
+ declare function rowPassesFilters(doc: SpreadsheetDocument, rowIndex: number, getValue: CellValueReader): boolean;
1156
+ /** Category groups of the (unhidden, unfiltered) body rows. */
1157
+ declare function computeRowGroups(doc: SpreadsheetDocument, getValue: CellValueReader): SpreadsheetRowGroup[];
1158
+ declare function buildSpreadsheetView(doc: SpreadsheetDocument, getValue: CellValueReader): SpreadsheetViewModel;
1159
+
1160
+ interface CsvExportOptions {
1161
+ range?: CellRange | null;
1162
+ delimiter?: string;
1163
+ lineEnding?: string;
1164
+ bom?: boolean;
1165
+ /** Export formulas as typed (`=SUM(A1:A3)`) instead of their values. */
1166
+ formulas?: boolean;
1167
+ }
1168
+ interface CsvImportOptions {
1169
+ startRow?: number;
1170
+ startCol?: number;
1171
+ delimiter?: string;
1172
+ /** Sheet (id or name) to import into; default the active sheet. */
1173
+ sheet?: string;
1174
+ }
1175
+ type NewFilterRule = Omit<FilterRule, 'id'> & {
1176
+ id?: string;
1177
+ };
1178
+ /**
1179
+ * Invalid input waiting for the user: a `stop` alert (retry or cancel) or a
1180
+ * `warning` / `information` prompt (accept, retry or cancel). See
1181
+ * `SpreadsheetController.resolveValidationPrompt`.
1182
+ */
1183
+ interface SpreadsheetValidationPrompt {
1184
+ rowId: string;
1185
+ colId: string;
1186
+ row: number;
1187
+ col: number;
1188
+ /** The input that failed validation. */
1189
+ raw: string;
1190
+ /** The failed check: rule, alert style, title and message. */
1191
+ result: DataValidationResult;
1192
+ /** True when the input came from the cell editor (which stays open meanwhile). */
1193
+ editing: boolean;
1194
+ }
1195
+ /**
1196
+ * Outcome of committing input: `committed`; `rejected` (a `stop` rule) or
1197
+ * `confirm` (a `warning` / `information` rule), with `prompt` now waiting
1198
+ * in `validationPrompt`; `pending` when an earlier prompt is still open;
1199
+ * `none` when nothing was being edited.
1200
+ */
1201
+ type SpreadsheetCommitResult = {
1202
+ status: 'committed' | 'none';
1203
+ } | {
1204
+ status: 'rejected' | 'confirm' | 'pending';
1205
+ prompt: SpreadsheetValidationPrompt;
1206
+ };
1207
+ /** How the user answered a validation prompt. */
1208
+ type SpreadsheetValidationAction = 'accept' | 'retry' | 'cancel';
1209
+ interface SpreadsheetControllerOptions {
1210
+ document?: Partial<SpreadsheetDocument>;
1211
+ dataSources?: SpreadsheetDataSource[];
1212
+ primaryDataSourceId?: string;
1213
+ onDocumentChange?: (doc: SpreadsheetDocument) => void;
1214
+ onSelectionChange?: (activeCell: CellCoordinate | null, range: CellRange | null) => void;
1215
+ onCellCommit?: (rowId: string, colId: string, raw: string, value: any) => void;
1216
+ /**
1217
+ * Start from a workbook with several sheets and defined names instead of
1218
+ * `document`. `document` then names nothing; the active sheet is
1219
+ * `workbook.activeSheetId` (default the first sheet).
1220
+ */
1221
+ workbook?: SpreadsheetWorkbook;
1222
+ /**
1223
+ * Called after any change, like `onDocumentChange`, with the whole
1224
+ * workbook. The object holds the live sheet documents: copy it (or use
1225
+ * `getWorkbook()`) before keeping it.
1226
+ */
1227
+ onWorkbookChange?: (workbook: SpreadsheetWorkbook) => void;
1228
+ /** Called when another sheet becomes active. */
1229
+ onActiveSheetChange?: (sheetId: string) => void;
1230
+ /**
1231
+ * Approximate memory budget for undo/redo snapshots, in bytes (UTF-16 size of
1232
+ * the serialized documents). The oldest undo steps beyond it are dropped, but
1233
+ * the most recent one is always kept. Defaults to 64 MiB; 0 = unlimited.
1234
+ */
1235
+ maxHistoryBytes?: number;
1236
+ }
1237
+ /** A defined name as listed by `getNames()`. */
1238
+ interface SpreadsheetNameInfo extends SpreadsheetDefinedName {
1239
+ /** Name of the sheet a sheet-scoped name belongs to; unset for workbook scope. */
1240
+ sheetName?: string;
1241
+ /** Whether the name holds a LAMBDA (it is called like a function). */
1242
+ isLambda: boolean;
1243
+ }
1244
+ /** Where a defined name lives: `sheet` (id or name) for a sheet-scoped name. */
1245
+ interface SpreadsheetNameScope {
1246
+ sheet?: string;
1247
+ }
1248
+ declare class SpreadsheetController {
1249
+ activeCell: CellCoordinate | null;
1250
+ selectedRange: CellRange | null;
1251
+ editingCell: CellCoordinate | null;
1252
+ draftValue: string;
1253
+ readonly binder: DataSourceBinder;
1254
+ readonly depGraph: DependencyGraph;
1255
+ readonly evaluator: FormulaEvaluator;
1256
+ private primaryDataSourceId?;
1257
+ private onDocumentChange?;
1258
+ private onWorkbookChange?;
1259
+ private onActiveSheetChange?;
1260
+ private runtimes;
1261
+ private active;
1262
+ private ctx;
1263
+ private boundSheetId;
1264
+ private names;
1265
+ private onSelectionChange?;
1266
+ private onCellCommit?;
1267
+ private undoStack;
1268
+ private redoStack;
1269
+ private isApplyingHistory;
1270
+ private readonly maxHistoryBytes;
1271
+ private batching;
1272
+ private pendingCommits;
1273
+ private evaluatingRowIndex;
1274
+ private evaluatingCell;
1275
+ private spillChanges;
1276
+ /** The active sheet's document (the sheet the editor shows). */
1277
+ get document(): SpreadsheetDocument;
1278
+ set document(doc: SpreadsheetDocument);
1279
+ private get spills();
1280
+ private get spilledBy();
1281
+ private get spillCells();
1282
+ private cfEngine;
1283
+ private cfDirty;
1284
+ private cfIncremental;
1285
+ private valueOverride;
1286
+ private circlesShown;
1287
+ private invalidCircles;
1288
+ /** Invalid input waiting for the user's answer (see `resolveValidationPrompt`). */
1289
+ validationPrompt: SpreadsheetValidationPrompt | null;
1290
+ constructor(options?: SpreadsheetControllerOptions);
1291
+ private get boundRuntime();
1292
+ /** Runs `fn` with `rt` as the sheet `this.document` (and spills) refer to. */
1293
+ private withSheet;
1294
+ /**
1295
+ * Runs `fn` on the sheet named `sheet` (a sheet-qualified reference), or
1296
+ * on the current sheet when undefined. `#REF!` when no sheet has that name.
1297
+ */
1298
+ private onSheet;
1299
+ private findRuntimeByName;
1300
+ private findRuntimeById;
1301
+ /** A sheet by id or name. */
1302
+ private findRuntime;
1303
+ /** Dependency-graph key of a cell (`A1`) on a sheet: sheet-qualified, so keys are unique in the workbook. */
1304
+ private qualify;
1305
+ /** The sheet and A1 key of a qualified key. */
1306
+ private unqualify;
1307
+ private resolveSheetSpan;
1308
+ /** The defined name `name` visible from `rt`: its sheet-scoped name first, then the workbook one. */
1309
+ private findName;
1310
+ private resolveDefinedName;
1311
+ /**
1312
+ * Replaces the active sheet with `document` (its name becomes the sheet's
1313
+ * name, made unique). Clears undo history.
1314
+ */
1315
+ loadDocument(document: SpreadsheetDocument): void;
1316
+ /** A deep copy of the workbook: every sheet, the active sheet and the defined names. */
1317
+ getWorkbook(): SpreadsheetWorkbook;
1318
+ /** Replaces the whole workbook (sheets, names, active sheet). Clears undo history. */
1319
+ loadWorkbook(workbook: SpreadsheetWorkbook): void;
1320
+ private workbookSnapshot;
1321
+ /**
1322
+ * Installs a workbook's sheets and names (taking ownership of the objects).
1323
+ * Duplicate sheet ids and names are made unique.
1324
+ */
1325
+ private setWorkbookState;
1326
+ /**
1327
+ * Re-parses the value of every stored typed (non-formula) cell from its
1328
+ * `raw` input, so documents saved before typed input was parsed (whose
1329
+ * values are text such as `"120"`) compare and sort as numbers. Cells of
1330
+ * bound columns in record rows keep their value: it belongs to the data
1331
+ * source.
1332
+ */
1333
+ private rederiveTypedValues;
1334
+ /**
1335
+ * Value of typed (non-formula) input: a number, boolean, ISO date, error
1336
+ * or text (see `parseCellInput`), its automatic number format, and the
1337
+ * `CellFormat` to use: the automatic one (currency, percentage, date,
1338
+ * number) when `format` is unset or `text` (the default of new columns).
1339
+ */
1340
+ private typedCell;
1341
+ /**
1342
+ * The number format a cell keeps whatever is typed into it: its explicit
1343
+ * one, else its column's. Undefined lets typed input choose one.
1344
+ */
1345
+ private fixedNumberFormat;
1346
+ /** `numberFormat` / `explicitNumberFormat` fields for a formula, bound or spilled cell. */
1347
+ private fixedNumberFormatFields;
1348
+ /**
1349
+ * Typed input for a bound field, coerced by the field's declared type:
1350
+ * number, boolean and date fields get a number, boolean or ISO date when
1351
+ * the input parses as one; string and enum fields (and unknown fields)
1352
+ * keep the text exactly as typed.
1353
+ */
1354
+ private boundInputValue;
1355
+ registerDataSource(ds: SpreadsheetDataSource): void;
1356
+ setPrimaryDataSource(dataSourceId: string | undefined): void;
1357
+ syncWithDataSource(): void;
1358
+ private recomputeRowIndices;
1359
+ getColumn(colIdOrKey: string): SpreadsheetColumn | undefined;
1360
+ getRow(rowIdOrIndex: string | number): SpreadsheetRow | undefined;
1361
+ getCell(rowId: string, colId: string): CellData;
1362
+ /** Value of a cell with no stored data: bound record value, column formula, or blank. */
1363
+ private getDerivedCell;
1364
+ setCellValue(rowId: string, colId: string, raw: string): void;
1365
+ private getCellKey;
1366
+ /**
1367
+ * Recalculates a cell and everything that depends on it, in dependency
1368
+ * order. Every cell in a reference cycle is marked `#CYCLE!`.
1369
+ */
1370
+ recalculateCell(rowId: string, colId: string): void;
1371
+ /**
1372
+ * Registers the dependencies of the formula in `cellKey` (A1 key on the
1373
+ * current sheet), or removes them when `formula` is null: its references
1374
+ * (sheet-qualified ones on their sheet, 3-D ones on every sheet of the
1375
+ * span) and, through defined names, the cells those names refer to.
1376
+ */
1377
+ private registerFormula;
1378
+ /** Adds the qualified keys `ast` depends on, with unqualified references on `home`. */
1379
+ private collectDependencies;
1380
+ /**
1381
+ * Recalculates `keys` (and, with `includeDependents`, their dependents) in
1382
+ * dependency order. Spill ranges are only known after evaluating their
1383
+ * anchors, so when a pass changes which cells hold spilled values (and so
1384
+ * the dependency graph), the dependents of those cells are recalculated in
1385
+ * another pass, until nothing changes.
1386
+ */
1387
+ private recalculateKeys;
1388
+ /**
1389
+ * Rebuilds the dependency graph from scratch and recalculates every formula
1390
+ * in dependency order.
1391
+ */
1392
+ recalculateAll(): void;
1393
+ private runEvaluationPlan;
1394
+ private locateCellKey;
1395
+ private markCycle;
1396
+ private evalSingleCellByKey;
1397
+ /**
1398
+ * Spills `array` from the anchor at (row, col) into the cells below and to
1399
+ * the right. Returns why it can't (the anchor then shows `#SPILL!`), or
1400
+ * null once placed. The grid never grows to fit an array, as in Excel.
1401
+ */
1402
+ private placeSpill;
1403
+ /** Removes the array spilled from `anchor`. With `keepEdges`, its dependency edges stay. */
1404
+ private clearSpill;
1405
+ private forgetSpilledCell;
1406
+ private resolveSpillByCoord;
1407
+ private toSpill;
1408
+ /**
1409
+ * The dynamic array covering (row, col), whether it is the anchor (the cell
1410
+ * holding the formula) or a spilled cell; null when there is none.
1411
+ */
1412
+ getSpillAt(row: number, col: number): SpreadsheetSpill | null;
1413
+ /** Every dynamic array currently spilled. */
1414
+ getSpills(): SpreadsheetSpill[];
1415
+ /** Whether `range` overlaps a spilled array (its anchor or spilled cells). */
1416
+ private intersectsSpill;
1417
+ private resolveCellByCoord;
1418
+ private resolveRangeByCoords;
1419
+ private resolveCurrentRowProperty;
1420
+ selectCell(row: number, col: number, extendSelection?: boolean): void;
1421
+ selectRange(range: CellRange): void;
1422
+ startEditing(row?: number, col?: number, initialValue?: string): void;
1423
+ /**
1424
+ * Commits the cell editor's draft (or `valueToCommit`). Input that breaks
1425
+ * the cell's data validation is not committed: the editor stays open and
1426
+ * `validationPrompt` holds the alert until `resolveValidationPrompt`.
1427
+ * Unchanged input is not validated.
1428
+ */
1429
+ commitEditing(valueToCommit?: string): SpreadsheetCommitResult;
1430
+ /**
1431
+ * Commits typed input to a cell (e.g. from the formula bar or a list
1432
+ * dropdown) with data validation, like `commitEditing` without an open
1433
+ * editor. `setCellValue` never validates (paste, import and code bypass
1434
+ * validation, as in Excel).
1435
+ */
1436
+ commitCellInput(rowId: string, colId: string, raw: string): SpreadsheetCommitResult;
1437
+ /** Validates input; when it fails, records and returns the prompt. */
1438
+ private checkInput;
1439
+ /**
1440
+ * Answers `validationPrompt`: `accept` keeps the input (warning and
1441
+ * information alerts only; for a stop alert it acts as `retry`), `retry`
1442
+ * returns to editing it, `cancel` discards it.
1443
+ */
1444
+ resolveValidationPrompt(action: SpreadsheetValidationAction): void;
1445
+ cancelEditing(): void;
1446
+ moveCursor(direction: 'up' | 'down' | 'left' | 'right', extendSelection?: boolean): void;
1447
+ insertColumn(index: number, config?: Partial<SpreadsheetColumn>): void;
1448
+ deleteColumn(colId: string): void;
1449
+ insertRow(index: number, config?: Partial<SpreadsheetRow>): void;
1450
+ deleteRow(rowId: string): void;
1451
+ private generateId;
1452
+ /**
1453
+ * Rewrites references in every cell formula (and, for column changes, every
1454
+ * column formula) so they keep pointing at the same cells.
1455
+ */
1456
+ private shiftReferences;
1457
+ /** Filter for references, in formulas on sheet `on`, that point at sheet `target`. */
1458
+ private referencesTo;
1459
+ setColumnWidth(colId: string, width: number): void;
1460
+ autoFitColumnWidth(colId: string, customWidth?: number): void;
1461
+ /**
1462
+ * Exports cell values as TSV: the whole sheet, or only `range` (e.g. the
1463
+ * current selection) when given.
1464
+ */
1465
+ exportToTsv(range?: CellRange | null): string;
1466
+ /**
1467
+ * Pastes tab-separated values starting at (startRow, startCol), adding rows
1468
+ * and columns as needed. The whole paste is a single undo step.
1469
+ */
1470
+ importFromTsv(tsvData: string, startRow?: number, startCol?: number): void;
1471
+ /** Adds rows/columns at the end until (rowIndex, colIndex) exists. */
1472
+ private growGrid;
1473
+ /**
1474
+ * Writes raw inputs starting at (startRow, startCol), growing the grid as
1475
+ * needed, as a single undo step with one recalculation.
1476
+ */
1477
+ private writeMatrix;
1478
+ /**
1479
+ * Runs `fn` as one undo step: cell writes inside it are batched and
1480
+ * recalculated once, then listeners are notified.
1481
+ */
1482
+ private runBatch;
1483
+ /**
1484
+ * Exports the sheet (or `range`) as RFC 4180 CSV. Values are exported as
1485
+ * displayed unless `formulas` is set.
1486
+ */
1487
+ exportToCsv(options?: CsvExportOptions): string;
1488
+ /**
1489
+ * Imports CSV text at (startRow, startCol) (default A1), growing the grid
1490
+ * as needed. The whole import is a single undo step.
1491
+ */
1492
+ importFromCsv(csv: string, options?: CsvImportOptions): void;
1493
+ /** Runs `fn` on the sheet `sheet` (id or name), default the active one. Throws for an unknown sheet. */
1494
+ private onTargetSheet;
1495
+ /**
1496
+ * Writes already-parsed rows of raw inputs (e.g. from an import adapter)
1497
+ * starting at (startRow, startCol), as a single undo step.
1498
+ */
1499
+ importRows(rows: string[][], options?: Omit<CsvImportOptions, 'delimiter'>): void;
1500
+ /** The cells of `range` (or the whole sheet), row by row. */
1501
+ private readMatrix;
1502
+ /**
1503
+ * Builds clipboard data for `range` (default: the selection) as TSV,
1504
+ * an HTML table and the lossless internal JSON format. Write every entry
1505
+ * with `clipboardData.setData(type, data)` in a `copy` event.
1506
+ */
1507
+ copyToClipboardData(range?: CellRange | null): SpreadsheetClipboardData;
1508
+ /**
1509
+ * Pastes clipboard data at `target` (default: the selection's top-left).
1510
+ * Prefers the internal format (formulas re-based to the target), then an
1511
+ * HTML table, then TSV. Returns false when there was nothing to paste.
1512
+ */
1513
+ pasteClipboardData(source: SpreadsheetClipboardSource, target?: CellPosition): boolean;
1514
+ private spillAnchorInRange;
1515
+ private getSelectionTopLeft;
1516
+ /** The table settings object, created on first use. */
1517
+ private get table();
1518
+ /** Records an undo step, applies `fn`, then notifies listeners. */
1519
+ private applyTableChange;
1520
+ /** First and last (inclusive) body row: rows between header and footer rows. */
1521
+ private getBodyRowBounds;
1522
+ private getCellValueAt;
1523
+ /** Rewrites every formula so references follow cells that moved. */
1524
+ private remapAllFormulas;
1525
+ /**
1526
+ * Keeps merges in place when rows/columns are inserted or deleted:
1527
+ * merges after the change shift, merges across it grow or shrink, and
1528
+ * merges reduced to a single cell are dropped.
1529
+ */
1530
+ private adjustTableForStructuralChange;
1531
+ /**
1532
+ * Sorts rows by one or more columns (stable; numbers before text, blanks
1533
+ * last). Without a range (or with a range spanning every column) whole rows
1534
+ * move; with a range only the cells inside it move. Header and footer rows
1535
+ * never move. References follow the moved cells. Returns false when the
1536
+ * sort is rejected (no valid keys, a key outside the range, or merged
1537
+ * cells in the sorted area).
1538
+ */
1539
+ sortRows(keys: SortKey[], options?: {
1540
+ range?: CellRange | null;
1541
+ }): boolean;
1542
+ getFilterState(): SpreadsheetFilterState;
1543
+ /** Replaces all filter rules (and turns filters on when there are any). */
1544
+ setFilterRules(rules: NewFilterRule[]): void;
1545
+ /** Adds a filter rule (AND-combined with the others) and turns filters on. Returns its id. */
1546
+ addFilterRule(rule: NewFilterRule): string;
1547
+ updateFilterRule(ruleId: string, changes: Partial<Omit<FilterRule, 'id'>>): void;
1548
+ removeFilterRule(ruleId: string): void;
1549
+ clearFilters(): void;
1550
+ /** Turns filtering on or off, keeping the rules. */
1551
+ setFiltersEnabled(enabled: boolean): void;
1552
+ toggleFilters(): void;
1553
+ private generateFilterId;
1554
+ setHeaderRowCount(count: number): void;
1555
+ setFooterRowCount(count: number): void;
1556
+ setHeaderColumnCount(count: number): void;
1557
+ /** Keeps the first `count` rows visible while scrolling. 0 unfreezes. */
1558
+ setFrozenRowCount(count: number): void;
1559
+ /** Keeps the first `count` columns visible while scrolling. 0 unfreezes. */
1560
+ setFrozenColumnCount(count: number): void;
1561
+ private setTableCount;
1562
+ /**
1563
+ * Sets an explicit number format code (e.g. `0.00`, `"$"#,##0.00`,
1564
+ * `m/d/yyyy`, `[Red]0;[Blue]-0`) on every cell in `range`, including blank
1565
+ * cells, so values typed later keep it. `null` removes explicit formats: the
1566
+ * cells go back to their column's format or the one chosen for typed input.
1567
+ * Undoable as one step. Returns false when there is no range.
1568
+ */
1569
+ setCellNumberFormat(range: CellRange | null, code: string | null): boolean;
1570
+ /**
1571
+ * Sets the number format code of a column (`null` or `General` clears it).
1572
+ * Its cells without an explicit format of their own use it, including
1573
+ * values typed later; when cleared they go back to the format chosen for
1574
+ * typed input. Undoable.
1575
+ */
1576
+ setColumnNumberFormat(colId: string, code: string | null): void;
1577
+ /** The column's format, or the one typed input chose (typed cells only). */
1578
+ private implicitNumberFormat;
1579
+ /** A copy of `cell` with `numberFormat` set, or removed when undefined. */
1580
+ private withNumberFormat;
1581
+ /** Re-applies the stored cell's (or the column's) format to a spilled value shown there. */
1582
+ private refreshSpilledNumberFormat;
1583
+ hideRows(indices: number[]): void;
1584
+ unhideRows(indices: number[]): void;
1585
+ hideColumns(indices: number[]): void;
1586
+ unhideColumns(indices: number[]): void;
1587
+ /** Unhides every hidden row and column (filters are unaffected). */
1588
+ unhideAll(): void;
1589
+ private setHidden;
1590
+ getMerges(): CellRange[];
1591
+ /** The merge containing (row, col), or null. */
1592
+ getMergeAt(row: number, col: number): CellRange | null;
1593
+ /** Grows `range` until no merge crosses its edge. Keeps the drag direction. */
1594
+ expandRangeToMerges(range: CellRange): CellRange;
1595
+ /**
1596
+ * Merges `range` (default: the selection) into one cell anchored on its
1597
+ * top-left cell; the other cells are cleared. Merges fully inside the range
1598
+ * are absorbed. Returns false for single cells and for ranges that
1599
+ * partially overlap an existing merge.
1600
+ */
1601
+ mergeCells(range?: CellRange | null): boolean;
1602
+ /** Removes every merge intersecting `range` (default: the selection). */
1603
+ unmergeCells(range?: CellRange | null): boolean;
1604
+ /**
1605
+ * Fills `target` from `source` like dragging the fill handle. `target` is
1606
+ * the extended range (source included) and must extend `source` down, up,
1607
+ * right or left. Numbers and dates continue their series, text ending in a
1608
+ * number counts up, other text repeats, and formulas are copied with
1609
+ * their relative references shifted (`$` parts stay). Returns false when
1610
+ * the ranges don't line up.
1611
+ */
1612
+ autofill(source: CellRange, target: CellRange): boolean;
1613
+ /**
1614
+ * Groups body rows by the value in `colId`, with optional per-group
1615
+ * summaries (e.g. `[{ colId, aggregate: 'sum' }]`).
1616
+ */
1617
+ groupRowsBy(colId: string, summaries?: GroupSummary[]): void;
1618
+ ungroupRows(): void;
1619
+ /** Sets (or with `null`, removes) the group summary for a column. */
1620
+ setGroupSummary(colId: string, aggregate: GroupAggregate | null): void;
1621
+ setGroupCollapsed(key: string, collapsed: boolean): void;
1622
+ toggleGroupCollapsed(key: string): void;
1623
+ /** The current row groups with their summaries (empty when not grouped). */
1624
+ getGroups(): SpreadsheetRowGroup[];
1625
+ /**
1626
+ * Transposes `range` (default: the selection) in place around its top-left
1627
+ * cell: rows become columns. Cells left uncovered are cleared, the grid
1628
+ * grows if needed, and references follow the moved cells. Returns false
1629
+ * for single cells or when merged cells are involved.
1630
+ */
1631
+ transposeRange(range?: CellRange | null): boolean;
1632
+ /**
1633
+ * What to render: visible rows (with group headers) and columns in display
1634
+ * order, frozen offsets and merged-cell spans. Filters, hidden rows/columns
1635
+ * and collapsed groups only affect this view, never the document.
1636
+ */
1637
+ getViewModel(): SpreadsheetViewModel;
1638
+ /** The sheets in tab order. */
1639
+ getSheets(): SpreadsheetSheetInfo[];
1640
+ /** Id of the active sheet (the one `document` is). */
1641
+ get activeSheetId(): string;
1642
+ /** A sheet's document by id or name (live: don't mutate it directly). */
1643
+ getSheetDocument(idOrName: string): SpreadsheetDocument | undefined;
1644
+ /** Why `name` can't name a sheet (or null): see `validateSheetName`. `exceptSheet` is the sheet being renamed. */
1645
+ validateSheetName(name: string, exceptSheet?: string): string | null;
1646
+ /**
1647
+ * Shows another sheet (by id or name). The current edit is committed and
1648
+ * each sheet keeps its own selection. Returns false for an unknown sheet.
1649
+ */
1650
+ setActiveSheet(idOrName: string): boolean;
1651
+ private activateRuntime;
1652
+ /**
1653
+ * Adds a sheet (default: `Sheet N`, empty, after the last sheet) and
1654
+ * activates it unless `activate` is false. Returns its id. Throws when
1655
+ * `name` is invalid or taken. Undoable.
1656
+ */
1657
+ addSheet(options?: {
1658
+ name?: string;
1659
+ index?: number;
1660
+ document?: Partial<SpreadsheetDocument>;
1661
+ activate?: boolean;
1662
+ }): string;
1663
+ /**
1664
+ * Renames a sheet. Formulas on every sheet and defined names that refer to
1665
+ * it follow (`=Old!A1` becomes `='New Name'!A1`). Throws when the name is
1666
+ * invalid or taken. Undoable.
1667
+ */
1668
+ renameSheet(idOrName: string, newName: string): void;
1669
+ /** Moves a sheet to position `toIndex` in tab order. Returns false for an unknown sheet. Undoable. */
1670
+ moveSheet(idOrName: string, toIndex: number): boolean;
1671
+ /**
1672
+ * Deletes a sheet and its sheet-scoped names. References to it become
1673
+ * `#REF!` (a 3-D reference losing an end sheet shrinks). The last sheet
1674
+ * can't be deleted (returns false). Undoable.
1675
+ */
1676
+ deleteSheet(idOrName: string): boolean;
1677
+ /**
1678
+ * Copies a sheet (default name `Name (2)`, placed after it) with its
1679
+ * sheet-scoped names, which refer to the copy. Activates the copy unless
1680
+ * `activate` is false. Returns the new sheet's id, or null for an unknown
1681
+ * sheet. Undoable.
1682
+ */
1683
+ duplicateSheet(idOrName: string, options?: {
1684
+ name?: string;
1685
+ index?: number;
1686
+ activate?: boolean;
1687
+ }): string | null;
1688
+ /** Applies `rewrite` to every formula: cells and column formulas on every sheet, and defined names. */
1689
+ private rewriteAllFormulas;
1690
+ private generateSheetId;
1691
+ /** Every defined name, workbook-scoped and sheet-scoped. */
1692
+ getNames(): SpreadsheetNameInfo[];
1693
+ /** The defined name `name` visible from the active sheet (its own sheet-scoped name first), or undefined. */
1694
+ getName(name: string, scope?: SpreadsheetNameScope): SpreadsheetNameInfo | undefined;
1695
+ /** Why `name` can't be a defined name (or null): see `validateDefinedName`. */
1696
+ validateDefinedName(name: string): string | null;
1697
+ private scopeRuntime;
1698
+ /**
1699
+ * Defines (or redefines) a name in the workbook, or on one sheet with
1700
+ * `sheet`. `refersTo` is a formula: a range (`=Data!$A$2:$A$20`), a
1701
+ * constant (`=0.07`), a formula or a LAMBDA (`=LAMBDA(x, x*2)`, called as
1702
+ * `=Double(4)`). Formulas using the name recalculate. Throws when the name
1703
+ * is invalid or the formula can't be read. Undoable.
1704
+ */
1705
+ defineName(name: string, refersTo: string, options?: SpreadsheetNameScope & {
1706
+ comment?: string;
1707
+ }): void;
1708
+ /**
1709
+ * Renames a defined name. Formulas that use it (cells, column formulas and
1710
+ * other names) follow, on the sheets where the old name meant this one.
1711
+ * Throws when the name doesn't exist or the new name is invalid or taken.
1712
+ * Undoable.
1713
+ */
1714
+ renameName(oldName: string, newName: string, options?: SpreadsheetNameScope): void;
1715
+ /**
1716
+ * Deletes a defined name. Formulas still using it show `#NAME?`. Returns
1717
+ * false when there is no such name. Undoable.
1718
+ */
1719
+ deleteName(name: string, options?: SpreadsheetNameScope): boolean;
1720
+ /**
1721
+ * Names formula autocomplete can offer on the active sheet: its
1722
+ * sheet-scoped names and the workbook names they don't hide.
1723
+ */
1724
+ getNameSuggestions(): Array<{
1725
+ name: string;
1726
+ description: string;
1727
+ isLambda: boolean;
1728
+ }>;
1729
+ /**
1730
+ * Evaluates a formula (e.g. `=Rate*2`, `=SUM(Sales)`) as if it were in a
1731
+ * cell of `sheet` (id or name; default the active sheet), without storing
1732
+ * it. Used by the Name Manager to show a name's current value.
1733
+ */
1734
+ evaluateFormula(formula: string, options?: {
1735
+ sheet?: string;
1736
+ }): FormulaEvaluationResult;
1737
+ private recordSnapshot;
1738
+ private recordWorkbookSnapshot;
1739
+ private pushUndo;
1740
+ /** Drops the oldest snapshots beyond `maxHistoryBytes`, always keeping the newest. */
1741
+ private trimHistory;
1742
+ /** Approximate bytes held by the undo/redo snapshots (UTF-16 size). */
1743
+ getHistoryByteSize(): number;
1744
+ /** Number of undo / redo snapshots currently held. */
1745
+ getHistoryDepth(): {
1746
+ undo: number;
1747
+ redo: number;
1748
+ };
1749
+ undo(): void;
1750
+ redo(): void;
1751
+ /** Restores the newest entry of `from`, saving the current state of the same scope on `to`. */
1752
+ private applyHistory;
1753
+ private notifyChange;
1754
+ /** The sheet as rule evaluation sees it. */
1755
+ private ruleSheet;
1756
+ /**
1757
+ * Evaluates `formula` as if it were in (row, col), without storing it:
1758
+ * relative references and `[property]` resolve from that cell. With
1759
+ * `entered`, that cell reads as the given value (input being validated).
1760
+ * Returns the value, or an array's values (column-major) for a range.
1761
+ */
1762
+ evaluateFormulaAt(formula: string, row: number, col: number, entered?: {
1763
+ row: number;
1764
+ col: number;
1765
+ value: unknown;
1766
+ }): unknown;
1767
+ /** Records that the value of `cellKey` (and of the array it spills) may have changed. */
1768
+ private markValueChanged;
1769
+ private generateRuleId;
1770
+ /** Moves rule ranges and rule formulas with inserted / deleted rows and columns. */
1771
+ private adjustRulesForStructuralChange;
1772
+ /** Conditional formats of the sheet, highest priority first. */
1773
+ getConditionalFormats(): ConditionalFormatRule[];
1774
+ /**
1775
+ * Adds a conditional format (one undo step). New rules get the highest
1776
+ * priority, as in Excel; pass `priority: 'last'` to add it below the
1777
+ * others. Returns the rule id.
1778
+ */
1779
+ addConditionalFormat(rule: NewConditionalFormatRule, options?: {
1780
+ priority?: 'first' | 'last';
1781
+ }): string;
1782
+ /** Changes a conditional format (its condition, ranges or stop-if-true). Returns false when not found. */
1783
+ updateConditionalFormat(id: string, changes: Partial<NewConditionalFormatRule>): boolean;
1784
+ /** Removes a conditional format. Returns false when not found. */
1785
+ deleteConditionalFormat(id: string): boolean;
1786
+ /**
1787
+ * Moves a conditional format to priority `to` (0 = highest), or by
1788
+ * `{ by: -1 }` (up) / `{ by: 1 }` (down). Returns false when nothing moved.
1789
+ */
1790
+ moveConditionalFormat(id: string, to: number | {
1791
+ by: number;
1792
+ }): boolean;
1793
+ /**
1794
+ * Removes conditional formatting from the cells of `range` (rules keep
1795
+ * their other cells; rules left without cells are deleted), or every rule
1796
+ * when `range` is null.
1797
+ */
1798
+ clearConditionalFormats(range?: CellRange | null): void;
1799
+ /**
1800
+ * The conditional look of every formatted cell. Evaluated on demand and
1801
+ * cached: after a cell edit only the affected cells are re-evaluated.
1802
+ */
1803
+ getConditionalFormatOverlay(): ConditionalFormatOverlay;
1804
+ /** The conditional look of (row, col), if any. */
1805
+ getConditionalFormat(row: number, col: number): ConditionalCellFormat | undefined;
1806
+ /** Data validation rules of the sheet. */
1807
+ getDataValidations(): DataValidationRule[];
1808
+ /** The rule that applies to (row, col), if any. */
1809
+ getDataValidationAt(row: number, col: number): DataValidationRule | undefined;
1810
+ /**
1811
+ * Adds a data validation rule (one undo step). Its cells are first
1812
+ * removed from other rules, so each cell has at most one. Returns the id.
1813
+ */
1814
+ addDataValidation(rule: NewDataValidationRule): string;
1815
+ /** Changes a data validation rule. Returns false when not found. */
1816
+ updateDataValidation(id: string, changes: Partial<NewDataValidationRule>): boolean;
1817
+ /** Removes a data validation rule. Returns false when not found. */
1818
+ deleteDataValidation(id: string): boolean;
1819
+ /** Removes validation from the cells of `range`, or every rule when `range` is null. */
1820
+ clearDataValidation(range?: CellRange | null): void;
1821
+ /** Checks input for (row, col) against its data validation, without committing it. */
1822
+ validateCellInput(row: number, col: number, raw: string): DataValidationResult;
1823
+ /**
1824
+ * Dropdown items of a list-validated cell, or null when the cell has no
1825
+ * list rule (or its in-cell dropdown is off).
1826
+ */
1827
+ getValidationListValues(row: number, col: number): string[] | null;
1828
+ /** Cells whose current value breaks their validation rule. */
1829
+ findInvalidCells(): CellPosition[];
1830
+ /**
1831
+ * Turns "circle invalid data" on or off. View state, not part of the
1832
+ * document (not undoable, not saved); listeners are notified so the grid
1833
+ * redraws.
1834
+ */
1835
+ setInvalidDataCircles(show: boolean): void;
1836
+ /** Whether invalid cells are circled. */
1837
+ getInvalidDataCircles(): boolean;
1838
+ /** Whether (row, col) is circled as invalid (always false while circles are off). */
1839
+ isInvalidDataCircled(row: number, col: number): boolean;
1840
+ }
1841
+
1842
+ export { type GroupSummary as $, type ASTNode as A, type BinaryOpNode as B, type CellCoordinate as C, DEFAULT_COLUMN_WIDTH as D, type DataValidationResult as E, type DataValidationRule as F, type DataValidationSheet as G, type DataValidationType as H, DependencyGraph as I, type EvaluationContext as J, FORMULA_ERRORS as K, type FilterOperator as L, type FilterRule as M, type FormulaDiagnostic as N, type FormulaErrorCode as O, type FormulaEvaluationResult as P, FormulaEvaluator as Q, type FormulaNameDefinition as R, SpreadsheetController as S, FormulaParser as T, type FormulaRange as U, type FormulaReferenceFilter as V, type FormulaReferenceInfo as W, type FormulaToken as X, type FormulaTokenType as Y, type FunctionCallNode as Z, type GroupAggregate as _, type CellData as a, getTableSections as a$, type InvokeNode as a0, type LiteralNode as a1, MAX_FORMULA_ARRAY_SIZE as a2, type MissingNode as a3, type NameDep as a4, type NameNode as a5, type NewConditionalFormatRule as a6, type NewDataValidationRule as a7, type NewFilterRule as a8, type ParsedSpreadsheetClipboard as a9, type SpreadsheetRowSection as aA, type SpreadsheetSheetInfo as aB, type SpreadsheetSpill as aC, type SpreadsheetTableSettings as aD, type SpreadsheetValidationAction as aE, type SpreadsheetValidationPrompt as aF, type SpreadsheetViewColumn as aG, type SpreadsheetViewModel as aH, type SpreadsheetViewRow as aI, type SpreadsheetWorkbook as aJ, type StructuralChange as aK, type UnaryOpNode as aL, WHOLE_COLUMN_END_ROW as aM, buildSpreadsheetView as aN, colNameToIndex as aO, columnDependencyKey as aP, compareNumbers as aQ, compareValues as aR, computeRowGroups as aS, createSpreadsheetClipboardData as aT, deleteSheetInFormula as aU, describeFormulaError as aV, extractCellDependencies as aW, extractNameDependencies as aX, formatSheetPrefix as aY, formulaIdentifiers as aZ, getRowSection as a_, type PropertyRefNode as aa, type RangeNode as ab, type RowType as ac, SPREADSHEET_CLIPBOARD_MIME as ad, type SheetQualifier as ae, type SortDirection as af, type SortKey as ag, type SpillRefNode as ah, type SpreadsheetCellSpan as ai, type SpreadsheetClipboardCell as aj, type SpreadsheetClipboardData as ak, type SpreadsheetClipboardPayload as al, type SpreadsheetClipboardSource as am, type SpreadsheetColumn as an, type SpreadsheetCommitResult as ao, type SpreadsheetControllerOptions as ap, type SpreadsheetDataSource as aq, type SpreadsheetDataSourceField as ar, type SpreadsheetDefinedName as as, type SpreadsheetDocument as at, type SpreadsheetFilterState as au, type SpreadsheetGrouping as av, type SpreadsheetNameInfo as aw, type SpreadsheetNameScope as ax, type SpreadsheetRow as ay, type SpreadsheetRowGroup as az, type CellDep as b, indexToColName as b0, isFormulaError as b1, mapFormulaReferences as b2, numberToText as b3, offsetFormulaReferences as b4, parseCellReference as b5, parseFormula as b6, parseHtmlTable as b7, parseRange as b8, quoteSheetName as b9, readSpreadsheetClipboard as ba, rebaseClipboardRows as bb, remapFormulaReferences as bc, renameNameInFormula as bd, renameSheetInFormula as be, rowPassesFilters as bf, serializeHtmlTable as bg, sheetNameNeedsQuotes as bh, shiftFormulaReferences as bi, sortCompareValues as bj, tokenizeFormula as bk, type CellFormat as c, type CellPosition as d, type CellRange as e, type CellRefNode as f, type CellValueReader as g, type ColumnBinding as h, type ColumnType as i, type ConditionalCellFormat as j, type ConditionalFormatCondition as k, type ConditionalFormatIconSet as l, type ConditionalFormatOperator as m, type ConditionalFormatOverlay as n, type ConditionalFormatRule as o, type ConditionalFormatSheet as p, type ConditionalFormatStyle as q, type ConditionalFormatTimePeriod as r, type ConditionalFormatType as s, type ConditionalFormatValue as t, type CsvExportOptions as u, type CsvImportOptions as v, DEFAULT_ROW_HEIGHT as w, DataSourceBinder as x, type DataValidationErrorStyle as y, type DataValidationOperator as z };