@svgrid/enterprise 3.0.1 → 3.0.3

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 (445) hide show
  1. package/LICENSE +94 -24
  2. package/README.md +36 -4
  3. package/dist/SvAdvancedFilter.svelte +1 -1
  4. package/dist/SvAlertsManager.svelte +2 -1
  5. package/dist/SvBoard.svelte +2 -1
  6. package/dist/SvExportMenu.svelte +4 -1
  7. package/dist/SvExportMenu.svelte.d.ts +0 -13
  8. package/dist/SvExpressionEditor.svelte +3 -3
  9. package/dist/SvFormulaBar.svelte +680 -0
  10. package/dist/SvFormulaBar.svelte.d.ts +69 -0
  11. package/dist/SvGridAlerts.svelte +49 -9
  12. package/dist/SvGridBoard.svelte +13 -8
  13. package/dist/SvGridBulkEditDrawer.svelte +26 -2
  14. package/dist/SvGridEditPanel.svelte +3 -0
  15. package/dist/SvGridScheduler.svelte +69 -40
  16. package/dist/SvGridSelectionBar.svelte +10 -3
  17. package/dist/SvPivotDesigner.svelte +263 -54
  18. package/dist/SvPivotDesigner.svelte.d.ts +27 -20
  19. package/dist/SvRibbonIcon.svelte +46 -0
  20. package/dist/SvRibbonIcon.svelte.d.ts +17 -0
  21. package/dist/SvSchemaChart.svelte +4 -2
  22. package/dist/SvSheet.svelte +7914 -0
  23. package/dist/SvSheet.svelte.d.ts +215 -0
  24. package/dist/SvSheetChartSetup.svelte +151 -0
  25. package/dist/SvSheetChartSetup.svelte.d.ts +18 -0
  26. package/dist/SvSheetComment.svelte +283 -0
  27. package/dist/SvSheetComment.svelte.d.ts +22 -0
  28. package/dist/SvSheetConditionalFormat.svelte +159 -0
  29. package/dist/SvSheetConditionalFormat.svelte.d.ts +14 -0
  30. package/dist/SvSheetDataValidation.svelte +273 -0
  31. package/dist/SvSheetDataValidation.svelte.d.ts +14 -0
  32. package/dist/SvSheetEditRanges.svelte +217 -0
  33. package/dist/SvSheetEditRanges.svelte.d.ts +15 -0
  34. package/dist/SvSheetErrors.svelte +125 -0
  35. package/dist/SvSheetErrors.svelte.d.ts +20 -0
  36. package/dist/SvSheetEvaluate.svelte +133 -0
  37. package/dist/SvSheetEvaluate.svelte.d.ts +15 -0
  38. package/dist/SvSheetFilterMenu.svelte +320 -0
  39. package/dist/SvSheetFilterMenu.svelte.d.ts +22 -0
  40. package/dist/SvSheetFindReplace.svelte +132 -0
  41. package/dist/SvSheetFindReplace.svelte.d.ts +10 -0
  42. package/dist/SvSheetFormatCells.svelte +465 -0
  43. package/dist/SvSheetFormatCells.svelte.d.ts +17 -0
  44. package/dist/SvSheetGoalSeek.svelte +145 -0
  45. package/dist/SvSheetGoalSeek.svelte.d.ts +12 -0
  46. package/dist/SvSheetInsertFunction.svelte +149 -0
  47. package/dist/SvSheetInsertFunction.svelte.d.ts +8 -0
  48. package/dist/SvSheetIteration.svelte +81 -0
  49. package/dist/SvSheetIteration.svelte.d.ts +10 -0
  50. package/dist/SvSheetLink.svelte +99 -0
  51. package/dist/SvSheetLink.svelte.d.ts +17 -0
  52. package/dist/SvSheetListPicker.svelte +91 -0
  53. package/dist/SvSheetListPicker.svelte.d.ts +10 -0
  54. package/dist/SvSheetManageRules.svelte +187 -0
  55. package/dist/SvSheetManageRules.svelte.d.ts +16 -0
  56. package/dist/SvSheetNameManager.svelte +227 -0
  57. package/dist/SvSheetNameManager.svelte.d.ts +11 -0
  58. package/dist/SvSheetPageSetup.svelte +159 -0
  59. package/dist/SvSheetPageSetup.svelte.d.ts +13 -0
  60. package/dist/SvSheetPasteSpecial.svelte +107 -0
  61. package/dist/SvSheetPasteSpecial.svelte.d.ts +12 -0
  62. package/dist/SvSheetPivot.svelte +220 -0
  63. package/dist/SvSheetPivot.svelte.d.ts +21 -0
  64. package/dist/SvSheetProtectSheet.svelte +81 -0
  65. package/dist/SvSheetProtectSheet.svelte.d.ts +11 -0
  66. package/dist/SvSheetRemoveDuplicates.svelte +152 -0
  67. package/dist/SvSheetRemoveDuplicates.svelte.d.ts +12 -0
  68. package/dist/SvSheetRibbon.svelte +1254 -0
  69. package/dist/SvSheetRibbon.svelte.d.ts +34 -0
  70. package/dist/SvSheetSizeDialog.svelte +60 -0
  71. package/dist/SvSheetSizeDialog.svelte.d.ts +11 -0
  72. package/dist/SvSheetSort.svelte +218 -0
  73. package/dist/SvSheetSort.svelte.d.ts +28 -0
  74. package/dist/SvSheetSparklines.svelte +135 -0
  75. package/dist/SvSheetSparklines.svelte.d.ts +14 -0
  76. package/dist/SvSheetTable.svelte +160 -0
  77. package/dist/SvSheetTable.svelte.d.ts +24 -0
  78. package/dist/SvSheetTabs.svelte +571 -0
  79. package/dist/SvSheetTabs.svelte.d.ts +50 -0
  80. package/dist/SvSheetTabs.test-harness.svelte.d.ts +17 -0
  81. package/dist/SvSheetTabs.test-harness.svelte.js +22 -0
  82. package/dist/SvSheetTextToColumns.svelte +172 -0
  83. package/dist/SvSheetTextToColumns.svelte.d.ts +13 -0
  84. package/dist/SvSheetValidationAlert.svelte +85 -0
  85. package/dist/SvSheetValidationAlert.svelte.d.ts +15 -0
  86. package/dist/advanced-filter-enable.js +1 -1
  87. package/dist/alerts/alert-engine.d.ts +6 -0
  88. package/dist/alerts/alert-engine.js +21 -4
  89. package/dist/alerts/alert-formats.js +2 -0
  90. package/dist/alerts/alert-types.d.ts +1 -1
  91. package/dist/alerts.d.ts +1 -1
  92. package/dist/alerts.js +2 -2
  93. package/dist/board.js +2 -2
  94. package/dist/bulk-edit.d.ts +3 -1
  95. package/dist/bulk-edit.js +1 -1
  96. package/dist/cdn/svgrid-enterprise.svelte-external.js +43538 -6539
  97. package/dist/designer/assets/GridMenus-8gTNssgV.js +8 -0
  98. package/dist/designer/assets/SvChartMenu-BDoeqGz6.js +1 -0
  99. package/dist/designer/assets/SvChartMenu-BYO9cYdy.css +1 -0
  100. package/dist/designer/assets/SvDateRangeInput-BBRzrQeg.js +1 -0
  101. package/dist/designer/assets/SvDateTimePicker-DCPg7WGN.js +1 -0
  102. package/dist/designer/assets/SvGridCellEditor-DMoWJjEI.js +4 -0
  103. package/dist/designer/assets/SvGridChart-BgLuPO7I.css +1 -0
  104. package/dist/designer/assets/SvGridChart-Cy1ATrWh.js +3 -0
  105. package/dist/designer/assets/SvGridChartBuilder-08YWWeqY.css +1 -0
  106. package/dist/designer/assets/SvGridChartBuilder-eQ3mn0L9.js +1 -0
  107. package/dist/designer/assets/SvGridChartPanel-4Pc8y5yO.css +1 -0
  108. package/dist/designer/assets/SvGridChartPanel-CATdVc9X.js +4 -0
  109. package/dist/designer/assets/{SvGridChartView-DUc-1RUf.css → SvGridChartView-7msfnWZT.css} +1 -1
  110. package/dist/designer/assets/SvGridChartView-CmsZtCED.js +1 -0
  111. package/dist/designer/assets/SvGridDropdown-Cjz0H-fI.js +1 -0
  112. package/dist/designer/assets/SvListBox-BDS66lmZ.js +110 -0
  113. package/dist/designer/assets/SvMenuList-DJ47ba1h.css +1 -0
  114. package/dist/designer/assets/SvMenuList-Dgq2D5VN.js +1 -0
  115. package/dist/designer/assets/SvTabs-2mHC6oaz.js +1 -0
  116. package/dist/designer/assets/SvTabs-DKmwb5p1.css +1 -0
  117. package/dist/designer/assets/cell-formatting-BbubJTVz.js +1 -0
  118. package/dist/designer/assets/chart-Cn7MnNqA.js +1 -0
  119. package/dist/designer/assets/chart-export-B6bkQ3X8.js +11 -0
  120. package/dist/designer/assets/chart-export-pdf-BbA28-gt.js +11 -0
  121. package/dist/designer/assets/chart-panel-messages-Dz7PTIqT.js +1 -0
  122. package/dist/designer/assets/chart-summary-BD1qYB2R.js +1 -0
  123. package/dist/designer/assets/chart-trend-B8xr5LuD.js +1 -0
  124. package/dist/designer/assets/chart-validate-BMqM-qkF.js +1 -0
  125. package/dist/designer/assets/column-resize-BYDzR1Ve.js +1 -0
  126. package/dist/designer/assets/date-format-B8JbEtIG.js +1 -0
  127. package/dist/designer/assets/date-format-DKS-z0xS.css +1 -0
  128. package/dist/designer/assets/{dismissable-BO547MH9.js → dismissable-ChWRPkoa.js} +1 -1
  129. package/dist/designer/assets/editor-contract-Bpoa7A5g.js +1 -0
  130. package/dist/designer/assets/{export-format-D-eP4b2l.js → export-format-DGckmgKr.js} +1 -1
  131. package/dist/designer/assets/focus-trap-V2-6Fy9I.js +1 -0
  132. package/dist/designer/assets/{index-C_a9Cj8Y.js → index-D5bVbuzI.js} +318 -315
  133. package/dist/designer/assets/index-_JVFxt02.css +1 -0
  134. package/dist/designer/assets/list-option-BP_dWS66.js +1 -0
  135. package/dist/designer/assets/row-resize-BInFWCpr.js +1 -0
  136. package/dist/designer/assets/server-block-cache-CXJKkJpy.js +1 -0
  137. package/dist/designer/assets/src-CITpcm6b.js +1 -0
  138. package/dist/designer/assets/src-DUQ4xE3x.js +58 -0
  139. package/dist/designer/assets/validate-C3B8QKsM.js +1 -0
  140. package/dist/designer/index.html +29 -19
  141. package/dist/export-pdf.d.ts +164 -0
  142. package/dist/export-pdf.js +346 -15
  143. package/dist/export.js +25 -10
  144. package/dist/gantt/SvGridGantt.svelte +2890 -0
  145. package/dist/gantt/SvGridGantt.svelte.d.ts +30 -0
  146. package/dist/gantt/gantt-config.d.ts +73 -0
  147. package/dist/gantt/gantt-config.js +1 -0
  148. package/dist/gantt/gantt-critical-path.d.ts +67 -0
  149. package/dist/gantt/gantt-critical-path.js +207 -0
  150. package/dist/gantt/gantt-model.d.ts +257 -0
  151. package/dist/gantt/gantt-model.js +651 -0
  152. package/dist/gantt/gantt-resources.d.ts +59 -0
  153. package/dist/gantt/gantt-resources.js +71 -0
  154. package/dist/gantt/gantt.d.ts +7 -0
  155. package/dist/gantt/gantt.js +36 -0
  156. package/dist/gantt/index.d.ts +15 -0
  157. package/dist/gantt/index.js +22 -0
  158. package/dist/gantt/timeline-arrows.d.ts +102 -0
  159. package/dist/gantt/timeline-arrows.js +181 -0
  160. package/dist/import.d.ts +2 -2
  161. package/dist/import.js +1 -1
  162. package/dist/index.d.ts +93 -3
  163. package/dist/index.js +107 -3
  164. package/dist/install.js +13 -1
  165. package/dist/license-core.d.ts +17 -1
  166. package/dist/license-core.js +16 -5
  167. package/dist/license.d.ts +18 -2
  168. package/dist/license.js +71 -6
  169. package/dist/node/studio.js +203 -9
  170. package/dist/pivot-chart.d.ts +25 -1
  171. package/dist/pivot-chart.js +25 -69
  172. package/dist/pivot-enable.js +2 -2
  173. package/dist/scheduler-dependencies.d.ts +35 -0
  174. package/dist/scheduler-dependencies.js +36 -1
  175. package/dist/scheduler.js +2 -2
  176. package/dist/selection-bar.js +2 -2
  177. package/dist/server/SvGroupCell.svelte +213 -0
  178. package/dist/server/SvGroupCell.svelte.d.ts +62 -0
  179. package/dist/server/SvRowGroupPanel.svelte +322 -0
  180. package/dist/server/SvRowGroupPanel.svelte.d.ts +37 -0
  181. package/dist/server/enable.d.ts +17 -0
  182. package/dist/server/enable.js +49 -0
  183. package/dist/server/index.d.ts +22 -0
  184. package/dist/server/index.js +24 -0
  185. package/dist/server/messages.d.ts +45 -0
  186. package/dist/server/messages.js +35 -0
  187. package/dist/server/server-group-model.d.ts +104 -0
  188. package/dist/server/server-group-model.js +272 -0
  189. package/dist/server/server-pivot.d.ts +46 -0
  190. package/dist/server/server-pivot.js +57 -0
  191. package/dist/server/server-row-model.d.ts +547 -0
  192. package/dist/server/server-row-model.js +1551 -0
  193. package/dist/server/server-selection.d.ts +99 -0
  194. package/dist/server/server-selection.js +215 -0
  195. package/dist/server/svgrid-adapter.d.ts +155 -0
  196. package/dist/server/svgrid-adapter.js +202 -0
  197. package/dist/sheet/address.d.ts +43 -0
  198. package/dist/sheet/address.js +81 -0
  199. package/dist/sheet/ast.d.ts +138 -0
  200. package/dist/sheet/ast.js +70 -0
  201. package/dist/sheet/auto-filter.d.ts +120 -0
  202. package/dist/sheet/auto-filter.js +295 -0
  203. package/dist/sheet/autocomplete.d.ts +51 -0
  204. package/dist/sheet/autocomplete.js +248 -0
  205. package/dist/sheet/cell-images.d.ts +39 -0
  206. package/dist/sheet/cell-images.js +90 -0
  207. package/dist/sheet/cell-types.d.ts +58 -0
  208. package/dist/sheet/cell-types.js +96 -0
  209. package/dist/sheet/coerce.d.ts +71 -0
  210. package/dist/sheet/coerce.js +289 -0
  211. package/dist/sheet/commands.d.ts +89 -0
  212. package/dist/sheet/commands.js +230 -0
  213. package/dist/sheet/comments.d.ts +63 -0
  214. package/dist/sheet/comments.js +131 -0
  215. package/dist/sheet/conditional-formats.d.ts +167 -0
  216. package/dist/sheet/conditional-formats.js +341 -0
  217. package/dist/sheet/csv.d.ts +32 -0
  218. package/dist/sheet/csv.js +158 -0
  219. package/dist/sheet/culture.d.ts +87 -0
  220. package/dist/sheet/culture.js +247 -0
  221. package/dist/sheet/delta.d.ts +102 -0
  222. package/dist/sheet/delta.js +203 -0
  223. package/dist/sheet/deps.d.ts +104 -0
  224. package/dist/sheet/deps.js +274 -0
  225. package/dist/sheet/document.d.ts +252 -0
  226. package/dist/sheet/document.js +465 -0
  227. package/dist/sheet/edit-keys.d.ts +14 -0
  228. package/dist/sheet/edit-keys.js +40 -0
  229. package/dist/sheet/engine.d.ts +67 -0
  230. package/dist/sheet/engine.js +19 -0
  231. package/dist/sheet/entry.d.ts +35 -0
  232. package/dist/sheet/entry.js +226 -0
  233. package/dist/sheet/error-check.d.ts +49 -0
  234. package/dist/sheet/error-check.js +83 -0
  235. package/dist/sheet/evaluate-steps.d.ts +48 -0
  236. package/dist/sheet/evaluate-steps.js +196 -0
  237. package/dist/sheet/evaluate.d.ts +128 -0
  238. package/dist/sheet/evaluate.js +1049 -0
  239. package/dist/sheet/filter-files.d.ts +37 -0
  240. package/dist/sheet/filter-files.js +465 -0
  241. package/dist/sheet/find-replace.d.ts +62 -0
  242. package/dist/sheet/find-replace.js +152 -0
  243. package/dist/sheet/format-store.d.ts +114 -0
  244. package/dist/sheet/format-store.js +243 -0
  245. package/dist/sheet/freeze.d.ts +54 -0
  246. package/dist/sheet/freeze.js +58 -0
  247. package/dist/sheet/from-rows.d.ts +14 -0
  248. package/dist/sheet/from-rows.js +50 -0
  249. package/dist/sheet/function-catalog.d.ts +10 -0
  250. package/dist/sheet/function-catalog.js +385 -0
  251. package/dist/sheet/functions.d.ts +28 -0
  252. package/dist/sheet/functions.js +634 -0
  253. package/dist/sheet/goal-seek.d.ts +73 -0
  254. package/dist/sheet/goal-seek.js +153 -0
  255. package/dist/sheet/index.d.ts +80 -0
  256. package/dist/sheet/index.js +80 -0
  257. package/dist/sheet/links.d.ts +57 -0
  258. package/dist/sheet/links.js +174 -0
  259. package/dist/sheet/merges.d.ts +71 -0
  260. package/dist/sheet/merges.js +137 -0
  261. package/dist/sheet/messages.d.ts +778 -0
  262. package/dist/sheet/messages.js +806 -0
  263. package/dist/sheet/names.d.ts +31 -0
  264. package/dist/sheet/names.js +87 -0
  265. package/dist/sheet/navigate.d.ts +52 -0
  266. package/dist/sheet/navigate.js +135 -0
  267. package/dist/sheet/number-format.d.ts +110 -0
  268. package/dist/sheet/number-format.js +905 -0
  269. package/dist/sheet/objects.d.ts +106 -0
  270. package/dist/sheet/objects.js +149 -0
  271. package/dist/sheet/ods-document.d.ts +44 -0
  272. package/dist/sheet/ods-document.js +1275 -0
  273. package/dist/sheet/open-file.d.ts +26 -0
  274. package/dist/sheet/open-file.js +56 -0
  275. package/dist/sheet/outline.d.ts +82 -0
  276. package/dist/sheet/outline.js +228 -0
  277. package/dist/sheet/packs/array.d.ts +16 -0
  278. package/dist/sheet/packs/array.js +172 -0
  279. package/dist/sheet/packs/database.d.ts +42 -0
  280. package/dist/sheet/packs/database.js +142 -0
  281. package/dist/sheet/packs/engineering.d.ts +2 -0
  282. package/dist/sheet/packs/engineering.js +296 -0
  283. package/dist/sheet/packs/financial.d.ts +5 -0
  284. package/dist/sheet/packs/financial.js +220 -0
  285. package/dist/sheet/packs/math-stats.d.ts +2 -0
  286. package/dist/sheet/packs/math-stats.js +372 -0
  287. package/dist/sheet/packs/special.d.ts +44 -0
  288. package/dist/sheet/packs/special.js +187 -0
  289. package/dist/sheet/packs/stats-dist.d.ts +2 -0
  290. package/dist/sheet/packs/stats-dist.js +785 -0
  291. package/dist/sheet/packs/text-date.d.ts +2 -0
  292. package/dist/sheet/packs/text-date.js +332 -0
  293. package/dist/sheet/packs/trig.d.ts +2 -0
  294. package/dist/sheet/packs/trig.js +73 -0
  295. package/dist/sheet/page-setup.d.ts +73 -0
  296. package/dist/sheet/page-setup.js +73 -0
  297. package/dist/sheet/palette.d.ts +19 -0
  298. package/dist/sheet/palette.js +84 -0
  299. package/dist/sheet/parse.d.ts +13 -0
  300. package/dist/sheet/parse.js +140 -0
  301. package/dist/sheet/paste-special.d.ts +186 -0
  302. package/dist/sheet/paste-special.js +601 -0
  303. package/dist/sheet/pivot-range.d.ts +160 -0
  304. package/dist/sheet/pivot-range.js +333 -0
  305. package/dist/sheet/presence.d.ts +73 -0
  306. package/dist/sheet/presence.js +79 -0
  307. package/dist/sheet/print.d.ts +104 -0
  308. package/dist/sheet/print.js +169 -0
  309. package/dist/sheet/protection.d.ts +75 -0
  310. package/dist/sheet/protection.js +101 -0
  311. package/dist/sheet/rects.d.ts +45 -0
  312. package/dist/sheet/rects.js +112 -0
  313. package/dist/sheet/refs.d.ts +130 -0
  314. package/dist/sheet/refs.js +413 -0
  315. package/dist/sheet/ribbon-icons.d.ts +31 -0
  316. package/dist/sheet/ribbon-icons.js +536 -0
  317. package/dist/sheet/ribbon.d.ts +173 -0
  318. package/dist/sheet/ribbon.js +1054 -0
  319. package/dist/sheet/sheet-kinds.d.ts +74 -0
  320. package/dist/sheet/sheet-kinds.js +91 -0
  321. package/dist/sheet/shortcuts.d.ts +174 -0
  322. package/dist/sheet/shortcuts.js +674 -0
  323. package/dist/sheet/sort.d.ts +51 -0
  324. package/dist/sheet/sort.js +107 -0
  325. package/dist/sheet/sparklines.d.ts +111 -0
  326. package/dist/sheet/sparklines.js +204 -0
  327. package/dist/sheet/structure.d.ts +87 -0
  328. package/dist/sheet/structure.js +166 -0
  329. package/dist/sheet/table-styles.d.ts +74 -0
  330. package/dist/sheet/table-styles.js +152 -0
  331. package/dist/sheet/tables.d.ts +89 -0
  332. package/dist/sheet/tables.js +178 -0
  333. package/dist/sheet/tokenize.d.ts +71 -0
  334. package/dist/sheet/tokenize.js +355 -0
  335. package/dist/sheet/transforms.d.ts +76 -0
  336. package/dist/sheet/transforms.js +154 -0
  337. package/dist/sheet/validation.d.ts +108 -0
  338. package/dist/sheet/validation.js +278 -0
  339. package/dist/sheet/workbook.d.ts +217 -0
  340. package/dist/sheet/workbook.js +1120 -0
  341. package/dist/sheet/xls-cfb.d.ts +32 -0
  342. package/dist/sheet/xls-cfb.js +290 -0
  343. package/dist/sheet/xls-document.d.ts +10 -0
  344. package/dist/sheet/xls-document.js +1243 -0
  345. package/dist/sheet/xls-formula.d.ts +40 -0
  346. package/dist/sheet/xls-formula.js +569 -0
  347. package/dist/sheet/xlsx-document.d.ts +108 -0
  348. package/dist/sheet/xlsx-document.js +1849 -0
  349. package/dist/sheet/xlsx-drawing.d.ts +99 -0
  350. package/dist/sheet/xlsx-drawing.js +420 -0
  351. package/dist/sheet-enable.d.ts +6 -0
  352. package/dist/sheet-enable.js +45 -0
  353. package/dist/sheet-text.d.ts +7 -0
  354. package/dist/sheet-text.js +29 -0
  355. package/dist/sources/auth-supabase.js +2 -2
  356. package/dist/sources/realtime-supabase.js +2 -2
  357. package/dist/sources/rest.d.ts +6 -2
  358. package/dist/sources/rest.js +42 -7
  359. package/dist/sources/supabase.d.ts +10 -1
  360. package/dist/sources/supabase.js +73 -40
  361. package/dist/studio/emit-project.js +14 -1
  362. package/dist/studio/index.js +1 -1
  363. package/dist/studio/project.d.ts +11 -2
  364. package/dist/studio/project.js +5 -2
  365. package/dist/studio/ui-components.generated.js +170 -3
  366. package/dist/sveltekit/in-memory.d.ts +2 -2
  367. package/dist/sveltekit/in-memory.js +125 -4
  368. package/dist/sveltekit/index.d.ts +1 -1
  369. package/dist/sveltekit/index.js +1 -1
  370. package/dist/sveltekit/query-plan.d.ts +50 -4
  371. package/dist/sveltekit/query-plan.js +25 -3
  372. package/dist/sveltekit/sql-source.d.ts +6 -0
  373. package/dist/sveltekit/sql-source.js +34 -6
  374. package/dist/sveltekit/sql.d.ts +31 -0
  375. package/dist/sveltekit/sql.js +135 -25
  376. package/dist/sveltekit/transport.d.ts +10 -2
  377. package/dist/sveltekit/transport.js +30 -6
  378. package/dist/upgrade-prompt.d.ts +1 -1
  379. package/dist/version.d.ts +1 -1
  380. package/dist/version.js +1 -1
  381. package/dist/watermark.js +35 -2
  382. package/dist/wc/GridMenus-By9vPuq0.js +1088 -0
  383. package/dist/wc/SvChartMenu-CQNrQGT2.js +308 -0
  384. package/dist/wc/SvDateRangeInput-DR6m7bSM.js +199 -0
  385. package/dist/wc/SvDateTimePicker-D-vRnaMo.js +771 -0
  386. package/dist/wc/SvField-B_kurx_P.js +149 -0
  387. package/dist/wc/SvGrid.helpers-BdVDtjUm.js +135 -0
  388. package/dist/wc/SvGridCellEditor-Bnf1Kr5C.js +560 -0
  389. package/dist/wc/SvGridChart-BqUJh2pG.js +3572 -0
  390. package/dist/wc/SvGridChartBuilder-CGycC5cn.js +988 -0
  391. package/dist/wc/SvGridChartPanel-CRnizsHD.js +1746 -0
  392. package/dist/wc/SvGridChartView-D1pa_xMy.js +47 -0
  393. package/dist/wc/SvGridDropdown-45WsObLL.js +259 -0
  394. package/dist/wc/SvModal-DrfOYYyX.js +189 -0
  395. package/dist/wc/cell-formatting-CBfgahv1.js +86 -0
  396. package/dist/wc/chart-6OXlybVT.js +4341 -0
  397. package/dist/wc/chart-export-CeSADGfi.js +135 -0
  398. package/dist/wc/chart-export-pdf-BGko7MER.js +104 -0
  399. package/dist/wc/chart-summary-2m3ia1-n.js +137 -0
  400. package/dist/wc/chart-trend-CQOQtTMl.js +50 -0
  401. package/dist/wc/chart-validate-CD6ptiwg.js +180 -0
  402. package/dist/wc/client-DQIzjDBG.js +3064 -0
  403. package/dist/wc/column-resize-DUPgynvc.js +101 -0
  404. package/dist/wc/date-format-DS-z_h9v.js +1130 -0
  405. package/dist/wc/dismissable-CQ6XFXsk.js +45 -0
  406. package/dist/wc/editor-contract-peBDxir_.js +22 -0
  407. package/dist/wc/editor-registry-DxGKqcvx.js +24 -0
  408. package/dist/wc/focus-trap-Dbb2tJxb.js +65 -0
  409. package/dist/wc/list-option-DrRyivWp.js +82 -0
  410. package/dist/wc/popover-WsGlvtQv.js +69 -0
  411. package/dist/wc/positioning-BiKLfu1E.js +112 -0
  412. package/dist/wc/react.d.ts +41 -0
  413. package/dist/wc/react.js +90 -0
  414. package/dist/wc/rolldown-runtime-Dy4uBu1J.js +11 -0
  415. package/dist/wc/row-drag-touch-CycRR65n.js +93 -0
  416. package/dist/wc/row-resize-limG_N1z.js +111 -0
  417. package/dist/wc/sv-sheet-element.d.ts +97 -0
  418. package/dist/wc/sv-sheet-element.js +44213 -0
  419. package/dist/wc/svelte-virtualizer.svelte-CXtQy2TQ.js +530 -0
  420. package/dist/wc/validate-BqDthkNr.js +88 -0
  421. package/dist/wc/vue.d.ts +31 -0
  422. package/dist/wc/vue.js +75 -0
  423. package/package.json +36 -6
  424. package/dist/designer/assets/GridMenus-B1JtIN21.js +0 -8
  425. package/dist/designer/assets/SvDateRangeInput-CjO7nn_x.js +0 -1
  426. package/dist/designer/assets/SvDateTimePicker-ByBD_ov6.js +0 -1
  427. package/dist/designer/assets/SvField-YDLipR6O.css +0 -1
  428. package/dist/designer/assets/SvField-cj1PFNgZ.js +0 -1
  429. package/dist/designer/assets/SvGridCellEditor-0W1L2hJ1.js +0 -2
  430. package/dist/designer/assets/SvGridChart-DBOR4xcz.js +0 -2
  431. package/dist/designer/assets/SvGridChart-fkMWeh1J.css +0 -1
  432. package/dist/designer/assets/SvGridChartPanel-symrhNnR.js +0 -11
  433. package/dist/designer/assets/SvGridChartView-BmRxq6mU.js +0 -1
  434. package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +0 -1
  435. package/dist/designer/assets/SvListBox-1oUF6Iav.js +0 -110
  436. package/dist/designer/assets/cell-formatting-wr5wm7US.js +0 -1
  437. package/dist/designer/assets/chart-DXFganU8.js +0 -1
  438. package/dist/designer/assets/column-resize-C_inr5zT.js +0 -1
  439. package/dist/designer/assets/date-format-DGagAqRc.css +0 -1
  440. package/dist/designer/assets/date-format-onlYDsrY.js +0 -1
  441. package/dist/designer/assets/easing-zaypKrr0.js +0 -3
  442. package/dist/designer/assets/index-k2stW6L8.css +0 -1
  443. package/dist/designer/assets/row-resize-B0FWHcNr.js +0 -1
  444. package/dist/designer/assets/src-D9p27OGC.js +0 -58
  445. package/dist/designer/assets/validate-h-aslRV9.js +0 -1
