@svgrid/enterprise 3.0.2 → 3.1.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 (364) 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 +94 -20
  10. package/dist/SvFormulaBar.svelte.d.ts +7 -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 +198 -40
  18. package/dist/SvPivotDesigner.svelte.d.ts +27 -20
  19. package/dist/SvSheet.svelte +4043 -243
  20. package/dist/SvSheet.svelte.d.ts +76 -3
  21. package/dist/SvSheetChartSetup.svelte +151 -0
  22. package/dist/SvSheetChartSetup.svelte.d.ts +18 -0
  23. package/dist/SvSheetComment.svelte +216 -31
  24. package/dist/SvSheetComment.svelte.d.ts +11 -11
  25. package/dist/SvSheetConditionalFormat.svelte +28 -31
  26. package/dist/SvSheetDataValidation.svelte +66 -42
  27. package/dist/SvSheetEditRanges.svelte +217 -0
  28. package/dist/SvSheetEditRanges.svelte.d.ts +15 -0
  29. package/dist/SvSheetErrors.svelte +125 -0
  30. package/dist/SvSheetErrors.svelte.d.ts +20 -0
  31. package/dist/SvSheetEvaluate.svelte +133 -0
  32. package/dist/SvSheetEvaluate.svelte.d.ts +15 -0
  33. package/dist/SvSheetFilterMenu.svelte +137 -34
  34. package/dist/SvSheetFilterMenu.svelte.d.ts +5 -0
  35. package/dist/SvSheetFindReplace.svelte +19 -19
  36. package/dist/SvSheetFormatCells.svelte +125 -81
  37. package/dist/SvSheetGoalSeek.svelte +17 -16
  38. package/dist/SvSheetInsertFunction.svelte +15 -13
  39. package/dist/SvSheetIteration.svelte +81 -0
  40. package/dist/SvSheetIteration.svelte.d.ts +10 -0
  41. package/dist/SvSheetLink.svelte +99 -0
  42. package/dist/SvSheetLink.svelte.d.ts +17 -0
  43. package/dist/SvSheetListPicker.svelte +4 -2
  44. package/dist/SvSheetListPicker.svelte.d.ts +0 -6
  45. package/dist/SvSheetManageRules.svelte +20 -18
  46. package/dist/SvSheetNameManager.svelte +17 -15
  47. package/dist/SvSheetPageSetup.svelte +159 -0
  48. package/dist/SvSheetPageSetup.svelte.d.ts +13 -0
  49. package/dist/SvSheetPasteSpecial.svelte +22 -20
  50. package/dist/SvSheetPivot.svelte +220 -0
  51. package/dist/SvSheetPivot.svelte.d.ts +21 -0
  52. package/dist/SvSheetProtectSheet.svelte +81 -0
  53. package/dist/SvSheetProtectSheet.svelte.d.ts +11 -0
  54. package/dist/SvSheetRemoveDuplicates.svelte +13 -10
  55. package/dist/SvSheetRibbon.svelte +104 -51
  56. package/dist/SvSheetSizeDialog.svelte +4 -2
  57. package/dist/SvSheetSort.svelte +218 -0
  58. package/dist/SvSheetSort.svelte.d.ts +28 -0
  59. package/dist/SvSheetSparklines.svelte +135 -0
  60. package/dist/SvSheetSparklines.svelte.d.ts +14 -0
  61. package/dist/SvSheetTable.svelte +160 -0
  62. package/dist/SvSheetTable.svelte.d.ts +24 -0
  63. package/dist/SvSheetTabs.svelte +161 -31
  64. package/dist/SvSheetTabs.svelte.d.ts +22 -8
  65. package/dist/SvSheetTextToColumns.svelte +20 -20
  66. package/dist/SvSheetValidationAlert.svelte +8 -6
  67. package/dist/advanced-filter-enable.js +1 -1
  68. package/dist/alerts/alert-engine.d.ts +6 -0
  69. package/dist/alerts/alert-engine.js +21 -4
  70. package/dist/alerts/alert-formats.js +2 -0
  71. package/dist/alerts/alert-types.d.ts +1 -1
  72. package/dist/alerts.d.ts +1 -1
  73. package/dist/alerts.js +2 -2
  74. package/dist/board.js +2 -2
  75. package/dist/bulk-edit.d.ts +3 -1
  76. package/dist/bulk-edit.js +1 -1
  77. package/dist/cdn/svgrid-enterprise.svelte-external.js +39827 -16429
  78. package/dist/designer/assets/GridMenus-8gTNssgV.js +8 -0
  79. package/dist/designer/assets/{SvChartMenu-D9hEeHar.js → SvChartMenu-BDoeqGz6.js} +1 -1
  80. package/dist/designer/assets/{SvDateTimePicker-DARvKUL2.js → SvDateTimePicker-DCPg7WGN.js} +1 -1
  81. package/dist/designer/assets/SvGridCellEditor-DMoWJjEI.js +4 -0
  82. package/dist/designer/assets/{SvGridChart-B8j1SSy3.js → SvGridChart-Cy1ATrWh.js} +2 -2
  83. package/dist/designer/assets/SvGridChartBuilder-eQ3mn0L9.js +1 -0
  84. package/dist/designer/assets/{SvGridChartPanel-pT6ITc2P.js → SvGridChartPanel-CATdVc9X.js} +3 -3
  85. package/dist/designer/assets/{SvGridChartView-bg281UA1.js → SvGridChartView-CmsZtCED.js} +1 -1
  86. package/dist/designer/assets/SvGridDropdown-Cjz0H-fI.js +1 -0
  87. package/dist/designer/assets/{SvTabs-UFCMTHXS.js → SvTabs-2mHC6oaz.js} +1 -1
  88. package/dist/designer/assets/cell-formatting-BbubJTVz.js +1 -0
  89. package/dist/designer/assets/{chart-cIPUsbM5.js → chart-Cn7MnNqA.js} +1 -1
  90. package/dist/designer/assets/{chart-panel-messages-DtTxpBUU.js → chart-panel-messages-Dz7PTIqT.js} +1 -1
  91. package/dist/designer/assets/{chart-summary-Czu_5epb.js → chart-summary-BD1qYB2R.js} +1 -1
  92. package/dist/designer/assets/{chart-trend-D5I5VEe8.js → chart-trend-B8xr5LuD.js} +1 -1
  93. package/dist/designer/assets/{dismissable-BO547MH9.js → dismissable-ChWRPkoa.js} +1 -1
  94. package/dist/designer/assets/{export-format-D-eP4b2l.js → export-format-DGckmgKr.js} +1 -1
  95. package/dist/designer/assets/{focus-trap-CAreAhlU.js → focus-trap-V2-6Fy9I.js} +1 -1
  96. package/dist/designer/assets/{index-DwU7CAMm.js → index-BSjv6Qec.js} +317 -315
  97. package/dist/designer/assets/index-_JVFxt02.css +1 -0
  98. package/dist/designer/assets/row-resize-BInFWCpr.js +1 -0
  99. package/dist/designer/assets/server-block-cache-CXJKkJpy.js +1 -0
  100. package/dist/designer/assets/src-DUQ4xE3x.js +58 -0
  101. package/dist/designer/assets/validate-C3B8QKsM.js +1 -0
  102. package/dist/designer/index.html +17 -16
  103. package/dist/export-pdf.d.ts +75 -0
  104. package/dist/export-pdf.js +216 -15
  105. package/dist/export.js +10 -2
  106. package/dist/gantt/SvGridGantt.svelte +2890 -0
  107. package/dist/gantt/SvGridGantt.svelte.d.ts +30 -0
  108. package/dist/gantt/gantt-config.d.ts +73 -0
  109. package/dist/gantt/gantt-config.js +1 -0
  110. package/dist/gantt/gantt-critical-path.d.ts +67 -0
  111. package/dist/gantt/gantt-critical-path.js +207 -0
  112. package/dist/gantt/gantt-model.d.ts +257 -0
  113. package/dist/gantt/gantt-model.js +651 -0
  114. package/dist/gantt/gantt-resources.d.ts +59 -0
  115. package/dist/gantt/gantt-resources.js +71 -0
  116. package/dist/gantt/gantt.d.ts +7 -0
  117. package/dist/gantt/gantt.js +36 -0
  118. package/dist/gantt/index.d.ts +15 -0
  119. package/dist/gantt/index.js +22 -0
  120. package/dist/gantt/timeline-arrows.d.ts +102 -0
  121. package/dist/gantt/timeline-arrows.js +181 -0
  122. package/dist/import.d.ts +2 -2
  123. package/dist/import.js +1 -1
  124. package/dist/index.d.ts +34 -7
  125. package/dist/index.js +44 -7
  126. package/dist/install.js +8 -1
  127. package/dist/license-core.d.ts +17 -1
  128. package/dist/license-core.js +16 -5
  129. package/dist/license.d.ts +18 -2
  130. package/dist/license.js +71 -6
  131. package/dist/node/studio.js +140 -8
  132. package/dist/pivot-enable.js +2 -2
  133. package/dist/scheduler-dependencies.d.ts +35 -0
  134. package/dist/scheduler-dependencies.js +36 -1
  135. package/dist/scheduler.js +2 -2
  136. package/dist/selection-bar.js +2 -2
  137. package/dist/server/SvGroupCell.svelte +213 -0
  138. package/dist/server/SvGroupCell.svelte.d.ts +62 -0
  139. package/dist/server/SvRowGroupPanel.svelte +322 -0
  140. package/dist/server/SvRowGroupPanel.svelte.d.ts +37 -0
  141. package/dist/server/enable.d.ts +17 -0
  142. package/dist/server/enable.js +49 -0
  143. package/dist/server/index.d.ts +22 -0
  144. package/dist/server/index.js +24 -0
  145. package/dist/server/messages.d.ts +45 -0
  146. package/dist/server/messages.js +35 -0
  147. package/dist/server/server-group-model.d.ts +104 -0
  148. package/dist/server/server-group-model.js +272 -0
  149. package/dist/server/server-pivot.d.ts +46 -0
  150. package/dist/server/server-pivot.js +57 -0
  151. package/dist/server/server-row-model.d.ts +547 -0
  152. package/dist/server/server-row-model.js +1551 -0
  153. package/dist/server/server-selection.d.ts +99 -0
  154. package/dist/server/server-selection.js +215 -0
  155. package/dist/server/svgrid-adapter.d.ts +155 -0
  156. package/dist/server/svgrid-adapter.js +202 -0
  157. package/dist/sheet/ast.d.ts +45 -1
  158. package/dist/sheet/ast.js +14 -0
  159. package/dist/sheet/auto-filter.d.ts +58 -4
  160. package/dist/sheet/auto-filter.js +159 -11
  161. package/dist/sheet/autocomplete.d.ts +9 -0
  162. package/dist/sheet/autocomplete.js +90 -4
  163. package/dist/sheet/cell-images.d.ts +39 -0
  164. package/dist/sheet/cell-images.js +90 -0
  165. package/dist/sheet/cell-types.d.ts +58 -0
  166. package/dist/sheet/cell-types.js +96 -0
  167. package/dist/sheet/coerce.d.ts +40 -0
  168. package/dist/sheet/coerce.js +170 -3
  169. package/dist/sheet/comments.d.ts +43 -9
  170. package/dist/sheet/comments.js +85 -27
  171. package/dist/sheet/conditional-formats.d.ts +29 -6
  172. package/dist/sheet/conditional-formats.js +37 -12
  173. package/dist/sheet/csv.d.ts +32 -0
  174. package/dist/sheet/csv.js +158 -0
  175. package/dist/sheet/culture.d.ts +87 -0
  176. package/dist/sheet/culture.js +247 -0
  177. package/dist/sheet/delta.d.ts +102 -0
  178. package/dist/sheet/delta.js +203 -0
  179. package/dist/sheet/deps.d.ts +45 -1
  180. package/dist/sheet/deps.js +77 -2
  181. package/dist/sheet/document.d.ts +106 -4
  182. package/dist/sheet/document.js +204 -3
  183. package/dist/sheet/engine.d.ts +67 -0
  184. package/dist/sheet/engine.js +19 -0
  185. package/dist/sheet/entry.d.ts +8 -4
  186. package/dist/sheet/entry.js +171 -21
  187. package/dist/sheet/error-check.d.ts +49 -0
  188. package/dist/sheet/error-check.js +83 -0
  189. package/dist/sheet/evaluate-steps.d.ts +48 -0
  190. package/dist/sheet/evaluate-steps.js +196 -0
  191. package/dist/sheet/evaluate.d.ts +67 -0
  192. package/dist/sheet/evaluate.js +725 -13
  193. package/dist/sheet/filter-files.d.ts +37 -0
  194. package/dist/sheet/filter-files.js +465 -0
  195. package/dist/sheet/format-store.d.ts +15 -0
  196. package/dist/sheet/format-store.js +11 -1
  197. package/dist/sheet/from-rows.d.ts +14 -0
  198. package/dist/sheet/from-rows.js +50 -0
  199. package/dist/sheet/function-catalog.d.ts +1 -1
  200. package/dist/sheet/function-catalog.js +296 -5
  201. package/dist/sheet/functions.js +363 -91
  202. package/dist/sheet/index.d.ts +35 -8
  203. package/dist/sheet/index.js +35 -8
  204. package/dist/sheet/links.d.ts +57 -0
  205. package/dist/sheet/links.js +174 -0
  206. package/dist/sheet/messages.d.ts +778 -0
  207. package/dist/sheet/messages.js +806 -0
  208. package/dist/sheet/number-format.d.ts +52 -5
  209. package/dist/sheet/number-format.js +465 -68
  210. package/dist/sheet/objects.d.ts +106 -0
  211. package/dist/sheet/objects.js +149 -0
  212. package/dist/sheet/ods-document.d.ts +44 -0
  213. package/dist/sheet/ods-document.js +1275 -0
  214. package/dist/sheet/open-file.d.ts +26 -0
  215. package/dist/sheet/open-file.js +56 -0
  216. package/dist/sheet/outline.d.ts +82 -0
  217. package/dist/sheet/outline.js +228 -0
  218. package/dist/sheet/packs/array.d.ts +16 -0
  219. package/dist/sheet/packs/array.js +172 -0
  220. package/dist/sheet/packs/database.d.ts +42 -0
  221. package/dist/sheet/packs/database.js +142 -0
  222. package/dist/sheet/packs/engineering.d.ts +2 -0
  223. package/dist/sheet/packs/engineering.js +296 -0
  224. package/dist/sheet/packs/financial.d.ts +5 -0
  225. package/dist/sheet/packs/financial.js +220 -0
  226. package/dist/sheet/packs/math-stats.d.ts +2 -0
  227. package/dist/sheet/packs/math-stats.js +372 -0
  228. package/dist/sheet/packs/special.d.ts +44 -0
  229. package/dist/sheet/packs/special.js +187 -0
  230. package/dist/sheet/packs/stats-dist.d.ts +2 -0
  231. package/dist/sheet/packs/stats-dist.js +785 -0
  232. package/dist/sheet/packs/text-date.d.ts +2 -0
  233. package/dist/sheet/packs/text-date.js +332 -0
  234. package/dist/sheet/packs/trig.d.ts +2 -0
  235. package/dist/sheet/packs/trig.js +73 -0
  236. package/dist/sheet/page-setup.d.ts +73 -0
  237. package/dist/sheet/page-setup.js +73 -0
  238. package/dist/sheet/parse.js +42 -10
  239. package/dist/sheet/paste-special.d.ts +22 -0
  240. package/dist/sheet/paste-special.js +14 -5
  241. package/dist/sheet/pivot-range.d.ts +160 -0
  242. package/dist/sheet/pivot-range.js +333 -0
  243. package/dist/sheet/presence.d.ts +73 -0
  244. package/dist/sheet/presence.js +79 -0
  245. package/dist/sheet/print.d.ts +104 -0
  246. package/dist/sheet/print.js +169 -0
  247. package/dist/sheet/protection.d.ts +55 -1
  248. package/dist/sheet/protection.js +55 -2
  249. package/dist/sheet/rects.d.ts +1 -1
  250. package/dist/sheet/refs.d.ts +48 -0
  251. package/dist/sheet/refs.js +155 -8
  252. package/dist/sheet/ribbon-icons.d.ts +1 -1
  253. package/dist/sheet/ribbon-icons.js +186 -0
  254. package/dist/sheet/ribbon.d.ts +1 -1
  255. package/dist/sheet/ribbon.js +324 -23
  256. package/dist/sheet/sheet-kinds.d.ts +74 -0
  257. package/dist/sheet/sheet-kinds.js +91 -0
  258. package/dist/sheet/shortcuts.d.ts +13 -3
  259. package/dist/sheet/shortcuts.js +63 -12
  260. package/dist/sheet/sort.d.ts +51 -0
  261. package/dist/sheet/sort.js +107 -0
  262. package/dist/sheet/sparklines.d.ts +111 -0
  263. package/dist/sheet/sparklines.js +204 -0
  264. package/dist/sheet/table-styles.d.ts +74 -0
  265. package/dist/sheet/table-styles.js +152 -0
  266. package/dist/sheet/tables.d.ts +19 -0
  267. package/dist/sheet/tables.js +31 -0
  268. package/dist/sheet/tokenize.d.ts +18 -1
  269. package/dist/sheet/tokenize.js +60 -9
  270. package/dist/sheet/validation.d.ts +16 -0
  271. package/dist/sheet/validation.js +37 -0
  272. package/dist/sheet/workbook.d.ts +148 -3
  273. package/dist/sheet/workbook.js +742 -31
  274. package/dist/sheet/xls-cfb.d.ts +32 -0
  275. package/dist/sheet/xls-cfb.js +290 -0
  276. package/dist/sheet/xls-document.d.ts +10 -0
  277. package/dist/sheet/xls-document.js +1243 -0
  278. package/dist/sheet/xls-formula.d.ts +40 -0
  279. package/dist/sheet/xls-formula.js +569 -0
  280. package/dist/sheet/xlsx-document.d.ts +108 -0
  281. package/dist/sheet/xlsx-document.js +1849 -0
  282. package/dist/sheet/xlsx-drawing.d.ts +99 -0
  283. package/dist/sheet/xlsx-drawing.js +420 -0
  284. package/dist/sheet-enable.js +6 -7
  285. package/dist/sheet-text.d.ts +7 -0
  286. package/dist/sheet-text.js +29 -0
  287. package/dist/sources/auth-supabase.js +2 -2
  288. package/dist/sources/realtime-supabase.js +2 -2
  289. package/dist/sources/rest.d.ts +6 -2
  290. package/dist/sources/rest.js +42 -7
  291. package/dist/sources/supabase.d.ts +10 -1
  292. package/dist/sources/supabase.js +73 -40
  293. package/dist/studio/emit-project.js +14 -1
  294. package/dist/studio/index.js +1 -1
  295. package/dist/studio/project.d.ts +11 -2
  296. package/dist/studio/project.js +5 -2
  297. package/dist/studio/ui-components.generated.js +107 -2
  298. package/dist/sveltekit/in-memory.d.ts +2 -2
  299. package/dist/sveltekit/in-memory.js +125 -4
  300. package/dist/sveltekit/index.d.ts +1 -1
  301. package/dist/sveltekit/index.js +1 -1
  302. package/dist/sveltekit/query-plan.d.ts +50 -4
  303. package/dist/sveltekit/query-plan.js +25 -3
  304. package/dist/sveltekit/sql-source.d.ts +6 -0
  305. package/dist/sveltekit/sql-source.js +34 -6
  306. package/dist/sveltekit/sql.d.ts +31 -0
  307. package/dist/sveltekit/sql.js +135 -25
  308. package/dist/sveltekit/transport.d.ts +10 -2
  309. package/dist/sveltekit/transport.js +30 -6
  310. package/dist/upgrade-prompt.d.ts +1 -1
  311. package/dist/version.d.ts +1 -1
  312. package/dist/version.js +1 -1
  313. package/dist/watermark.js +35 -2
  314. package/dist/wc/GridMenus-By9vPuq0.js +1088 -0
  315. package/dist/wc/SvChartMenu-CQNrQGT2.js +308 -0
  316. package/dist/wc/SvDateRangeInput-DR6m7bSM.js +199 -0
  317. package/dist/wc/SvDateTimePicker-D-vRnaMo.js +771 -0
  318. package/dist/wc/SvField-B_kurx_P.js +149 -0
  319. package/dist/wc/SvGrid.helpers-BdVDtjUm.js +135 -0
  320. package/dist/wc/SvGridCellEditor-Bnf1Kr5C.js +560 -0
  321. package/dist/wc/SvGridChart-BqUJh2pG.js +3572 -0
  322. package/dist/wc/SvGridChartBuilder-CGycC5cn.js +988 -0
  323. package/dist/wc/SvGridChartPanel-CRnizsHD.js +1746 -0
  324. package/dist/wc/SvGridChartView-D1pa_xMy.js +47 -0
  325. package/dist/wc/SvGridDropdown-45WsObLL.js +259 -0
  326. package/dist/wc/SvModal-DrfOYYyX.js +189 -0
  327. package/dist/wc/cell-formatting-CBfgahv1.js +86 -0
  328. package/dist/wc/chart-6OXlybVT.js +4341 -0
  329. package/dist/wc/chart-export-CeSADGfi.js +135 -0
  330. package/dist/wc/chart-export-pdf-BGko7MER.js +104 -0
  331. package/dist/wc/chart-summary-2m3ia1-n.js +137 -0
  332. package/dist/wc/chart-trend-CQOQtTMl.js +50 -0
  333. package/dist/wc/chart-validate-CD6ptiwg.js +180 -0
  334. package/dist/wc/client-DQIzjDBG.js +3064 -0
  335. package/dist/wc/column-resize-DUPgynvc.js +101 -0
  336. package/dist/wc/date-format-DS-z_h9v.js +1130 -0
  337. package/dist/wc/dismissable-CQ6XFXsk.js +45 -0
  338. package/dist/wc/editor-contract-peBDxir_.js +22 -0
  339. package/dist/wc/editor-registry-DxGKqcvx.js +24 -0
  340. package/dist/wc/focus-trap-Dbb2tJxb.js +65 -0
  341. package/dist/wc/list-option-DrRyivWp.js +82 -0
  342. package/dist/wc/popover-WsGlvtQv.js +69 -0
  343. package/dist/wc/positioning-BiKLfu1E.js +112 -0
  344. package/dist/wc/react.d.ts +41 -0
  345. package/dist/wc/react.js +90 -0
  346. package/dist/wc/rolldown-runtime-Dy4uBu1J.js +11 -0
  347. package/dist/wc/row-drag-touch-CycRR65n.js +93 -0
  348. package/dist/wc/row-resize-limG_N1z.js +111 -0
  349. package/dist/wc/sv-sheet-element.d.ts +97 -0
  350. package/dist/wc/sv-sheet-element.js +44213 -0
  351. package/dist/wc/svelte-virtualizer.svelte-CXtQy2TQ.js +530 -0
  352. package/dist/wc/validate-BqDthkNr.js +88 -0
  353. package/dist/wc/vue.d.ts +31 -0
  354. package/dist/wc/vue.js +75 -0
  355. package/package.json +30 -5
  356. package/dist/designer/assets/GridMenus-BlsvL_aU.js +0 -8
  357. package/dist/designer/assets/SvGridCellEditor-C7uQXYds.js +0 -4
  358. package/dist/designer/assets/SvGridChartBuilder-kvyIU_Rl.js +0 -1
  359. package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +0 -1
  360. package/dist/designer/assets/cell-formatting-wr5wm7US.js +0 -1
  361. package/dist/designer/assets/index-CMFgAoVV.css +0 -1
  362. package/dist/designer/assets/row-resize-DLktcqUK.js +0 -1
  363. package/dist/designer/assets/src-EdI3Xqds.js +0 -58
  364. package/dist/designer/assets/validate-h-aslRV9.js +0 -1
