@svgrid/enterprise 3.0.0 → 3.0.2

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 (390) hide show
  1. package/README.md +95 -95
  2. package/dist/ExpressionEditorHarness.svelte.d.ts +2 -2
  3. package/dist/SvAdvancedFilter.svelte.d.ts +2 -2
  4. package/dist/SvAlertRuleEditor.svelte.d.ts +2 -2
  5. package/dist/SvAlertsManager.svelte.d.ts +3 -3
  6. package/dist/SvAlertsPanel.svelte.d.ts +1 -1
  7. package/dist/SvAuthGate.svelte +115 -115
  8. package/dist/SvAuthGate.svelte.d.ts +1 -1
  9. package/dist/SvBoard.svelte.d.ts +1 -1
  10. package/dist/SvExportMenu.svelte +553 -553
  11. package/dist/SvExportMenu.svelte.d.ts +2 -2
  12. package/dist/SvExpressionEditor.svelte.d.ts +2 -2
  13. package/dist/SvFileInput.svelte +113 -113
  14. package/dist/SvFormulaBar.svelte +606 -0
  15. package/dist/SvFormulaBar.svelte.d.ts +62 -0
  16. package/dist/SvGridAlerts.svelte.d.ts +2 -2
  17. package/dist/SvGridBoard.svelte +2358 -2358
  18. package/dist/SvGridBulkEditDrawer.svelte.d.ts +1 -1
  19. package/dist/SvGridEditPanel.svelte +1157 -1157
  20. package/dist/SvGridEditPanel.svelte.d.ts +3 -3
  21. package/dist/SvGridMasterDetail.svelte +116 -116
  22. package/dist/SvGridMasterDetail.svelte.d.ts +1 -1
  23. package/dist/SvGridScheduler.svelte +5358 -5358
  24. package/dist/SvImportDialog.svelte +1020 -1020
  25. package/dist/SvImportDialog.svelte.d.ts +2 -2
  26. package/dist/SvLookupInput.svelte +180 -180
  27. package/dist/SvLookupInput.svelte.d.ts +1 -1
  28. package/dist/SvPivotDesigner.svelte +2041 -1990
  29. package/dist/SvPivotDesigner.svelte.d.ts +2 -2
  30. package/dist/SvRecordDetail.svelte.d.ts +1 -1
  31. package/dist/SvRibbonIcon.svelte +46 -0
  32. package/dist/SvRibbonIcon.svelte.d.ts +17 -0
  33. package/dist/SvSchedule.svelte.d.ts +1 -1
  34. package/dist/SvSchemaChart.svelte +236 -234
  35. package/dist/SvSchemaChart.svelte.d.ts +2 -2
  36. package/dist/SvSchemaDashboard.svelte +130 -130
  37. package/dist/SvSchemaDashboard.svelte.d.ts +3 -3
  38. package/dist/SvSheet.svelte +4114 -0
  39. package/dist/SvSheet.svelte.d.ts +142 -0
  40. package/dist/SvSheetComment.svelte +98 -0
  41. package/dist/SvSheetComment.svelte.d.ts +22 -0
  42. package/dist/SvSheetConditionalFormat.svelte +162 -0
  43. package/dist/SvSheetConditionalFormat.svelte.d.ts +14 -0
  44. package/dist/SvSheetDataValidation.svelte +249 -0
  45. package/dist/SvSheetDataValidation.svelte.d.ts +14 -0
  46. package/dist/SvSheetFilterMenu.svelte +217 -0
  47. package/dist/SvSheetFilterMenu.svelte.d.ts +17 -0
  48. package/dist/SvSheetFindReplace.svelte +132 -0
  49. package/dist/SvSheetFindReplace.svelte.d.ts +10 -0
  50. package/dist/SvSheetFormatCells.svelte +421 -0
  51. package/dist/SvSheetFormatCells.svelte.d.ts +17 -0
  52. package/dist/SvSheetGoalSeek.svelte +144 -0
  53. package/dist/SvSheetGoalSeek.svelte.d.ts +12 -0
  54. package/dist/SvSheetInsertFunction.svelte +147 -0
  55. package/dist/SvSheetInsertFunction.svelte.d.ts +8 -0
  56. package/dist/SvSheetListPicker.svelte +89 -0
  57. package/dist/SvSheetListPicker.svelte.d.ts +16 -0
  58. package/dist/SvSheetManageRules.svelte +185 -0
  59. package/dist/SvSheetManageRules.svelte.d.ts +16 -0
  60. package/dist/SvSheetNameManager.svelte +225 -0
  61. package/dist/SvSheetNameManager.svelte.d.ts +11 -0
  62. package/dist/SvSheetPasteSpecial.svelte +105 -0
  63. package/dist/SvSheetPasteSpecial.svelte.d.ts +12 -0
  64. package/dist/SvSheetRemoveDuplicates.svelte +149 -0
  65. package/dist/SvSheetRemoveDuplicates.svelte.d.ts +12 -0
  66. package/dist/SvSheetRibbon.svelte +1201 -0
  67. package/dist/SvSheetRibbon.svelte.d.ts +34 -0
  68. package/dist/SvSheetSizeDialog.svelte +58 -0
  69. package/dist/SvSheetSizeDialog.svelte.d.ts +11 -0
  70. package/dist/SvSheetTabs.svelte +441 -0
  71. package/dist/SvSheetTabs.svelte.d.ts +36 -0
  72. package/dist/SvSheetTabs.test-harness.svelte.d.ts +17 -0
  73. package/dist/SvSheetTabs.test-harness.svelte.js +22 -0
  74. package/dist/SvSheetTextToColumns.svelte +172 -0
  75. package/dist/SvSheetTextToColumns.svelte.d.ts +13 -0
  76. package/dist/SvSheetValidationAlert.svelte +83 -0
  77. package/dist/SvSheetValidationAlert.svelte.d.ts +15 -0
  78. package/dist/advanced-filter/expr-columns-from-grid.d.ts +1 -1
  79. package/dist/advanced-filter-enable.js +3 -3
  80. package/dist/alerts/alert-engine-attach.d.ts +2 -2
  81. package/dist/alerts/alert-engine-attach.js +3 -3
  82. package/dist/alerts/alert-engine.d.ts +1 -1
  83. package/dist/alerts/alert-engine.js +2 -2
  84. package/dist/alerts/alert-formats.d.ts +1 -1
  85. package/dist/alerts/alert-formats.js +1 -1
  86. package/dist/alerts/alert-observer.d.ts +3 -3
  87. package/dist/alerts/alert-observer.js +1 -1
  88. package/dist/alerts/alert-storage.d.ts +1 -1
  89. package/dist/alerts/alert-store.svelte.d.ts +1 -1
  90. package/dist/alerts/alert-types.d.ts +2 -2
  91. package/dist/alerts.js +2 -2
  92. package/dist/board.js +2 -2
  93. package/dist/cdn/svgrid-enterprise.svelte-external.js +19046 -5428
  94. package/dist/designer/assets/GridMenus-BlsvL_aU.js +8 -0
  95. package/dist/designer/assets/SvChartMenu-BYO9cYdy.css +1 -0
  96. package/dist/designer/assets/SvChartMenu-D9hEeHar.js +1 -0
  97. package/dist/designer/assets/SvDateRangeInput-BBRzrQeg.js +1 -0
  98. package/dist/designer/assets/SvDateRangeInput-C0iCCZ8o.css +1 -0
  99. package/dist/designer/assets/SvDateTimePicker-DARvKUL2.js +1 -0
  100. package/dist/designer/assets/SvDateTimePicker-DPv09DIT.css +1 -0
  101. package/dist/designer/assets/{preload-helper-CG0n22O7.js → SvGrid.helpers-BgT-gnCo.js} +1 -1
  102. package/dist/designer/assets/SvGridCellEditor-C7uQXYds.js +4 -0
  103. package/dist/designer/assets/SvGridChart-B8j1SSy3.js +3 -0
  104. package/dist/designer/assets/SvGridChart-BgLuPO7I.css +1 -0
  105. package/dist/designer/assets/SvGridChartBuilder-08YWWeqY.css +1 -0
  106. package/dist/designer/assets/SvGridChartBuilder-kvyIU_Rl.js +1 -0
  107. package/dist/designer/assets/SvGridChartPanel-4Pc8y5yO.css +1 -0
  108. package/dist/designer/assets/SvGridChartPanel-pT6ITc2P.js +4 -0
  109. package/dist/designer/assets/SvGridChartView-7msfnWZT.css +1 -0
  110. package/dist/designer/assets/SvGridChartView-bg281UA1.js +1 -0
  111. package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +1 -0
  112. package/dist/designer/assets/SvGridDropdown-CcidB3rm.css +1 -0
  113. package/dist/designer/assets/SvListBox-BDS66lmZ.js +110 -0
  114. package/dist/designer/assets/SvListBox-BXfyqy4a.css +1 -0
  115. package/dist/designer/assets/SvMenuList-DJ47ba1h.css +1 -0
  116. package/dist/designer/assets/SvMenuList-Dgq2D5VN.js +1 -0
  117. package/dist/designer/assets/SvTabs-DKmwb5p1.css +1 -0
  118. package/dist/designer/assets/SvTabs-UFCMTHXS.js +1 -0
  119. package/dist/designer/assets/cell-formatting-wr5wm7US.js +1 -0
  120. package/dist/designer/assets/chart-cIPUsbM5.js +1 -0
  121. package/dist/designer/assets/chart-export-B6bkQ3X8.js +11 -0
  122. package/dist/designer/assets/chart-export-pdf-BbA28-gt.js +11 -0
  123. package/dist/designer/assets/chart-panel-messages-DtTxpBUU.js +1 -0
  124. package/dist/designer/assets/chart-summary-Czu_5epb.js +1 -0
  125. package/dist/designer/assets/chart-trend-D5I5VEe8.js +1 -0
  126. package/dist/designer/assets/chart-validate-BMqM-qkF.js +1 -0
  127. package/dist/designer/assets/column-resize-BYDzR1Ve.js +1 -0
  128. package/dist/designer/assets/date-format-B8JbEtIG.js +1 -0
  129. package/dist/designer/assets/date-format-DKS-z0xS.css +1 -0
  130. package/dist/designer/assets/editor-contract-Bpoa7A5g.js +1 -0
  131. package/dist/designer/assets/export-format-D-eP4b2l.js +6 -0
  132. package/dist/designer/assets/focus-trap-CAreAhlU.js +1 -0
  133. package/dist/designer/assets/index-CMFgAoVV.css +1 -0
  134. package/dist/designer/assets/{index-zUBix-JQ.js → index-DwU7CAMm.js} +2985 -141
  135. package/dist/designer/assets/list-option-BP_dWS66.js +1 -0
  136. package/dist/designer/assets/preload-helper-HclGiUj8.js +1 -0
  137. package/dist/designer/assets/row-resize-DLktcqUK.js +1 -0
  138. package/dist/designer/assets/src-CITpcm6b.js +1 -0
  139. package/dist/designer/assets/src-EdI3Xqds.js +58 -0
  140. package/dist/designer/index.html +32 -23
  141. package/dist/export-conditional.d.ts +1 -1
  142. package/dist/export-pdf.d.ts +89 -0
  143. package/dist/export-pdf.js +130 -0
  144. package/dist/export-print.js +19 -19
  145. package/dist/export-xls.d.ts +2 -2
  146. package/dist/export.d.ts +2 -2
  147. package/dist/export.js +23 -16
  148. package/dist/expressions/builder-tree.d.ts +2 -2
  149. package/dist/expressions/builder-tree.js +1 -1
  150. package/dist/expressions/compile.d.ts +1 -1
  151. package/dist/import.js +1 -1
  152. package/dist/index.d.ts +116 -53
  153. package/dist/index.js +117 -50
  154. package/dist/install.d.ts +4 -4
  155. package/dist/install.js +16 -11
  156. package/dist/license.d.ts +3 -2
  157. package/dist/license.js +9 -4
  158. package/dist/node/studio.js +187 -116
  159. package/dist/pivot-chart.d.ts +26 -2
  160. package/dist/pivot-chart.js +25 -69
  161. package/dist/pivot-designer.d.ts +1 -1
  162. package/dist/pivot-enable.js +3 -3
  163. package/dist/print.d.ts +1 -1
  164. package/dist/print.js +4 -4
  165. package/dist/scheduler-config.d.ts +5 -5
  166. package/dist/scheduler-freebusy.d.ts +1 -1
  167. package/dist/scheduler-freebusy.js +1 -1
  168. package/dist/scheduler.js +2 -2
  169. package/dist/schema-designer.d.ts +1 -1
  170. package/dist/schema-designer.js +2 -2
  171. package/dist/selection-bar.js +2 -2
  172. package/dist/sheet/address.d.ts +43 -0
  173. package/dist/sheet/address.js +81 -0
  174. package/dist/sheet/ast.d.ts +94 -0
  175. package/dist/sheet/ast.js +56 -0
  176. package/dist/sheet/auto-filter.d.ts +66 -0
  177. package/dist/sheet/auto-filter.js +147 -0
  178. package/dist/sheet/autocomplete.d.ts +42 -0
  179. package/dist/sheet/autocomplete.js +162 -0
  180. package/dist/sheet/coerce.d.ts +31 -0
  181. package/dist/sheet/coerce.js +122 -0
  182. package/dist/sheet/commands.d.ts +89 -0
  183. package/dist/sheet/commands.js +230 -0
  184. package/dist/sheet/comments.d.ts +29 -0
  185. package/dist/sheet/comments.js +73 -0
  186. package/dist/sheet/conditional-formats.d.ts +144 -0
  187. package/dist/sheet/conditional-formats.js +316 -0
  188. package/dist/sheet/deps.d.ts +60 -0
  189. package/dist/sheet/deps.js +199 -0
  190. package/dist/sheet/document.d.ts +150 -0
  191. package/dist/sheet/document.js +264 -0
  192. package/dist/sheet/edit-keys.d.ts +14 -0
  193. package/dist/sheet/edit-keys.js +40 -0
  194. package/dist/sheet/entry.d.ts +31 -0
  195. package/dist/sheet/entry.js +76 -0
  196. package/dist/sheet/evaluate.d.ts +61 -0
  197. package/dist/sheet/evaluate.js +337 -0
  198. package/dist/sheet/find-replace.d.ts +62 -0
  199. package/dist/sheet/find-replace.js +152 -0
  200. package/dist/sheet/format-store.d.ts +99 -0
  201. package/dist/sheet/format-store.js +233 -0
  202. package/dist/sheet/freeze.d.ts +54 -0
  203. package/dist/sheet/freeze.js +58 -0
  204. package/dist/sheet/function-catalog.d.ts +10 -0
  205. package/dist/sheet/function-catalog.js +94 -0
  206. package/dist/sheet/functions.d.ts +28 -0
  207. package/dist/sheet/functions.js +362 -0
  208. package/dist/sheet/goal-seek.d.ts +73 -0
  209. package/dist/sheet/goal-seek.js +153 -0
  210. package/dist/sheet/index.d.ts +53 -0
  211. package/dist/sheet/index.js +53 -0
  212. package/dist/sheet/merges.d.ts +71 -0
  213. package/dist/sheet/merges.js +137 -0
  214. package/dist/sheet/names.d.ts +31 -0
  215. package/dist/sheet/names.js +87 -0
  216. package/dist/sheet/navigate.d.ts +52 -0
  217. package/dist/sheet/navigate.js +135 -0
  218. package/dist/sheet/number-format.d.ts +63 -0
  219. package/dist/sheet/number-format.js +508 -0
  220. package/dist/sheet/palette.d.ts +19 -0
  221. package/dist/sheet/palette.js +84 -0
  222. package/dist/sheet/parse.d.ts +13 -0
  223. package/dist/sheet/parse.js +108 -0
  224. package/dist/sheet/paste-special.d.ts +164 -0
  225. package/dist/sheet/paste-special.js +592 -0
  226. package/dist/sheet/protection.d.ts +21 -0
  227. package/dist/sheet/protection.js +48 -0
  228. package/dist/sheet/rects.d.ts +45 -0
  229. package/dist/sheet/rects.js +112 -0
  230. package/dist/sheet/refs.d.ts +82 -0
  231. package/dist/sheet/refs.js +266 -0
  232. package/dist/sheet/ribbon-icons.d.ts +31 -0
  233. package/dist/sheet/ribbon-icons.js +350 -0
  234. package/dist/sheet/ribbon.d.ts +173 -0
  235. package/dist/sheet/ribbon.js +753 -0
  236. package/dist/sheet/shortcuts.d.ts +164 -0
  237. package/dist/sheet/shortcuts.js +623 -0
  238. package/dist/sheet/structure.d.ts +87 -0
  239. package/dist/sheet/structure.js +166 -0
  240. package/dist/sheet/tables.d.ts +70 -0
  241. package/dist/sheet/tables.js +147 -0
  242. package/dist/sheet/tokenize.d.ts +54 -0
  243. package/dist/sheet/tokenize.js +304 -0
  244. package/dist/sheet/transforms.d.ts +76 -0
  245. package/dist/sheet/transforms.js +154 -0
  246. package/dist/sheet/validation.d.ts +92 -0
  247. package/dist/sheet/validation.js +241 -0
  248. package/dist/sheet/workbook.d.ts +72 -0
  249. package/dist/sheet/workbook.js +409 -0
  250. package/dist/sheet-enable.d.ts +6 -0
  251. package/dist/sheet-enable.js +46 -0
  252. package/dist/sources/aggregate.d.ts +1 -1
  253. package/dist/sources/auth-supabase.js +1 -1
  254. package/dist/sources/dashboard.d.ts +2 -2
  255. package/dist/sources/dashboard.js +1 -1
  256. package/dist/sources/index.d.ts +13 -13
  257. package/dist/sources/index.js +13 -13
  258. package/dist/sources/realtime-supabase.js +1 -1
  259. package/dist/sources/relation-lookup.d.ts +1 -1
  260. package/dist/sources/relation-lookup.js +1 -1
  261. package/dist/sources/rest-adapters.d.ts +1 -1
  262. package/dist/sources/rest-adapters.js +1 -1
  263. package/dist/sources/rest.d.ts +2 -2
  264. package/dist/sources/rest.js +3 -3
  265. package/dist/sources/supabase.d.ts +2 -2
  266. package/dist/sources/supabase.js +3 -3
  267. package/dist/sources/with-entity-rules.d.ts +1 -1
  268. package/dist/sources/with-entity-rules.js +1 -1
  269. package/dist/sources/with-relation-labels.d.ts +1 -1
  270. package/dist/studio/emit-project.js +2161 -2127
  271. package/dist/studio/emit-schema.js +369 -369
  272. package/dist/studio/index.d.ts +1 -1
  273. package/dist/studio/index.js +1 -1
  274. package/dist/studio/introspect-db.js +45 -45
  275. package/dist/studio/project.d.ts +10 -0
  276. package/dist/studio/samples/crm.js +6 -6
  277. package/dist/studio/samples/fleet.js +7 -7
  278. package/dist/studio/samples/insurance.js +9 -9
  279. package/dist/studio/samples/inventory.js +12 -12
  280. package/dist/studio/samples/projects.js +5 -5
  281. package/dist/studio/samples/support.js +8 -8
  282. package/dist/studio/scaffold-app.js +104 -104
  283. package/dist/studio/scaffold.js +151 -151
  284. package/dist/studio/ui-components.d.ts +7 -0
  285. package/dist/studio/ui-components.generated.js +63 -1
  286. package/dist/studio/ui-components.js +35 -0
  287. package/dist/sveltekit/in-memory.d.ts +3 -3
  288. package/dist/sveltekit/in-memory.js +4 -4
  289. package/dist/sveltekit/index.d.ts +6 -6
  290. package/dist/sveltekit/index.js +5 -5
  291. package/dist/sveltekit/query-plan.d.ts +1 -1
  292. package/dist/sveltekit/sql-source.d.ts +4 -4
  293. package/dist/sveltekit/sql-source.js +4 -4
  294. package/dist/sveltekit/sql.d.ts +1 -1
  295. package/dist/sveltekit/transport.d.ts +2 -2
  296. package/dist/sveltekit/transport.js +1 -1
  297. package/dist/upgrade-prompt.js +25 -25
  298. package/dist/version.d.ts +1 -1
  299. package/dist/version.js +1 -1
  300. package/package.json +12 -4
  301. package/dist/designer/assets/GridMenus-Cgilexpk.js +0 -8
  302. package/dist/designer/assets/SvDateRangeInput-BV5OXYQ2.css +0 -1
  303. package/dist/designer/assets/SvDateRangeInput-CVn-yqrQ.js +0 -1
  304. package/dist/designer/assets/SvDateTimePicker-BdioTrJQ.js +0 -1
  305. package/dist/designer/assets/SvDateTimePicker-CY8TK4BT.css +0 -1
  306. package/dist/designer/assets/SvField-BF-9TJSd.css +0 -1
  307. package/dist/designer/assets/SvField-BsqiA5me.js +0 -1
  308. package/dist/designer/assets/SvGridCellEditor-dLY7_kk9.js +0 -2
  309. package/dist/designer/assets/SvGridChart-BEDNTdc5.js +0 -2
  310. package/dist/designer/assets/SvGridChart-Vu4Nvjiv.css +0 -1
  311. package/dist/designer/assets/SvGridChartPanel-x3lzSxuf.js +0 -10
  312. package/dist/designer/assets/SvGridChartView-CAKhPELi.js +0 -1
  313. package/dist/designer/assets/SvGridChartView-DX9HfkBR.css +0 -1
  314. package/dist/designer/assets/SvGridDropdown-CAYG7Y-O.js +0 -1
  315. package/dist/designer/assets/SvGridDropdown-Crwb2P3Q.css +0 -1
  316. package/dist/designer/assets/SvListBox-CVYQcLX9.js +0 -1
  317. package/dist/designer/assets/SvListBox-DgN8kvjt.css +0 -1
  318. package/dist/designer/assets/chart-DHEgt4lN.js +0 -1
  319. package/dist/designer/assets/column-resize-C_inr5zT.js +0 -1
  320. package/dist/designer/assets/date-format-4DJvNtG2.js +0 -1
  321. package/dist/designer/assets/date-format-Dzy4mTGh.css +0 -1
  322. package/dist/designer/assets/easing-zaypKrr0.js +0 -3
  323. package/dist/designer/assets/export-format-DwjuTfrQ.js +0 -6
  324. package/dist/designer/assets/index-Cp7fDJ3b.css +0 -1
  325. package/dist/designer/assets/js-scroller.svelte-Bhxqb3-c.js +0 -110
  326. package/dist/designer/assets/row-resize-B0FWHcNr.js +0 -1
  327. package/dist/designer/assets/src-B7DNcoQK.css +0 -1
  328. package/dist/designer/assets/src-BoYyigAC.js +0 -2896
  329. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +0 -1
  330. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +0 -178
  331. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js +0 -3875
  332. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js.map +0 -1
  333. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js +0 -21
  334. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js.map +0 -1
  335. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js +0 -1938
  336. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js.map +0 -1
  337. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js +0 -205
  338. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js.map +0 -1
  339. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js +0 -18
  340. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js.map +0 -1
  341. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js +0 -264
  342. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js.map +0 -1
  343. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js +0 -697
  344. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js.map +0 -1
  345. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +0 -3
  346. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +0 -134
  347. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +0 -1
  348. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +0 -55
  349. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +0 -1
  350. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +0 -2
  351. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +0 -46843
  352. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +0 -1
  353. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +0 -237
  354. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +0 -1
  355. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +0 -2
  356. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +0 -4
  357. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +0 -1
  358. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +0 -7
  359. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +0 -4
  360. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +0 -1
  361. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +0 -5
  362. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +0 -1
  363. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +0 -5
  364. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -1
  365. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +0 -5
  366. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -1
  367. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +0 -6
  368. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +0 -83
  369. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +0 -1
  370. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +0 -559
  371. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +0 -1
  372. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +0 -24
  373. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +0 -1
  374. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +0 -122
  375. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +0 -1
  376. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +0 -2
  377. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +0 -89
  378. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +0 -1
  379. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +0 -241
  380. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +0 -1
  381. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js +0 -4938
  382. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js.map +0 -1
  383. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js +0 -495
  384. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js.map +0 -1
  385. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js +0 -190
  386. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js.map +0 -1
  387. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js +0 -8
  388. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js.map +0 -1
  389. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js +0 -138
  390. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js.map +0 -1
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Cell comments, Excel's notes: a text on a cell, shown as a corner mark
3
+ * and read on hover. They live in the sheet document in the grid's own
4
+ * `notes` shape (`r4` -> `B` -> text), so the grid draws the mark and the
5
+ * tooltip and the document moves them with an insert or delete
6
+ * (`remapNotes`). This module is the pure part: reading, writing, and
7
+ * walking them the way Review > Previous / Next do.
8
+ */
9
+ import { colToLetters, lettersToCol } from './address.js';
10
+ /** The comment on (r, c), or undefined when there is none. */
11
+ export function commentAt(notes, r, c) {
12
+ const text = notes[`r${r}`]?.[colToLetters(c)];
13
+ return text && text.trim() ? text : undefined;
14
+ }
15
+ /**
16
+ * The map with (r, c) set to `text`, or cleared when the text is blank.
17
+ * A new map, never the old one changed: the grid re-reads `notes` only
18
+ * when the object it is handed is a different one.
19
+ */
20
+ export function withComment(notes, r, c, text) {
21
+ const rowId = `r${r}`;
22
+ const columnId = colToLetters(c);
23
+ const out = {};
24
+ for (const [id, line] of Object.entries(notes))
25
+ out[id] = { ...line };
26
+ if (text.trim()) {
27
+ out[rowId] = { ...(out[rowId] ?? {}), [columnId]: text };
28
+ }
29
+ else if (out[rowId]) {
30
+ delete out[rowId][columnId];
31
+ if (Object.keys(out[rowId]).length === 0)
32
+ delete out[rowId];
33
+ }
34
+ return out;
35
+ }
36
+ /** Every comment, top to bottom then left to right. */
37
+ export function listComments(notes) {
38
+ const out = [];
39
+ for (const [rowId, line] of Object.entries(notes)) {
40
+ const row = Number(rowId.slice(1));
41
+ if (!Number.isInteger(row) || row < 0)
42
+ continue;
43
+ for (const [columnId, text] of Object.entries(line)) {
44
+ const col = lettersToCol(columnId);
45
+ if (col < 0 || !text || !text.trim())
46
+ continue;
47
+ out.push({ row, col, text });
48
+ }
49
+ }
50
+ return out.sort((a, b) => a.row - b.row || a.col - b.col);
51
+ }
52
+ /**
53
+ * The comment after (or before) `from`, reading the sheet row by row and
54
+ * wrapping at the end, as Excel's Next Comment and Previous Comment do. The
55
+ * cell itself is skipped, so pressing Next on a commented cell moves on;
56
+ * null when the sheet has no comments at all.
57
+ */
58
+ export function nextComment(notes, from, dir) {
59
+ const all = listComments(notes);
60
+ if (!all.length)
61
+ return null;
62
+ const after = (a, b) => a.row > b.row || (a.row === b.row && a.col > b.col);
63
+ const at = (entry) => ({ row: entry.row, col: entry.col });
64
+ if (dir === 1) {
65
+ const hit = all.find((entry) => after(entry, from));
66
+ return at(hit ?? all[0]);
67
+ }
68
+ for (let i = all.length - 1; i >= 0; i -= 1) {
69
+ if (after(from, all[i]))
70
+ return at(all[i]);
71
+ }
72
+ return at(all[all.length - 1]);
73
+ }
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Conditional formatting, Excel's: rules over cells that colour them by
3
+ * what they hold. Highlight Cells Rules (greater than, between, text that
4
+ * contains, duplicates), Top/Bottom Rules (top 10, above average), Data
5
+ * Bars, Color Scales and Icon Sets, each over rectangles that move with
6
+ * an insert or delete.
7
+ *
8
+ * Rules are evaluated over COMPUTED values (what a formula shows, not its
9
+ * text), which is why the model lives here beside the workbook rather than
10
+ * in the grid's own value-driven rules. The statistics a rule needs over
11
+ * its range (min, max, mean, rank, counts) are computed once per repaint by
12
+ * the shell and handed in, so a thousand cells cost one pass.
13
+ *
14
+ * Priority is array order, first rule first, as Excel's Manage Rules lists
15
+ * them: the first rule that decides a property wins it, and a rule with
16
+ * Stop If True stops the rules below it for the cells it matches.
17
+ */
18
+ import { type CellValue } from './ast.js';
19
+ import type { StructuralEdit } from './refs.js';
20
+ import { type Rect } from './rects.js';
21
+ import type { CellFormatEntry } from './format-store.js';
22
+ export type CfStyle = Pick<CellFormatEntry, 'fill' | 'color' | 'bold' | 'italic' | 'underline' | 'strike' | 'numFmt'>;
23
+ export type CfOperator = 'greater' | 'less' | 'between' | 'notBetween' | 'equal' | 'notEqual' | 'greaterOrEqual' | 'lessOrEqual';
24
+ export type CfTextMatch = 'contains' | 'notContains' | 'beginsWith' | 'endsWith';
25
+ export type CfIconSet = 'arrows' | 'traffic' | 'flags' | 'symbols';
26
+ export type CfScaleColors = readonly [string, string] | readonly [string, string, string];
27
+ export type CfRule = {
28
+ id: string;
29
+ rects: ReadonlyArray<Rect>;
30
+ stopIfTrue?: boolean;
31
+ } & ({
32
+ kind: 'cellIs';
33
+ operator: CfOperator;
34
+ value1: string;
35
+ value2?: string;
36
+ style: CfStyle;
37
+ } | {
38
+ kind: 'text';
39
+ match: CfTextMatch;
40
+ value: string;
41
+ style: CfStyle;
42
+ } | {
43
+ kind: 'duplicates';
44
+ unique?: boolean;
45
+ style: CfStyle;
46
+ } | {
47
+ kind: 'topBottom';
48
+ top: boolean;
49
+ rank: number;
50
+ percent?: boolean;
51
+ style: CfStyle;
52
+ } | {
53
+ kind: 'average';
54
+ above: boolean;
55
+ style: CfStyle;
56
+ } | {
57
+ kind: 'dataBar';
58
+ color: string;
59
+ } | {
60
+ kind: 'colorScale';
61
+ colors: CfScaleColors;
62
+ } | {
63
+ kind: 'iconSet';
64
+ set: CfIconSet;
65
+ });
66
+ export type CfKind = CfRule['kind'];
67
+ /** A rule that carries a style: what the small dialogs make. */
68
+ export type CfStyledRule = Extract<CfRule, {
69
+ style: CfStyle;
70
+ }>;
71
+ /** Omit that keeps a union a union, one member at a time. */
72
+ type DistributiveOmit<T, K extends keyof never> = T extends unknown ? Omit<T, K> : never;
73
+ /** Any rule without its id and rectangles: what a new rule is made from. */
74
+ export type CfRuleBody = DistributiveOmit<CfRule, 'id' | 'rects'>;
75
+ /** A styled rule without its id and rectangles: what the dialog hands back. */
76
+ export type CfBody = DistributiveOmit<CfStyledRule, 'id' | 'rects'>;
77
+ /** The small dialogs, one per ribbon entry. */
78
+ export type CfPreset = 'greater' | 'less' | 'between' | 'equal' | 'text' | 'duplicates' | 'top10' | 'bottom10' | 'aboveAverage' | 'belowAverage';
79
+ /** What one rule knows about the numbers in its rectangles. */
80
+ export type CfStats = {
81
+ /** Numbers, sorted ascending. */
82
+ sorted: number[];
83
+ min: number;
84
+ max: number;
85
+ mean: number;
86
+ /** How often each display text occurs, for Duplicate Values. */
87
+ counts: Map<string, number>;
88
+ };
89
+ /** What the rules say about one cell. */
90
+ export type CfResult = {
91
+ style?: CfStyle;
92
+ /** A bar across the cell, 0..1 of its width. */
93
+ dataBar?: {
94
+ ratio: number;
95
+ color: string;
96
+ };
97
+ /** The icon set and which of its three icons: 0 = the top one. */
98
+ icon?: {
99
+ set: CfIconSet;
100
+ index: 0 | 1 | 2;
101
+ };
102
+ };
103
+ /** How a rule reads the sheet: the shell wires the workbook in. */
104
+ export type CfContext = {
105
+ /** A formula or a literal, evaluated in the sheet. */
106
+ evaluate(text: string): CellValue;
107
+ };
108
+ /** The six "with" styles of Excel's Highlight Cells dialogs. */
109
+ export declare const CF_PRESET_STYLES: ReadonlyArray<{
110
+ id: string;
111
+ label: string;
112
+ style: CfStyle;
113
+ }>;
114
+ export declare const DATA_BAR_COLOR = "#638EC6";
115
+ export declare const COLOR_SCALES: Record<'green-yellow-red' | 'red-yellow-green' | 'green-white' | 'white-red', CfScaleColors>;
116
+ export declare function cfId(): string;
117
+ /**
118
+ * The numbers and the texts a rule's rectangles hold. One pass; the shell
119
+ * caches the result per rule until the next repaint.
120
+ */
121
+ export declare function ruleStats(rule: CfRule, valueAt: (r: number, c: number) => CellValue, displayAt: (r: number, c: number) => string): CfStats;
122
+ /** The colour a scale gives a position 0..1. */
123
+ export declare function scaleColor(colors: CfScaleColors, t: number): string;
124
+ /** Which of an icon set's three icons a position 0..1 gets: Excel's thirds. */
125
+ export declare function iconIndex(t: number): 0 | 1 | 2;
126
+ /**
127
+ * What the rules say about (r, c). Array order is priority; the first rule
128
+ * that decides a property (the fill, the text colour, the bar, the icon)
129
+ * keeps it; a matching rule with Stop If True ends the walk.
130
+ */
131
+ export declare function evaluateCf(rules: ReadonlyArray<CfRule>, r: number, c: number, value: CellValue, display: string, statsFor: (rule: CfRule) => CfStats, ctx: CfContext): CfResult | null;
132
+ /** The rules after an insert or delete. */
133
+ export declare function shiftCf(rules: ReadonlyArray<CfRule>, edit: StructuralEdit): CfRule[];
134
+ /** The rules with the rectangles cut out of them: Clear Rules from Selected Cells. */
135
+ export declare function removeCf(rules: ReadonlyArray<CfRule>, rects: ReadonlyArray<Rect>): CfRule[];
136
+ /** The rules touching any of the rectangles. */
137
+ export declare function cfIn(rules: ReadonlyArray<CfRule>, rects: ReadonlyArray<Rect>): CfRule[];
138
+ /** A rule in words, the way Excel's Manage Rules lists it. */
139
+ export declare function describeCf(rule: CfRule): string;
140
+ /** Whether a rule carries a style the dialog can edit. */
141
+ export declare function hasStyle(rule: CfRule): rule is Extract<CfRule, {
142
+ style: CfStyle;
143
+ }>;
144
+ export {};
@@ -0,0 +1,316 @@
1
+ /**
2
+ * Conditional formatting, Excel's: rules over cells that colour them by
3
+ * what they hold. Highlight Cells Rules (greater than, between, text that
4
+ * contains, duplicates), Top/Bottom Rules (top 10, above average), Data
5
+ * Bars, Color Scales and Icon Sets, each over rectangles that move with
6
+ * an insert or delete.
7
+ *
8
+ * Rules are evaluated over COMPUTED values (what a formula shows, not its
9
+ * text), which is why the model lives here beside the workbook rather than
10
+ * in the grid's own value-driven rules. The statistics a rule needs over
11
+ * its range (min, max, mean, rank, counts) are computed once per repaint by
12
+ * the shell and handed in, so a thousand cells cost one pass.
13
+ *
14
+ * Priority is array order, first rule first, as Excel's Manage Rules lists
15
+ * them: the first rule that decides a property wins it, and a rule with
16
+ * Stop If True stops the rules below it for the cells it matches.
17
+ */
18
+ import { isError } from './ast.js';
19
+ import { toText } from './coerce.js';
20
+ import { rectContains, shiftRects, subtractRect, rectsIntersect } from './rects.js';
21
+ // ---------------------------------------------------------------------------
22
+ // Excel's palettes
23
+ // ---------------------------------------------------------------------------
24
+ /** The six "with" styles of Excel's Highlight Cells dialogs. */
25
+ export const CF_PRESET_STYLES = [
26
+ { id: 'light-red', label: 'Light Red Fill with Dark Red Text', style: { fill: '#FFC7CE', color: '#9C0006' } },
27
+ { id: 'yellow', label: 'Yellow Fill with Dark Yellow Text', style: { fill: '#FFEB9C', color: '#9C5700' } },
28
+ { id: 'green', label: 'Green Fill with Dark Green Text', style: { fill: '#C6EFCE', color: '#006100' } },
29
+ { id: 'red-fill', label: 'Light Red Fill', style: { fill: '#FFC7CE' } },
30
+ { id: 'red-text', label: 'Red Text', style: { color: '#9C0006' } },
31
+ ];
32
+ export const DATA_BAR_COLOR = '#638EC6';
33
+ export const COLOR_SCALES = {
34
+ 'green-yellow-red': ['#63BE7B', '#FFEB84', '#F8696B'],
35
+ 'red-yellow-green': ['#F8696B', '#FFEB84', '#63BE7B'],
36
+ 'green-white': ['#63BE7B', '#FCFCFF'],
37
+ 'white-red': ['#FCFCFF', '#F8696B'],
38
+ };
39
+ let nextId = 1;
40
+ export function cfId() {
41
+ nextId += 1;
42
+ return `cf${Date.now().toString(36)}${nextId}`;
43
+ }
44
+ // ---------------------------------------------------------------------------
45
+ // Statistics
46
+ // ---------------------------------------------------------------------------
47
+ /**
48
+ * The numbers and the texts a rule's rectangles hold. One pass; the shell
49
+ * caches the result per rule until the next repaint.
50
+ */
51
+ export function ruleStats(rule, valueAt, displayAt) {
52
+ const numbers = [];
53
+ const counts = new Map();
54
+ let sum = 0;
55
+ for (const [r1, c1, r2, c2] of rule.rects) {
56
+ for (let r = r1; r <= r2; r += 1) {
57
+ for (let c = c1; c <= c2; c += 1) {
58
+ const v = valueAt(r, c);
59
+ if (typeof v === 'number' && Number.isFinite(v)) {
60
+ numbers.push(v);
61
+ sum += v;
62
+ }
63
+ if (rule.kind === 'duplicates') {
64
+ const shown = displayAt(r, c);
65
+ if (shown !== '')
66
+ counts.set(shown, (counts.get(shown) ?? 0) + 1);
67
+ }
68
+ }
69
+ }
70
+ }
71
+ numbers.sort((a, b) => a - b);
72
+ return {
73
+ sorted: numbers,
74
+ min: numbers[0] ?? 0,
75
+ max: numbers[numbers.length - 1] ?? 0,
76
+ mean: numbers.length ? sum / numbers.length : 0,
77
+ counts,
78
+ };
79
+ }
80
+ // ---------------------------------------------------------------------------
81
+ // Evaluation
82
+ // ---------------------------------------------------------------------------
83
+ function numberOf(text, ctx) {
84
+ const v = ctx.evaluate(text);
85
+ if (isError(v) || typeof v === 'boolean')
86
+ return null;
87
+ const n = typeof v === 'number' ? v : Number(v);
88
+ return Number.isFinite(n) ? n : null;
89
+ }
90
+ function textOf(text, ctx) {
91
+ const t = text.trim();
92
+ if (!t.startsWith('='))
93
+ return t;
94
+ const v = ctx.evaluate(t);
95
+ return isError(v) ? '' : toText(v);
96
+ }
97
+ function cellIs(value, operator, a, b) {
98
+ if (a === null)
99
+ return false;
100
+ switch (operator) {
101
+ case 'greater': return value > a;
102
+ case 'less': return value < a;
103
+ case 'greaterOrEqual': return value >= a;
104
+ case 'lessOrEqual': return value <= a;
105
+ case 'equal': return value === a;
106
+ case 'notEqual': return value !== a;
107
+ case 'between': return b !== null && value >= Math.min(a, b) && value <= Math.max(a, b);
108
+ case 'notBetween': return b !== null && (value < Math.min(a, b) || value > Math.max(a, b));
109
+ }
110
+ }
111
+ /** Whether a styling rule matches the cell. */
112
+ function matches(rule, value, display, stats, ctx) {
113
+ switch (rule.kind) {
114
+ case 'cellIs': {
115
+ const isEquality = rule.operator === 'equal' || rule.operator === 'notEqual';
116
+ const a = numberOf(rule.value1, ctx);
117
+ if (typeof value === 'number' && (a !== null || !isEquality)) {
118
+ return cellIs(value, rule.operator, a, rule.value2 === undefined ? null : numberOf(rule.value2, ctx));
119
+ }
120
+ // Equal to / not equal to compare as text where either side is text,
121
+ // as Excel does: 5 is not equal to 'Paid', and 'paid' is equal to it.
122
+ if (!isEquality)
123
+ return false;
124
+ const same = display !== '' && display.toLowerCase() === textOf(rule.value1, ctx).toLowerCase();
125
+ return rule.operator === 'equal' ? same : display !== '' && !same;
126
+ }
127
+ case 'text': {
128
+ if (display === '')
129
+ return false;
130
+ const hay = display.toLowerCase();
131
+ const needle = textOf(rule.value, ctx).toLowerCase();
132
+ if (needle === '')
133
+ return false;
134
+ switch (rule.match) {
135
+ case 'contains': return hay.includes(needle);
136
+ case 'notContains': return !hay.includes(needle);
137
+ case 'beginsWith': return hay.startsWith(needle);
138
+ case 'endsWith': return hay.endsWith(needle);
139
+ default: return false;
140
+ }
141
+ }
142
+ case 'duplicates': {
143
+ if (display === '')
144
+ return false;
145
+ const n = stats.counts.get(display) ?? 0;
146
+ return rule.unique ? n === 1 : n > 1;
147
+ }
148
+ case 'topBottom': {
149
+ if (typeof value !== 'number' || !stats.sorted.length)
150
+ return false;
151
+ const count = rule.percent
152
+ ? Math.max(1, Math.round((stats.sorted.length * rule.rank) / 100))
153
+ : rule.rank;
154
+ if (count <= 0)
155
+ return false;
156
+ // The cut is the count-th value from the top (or bottom); ties keep
157
+ // every cell at that value in, as Excel's do.
158
+ const sorted = stats.sorted;
159
+ const cut = rule.top
160
+ ? sorted[Math.max(sorted.length - count, 0)]
161
+ : sorted[Math.min(count - 1, sorted.length - 1)];
162
+ return rule.top ? value >= cut : value <= cut;
163
+ }
164
+ case 'average': {
165
+ if (typeof value !== 'number' || !stats.sorted.length)
166
+ return false;
167
+ return rule.above ? value > stats.mean : value < stats.mean;
168
+ }
169
+ default:
170
+ return false;
171
+ }
172
+ }
173
+ /**
174
+ * A data bar's share of the cell, 0..1. Excel measures from zero when the
175
+ * range is non-negative (10, 20, 40 draw a quarter, a half and the whole
176
+ * width), so the smallest value keeps a bar; a range with negatives runs
177
+ * from its minimum instead, since there is no negative axis here.
178
+ */
179
+ function barRatio(value, stats) {
180
+ const lo = Math.min(0, stats.min);
181
+ const hi = Math.max(0, stats.max);
182
+ if (hi === lo)
183
+ return 0;
184
+ return Math.min(1, Math.max(0, (value - lo) / (hi - lo)));
185
+ }
186
+ /** Where a number sits in a range, 0..1; 0.5 for a flat range. */
187
+ function ratioOf(value, stats) {
188
+ if (stats.max === stats.min)
189
+ return 0.5;
190
+ return Math.min(1, Math.max(0, (value - stats.min) / (stats.max - stats.min)));
191
+ }
192
+ /** Linear interpolate two hex colours. */
193
+ function lerp(a, b, t) {
194
+ const pa = parseHex(a);
195
+ const pb = parseHex(b);
196
+ if (!pa || !pb)
197
+ return a;
198
+ const k = Math.min(1, Math.max(0, t));
199
+ const ch = (i) => Math.round(pa[i] + (pb[i] - pa[i]) * k).toString(16).padStart(2, '0');
200
+ return `#${ch(0)}${ch(1)}${ch(2)}`;
201
+ }
202
+ function parseHex(hex) {
203
+ const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim());
204
+ if (!m)
205
+ return null;
206
+ const n = parseInt(m[1], 16);
207
+ return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
208
+ }
209
+ /** The colour a scale gives a position 0..1. */
210
+ export function scaleColor(colors, t) {
211
+ if (colors.length === 2)
212
+ return lerp(colors[0], colors[1], t);
213
+ return t <= 0.5 ? lerp(colors[0], colors[1], t * 2) : lerp(colors[1], colors[2], (t - 0.5) * 2);
214
+ }
215
+ /** Which of an icon set's three icons a position 0..1 gets: Excel's thirds. */
216
+ export function iconIndex(t) {
217
+ return t >= 2 / 3 ? 0 : t >= 1 / 3 ? 1 : 2;
218
+ }
219
+ /**
220
+ * What the rules say about (r, c). Array order is priority; the first rule
221
+ * that decides a property (the fill, the text colour, the bar, the icon)
222
+ * keeps it; a matching rule with Stop If True ends the walk.
223
+ */
224
+ export function evaluateCf(rules, r, c, value, display, statsFor, ctx) {
225
+ let out = null;
226
+ for (const rule of rules) {
227
+ if (!rule.rects.some((rect) => rectContains(rect, r, c)))
228
+ continue;
229
+ let hit = false;
230
+ if (rule.kind === 'dataBar') {
231
+ if (typeof value === 'number' && !(out?.dataBar)) {
232
+ const stats = statsFor(rule);
233
+ out = { ...(out ?? {}), dataBar: { ratio: barRatio(value, stats), color: rule.color } };
234
+ hit = true;
235
+ }
236
+ }
237
+ else if (rule.kind === 'colorScale') {
238
+ const current = out ?? {};
239
+ if (typeof value === 'number' && current.style?.fill === undefined) {
240
+ const stats = statsFor(rule);
241
+ out = { ...current, style: { ...(current.style ?? {}), fill: scaleColor(rule.colors, ratioOf(value, stats)) } };
242
+ hit = true;
243
+ }
244
+ }
245
+ else if (rule.kind === 'iconSet') {
246
+ if (typeof value === 'number' && !(out?.icon)) {
247
+ const stats = statsFor(rule);
248
+ out = { ...(out ?? {}), icon: { set: rule.set, index: iconIndex(ratioOf(value, stats)) } };
249
+ hit = true;
250
+ }
251
+ }
252
+ else if (hasStyle(rule) && matches(rule, value, display, statsFor(rule), ctx)) {
253
+ const style = { ...(out?.style ?? {}) };
254
+ const own = rule.style;
255
+ for (const key of Object.keys(own)) {
256
+ if (style[key] === undefined && own[key] !== undefined)
257
+ style[key] = own[key];
258
+ }
259
+ out = { ...(out ?? {}), style };
260
+ hit = true;
261
+ }
262
+ if (hit && rule.stopIfTrue)
263
+ break;
264
+ }
265
+ return out;
266
+ }
267
+ // ---------------------------------------------------------------------------
268
+ // Bookkeeping
269
+ // ---------------------------------------------------------------------------
270
+ /** The rules after an insert or delete. */
271
+ export function shiftCf(rules, edit) {
272
+ return shiftRects(rules, edit);
273
+ }
274
+ /** The rules with the rectangles cut out of them: Clear Rules from Selected Cells. */
275
+ export function removeCf(rules, rects) {
276
+ const out = [];
277
+ for (const rule of rules) {
278
+ let kept = [...rule.rects];
279
+ for (const hole of rects)
280
+ kept = kept.flatMap((rect) => subtractRect(rect, hole));
281
+ if (kept.length)
282
+ out.push({ ...rule, rects: kept });
283
+ }
284
+ return out;
285
+ }
286
+ /** The rules touching any of the rectangles. */
287
+ export function cfIn(rules, rects) {
288
+ return rules.filter((rule) => rule.rects.some((a) => rects.some((b) => rectsIntersect(a, b))));
289
+ }
290
+ const OPERATOR_WORDS = {
291
+ greater: 'greater than', less: 'less than', between: 'between', notBetween: 'not between',
292
+ equal: 'equal to', notEqual: 'not equal to', greaterOrEqual: 'greater than or equal to', lessOrEqual: 'less than or equal to',
293
+ };
294
+ const MATCH_WORDS = {
295
+ contains: 'contains', notContains: 'does not contain', beginsWith: 'begins with', endsWith: 'ends with',
296
+ };
297
+ /** A rule in words, the way Excel's Manage Rules lists it. */
298
+ export function describeCf(rule) {
299
+ switch (rule.kind) {
300
+ case 'cellIs':
301
+ return rule.operator === 'between' || rule.operator === 'notBetween'
302
+ ? `Cell Value ${OPERATOR_WORDS[rule.operator]} ${rule.value1} and ${rule.value2 ?? ''}`
303
+ : `Cell Value ${OPERATOR_WORDS[rule.operator]} ${rule.value1}`;
304
+ case 'text': return `Cell Value ${MATCH_WORDS[rule.match]} '${rule.value}'`;
305
+ case 'duplicates': return rule.unique ? 'Unique Values' : 'Duplicate Values';
306
+ case 'topBottom': return `${rule.top ? 'Top' : 'Bottom'} ${rule.rank}${rule.percent ? '%' : ''}`;
307
+ case 'average': return rule.above ? 'Above Average' : 'Below Average';
308
+ case 'dataBar': return 'Data Bar';
309
+ case 'colorScale': return rule.colors.length === 3 ? 'Graded Color Scale' : 'Two-Color Scale';
310
+ case 'iconSet': return 'Icon Set';
311
+ }
312
+ }
313
+ /** Whether a rule carries a style the dialog can edit. */
314
+ export function hasStyle(rule) {
315
+ return 'style' in rule;
316
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Dependency graph, so a recalc costs what the edit actually affects.
3
+ *
4
+ * The demo engines call `computeSheet`, which resolves every cell on every
5
+ * keystroke. On a small budget sheet nobody notices; on demo 211's 360-row
6
+ * amortisation schedule, typing one digit in an input cell walks every cell in
7
+ * the sheet and re-parses every formula among them.
8
+ *
9
+ * This tracks which cells each formula reads, inverts that into "who reads
10
+ * me", and walks forward from an edit in topological order.
11
+ *
12
+ * Cycles are reported rather than thrown. A cycle is a normal thing to type on
13
+ * the way to something correct, and every cell in one shows #CYCLE! while the
14
+ * rest of the sheet keeps working.
15
+ */
16
+ import { type Node } from './ast.js';
17
+ export type CellKey = string;
18
+ /**
19
+ * Cells are keyed "row col sheet", in that order deliberately.
20
+ *
21
+ * Row and column are numbers and contain no separator, so the first two fields
22
+ * are unambiguous and EVERYTHING after the second space is the sheet name.
23
+ * Putting the sheet first would let a name like `Price list` collide with a
24
+ * different cell, and a ':' or '!' separator has the same problem the moment
25
+ * someone names a sheet after a range.
26
+ */
27
+ export declare function cellKey(sheet: string | null, row: number, col: number): CellKey;
28
+ export declare function parseCellKey(key: CellKey): {
29
+ sheet: string | null;
30
+ row: number;
31
+ col: number;
32
+ };
33
+ /**
34
+ * Every cell a formula reads. A range contributes each cell inside it, which
35
+ * is why `lastRow` is needed: a whole-column reference has no upper bound of
36
+ * its own.
37
+ */
38
+ export declare function precedentsOf(ast: Node, self: {
39
+ sheet: string | null;
40
+ }, lastRow: (sheet: string | null) => number,
41
+ /**
42
+ * The reference behind a defined name. Without it a formula that reads
43
+ * `=Subtotal*Tax` records no precedents at all, so editing the cell behind
44
+ * `Tax` leaves the formula showing its old value until something else
45
+ * forces a recalculation.
46
+ */
47
+ resolveName?: (name: string) => Node | null, depth?: number): CellKey[];
48
+ export type DependencyGraph = {
49
+ /** Record (or clear, with null) what one cell reads. */
50
+ setPrecedents(cell: CellKey, precedents: ReadonlyArray<CellKey> | null): void;
51
+ /** Cells that must recompute after `changed`, ordered so every cell comes
52
+ * after everything it reads. Excludes the changed cells themselves. */
53
+ dirtyFrom(changed: ReadonlyArray<CellKey>): CellKey[];
54
+ /** Every cell taking part in a dependency cycle. */
55
+ cycles(): CellKey[];
56
+ /** Direct readers of a cell. */
57
+ dependentsOf(cell: CellKey): CellKey[];
58
+ clear(): void;
59
+ };
60
+ export declare function createDependencyGraph(): DependencyGraph;