@k2b/ui 0.4.2 → 0.5.1

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 (383) hide show
  1. package/dist/browser/actions/Button.js.map +1 -1
  2. package/dist/browser/actions/ContextMenu.js.map +1 -1
  3. package/dist/browser/actions/CopyButton.js.map +1 -1
  4. package/dist/browser/actions/Disclosure.js.map +1 -1
  5. package/dist/browser/actions/Dropdown.js.map +1 -1
  6. package/dist/browser/actions/FilterChip.js.map +1 -1
  7. package/dist/browser/actions/RemoveButton.js.map +1 -1
  8. package/dist/browser/actions/SegmentedControl.js.map +1 -1
  9. package/dist/browser/actions/SplitButton.js.map +1 -1
  10. package/dist/browser/actions/SpotlightSearch.js.map +1 -1
  11. package/dist/browser/actions/Tabs.js.map +1 -1
  12. package/dist/browser/actions/Toolbar.js.map +1 -1
  13. package/dist/browser/actions/index.js.map +1 -1
  14. package/dist/browser/chat/ChatComposer.js.map +1 -1
  15. package/dist/browser/chat/ChatContextPopup.js.map +1 -1
  16. package/dist/browser/chat/ChatPrimitives.js.map +1 -1
  17. package/dist/browser/chat/ChatRoot.js.map +1 -1
  18. package/dist/browser/chat/ChatTasks.js +1 -1
  19. package/dist/browser/chat/ChatTasks.js.map +1 -1
  20. package/dist/browser/chat/ChatTimeline.js.map +1 -1
  21. package/dist/browser/chat/chat-behavior.js.map +1 -1
  22. package/dist/browser/chat/composer-document.js.map +1 -1
  23. package/dist/browser/chat/index.js.map +1 -1
  24. package/dist/browser/content/Calendar.js.map +1 -1
  25. package/dist/browser/content/Chart.js.map +1 -1
  26. package/dist/browser/content/ChartExplorer.js.map +1 -1
  27. package/dist/browser/content/ChartExplorerControls.js.map +1 -1
  28. package/dist/browser/content/ChartFilterControls.js +1 -1
  29. package/dist/browser/content/ChartFilterControls.js.map +1 -1
  30. package/dist/browser/content/ChartSnapshotView.js.map +1 -1
  31. package/dist/browser/content/CodeDisplay.js.map +1 -1
  32. package/dist/browser/content/DataTable.js.map +1 -1
  33. package/dist/browser/content/Docs.js.map +1 -1
  34. package/dist/browser/content/FileBrowser.js.map +1 -1
  35. package/dist/browser/content/FileGrid.js.map +1 -1
  36. package/dist/browser/content/FileTree.js.map +1 -1
  37. package/dist/browser/content/FileView.js.map +1 -1
  38. package/dist/browser/content/Lightbox.js.map +1 -1
  39. package/dist/browser/content/LogEntriesTable.js.map +1 -1
  40. package/dist/browser/content/MarkdownView.js.map +1 -1
  41. package/dist/browser/content/Pagination.js.map +1 -1
  42. package/dist/browser/content/PdfPreview.js.map +1 -1
  43. package/dist/browser/content/RangePicker.js.map +1 -1
  44. package/dist/browser/content/StructuredDataPreview.js.map +1 -1
  45. package/dist/browser/content/calendar-event-layout.js.map +1 -1
  46. package/dist/browser/content/calendar-pointer.js.map +1 -1
  47. package/dist/browser/content/chart-cursor.js.map +1 -1
  48. package/dist/browser/content/chart-explorer.js.map +1 -1
  49. package/dist/browser/content/chart-inspection.js.map +1 -1
  50. package/dist/browser/content/chart-line-gaps.js.map +1 -1
  51. package/dist/browser/content/chart-map-viewport.js.map +1 -1
  52. package/dist/browser/content/chart-snapshot.js.map +1 -1
  53. package/dist/browser/content/chart-state-timeline.js.map +1 -1
  54. package/dist/browser/content/chart-svg.js.map +1 -1
  55. package/dist/browser/content/code-highlight.js.map +1 -1
  56. package/dist/browser/content/collection-selection.js.map +1 -1
  57. package/dist/browser/content/delimited-preferences.js.map +1 -1
  58. package/dist/browser/content/file-tree.js.map +1 -1
  59. package/dist/browser/content/file-view-preview.js.map +1 -1
  60. package/dist/browser/content/index.js.map +1 -1
  61. package/dist/browser/feedback/InlineGuidance.js.map +1 -1
  62. package/dist/browser/feedback/Tooltip.js.map +1 -1
  63. package/dist/browser/feedback/dialog-core.js.map +1 -1
  64. package/dist/browser/feedback/index.js.map +1 -1
  65. package/dist/browser/feedback/prompts.js.map +1 -1
  66. package/dist/browser/feedback/toast.js.map +1 -1
  67. package/dist/browser/feedback/tooltip-position.js.map +1 -1
  68. package/dist/browser/inputs/AutocompleteEditor.js.map +1 -1
  69. package/dist/browser/inputs/AutocompleteSelect.js.map +1 -1
  70. package/dist/browser/inputs/Checkbox.js.map +1 -1
  71. package/dist/browser/inputs/CheckboxCard.js.map +1 -1
  72. package/dist/browser/inputs/ChoiceGroups.js.map +1 -1
  73. package/dist/browser/inputs/ChoiceInputs.js.map +1 -1
  74. package/dist/browser/inputs/Combobox.js.map +1 -1
  75. package/dist/browser/inputs/DatePicker.js.map +1 -1
  76. package/dist/browser/inputs/FileInputs.js.map +1 -1
  77. package/dist/browser/inputs/MultiSelectInput.js.map +1 -1
  78. package/dist/browser/inputs/NumberInput.js.map +1 -1
  79. package/dist/browser/inputs/Select.js.map +1 -1
  80. package/dist/browser/inputs/SelectChip.js.map +1 -1
  81. package/dist/browser/inputs/SpecialInputs.js.map +1 -1
  82. package/dist/browser/inputs/Switch.js.map +1 -1
  83. package/dist/browser/inputs/TagEditor.js.map +1 -1
  84. package/dist/browser/inputs/TagsInput.js.map +1 -1
  85. package/dist/browser/inputs/TemplateEditor.js.map +1 -1
  86. package/dist/browser/inputs/TextInput.js.map +1 -1
  87. package/dist/browser/inputs/choice.js.map +1 -1
  88. package/dist/browser/inputs/completion/behaviors.js.map +1 -1
  89. package/dist/browser/inputs/completion/engine.js.map +1 -1
  90. package/dist/browser/inputs/completion/index.js.map +1 -1
  91. package/dist/browser/inputs/completion/overlay.js.map +1 -1
  92. package/dist/browser/inputs/date-picker.js.map +1 -1
  93. package/dist/browser/inputs/editor-dom.js.map +1 -1
  94. package/dist/browser/inputs/field-contract.js.map +1 -1
  95. package/dist/browser/inputs/icon-options.js.map +1 -1
  96. package/dist/browser/inputs/image-crop.js.map +1 -1
  97. package/dist/browser/inputs/index.js.map +1 -1
  98. package/dist/browser/inputs/markdown/MarkdownEditor.js.map +1 -1
  99. package/dist/browser/inputs/markdown/Toolbar.js.map +1 -1
  100. package/dist/browser/inputs/markdown/actions.js.map +1 -1
  101. package/dist/browser/inputs/markdown/active-formats.js.map +1 -1
  102. package/dist/browser/inputs/markdown/behaviors.js.map +1 -1
  103. package/dist/browser/inputs/markdown/code-zone.js.map +1 -1
  104. package/dist/browser/internal/color.js.map +1 -1
  105. package/dist/browser/internal/field.js.map +1 -1
  106. package/dist/browser/internal/portal.js.map +1 -1
  107. package/dist/browser/intl/Format.js.map +1 -1
  108. package/dist/browser/intl/index.js.map +1 -1
  109. package/dist/browser/intl/locale.js.map +1 -1
  110. package/dist/browser/intl/messages.js +2 -0
  111. package/dist/browser/intl/messages.js.map +1 -1
  112. package/dist/browser/layout/AppOverview.js +29 -20
  113. package/dist/browser/layout/AppOverview.js.map +1 -1
  114. package/dist/browser/layout/AppWorkspace.js +60 -54
  115. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  116. package/dist/browser/layout/BottomSheet.js.map +1 -1
  117. package/dist/browser/layout/DataPanel.js.map +1 -1
  118. package/dist/browser/layout/DetailPanel.js.map +1 -1
  119. package/dist/browser/layout/Discussion.js.map +1 -1
  120. package/dist/browser/layout/FloatingWindow.js.map +1 -1
  121. package/dist/browser/layout/Navigation.js.map +1 -1
  122. package/dist/browser/layout/PanelDialog.js.map +1 -1
  123. package/dist/browser/layout/PanelHeader.js +1 -1
  124. package/dist/browser/layout/PanelHeader.js.map +1 -1
  125. package/dist/browser/layout/Panes.js.map +1 -1
  126. package/dist/browser/layout/PullToRefresh.js +217 -0
  127. package/dist/browser/layout/PullToRefresh.js.map +1 -0
  128. package/dist/browser/layout/ScrollArea.js.map +1 -1
  129. package/dist/browser/layout/Settings.js.map +1 -1
  130. package/dist/browser/layout/SettingsCollection.js.map +1 -1
  131. package/dist/browser/layout/SettingsModal.js.map +1 -1
  132. package/dist/browser/layout/SidebarItemPreview.js.map +1 -1
  133. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  134. package/dist/browser/layout/app-workspace-state.js.map +1 -1
  135. package/dist/browser/layout/floating-window-geometry.js.map +1 -1
  136. package/dist/browser/layout/index.js +1 -0
  137. package/dist/browser/layout/index.js.map +1 -1
  138. package/dist/browser/layout/navigation-model.js.map +1 -1
  139. package/dist/browser/layout/panes-layout.js.map +1 -1
  140. package/dist/browser/layout/scroll-fade.js.map +1 -1
  141. package/dist/browser/layout/stable-id.js.map +1 -1
  142. package/dist/browser/surfaces/Avatar.js.map +1 -1
  143. package/dist/browser/surfaces/DescriptionList.js.map +1 -1
  144. package/dist/browser/surfaces/LinkCard.js +13 -2
  145. package/dist/browser/surfaces/LinkCard.js.map +1 -1
  146. package/dist/browser/surfaces/NotFoundState.js.map +1 -1
  147. package/dist/browser/surfaces/NoticeCard.js.map +1 -1
  148. package/dist/browser/surfaces/Paper.js.map +1 -1
  149. package/dist/browser/surfaces/Placeholder.js.map +1 -1
  150. package/dist/browser/surfaces/ProgressBar.js.map +1 -1
  151. package/dist/browser/surfaces/StatCell.js.map +1 -1
  152. package/dist/browser/surfaces/StatGrid.js.map +1 -1
  153. package/dist/browser/surfaces/StatusBadge.js.map +1 -1
  154. package/dist/browser/surfaces/Tag.js.map +1 -1
  155. package/dist/browser/surfaces/index.js.map +1 -1
  156. package/dist/browser/widgets/Widget.js.map +1 -1
  157. package/dist/browser/widgets/WidgetHero.js.map +1 -1
  158. package/dist/browser/widgets/WidgetList.js.map +1 -1
  159. package/dist/browser/widgets/WidgetPills.js.map +1 -1
  160. package/dist/browser/widgets/WidgetStat.js.map +1 -1
  161. package/dist/browser/widgets/WidgetStatus.js.map +1 -1
  162. package/dist/ssr/actions/Button.js +5 -4
  163. package/dist/ssr/actions/Button.js.map +1 -1
  164. package/dist/ssr/actions/ContextMenu.js.map +1 -1
  165. package/dist/ssr/actions/CopyButton.js +2 -1
  166. package/dist/ssr/actions/CopyButton.js.map +1 -1
  167. package/dist/ssr/actions/Disclosure.js.map +1 -1
  168. package/dist/ssr/actions/Dropdown.js +7 -6
  169. package/dist/ssr/actions/Dropdown.js.map +1 -1
  170. package/dist/ssr/actions/FilterChip.js +5 -4
  171. package/dist/ssr/actions/FilterChip.js.map +1 -1
  172. package/dist/ssr/actions/RemoveButton.js +1 -0
  173. package/dist/ssr/actions/RemoveButton.js.map +1 -1
  174. package/dist/ssr/actions/SegmentedControl.js.map +1 -1
  175. package/dist/ssr/actions/SplitButton.js +1 -0
  176. package/dist/ssr/actions/SplitButton.js.map +1 -1
  177. package/dist/ssr/actions/SpotlightSearch.js.map +1 -1
  178. package/dist/ssr/actions/Tabs.js.map +1 -1
  179. package/dist/ssr/actions/Toolbar.js.map +1 -1
  180. package/dist/ssr/actions/index.js.map +1 -1
  181. package/dist/ssr/chat/ChatComposer.js +6 -5
  182. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  183. package/dist/ssr/chat/ChatContextPopup.js.map +1 -1
  184. package/dist/ssr/chat/ChatPrimitives.js +6 -5
  185. package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
  186. package/dist/ssr/chat/ChatRoot.js.map +1 -1
  187. package/dist/ssr/chat/ChatTasks.js +1 -1
  188. package/dist/ssr/chat/ChatTasks.js.map +1 -1
  189. package/dist/ssr/chat/ChatTimeline.js +5 -4
  190. package/dist/ssr/chat/ChatTimeline.js.map +1 -1
  191. package/dist/ssr/chat/chat-behavior.js.map +1 -1
  192. package/dist/ssr/chat/composer-document.js.map +1 -1
  193. package/dist/ssr/chat/index.js.map +1 -1
  194. package/dist/ssr/content/Calendar.js +2 -1
  195. package/dist/ssr/content/Calendar.js.map +1 -1
  196. package/dist/ssr/content/Chart.js.map +1 -1
  197. package/dist/ssr/content/ChartExplorer.js.map +1 -1
  198. package/dist/ssr/content/ChartExplorerControls.js +5 -4
  199. package/dist/ssr/content/ChartExplorerControls.js.map +1 -1
  200. package/dist/ssr/content/ChartFilterControls.js +3 -2
  201. package/dist/ssr/content/ChartFilterControls.js.map +1 -1
  202. package/dist/ssr/content/ChartSnapshotView.js.map +1 -1
  203. package/dist/ssr/content/CodeDisplay.js.map +1 -1
  204. package/dist/ssr/content/DataTable.js +1 -0
  205. package/dist/ssr/content/DataTable.js.map +1 -1
  206. package/dist/ssr/content/Docs.js +1 -0
  207. package/dist/ssr/content/Docs.js.map +1 -1
  208. package/dist/ssr/content/FileBrowser.js +2 -1
  209. package/dist/ssr/content/FileBrowser.js.map +1 -1
  210. package/dist/ssr/content/FileGrid.js.map +1 -1
  211. package/dist/ssr/content/FileTree.js +2 -1
  212. package/dist/ssr/content/FileTree.js.map +1 -1
  213. package/dist/ssr/content/FileView.js +5 -4
  214. package/dist/ssr/content/FileView.js.map +1 -1
  215. package/dist/ssr/content/Lightbox.js +2 -1
  216. package/dist/ssr/content/Lightbox.js.map +1 -1
  217. package/dist/ssr/content/LogEntriesTable.js.map +1 -1
  218. package/dist/ssr/content/MarkdownView.js.map +1 -1
  219. package/dist/ssr/content/Pagination.js +2 -1
  220. package/dist/ssr/content/Pagination.js.map +1 -1
  221. package/dist/ssr/content/PdfPreview.js.map +1 -1
  222. package/dist/ssr/content/RangePicker.js.map +1 -1
  223. package/dist/ssr/content/StructuredDataPreview.js.map +1 -1
  224. package/dist/ssr/content/calendar-event-layout.js.map +1 -1
  225. package/dist/ssr/content/calendar-pointer.js.map +1 -1
  226. package/dist/ssr/content/chart-cursor.js.map +1 -1
  227. package/dist/ssr/content/chart-explorer.js.map +1 -1
  228. package/dist/ssr/content/chart-inspection.js.map +1 -1
  229. package/dist/ssr/content/chart-line-gaps.js.map +1 -1
  230. package/dist/ssr/content/chart-map-viewport.js.map +1 -1
  231. package/dist/ssr/content/chart-snapshot.js.map +1 -1
  232. package/dist/ssr/content/chart-state-timeline.js.map +1 -1
  233. package/dist/ssr/content/chart-svg.js.map +1 -1
  234. package/dist/ssr/content/code-highlight.js.map +1 -1
  235. package/dist/ssr/content/collection-selection.js.map +1 -1
  236. package/dist/ssr/content/delimited-preferences.js.map +1 -1
  237. package/dist/ssr/content/file-tree.js.map +1 -1
  238. package/dist/ssr/content/file-view-preview.js.map +1 -1
  239. package/dist/ssr/content/index.js.map +1 -1
  240. package/dist/ssr/feedback/InlineGuidance.js.map +1 -1
  241. package/dist/ssr/feedback/Tooltip.js.map +1 -1
  242. package/dist/ssr/feedback/dialog-core.js.map +1 -1
  243. package/dist/ssr/feedback/index.js.map +1 -1
  244. package/dist/ssr/feedback/prompts.js +3 -2
  245. package/dist/ssr/feedback/prompts.js.map +1 -1
  246. package/dist/ssr/feedback/toast.js.map +1 -1
  247. package/dist/ssr/feedback/tooltip-position.js.map +1 -1
  248. package/dist/ssr/inputs/AutocompleteEditor.js +3 -2
  249. package/dist/ssr/inputs/AutocompleteEditor.js.map +1 -1
  250. package/dist/ssr/inputs/AutocompleteSelect.js +5 -4
  251. package/dist/ssr/inputs/AutocompleteSelect.js.map +1 -1
  252. package/dist/ssr/inputs/Checkbox.js +1 -0
  253. package/dist/ssr/inputs/Checkbox.js.map +1 -1
  254. package/dist/ssr/inputs/CheckboxCard.js.map +1 -1
  255. package/dist/ssr/inputs/ChoiceGroups.js.map +1 -1
  256. package/dist/ssr/inputs/ChoiceInputs.js +1 -0
  257. package/dist/ssr/inputs/ChoiceInputs.js.map +1 -1
  258. package/dist/ssr/inputs/Combobox.js +2 -1
  259. package/dist/ssr/inputs/Combobox.js.map +1 -1
  260. package/dist/ssr/inputs/DatePicker.js +4 -3
  261. package/dist/ssr/inputs/DatePicker.js.map +1 -1
  262. package/dist/ssr/inputs/FileInputs.js +2 -1
  263. package/dist/ssr/inputs/FileInputs.js.map +1 -1
  264. package/dist/ssr/inputs/MultiSelectInput.js +4 -3
  265. package/dist/ssr/inputs/MultiSelectInput.js.map +1 -1
  266. package/dist/ssr/inputs/NumberInput.js +2 -1
  267. package/dist/ssr/inputs/NumberInput.js.map +1 -1
  268. package/dist/ssr/inputs/Select.js +4 -3
  269. package/dist/ssr/inputs/Select.js.map +1 -1
  270. package/dist/ssr/inputs/SelectChip.js +3 -2
  271. package/dist/ssr/inputs/SelectChip.js.map +1 -1
  272. package/dist/ssr/inputs/SpecialInputs.js +1 -0
  273. package/dist/ssr/inputs/SpecialInputs.js.map +1 -1
  274. package/dist/ssr/inputs/Switch.js.map +1 -1
  275. package/dist/ssr/inputs/TagEditor.js +3 -2
  276. package/dist/ssr/inputs/TagEditor.js.map +1 -1
  277. package/dist/ssr/inputs/TagsInput.js.map +1 -1
  278. package/dist/ssr/inputs/TemplateEditor.js +1 -0
  279. package/dist/ssr/inputs/TemplateEditor.js.map +1 -1
  280. package/dist/ssr/inputs/TextInput.js +4 -3
  281. package/dist/ssr/inputs/TextInput.js.map +1 -1
  282. package/dist/ssr/inputs/choice.js.map +1 -1
  283. package/dist/ssr/inputs/completion/behaviors.js.map +1 -1
  284. package/dist/ssr/inputs/completion/engine.js.map +1 -1
  285. package/dist/ssr/inputs/completion/index.js.map +1 -1
  286. package/dist/ssr/inputs/completion/overlay.js.map +1 -1
  287. package/dist/ssr/inputs/date-picker.js.map +1 -1
  288. package/dist/ssr/inputs/editor-dom.js.map +1 -1
  289. package/dist/ssr/inputs/field-contract.js.map +1 -1
  290. package/dist/ssr/inputs/icon-options.js.map +1 -1
  291. package/dist/ssr/inputs/image-crop.js.map +1 -1
  292. package/dist/ssr/inputs/index.js.map +1 -1
  293. package/dist/ssr/inputs/markdown/MarkdownEditor.js +3 -2
  294. package/dist/ssr/inputs/markdown/MarkdownEditor.js.map +1 -1
  295. package/dist/ssr/inputs/markdown/Toolbar.js.map +1 -1
  296. package/dist/ssr/inputs/markdown/actions.js.map +1 -1
  297. package/dist/ssr/inputs/markdown/active-formats.js.map +1 -1
  298. package/dist/ssr/inputs/markdown/behaviors.js.map +1 -1
  299. package/dist/ssr/inputs/markdown/code-zone.js.map +1 -1
  300. package/dist/ssr/internal/color.js.map +1 -1
  301. package/dist/ssr/internal/field.js.map +1 -1
  302. package/dist/ssr/internal/portal.js.map +1 -1
  303. package/dist/ssr/intl/Format.js.map +1 -1
  304. package/dist/ssr/intl/index.js.map +1 -1
  305. package/dist/ssr/intl/locale.js.map +1 -1
  306. package/dist/ssr/intl/messages.js +2 -0
  307. package/dist/ssr/intl/messages.js.map +1 -1
  308. package/dist/ssr/layout/AppOverview.js +16 -6
  309. package/dist/ssr/layout/AppOverview.js.map +1 -1
  310. package/dist/ssr/layout/AppWorkspace.js +12 -8
  311. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  312. package/dist/ssr/layout/BottomSheet.js.map +1 -1
  313. package/dist/ssr/layout/DataPanel.js +1 -0
  314. package/dist/ssr/layout/DataPanel.js.map +1 -1
  315. package/dist/ssr/layout/DetailPanel.js +1 -0
  316. package/dist/ssr/layout/DetailPanel.js.map +1 -1
  317. package/dist/ssr/layout/Discussion.js +3 -2
  318. package/dist/ssr/layout/Discussion.js.map +1 -1
  319. package/dist/ssr/layout/FloatingWindow.js +1 -0
  320. package/dist/ssr/layout/FloatingWindow.js.map +1 -1
  321. package/dist/ssr/layout/Navigation.js +3 -2
  322. package/dist/ssr/layout/Navigation.js.map +1 -1
  323. package/dist/ssr/layout/PanelDialog.js +1 -0
  324. package/dist/ssr/layout/PanelDialog.js.map +1 -1
  325. package/dist/ssr/layout/PanelHeader.js +1 -1
  326. package/dist/ssr/layout/PanelHeader.js.map +1 -1
  327. package/dist/ssr/layout/Panes.js.map +1 -1
  328. package/dist/ssr/layout/PullToRefresh.js +177 -0
  329. package/dist/ssr/layout/PullToRefresh.js.map +1 -0
  330. package/dist/ssr/layout/ScrollArea.js.map +1 -1
  331. package/dist/ssr/layout/Settings.js +2 -1
  332. package/dist/ssr/layout/Settings.js.map +1 -1
  333. package/dist/ssr/layout/SettingsCollection.js +1 -0
  334. package/dist/ssr/layout/SettingsCollection.js.map +1 -1
  335. package/dist/ssr/layout/SettingsModal.js.map +1 -1
  336. package/dist/ssr/layout/SidebarItemPreview.js.map +1 -1
  337. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  338. package/dist/ssr/layout/app-workspace-state.js.map +1 -1
  339. package/dist/ssr/layout/floating-window-geometry.js.map +1 -1
  340. package/dist/ssr/layout/index.js +1 -0
  341. package/dist/ssr/layout/index.js.map +1 -1
  342. package/dist/ssr/layout/navigation-model.js.map +1 -1
  343. package/dist/ssr/layout/panes-layout.js.map +1 -1
  344. package/dist/ssr/layout/scroll-fade.js.map +1 -1
  345. package/dist/ssr/layout/stable-id.js.map +1 -1
  346. package/dist/ssr/surfaces/Avatar.js +2 -1
  347. package/dist/ssr/surfaces/Avatar.js.map +1 -1
  348. package/dist/ssr/surfaces/DescriptionList.js.map +1 -1
  349. package/dist/ssr/surfaces/LinkCard.js +11 -2
  350. package/dist/ssr/surfaces/LinkCard.js.map +1 -1
  351. package/dist/ssr/surfaces/NotFoundState.js.map +1 -1
  352. package/dist/ssr/surfaces/NoticeCard.js.map +1 -1
  353. package/dist/ssr/surfaces/Paper.js +2 -1
  354. package/dist/ssr/surfaces/Paper.js.map +1 -1
  355. package/dist/ssr/surfaces/Placeholder.js +2 -1
  356. package/dist/ssr/surfaces/Placeholder.js.map +1 -1
  357. package/dist/ssr/surfaces/ProgressBar.js.map +1 -1
  358. package/dist/ssr/surfaces/StatCell.js +2 -1
  359. package/dist/ssr/surfaces/StatCell.js.map +1 -1
  360. package/dist/ssr/surfaces/StatGrid.js +1 -0
  361. package/dist/ssr/surfaces/StatGrid.js.map +1 -1
  362. package/dist/ssr/surfaces/StatusBadge.js.map +1 -1
  363. package/dist/ssr/surfaces/Tag.js.map +1 -1
  364. package/dist/ssr/surfaces/index.js.map +1 -1
  365. package/dist/ssr/widgets/Widget.js +1 -0
  366. package/dist/ssr/widgets/Widget.js.map +1 -1
  367. package/dist/ssr/widgets/WidgetHero.js.map +1 -1
  368. package/dist/ssr/widgets/WidgetList.js.map +1 -1
  369. package/dist/ssr/widgets/WidgetPills.js.map +1 -1
  370. package/dist/ssr/widgets/WidgetStat.js +1 -0
  371. package/dist/ssr/widgets/WidgetStat.js.map +1 -1
  372. package/dist/ssr/widgets/WidgetStatus.js.map +1 -1
  373. package/dist/styles.css +1 -1
  374. package/dist/types/actions/SpotlightSearch.d.ts +1 -1
  375. package/dist/types/feedback/prompts.d.ts +2 -2
  376. package/dist/types/intl/messages.d.ts +1 -0
  377. package/dist/types/layout/AppOverview.d.ts +7 -0
  378. package/dist/types/layout/AppWorkspace.d.ts +14 -2
  379. package/dist/types/layout/PanelHeader.d.ts +1 -1
  380. package/dist/types/layout/PullToRefresh.d.ts +21 -0
  381. package/dist/types/layout/index.d.ts +3 -1
  382. package/dist/types/surfaces/LinkCard.d.ts +5 -2
  383. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"names":["dates","Show","useUiMessages","Placeholder","DataTable","levelIcon","debug","icon","level","label","info","warn","error","LogEntriesTable","props","messages","columns","id","header","value","entry","entries","length","source","message","createdAt","cellClass","_$createComponent","when","fallback","surface","description","emptyMessage","noLogEntries","children","rows","getRowId","String","hoverRows","renderCell","row","col","_$ssr","_tmpl$","_$ssrAttribute","_$escape","_tmpl$2","_tmpl$3","_tmpl$4","formatDateTime"],"sources":["content/LogEntriesTable.tsx"],"sourcesContent":["import { dates } from \"@k2b/stdlib\";\nimport { Show } from \"solid-js\";\nimport { useUiMessages } from \"../intl/messages\";\nimport Placeholder from \"../surfaces/Placeholder\";\nimport DataTable, { type DataTableColumn } from \"./DataTable\";\n\nexport type LogTableEntry = {\n id: number | string;\n level: string;\n source: string;\n message: string;\n metadata: Record<string, unknown> | null;\n createdAt: string;\n};\n\ntype Props = {\n entries: readonly LogTableEntry[];\n emptyMessage?: string;\n};\n\n/**\n * Cloud paints each level with a hardcoded Tailwind palette pair\n * (`text-amber-500 dark:text-amber-400`, …). The package keeps the same\n * per-level distinction but routes it through `data-level` so the semantic\n * `--k2b-*` tokens stay the single theming contract in both schemes.\n */\nconst levelIcon: Record<string, { icon: string; level: string; label: string }> = {\n debug: { icon: \"ti ti-bug\", level: \"debug\", label: \"debug\" },\n info: { icon: \"ti ti-info-circle\", level: \"info\", label: \"info\" },\n warn: { icon: \"ti ti-alert-triangle\", level: \"warn\", label: \"warn\" },\n error: { icon: \"ti ti-alert-circle\", level: \"error\", label: \"error\" },\n};\n\nexport default function LogEntriesTable(props: Props) {\n const messages = useUiMessages();\n const columns = (): DataTableColumn<LogTableEntry>[] => [\n { id: \"level\", header: \"Level\", value: (entry) => entry.level },\n { id: \"source\", header: `Source (${props.entries.length})`, value: (entry) => entry.source },\n { id: \"message\", header: \"Message\", value: (entry) => entry.message },\n { id: \"time\", header: \"Time\", value: (entry) => entry.createdAt, cellClass: \"k2b-log-table__time-cell\" },\n ];\n\n return (\n <Show\n when={props.entries.length > 0}\n fallback={<Placeholder surface=\"paper\" description={<>{props.emptyMessage ?? messages().noLogEntries}</>} />}\n >\n <DataTable\n rows={props.entries}\n columns={columns()}\n getRowId={(entry) => String(entry.id)}\n hoverRows\n class=\"k2b-log-table\"\n renderCell={({ row, col }) => {\n if (col.id === \"level\") {\n const level = levelIcon[row.level] ?? { icon: \"ti ti-circle\", level: \"neutral\", label: row.level || \"unknown\" };\n return (\n <span class=\"k2b-log-level\" data-level={level.level}>\n <i class={`k2b-log-level__icon ${level.icon}`} aria-hidden=\"true\" />\n <span>{level.label}</span>\n </span>\n );\n }\n if (col.id === \"source\") return <span class=\"k2b-log-table__source\">{row.source}</span>;\n if (col.id === \"message\") return <span title={row.message}>{row.message}</span>;\n if (col.id === \"time\") return <span class=\"k2b-log-table__time\">{dates.formatDateTime(row.createdAt)}</span>;\n return \"\";\n }}\n />\n </Show>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/LogEntriesTable.tsx"],"sourcesContent":["import { dates } from \"@k2b/stdlib\";\nimport { Show } from \"solid-js\";\nimport { useUiMessages } from \"../intl/messages\";\nimport Placeholder from \"../surfaces/Placeholder\";\nimport DataTable, { type DataTableColumn } from \"./DataTable\";\n\nexport type LogTableEntry = {\n id: number | string;\n level: string;\n source: string;\n message: string;\n metadata: Record<string, unknown> | null;\n createdAt: string;\n};\n\ntype Props = {\n entries: readonly LogTableEntry[];\n emptyMessage?: string;\n};\n\n/**\n * Cloud paints each level with a hardcoded Tailwind palette pair\n * (`text-amber-500 dark:text-amber-400`, …). The package keeps the same\n * per-level distinction but routes it through `data-level` so the semantic\n * `--k2b-*` tokens stay the single theming contract in both schemes.\n */\nconst levelIcon: Record<string, { icon: string; level: string; label: string }> = {\n debug: { icon: \"ti ti-bug\", level: \"debug\", label: \"debug\" },\n info: { icon: \"ti ti-info-circle\", level: \"info\", label: \"info\" },\n warn: { icon: \"ti ti-alert-triangle\", level: \"warn\", label: \"warn\" },\n error: { icon: \"ti ti-alert-circle\", level: \"error\", label: \"error\" },\n};\n\nexport default function LogEntriesTable(props: Props) {\n const messages = useUiMessages();\n const columns = (): DataTableColumn<LogTableEntry>[] => [\n { id: \"level\", header: \"Level\", value: (entry) => entry.level },\n { id: \"source\", header: `Source (${props.entries.length})`, value: (entry) => entry.source },\n { id: \"message\", header: \"Message\", value: (entry) => entry.message },\n { id: \"time\", header: \"Time\", value: (entry) => entry.createdAt, cellClass: \"k2b-log-table__time-cell\" },\n ];\n\n return (\n <Show\n when={props.entries.length > 0}\n fallback={<Placeholder surface=\"paper\" description={<>{props.emptyMessage ?? messages().noLogEntries}</>} />}\n >\n <DataTable\n rows={props.entries}\n columns={columns()}\n getRowId={(entry) => String(entry.id)}\n hoverRows\n class=\"k2b-log-table\"\n renderCell={({ row, col }) => {\n if (col.id === \"level\") {\n const level = levelIcon[row.level] ?? { icon: \"ti ti-circle\", level: \"neutral\", label: row.level || \"unknown\" };\n return (\n <span class=\"k2b-log-level\" data-level={level.level}>\n <i class={`k2b-log-level__icon ${level.icon}`} aria-hidden=\"true\" />\n <span>{level.label}</span>\n </span>\n );\n }\n if (col.id === \"source\") return <span class=\"k2b-log-table__source\">{row.source}</span>;\n if (col.id === \"message\") return <span title={row.message}>{row.message}</span>;\n if (col.id === \"time\") return <span class=\"k2b-log-table__time\">{dates.formatDateTime(row.createdAt)}</span>;\n return \"\";\n }}\n />\n </Show>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["marked","Renderer","escapeHtml","value","replaceAll","safeUrl","normalized","trim","replace","test","normalizeInlineTokens","tokens","Set","filter","Boolean","sort","left","right","length","isStandaloneInlineToken","text","start","before","end","after","createSafeRenderer","options","renderer","inlineTokens","renderText","bind","renderTable","table","token","content","header","every","cell","html","link","href","title","body","parser","parseInline","url","linkProtocols","includes","URL","protocol","titleAttribute","target","linkTarget","image","allowImages","type","parts","plainStart","cursor","inlineToken","find","candidate","startsWith","slice","push","raw","join","renderSafeMarkdown","markdown","parse","async","MarkdownView","props","undefined","trustedHtml","_$ssr","_tmpl$","_$escape","class","_$ssrAttribute","headingScale"],"sources":["content/MarkdownView.tsx"],"sourcesContent":["import { marked, Renderer, type Tokens } from \"marked\";\n\ntype CommonProps = MarkdownRenderOptions & {\n /** Optional additional CSS classes */\n class?: string;\n /**\n * Visual heading scale. Markdown heading levels and document structure stay\n * unchanged.\n */\n headingScale?: \"compact\" | \"normal\" | \"large\";\n};\n\nexport type MarkdownViewProps = CommonProps &\n (\n | {\n /** Untrusted Markdown. Raw HTML and unsafe link protocols are escaped. */\n markdown: string;\n /** Exact standalone text tokens to emphasize without changing Markdown parsing or trusted-HTML boundaries. */\n inlineTokens?: readonly string[];\n trustedHtml?: never;\n }\n | {\n /** Explicitly trusted, already-rendered HTML. The caller owns sanitization. */\n trustedHtml: string;\n markdown?: never;\n inlineTokens?: never;\n }\n );\n\nexport type MarkdownRenderOptions = {\n inlineTokens?: readonly string[];\n /** Whether to render images. False renders alt text without resource requests. Defaults to true. */\n allowImages?: boolean;\n /** Optional protocol allowlist, including trailing colons. Relative URLs resolve as HTTPS. */\n linkProtocols?: readonly string[];\n linkTarget?: \"_blank\";\n};\n\nconst escapeHtml = (value: string): string =>\n value.replaceAll(\"&\", \"&amp;\").replaceAll(\"<\", \"&lt;\").replaceAll(\">\", \"&gt;\").replaceAll('\"', \"&quot;\").replaceAll(\"'\", \"&#39;\");\n\nconst safeUrl = (value: string): string | null => {\n const normalized = value.trim().replace(/[\\u0000-\\u001f\\u007f-\\u009f\\s]+/g, \"\");\n if (/^(?:javascript|vbscript|data):/i.test(normalized)) return null;\n return value;\n};\n\nconst normalizeInlineTokens = (tokens: readonly string[] | undefined): string[] =>\n [...new Set(tokens?.filter(Boolean) ?? [])].sort((left, right) => right.length - left.length);\n\nconst isStandaloneInlineToken = (text: string, start: number, value: string): boolean => {\n const before = text[start - 1];\n if (before && /[a-zA-Z0-9_.%+\\-]/.test(before)) return false;\n const end = start + value.length;\n const after = text[end];\n if (after && /[a-zA-Z0-9_@]/.test(after)) return false;\n return !(after === \".\" && /[a-zA-Z0-9_]/.test(text[end + 1] ?? \"\"));\n};\n\nconst createSafeRenderer = (options: MarkdownRenderOptions = {}): Renderer => {\n const renderer = new Renderer();\n const inlineTokens = normalizeInlineTokens(options.inlineTokens);\n const renderText = renderer.text.bind(renderer);\n const renderTable = renderer.table.bind(renderer);\n renderer.table = (token: Tokens.Table) => {\n const table = renderTable(token);\n const content = token.header.every((cell) => !cell.text.trim()) ? table.replace(/<thead>[\\s\\S]*?<\\/thead>\\n?/, \"\") : table;\n return `<div class=\"k2b-content-markdown__table\" tabindex=\"0\">${content}</div>`;\n };\n renderer.html = ({ text }: Tokens.HTML | Tokens.Tag) => escapeHtml(text);\n renderer.link = function ({ href, title, tokens }: Tokens.Link) {\n const body = this.parser.parseInline(tokens);\n const url = safeUrl(href);\n if (!url) return body;\n if (options.linkProtocols) {\n try {\n if (!options.linkProtocols.includes(new URL(url, \"https://markdown.invalid/\").protocol)) return body;\n } catch {\n return body;\n }\n }\n const titleAttribute = title ? ` title=\"${escapeHtml(title)}\"` : \"\";\n const target = options.linkTarget === \"_blank\" ? ' target=\"_blank\" rel=\"noopener noreferrer\"' : \"\";\n return `<a href=\"${escapeHtml(url)}\"${titleAttribute}${target}>${body}</a>`;\n };\n renderer.image = ({ href, title, text }: Tokens.Image) => {\n const url = safeUrl(href);\n if (!url || options.allowImages === false) return escapeHtml(text);\n const titleAttribute = title ? ` title=\"${escapeHtml(title)}\"` : \"\";\n return `<img src=\"${escapeHtml(url)}\" alt=\"${escapeHtml(text)}\"${titleAttribute}>`;\n };\n renderer.text = (token) => {\n if (inlineTokens.length === 0 || token.type === \"escape\" || (\"tokens\" in token && token.tokens)) return renderText(token);\n const parts: string[] = [];\n let plainStart = 0;\n let cursor = 0;\n while (cursor < token.text.length) {\n const inlineToken = inlineTokens.find(\n (candidate) => token.text.startsWith(candidate, cursor) && isStandaloneInlineToken(token.text, cursor, candidate),\n );\n if (!inlineToken) {\n cursor += 1;\n continue;\n }\n if (plainStart < cursor) {\n const text = token.text.slice(plainStart, cursor);\n parts.push(renderText({ ...token, raw: text, text }));\n }\n parts.push(\n `<span class=\"k2b-content-markdown__inline-token\">${renderText({ ...token, raw: inlineToken, text: inlineToken })}</span>`,\n );\n cursor += inlineToken.length;\n plainStart = cursor;\n }\n if (plainStart === 0) return renderText(token);\n if (plainStart < token.text.length) {\n const text = token.text.slice(plainStart);\n parts.push(renderText({ ...token, raw: text, text }));\n }\n return parts.join(\"\");\n };\n return renderer;\n};\n\nexport const renderSafeMarkdown = (markdown: string, options: MarkdownRenderOptions = {}): string =>\n marked.parse(markdown, {\n async: false,\n renderer: createSafeRenderer(options),\n }) as string;\n\n/**\n * Markdown View Component (SSR)\n *\n * Renders untrusted Markdown safely by default. Raw HTML and unsafe link\n * protocols are escaped. Already-rendered HTML requires the deliberately named\n * `trustedHtml` boundary; the caller owns sanitization in that mode.\n *\n * @example\n * ```tsx\n * import { MarkdownView } from \"@k2b/ui\";\n *\n * <MarkdownView markdown={source} />;\n * ```\n *\n * @example Compact headings, e.g. inside comments or file previews:\n * ```tsx\n * <MarkdownView markdown={source} headingScale=\"compact\" />;\n * ```\n */\nexport default function MarkdownView(props: MarkdownViewProps) {\n const html = () =>\n props.markdown !== undefined\n ? renderSafeMarkdown(props.markdown, {\n inlineTokens: props.inlineTokens,\n allowImages: props.allowImages,\n linkProtocols: props.linkProtocols,\n linkTarget: props.linkTarget,\n })\n : props.trustedHtml;\n return (\n <div\n class={`k2b-content-markdown ${props.class ?? \"\"}`}\n data-heading-scale={props.headingScale && props.headingScale !== \"normal\" ? props.headingScale : undefined}\n innerHTML={html()}\n />\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/MarkdownView.tsx"],"sourcesContent":["import { marked, Renderer, type Tokens } from \"marked\";\n\ntype CommonProps = MarkdownRenderOptions & {\n /** Optional additional CSS classes */\n class?: string;\n /**\n * Visual heading scale. Markdown heading levels and document structure stay\n * unchanged.\n */\n headingScale?: \"compact\" | \"normal\" | \"large\";\n};\n\nexport type MarkdownViewProps = CommonProps &\n (\n | {\n /** Untrusted Markdown. Raw HTML and unsafe link protocols are escaped. */\n markdown: string;\n /** Exact standalone text tokens to emphasize without changing Markdown parsing or trusted-HTML boundaries. */\n inlineTokens?: readonly string[];\n trustedHtml?: never;\n }\n | {\n /** Explicitly trusted, already-rendered HTML. The caller owns sanitization. */\n trustedHtml: string;\n markdown?: never;\n inlineTokens?: never;\n }\n );\n\nexport type MarkdownRenderOptions = {\n inlineTokens?: readonly string[];\n /** Whether to render images. False renders alt text without resource requests. Defaults to true. */\n allowImages?: boolean;\n /** Optional protocol allowlist, including trailing colons. Relative URLs resolve as HTTPS. */\n linkProtocols?: readonly string[];\n linkTarget?: \"_blank\";\n};\n\nconst escapeHtml = (value: string): string =>\n value.replaceAll(\"&\", \"&amp;\").replaceAll(\"<\", \"&lt;\").replaceAll(\">\", \"&gt;\").replaceAll('\"', \"&quot;\").replaceAll(\"'\", \"&#39;\");\n\nconst safeUrl = (value: string): string | null => {\n const normalized = value.trim().replace(/[\\u0000-\\u001f\\u007f-\\u009f\\s]+/g, \"\");\n if (/^(?:javascript|vbscript|data):/i.test(normalized)) return null;\n return value;\n};\n\nconst normalizeInlineTokens = (tokens: readonly string[] | undefined): string[] =>\n [...new Set(tokens?.filter(Boolean) ?? [])].sort((left, right) => right.length - left.length);\n\nconst isStandaloneInlineToken = (text: string, start: number, value: string): boolean => {\n const before = text[start - 1];\n if (before && /[a-zA-Z0-9_.%+\\-]/.test(before)) return false;\n const end = start + value.length;\n const after = text[end];\n if (after && /[a-zA-Z0-9_@]/.test(after)) return false;\n return !(after === \".\" && /[a-zA-Z0-9_]/.test(text[end + 1] ?? \"\"));\n};\n\nconst createSafeRenderer = (options: MarkdownRenderOptions = {}): Renderer => {\n const renderer = new Renderer();\n const inlineTokens = normalizeInlineTokens(options.inlineTokens);\n const renderText = renderer.text.bind(renderer);\n const renderTable = renderer.table.bind(renderer);\n renderer.table = (token: Tokens.Table) => {\n const table = renderTable(token);\n const content = token.header.every((cell) => !cell.text.trim()) ? table.replace(/<thead>[\\s\\S]*?<\\/thead>\\n?/, \"\") : table;\n return `<div class=\"k2b-content-markdown__table\" tabindex=\"0\">${content}</div>`;\n };\n renderer.html = ({ text }: Tokens.HTML | Tokens.Tag) => escapeHtml(text);\n renderer.link = function ({ href, title, tokens }: Tokens.Link) {\n const body = this.parser.parseInline(tokens);\n const url = safeUrl(href);\n if (!url) return body;\n if (options.linkProtocols) {\n try {\n if (!options.linkProtocols.includes(new URL(url, \"https://markdown.invalid/\").protocol)) return body;\n } catch {\n return body;\n }\n }\n const titleAttribute = title ? ` title=\"${escapeHtml(title)}\"` : \"\";\n const target = options.linkTarget === \"_blank\" ? ' target=\"_blank\" rel=\"noopener noreferrer\"' : \"\";\n return `<a href=\"${escapeHtml(url)}\"${titleAttribute}${target}>${body}</a>`;\n };\n renderer.image = ({ href, title, text }: Tokens.Image) => {\n const url = safeUrl(href);\n if (!url || options.allowImages === false) return escapeHtml(text);\n const titleAttribute = title ? ` title=\"${escapeHtml(title)}\"` : \"\";\n return `<img src=\"${escapeHtml(url)}\" alt=\"${escapeHtml(text)}\"${titleAttribute}>`;\n };\n renderer.text = (token) => {\n if (inlineTokens.length === 0 || token.type === \"escape\" || (\"tokens\" in token && token.tokens)) return renderText(token);\n const parts: string[] = [];\n let plainStart = 0;\n let cursor = 0;\n while (cursor < token.text.length) {\n const inlineToken = inlineTokens.find(\n (candidate) => token.text.startsWith(candidate, cursor) && isStandaloneInlineToken(token.text, cursor, candidate),\n );\n if (!inlineToken) {\n cursor += 1;\n continue;\n }\n if (plainStart < cursor) {\n const text = token.text.slice(plainStart, cursor);\n parts.push(renderText({ ...token, raw: text, text }));\n }\n parts.push(\n `<span class=\"k2b-content-markdown__inline-token\">${renderText({ ...token, raw: inlineToken, text: inlineToken })}</span>`,\n );\n cursor += inlineToken.length;\n plainStart = cursor;\n }\n if (plainStart === 0) return renderText(token);\n if (plainStart < token.text.length) {\n const text = token.text.slice(plainStart);\n parts.push(renderText({ ...token, raw: text, text }));\n }\n return parts.join(\"\");\n };\n return renderer;\n};\n\nexport const renderSafeMarkdown = (markdown: string, options: MarkdownRenderOptions = {}): string =>\n marked.parse(markdown, {\n async: false,\n renderer: createSafeRenderer(options),\n }) as string;\n\n/**\n * Markdown View Component (SSR)\n *\n * Renders untrusted Markdown safely by default. Raw HTML and unsafe link\n * protocols are escaped. Already-rendered HTML requires the deliberately named\n * `trustedHtml` boundary; the caller owns sanitization in that mode.\n *\n * @example\n * ```tsx\n * import { MarkdownView } from \"@k2b/ui\";\n *\n * <MarkdownView markdown={source} />;\n * ```\n *\n * @example Compact headings, e.g. inside comments or file previews:\n * ```tsx\n * <MarkdownView markdown={source} headingScale=\"compact\" />;\n * ```\n */\nexport default function MarkdownView(props: MarkdownViewProps) {\n const html = () =>\n props.markdown !== undefined\n ? renderSafeMarkdown(props.markdown, {\n inlineTokens: props.inlineTokens,\n allowImages: props.allowImages,\n linkProtocols: props.linkProtocols,\n linkTarget: props.linkTarget,\n })\n : props.trustedHtml;\n return (\n <div\n class={`k2b-content-markdown ${props.class ?? \"\"}`}\n data-heading-scale={props.headingScale && props.headingScale !== \"normal\" ? props.headingScale : undefined}\n innerHTML={html()}\n />\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,3 +1,4 @@
1
+ import { memo as _$memo } from "solid-js/web";
1
2
  import { ssr as _$ssr } from "solid-js/web";
2
3
  import { ssrAttribute as _$ssrAttribute } from "solid-js/web";
3
4
  import { escape as _$escape } from "solid-js/web";
@@ -6,7 +7,7 @@ var _tmpl$ = ["<a", " class=\"", "\"", ">", "</a>"],
6
7
  _tmpl$2 = "<i class=\"ti ti-chevron-left\" aria-hidden=\"true\"></i>",
7
8
  _tmpl$3 = "<i class=\"ti ti-chevron-right\" aria-hidden=\"true\"></i>",
8
9
  _tmpl$4 = ["<nav class=\"k2b-pagination\"", "><span class=\"k2b-sr-only\">", "</span><div class=\"k2b-pagination__pages\">", "", "", "</div></nav>"],
9
- _tmpl$5 = "<span class=\"k2b-pagination__ellipsis\" aria-hidden=\"true\">\u2026</span>",
10
+ _tmpl$5 = "<span class=\"k2b-pagination__ellipsis\" aria-hidden=\"true\">…</span>",
10
11
  _tmpl$6 = ["<span class=\"k2b-pagination__page is-current\" aria-current=\"page\">", "</span>"];
11
12
  import { Link } from "@k2b/ssr/nav";
12
13
  import { createMemo, For, Show } from "solid-js";
@@ -1 +1 @@
1
- {"version":3,"names":["Link","createMemo","For","Show","useUiMessages","PaginationLink","props","onNavigate","_$createComponent","href","rel","scroll","class","aria-label","label","children","_$ssr","_tmpl$","_$ssrAttribute","_$escape","Pagination","messages","totalPages","Math","max","floor","Number","isFinite","currentPage","min","page","baseUrl","visiblePages","Set","filter","sort","left","right","when","_tmpl$4","pagination","pageOf","total","previousPage","_tmpl$2","each","index","hasGap","undefined","isCurrent","mobileVisible","_tmpl$5","fallback","goToPage","_tmpl$6","nextPage","_tmpl$3"],"sources":["content/Pagination.tsx"],"sourcesContent":["import { Link, type LinkNavigateEvent } from \"@k2b/ssr/nav\";\nimport { createMemo, For, type JSX, Show } from \"solid-js\";\nimport { useUiMessages } from \"../intl/messages\";\n\nexport type PaginationProps = {\n currentPage: number;\n totalPages: number;\n baseUrl: string;\n onNavigate?: (event: LinkNavigateEvent) => void | Promise<void>;\n};\n\ntype PaginationLinkProps = {\n href: string;\n label: string;\n rel?: \"prev\" | \"next\";\n class?: string;\n onNavigate?: PaginationProps[\"onNavigate\"];\n children: JSX.Element;\n};\n\nconst PaginationLink = (props: PaginationLinkProps) =>\n props.onNavigate ? (\n <Link\n href={props.href}\n rel={props.rel}\n scroll=\"top\"\n onNavigate={props.onNavigate}\n class={`k2b-pagination__page ${props.class ?? \"\"}`}\n aria-label={props.label}\n >\n {props.children}\n </Link>\n ) : (\n <a href={props.href} rel={props.rel} class={`k2b-pagination__page ${props.class ?? \"\"}`} aria-label={props.label}>\n {props.children}\n </a>\n );\n\n/** Link-based pagination with directional navigation and compact mobile disclosure. */\nexport const Pagination = (props: PaginationProps): JSX.Element => {\n const messages = useUiMessages();\n const totalPages = createMemo(() => Math.max(1, Math.floor(Number.isFinite(props.totalPages) ? props.totalPages : 1)));\n const currentPage = createMemo(() =>\n Math.min(totalPages(), Math.max(1, Math.floor(Number.isFinite(props.currentPage) ? props.currentPage : 1))),\n );\n const href = (page: number) => `${props.baseUrl}${page}`;\n const visiblePages = createMemo(() =>\n [...new Set([1, currentPage() - 1, currentPage(), currentPage() + 1, totalPages()])]\n .filter((page) => page >= 1 && page <= totalPages())\n .sort((left, right) => left - right),\n );\n\n return (\n <Show when={totalPages() > 1}>\n <nav class=\"k2b-pagination\" aria-label={messages().pagination}>\n <span class=\"k2b-sr-only\">{messages().pageOf({ page: currentPage(), total: totalPages() })}</span>\n <div class=\"k2b-pagination__pages\">\n <Show when={currentPage() > 1}>\n <PaginationLink href={href(currentPage() - 1)} rel=\"prev\" label={messages().previousPage} onNavigate={props.onNavigate}>\n <i class=\"ti ti-chevron-left\" aria-hidden=\"true\" />\n </PaginationLink>\n </Show>\n\n <For each={visiblePages()}>\n {(page, index) => {\n const previousPage = () => visiblePages()[index() - 1];\n const hasGap = () => previousPage() !== undefined && page - previousPage()! > 1;\n const isCurrent = () => page === currentPage();\n const mobileVisible = () => page === 1 || page === totalPages() || isCurrent();\n\n return (\n <>\n <Show when={hasGap()}>\n <span class=\"k2b-pagination__ellipsis\" aria-hidden=\"true\">\n …\n </span>\n </Show>\n <Show\n when={isCurrent()}\n fallback={\n <PaginationLink\n href={href(page)}\n label={messages().goToPage({ page })}\n class={mobileVisible() ? \"\" : \"k2b-pagination__page--wide-only\"}\n onNavigate={props.onNavigate}\n >\n {page}\n </PaginationLink>\n }\n >\n <span class=\"k2b-pagination__page is-current\" aria-current=\"page\">\n {page}\n </span>\n </Show>\n </>\n );\n }}\n </For>\n\n <Show when={currentPage() < totalPages()}>\n <PaginationLink href={href(currentPage() + 1)} rel=\"next\" label={messages().nextPage} onNavigate={props.onNavigate}>\n <i class=\"ti ti-chevron-right\" aria-hidden=\"true\" />\n </PaginationLink>\n </Show>\n </div>\n </nav>\n </Show>\n );\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/Pagination.tsx"],"sourcesContent":["import { Link, type LinkNavigateEvent } from \"@k2b/ssr/nav\";\nimport { createMemo, For, type JSX, Show } from \"solid-js\";\nimport { useUiMessages } from \"../intl/messages\";\n\nexport type PaginationProps = {\n currentPage: number;\n totalPages: number;\n baseUrl: string;\n onNavigate?: (event: LinkNavigateEvent) => void | Promise<void>;\n};\n\ntype PaginationLinkProps = {\n href: string;\n label: string;\n rel?: \"prev\" | \"next\";\n class?: string;\n onNavigate?: PaginationProps[\"onNavigate\"];\n children: JSX.Element;\n};\n\nconst PaginationLink = (props: PaginationLinkProps) =>\n props.onNavigate ? (\n <Link\n href={props.href}\n rel={props.rel}\n scroll=\"top\"\n onNavigate={props.onNavigate}\n class={`k2b-pagination__page ${props.class ?? \"\"}`}\n aria-label={props.label}\n >\n {props.children}\n </Link>\n ) : (\n <a href={props.href} rel={props.rel} class={`k2b-pagination__page ${props.class ?? \"\"}`} aria-label={props.label}>\n {props.children}\n </a>\n );\n\n/** Link-based pagination with directional navigation and compact mobile disclosure. */\nexport const Pagination = (props: PaginationProps): JSX.Element => {\n const messages = useUiMessages();\n const totalPages = createMemo(() => Math.max(1, Math.floor(Number.isFinite(props.totalPages) ? props.totalPages : 1)));\n const currentPage = createMemo(() =>\n Math.min(totalPages(), Math.max(1, Math.floor(Number.isFinite(props.currentPage) ? props.currentPage : 1))),\n );\n const href = (page: number) => `${props.baseUrl}${page}`;\n const visiblePages = createMemo(() =>\n [...new Set([1, currentPage() - 1, currentPage(), currentPage() + 1, totalPages()])]\n .filter((page) => page >= 1 && page <= totalPages())\n .sort((left, right) => left - right),\n );\n\n return (\n <Show when={totalPages() > 1}>\n <nav class=\"k2b-pagination\" aria-label={messages().pagination}>\n <span class=\"k2b-sr-only\">{messages().pageOf({ page: currentPage(), total: totalPages() })}</span>\n <div class=\"k2b-pagination__pages\">\n <Show when={currentPage() > 1}>\n <PaginationLink href={href(currentPage() - 1)} rel=\"prev\" label={messages().previousPage} onNavigate={props.onNavigate}>\n <i class=\"ti ti-chevron-left\" aria-hidden=\"true\" />\n </PaginationLink>\n </Show>\n\n <For each={visiblePages()}>\n {(page, index) => {\n const previousPage = () => visiblePages()[index() - 1];\n const hasGap = () => previousPage() !== undefined && page - previousPage()! > 1;\n const isCurrent = () => page === currentPage();\n const mobileVisible = () => page === 1 || page === totalPages() || isCurrent();\n\n return (\n <>\n <Show when={hasGap()}>\n <span class=\"k2b-pagination__ellipsis\" aria-hidden=\"true\">\n …\n </span>\n </Show>\n <Show\n when={isCurrent()}\n fallback={\n <PaginationLink\n href={href(page)}\n label={messages().goToPage({ page })}\n class={mobileVisible() ? \"\" : \"k2b-pagination__page--wide-only\"}\n onNavigate={props.onNavigate}\n >\n {page}\n </PaginationLink>\n }\n >\n <span class=\"k2b-pagination__page is-current\" aria-current=\"page\">\n {page}\n </span>\n </Show>\n </>\n );\n }}\n </For>\n\n <Show when={currentPage() < totalPages()}>\n <PaginationLink href={href(currentPage() + 1)} rel=\"next\" label={messages().nextPage} onNavigate={props.onNavigate}>\n <i class=\"ti ti-chevron-right\" aria-hidden=\"true\" />\n </PaginationLink>\n </Show>\n </div>\n </nav>\n </Show>\n );\n};\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["createSignal","onCleanup","onMount","Show","resolveUiMessages","useUiMessages","readErrorMessage","response","data","json","message","pdfPreviewHttpError","status","PdfPreview","props","messages","url","setUrl","loading","setLoading","opening","setOpening","error","setError","disposed","loadGeneration","openGeneration","revokeCurrent","current","URL","revokeObjectURL","readPdfBlob","request","blob","Response","ok","Error","type","load","disabled","generation","nextUrl","createObjectURL","previousUrl","e","autoLoad","openInNewTab","tab","window","open","opener","document","title","pdfPreview","body","textContent","close","objectUrl","location","href","setTimeout","actions","_$ssr","_tmpl$","_$ssrAttribute","_$escape","openButtonLabel","openPreview","buttonLabel","previewPdf","content","_$createComponent","when","fallback","_tmpl$2","undefined","emptyText","renderPdfPreview","children","currentUrl","_tmpl$3","renderError","_tmpl$4","_tmpl$6","class","_tmpl$5"],"sources":["content/PdfPreview.tsx"],"sourcesContent":["import { createSignal, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { resolveUiMessages, useUiMessages } from \"../intl/messages\";\n\nexport type PdfPreviewRequest = () => Promise<Response | Blob>;\n\nexport type PdfPreviewProps = {\n request: PdfPreviewRequest;\n autoLoad?: boolean;\n disabled?: () => boolean;\n title?: string;\n buttonLabel?: string;\n openButtonLabel?: string;\n emptyText?: string;\n class?: string;\n children?: (parts: { actions: JSX.Element; content: JSX.Element }) => JSX.Element;\n renderError?: (message: string) => JSX.Element;\n};\n\nconst readErrorMessage = async (response: Response): Promise<string> => {\n try {\n const data = (await response.json()) as unknown;\n if (data && typeof data === \"object\" && \"message\" in data && typeof data.message === \"string\") return data.message;\n } catch {\n // Fall through to the HTTP status fallback.\n }\n return resolveUiMessages().pdfPreviewHttpError({ status: response.status });\n};\n\nexport default function PdfPreview(props: PdfPreviewProps) {\n const messages = useUiMessages();\n const [url, setUrl] = createSignal<string | null>(null);\n const [loading, setLoading] = createSignal(false);\n const [opening, setOpening] = createSignal(false);\n const [error, setError] = createSignal<string | null>(null);\n let disposed = false;\n let loadGeneration = 0;\n let openGeneration = 0;\n\n const revokeCurrent = () => {\n const current = url();\n if (current) URL.revokeObjectURL(current);\n setUrl(null);\n };\n\n onCleanup(() => {\n disposed = true;\n loadGeneration += 1;\n openGeneration += 1;\n revokeCurrent();\n });\n\n const readPdfBlob = async () => {\n const response = await props.request();\n const blob = response instanceof Response ? (response.ok ? await response.blob() : null) : response;\n if (!blob) throw new Error(await readErrorMessage(response as Response));\n if (blob.type && blob.type !== \"application/pdf\") throw new Error(`PDF preview returned ${blob.type} instead of application/pdf`);\n return blob;\n };\n\n const load = async () => {\n if (loading() || opening() || props.disabled?.()) return;\n const generation = ++loadGeneration;\n setLoading(true);\n setError(null);\n try {\n const blob = await readPdfBlob();\n const nextUrl = URL.createObjectURL(blob);\n if (disposed || generation !== loadGeneration) {\n URL.revokeObjectURL(nextUrl);\n return;\n }\n const previousUrl = url();\n setUrl(nextUrl);\n if (previousUrl) URL.revokeObjectURL(previousUrl);\n } catch (e) {\n if (!disposed && generation === loadGeneration) setError(e instanceof Error ? e.message : \"PDF preview failed\");\n } finally {\n if (!disposed && generation === loadGeneration) setLoading(false);\n }\n };\n\n onMount(() => {\n if (props.autoLoad) void load();\n });\n\n const openInNewTab = async () => {\n if (loading() || opening() || props.disabled?.()) return;\n const generation = ++openGeneration;\n const tab = window.open(\"\", \"_blank\");\n if (!tab) {\n setError(\"Browser blocked the preview tab\");\n return;\n }\n tab.opener = null;\n tab.document.title = props.title ?? messages().pdfPreview;\n tab.document.body.textContent = \"Rendering PDF preview...\";\n setOpening(true);\n setError(null);\n try {\n const blob = await readPdfBlob();\n if (disposed || generation !== openGeneration) {\n tab.close();\n return;\n }\n const objectUrl = URL.createObjectURL(blob);\n tab.location.href = objectUrl;\n window.setTimeout(() => URL.revokeObjectURL(objectUrl), 60_000);\n } catch (e) {\n tab.close();\n if (!disposed && generation === openGeneration) setError(e instanceof Error ? e.message : \"PDF preview failed\");\n } finally {\n if (!disposed && generation === openGeneration) setOpening(false);\n }\n };\n\n const actions = () => (\n <div class=\"k2b-content-pdf-preview__actions\">\n <button\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => void openInNewTab()}\n disabled={loading() || opening() || props.disabled?.()}\n >\n <i class={opening() ? \"ti ti-loader-2 k2b-spin\" : \"ti ti-external-link\"} aria-hidden=\"true\" />\n {props.openButtonLabel ?? messages().openPreview}\n </button>\n <button\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => void load()}\n disabled={loading() || opening() || props.disabled?.()}\n >\n <i class={loading() ? \"ti ti-loader-2 k2b-spin\" : \"ti ti-file-type-pdf\"} aria-hidden=\"true\" />\n {props.buttonLabel ?? messages().previewPdf}\n </button>\n </div>\n );\n const content = () => (\n <Show\n when={error()}\n fallback={\n <Show\n when={url()}\n fallback={\n <div class=\"k2b-content-pdf-preview__empty\">\n <span role={loading() ? \"status\" : undefined}>\n {loading() ? messages().loading : (props.emptyText ?? messages().renderPdfPreview)}\n </span>\n </div>\n }\n >\n {(currentUrl) => (\n <iframe class=\"k2b-content-pdf-preview__frame\" src={currentUrl()} title={props.title ?? messages().pdfPreview} />\n )}\n </Show>\n }\n >\n {(message) =>\n props.renderError?.(message()) ?? (\n <div role=\"alert\" class=\"k2b-content-pdf-preview__error\">\n {message()}\n </div>\n )\n }\n </Show>\n );\n\n if (props.children)\n return props.children({\n get actions() {\n return actions();\n },\n get content() {\n return content();\n },\n });\n return (\n <section class={`k2b-content-pdf-preview ${props.class ?? \"\"}`}>\n <div class=\"k2b-content-pdf-preview__toolbar\">\n <div class=\"k2b-content-pdf-preview__heading\">\n <Show when={props.title}>\n <h2 class=\"k2b-content-pdf-preview__title\">{props.title}</h2>\n </Show>\n </div>\n {actions()}\n </div>\n {content()}\n </section>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/PdfPreview.tsx"],"sourcesContent":["import { createSignal, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { resolveUiMessages, useUiMessages } from \"../intl/messages\";\n\nexport type PdfPreviewRequest = () => Promise<Response | Blob>;\n\nexport type PdfPreviewProps = {\n request: PdfPreviewRequest;\n autoLoad?: boolean;\n disabled?: () => boolean;\n title?: string;\n buttonLabel?: string;\n openButtonLabel?: string;\n emptyText?: string;\n class?: string;\n children?: (parts: { actions: JSX.Element; content: JSX.Element }) => JSX.Element;\n renderError?: (message: string) => JSX.Element;\n};\n\nconst readErrorMessage = async (response: Response): Promise<string> => {\n try {\n const data = (await response.json()) as unknown;\n if (data && typeof data === \"object\" && \"message\" in data && typeof data.message === \"string\") return data.message;\n } catch {\n // Fall through to the HTTP status fallback.\n }\n return resolveUiMessages().pdfPreviewHttpError({ status: response.status });\n};\n\nexport default function PdfPreview(props: PdfPreviewProps) {\n const messages = useUiMessages();\n const [url, setUrl] = createSignal<string | null>(null);\n const [loading, setLoading] = createSignal(false);\n const [opening, setOpening] = createSignal(false);\n const [error, setError] = createSignal<string | null>(null);\n let disposed = false;\n let loadGeneration = 0;\n let openGeneration = 0;\n\n const revokeCurrent = () => {\n const current = url();\n if (current) URL.revokeObjectURL(current);\n setUrl(null);\n };\n\n onCleanup(() => {\n disposed = true;\n loadGeneration += 1;\n openGeneration += 1;\n revokeCurrent();\n });\n\n const readPdfBlob = async () => {\n const response = await props.request();\n const blob = response instanceof Response ? (response.ok ? await response.blob() : null) : response;\n if (!blob) throw new Error(await readErrorMessage(response as Response));\n if (blob.type && blob.type !== \"application/pdf\") throw new Error(`PDF preview returned ${blob.type} instead of application/pdf`);\n return blob;\n };\n\n const load = async () => {\n if (loading() || opening() || props.disabled?.()) return;\n const generation = ++loadGeneration;\n setLoading(true);\n setError(null);\n try {\n const blob = await readPdfBlob();\n const nextUrl = URL.createObjectURL(blob);\n if (disposed || generation !== loadGeneration) {\n URL.revokeObjectURL(nextUrl);\n return;\n }\n const previousUrl = url();\n setUrl(nextUrl);\n if (previousUrl) URL.revokeObjectURL(previousUrl);\n } catch (e) {\n if (!disposed && generation === loadGeneration) setError(e instanceof Error ? e.message : \"PDF preview failed\");\n } finally {\n if (!disposed && generation === loadGeneration) setLoading(false);\n }\n };\n\n onMount(() => {\n if (props.autoLoad) void load();\n });\n\n const openInNewTab = async () => {\n if (loading() || opening() || props.disabled?.()) return;\n const generation = ++openGeneration;\n const tab = window.open(\"\", \"_blank\");\n if (!tab) {\n setError(\"Browser blocked the preview tab\");\n return;\n }\n tab.opener = null;\n tab.document.title = props.title ?? messages().pdfPreview;\n tab.document.body.textContent = \"Rendering PDF preview...\";\n setOpening(true);\n setError(null);\n try {\n const blob = await readPdfBlob();\n if (disposed || generation !== openGeneration) {\n tab.close();\n return;\n }\n const objectUrl = URL.createObjectURL(blob);\n tab.location.href = objectUrl;\n window.setTimeout(() => URL.revokeObjectURL(objectUrl), 60_000);\n } catch (e) {\n tab.close();\n if (!disposed && generation === openGeneration) setError(e instanceof Error ? e.message : \"PDF preview failed\");\n } finally {\n if (!disposed && generation === openGeneration) setOpening(false);\n }\n };\n\n const actions = () => (\n <div class=\"k2b-content-pdf-preview__actions\">\n <button\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => void openInNewTab()}\n disabled={loading() || opening() || props.disabled?.()}\n >\n <i class={opening() ? \"ti ti-loader-2 k2b-spin\" : \"ti ti-external-link\"} aria-hidden=\"true\" />\n {props.openButtonLabel ?? messages().openPreview}\n </button>\n <button\n type=\"button\"\n class=\"k2b-button\"\n data-variant=\"secondary\"\n data-size=\"sm\"\n onClick={() => void load()}\n disabled={loading() || opening() || props.disabled?.()}\n >\n <i class={loading() ? \"ti ti-loader-2 k2b-spin\" : \"ti ti-file-type-pdf\"} aria-hidden=\"true\" />\n {props.buttonLabel ?? messages().previewPdf}\n </button>\n </div>\n );\n const content = () => (\n <Show\n when={error()}\n fallback={\n <Show\n when={url()}\n fallback={\n <div class=\"k2b-content-pdf-preview__empty\">\n <span role={loading() ? \"status\" : undefined}>\n {loading() ? messages().loading : (props.emptyText ?? messages().renderPdfPreview)}\n </span>\n </div>\n }\n >\n {(currentUrl) => (\n <iframe class=\"k2b-content-pdf-preview__frame\" src={currentUrl()} title={props.title ?? messages().pdfPreview} />\n )}\n </Show>\n }\n >\n {(message) =>\n props.renderError?.(message()) ?? (\n <div role=\"alert\" class=\"k2b-content-pdf-preview__error\">\n {message()}\n </div>\n )\n }\n </Show>\n );\n\n if (props.children)\n return props.children({\n get actions() {\n return actions();\n },\n get content() {\n return content();\n },\n });\n return (\n <section class={`k2b-content-pdf-preview ${props.class ?? \"\"}`}>\n <div class=\"k2b-content-pdf-preview__toolbar\">\n <div class=\"k2b-content-pdf-preview__heading\">\n <Show when={props.title}>\n <h2 class=\"k2b-content-pdf-preview__title\">{props.title}</h2>\n </Show>\n </div>\n {actions()}\n </div>\n {content()}\n </section>\n );\n}\n"],"mappings":";;;;;;;;;;AAAA,SAAS,YAAY,EAAY,SAAS,EAAE,OAAO,EAAE,IAAI,QAAQ,UAAU;AAC3E,SAAS,iBAAiB,EAAE,aAAa,QAAQ,kBAAkB;AAiBnE,MAAM,gBAAgB,GAAG,MAAO,QAAkB,IAAsB;EACtE,IAAI;IACF,MAAM,IAAI,GAAI,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAa;IAC/C,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,SAAS,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,OAAO,IAAI,CAAC,OAAO;EACpH,CAAC,CAAC,MAAM;IACN;EAAA;EAEF,OAAO,iBAAiB,CAAC,CAAC,CAAC,mBAAmB,CAAC;IAAE,MAAM,EAAE,QAAQ,CAAC;EAAO,CAAC,CAAC;AAC7E,CAAC;AAED,eAAe,SAAS,UAAU,CAAC,KAAsB,EAAE;EACzD,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC;EAChC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,YAAY,CAAgB,IAAI,CAAC;EACvD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC;EACjD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC;EACjD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAgB,IAAI,CAAC;EAC3D,IAAI,QAAQ,GAAG,KAAK;EACpB,IAAI,cAAc,GAAG,CAAC;EACtB,IAAI,cAAc,GAAG,CAAC;EAEtB,MAAM,aAAa,GAAG,MAAM;IAC1B,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC;IACrB,IAAI,OAAO,EAAE,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC;IACzC,MAAM,CAAC,IAAI,CAAC;EACd,CAAC;EAED,SAAS,CAAC,MAAM;IACd,QAAQ,GAAG,IAAI;IACf,cAAc,IAAI,CAAC;IACnB,cAAc,IAAI,CAAC;IACnB,aAAa,CAAC,CAAC;EACjB,CAAC,CAAC;EAEF,MAAM,WAAW,GAAG,YAAY;IAC9B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,QAAQ,YAAY,QAAQ,GAAI,QAAQ,CAAC,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,GAAI,QAAQ;IACnG,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI,KAAK,CAAC,MAAM,gBAAgB,CAAC,QAAoB,CAAC,CAAC;IACxE,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,iBAAiB,EAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,CAAC,IAAI,6BAA6B,CAAC;IACjI,OAAO,IAAI;EACb,CAAC;EAED,MAAM,IAAI,GAAG,YAAY;IACvB,IAAI,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE;IAClD,MAAM,UAAU,GAAG,EAAE,cAAc;IACnC,UAAU,CAAC,IAAI,CAAC;IAChB,QAAQ,CAAC,IAAI,CAAC;IACd,IAAI;MACF,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,CAAC;MAChC,MAAM,OAAO,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC;MACzC,IAAI,QAAQ,IAAI,UAAU,KAAK,cAAc,EAAE;QAC7C,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC;QAC5B;MACF;MACA,MAAM,WAAW,GAAG,GAAG,CAAC,CAAC;MACzB,MAAM,CAAC,OAAO,CAAC;MACf,IAAI,WAAW,EAAE,GAAG,CAAC,eAAe,CAAC,WAAW,CAAC;IACnD,CAAC,CAAC,OAAO,CAAC,EAAE;MACV,IAAI,CAAC,QAAQ,IAAI,UAAU,KAAK,cAAc,EAAE,QAAQ,CAAC,CAAC,YAAY,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,oBAAoB,CAAC;IACjH,CAAC,SAAS;MACR,IAAI,CAAC,QAAQ,IAAI,UAAU,KAAK,cAAc,EAAE,UAAU,CAAC,KAAK,CAAC;IACnE;EACF,CAAC;EAED,OAAO,CAAC,MAAM;IACZ,IAAI,KAAK,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,CAAC;EACjC,CAAC,CAAC;EAEF,MAAM,YAAY,GAAG,YAAY;IAC/B,IAAI,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE;IAClD,MAAM,UAAU,GAAG,EAAE,cAAc;IACnC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC;IACrC,IAAI,CAAC,GAAG,EAAE;MACR,QAAQ,CAAC,iCAAiC,CAAC;MAC3C;IACF;IACA,GAAG,CAAC,MAAM,GAAG,IAAI;IACjB,GAAG,CAAC,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,CAAC,CAAC,UAAU;IACzD,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,GAAG,0BAA0B;IAC1D,UAAU,CAAC,IAAI,CAAC;IAChB,QAAQ,CAAC,IAAI,CAAC;IACd,IAAI;MACF,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,CAAC;MAChC,IAAI,QAAQ,IAAI,UAAU,KAAK,cAAc,EAAE;QAC7C,GAAG,CAAC,KAAK,CAAC,CAAC;QACX;MACF;MACA,MAAM,SAAS,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC;MAC3C,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,SAAS;MAC7B,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IACjE,CAAC,CAAC,OAAO,CAAC,EAAE;MACV,GAAG,CAAC,KAAK,CAAC,CAAC;MACX,IAAI,CAAC,QAAQ,IAAI,UAAU,KAAK,cAAc,EAAE,QAAQ,CAAC,CAAC,YAAY,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,oBAAoB,CAAC;IACjH,CAAC,SAAS;MACR,IAAI,CAAC,QAAQ,IAAI,UAAU,KAAK,cAAc,EAAE,UAAU,CAAC,KAAK,CAAC;IACnE;EACF,CAAC;EAED,MAAM,OAAO,GAAG,+CAQA,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,iCAE5C,OAAO,CAAC,CAAC,GAAG,yBAAyB,GAAG,qBAAqB,mBACtE,KAAK,CAAC,eAAe,IAAI,QAAQ,CAAC,CAAC,CAAC,WAAW,8BAQtC,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,iCAE5C,OAAO,CAAC,CAAC,GAAG,yBAAyB,GAAG,qBAAqB,mBACtE,KAAK,CAAC,WAAW,IAAI,QAAQ,CAAC,CAAC,CAAC,UAAU,EAGhD;EACD,MAAM,OAAO,GAAG,wBACb,IAAI;IAAA,IACH,IAAI;MAAA,OAAE,KAAK,CAAC,CAAC;IAAA;IAAA,IACb,QAAQ;MAAA,yBACL,IAAI;QAAA,IACH,IAAI;UAAA,OAAE,GAAG,CAAC,CAAC;QAAA;QAAA,IACX,QAAQ;UAAA,6CAEQ,OAAO,CAAC,CAAC,GAAG,QAAQ,YAAG,SAAS,iBACzC,OAAO,CAAC,CAAC,YAAG,QAAQ,CAAC,CAAC,CAAC,OAAO,aAAI,KAAK,CAAC,SAAS,IAAI,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC;QAAA;QAAA,UAKtF,UAAU,kDAC0C,UAAU,CAAC,CAAC,mDAAS,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,CAAC,CAAC,UAAU;MAC9G;IAAA;IAAA,UAIH,OAAO,IACP,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,4BAEzB,OAAO,CAAC,CAAC;EAEb,EAGN;EAED,IAAI,KAAK,CAAC,QAAQ,EAChB,OAAO,KAAK,CAAC,QAAQ,CAAC;IACpB,IAAI,OAAO,GAAG;MACZ,OAAO,OAAO,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,OAAO,GAAG;MACZ,OAAO,OAAO,CAAC,CAAC;IAClB;EACF,CAAC,CAAC;EACJ,sBACkB,oCAA2B,KAAK,CAAC,KAAK,IAAI,EAAE,SAAE,6BAGvD,IAAI;IAAA,IAAC,IAAI;MAAA,OAAE,KAAK,CAAC,KAAK;IAAA;IAAA;MAAA,+BACuB,KAAK,CAAC,KAAK;IAAA;EAAA,cAG1D,OAAO,CAAC,CAAC,YAEX,OAAO,CAAC,CAAC;AAGhB","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["For","useUiMessages","RangePicker","props","messages","caption","label","window","_$ssr","_tmpl$","_$escape","class","_$ssrAttribute","ariaLabel","range","_tmpl$2","_$createComponent","each","options","children","option","_tmpl$3","href","value","undefined"],"sources":["content/RangePicker.tsx"],"sourcesContent":["import { For } from \"solid-js\";\nimport { useUiMessages } from \"../intl/messages\";\n\n/**\n * RangePicker — the time window every observability surface needs.\n *\n * Rendered as links rather than buttons on purpose: window selection is a\n * server concern (the query, not the rendering), so it belongs in the URL and\n * works without hydration. Callers supply the href per option, which is what\n * lets each page keep its own other params intact — the hand-rolled copies\n * differed exactly there, with one silently dropping every unrelated filter.\n *\n * The vocabulary stays with the caller too. Traces think in `10m…30d`, request\n * telemetry in `1h…30d`, audit in days; a single hardcoded list would be wrong\n * for most of them.\n */\nexport type RangeOption<T extends string> = {\n value: T;\n /** Defaults to the value, which is already short by convention (`24h`). */\n label?: string;\n href: string;\n};\n\nexport type RangePickerProps<T extends string> = {\n options: readonly RangeOption<T>[];\n value: T;\n /** Leading caption. Pass `null` to omit it in tight toolbars. */\n label?: string | null;\n /** Names the control for assistive tech; defaults to the visible label. */\n ariaLabel?: string;\n class?: string;\n};\n\nexport default function RangePicker<T extends string>(props: RangePickerProps<T>) {\n const messages = useUiMessages();\n const caption = () => (props.label === null ? null : (props.label ?? messages().window));\n return (\n <nav class={`k2b-range-picker ${props.class ?? \"\"}`} aria-label={props.ariaLabel ?? caption() ?? messages().range}>\n {caption() ? <span class=\"k2b-range-picker__caption\">{caption()}</span> : null}\n <For each={props.options}>\n {(option) => (\n <a\n href={option.href}\n class=\"k2b-range-picker__option\"\n data-selected={option.value === props.value ? \"true\" : undefined}\n aria-current={option.value === props.value ? \"true\" : undefined}\n >\n {option.label ?? option.value}\n </a>\n )}\n </For>\n </nav>\n );\n}\n"],"mappings":";;;;;;;AAAA,SAASA,GAAG,QAAQ,UAAU;AAC9B,SAASC,aAAa,QAAQ,kBAAkB;;AAEhD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAkBA,eAAe,SAASC,WAAWA,CAAmBC,KAA0B,EAAE;EAChF,MAAMC,QAAQ,GAAGH,aAAa,CAAC,CAAC;EAChC,MAAMI,OAAO,GAAGA,CAAA,KAAOF,KAAK,CAACG,KAAK,KAAK,IAAI,GAAG,IAAI,GAAIH,KAAK,CAACG,KAAK,IAAIF,QAAQ,CAAC,CAAC,CAACG,MAAQ;EACxF,OAAAC,KAAA,CAAAC,MAAA,EACc,oBAAAC,QAAA,CAAoBP,KAAK,CAACQ,KAAK,IAAI,EAAE,SAAE,EAAAC,cAAA,eAAAF,QAAA,CAAcP,KAAK,CAACU,SAAS,IAAIR,OAAO,CAAC,CAAC,IAAID,QAAQ,CAAC,CAAC,CAACU,KAAK,iBAC9GT,OAAO,CAAC,CAAC,GAAAG,KAAA,CAAAO,OAAA,EAAAL,QAAA,CAA4CL,OAAO,CAAC,CAAC,KAAAK,QAAA,CAAW,IAAI,GAAAA,QAAA,CAAAM,iBAAA,CAC7EhB,GAAG;IAAA,IAACiB,IAAIA,CAAA;MAAA,OAAEd,KAAK,CAACe,OAAO;IAAA;IAAAC,QAAA,EACpBC,MAAM,IAAAZ,KAAA,CAAAa,OAAA,EAAAT,cAAA,SAAAF,QAAA,CAEEU,MAAM,CAACE,IAAI,iBAAAV,cAAA,kBAEFQ,MAAM,CAACG,KAAK,KAAKpB,KAAK,CAACoB,KAAK,GAAG,MAAM,GAAAb,QAAA,CAAGc,SAAS,kBAAAZ,cAAA,iBAClDQ,MAAM,CAACG,KAAK,KAAKpB,KAAK,CAACoB,KAAK,GAAG,MAAM,GAAAb,QAAA,CAAGc,SAAS,iBAAAd,QAAA,CAE9DU,MAAM,CAACd,KAAK,IAAIc,MAAM,CAACG,KAAK;EAEhC;AAIT","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/RangePicker.tsx"],"sourcesContent":["import { For } from \"solid-js\";\nimport { useUiMessages } from \"../intl/messages\";\n\n/**\n * RangePicker — the time window every observability surface needs.\n *\n * Rendered as links rather than buttons on purpose: window selection is a\n * server concern (the query, not the rendering), so it belongs in the URL and\n * works without hydration. Callers supply the href per option, which is what\n * lets each page keep its own other params intact — the hand-rolled copies\n * differed exactly there, with one silently dropping every unrelated filter.\n *\n * The vocabulary stays with the caller too. Traces think in `10m…30d`, request\n * telemetry in `1h…30d`, audit in days; a single hardcoded list would be wrong\n * for most of them.\n */\nexport type RangeOption<T extends string> = {\n value: T;\n /** Defaults to the value, which is already short by convention (`24h`). */\n label?: string;\n href: string;\n};\n\nexport type RangePickerProps<T extends string> = {\n options: readonly RangeOption<T>[];\n value: T;\n /** Leading caption. Pass `null` to omit it in tight toolbars. */\n label?: string | null;\n /** Names the control for assistive tech; defaults to the visible label. */\n ariaLabel?: string;\n class?: string;\n};\n\nexport default function RangePicker<T extends string>(props: RangePickerProps<T>) {\n const messages = useUiMessages();\n const caption = () => (props.label === null ? null : (props.label ?? messages().window));\n return (\n <nav class={`k2b-range-picker ${props.class ?? \"\"}`} aria-label={props.ariaLabel ?? caption() ?? messages().range}>\n {caption() ? <span class=\"k2b-range-picker__caption\">{caption()}</span> : null}\n <For each={props.options}>\n {(option) => (\n <a\n href={option.href}\n class=\"k2b-range-picker__option\"\n data-selected={option.value === props.value ? \"true\" : undefined}\n aria-current={option.value === props.value ? \"true\" : undefined}\n >\n {option.label ?? option.value}\n </a>\n )}\n </For>\n </nav>\n );\n}\n"],"mappings":";;;;;;;AAAA,SAAS,GAAG,QAAQ,UAAU;AAC9B,SAAS,aAAa,QAAQ,kBAAkB;;AAEhD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAkBA,eAAe,SAAS,WAAW,CAAmB,KAA0B,EAAE;EAChF,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC;EAChC,MAAM,OAAO,GAAG,MAAO,KAAK,CAAC,KAAK,KAAK,IAAI,GAAG,IAAI,GAAI,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAQ;EACxF,qBACc,6BAAoB,KAAK,CAAC,KAAK,IAAI,EAAE,SAAE,wCAAc,KAAK,CAAC,SAAS,IAAI,OAAO,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,iBAC9G,OAAO,CAAC,CAAC,2BAA4C,OAAO,CAAC,CAAC,cAAW,IAAI,8BAC7E,GAAG;IAAA,IAAC,IAAI;MAAA,OAAE,KAAK,CAAC,OAAO;IAAA;IAAA,UACpB,MAAM,mDAEE,MAAM,CAAC,IAAI,iDAEF,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,GAAG,MAAM,YAAG,SAAS,iDAClD,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,GAAG,MAAM,YAAG,SAAS,0BAE9D,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK;EAEhC;AAIT","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["createMemo","createSignal","For","Show","CopyButton","resolveMaybeAccessor","useUiMessages","isStructuredDataValue","value","seen","WeakSet","Number","isFinite","has","prototype","Object","getPrototypeOf","Array","isArray","add","valid","every","item","values","delete","toRows","data","map","index","key","String","entries","formatInlineValue","JSON","stringify","formatJson","StructuredDataPreview","props","messages","internalMode","setInternalMode","defaultMode","mode","undefined","setMode","next","onModeChange","rows","visibleRows","slice","maxRows","length","hiddenCount","Math","max","raw","hasData","showRaw","_$ssr","_tmpl$5","_$ssrAttribute","_$escape","class","filter","Boolean","join","_$createComponent","when","title","children","_tmpl$6","fallback","_tmpl$8","copy","_tmpl$7","text","_tmpl$3","_tmpl$9","empty","noData","_tmpl$","each","row","complex","_tmpl$0","_tmpl$1","_tmpl$2","_tmpl$4"],"sources":["content/StructuredDataPreview.tsx"],"sourcesContent":["import { createMemo, createSignal, For, Show } from \"solid-js\";\nimport CopyButton from \"../actions/CopyButton\";\nimport { type MaybeAccessor, resolveMaybeAccessor } from \"../inputs/field-contract\";\nimport { useUiMessages } from \"../intl/messages\";\n\nexport type StructuredDataPreviewMode = \"formatted\" | \"raw\";\nexport type StructuredDataValue =\n | null\n | boolean\n | number\n | string\n | readonly StructuredDataValue[]\n | { readonly [key: string]: StructuredDataValue };\n\nexport const isStructuredDataValue = (value: unknown, seen = new WeakSet<object>()): value is StructuredDataValue => {\n if (value === null || typeof value === \"string\" || typeof value === \"boolean\") return true;\n if (typeof value === \"number\") return Number.isFinite(value);\n if (typeof value !== \"object\" || seen.has(value)) return false;\n\n const prototype = Object.getPrototypeOf(value);\n if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) return false;\n\n seen.add(value);\n const valid = Array.isArray(value)\n ? value.every((item) => isStructuredDataValue(item, seen))\n : Object.values(value).every((item) => isStructuredDataValue(item, seen));\n seen.delete(value);\n return valid;\n};\n\nexport type StructuredDataPreviewProps = {\n title?: string;\n data: StructuredDataValue;\n /** Controlled display mode. */\n mode?: MaybeAccessor<StructuredDataPreviewMode>;\n onModeChange?: (mode: StructuredDataPreviewMode) => void;\n /** Initial mode for an uncontrolled preview. */\n defaultMode?: StructuredDataPreviewMode;\n copy?: boolean;\n empty?: string;\n maxRows?: number;\n class?: string;\n};\n\ntype Row = {\n key: string;\n value: StructuredDataValue;\n};\n\nconst toRows = (data: StructuredDataValue): Row[] => {\n if (Array.isArray(data)) return data.map((value, index) => ({ key: String(index), value }));\n if (data && typeof data === \"object\") return Object.entries(data).map(([key, value]) => ({ key, value }));\n if (data === null) return [];\n return [{ key: \"value\", value: data }];\n};\n\nconst formatInlineValue = (value: StructuredDataValue): string => {\n if (value === null) return \"null\";\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value);\n return JSON.stringify(value);\n};\n\nconst formatJson = (data: StructuredDataValue): string => JSON.stringify(data, null, 2);\n\nexport default function StructuredDataPreview(props: StructuredDataPreviewProps) {\n const messages = useUiMessages();\n const [internalMode, setInternalMode] = createSignal<StructuredDataPreviewMode>(props.defaultMode ?? \"formatted\");\n const mode = () => (props.mode === undefined ? internalMode() : resolveMaybeAccessor(props.mode));\n const setMode = (next: StructuredDataPreviewMode) => {\n if (props.mode === undefined) setInternalMode(next);\n props.onModeChange?.(next);\n };\n const rows = createMemo(() => toRows(props.data));\n const visibleRows = createMemo(() => rows().slice(0, props.maxRows ?? rows().length));\n const hiddenCount = createMemo(() => Math.max(0, rows().length - visibleRows().length));\n const raw = createMemo(() => formatJson(props.data));\n const hasData = createMemo(() => rows().length > 0);\n const showRaw = createMemo(() => mode() === \"raw\");\n\n return (\n <div class={[\"k2b-content-structured-data\", props.class].filter(Boolean).join(\" \")}>\n <Show when={props.title}>{(title) => <h2 class=\"k2b-content-structured-data__title\">{title()}</h2>}</Show>\n\n <Show\n when={!showRaw()}\n fallback={\n <div class=\"k2b-content-structured-data__surface\" data-mode=\"raw\">\n <pre>{raw()}</pre>\n <Show when={props.copy !== false}>\n <div class=\"k2b-content-structured-data__copy\">\n <CopyButton text={raw()} />\n </div>\n </Show>\n </div>\n }\n >\n <div class=\"k2b-content-structured-data__surface\">\n <Show when={hasData()} fallback={<p class=\"k2b-content-structured-data__empty\">{props.empty ?? messages().noData}</p>}>\n <div class=\"k2b-content-structured-data__rows\">\n <For each={visibleRows()}>\n {(row) => {\n const complex = typeof row.value === \"object\" && row.value !== null;\n return (\n <>\n <span class=\"k2b-content-structured-data__key\" title={row.key}>\n {row.key}\n </span>\n <span class=\"k2b-content-structured-data__value\" data-complex={complex ? \"true\" : undefined}>\n {formatInlineValue(row.value)}\n </span>\n </>\n );\n }}\n </For>\n </div>\n <Show when={hiddenCount() > 0}>\n <p class=\"k2b-content-structured-data__hidden\">\n {hiddenCount()} more row{hiddenCount() === 1 ? \"\" : \"s\"} hidden.\n </p>\n </Show>\n </Show>\n </div>\n </Show>\n\n <div class=\"k2b-content-structured-data__footer\">\n <Show when={hasData()}>\n <button type=\"button\" class=\"k2b-content-structured-data__action\" onClick={() => setMode(showRaw() ? \"formatted\" : \"raw\")}>\n {showRaw() ? \"View formatted\" : \"View raw\"}\n </button>\n </Show>\n </div>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/StructuredDataPreview.tsx"],"sourcesContent":["import { createMemo, createSignal, For, Show } from \"solid-js\";\nimport CopyButton from \"../actions/CopyButton\";\nimport { type MaybeAccessor, resolveMaybeAccessor } from \"../inputs/field-contract\";\nimport { useUiMessages } from \"../intl/messages\";\n\nexport type StructuredDataPreviewMode = \"formatted\" | \"raw\";\nexport type StructuredDataValue =\n | null\n | boolean\n | number\n | string\n | readonly StructuredDataValue[]\n | { readonly [key: string]: StructuredDataValue };\n\nexport const isStructuredDataValue = (value: unknown, seen = new WeakSet<object>()): value is StructuredDataValue => {\n if (value === null || typeof value === \"string\" || typeof value === \"boolean\") return true;\n if (typeof value === \"number\") return Number.isFinite(value);\n if (typeof value !== \"object\" || seen.has(value)) return false;\n\n const prototype = Object.getPrototypeOf(value);\n if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) return false;\n\n seen.add(value);\n const valid = Array.isArray(value)\n ? value.every((item) => isStructuredDataValue(item, seen))\n : Object.values(value).every((item) => isStructuredDataValue(item, seen));\n seen.delete(value);\n return valid;\n};\n\nexport type StructuredDataPreviewProps = {\n title?: string;\n data: StructuredDataValue;\n /** Controlled display mode. */\n mode?: MaybeAccessor<StructuredDataPreviewMode>;\n onModeChange?: (mode: StructuredDataPreviewMode) => void;\n /** Initial mode for an uncontrolled preview. */\n defaultMode?: StructuredDataPreviewMode;\n copy?: boolean;\n empty?: string;\n maxRows?: number;\n class?: string;\n};\n\ntype Row = {\n key: string;\n value: StructuredDataValue;\n};\n\nconst toRows = (data: StructuredDataValue): Row[] => {\n if (Array.isArray(data)) return data.map((value, index) => ({ key: String(index), value }));\n if (data && typeof data === \"object\") return Object.entries(data).map(([key, value]) => ({ key, value }));\n if (data === null) return [];\n return [{ key: \"value\", value: data }];\n};\n\nconst formatInlineValue = (value: StructuredDataValue): string => {\n if (value === null) return \"null\";\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value);\n return JSON.stringify(value);\n};\n\nconst formatJson = (data: StructuredDataValue): string => JSON.stringify(data, null, 2);\n\nexport default function StructuredDataPreview(props: StructuredDataPreviewProps) {\n const messages = useUiMessages();\n const [internalMode, setInternalMode] = createSignal<StructuredDataPreviewMode>(props.defaultMode ?? \"formatted\");\n const mode = () => (props.mode === undefined ? internalMode() : resolveMaybeAccessor(props.mode));\n const setMode = (next: StructuredDataPreviewMode) => {\n if (props.mode === undefined) setInternalMode(next);\n props.onModeChange?.(next);\n };\n const rows = createMemo(() => toRows(props.data));\n const visibleRows = createMemo(() => rows().slice(0, props.maxRows ?? rows().length));\n const hiddenCount = createMemo(() => Math.max(0, rows().length - visibleRows().length));\n const raw = createMemo(() => formatJson(props.data));\n const hasData = createMemo(() => rows().length > 0);\n const showRaw = createMemo(() => mode() === \"raw\");\n\n return (\n <div class={[\"k2b-content-structured-data\", props.class].filter(Boolean).join(\" \")}>\n <Show when={props.title}>{(title) => <h2 class=\"k2b-content-structured-data__title\">{title()}</h2>}</Show>\n\n <Show\n when={!showRaw()}\n fallback={\n <div class=\"k2b-content-structured-data__surface\" data-mode=\"raw\">\n <pre>{raw()}</pre>\n <Show when={props.copy !== false}>\n <div class=\"k2b-content-structured-data__copy\">\n <CopyButton text={raw()} />\n </div>\n </Show>\n </div>\n }\n >\n <div class=\"k2b-content-structured-data__surface\">\n <Show when={hasData()} fallback={<p class=\"k2b-content-structured-data__empty\">{props.empty ?? messages().noData}</p>}>\n <div class=\"k2b-content-structured-data__rows\">\n <For each={visibleRows()}>\n {(row) => {\n const complex = typeof row.value === \"object\" && row.value !== null;\n return (\n <>\n <span class=\"k2b-content-structured-data__key\" title={row.key}>\n {row.key}\n </span>\n <span class=\"k2b-content-structured-data__value\" data-complex={complex ? \"true\" : undefined}>\n {formatInlineValue(row.value)}\n </span>\n </>\n );\n }}\n </For>\n </div>\n <Show when={hiddenCount() > 0}>\n <p class=\"k2b-content-structured-data__hidden\">\n {hiddenCount()} more row{hiddenCount() === 1 ? \"\" : \"s\"} hidden.\n </p>\n </Show>\n </Show>\n </div>\n </Show>\n\n <div class=\"k2b-content-structured-data__footer\">\n <Show when={hasData()}>\n <button type=\"button\" class=\"k2b-content-structured-data__action\" onClick={() => setMode(showRaw() ? \"formatted\" : \"raw\")}>\n {showRaw() ? \"View formatted\" : \"View raw\"}\n </button>\n </Show>\n </div>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["heapPush","heap","value","before","push","index","length","parent","Math","floor","heapPop","first","last","pop","undefined","left","right","next","layoutGroup","group","groupId","active","freeLanes","assigned","laneCount","entry","end","start","released","lane","item","groupStart","groupEnd","reduce","latest","max","map","lanes","layoutCalendarIntervals","items","bounds","sorted","interval","sort","groups","Number","NEGATIVE_INFINITY","flatMap","entries"],"sources":["content/calendar-event-layout.ts"],"sourcesContent":["export type CalendarIntervalLayout<T> = {\n item: T;\n lane: number;\n lanes: number;\n groupId: number;\n groupStart: number;\n groupEnd: number;\n};\n\ntype BoundedItem<T> = {\n item: T;\n start: number;\n end: number;\n};\n\ntype ActiveLane = {\n end: number;\n lane: number;\n};\n\nconst heapPush = <T>(heap: T[], value: T, before: (left: T, right: T) => boolean): void => {\n heap.push(value);\n let index = heap.length - 1;\n while (index > 0) {\n const parent = Math.floor((index - 1) / 2);\n if (!before(heap[index]!, heap[parent]!)) break;\n [heap[parent], heap[index]] = [heap[index]!, heap[parent]!];\n index = parent;\n }\n};\n\nconst heapPop = <T>(heap: T[], before: (left: T, right: T) => boolean): T | undefined => {\n const first = heap[0];\n const last = heap.pop();\n if (heap.length === 0 || last === undefined) return first;\n heap[0] = last;\n let index = 0;\n while (true) {\n const left = index * 2 + 1;\n const right = left + 1;\n let next = index;\n if (left < heap.length && before(heap[left]!, heap[next]!)) next = left;\n if (right < heap.length && before(heap[right]!, heap[next]!)) next = right;\n if (next === index) return first;\n [heap[index], heap[next]] = [heap[next]!, heap[index]!];\n index = next;\n }\n};\n\nconst layoutGroup = <T>(group: readonly BoundedItem<T>[], groupId: number): CalendarIntervalLayout<T>[] => {\n const active: ActiveLane[] = [];\n const freeLanes: number[] = [];\n const assigned: Array<{ item: T; lane: number }> = [];\n let laneCount = 0;\n\n for (const entry of group) {\n while (active[0] && active[0].end <= entry.start) {\n const released = heapPop(active, (left, right) => left.end < right.end || (left.end === right.end && left.lane < right.lane));\n if (released) heapPush(freeLanes, released.lane, (left, right) => left < right);\n }\n const lane = heapPop(freeLanes, (left, right) => left < right) ?? laneCount++;\n heapPush(active, { end: entry.end, lane }, (left, right) => left.end < right.end || (left.end === right.end && left.lane < right.lane));\n assigned.push({ item: entry.item, lane });\n }\n\n const groupStart = group[0]?.start ?? 0;\n const groupEnd = group.reduce((latest, entry) => Math.max(latest, entry.end), groupStart);\n return assigned.map(({ item, lane }) => ({ item, lane, lanes: Math.max(1, laneCount), groupId, groupStart, groupEnd }));\n};\n\n/**\n * Assigns the lowest available visual lane to overlapping intervals.\n * Sorting plus two binary heaps keeps large overlap groups at O(n log n).\n */\nexport const layoutCalendarIntervals = <T>(\n items: readonly T[],\n bounds: (item: T) => { start: number; end: number },\n): CalendarIntervalLayout<T>[] => {\n const sorted = items\n .map((item) => {\n const interval = bounds(item);\n return { item, start: interval.start, end: Math.max(interval.start, interval.end) };\n })\n .sort((left, right) => left.start - right.start || right.end - left.end);\n const groups: Array<Array<BoundedItem<T>>> = [];\n let group: Array<BoundedItem<T>> = [];\n let groupEnd = Number.NEGATIVE_INFINITY;\n\n for (const entry of sorted) {\n if (group.length === 0 || entry.start < groupEnd) {\n group.push(entry);\n groupEnd = Math.max(groupEnd, entry.end);\n continue;\n }\n groups.push(group);\n group = [entry];\n groupEnd = entry.end;\n }\n if (group.length > 0) groups.push(group);\n\n return groups.flatMap((entries, groupId) => layoutGroup(entries, groupId));\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/calendar-event-layout.ts"],"sourcesContent":["export type CalendarIntervalLayout<T> = {\n item: T;\n lane: number;\n lanes: number;\n groupId: number;\n groupStart: number;\n groupEnd: number;\n};\n\ntype BoundedItem<T> = {\n item: T;\n start: number;\n end: number;\n};\n\ntype ActiveLane = {\n end: number;\n lane: number;\n};\n\nconst heapPush = <T>(heap: T[], value: T, before: (left: T, right: T) => boolean): void => {\n heap.push(value);\n let index = heap.length - 1;\n while (index > 0) {\n const parent = Math.floor((index - 1) / 2);\n if (!before(heap[index]!, heap[parent]!)) break;\n [heap[parent], heap[index]] = [heap[index]!, heap[parent]!];\n index = parent;\n }\n};\n\nconst heapPop = <T>(heap: T[], before: (left: T, right: T) => boolean): T | undefined => {\n const first = heap[0];\n const last = heap.pop();\n if (heap.length === 0 || last === undefined) return first;\n heap[0] = last;\n let index = 0;\n while (true) {\n const left = index * 2 + 1;\n const right = left + 1;\n let next = index;\n if (left < heap.length && before(heap[left]!, heap[next]!)) next = left;\n if (right < heap.length && before(heap[right]!, heap[next]!)) next = right;\n if (next === index) return first;\n [heap[index], heap[next]] = [heap[next]!, heap[index]!];\n index = next;\n }\n};\n\nconst layoutGroup = <T>(group: readonly BoundedItem<T>[], groupId: number): CalendarIntervalLayout<T>[] => {\n const active: ActiveLane[] = [];\n const freeLanes: number[] = [];\n const assigned: Array<{ item: T; lane: number }> = [];\n let laneCount = 0;\n\n for (const entry of group) {\n while (active[0] && active[0].end <= entry.start) {\n const released = heapPop(active, (left, right) => left.end < right.end || (left.end === right.end && left.lane < right.lane));\n if (released) heapPush(freeLanes, released.lane, (left, right) => left < right);\n }\n const lane = heapPop(freeLanes, (left, right) => left < right) ?? laneCount++;\n heapPush(active, { end: entry.end, lane }, (left, right) => left.end < right.end || (left.end === right.end && left.lane < right.lane));\n assigned.push({ item: entry.item, lane });\n }\n\n const groupStart = group[0]?.start ?? 0;\n const groupEnd = group.reduce((latest, entry) => Math.max(latest, entry.end), groupStart);\n return assigned.map(({ item, lane }) => ({ item, lane, lanes: Math.max(1, laneCount), groupId, groupStart, groupEnd }));\n};\n\n/**\n * Assigns the lowest available visual lane to overlapping intervals.\n * Sorting plus two binary heaps keeps large overlap groups at O(n log n).\n */\nexport const layoutCalendarIntervals = <T>(\n items: readonly T[],\n bounds: (item: T) => { start: number; end: number },\n): CalendarIntervalLayout<T>[] => {\n const sorted = items\n .map((item) => {\n const interval = bounds(item);\n return { item, start: interval.start, end: Math.max(interval.start, interval.end) };\n })\n .sort((left, right) => left.start - right.start || right.end - left.end);\n const groups: Array<Array<BoundedItem<T>>> = [];\n let group: Array<BoundedItem<T>> = [];\n let groupEnd = Number.NEGATIVE_INFINITY;\n\n for (const entry of sorted) {\n if (group.length === 0 || entry.start < groupEnd) {\n group.push(entry);\n groupEnd = Math.max(groupEnd, entry.end);\n continue;\n }\n groups.push(group);\n group = [entry];\n groupEnd = entry.end;\n }\n if (group.length > 0) groups.push(group);\n\n return groups.flatMap((entries, groupId) => layoutGroup(entries, groupId));\n};\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["CALENDAR_SNAP_MINUTES","snapCalendarMinutes","minutes","step","Math","round","calendarDayIndexAtPoint","clientX","startX","width","days","min","floor","calendarMinuteAtPoint","clientY","top","height","startHour","endHour","totalMinutes","max","ratio","calendarAutoScrollSpeed","bottom","edge","maximum","ceil","cancelActiveSession","startCalendarPointerSession","options","event","button","isPrimary","pointerId","target","currentTarget","HTMLElement","startY","threshold","previousUserSelect","document","body","style","userSelect","active","finished","latest","scrollFrame","preview","value","resolve","onPreview","autoScroll","scrollContainer","rect","getBoundingClientRect","speed","before","scrollTop","requestAnimationFrame","cleanup","cancelAnimationFrame","window","removeEventListener","onMove","onUp","cancel","onKeyDown","hasPointerCapture","releasePointerCapture","activate","setPointerCapture","onActivate","onCancel","hypot","preventDefault","onCommit","key","addEventListener","passive"],"sources":["content/calendar-pointer.ts"],"sourcesContent":["export const CALENDAR_SNAP_MINUTES = 15;\n\nexport const snapCalendarMinutes = (minutes: number, step = CALENDAR_SNAP_MINUTES): number => Math.round(minutes / step) * step;\n\nexport const calendarDayIndexAtPoint = (clientX: number, startX: number, width: number, days: number): number | null => {\n if (days <= 0 || width <= 0 || clientX < startX || clientX >= startX + width) return null;\n return Math.min(days - 1, Math.floor(((clientX - startX) / width) * days));\n};\n\nexport const calendarMinuteAtPoint = (clientY: number, top: number, height: number, startHour: number, endHour: number): number => {\n const totalMinutes = Math.max(60, (endHour - startHour + 1) * 60);\n const ratio = height > 0 ? Math.min(1, Math.max(0, (clientY - top) / height)) : 0;\n return snapCalendarMinutes(startHour * 60 + ratio * totalMinutes);\n};\n\nexport const calendarAutoScrollSpeed = (clientY: number, top: number, bottom: number, edge = 56, maximum = 18): number => {\n if (clientY < top + edge) return -Math.ceil(maximum * Math.min(1, (top + edge - clientY) / edge));\n if (clientY > bottom - edge) return Math.ceil(maximum * Math.min(1, (clientY - (bottom - edge)) / edge));\n return 0;\n};\n\ntype CalendarPointerSessionOptions<T> = {\n event: PointerEvent;\n resolve: (clientX: number, clientY: number) => T | null;\n onActivate?: () => void;\n onPreview: (value: T) => void;\n onCommit: (value: T) => void;\n onCancel?: () => void;\n scrollContainer?: HTMLElement;\n threshold?: number;\n};\n\nlet cancelActiveSession: (() => void) | null = null;\n\n/**\n * Owns one pointer gesture from threshold crossing through commit or cancel.\n * Views provide geometry through `resolve`; this helper owns global cleanup,\n * pointer cancellation, Escape handling, and edge auto-scroll.\n */\nexport const startCalendarPointerSession = <T>(options: CalendarPointerSessionOptions<T>): (() => void) => {\n if (options.event.button !== 0 || !options.event.isPrimary) return () => {};\n\n cancelActiveSession?.();\n\n const pointerId = options.event.pointerId;\n const target = options.event.currentTarget instanceof HTMLElement ? options.event.currentTarget : null;\n const startX = options.event.clientX;\n const startY = options.event.clientY;\n // Leave enough room for normal click jitter before an event becomes a drag.\n const threshold = options.threshold ?? 6;\n const previousUserSelect = document.body.style.userSelect;\n let clientX = startX;\n let clientY = startY;\n let active = false;\n let finished = false;\n let latest: T | null = null;\n let scrollFrame = 0;\n\n const preview = () => {\n const value = options.resolve(clientX, clientY);\n if (value === null) return;\n latest = value;\n options.onPreview(value);\n };\n\n const autoScroll = () => {\n scrollFrame = 0;\n if (!active || !options.scrollContainer) return;\n const rect = options.scrollContainer.getBoundingClientRect();\n const speed = calendarAutoScrollSpeed(clientY, rect.top, rect.bottom);\n if (speed !== 0) {\n const before = options.scrollContainer.scrollTop;\n options.scrollContainer.scrollTop += speed;\n if (options.scrollContainer.scrollTop !== before) preview();\n }\n scrollFrame = requestAnimationFrame(autoScroll);\n };\n\n const cleanup = () => {\n if (scrollFrame) cancelAnimationFrame(scrollFrame);\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n window.removeEventListener(\"pointercancel\", cancel);\n window.removeEventListener(\"blur\", cancel);\n window.removeEventListener(\"keydown\", onKeyDown);\n if (target?.hasPointerCapture?.(pointerId)) target.releasePointerCapture(pointerId);\n document.body.style.userSelect = previousUserSelect;\n if (cancelActiveSession === cancel) cancelActiveSession = null;\n };\n\n const activate = () => {\n if (active) return;\n active = true;\n document.body.style.userSelect = \"none\";\n target?.setPointerCapture?.(pointerId);\n options.onActivate?.();\n preview();\n if (options.scrollContainer) scrollFrame = requestAnimationFrame(autoScroll);\n };\n\n function cancel() {\n if (finished) return;\n finished = true;\n cleanup();\n if (active) options.onCancel?.();\n }\n\n function onMove(event: PointerEvent) {\n if (finished || event.pointerId !== pointerId) return;\n clientX = event.clientX;\n clientY = event.clientY;\n if (!active && Math.hypot(clientX - startX, clientY - startY) >= threshold) activate();\n if (!active) return;\n event.preventDefault();\n preview();\n }\n\n function onUp(event: PointerEvent) {\n if (finished || event.pointerId !== pointerId) return;\n finished = true;\n cleanup();\n if (active && latest !== null) options.onCommit(latest);\n else if (active) options.onCancel?.();\n }\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key !== \"Escape\") return;\n event.preventDefault();\n cancel();\n }\n\n window.addEventListener(\"pointermove\", onMove, { passive: false });\n window.addEventListener(\"pointerup\", onUp);\n window.addEventListener(\"pointercancel\", cancel);\n window.addEventListener(\"blur\", cancel);\n window.addEventListener(\"keydown\", onKeyDown);\n cancelActiveSession = cancel;\n return cancel;\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/calendar-pointer.ts"],"sourcesContent":["export const CALENDAR_SNAP_MINUTES = 15;\n\nexport const snapCalendarMinutes = (minutes: number, step = CALENDAR_SNAP_MINUTES): number => Math.round(minutes / step) * step;\n\nexport const calendarDayIndexAtPoint = (clientX: number, startX: number, width: number, days: number): number | null => {\n if (days <= 0 || width <= 0 || clientX < startX || clientX >= startX + width) return null;\n return Math.min(days - 1, Math.floor(((clientX - startX) / width) * days));\n};\n\nexport const calendarMinuteAtPoint = (clientY: number, top: number, height: number, startHour: number, endHour: number): number => {\n const totalMinutes = Math.max(60, (endHour - startHour + 1) * 60);\n const ratio = height > 0 ? Math.min(1, Math.max(0, (clientY - top) / height)) : 0;\n return snapCalendarMinutes(startHour * 60 + ratio * totalMinutes);\n};\n\nexport const calendarAutoScrollSpeed = (clientY: number, top: number, bottom: number, edge = 56, maximum = 18): number => {\n if (clientY < top + edge) return -Math.ceil(maximum * Math.min(1, (top + edge - clientY) / edge));\n if (clientY > bottom - edge) return Math.ceil(maximum * Math.min(1, (clientY - (bottom - edge)) / edge));\n return 0;\n};\n\ntype CalendarPointerSessionOptions<T> = {\n event: PointerEvent;\n resolve: (clientX: number, clientY: number) => T | null;\n onActivate?: () => void;\n onPreview: (value: T) => void;\n onCommit: (value: T) => void;\n onCancel?: () => void;\n scrollContainer?: HTMLElement;\n threshold?: number;\n};\n\nlet cancelActiveSession: (() => void) | null = null;\n\n/**\n * Owns one pointer gesture from threshold crossing through commit or cancel.\n * Views provide geometry through `resolve`; this helper owns global cleanup,\n * pointer cancellation, Escape handling, and edge auto-scroll.\n */\nexport const startCalendarPointerSession = <T>(options: CalendarPointerSessionOptions<T>): (() => void) => {\n if (options.event.button !== 0 || !options.event.isPrimary) return () => {};\n\n cancelActiveSession?.();\n\n const pointerId = options.event.pointerId;\n const target = options.event.currentTarget instanceof HTMLElement ? options.event.currentTarget : null;\n const startX = options.event.clientX;\n const startY = options.event.clientY;\n // Leave enough room for normal click jitter before an event becomes a drag.\n const threshold = options.threshold ?? 6;\n const previousUserSelect = document.body.style.userSelect;\n let clientX = startX;\n let clientY = startY;\n let active = false;\n let finished = false;\n let latest: T | null = null;\n let scrollFrame = 0;\n\n const preview = () => {\n const value = options.resolve(clientX, clientY);\n if (value === null) return;\n latest = value;\n options.onPreview(value);\n };\n\n const autoScroll = () => {\n scrollFrame = 0;\n if (!active || !options.scrollContainer) return;\n const rect = options.scrollContainer.getBoundingClientRect();\n const speed = calendarAutoScrollSpeed(clientY, rect.top, rect.bottom);\n if (speed !== 0) {\n const before = options.scrollContainer.scrollTop;\n options.scrollContainer.scrollTop += speed;\n if (options.scrollContainer.scrollTop !== before) preview();\n }\n scrollFrame = requestAnimationFrame(autoScroll);\n };\n\n const cleanup = () => {\n if (scrollFrame) cancelAnimationFrame(scrollFrame);\n window.removeEventListener(\"pointermove\", onMove);\n window.removeEventListener(\"pointerup\", onUp);\n window.removeEventListener(\"pointercancel\", cancel);\n window.removeEventListener(\"blur\", cancel);\n window.removeEventListener(\"keydown\", onKeyDown);\n if (target?.hasPointerCapture?.(pointerId)) target.releasePointerCapture(pointerId);\n document.body.style.userSelect = previousUserSelect;\n if (cancelActiveSession === cancel) cancelActiveSession = null;\n };\n\n const activate = () => {\n if (active) return;\n active = true;\n document.body.style.userSelect = \"none\";\n target?.setPointerCapture?.(pointerId);\n options.onActivate?.();\n preview();\n if (options.scrollContainer) scrollFrame = requestAnimationFrame(autoScroll);\n };\n\n function cancel() {\n if (finished) return;\n finished = true;\n cleanup();\n if (active) options.onCancel?.();\n }\n\n function onMove(event: PointerEvent) {\n if (finished || event.pointerId !== pointerId) return;\n clientX = event.clientX;\n clientY = event.clientY;\n if (!active && Math.hypot(clientX - startX, clientY - startY) >= threshold) activate();\n if (!active) return;\n event.preventDefault();\n preview();\n }\n\n function onUp(event: PointerEvent) {\n if (finished || event.pointerId !== pointerId) return;\n finished = true;\n cleanup();\n if (active && latest !== null) options.onCommit(latest);\n else if (active) options.onCancel?.();\n }\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key !== \"Escape\") return;\n event.preventDefault();\n cancel();\n }\n\n window.addEventListener(\"pointermove\", onMove, { passive: false });\n window.addEventListener(\"pointerup\", onUp);\n window.addEventListener(\"pointercancel\", cancel);\n window.addEventListener(\"blur\", cancel);\n window.addEventListener(\"keydown\", onKeyDown);\n cancelActiveSession = cancel;\n return cancel;\n};\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["createChartCursor","options","state","listeners","Set","notify","listener","formatX","read","subscribe","add","delete","move","source","x","Number","isFinite","clear"],"sources":["content/chart-cursor.ts"],"sourcesContent":["export type ChartCursorState = { source: symbol; x: number } | null;\n\n/** Share one numeric X value between line charts. Create one instance per group. */\nexport function createChartCursor(options: { formatX?: (x: number) => string } = {}) {\n let state: ChartCursorState = null;\n const listeners = new Set<(state: ChartCursorState) => void>();\n const notify = () => {\n for (const listener of listeners) listener(state);\n };\n return {\n formatX: options.formatX,\n read: () => state,\n subscribe(listener: (state: ChartCursorState) => void) {\n listeners.add(listener);\n listener(state);\n return () => {\n listeners.delete(listener);\n };\n },\n move(source: symbol, x: number) {\n if (!Number.isFinite(x) || (state?.source === source && state.x === x)) return;\n state = { source, x };\n notify();\n },\n clear(source: symbol) {\n if (state?.source !== source) return;\n state = null;\n notify();\n },\n };\n}\nexport type ChartCursor = ReturnType<typeof createChartCursor>;\n"],"mappings":"AAEA;AACA,OAAO,SAASA,iBAAiBA,CAACC,OAA4C,GAAG,CAAC,CAAC,EAAE;EACnF,IAAIC,KAAuB,GAAG,IAAI;EAClC,MAAMC,SAAS,GAAG,IAAIC,GAAG,CAAoC,CAAC;EAC9D,MAAMC,MAAM,GAAGA,CAAA,KAAM;IACnB,KAAK,MAAMC,QAAQ,IAAIH,SAAS,EAAEG,QAAQ,CAACJ,KAAK,CAAC;EACnD,CAAC;EACD,OAAO;IACLK,OAAO,EAAEN,OAAO,CAACM,OAAO;IACxBC,IAAI,EAAEA,CAAA,KAAMN,KAAK;IACjBO,SAASA,CAACH,QAA2C,EAAE;MACrDH,SAAS,CAACO,GAAG,CAACJ,QAAQ,CAAC;MACvBA,QAAQ,CAACJ,KAAK,CAAC;MACf,OAAO,MAAM;QACXC,SAAS,CAACQ,MAAM,CAACL,QAAQ,CAAC;MAC5B,CAAC;IACH,CAAC;IACDM,IAAIA,CAACC,MAAc,EAAEC,CAAS,EAAE;MAC9B,IAAI,CAACC,MAAM,CAACC,QAAQ,CAACF,CAAC,CAAC,IAAKZ,KAAK,EAAEW,MAAM,KAAKA,MAAM,IAAIX,KAAK,CAACY,CAAC,KAAKA,CAAE,EAAE;MACxEZ,KAAK,GAAG;QAAEW,MAAM;QAAEC;MAAE,CAAC;MACrBT,MAAM,CAAC,CAAC;IACV,CAAC;IACDY,KAAKA,CAACJ,MAAc,EAAE;MACpB,IAAIX,KAAK,EAAEW,MAAM,KAAKA,MAAM,EAAE;MAC9BX,KAAK,GAAG,IAAI;MACZG,MAAM,CAAC,CAAC;IACV;EACF,CAAC;AACH","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/chart-cursor.ts"],"sourcesContent":["export type ChartCursorState = { source: symbol; x: number } | null;\n\n/** Share one numeric X value between line charts. Create one instance per group. */\nexport function createChartCursor(options: { formatX?: (x: number) => string } = {}) {\n let state: ChartCursorState = null;\n const listeners = new Set<(state: ChartCursorState) => void>();\n const notify = () => {\n for (const listener of listeners) listener(state);\n };\n return {\n formatX: options.formatX,\n read: () => state,\n subscribe(listener: (state: ChartCursorState) => void) {\n listeners.add(listener);\n listener(state);\n return () => {\n listeners.delete(listener);\n };\n },\n move(source: symbol, x: number) {\n if (!Number.isFinite(x) || (state?.source === source && state.x === x)) return;\n state = { source, x };\n notify();\n },\n clear(source: symbol) {\n if (state?.source !== source) return;\n state = null;\n notify();\n },\n };\n}\nexport type ChartCursor = ReturnType<typeof createChartCursor>;\n"],"mappings":"AAEA;AACA,OAAO,SAAS,iBAAiB,CAAC,OAA4C,GAAG,CAAC,CAAC,EAAE;EACnF,IAAI,KAAuB,GAAG,IAAI;EAClC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAoC,CAAC;EAC9D,MAAM,MAAM,GAAG,MAAM;IACnB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC;EACnD,CAAC;EACD,OAAO;IACL,OAAO,EAAE,OAAO,CAAC,OAAO;IACxB,IAAI,EAAE,MAAM,KAAK;IACjB,SAAS,CAAC,QAA2C,EAAE;MACrD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC;MACvB,QAAQ,CAAC,KAAK,CAAC;MACf,OAAO,MAAM;QACX,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC;MAC5B,CAAC;IACH,CAAC;IACD,IAAI,CAAC,MAAc,EAAE,CAAS,EAAE;MAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAK,KAAK,EAAE,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,CAAC,KAAK,CAAE,EAAE;MACxE,KAAK,GAAG;QAAE,MAAM;QAAE;MAAE,CAAC;MACrB,MAAM,CAAC,CAAC;IACV,CAAC;IACD,KAAK,CAAC,MAAc,EAAE;MACpB,IAAI,KAAK,EAAE,MAAM,KAAK,MAAM,EAAE;MAC9B,KAAK,GAAG,IAAI;MACZ,MAAM,CAAC,CAAC;IACV;EACF,CAAC;AACH","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["batch","createEffect","createSignal","onCleanup","untrack","sameExplorerRequest","a","b","step","referenceStep","visibleKeys","undefined","length","every","key","includes","validateRequest","request","some","Set","size","Error","validateChartExplorerData","data","keys","rows","map","row","marks","chart","mark","has","rowKey","createChartExplorer","options","onRequestChange","selectedKey","onSelectedKeyChange","initial","snapshot","ids","Object","charts","sort","id","validate","value","nextIds","i","values","forEach","setSnapshot","desired","setDesired","loading","setLoading","error","setError","localSelection","setLocalSelection","rawSelection","hasRow","select","pending","disposed","adopt","next","execute","force","abort","controller","AbortController","result","load","signal","aborted","cause","setRequest","refresh","retry","pinReference","clearReference"],"sources":["content/chart-explorer.ts"],"sourcesContent":["import { type Accessor, batch, createEffect, createSignal, onCleanup, untrack } from \"solid-js\";\nimport type { ChartSnapshot } from \"./chart-snapshot\";\n\n/** Omitted visibleKeys means no series filter; [] explicitly hides every series. */\nexport type ChartExplorerRequest = { step?: string; visibleKeys?: readonly string[]; referenceStep?: string };\nexport type ChartExplorerRow = { key: string };\nexport type ChartExplorerData<T extends ChartExplorerRow = ChartExplorerRow> = { chart: ChartSnapshot; rows: readonly T[] };\nexport type ChartExplorerCharts = Readonly<Record<string, ChartExplorerData>>;\nexport type ChartExplorerSnapshot<C extends ChartExplorerCharts> = { request: ChartExplorerRequest; charts: C };\nexport type ChartExplorerOptions<C extends ChartExplorerCharts> = {\n /** Authoritative initial/replacement data. Replacements cancel pending work. */\n snapshot: Accessor<ChartExplorerSnapshot<C>>;\n load: (\n request: ChartExplorerRequest,\n signal: AbortSignal,\n ) => ChartExplorerSnapshot<NoInfer<C>> | Promise<ChartExplorerSnapshot<NoInfer<C>>>;\n /** Optional controlled filters. Changes trigger loading; setRequest emits onRequestChange. */\n request?: Accessor<ChartExplorerRequest>;\n onRequestChange?: (request: ChartExplorerRequest) => void;\n selectedKey?: Accessor<string | null>;\n onSelectedKeyChange?: (key: string | null) => void;\n};\nexport type ChartExplorerController<C extends ChartExplorerCharts> = ReturnType<typeof createChartExplorer<C>>;\n\nexport const sameExplorerRequest = (a: ChartExplorerRequest, b: ChartExplorerRequest) =>\n a.step === b.step &&\n a.referenceStep === b.referenceStep &&\n (a.visibleKeys === undefined || b.visibleKeys === undefined\n ? a.visibleKeys === b.visibleKeys\n : a.visibleKeys.length === b.visibleKeys.length && a.visibleKeys.every((key) => b.visibleKeys!.includes(key)));\n\nfunction validateRequest(request: ChartExplorerRequest) {\n if (\n request.step === \"\" ||\n request.referenceStep === \"\" ||\n (request.referenceStep !== undefined && request.step === undefined) ||\n request.visibleKeys?.some((key) => !key) ||\n new Set(request.visibleKeys).size !== (request.visibleKeys?.length ?? 0)\n ) {\n throw new Error(\"Chart filters require nonempty unique keys; a reference requires a current step\");\n }\n}\n\nexport function validateChartExplorerData(data: ChartExplorerData) {\n const keys = data.rows.map((row) => row.key);\n const rows = new Set(keys);\n const marks = data.chart.marks.map((mark) => mark.key);\n if (\n keys.some((key) => !key) ||\n rows.size !== keys.length ||\n marks.some((key) => !key) ||\n new Set(marks).size !== marks.length ||\n data.chart.marks.some((mark) => !rows.has(mark.rowKey))\n ) {\n throw new Error(\"Chart data requires unique row/mark keys and a row for every mark.rowKey\");\n }\n}\n\n/** One owner for one or many charts. Source/HTTP/aggregation remain caller-owned. */\nexport function createChartExplorer<C extends ChartExplorerCharts>(options: ChartExplorerOptions<C>) {\n if (options.request && !options.onRequestChange) throw new Error(\"Controlled chart filters require onRequestChange\");\n if (options.selectedKey && !options.onSelectedKeyChange) throw new Error(\"Controlled chart selection requires onSelectedKeyChange\");\n const initial = options.snapshot();\n const ids = Object.keys(initial.charts).sort();\n if (!ids.length || ids.some((id) => !id)) throw new Error(\"An explorer needs named charts\");\n const validate = (value: ChartExplorerSnapshot<C>) => {\n validateRequest(value.request);\n const nextIds = Object.keys(value.charts).sort();\n if (nextIds.length !== ids.length || nextIds.some((id, i) => id !== ids[i])) throw new Error(\"Return every configured chart\");\n Object.values(value.charts).forEach(validateChartExplorerData);\n };\n validate(initial);\n const [snapshot, setSnapshot] = createSignal(initial);\n const [desired, setDesired] = createSignal(options.request?.() ?? initial.request);\n const [loading, setLoading] = createSignal(false);\n const [error, setError] = createSignal<Error | null>(null);\n const [localSelection, setLocalSelection] = createSignal<string | null>(null);\n const rawSelection = () => (options.selectedKey ? options.selectedKey() : localSelection());\n const hasRow = (value: ChartExplorerSnapshot<C>, key: string) =>\n Object.values(value.charts).some((data) => data.rows.some((row) => row.key === key));\n const selectedKey = () => {\n const key = rawSelection();\n return key !== null && hasRow(snapshot(), key) ? key : null;\n };\n const select = (key: string | null) => {\n if (key !== null && !hasRow(snapshot(), key)) return;\n if (!options.selectedKey) setLocalSelection(key);\n options.onSelectedKeyChange?.(key);\n };\n let pending: AbortController | undefined;\n let disposed = false;\n const adopt = (next: ChartExplorerSnapshot<C>) => {\n setSnapshot(() => next);\n const key = rawSelection();\n if (!options.selectedKey && key !== null && !hasRow(next, key)) select(null);\n };\n const execute = async (next: ChartExplorerRequest, force = false) => {\n if (disposed) return;\n validateRequest(next);\n if (!force && pending && sameExplorerRequest(next, desired())) return;\n pending?.abort();\n const controller = new AbortController();\n pending = controller;\n batch(() => {\n setDesired(next);\n setError(null);\n });\n if (!force && sameExplorerRequest(next, snapshot().request)) {\n pending = undefined;\n setLoading(false);\n return;\n }\n setLoading(true);\n try {\n const result = await options.load(next, controller.signal);\n if (controller.signal.aborted || pending !== controller) return;\n if (!sameExplorerRequest(result.request, next)) throw new Error(\"Chart response does not match requested filters\");\n validate(result);\n batch(() => adopt(result));\n } catch (cause) {\n if (!controller.signal.aborted && pending === controller)\n setError(() => (cause instanceof Error ? cause : new Error(\"Could not load chart data\", { cause })));\n } finally {\n if (!controller.signal.aborted && pending === controller) {\n setLoading(false);\n pending = undefined;\n }\n }\n };\n createEffect(() => {\n const next = options.snapshot();\n untrack(() => {\n validate(next);\n pending?.abort();\n pending = undefined;\n batch(() => {\n adopt(next);\n setDesired(options.request?.() ?? next.request);\n setLoading(false);\n setError(null);\n });\n });\n });\n createEffect(() => {\n options.snapshot();\n const request = options.request?.();\n if (request)\n untrack(() => {\n void execute(request);\n });\n });\n onCleanup(() => {\n disposed = true;\n pending?.abort();\n });\n const setRequest = (next: ChartExplorerRequest) => {\n validateRequest(next);\n if (!options.request) void execute(next);\n options.onRequestChange?.(next);\n };\n return {\n snapshot,\n desired,\n loading,\n error,\n selectedKey,\n select,\n setRequest,\n /** Force a fresh read of the desired filters, even when nothing changed. */\n refresh: () => execute(options.request?.() ?? desired(), true),\n retry: () => execute(options.request?.() ?? desired(), true),\n pinReference() {\n const step = snapshot().request.step;\n if (step !== undefined) setRequest({ ...desired(), referenceStep: step });\n },\n clearReference() {\n setRequest({ ...desired(), referenceStep: undefined });\n },\n };\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/chart-explorer.ts"],"sourcesContent":["import { type Accessor, batch, createEffect, createSignal, onCleanup, untrack } from \"solid-js\";\nimport type { ChartSnapshot } from \"./chart-snapshot\";\n\n/** Omitted visibleKeys means no series filter; [] explicitly hides every series. */\nexport type ChartExplorerRequest = { step?: string; visibleKeys?: readonly string[]; referenceStep?: string };\nexport type ChartExplorerRow = { key: string };\nexport type ChartExplorerData<T extends ChartExplorerRow = ChartExplorerRow> = { chart: ChartSnapshot; rows: readonly T[] };\nexport type ChartExplorerCharts = Readonly<Record<string, ChartExplorerData>>;\nexport type ChartExplorerSnapshot<C extends ChartExplorerCharts> = { request: ChartExplorerRequest; charts: C };\nexport type ChartExplorerOptions<C extends ChartExplorerCharts> = {\n /** Authoritative initial/replacement data. Replacements cancel pending work. */\n snapshot: Accessor<ChartExplorerSnapshot<C>>;\n load: (\n request: ChartExplorerRequest,\n signal: AbortSignal,\n ) => ChartExplorerSnapshot<NoInfer<C>> | Promise<ChartExplorerSnapshot<NoInfer<C>>>;\n /** Optional controlled filters. Changes trigger loading; setRequest emits onRequestChange. */\n request?: Accessor<ChartExplorerRequest>;\n onRequestChange?: (request: ChartExplorerRequest) => void;\n selectedKey?: Accessor<string | null>;\n onSelectedKeyChange?: (key: string | null) => void;\n};\nexport type ChartExplorerController<C extends ChartExplorerCharts> = ReturnType<typeof createChartExplorer<C>>;\n\nexport const sameExplorerRequest = (a: ChartExplorerRequest, b: ChartExplorerRequest) =>\n a.step === b.step &&\n a.referenceStep === b.referenceStep &&\n (a.visibleKeys === undefined || b.visibleKeys === undefined\n ? a.visibleKeys === b.visibleKeys\n : a.visibleKeys.length === b.visibleKeys.length && a.visibleKeys.every((key) => b.visibleKeys!.includes(key)));\n\nfunction validateRequest(request: ChartExplorerRequest) {\n if (\n request.step === \"\" ||\n request.referenceStep === \"\" ||\n (request.referenceStep !== undefined && request.step === undefined) ||\n request.visibleKeys?.some((key) => !key) ||\n new Set(request.visibleKeys).size !== (request.visibleKeys?.length ?? 0)\n ) {\n throw new Error(\"Chart filters require nonempty unique keys; a reference requires a current step\");\n }\n}\n\nexport function validateChartExplorerData(data: ChartExplorerData) {\n const keys = data.rows.map((row) => row.key);\n const rows = new Set(keys);\n const marks = data.chart.marks.map((mark) => mark.key);\n if (\n keys.some((key) => !key) ||\n rows.size !== keys.length ||\n marks.some((key) => !key) ||\n new Set(marks).size !== marks.length ||\n data.chart.marks.some((mark) => !rows.has(mark.rowKey))\n ) {\n throw new Error(\"Chart data requires unique row/mark keys and a row for every mark.rowKey\");\n }\n}\n\n/** One owner for one or many charts. Source/HTTP/aggregation remain caller-owned. */\nexport function createChartExplorer<C extends ChartExplorerCharts>(options: ChartExplorerOptions<C>) {\n if (options.request && !options.onRequestChange) throw new Error(\"Controlled chart filters require onRequestChange\");\n if (options.selectedKey && !options.onSelectedKeyChange) throw new Error(\"Controlled chart selection requires onSelectedKeyChange\");\n const initial = options.snapshot();\n const ids = Object.keys(initial.charts).sort();\n if (!ids.length || ids.some((id) => !id)) throw new Error(\"An explorer needs named charts\");\n const validate = (value: ChartExplorerSnapshot<C>) => {\n validateRequest(value.request);\n const nextIds = Object.keys(value.charts).sort();\n if (nextIds.length !== ids.length || nextIds.some((id, i) => id !== ids[i])) throw new Error(\"Return every configured chart\");\n Object.values(value.charts).forEach(validateChartExplorerData);\n };\n validate(initial);\n const [snapshot, setSnapshot] = createSignal(initial);\n const [desired, setDesired] = createSignal(options.request?.() ?? initial.request);\n const [loading, setLoading] = createSignal(false);\n const [error, setError] = createSignal<Error | null>(null);\n const [localSelection, setLocalSelection] = createSignal<string | null>(null);\n const rawSelection = () => (options.selectedKey ? options.selectedKey() : localSelection());\n const hasRow = (value: ChartExplorerSnapshot<C>, key: string) =>\n Object.values(value.charts).some((data) => data.rows.some((row) => row.key === key));\n const selectedKey = () => {\n const key = rawSelection();\n return key !== null && hasRow(snapshot(), key) ? key : null;\n };\n const select = (key: string | null) => {\n if (key !== null && !hasRow(snapshot(), key)) return;\n if (!options.selectedKey) setLocalSelection(key);\n options.onSelectedKeyChange?.(key);\n };\n let pending: AbortController | undefined;\n let disposed = false;\n const adopt = (next: ChartExplorerSnapshot<C>) => {\n setSnapshot(() => next);\n const key = rawSelection();\n if (!options.selectedKey && key !== null && !hasRow(next, key)) select(null);\n };\n const execute = async (next: ChartExplorerRequest, force = false) => {\n if (disposed) return;\n validateRequest(next);\n if (!force && pending && sameExplorerRequest(next, desired())) return;\n pending?.abort();\n const controller = new AbortController();\n pending = controller;\n batch(() => {\n setDesired(next);\n setError(null);\n });\n if (!force && sameExplorerRequest(next, snapshot().request)) {\n pending = undefined;\n setLoading(false);\n return;\n }\n setLoading(true);\n try {\n const result = await options.load(next, controller.signal);\n if (controller.signal.aborted || pending !== controller) return;\n if (!sameExplorerRequest(result.request, next)) throw new Error(\"Chart response does not match requested filters\");\n validate(result);\n batch(() => adopt(result));\n } catch (cause) {\n if (!controller.signal.aborted && pending === controller)\n setError(() => (cause instanceof Error ? cause : new Error(\"Could not load chart data\", { cause })));\n } finally {\n if (!controller.signal.aborted && pending === controller) {\n setLoading(false);\n pending = undefined;\n }\n }\n };\n createEffect(() => {\n const next = options.snapshot();\n untrack(() => {\n validate(next);\n pending?.abort();\n pending = undefined;\n batch(() => {\n adopt(next);\n setDesired(options.request?.() ?? next.request);\n setLoading(false);\n setError(null);\n });\n });\n });\n createEffect(() => {\n options.snapshot();\n const request = options.request?.();\n if (request)\n untrack(() => {\n void execute(request);\n });\n });\n onCleanup(() => {\n disposed = true;\n pending?.abort();\n });\n const setRequest = (next: ChartExplorerRequest) => {\n validateRequest(next);\n if (!options.request) void execute(next);\n options.onRequestChange?.(next);\n };\n return {\n snapshot,\n desired,\n loading,\n error,\n selectedKey,\n select,\n setRequest,\n /** Force a fresh read of the desired filters, even when nothing changed. */\n refresh: () => execute(options.request?.() ?? desired(), true),\n retry: () => execute(options.request?.() ?? desired(), true),\n pinReference() {\n const step = snapshot().request.step;\n if (step !== undefined) setRequest({ ...desired(), referenceStep: step });\n },\n clearReference() {\n setRequest({ ...desired(), referenceStep: undefined });\n },\n };\n}\n"],"mappings":"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","ignoreList":[]}