@@ -0,0 +1,2 @@
1
+ import type { SheetFunction } from '../functions.js';
2
+ export declare const TEXT_DATE_FUNCTIONS: Record<string, SheetFunction>;
@@ -0,0 +1,332 @@
1
+ /**
2
+ * More of Excel's text and date functions.
3
+ *
4
+ * Dates in this engine are the `yyyy-mm-dd` text the DATE family already
5
+ * hands back, or a serial number; `toDate` reads either. The functions that
6
+ * produce a date produce the text form, the ones that produce a time
7
+ * produce a serial fraction of a day, which the `h:mm` number formats show.
8
+ */
9
+ import { FormulaError, err } from '../ast.js';
10
+ import { toNumber, toText, isBlank, toDate, isoDate, dateSerial } from '../coerce.js';
11
+ const first = (a) => a.flat[0] ?? '';
12
+ const nth = (a, i) => a.args[i]?.[0] ?? '';
13
+ const num = (a, i) => toNumber(nth(a, i));
14
+ function opt(a, i, fallback) {
15
+ const v = a.args[i]?.[0];
16
+ return v === undefined || v === '' ? fallback : toNumber(v);
17
+ }
18
+ const DAY_MS = 86400000;
19
+ /** Hours, minutes and seconds out of a value: a serial's fraction, a
20
+ * `hh:mm[:ss] [AM|PM]` text (with or without a date before it), or a
21
+ * date-time `toDate` can read. */
22
+ function timeOf(v) {
23
+ if (typeof v === 'number') {
24
+ const secs = Math.round((v - Math.floor(v)) * 86400) % 86400;
25
+ return { h: Math.floor(secs / 3600), m: Math.floor((secs % 3600) / 60), s: secs % 60 };
26
+ }
27
+ const text = toText(v).trim();
28
+ const m = /(\d{1,2}):(\d{2})(?::(\d{2}))?\s*(AM|PM|am|pm)?\s*$/.exec(text);
29
+ if (m) {
30
+ let h = Number(m[1]);
31
+ const meridian = m[4]?.toUpperCase();
32
+ if (meridian === 'PM' && h < 12)
33
+ h += 12;
34
+ if (meridian === 'AM' && h === 12)
35
+ h = 0;
36
+ if (h > 23 || Number(m[2]) > 59 || Number(m[3] ?? 0) > 59)
37
+ throw new FormulaError('#VALUE!');
38
+ return { h, m: Number(m[2]), s: Number(m[3] ?? 0) };
39
+ }
40
+ const d = toDate(v);
41
+ return { h: d.getUTCHours(), m: d.getUTCMinutes(), s: d.getUTCSeconds() };
42
+ }
43
+ const isWeekend = (d) => d.getUTCDay() === 0 || d.getUTCDay() === 6;
44
+ const daySerial = (d) => Math.floor(dateSerial(d));
45
+ /** The holidays argument of NETWORKDAYS / WORKDAY as a set of day serials. */
46
+ function holidaySet(values) {
47
+ const out = new Set();
48
+ for (const v of values ?? []) {
49
+ if (isBlank(v))
50
+ continue;
51
+ out.add(daySerial(toDate(v)));
52
+ }
53
+ return out;
54
+ }
55
+ const isLetter = (ch) => ch.toLowerCase() !== ch.toUpperCase();
56
+ const lastOfMonth = (d) => new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + 1, 0)).getUTCDate();
57
+ /** Days between two dates on a 360-day year, the US (NASD) method Excel
58
+ * defaults to. */
59
+ function days360(s, e) {
60
+ let d1 = s.getUTCDate();
61
+ let d2 = e.getUTCDate();
62
+ if (d1 === 31 || (s.getUTCMonth() === 1 && d1 === lastOfMonth(s)))
63
+ d1 = 30;
64
+ if (d2 === 31 && d1 === 30)
65
+ d2 = 30;
66
+ return (e.getUTCFullYear() - s.getUTCFullYear()) * 360 + (e.getUTCMonth() - s.getUTCMonth()) * 30 + (d2 - d1);
67
+ }
68
+ const isLeap = (y) => (y % 4 === 0 && y % 100 !== 0) || y % 400 === 0;
69
+ export const TEXT_DATE_FUNCTIONS = {
70
+ // ---- Text ------------------------------------------------------------
71
+ // Excel capitalises a letter that follows anything but a letter, so
72
+ // "76BudGet" is "76Budget" and "2-way" is "2-Way".
73
+ PROPER: (a) => {
74
+ const s = toText(first(a));
75
+ let out = '';
76
+ let afterLetter = false;
77
+ for (const ch of s) {
78
+ if (isLetter(ch)) {
79
+ out += afterLetter ? ch.toLowerCase() : ch.toUpperCase();
80
+ afterLetter = true;
81
+ }
82
+ else {
83
+ out += ch;
84
+ afterLetter = false;
85
+ }
86
+ }
87
+ return out;
88
+ },
89
+ REPT: (a) => {
90
+ const n = Math.trunc(num(a, 1));
91
+ if (n < 0)
92
+ return err('#VALUE!');
93
+ return toText(nth(a, 0)).repeat(n);
94
+ },
95
+ // VALUE reads what a typed entry would: a plain number, a currency or
96
+ // grouped one, a percentage, a time or a date.
97
+ VALUE: (a) => {
98
+ const v = first(a);
99
+ if (typeof v === 'number')
100
+ return v;
101
+ if (typeof v === 'boolean')
102
+ return err('#VALUE!');
103
+ const text = toText(v).trim();
104
+ if (text === '')
105
+ return err('#VALUE!');
106
+ const cleaned = text.replace(/[$,]/g, '');
107
+ if (/^-?\d*\.?\d+(e[+-]?\d+)?%$/i.test(cleaned))
108
+ return Number(cleaned.slice(0, -1)) / 100;
109
+ const n = Number(cleaned);
110
+ if (cleaned !== '' && Number.isFinite(n))
111
+ return n;
112
+ if (/^\d{1,2}:\d{2}(:\d{2})?\s*(AM|PM)?$/i.test(text)) {
113
+ const t = timeOf(text);
114
+ return (t.h * 3600 + t.m * 60 + t.s) / 86400;
115
+ }
116
+ try {
117
+ return dateSerial(toDate(text));
118
+ }
119
+ catch {
120
+ return err('#VALUE!');
121
+ }
122
+ },
123
+ /**
124
+ * NUMBERVALUE(text, [decimal], [group]): VALUE for a number written the
125
+ * way another country writes one. The separators are given rather than
126
+ * guessed, which is the whole point of it: "1.234,56" is a thousand two
127
+ * hundred in Germany and one point two in Britain, and only the caller
128
+ * knows which.
129
+ */
130
+ NUMBERVALUE: (a) => {
131
+ const v = first(a);
132
+ if (typeof v === 'number')
133
+ return v;
134
+ if (typeof v === 'boolean')
135
+ return err('#VALUE!');
136
+ const decimal = (toText(nth(a, 1)) || '.').trim().slice(0, 1) || '.';
137
+ const group = (toText(nth(a, 2)) || ',').trim().slice(0, 1);
138
+ if (decimal === group)
139
+ return err('#VALUE!');
140
+ let text = toText(v).trim();
141
+ if (text === '')
142
+ return 0;
143
+ // Trailing percent signs each divide by a hundred, as Excel's do.
144
+ let percents = 0;
145
+ while (text.endsWith('%')) {
146
+ percents += 1;
147
+ text = text.slice(0, -1).trim();
148
+ }
149
+ // Excel reads the group separator as a thousands mark, so one AFTER the
150
+ // decimal separator is not a number written another way, it is a typo:
151
+ // "1.5,5" is #VALUE! rather than fifteen and a half.
152
+ const point = text.indexOf(decimal);
153
+ if (group !== '' && point >= 0 && text.indexOf(group, point) > point)
154
+ return err('#VALUE!');
155
+ // The group separator is dropped and the decimal one becomes a point;
156
+ // spaces are dropped too, since a space is a group separator in half of
157
+ // Europe whatever was asked for.
158
+ const stripped = text
159
+ .split('').filter((ch) => ch !== group && !/\s/.test(ch)).join('')
160
+ .replace(decimal, '.');
161
+ if (stripped === '' || /[^0-9.+-]/.test(stripped))
162
+ return err('#VALUE!');
163
+ const n = Number(stripped);
164
+ if (!Number.isFinite(n))
165
+ return err('#VALUE!');
166
+ return n / 100 ** percents;
167
+ },
168
+ CHAR: (a) => {
169
+ const n = Math.trunc(num(a, 0));
170
+ if (n < 1 || n > 255)
171
+ return err('#VALUE!');
172
+ return String.fromCharCode(n);
173
+ },
174
+ CODE: (a) => {
175
+ const s = toText(first(a));
176
+ return s === '' ? err('#VALUE!') : s.charCodeAt(0);
177
+ },
178
+ UNICHAR: (a) => {
179
+ const n = Math.trunc(num(a, 0));
180
+ if (n < 1 || n > 0x10ffff)
181
+ return err('#VALUE!');
182
+ return String.fromCodePoint(n);
183
+ },
184
+ UNICODE: (a) => {
185
+ const s = toText(first(a));
186
+ return s === '' ? err('#VALUE!') : s.codePointAt(0);
187
+ },
188
+ EXACT: (a) => toText(nth(a, 0)) === toText(nth(a, 1)),
189
+ CLEAN: (a) => {
190
+ let out = '';
191
+ for (const ch of toText(first(a)))
192
+ if (ch.charCodeAt(0) >= 32)
193
+ out += ch;
194
+ return out;
195
+ },
196
+ REPLACE: (a) => {
197
+ const s = toText(nth(a, 0));
198
+ const start = Math.trunc(num(a, 1));
199
+ const count = Math.trunc(num(a, 2));
200
+ if (start < 1 || count < 0)
201
+ return err('#VALUE!');
202
+ return s.slice(0, start - 1) + toText(nth(a, 3)) + s.slice(start - 1 + count);
203
+ },
204
+ T: (a) => (typeof first(a) === 'string' ? first(a) : ''),
205
+ N: (a) => {
206
+ const v = first(a);
207
+ return typeof v === 'number' ? v : typeof v === 'boolean' ? (v ? 1 : 0) : 0;
208
+ },
209
+ // ---- Date and time ---------------------------------------------------
210
+ // WEEKDAY(date, [type]): 1 counts Sunday as 1, 2 counts Monday as 1, 3
211
+ // counts Monday as 0; 11 to 17 count from Monday to Sunday as 1.
212
+ WEEKDAY: (a) => {
213
+ const day = toDate(nth(a, 0)).getUTCDay();
214
+ const type = opt(a, 1, 1);
215
+ if (type === 1)
216
+ return day + 1;
217
+ if (type === 2)
218
+ return ((day + 6) % 7) + 1;
219
+ if (type === 3)
220
+ return (day + 6) % 7;
221
+ if (type >= 11 && type <= 17) {
222
+ const start = (type - 10) % 7;
223
+ return ((day - start + 7) % 7) + 1;
224
+ }
225
+ return err('#NUM!');
226
+ },
227
+ // EDATE(date, months): the same day `months` on, clamped to the end of a
228
+ // shorter month, so a 31st in January lands on the 28th or 29th.
229
+ EDATE: (a) => {
230
+ const d = toDate(nth(a, 0));
231
+ const months = Math.trunc(num(a, 1));
232
+ const y = d.getUTCFullYear();
233
+ const m = d.getUTCMonth() + months;
234
+ const last = new Date(Date.UTC(y, m + 1, 0)).getUTCDate();
235
+ return isoDate(new Date(Date.UTC(y, m, Math.min(d.getUTCDate(), last))));
236
+ },
237
+ NETWORKDAYS: (a) => {
238
+ const start = daySerial(toDate(nth(a, 0)));
239
+ const end = daySerial(toDate(nth(a, 1)));
240
+ const holidays = holidaySet(a.args[2]);
241
+ const from = Math.min(start, end);
242
+ const to = Math.max(start, end);
243
+ let count = 0;
244
+ for (let s = from; s <= to; s += 1) {
245
+ if (!isWeekend(toDate(s)) && !holidays.has(s))
246
+ count += 1;
247
+ }
248
+ return end < start ? -count : count;
249
+ },
250
+ WORKDAY: (a) => {
251
+ let s = daySerial(toDate(nth(a, 0)));
252
+ let left = Math.trunc(num(a, 1));
253
+ const holidays = holidaySet(a.args[2]);
254
+ const step = left < 0 ? -1 : 1;
255
+ while (left !== 0) {
256
+ s += step;
257
+ if (isWeekend(toDate(s)) || holidays.has(s))
258
+ continue;
259
+ left -= step;
260
+ }
261
+ return isoDate(toDate(s));
262
+ },
263
+ // WEEKNUM(date, [type]): 1 and 2 make the week holding January 1 week 1,
264
+ // starting Sunday or Monday; 11 to 17 start on Monday to Sunday; 21 is
265
+ // the ISO week.
266
+ WEEKNUM: (a) => {
267
+ const d = toDate(nth(a, 0));
268
+ const type = opt(a, 1, 1);
269
+ if (type === 21) {
270
+ const t = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));
271
+ // Move to the Thursday of this week; its year is the ISO year.
272
+ t.setUTCDate(t.getUTCDate() - ((t.getUTCDay() + 6) % 7) + 3);
273
+ const jan4 = new Date(Date.UTC(t.getUTCFullYear(), 0, 4));
274
+ const firstThursday = new Date(jan4.getTime());
275
+ firstThursday.setUTCDate(jan4.getUTCDate() - ((jan4.getUTCDay() + 6) % 7) + 3);
276
+ return 1 + Math.round((t.getTime() - firstThursday.getTime()) / (7 * DAY_MS));
277
+ }
278
+ const startDay = type === 1 ? 0 : type === 2 ? 1 : type >= 11 && type <= 17 ? (type - 10) % 7 : -1;
279
+ if (startDay < 0)
280
+ return err('#NUM!');
281
+ const jan1 = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
282
+ const offset = (jan1.getUTCDay() - startDay + 7) % 7;
283
+ const dayOfYear = Math.floor((Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()) - jan1.getTime()) / DAY_MS);
284
+ return Math.floor((dayOfYear + offset) / 7) + 1;
285
+ },
286
+ HOUR: (a) => timeOf(first(a)).h,
287
+ MINUTE: (a) => timeOf(first(a)).m,
288
+ SECOND: (a) => timeOf(first(a)).s,
289
+ // TIME(hour, minute, second): a fraction of a day, wrapping past 24 hours.
290
+ TIME: (a) => {
291
+ const secs = Math.trunc(num(a, 0)) * 3600 + Math.trunc(num(a, 1)) * 60 + Math.trunc(num(a, 2));
292
+ if (secs < 0)
293
+ return err('#NUM!');
294
+ return (secs % 86400) / 86400;
295
+ },
296
+ DATEVALUE: (a) => {
297
+ const v = first(a);
298
+ if (typeof v === 'number')
299
+ return err('#VALUE!');
300
+ return daySerial(toDate(v));
301
+ },
302
+ TIMEVALUE: (a) => {
303
+ const t = timeOf(first(a));
304
+ return (t.h * 3600 + t.m * 60 + t.s) / 86400;
305
+ },
306
+ DAYS360: (a) => days360(toDate(nth(a, 0)), toDate(nth(a, 1))),
307
+ // YEARFRAC(start, end, [basis]): 0 is US 30/360, 1 actual/actual, 2
308
+ // actual/360, 3 actual/365, 4 European 30/360 (read as US here).
309
+ YEARFRAC: (a) => {
310
+ const s = toDate(nth(a, 0));
311
+ const e = toDate(nth(a, 1));
312
+ const basis = Math.trunc(opt(a, 2, 0));
313
+ const from = s.getTime() <= e.getTime() ? s : e;
314
+ const to = s.getTime() <= e.getTime() ? e : s;
315
+ if (basis === 0 || basis === 4)
316
+ return days360(from, to) / 360;
317
+ const days = daySerial(to) - daySerial(from);
318
+ if (basis === 2)
319
+ return days / 360;
320
+ if (basis === 3)
321
+ return days / 365;
322
+ if (basis !== 1)
323
+ return err('#NUM!');
324
+ // Actual/actual: the average year length across the span.
325
+ const y1 = from.getUTCFullYear();
326
+ const y2 = to.getUTCFullYear();
327
+ let total = 0;
328
+ for (let y = y1; y <= y2; y += 1)
329
+ total += isLeap(y) ? 366 : 365;
330
+ return days / (total / (y2 - y1 + 1));
331
+ },
332
+ };
@@ -0,0 +1,2 @@
1
+ import type { SheetFunction } from '../functions.js';
2
+ export declare const TRIG_FUNCTIONS: Record<string, SheetFunction>;
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Excel's Math and Trigonometry family: the circular functions, their
3
+ * inverses, the hyperbolic set, and the two that turn one angle measure
4
+ * into the other.
5
+ *
6
+ * Two traps live here, both of which read as a bug in a model rather than
7
+ * as a difference of convention:
8
+ *
9
+ * - `ATAN2` takes its arguments x first, y second, which is the opposite
10
+ * order from every C-family `atan2`. `=ATAN2(-1, 1)` is 3/4 pi in
11
+ * Excel; handing the pair straight to `Math.atan2` gives -1/4 pi.
12
+ * - The reciprocal functions are undefined where their partner is zero,
13
+ * and Excel reports that as `#DIV/0!` rather than as infinity.
14
+ *
15
+ * Domain errors are `#NUM!`, as Excel reports them: ASIN past 1, ACOSH
16
+ * below 1, ATANH at 1.
17
+ */
18
+ import { err } from '../ast.js';
19
+ import { toNumber } from '../coerce.js';
20
+ const nth = (a, i) => a.args[i]?.[0] ?? '';
21
+ const num = (a, i) => toNumber(nth(a, i));
22
+ /** A result that has to lie in a domain, with Excel's error when it does not. */
23
+ const guard = (ok, value) => (ok ? value() : err('#NUM!'));
24
+ /**
25
+ * A reciprocal of a circular function. Excel calls the pole `#DIV/0!`, and
26
+ * a pole is where the partner function is zero. Comparing against an exact
27
+ * zero is right for COT(0) and CSC(0), which is what people actually type;
28
+ * at pi the partner is only near zero in binary floating point, and Excel
29
+ * answers with the same large number JavaScript does, so nothing is snapped.
30
+ */
31
+ const reciprocal = (partner) => (partner === 0 ? err('#DIV/0!') : 1 / partner);
32
+ export const TRIG_FUNCTIONS = {
33
+ // ---- Circular --------------------------------------------------------
34
+ SIN: (a) => Math.sin(num(a, 0)),
35
+ COS: (a) => Math.cos(num(a, 0)),
36
+ TAN: (a) => Math.tan(num(a, 0)),
37
+ COT: (a) => reciprocal(Math.tan(num(a, 0))),
38
+ SEC: (a) => reciprocal(Math.cos(num(a, 0))),
39
+ CSC: (a) => reciprocal(Math.sin(num(a, 0))),
40
+ // ---- Inverse circular ------------------------------------------------
41
+ ASIN: (a) => { const x = num(a, 0); return guard(x >= -1 && x <= 1, () => Math.asin(x)); },
42
+ ACOS: (a) => { const x = num(a, 0); return guard(x >= -1 && x <= 1, () => Math.acos(x)); },
43
+ ATAN: (a) => Math.atan(num(a, 0)),
44
+ // Excel's argument order is (x, y); Math.atan2 wants (y, x).
45
+ ATAN2: (a) => {
46
+ const x = num(a, 0);
47
+ const y = num(a, 1);
48
+ return x === 0 && y === 0 ? err('#DIV/0!') : Math.atan2(y, x);
49
+ },
50
+ // ACOT is the angle in (0, pi), which is what pi/2 minus ATAN gives for
51
+ // every real argument, zero included.
52
+ ACOT: (a) => Math.PI / 2 - Math.atan(num(a, 0)),
53
+ // ---- Hyperbolic ------------------------------------------------------
54
+ SINH: (a) => Math.sinh(num(a, 0)),
55
+ COSH: (a) => Math.cosh(num(a, 0)),
56
+ TANH: (a) => Math.tanh(num(a, 0)),
57
+ COTH: (a) => reciprocal(Math.tanh(num(a, 0))),
58
+ SECH: (a) => reciprocal(Math.cosh(num(a, 0))),
59
+ CSCH: (a) => reciprocal(Math.sinh(num(a, 0))),
60
+ // ---- Inverse hyperbolic ---------------------------------------------
61
+ ASINH: (a) => Math.asinh(num(a, 0)),
62
+ ACOSH: (a) => { const x = num(a, 0); return guard(x >= 1, () => Math.acosh(x)); },
63
+ ATANH: (a) => { const x = num(a, 0); return guard(x > -1 && x < 1, () => Math.atanh(x)); },
64
+ // ACOTH is defined outside [-1, 1]; at the ends it is a pole.
65
+ ACOTH: (a) => {
66
+ const x = num(a, 0);
67
+ return guard(Math.abs(x) > 1, () => 0.5 * Math.log((x + 1) / (x - 1)));
68
+ },
69
+ // ---- Angle measure and the odd one out -------------------------------
70
+ DEGREES: (a) => (num(a, 0) * 180) / Math.PI,
71
+ RADIANS: (a) => (num(a, 0) * Math.PI) / 180,
72
+ SQRTPI: (a) => { const x = num(a, 0); return guard(x >= 0, () => Math.sqrt(x * Math.PI)); },
73
+ };
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Excel's Page Setup, per sheet: what the Page Layout tab sets and File >
3
+ * Print reads. Orientation, paper, margins, the print area, the rows that
4
+ * repeat at the top of every page, whether gridlines and headings print,
5
+ * and the scale. Margins are in inches, the unit the file keeps them in.
6
+ * Nothing here touches the DOM; `print.ts` turns a sheet and its setup
7
+ * into the page.
8
+ */
9
+ import type { Rect } from './rects.js';
10
+ import type { StructuralEdit } from './refs.js';
11
+ export type PageOrientation = 'portrait' | 'landscape';
12
+ /** The papers Excel's list starts with, with their OOXML `paperSize` codes. */
13
+ export declare const PAPER_SIZES: {
14
+ readonly Letter: {
15
+ readonly code: 1;
16
+ readonly css: "letter";
17
+ };
18
+ readonly Tabloid: {
19
+ readonly code: 3;
20
+ readonly css: "11in 17in";
21
+ };
22
+ readonly Legal: {
23
+ readonly code: 5;
24
+ readonly css: "legal";
25
+ };
26
+ readonly A3: {
27
+ readonly code: 8;
28
+ readonly css: "A3";
29
+ };
30
+ readonly A4: {
31
+ readonly code: 9;
32
+ readonly css: "A4";
33
+ };
34
+ readonly A5: {
35
+ readonly code: 11;
36
+ readonly css: "A5";
37
+ };
38
+ };
39
+ export type PaperSize = keyof typeof PAPER_SIZES;
40
+ /** Inches, as the file keeps them: page edges, and the header and footer bands. */
41
+ export type PageMargins = {
42
+ top: number;
43
+ bottom: number;
44
+ left: number;
45
+ right: number;
46
+ header: number;
47
+ footer: number;
48
+ };
49
+ /** Excel's Margins dropdown. */
50
+ export declare const MARGIN_PRESETS: Record<'normal' | 'narrow' | 'wide', PageMargins>;
51
+ export type MarginPreset = keyof typeof MARGIN_PRESETS;
52
+ export type PageSetup = {
53
+ orientation: PageOrientation;
54
+ paper: PaperSize;
55
+ margins: PageMargins;
56
+ /** The cells that print, or null for everything the sheet holds. */
57
+ printArea: Rect[] | null;
58
+ /** Rows repeated at the top of every page, `[first, last]` 0-based, or null. */
59
+ printTitleRows: [number, number] | null;
60
+ gridlines: boolean;
61
+ headings: boolean;
62
+ /** Percent; 100 prints at size. */
63
+ scale: number;
64
+ };
65
+ export declare const defaultPageSetup: () => PageSetup;
66
+ /** A copy safe to hand out or save. */
67
+ export declare function copyPageSetup(setup: PageSetup): PageSetup;
68
+ /** Which preset the margins are, if any, for the dropdown's lit entry. */
69
+ export declare function marginPresetOf(margins: PageMargins): MarginPreset | null;
70
+ /** The setup after an insert or delete: the print area and the title rows move with their lines. */
71
+ export declare function shiftPageSetup(setup: PageSetup, edit: StructuralEdit): PageSetup;
72
+ /** `@page` margins from inches, the order CSS wants. */
73
+ export declare function marginsCss(margins: PageMargins): string;
@@ -0,0 +1,73 @@
1
+ import { shiftRect, lineShift } from './rects.js';
2
+ /** The papers Excel's list starts with, with their OOXML `paperSize` codes. */
3
+ export const PAPER_SIZES = {
4
+ Letter: { code: 1, css: 'letter' },
5
+ Tabloid: { code: 3, css: '11in 17in' },
6
+ Legal: { code: 5, css: 'legal' },
7
+ A3: { code: 8, css: 'A3' },
8
+ A4: { code: 9, css: 'A4' },
9
+ A5: { code: 11, css: 'A5' },
10
+ };
11
+ /** Excel's Margins dropdown. */
12
+ export const MARGIN_PRESETS = {
13
+ normal: { top: 0.75, bottom: 0.75, left: 0.7, right: 0.7, header: 0.3, footer: 0.3 },
14
+ narrow: { top: 0.75, bottom: 0.75, left: 0.25, right: 0.25, header: 0.3, footer: 0.3 },
15
+ wide: { top: 1, bottom: 1, left: 1, right: 1, header: 0.5, footer: 0.5 },
16
+ };
17
+ export const defaultPageSetup = () => ({
18
+ orientation: 'portrait',
19
+ paper: 'A4',
20
+ margins: { ...MARGIN_PRESETS.normal },
21
+ printArea: null,
22
+ printTitleRows: null,
23
+ gridlines: false,
24
+ headings: false,
25
+ scale: 100,
26
+ });
27
+ /** A copy safe to hand out or save. */
28
+ export function copyPageSetup(setup) {
29
+ return {
30
+ ...setup,
31
+ margins: { ...setup.margins },
32
+ printArea: setup.printArea ? setup.printArea.map(([r1, c1, r2, c2]) => [r1, c1, r2, c2]) : null,
33
+ printTitleRows: setup.printTitleRows ? [setup.printTitleRows[0], setup.printTitleRows[1]] : null,
34
+ };
35
+ }
36
+ /** Which preset the margins are, if any, for the dropdown's lit entry. */
37
+ export function marginPresetOf(margins) {
38
+ for (const [name, preset] of Object.entries(MARGIN_PRESETS)) {
39
+ if (Object.keys(preset).every((k) => Math.abs(preset[k] - margins[k]) < 1e-6))
40
+ return name;
41
+ }
42
+ return null;
43
+ }
44
+ /** The setup after an insert or delete: the print area and the title rows move with their lines. */
45
+ export function shiftPageSetup(setup, edit) {
46
+ const out = copyPageSetup(setup);
47
+ if (out.printArea) {
48
+ const moved = out.printArea.map((r) => shiftRect(r, edit)).filter((r) => r !== null);
49
+ out.printArea = moved.length ? moved : null;
50
+ }
51
+ if (out.printTitleRows && (edit.kind === 'insertRows' || edit.kind === 'deleteRows')) {
52
+ const shift = lineShift(edit);
53
+ const [a, b] = out.printTitleRows;
54
+ if (edit.kind === 'insertRows') {
55
+ out.printTitleRows = [shift(a), shift(b)];
56
+ }
57
+ else {
58
+ const rows = [];
59
+ for (let r = a; r <= b; r += 1) {
60
+ const next = shift(r);
61
+ if (next !== null)
62
+ rows.push(next);
63
+ }
64
+ out.printTitleRows = rows.length ? [rows[0], rows[rows.length - 1]] : null;
65
+ }
66
+ }
67
+ return out;
68
+ }
69
+ /** `@page` margins from inches, the order CSS wants. */
70
+ export function marginsCss(margins) {
71
+ const inch = (n) => `${Math.round(n * 100) / 100}in`;
72
+ return `${inch(margins.top)} ${inch(margins.right)} ${inch(margins.bottom)} ${inch(margins.left)}`;
73
+ }
@@ -22,9 +22,9 @@ export function parse(tokens) {
22
22
  if (prec === undefined || prec < minPrec)
23
23
  break;
24
24
  next();
25
- // Left-associative for everything except `^`, which Excel binds right.
26
- const nextMin = t.v === '^' ? prec : prec + 1;
27
- left = { k: 'binary', op: t.v, left, right: expression(nextMin) };
25
+ // Every binary operator binds left, `^` included: Excel reads 2^3^2 as
26
+ // (2^3)^2, which is 64, where a right-binding `^` would make it 512.
27
+ left = { k: 'binary', op: t.v, left, right: expression(prec + 1) };
28
28
  }