@@ -0,0 +1,1049 @@
1
+ /**
2
+ * The evaluator.
3
+ *
4
+ * Errors travel as VALUES once evaluation finishes, but as thrown
5
+ * `FormulaError`s while it runs. That split is deliberate: a coercion buried
6
+ * three calls deep inside a function needs to abort the whole expression, and
7
+ * threading a result type through every branch of every builtin would swamp the
8
+ * table. The throw is caught here, at the one boundary, and becomes a value.
9
+ *
10
+ * Four functions never reach the table because they must NOT have every
11
+ * argument evaluated first: IF and IFS pick a branch, IFERROR needs to catch,
12
+ * and SWITCH matches before evaluating. Evaluating both branches of an IF is
13
+ * not just wasted work - `=IF(A1=0, 0, 100/A1)` would raise #DIV/0! from the
14
+ * branch it did not take.
15
+ */
16
+ import { FormulaError, isError, err, } from './ast.js';
17
+ import { toNumber, toBool, toText, looseEquals, compare } from './coerce.js';
18
+ import { withCustomFunctions } from './functions.js';
19
+ import { ARRAY_FUNCTIONS } from './packs/array.js';
20
+ import { colToLetters } from './address.js';
21
+ import { parseFormula } from './parse.js';
22
+ import { resolveTableRange, columnIndexOf, } from './tables.js';
23
+ const isLambda = (v) => typeof v === 'object' && v !== null && !Array.isArray(v) && 'lambda' in v;
24
+ const isGrid = (v) => Array.isArray(v);
25
+ /** The names a lambda helper takes its function in. */
26
+ const LAMBDA_HELPERS = new Set(['MAP', 'BYROW', 'BYCOL', 'REDUCE', 'SCAN', 'MAKEARRAY']);
27
+ /** A local binding, by name, case-insensitively as Excel reads a name. */
28
+ function localOf(ctx, name) {
29
+ return ctx.locals?.get(name.toUpperCase());
30
+ }
31
+ /** The same context with more names bound over it. */
32
+ function withLocals(ctx, added) {
33
+ const next = new Map(ctx.locals ?? []);
34
+ for (const [name, value] of added)
35
+ next.set(name.toUpperCase(), value);
36
+ return { ...ctx, locals: next };
37
+ }
38
+ function rangeGrid(from, to, ctx) {
39
+ const sheet = from.sheet ?? to.sheet;
40
+ const r1 = Math.min(from.row ?? 0, to.row ?? from.row ?? 0);
41
+ const r2 = to.row === null || from.row === null
42
+ ? ctx.lastRow(sheet)
43
+ : Math.max(from.row, to.row);
44
+ const c1 = Math.min(from.col, to.col);
45
+ const c2 = Math.max(from.col, to.col);
46
+ const out = [];
47
+ for (let r = r1; r <= r2; r += 1) {
48
+ const row = [];
49
+ for (let c = c1; c <= c2; c += 1)
50
+ row.push(ctx.resolve(sheet, r, c));
51
+ out.push(row);
52
+ }
53
+ return out;
54
+ }
55
+ function binary(op, l, r) {
56
+ switch (op) {
57
+ case '+': return toNumber(l) + toNumber(r);
58
+ case '-': return toNumber(l) - toNumber(r);
59
+ case '*': return toNumber(l) * toNumber(r);
60
+ case '/': {
61
+ const d = toNumber(r);
62
+ return d === 0 ? err('#DIV/0!') : toNumber(l) / d;
63
+ }
64
+ case '^': return Math.pow(toNumber(l), toNumber(r));
65
+ case '&': return toText(l) + toText(r);
66
+ case '=': return looseEquals(l, r);
67
+ case '<>': return !looseEquals(l, r);
68
+ case '<': return compare(l, r) < 0;
69
+ case '>': return compare(l, r) > 0;
70
+ case '<=': return compare(l, r) <= 0;
71
+ case '>=': return compare(l, r) >= 0;
72
+ default: return err('#VALUE!');
73
+ }
74
+ }
75
+ /** Functions handled before the table, because their arguments must not all
76
+ * be evaluated up front. */
77
+ const SHORT_CIRCUIT = new Set(['IF', 'IFS', 'IFERROR', 'IFNA', 'SWITCH', 'ISERROR', 'ISERR', 'ISNA']);
78
+ /** Functions that PRODUCE a reference rather than a value. In scalar position
79
+ * they read as their top-left cell, as a range does; as an argument they
80
+ * expand to the range, so =SUM(OFFSET(A1,0,0,3,1)) adds three cells. */
81
+ const REFERENCE_FUNCTIONS = new Set(['OFFSET', 'INDIRECT']);
82
+ /**
83
+ * The rectangle a node stands for: a cell, a range (open-ended ones closed
84
+ * at the last used row), a name that refers to one, or a reference
85
+ * function's result. Null for anything that is a plain value.
86
+ */
87
+ function referenceOf(node, ctx) {
88
+ switch (node.k) {
89
+ case 'ref':
90
+ return { sheet: node.ref.sheet, r1: node.ref.row ?? 0, c1: node.ref.col, r2: node.ref.row ?? 0, c2: node.ref.col };
91
+ case 'range': {
92
+ const sheet = node.from.sheet ?? node.to.sheet;
93
+ const r1 = Math.min(node.from.row ?? 0, node.to.row ?? node.from.row ?? 0);
94
+ const r2 = node.to.row === null || node.from.row === null ? ctx.lastRow(sheet) : Math.max(node.from.row, node.to.row);
95
+ return { sheet, r1, c1: Math.min(node.from.col, node.to.col), r2, c2: Math.max(node.from.col, node.to.col) };
96
+ }
97
+ case 'name': {
98
+ const target = nameTarget(node.name, ctx);
99
+ return target ? referenceOf(target, ctx) : null;
100
+ }
101
+ case 'fn':
102
+ return REFERENCE_FUNCTIONS.has(node.name) ? referenceCall(node, ctx) : null;
103
+ case 'table': {
104
+ // A structured reference is a rectangle too, so SUBTOTAL(109,[Qty])
105
+ // in a totals row skips the rows a filter folds, as Excel's does,
106
+ // rather than reading the column's first cell as a scalar.
107
+ const rect = tableRectOf(node, ctx);
108
+ return rect ? { sheet: rect.sheet, r1: rect.firstRow, c1: rect.firstCol, r2: rect.lastRow, c2: rect.lastCol } : null;
109
+ }
110
+ case 'spill':
111
+ return spillRectOf(node, ctx);
112
+ default:
113
+ return null;
114
+ }
115
+ }
116
+ /**
117
+ * The rectangle a spilled-range operator (`A1#`) stands for: the array the
118
+ * anchor currently spills. Null when the cell is not a spill anchor, which
119
+ * the callers turn into #REF!, the way Excel does for `A1#` on a cell that
120
+ * holds no dynamic array.
121
+ */
122
+ function spillRectOf(node, ctx) {
123
+ const rect = ctx.spillRect?.(node.ref.sheet, node.ref.row ?? 0, node.ref.col);
124
+ return rect ? { sheet: node.ref.sheet, r1: rect[0], c1: rect[1], r2: rect[2], c2: rect[3] } : null;
125
+ }
126
+ /**
127
+ * Every value a 3D reference reads: the cell or rectangle on each sheet in
128
+ * the tab range, in sheet order. Null when a sheet name is unknown, which the
129
+ * callers turn into #REF!. Aggregates take the flat list, so a nested
130
+ * rectangle spans sheet by sheet.
131
+ */
132
+ function values3d(node, ctx) {
133
+ const sheets = ctx.sheetsBetween?.(node.sheetFrom, node.sheetTo);
134
+ if (!sheets)
135
+ return null;
136
+ const r1 = Math.min(node.from.row ?? 0, node.to.row ?? 0);
137
+ const r2 = Math.max(node.from.row ?? 0, node.to.row ?? 0);
138
+ const c1 = Math.min(node.from.col, node.to.col);
139
+ const c2 = Math.max(node.from.col, node.to.col);
140
+ const out = [];
141
+ for (const s of sheets) {
142
+ for (let r = r1; r <= r2; r += 1) {
143
+ for (let c = c1; c <= c2; c += 1)
144
+ out.push(ctx.resolve(s, r, c));
145
+ }
146
+ }
147
+ return out;
148
+ }
149
+ function rectGrid(rect, ctx) {
150
+ return rangeGrid({ sheet: rect.sheet, row: rect.r1, col: rect.c1, rowAbs: false, colAbs: false }, { sheet: rect.sheet, row: rect.r2, col: rect.c2, rowAbs: false, colAbs: false }, ctx);
151
+ }
152
+ const scalarArg = (node, ctx) => (node ? evalNode(node, ctx) : '');
153
+ const optNumber = (node, ctx, fallback) => {
154
+ if (!node || node.k === 'empty')
155
+ return fallback;
156
+ const v = evalNode(node, ctx);
157
+ if (isError(v))
158
+ throw new FormulaError(v.error);
159
+ return v === '' ? fallback : toNumber(v);
160
+ };
161
+ /** OFFSET and INDIRECT: the rectangle they name, or a throw for the error. */
162
+ function referenceCall(node, ctx) {
163
+ const { name, args } = node;
164
+ if (name === 'INDIRECT') {
165
+ const text = scalarArg(args[0], ctx);
166
+ if (isError(text))
167
+ throw new FormulaError(text.error);
168
+ const a1 = args[1] && args[1].k !== 'empty' ? toBool(evalNode(args[1], ctx)) : true;
169
+ if (!a1)
170
+ throw new FormulaError('#REF!');
171
+ let parsed;
172
+ try {
173
+ parsed = parseFormula(`=${toText(text).trim()}`);
174
+ }
175
+ catch {
176
+ throw new FormulaError('#REF!');
177
+ }
178
+ const rect = parsed.k === 'ref' || parsed.k === 'range' || parsed.k === 'name' ? referenceOf(parsed, ctx) : null;
179
+ if (!rect)
180
+ throw new FormulaError('#REF!');
181
+ return rect;
182
+ }
183
+ // OFFSET(reference, rows, cols, [height], [width])
184
+ const base = args[0] ? referenceOf(args[0], ctx) : null;
185
+ if (!base)
186
+ throw new FormulaError('#VALUE!');
187
+ const rows = Math.trunc(optNumber(args[1], ctx, 0));
188
+ const cols = Math.trunc(optNumber(args[2], ctx, 0));
189
+ const height = Math.trunc(optNumber(args[3], ctx, base.r2 - base.r1 + 1));
190
+ const width = Math.trunc(optNumber(args[4], ctx, base.c2 - base.c1 + 1));
191
+ if (height <= 0 || width <= 0)
192
+ throw new FormulaError('#REF!');
193
+ const r1 = base.r1 + rows;
194
+ const c1 = base.c1 + cols;
195
+ if (r1 < 0 || c1 < 0)
196
+ throw new FormulaError('#REF!');
197
+ return { sheet: base.sheet, r1, c1, r2: r1 + height - 1, c2: c1 + width - 1 };
198
+ }
199
+ /** ROW, COLUMN and ADDRESS: about a reference, not its value. */
200
+ function positionCall(node, ctx) {
201
+ const { name, args } = node;
202
+ if (name === 'ADDRESS') {
203
+ const row = Math.trunc(toNumber(scalarArg(args[0], ctx)));
204
+ const col = Math.trunc(toNumber(scalarArg(args[1], ctx)));
205
+ const abs = Math.trunc(optNumber(args[2], ctx, 1));
206
+ if (row < 1 || col < 1 || abs < 1 || abs > 4)
207
+ return err('#VALUE!');
208
+ const sheet = args[4] && args[4].k !== 'empty' ? toText(scalarArg(args[4], ctx)) : '';
209
+ const rowText = `${abs === 1 || abs === 2 ? '$' : ''}${row}`;
210
+ const colText = `${abs === 1 || abs === 3 ? '$' : ''}${colToLetters(col - 1)}`;
211
+ const prefix = sheet ? (/^[A-Za-z_][A-Za-z0-9_]*$/.test(sheet) ? `${sheet}!` : `'${sheet.replace(/'/g, "''")}'!`) : '';
212
+ return `${prefix}${colText}${rowText}`;
213
+ }
214
+ const target = args[0] && args[0].k !== 'empty' ? referenceOf(args[0], ctx) : null;
215
+ if (!target) {
216
+ const here = ctx.currentCell;
217
+ if (!here)
218
+ return err('#VALUE!');
219
+ return name === 'ROW' ? here.row + 1 : here.col + 1;
220
+ }
221
+ return name === 'ROW' ? target.r1 + 1 : target.c1 + 1;
222
+ }
223
+ function evalNode(node, ctx) {
224
+ switch (node.k) {
225
+ case 'num': return node.v;
226
+ case 'str': return node.v;
227
+ case 'bool': return node.v;
228
+ case 'err': return err(node.v);
229
+ case 'empty': return '';
230
+ case 'ref':
231
+ return ctx.resolve(node.ref.sheet, node.ref.row ?? 0, node.ref.col);
232
+ case 'range': {
233
+ // A range in scalar position collapses to its top-left cell, which is
234
+ // what Excel does outside an array context.
235
+ const grid = rangeGrid(node.from, node.to, ctx);
236
+ return grid[0]?.[0] ?? '';
237
+ }
238
+ case 'spill': {
239
+ // The spilled range in scalar position is its top-left, the anchor's
240
+ // own value; a cell that anchors no array is #REF!.
241
+ const rect = spillRectOf(node, ctx);
242
+ return rect ? ctx.resolve(rect.sheet, rect.r1, rect.c1) : err('#REF!');
243
+ }
244
+ case 'ref3d': {
245
+ // In scalar position a 3D reference reads the cell on the first sheet
246
+ // of the range, the way an ordinary range collapses to its top-left.
247
+ const vals = values3d(node, ctx);
248
+ if (!vals)
249
+ return err('#REF!');
250
+ return vals[0] ?? '';
251
+ }
252
+ case 'name': {
253
+ // A name bound inside the formula wins over the workbook's own, which
254
+ // is what makes `=LET(x, 2, x * 3)` mean 6 on a sheet that has an `x`.
255
+ const local = localOf(ctx, node.name);
256
+ if (local !== undefined) {
257
+ // A lambda that is never called is #CALC!, as Excel shows it; a
258
+ // grid in scalar position reads as its top-left cell.
259
+ if (isLambda(local))
260
+ return err('#CALC!');
261
+ if (isGrid(local))
262
+ return local[0]?.[0] ?? '';
263
+ return local;
264
+ }
265
+ const target = nameTarget(node.name, ctx);
266
+ if (target)
267
+ return evalNode(target, ctx);
268
+ const v = ctx.resolveName?.(node.name);
269
+ return v === undefined ? err('#NAME?') : v;
270
+ }
271
+ case 'unary': {
272
+ const v = evalNode(node.arg, ctx);
273
+ if (isError(v))
274
+ return v;
275
+ if (node.op === '-')
276
+ return -toNumber(v);
277
+ if (node.op === '%')
278
+ return toNumber(v) / 100;
279
+ return toNumber(v);
280
+ }
281
+ case 'binary': {
282
+ const l = evalNode(node.left, ctx);
283
+ if (isError(l))
284
+ return l;
285
+ const r = evalNode(node.right, ctx);
286
+ if (isError(r))
287
+ return r;
288
+ return binary(node.op, l, r);
289
+ }
290
+ case 'table':
291
+ return evalTableRef(node, ctx);
292
+ case 'fn':
293
+ return evalCall(node, ctx);
294
+ }
295
+ }
296
+ /**
297
+ * Turn a structured reference into a rectangle and read it.
298
+ *
299
+ * Every failure here is #REF! rather than a throw, because a table reference
300
+ * naming a column that was renamed is an ordinary thing to find in a sheet,
301
+ * and one broken total should not take the rest of the workbook with it.
302
+ */
303
+ export function tableRectOf(node, ctx) {
304
+ const here = ctx.currentCell;
305
+ const table = node.table
306
+ ? ctx.findTable?.(node.table)
307
+ : here
308
+ ? ctx.tableAt?.(here.sheet, here.row, here.col)
309
+ : undefined;
310
+ if (!table)
311
+ return null;
312
+ const headerAt = (sheet, row, col) => {
313
+ const v = ctx.resolve(sheet, row, col);
314
+ return isError(v) ? '' : toText(v);
315
+ };
316
+ let columns = null;
317
+ if (node.column !== null) {
318
+ const from = columnIndexOf(table, node.column, headerAt);
319
+ if (from < 0)
320
+ return null;
321
+ const to = node.columnTo != null
322
+ ? columnIndexOf(table, node.columnTo, headerAt)
323
+ : from;
324
+ if (to < 0)
325
+ return null;
326
+ columns = { from: Math.min(from, to), to: Math.max(from, to) };
327
+ }
328
+ return resolveTableRange(table, node.specifier, columns, here ? here.row : null);
329
+ }
330
+ function evalTableRef(node, ctx) {
331
+ const rect = tableRectOf(node, ctx);
332
+ if (!rect)
333
+ return err('#REF!');
334
+ // Scalar position collapses to the top-left, the same as an A1 range.
335
+ return ctx.resolve(rect.sheet, rect.firstRow, rect.firstCol);
336
+ }
337
+ /** Every cell of a structured reference, for the aggregate functions. */
338
+ function tableGrid(node, ctx) {
339
+ const rect = tableRectOf(node, ctx);
340
+ if (!rect)
341
+ return null;
342
+ const out = [];
343
+ for (let r = rect.firstRow; r <= rect.lastRow; r += 1) {
344
+ const line = [];
345
+ for (let c = rect.firstCol; c <= rect.lastCol; c += 1)
346
+ line.push(ctx.resolve(rect.sheet, r, c));
347
+ out.push(line);
348
+ }
349
+ return out;
350
+ }
351
+ /**
352
+ * The reference a defined name stands for, or null.
353
+ *
354
+ * A name may be defined as another name (`Sales` -> `Q3Sales`), so this
355
+ * follows the chain. It stops after a handful of hops rather than walking a
356
+ * circular definition forever: `A` -> `B` -> `A` is a mistake in the Name
357
+ * Manager, and the formula that used it reads #NAME? rather than hanging.
358
+ */
359
+ function nameTarget(name, ctx) {
360
+ let node = ctx.resolveNameNode?.(name) ?? null;
361
+ for (let hops = 0; node && node.k === 'name'; hops += 1) {
362
+ if (hops >= 8)
363
+ return null;
364
+ node = ctx.resolveNameNode?.(node.name) ?? null;
365
+ }
366
+ return node;
367
+ }
368
+ /** Functions whose arguments must not all be evaluated up front. */
369
+ /**
370
+ * `SUBTOTAL(code, ref1, ...)`: the aggregate Excel's AutoFilter is built on.
371
+ *
372
+ * The code names the function - 1 AVERAGE, 2 COUNT, 3 COUNTA, 4 MAX, 5 MIN,
373
+ * 6 PRODUCT, 7 STDEV, 8 STDEVP, 9 SUM, 10 VAR, 11 VARP - and a hundred more
374
+ * means "and leave out the rows hidden by hand as well". A filtered-out row
375
+ * is left out either way, which is what makes a total under a filtered list
376
+ * follow the filter, and why a table's totals row is written with this
377
+ * rather than with SUM. A cell holding a SUBTOTAL of its own is skipped, so
378
+ * a grand total over subtotals counts each row once.
379
+ */
380
+ const SUBTOTAL_FUNCTIONS = {
381
+ 1: 'AVERAGE', 2: 'COUNT', 3: 'COUNTA', 4: 'MAX', 5: 'MIN', 6: 'PRODUCT',
382
+ 7: 'STDEV', 8: 'STDEVP', 9: 'SUM', 10: 'VAR', 11: 'VARP',
383
+ };
384
+ function subtotalCall(node, ctx) {
385
+ const first = node.args[0];
386
+ if (!first)
387
+ return err('#VALUE!');
388
+ const codeValue = evalNode(first, ctx);
389
+ if (isError(codeValue))
390
+ return codeValue;
391
+ const code = Math.trunc(toNumber(codeValue));
392
+ const ignoreHandHidden = code > 100;
393
+ const fnName = SUBTOTAL_FUNCTIONS[ignoreHandHidden ? code - 100 : code];
394
+ if (!fnName)
395
+ return err('#VALUE!');
396
+ const table = ctx.functions ?? withCustomFunctions(undefined);
397
+ const fn = table[fnName];
398
+ if (!fn)
399
+ return err('#NAME?');
400
+ const perArg = [];
401
+ for (const arg of node.args.slice(1)) {
402
+ const rect = referenceOf(arg, ctx);
403
+ if (!rect) {
404
+ // A plain value or an expression: nothing is hidden about it.
405
+ perArg.push([evalNode(arg, ctx)]);
406
+ continue;
407
+ }
408
+ const values = [];
409
+ for (let r = rect.r1; r <= rect.r2; r += 1) {
410
+ const how = ctx.hiddenRow?.(rect.sheet, r) ?? null;
411
+ if (how === 'filter' || (how === 'hand' && ignoreHandHidden))
412
+ continue;
413
+ for (let c = rect.c1; c <= rect.c2; c += 1) {
414
+ if (ctx.isSubtotal?.(rect.sheet, r, c))
415
+ continue;
416
+ values.push(ctx.resolve(rect.sheet, r, c));
417
+ }
418
+ }
419
+ perArg.push(values);
420
+ }
421
+ const flat = perArg.flat();
422
+ for (const v of flat)
423
+ if (isError(v))
424
+ return v;
425
+ return fn({ flat, args: perArg, grids: perArg.map(() => null) });
426
+ }
427
+ function evalCall(node, ctx) {
428
+ const { name, args } = node;
429
+ // Every short-circuiting function below indexes its arguments directly.
430
+ // `=IF()` parses fine, so without this the index is undefined and the
431
+ // TypeError escapes the boundary this module promises never to throw past.
432
+ if (SHORT_CIRCUIT.has(name) && args.length === 0)
433
+ return err('#VALUE!');
434
+ // LET, LAMBDA and the helpers that take one see the AST rather than
435
+ // evaluated arguments: a lambda IS its body, and a name bound by LET has
436
+ // to exist before the expression that reads it is evaluated.
437
+ if (name === 'LET')
438
+ return evalLet(args, ctx);
439
+ // The call the parser builds for `LAMBDA(x, x * 2)(5)`: the callee first,
440
+ // then the arguments it is called with.
441
+ if (name === '(')
442
+ return scalarOf(bindingOf(node, ctx));
443
+ if (name === 'LAMBDA')
444
+ return err('#CALC!');
445
+ if (LAMBDA_HELPERS.has(name)) {
446
+ const grid = lambdaCall(node, ctx);
447
+ return Array.isArray(grid) ? grid[0]?.[0] ?? '' : grid;
448
+ }
449
+ // `=LET(double, LAMBDA(x, x * 2), double(21))`: a call on a name the
450
+ // formula bound rather than on a function the library ships.
451
+ const bound = localOf(ctx, name);
452
+ if (isLambda(bound))
453
+ return applyLambda(bound, args.map((a) => bindingOf(a, ctx)), ctx);
454
+ if (name === 'IF') {
455
+ const cond = evalNode(args[0], ctx);
456
+ if (isError(cond))
457
+ return cond;
458
+ const branch = toBool(cond) ? args[1] : args[2];
459
+ if (!branch)
460
+ return toBool(cond);
461
+ return evalNode(branch, ctx);
462
+ }
463
+ if (name === 'ISERROR' || name === 'ISERR' || name === 'ISNA') {
464
+ let code = null;
465
+ try {
466
+ const v = evalNode(args[0], ctx);
467
+ if (isError(v))
468
+ code = v.error;
469
+ }
470
+ catch (e) {
471
+ if (!(e instanceof FormulaError))
472
+ throw e;
473
+ code = e.code;
474
+ }
475
+ if (code === null)
476
+ return false;
477
+ if (name === 'ISNA')
478
+ return code === '#N/A';
479
+ if (name === 'ISERR')
480
+ return code !== '#N/A';
481
+ return true;
482
+ }
483
+ if (name === 'IFERROR' || name === 'IFNA') {
484
+ try {
485
+ const v = evalNode(args[0], ctx);
486
+ if (!isError(v))
487
+ return v;
488
+ if (name === 'IFNA' && v.error !== '#N/A')
489
+ return v;
490
+ }
491
+ catch (e) {
492
+ if (!(e instanceof FormulaError))
493
+ throw e;
494
+ if (name === 'IFNA' && e.code !== '#N/A')
495
+ return err(e.code);
496
+ }
497
+ return args[1] ? evalNode(args[1], ctx) : err('#N/A');
498
+ }
499
+ if (name === 'IFS') {
500
+ for (let i = 0; i + 1 < args.length; i += 2) {
501
+ const cond = evalNode(args[i], ctx);
502
+ if (isError(cond))
503
+ return cond;
504
+ if (toBool(cond))
505
+ return evalNode(args[i + 1], ctx);
506
+ }
507
+ return err('#N/A');
508
+ }
509
+ if (name === 'SWITCH') {
510
+ const subject = evalNode(args[0], ctx);
511
+ if (isError(subject))
512
+ return subject;
513
+ let i = 1;
514
+ for (; i + 1 < args.length; i += 2) {
515
+ const candidate = evalNode(args[i], ctx);
516
+ if (isError(candidate))
517
+ return candidate;
518
+ if (looseEquals(subject, candidate))
519
+ return evalNode(args[i + 1], ctx);
520
+ }
521
+ // A trailing odd argument is the default.
522
+ return i < args.length ? evalNode(args[i], ctx) : err('#N/A');
523
+ }
524
+ if (name === 'SUBTOTAL')
525
+ return subtotalCall(node, ctx);
526
+ if (name === 'ROW' || name === 'COLUMN' || name === 'ADDRESS')
527
+ return positionCall(node, ctx);
528
+ if (REFERENCE_FUNCTIONS.has(name)) {
529
+ // In scalar position a reference collapses to its top-left cell.
530
+ const rect = referenceCall(node, ctx);
531
+ return ctx.resolve(rect.sheet, rect.r1, rect.c1);
532
+ }
533
+ if (ARRAY_FUNCTIONS[name]) {
534
+ // In scalar position a grid reads as its top-left cell; the workbook
535
+ // asks `evaluateSpill` for the whole of it.
536
+ const grid = arrayCall(node, ctx);
537
+ return Array.isArray(grid) ? grid[0]?.[0] ?? '' : grid;
538
+ }
539
+ const table = ctx.functions ?? withCustomFunctions(undefined);
540
+ const fn = table[name];
541
+ if (!fn)
542
+ return err('#NAME?');
543
+ const { perArg, grids } = collectArgs(args, ctx);
544
+ const flat = perArg.flat();
545
+ // An error anywhere in the arguments propagates, except for the counting
546
+ // functions, which Excel lets see errors in their range, and TYPE, whose
547
+ // whole job is to report that an error IS one (it answers 16).
548
+ if (name !== 'COUNTA' && name !== 'COUNTBLANK' && name !== 'TYPE') {
549
+ for (const v of flat)
550
+ if (isError(v))
551
+ return v;
552
+ }
553
+ const payload = { flat, args: perArg, grids };
554
+ return fn(payload);
555
+ }
556
+ /**
557
+ * `LET(name1, value1, [name2, value2, ...], calculation)`.
558
+ *
559
+ * Each value is evaluated in the scope built so far, so a later binding can
560
+ * read an earlier one, and the calculation sees them all. A binding holds a
561
+ * GRID where its expression is one, which is what lets `LET(r, A1:A9,
562
+ * SUM(r))` add the range rather than its first cell.
563
+ */
564
+ function evalLet(args, ctx) {
565
+ if (args.length < 3 || args.length % 2 === 0)
566
+ return err('#VALUE!');
567
+ let scope = ctx;
568
+ for (let i = 0; i + 1 < args.length - 1; i += 2) {
569
+ const nameNode = args[i];
570
+ if (nameNode.k !== 'name')
571
+ return err('#VALUE!');
572
+ scope = withLocals(scope, [[nameNode.name, bindingOf(args[i + 1], scope)]]);
573
+ }
574
+ const result = bindingOf(args[args.length - 1], scope);
575
+ if (isLambda(result))
576
+ return err('#CALC!');
577
+ if (isGrid(result))
578
+ return result[0]?.[0] ?? '';
579
+ return result;
580
+ }
581
+ /** The grid a LET's calculation stands for, or null when it is one value. */
582
+ function letGrid(args, ctx) {
583
+ if (args.length < 3 || args.length % 2 === 0)
584
+ return null;
585
+ let scope = ctx;
586
+ for (let i = 0; i + 1 < args.length - 1; i += 2) {
587
+ const nameNode = args[i];
588
+ if (nameNode.k !== 'name')
589
+ return null;
590
+ scope = withLocals(scope, [[nameNode.name, bindingOf(args[i + 1], scope)]]);
591
+ }
592
+ const result = bindingOf(args[args.length - 1], scope);
593
+ return isGrid(result) ? result : null;
594
+ }
595
+ /** What a name is bound to: a lambda, a grid, or a plain value. */
596
+ function bindingOf(node, ctx) {
597
+ if (node.k === 'fn' && node.name === 'LAMBDA')
598
+ return lambdaOf(node, ctx);
599
+ if (node.k === 'fn' && node.name === '(') {
600
+ const fn = lambdaArg(node.args[0], ctx);
601
+ if (!fn)
602
+ return err('#VALUE!');
603
+ return callLambda(fn, node.args.slice(1).map((a) => bindingOf(a, ctx)), ctx);
604
+ }
605
+ if (node.k === 'fn') {
606
+ const bound = localOf(ctx, node.name);
607
+ if (isLambda(bound))
608
+ return callLambda(bound, node.args.map((a) => bindingOf(a, ctx)), ctx);
609
+ }
610
+ if (node.k === 'name') {
611
+ const local = localOf(ctx, node.name);
612
+ if (local !== undefined)
613
+ return local;
614
+ }
615
+ // Arithmetic over ranges is a grid too, cell by cell: `B2:B6 * D2:D6` is
616
+ // what a REDUCE or a BYROW is usually handed.
617
+ if ((node.k === 'binary' || node.k === 'unary') && hasArray(node, ctx))
618
+ return gridOf(node, ctx);
619
+ const grid = hasArray(node, ctx) ? rangeValues(node, ctx) : null;
620
+ if (grid && (grid.length > 1 || (grid[0]?.length ?? 0) > 1))
621
+ return grid;
622
+ return evalNode(node, ctx);
623
+ }
624
+ /** The lambda a `LAMBDA(p1, ..., body)` node stands for, closed over `ctx`. */
625
+ function lambdaOf(node, ctx) {
626
+ const args = node.args;
627
+ if (args.length < 1)
628
+ return err('#VALUE!');
629
+ const params = [];
630
+ for (let i = 0; i < args.length - 1; i += 1) {
631
+ const p = args[i];
632
+ if (p.k !== 'name')
633
+ return err('#VALUE!');
634
+ params.push(p.name);
635
+ }
636
+ return { lambda: true, params, body: args[args.length - 1], scope: ctx.locals };
637
+ }
638
+ /**
639
+ * Call a lambda, keeping whatever it answers with: a value, a grid, or
640
+ * another lambda, which is what a curried `LAMBDA(x, LAMBDA(y, x + y))`
641
+ * gives back.
642
+ */
643
+ function callLambda(fn, values, ctx) {
644
+ // Excel is strict about the count: too few is #VALUE!, and so is too many.
645
+ if (values.length !== fn.params.length)
646
+ return err('#VALUE!');
647
+ const scope = withLocals({ ...ctx, locals: fn.scope }, fn.params.map((p, i) => [p, values[i]]));
648
+ return bindingOf(fn.body, scope);
649
+ }
650
+ /** The same, in a place that wants one value. */
651
+ function applyLambda(fn, values, ctx) {
652
+ return scalarOf(callLambda(fn, values, ctx));
653
+ }
654
+ /** A binding where one value is wanted: a lambda is #CALC!, a grid its corner. */
655
+ function scalarOf(binding) {
656
+ if (isLambda(binding))
657
+ return err('#CALC!');
658
+ if (isGrid(binding))
659
+ return binding[0]?.[0] ?? '';
660
+ return binding;
661
+ }
662
+ /** The lambda an argument names: written there, or bound to a name. */
663
+ function lambdaArg(node, ctx) {
664
+ if (!node)
665
+ return null;
666
+ if (node.k === 'fn' && node.name === 'LAMBDA') {
667
+ const made = lambdaOf(node, ctx);
668
+ return isLambda(made) ? made : null;
669
+ }
670
+ if (node.k === 'name') {
671
+ const local = localOf(ctx, node.name);
672
+ if (isLambda(local))
673
+ return local;
674
+ return null;
675
+ }
676
+ // A call that answers with another lambda: `LAMBDA(x, LAMBDA(y, x + y))(2)`.
677
+ if (node.k === 'fn' && (node.name === '(' || isLambda(localOf(ctx, node.name)))) {
678
+ const made = bindingOf(node, ctx);
679
+ return isLambda(made) ? made : null;
680
+ }
681
+ return null;
682
+ }
683
+ /** An argument as a grid, one cell wide where it is a plain value. */
684
+ function gridArgOf(node, ctx) {
685
+ if (!node)
686
+ return [['']];
687
+ const binding = bindingOf(node, ctx);
688
+ if (isGrid(binding))
689
+ return binding;
690
+ if (isLambda(binding))
691
+ return [[err('#CALC!')]];
692
+ return [[binding]];
693
+ }
694
+ /**
695
+ * Excel's lambda helpers, which is where a lambda earns its keep:
696
+ *
697
+ * MAP(array, ..., fn) every cell through the function
698
+ * BYROW(array, fn) one answer per row, as a column
699
+ * BYCOL(array, fn) one answer per column, as a row
700
+ * REDUCE(init, array, fn) folded to one value, accumulator first
701
+ * SCAN(init, array, fn) the same, keeping every step
702
+ * MAKEARRAY(rows, cols, fn) built from the row and column numbers
703
+ */
704
+ function lambdaCall(node, ctx) {
705
+ const { name, args } = node;
706
+ const fn = lambdaArg(args[args.length - 1], ctx);
707
+ if (!fn)
708
+ return err('#VALUE!');
709
+ if (name === 'MAKEARRAY') {
710
+ const rows = Math.trunc(toNumber(evalNode(args[0] ?? { k: 'num', v: 0 }, ctx)));
711
+ const cols = Math.trunc(toNumber(evalNode(args[1] ?? { k: 'num', v: 0 }, ctx)));
712
+ if (!(rows > 0) || !(cols > 0))
713
+ return err('#VALUE!');
714
+ if (rows * cols > 1000000)
715
+ return err('#NUM!');
716
+ return Array.from({ length: rows }, (_, r) => Array.from({ length: cols }, (_, c) => applyLambda(fn, [r + 1, c + 1], ctx)));
717
+ }
718
+ if (name === 'MAP') {
719
+ const grids = args.slice(0, -1).map((a) => gridArgOf(a, ctx));
720
+ if (!grids.length)
721
+ return err('#VALUE!');
722
+ const rows = grids[0].length;
723
+ const cols = grids[0][0]?.length ?? 0;
724
+ // Every array has to be the same shape, as Excel asks.
725
+ for (const g of grids)
726
+ if (g.length !== rows || (g[0]?.length ?? 0) !== cols)
727
+ return err('#VALUE!');
728
+ return Array.from({ length: rows }, (_, r) => Array.from({ length: cols }, (_, c) => applyLambda(fn, grids.map((g) => g[r]?.[c] ?? ''), ctx)));
729
+ }
730
+ if (name === 'BYROW' || name === 'BYCOL') {
731
+ const grid = gridArgOf(args[0], ctx);
732
+ if (name === 'BYROW') {
733
+ // Each row goes in as a grid one row tall, and the answers come back
734
+ // as a column, which is the shape Excel spills.
735
+ return grid.map((row) => [applyLambda(fn, [[row]], ctx)]);
736
+ }
737
+ // Each column goes in as a grid one column wide, answers along a row.
738
+ return [transposeGrid(grid).map((col) => applyLambda(fn, [col.map((v) => [v])], ctx))];
739
+ }
740
+ // REDUCE and SCAN: the accumulator, then each cell in reading order.
741
+ const grid = gridArgOf(args[1], ctx);
742
+ let acc = args[0] ? evalNode(args[0], ctx) : '';
743
+ const steps = [];
744
+ for (const row of grid) {
745
+ const line = [];
746
+ for (const cell of row) {
747
+ acc = applyLambda(fn, [acc, cell], ctx);
748
+ line.push(acc);
749
+ }
750
+ steps.push(line);
751
+ }
752
+ return name === 'SCAN' ? steps : acc;
753
+ }
754
+ /** A grid with its rows and columns swapped. */
755
+ function transposeGrid(grid) {
756
+ const cols = grid.reduce((m, row) => Math.max(m, row.length), 0);
757
+ return Array.from({ length: cols }, (_, c) => grid.map((row) => row[c] ?? ''));
758
+ }
759
+ /** Whether a node stands for a grid: a range, an array or reference function, a name to one, or arithmetic over those. */
760
+ function hasArray(node, ctx, depth = 0) {
761
+ switch (node.k) {
762
+ case 'range': return true;
763
+ case 'spill': return true;
764
+ case 'name': {
765
+ if (isGrid(localOf(ctx, node.name)))
766
+ return true;
767
+ const target = depth < 8 ? nameTarget(node.name, ctx) : null;
768
+ return target ? hasArray(target, ctx, depth + 1) : false;
769
+ }
770
+ case 'fn': return REFERENCE_FUNCTIONS.has(node.name) || Boolean(ARRAY_FUNCTIONS[node.name]) || LAMBDA_HELPERS.has(node.name) || node.name === 'LET';
771
+ case 'binary': return hasArray(node.left, ctx, depth) || hasArray(node.right, ctx, depth);
772
+ case 'unary': return hasArray(node.arg, ctx, depth);
773
+ default: return false;
774
+ }
775
+ }
776
+ /**
777
+ * A node as a grid, with Excel's broadcasting: a side that is one row, one
778
+ * column or one cell stretches to the other's shape, and where both are
779
+ * bigger and differ the cells past the shorter side are #N/A.
780
+ */
781
+ function gridOf(node, ctx) {
782
+ if (node.k === 'binary') {
783
+ const l = gridOf(node.left, ctx);
784
+ const r = gridOf(node.right, ctx);
785
+ return broadcast(l, r, (a, b) => {
786
+ if (isError(a))
787
+ return a;
788
+ if (isError(b))
789
+ return b;
790
+ try {
791
+ return binary(node.op, a, b);
792
+ }
793
+ catch (e) {
794
+ if (e instanceof FormulaError)
795
+ return err(e.code);
796
+ throw e;
797
+ }
798
+ });
799
+ }
800
+ if (node.k === 'unary') {
801
+ return gridOf(node.arg, ctx).map((row) => row.map((v) => {
802
+ if (isError(v))
803
+ return v;
804
+ try {
805
+ return node.op === '-' ? -toNumber(v) : node.op === '%' ? toNumber(v) / 100 : toNumber(v);
806
+ }
807
+ catch (e) {
808
+ if (e instanceof FormulaError)
809
+ return err(e.code);
810
+ throw e;
811
+ }
812
+ }));
813
+ }
814
+ const grid = rangeValues(node, ctx);
815
+ return grid ?? [[evalNode(node, ctx)]];
816
+ }
817
+ function broadcast(l, r, op) {
818
+ const lr = l.length, lc = l[0]?.length ?? 0;
819
+ const rr = r.length, rc = r[0]?.length ?? 0;
820
+ const rows = lr === 1 ? rr : rr === 1 ? lr : Math.max(lr, rr);
821
+ const cols = lc === 1 ? rc : rc === 1 ? lc : Math.max(lc, rc);
822
+ const pick = (g, gr, gc, i, j) => {
823
+ const y = gr === 1 ? 0 : i;
824
+ const x = gc === 1 ? 0 : j;
825
+ if (y >= gr || x >= gc)
826
+ return err('#N/A');
827
+ return g[y]?.[x] ?? '';
828
+ };
829
+ return Array.from({ length: rows }, (_, i) => Array.from({ length: cols }, (_, j) => op(pick(l, lr, lc, i, j), pick(r, rr, rc, i, j))));
830
+ }
831
+ /** An array function's answer: a grid, or a value where it had none to give. */
832
+ function arrayCall(node, ctx) {
833
+ const { perArg, grids } = collectArgs(node.args, ctx);
834
+ // Errors stay inside the array: FILTER and SORT carry an error cell
835
+ // through as Excel does, and decide for themselves about the rest.
836
+ return ARRAY_FUNCTIONS[node.name]({ flat: perArg.flat(), args: perArg, grids });
837
+ }
838
+ /** Every argument evaluated, keeping range shape for the functions that need it. */
839
+ function collectArgs(args, ctx) {
840
+ const perArg = [];
841
+ const grids = [];
842
+ for (const given of args) {
843
+ // A name bound inside the formula, by LET or as a lambda's parameter,
844
+ // hands over its grid: `LET(r, A1:C1, SUM(r))` adds the range.
845
+ if (given.k === 'name') {
846
+ const local = localOf(ctx, given.name);
847
+ if (isGrid(local)) {
848
+ grids.push(local);
849
+ perArg.push(local.flat());
850
+ continue;
851
+ }
852
+ }
853
+ // A name stands for whatever it was defined as. Substituting the node
854
+ // here, before the shape check, is what lets `Sales` in =SUM(Sales) be a
855
+ // whole column rather than the top-left cell a scalar read would give.
856
+ const arg = given.k === 'name' ? (nameTarget(given.name, ctx) ?? given) : given;
857
+ if (arg.k === 'range') {
858
+ const grid = rangeGrid(arg.from, arg.to, ctx);
859
+ grids.push(grid);
860
+ perArg.push(grid.flat());
861
+ }
862
+ else if (arg.k === 'fn' && REFERENCE_FUNCTIONS.has(arg.name)) {
863
+ // OFFSET and INDIRECT hand their whole rectangle to the caller, so
864
+ // =SUM(OFFSET(A1,0,0,3,1)) adds three cells rather than one.
865
+ const grid = rectGrid(referenceCall(arg, ctx), ctx);
866
+ grids.push(grid);
867
+ perArg.push(grid.flat());
868
+ }
869
+ else if (arg.k === 'table') {
870
+ // A structured reference expands exactly as a range does, which is
871
+ // what makes =SUM(Orders[Amount]) work.
872
+ const grid = tableGrid(arg, ctx);
873
+ if (!grid) {
874
+ grids.push(null);
875
+ perArg.push([err('#REF!')]);
876
+ }
877
+ else {
878
+ grids.push(grid);
879
+ perArg.push(grid.flat());
880
+ }
881
+ }
882
+ else if (arg.k === 'spill') {
883
+ // The spilled range hands the whole array to the caller, so
884
+ // =SUM(E1#) adds every cell the dynamic array reaches.
885
+ const rect = spillRectOf(arg, ctx);
886
+ if (!rect) {
887
+ grids.push(null);
888
+ perArg.push([err('#REF!')]);
889
+ }
890
+ else {
891
+ const grid = rectGrid(rect, ctx);
892
+ grids.push(grid);
893
+ perArg.push(grid.flat());
894
+ }
895
+ }
896
+ else if (arg.k === 'ref3d') {
897
+ // A 3D reference hands over its cell on every sheet in the range, so
898
+ // =SUM(Sheet1:Sheet3!A1) adds the same cell down the tabs.
899
+ const vals = values3d(arg, ctx);
900
+ grids.push(null);
901
+ perArg.push(vals ?? [err('#REF!')]);
902
+ }
903
+ else if (arg.k === 'fn' && ARRAY_FUNCTIONS[arg.name]) {
904
+ // An array function nested in another hands over its grid, so
905
+ // =SORT(FILTER(...)) and =SUM(SEQUENCE(10)) work.
906
+ const grid = arrayCall(arg, ctx);
907
+ if (Array.isArray(grid)) {
908
+ grids.push(grid);
909
+ perArg.push(grid.flat());
910
+ }
911
+ else {
912
+ grids.push(null);
913
+ perArg.push([grid]);
914
+ }
915
+ }
916
+ else if (arg.k === 'fn' && LAMBDA_HELPERS.has(arg.name)) {
917
+ // And so do the lambda helpers: =SUM(MAP(A1:A9, LAMBDA(v, v * 2))) is
918
+ // the sum of every doubled value, not of the first one. REDUCE hands
919
+ // back one value rather than a grid, which is the same branch.
920
+ const grid = lambdaCall(arg, ctx);
921
+ if (Array.isArray(grid)) {
922
+ grids.push(grid);
923
+ perArg.push(grid.flat());
924
+ }
925
+ else {
926
+ grids.push(null);
927
+ perArg.push([grid]);
928
+ }
929
+ }
930
+ else if ((arg.k === 'binary' || arg.k === 'unary') && hasArray(arg, ctx)) {
931
+ // Arithmetic over a range is a grid, cell by cell: the `B2:B9>3` a
932
+ // FILTER takes, or `A1:A9*2` on its own.
933
+ const grid = gridOf(arg, ctx);
934
+ grids.push(grid);
935
+ perArg.push(grid.flat());
936
+ }
937
+ else {
938
+ grids.push(null);
939
+ perArg.push([evalNode(arg, ctx)]);
940
+ }
941
+ }
942
+ return { perArg, grids };
943
+ }
944
+ /**
945
+ * Evaluate a parsed formula. Never throws: a `FormulaError` raised anywhere
946
+ * inside becomes the matching error value.
947
+ */
948
+ /**
949
+ * The values a node stands for as a grid: a range, a reference (one cell),
950
+ * or a name that refers to either. Null for anything else, which is how a
951
+ * caller tells "a list source that is a range" from "a formula".
952
+ */
953
+ export function rangeValues(node, ctx) {
954
+ try {
955
+ if (node.k === 'range')
956
+ return rangeGrid(node.from, node.to, ctx);
957
+ if (node.k === 'ref')
958
+ return [[ctx.resolve(node.ref.sheet, node.ref.row ?? 0, node.ref.col)]];
959
+ if (node.k === 'spill') {
960
+ const rect = spillRectOf(node, ctx);
961
+ return rect ? rectGrid(rect, ctx) : [[err('#REF!')]];
962
+ }
963
+ if (node.k === 'name') {
964
+ const local = localOf(ctx, node.name);
965
+ if (isGrid(local))
966
+ return local;
967
+ const target = nameTarget(node.name, ctx);
968
+ return target ? rangeValues(target, ctx) : null;
969
+ }
970
+ if (node.k === 'fn' && REFERENCE_FUNCTIONS.has(node.name))
971
+ return rectGrid(referenceCall(node, ctx), ctx);
972
+ if (node.k === 'fn' && ARRAY_FUNCTIONS[node.name]) {
973
+ const grid = arrayCall(node, ctx);
974
+ return Array.isArray(grid) ? grid : [[grid]];
975
+ }
976
+ if (node.k === 'fn' && LAMBDA_HELPERS.has(node.name)) {
977
+ const grid = lambdaCall(node, ctx);
978
+ return Array.isArray(grid) ? grid : [[grid]];
979
+ }
980
+ // `=LET(r, A1:A9, SORT(r))` spills what its calculation is.
981
+ if (node.k === 'fn' && node.name === 'LET') {
982
+ const grid = letGrid(node.args, ctx);
983
+ return grid ?? [[evalNode(node, ctx)]];
984
+ }
985
+ return null;
986
+ }
987
+ catch (e) {
988
+ if (e instanceof FormulaError)
989
+ return [[err(e.code)]];
990
+ throw e;
991
+ }
992
+ }
993
+ /**
994
+ * The grid a formula spills, or null when it is a plain value: a range on
995
+ * its own (`=A1:A5`), a name that refers to one, a reference function's
996
+ * rectangle, or an array function's answer, when that is more than one
997
+ * cell. A throw inside is the error the cell shows, and no spill.
998
+ */
999
+ export function evaluateSpill(node, ctx) {
1000
+ try {
1001
+ let grid = null;
1002
+ if (node.k === 'range' || node.k === 'name' || node.k === 'spill'
1003
+ || (node.k === 'fn' && (REFERENCE_FUNCTIONS.has(node.name) || ARRAY_FUNCTIONS[node.name] || LAMBDA_HELPERS.has(node.name) || node.name === 'LET'))) {
1004
+ grid = rangeValues(node, ctx);
1005
+ }
1006
+ else if ((node.k === 'binary' || node.k === 'unary') && hasArray(node, ctx)) {
1007
+ grid = gridOf(node, ctx);
1008
+ }
1009
+ if (!grid || (grid.length === 1 && (grid[0]?.length ?? 0) <= 1))
1010
+ return null;
1011
+ const width = grid.reduce((m, row) => Math.max(m, row.length), 0);
1012
+ return grid.map((row) => Array.from({ length: width }, (_, i) => row[i] ?? ''));
1013
+ }
1014
+ catch (e) {
1015
+ if (e instanceof FormulaError)
1016
+ return null;
1017
+ throw e;
1018
+ }
1019
+ }
1020
+ export function evaluate(node, ctx) {
1021
+ try {
1022
+ return evalNode(node, ctx);
1023
+ }
1024
+ catch (e) {
1025
+ if (e instanceof FormulaError)
1026
+ return err(e.code);
1027
+ if (e instanceof RangeError)
1028
+ return err('#NUM!');
1029
+ // Last resort. This module promises callers it never throws, and a cell
1030
+ // showing #VALUE! is recoverable where an exception out of a render pass
1031
+ // is not.
1032
+ if (e instanceof TypeError)
1033
+ return err('#VALUE!');
1034
+ throw e;
1035
+ }
1036
+ }
1037
+ /** Render a computed value the way a cell shows it. */
1038
+ export function formatValue(v) {
1039
+ if (isError(v))
1040
+ return v.error;
1041
+ if (typeof v === 'boolean')
1042
+ return v ? 'TRUE' : 'FALSE';
1043
+ if (typeof v === 'number') {
1044
+ if (!Number.isFinite(v))
1045
+ return '#NUM!';
1046
+ return String(v);
1047
+ }
1048
+ return String(v);
1049
+ }