29
29
  return left;
30
30
  }
@@ -47,8 +47,11 @@ export function parse(tokens) {
47
47
  case 'num': return { k: 'num', v: t.v };
48
48
  case 'str': return { k: 'str', v: t.v };
49
49
  case 'bool': return { k: 'bool', v: t.v };
50
+ case 'err': return { k: 'err', v: t.v };
50
51
  case 'ref': return { k: 'ref', ref: t.ref };
52
+ case 'spill': return { k: 'spill', ref: t.ref };
51
53
  case 'range': return { k: 'range', from: t.from, to: t.to };
54
+ case 'range3d': return { k: 'ref3d', sheetFrom: t.sheetFrom, sheetTo: t.sheetTo, from: t.from, to: t.to };
52
55
  case 'name': return { k: 'name', name: t.v };
53
56
  case 'table':
54
57
  return t.columnTo === undefined
@@ -69,25 +72,54 @@ export function parse(tokens) {
69
72
  if (!open || open.t !== 'lparen')
70
73
  throw new FormulaError('#PARSE!');
71
74
  const args = [];
75
+ // An argument left out between two commas, or before the closing
76
+ // paren after a comma, is an empty node rather than a parse error,
77
+ // as Excel reads `PMT(A1, A2, A3, , 1)`.
78
+ const argument = () => {
79
+ const t = peek()?.t;
80
+ return t === 'comma' || t === 'rparen' ? { k: 'empty' } : expression(1);
81
+ };
72
82
  if (peek()?.t !== 'rparen') {
73
- args.push(expression(1));
83
+ args.push(argument());
74
84
  while (peek()?.t === 'comma') {
75
85
  next();
76
- args.push(expression(1));
86
+ args.push(argument());
77
87
  }
78
88
  }
79
89
  const close = next();
80
90
  if (!close || close.t !== 'rparen')
81
91
  throw new FormulaError('#PARSE!');
82
- return { k: 'fn', name: t.v, args };
92
+ let made = { k: 'fn', name: t.v, args };
93
+ // `=LAMBDA(x, x * 2)(5)`: a lambda written and called on the spot.
94
+ // Only a lambda is callable this way, so nothing else changes shape;
95
+ // the call is a `fn` node named `(`, which no tokenizer can produce.
96
+ while (made.k === 'fn' && (made.name === 'LAMBDA' || made.name === '(') && peek()?.t === 'lparen') {
97
+ next();
98
+ const callArgs = [made];
99
+ if (peek()?.t !== 'rparen') {
100
+ callArgs.push(argument());
101
+ while (peek()?.t === 'comma') {
102
+ next();
103
+ callArgs.push(argument());
104
+ }
105
+ }
106
+ const end = next();
107
+ if (!end || end.t !== 'rparen')
108
+ throw new FormulaError('#PARSE!');
109
+ made = { k: 'fn', name: '(', args: callArgs };
110
+ }
111
+ return made;
83
112
  }
84
113
  case 'op': {
85
- // Unary. Binds tighter than every binary operator except `^`, so
86
- // `-2^2` is -(2^2) as in Excel, and `-A1*2` is (-A1)*2.
114
+ // Unary, and it binds tighter than every binary operator, `^`
115
+ // included: Excel reads -2^2 as (-2)^2, which is 4, not -4. Only the
116
+ // postfix `%` is tighter still, so -A1% is -(A1/100). The operand is
117
+ // therefore one term, not an expression: taking an expression here
118
+ // is what swallows the `^`.
87
119
  if (t.v === '-')
88
- return { k: 'unary', op: '-', arg: expression(5) };
120
+ return { k: 'unary', op: '-', arg: postfix(primary()) };
89
121
  if (t.v === '+')
90
- return { k: 'unary', op: '+', arg: expression(5) };
122
+ return { k: 'unary', op: '+', arg: postfix(primary()) };
91
123
  throw new FormulaError('#PARSE!');
92
124
  }
93
125
  default:
@@ -105,6 +105,18 @@ export declare function resolvePasteCell(source: ClipboardCell | undefined, exis
105
105
  }, at?: {
106
106
  row: number;
107
107
  col: number;
108
+ },
109
+ /** Where the cell came from and lands, for a transposed paste: its
110
+ * relative references are turned rather than shifted. */
111
+ turn?: {
112
+ source: {
113
+ row: number;
114
+ col: number;
115
+ };
116
+ dest: {
117
+ row: number;
118
+ col: number;
119
+ };
108
120
  }): PasteResolution;
109
121
  /**
110
122
  * A block from another application says nothing about where it was copied
@@ -161,4 +173,14 @@ export declare function planPaste(grid: ClipboardGrid, destination: {
161
173
  rows: number;
162
174
  cols: number;
163
175
  };
176
+ turn?: {
177
+ source: {
178
+ row: number;
179
+ col: number;
180
+ };
181
+ dest: {
182
+ row: number;
183
+ col: number;
184
+ };
185
+ };
164
186
  }>;