@jimka/typescript-ui 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (306) hide show
  1. package/dist/lib/AbstractInput-Dt9ooHjo.js +2 -0
  2. package/dist/lib/AbstractInput-Dt9ooHjo.js.map +1 -0
  3. package/dist/lib/AccordionConstraints-DahZEfEp.js +2 -0
  4. package/dist/lib/AccordionConstraints-DahZEfEp.js.map +1 -0
  5. package/dist/lib/{Anchor-CwRhdP2J.js → Anchor-DdYgyn2V.js} +2 -2
  6. package/dist/lib/{Anchor-CwRhdP2J.js.map → Anchor-DdYgyn2V.js.map} +1 -1
  7. package/dist/lib/AnimatedDropdown-_KhHzX5D.js +2 -0
  8. package/dist/lib/AnimatedDropdown-_KhHzX5D.js.map +1 -0
  9. package/dist/lib/Border-BELbqMDJ.js +2 -0
  10. package/dist/lib/Border-BELbqMDJ.js.map +1 -0
  11. package/dist/lib/Button-CKzjQyqA.js +2 -0
  12. package/dist/lib/Button-CKzjQyqA.js.map +1 -0
  13. package/dist/lib/{Card-QYo27r5b.js → Card-CAp7LcB5.js} +2 -2
  14. package/dist/lib/{Card-QYo27r5b.js.map → Card-CAp7LcB5.js.map} +1 -1
  15. package/dist/lib/Checkbox-CvAZJ4_T.js +2 -0
  16. package/dist/lib/Checkbox-CvAZJ4_T.js.map +1 -0
  17. package/dist/lib/CodeEditor-DoGGdL1Y.js +2 -0
  18. package/dist/lib/CodeEditor-DoGGdL1Y.js.map +1 -0
  19. package/dist/lib/ComboBox-DgjMnpdh.js +2 -0
  20. package/dist/lib/ComboBox-DgjMnpdh.js.map +1 -0
  21. package/dist/lib/Component-YrLXKJZS.js +2 -0
  22. package/dist/lib/Component-YrLXKJZS.js.map +1 -0
  23. package/dist/lib/Container-C5cxnioS.js +2 -0
  24. package/dist/lib/{Container-abY5Ww3W.js.map → Container-C5cxnioS.js.map} +1 -1
  25. package/dist/lib/DOM-DDhDN8lQ.js +2 -0
  26. package/dist/lib/DOM-DDhDN8lQ.js.map +1 -0
  27. package/dist/lib/Diagnostics-MI6Yw-3E.js +2 -0
  28. package/dist/lib/Diagnostics-MI6Yw-3E.js.map +1 -0
  29. package/dist/lib/Dialog-CXQXRQQK.js +2 -0
  30. package/dist/lib/Dialog-CXQXRQQK.js.map +1 -0
  31. package/dist/lib/DragManager-D5pBaPPg.js +2 -0
  32. package/dist/lib/DragManager-D5pBaPPg.js.map +1 -0
  33. package/dist/lib/{FieldDecorator-BlYMfZ9L.js → FieldDecorator-37IgKHHm.js} +2 -2
  34. package/dist/lib/{FieldDecorator-BlYMfZ9L.js.map → FieldDecorator-37IgKHHm.js.map} +1 -1
  35. package/dist/lib/{Fit-BhlB-HAo.js → Fit-amTWlJM2.js} +2 -2
  36. package/dist/lib/{Fit-BhlB-HAo.js.map → Fit-amTWlJM2.js.map} +1 -1
  37. package/dist/lib/{FloatingPanel-DkJXsZ2D.js → FloatingPanel-CwsFPYbc.js} +2 -2
  38. package/dist/lib/{FloatingPanel-DkJXsZ2D.js.map → FloatingPanel-CwsFPYbc.js.map} +1 -1
  39. package/dist/lib/Glyph-Cof7BxfJ.js +2 -0
  40. package/dist/lib/Glyph-Cof7BxfJ.js.map +1 -0
  41. package/dist/lib/{Grid-Daiz7F5d.js → Grid-BQZ4UIUH.js} +2 -2
  42. package/dist/lib/{Grid-Daiz7F5d.js.map → Grid-BQZ4UIUH.js.map} +1 -1
  43. package/dist/lib/GridConstraints-BkXa62z0.js +2 -0
  44. package/dist/lib/GridConstraints-BkXa62z0.js.map +1 -0
  45. package/dist/lib/{Header-Dql3Zxc6.js → Header-Cj33ABP1.js} +2 -2
  46. package/dist/lib/{Header-Dql3Zxc6.js.map → Header-Cj33ABP1.js.map} +1 -1
  47. package/dist/lib/{IconText-PUjhTLlp.js → IconText-Dp64iq_q.js} +2 -2
  48. package/dist/lib/{IconText-PUjhTLlp.js.map → IconText-Dp64iq_q.js.map} +1 -1
  49. package/dist/lib/LabeledGrid-Dpelrc1k.js +2 -0
  50. package/dist/lib/LabeledGrid-Dpelrc1k.js.map +1 -0
  51. package/dist/lib/LayoutSerialization-DgLJSuew.js +2 -0
  52. package/dist/lib/LayoutSerialization-DgLJSuew.js.map +1 -0
  53. package/dist/lib/Link-DE8tE3u3.js +2 -0
  54. package/dist/lib/Link-DE8tE3u3.js.map +1 -0
  55. package/dist/lib/List-TfgHScl3.js +2 -0
  56. package/dist/lib/List-TfgHScl3.js.map +1 -0
  57. package/dist/lib/ListenerBag-DYRl4TSb.js +2 -0
  58. package/dist/lib/ListenerBag-DYRl4TSb.js.map +1 -0
  59. package/dist/lib/{MemoryStore-DhPoU-7X.js → MemoryStore-ByGDEKYI.js} +2 -2
  60. package/dist/lib/{MemoryStore-DhPoU-7X.js.map → MemoryStore-ByGDEKYI.js.map} +1 -1
  61. package/dist/lib/Menu-BCQISKiQ.js +2 -0
  62. package/dist/lib/Menu-BCQISKiQ.js.map +1 -0
  63. package/dist/lib/{MenuButton-DCXi0tsP.js → MenuButton-BO4y3jf2.js} +2 -2
  64. package/dist/lib/{MenuButton-DCXi0tsP.js.map → MenuButton-BO4y3jf2.js.map} +1 -1
  65. package/dist/lib/{OverlayFade-3pof2AJH.js → OverlayFade-C1yQKffL.js} +2 -2
  66. package/dist/lib/{OverlayFade-3pof2AJH.js.map → OverlayFade-C1yQKffL.js.map} +1 -1
  67. package/dist/lib/{Panel-Cy1pdlWO.js → Panel-DlsVVuvn.js} +2 -2
  68. package/dist/lib/{Panel-Cy1pdlWO.js.map → Panel-DlsVVuvn.js.map} +1 -1
  69. package/dist/lib/{Position-BwtxouxK.js → Position-DWR1nIpA.js} +2 -2
  70. package/dist/lib/Position-DWR1nIpA.js.map +1 -0
  71. package/dist/lib/ProgressSpinner-BI9tFIVm.js +2 -0
  72. package/dist/lib/ProgressSpinner-BI9tFIVm.js.map +1 -0
  73. package/dist/lib/RadioButton-BxcuFChp.js +2 -0
  74. package/dist/lib/RadioButton-BxcuFChp.js.map +1 -0
  75. package/dist/lib/RadioMenuRow-B2bthoxj.js +2 -0
  76. package/dist/lib/RadioMenuRow-B2bthoxj.js.map +1 -0
  77. package/dist/lib/{RovingTabIndex-pHEv5oLD.js → RovingTabIndex-BttlsARv.js} +2 -2
  78. package/dist/lib/{RovingTabIndex-pHEv5oLD.js.map → RovingTabIndex-BttlsARv.js.map} +1 -1
  79. package/dist/lib/Scrollbar-orAWHWap.js +2 -0
  80. package/dist/lib/Scrollbar-orAWHWap.js.map +1 -0
  81. package/dist/lib/SelectableText-BbS_lRzY.js +2 -0
  82. package/dist/lib/SelectableText-BbS_lRzY.js.map +1 -0
  83. package/dist/lib/Slider-BvXc-cx5.js +2 -0
  84. package/dist/lib/Slider-BvXc-cx5.js.map +1 -0
  85. package/dist/lib/Spacer-C6faKe1V.js +2 -0
  86. package/dist/lib/Spacer-C6faKe1V.js.map +1 -0
  87. package/dist/lib/StyleTraits-CAtzeyRR.js +2 -0
  88. package/dist/lib/StyleTraits-CAtzeyRR.js.map +1 -0
  89. package/dist/lib/TabButton-BQDaBszs.js +2 -0
  90. package/dist/lib/TabButton-BQDaBszs.js.map +1 -0
  91. package/dist/lib/TabCloseButton-B-iLVPGZ.js +2 -0
  92. package/dist/lib/TabCloseButton-B-iLVPGZ.js.map +1 -0
  93. package/dist/lib/Table-3McEw5gr.js +7 -0
  94. package/dist/lib/Table-3McEw5gr.js.map +1 -0
  95. package/dist/lib/Text-CGFXPhHD.js +2 -0
  96. package/dist/lib/Text-CGFXPhHD.js.map +1 -0
  97. package/dist/lib/Tooltip-DgRHQZhL.js +3 -0
  98. package/dist/lib/Tooltip-DgRHQZhL.js.map +1 -0
  99. package/dist/lib/Tree-Bq2pjjAz.js +2 -0
  100. package/dist/lib/Tree-Bq2pjjAz.js.map +1 -0
  101. package/dist/lib/{VBox-DfJPWXqc.js → VBox-hFIZAEpT.js} +2 -2
  102. package/dist/lib/{VBox-DfJPWXqc.js.map → VBox-hFIZAEpT.js.map} +1 -1
  103. package/dist/lib/{VirtualScroller-DTIn19o1.js → VirtualScroller-Csa3GBSM.js} +2 -2
  104. package/dist/lib/{VirtualScroller-DTIn19o1.js.map → VirtualScroller-Csa3GBSM.js.map} +1 -1
  105. package/dist/lib/Window-CQ14_65z.js +2 -0
  106. package/dist/lib/Window-CQ14_65z.js.map +1 -0
  107. package/dist/lib/component/button.es.js +1 -1
  108. package/dist/lib/component/button.es.js.map +1 -1
  109. package/dist/lib/component/chart.es.js +1 -1
  110. package/dist/lib/component/chart.es.js.map +1 -1
  111. package/dist/lib/component/container.es.js +1 -1
  112. package/dist/lib/component/container.es.js.map +1 -1
  113. package/dist/lib/component/diagram.es.js +1 -1
  114. package/dist/lib/component/diagram.es.js.map +1 -1
  115. package/dist/lib/component/display.es.js +1 -1
  116. package/dist/lib/component/display.es.js.map +1 -1
  117. package/dist/lib/component/editor.es.js +2 -2
  118. package/dist/lib/component/editor.es.js.map +1 -1
  119. package/dist/lib/component/input.es.js +1 -1
  120. package/dist/lib/component/input.es.js.map +1 -1
  121. package/dist/lib/component/list.es.js +1 -1
  122. package/dist/lib/component/list.es.js.map +1 -1
  123. package/dist/lib/component/menubar.es.js +1 -1
  124. package/dist/lib/component/menubar.es.js.map +1 -1
  125. package/dist/lib/component/table.es.js +1 -6
  126. package/dist/lib/component/table.es.js.map +1 -1
  127. package/dist/lib/component/tree.es.js +1 -1
  128. package/dist/lib/component/tree.es.js.map +1 -1
  129. package/dist/lib/core-DpzpKLWE.js +2 -0
  130. package/dist/lib/core-DpzpKLWE.js.map +1 -0
  131. package/dist/lib/core.es.js +1 -2
  132. package/dist/lib/data.es.js +1 -1
  133. package/dist/lib/diagnostics.es.js +24 -0
  134. package/dist/lib/diagnostics.es.js.map +1 -0
  135. package/dist/lib/glyphs/solid/index.es.js +1 -1
  136. package/dist/lib/layout.es.js +1 -1
  137. package/dist/lib/layout.es.js.map +1 -1
  138. package/dist/lib/overlay.es.js +1 -1
  139. package/dist/lib/overlay.es.js.map +1 -1
  140. package/dist/lib/primitive-8YvORgGS.js +2 -0
  141. package/dist/lib/primitive-8YvORgGS.js.map +1 -0
  142. package/dist/lib/primitive.es.js +1 -2
  143. package/dist/lib/router.es.js +1 -1
  144. package/dist/lib/selectionsEqual-DWdW5pxP.js +2 -0
  145. package/dist/lib/{selectionsEqual-gMG7gCVI.js.map → selectionsEqual-DWdW5pxP.js.map} +1 -1
  146. package/dist/lib/types/component/button/Button.d.ts +7 -6
  147. package/dist/lib/types/component/button/TabButton.d.ts +3 -0
  148. package/dist/lib/types/component/button/TabCloseButton.d.ts +3 -0
  149. package/dist/lib/types/component/button/ToggleButton.d.ts +2 -2
  150. package/dist/lib/types/component/chart/AbstractChart.d.ts +2 -0
  151. package/dist/lib/types/component/container/AccordionHeader.d.ts +6 -1
  152. package/dist/lib/types/component/container/AccordionIndicator.d.ts +2 -0
  153. package/dist/lib/types/component/container/FieldSet.d.ts +2 -0
  154. package/dist/lib/types/component/container/LabeledFieldSet.d.ts +1 -1
  155. package/dist/lib/types/component/container/LabeledGrid.d.ts +4 -1
  156. package/dist/lib/types/component/container/Legend.d.ts +2 -2
  157. package/dist/lib/types/component/container/MenuItem.d.ts +1 -0
  158. package/dist/lib/types/component/container/WindowBorder.d.ts +2 -2
  159. package/dist/lib/types/component/container/WindowHeader.d.ts +6 -0
  160. package/dist/lib/types/component/diagram/DiagramEdgeLayer.d.ts +10 -0
  161. package/dist/lib/types/component/diagram/DiagramGroupNode.d.ts +2 -0
  162. package/dist/lib/types/component/diagram/DiagramNode.d.ts +6 -2
  163. package/dist/lib/types/component/diagram/DiagramNodeLayer.d.ts +25 -0
  164. package/dist/lib/types/component/diagram/DiagramResidency.d.ts +11 -0
  165. package/dist/lib/types/component/diagram/DiagramView.d.ts +22 -0
  166. package/dist/lib/types/component/display/Markdown.d.ts +2 -1
  167. package/dist/lib/types/component/input/AbstractCalendarDropdown.d.ts +4 -2
  168. package/dist/lib/types/component/input/AbstractInput.d.ts +1 -0
  169. package/dist/lib/types/component/input/AbstractPickerField.d.ts +4 -0
  170. package/dist/lib/types/component/input/AutoCompleteDropdown.d.ts +2 -0
  171. package/dist/lib/types/component/input/AutoCompleteField.d.ts +1 -0
  172. package/dist/lib/types/component/input/ComboBox.d.ts +6 -1
  173. package/dist/lib/types/component/input/Link.d.ts +2 -0
  174. package/dist/lib/types/component/input/PasswordField.d.ts +2 -0
  175. package/dist/lib/types/component/input/PickerButton.d.ts +5 -2
  176. package/dist/lib/types/component/input/PickerInput.d.ts +2 -0
  177. package/dist/lib/types/component/input/SelectableText.d.ts +11 -0
  178. package/dist/lib/types/component/input/SpinButton.d.ts +3 -0
  179. package/dist/lib/types/component/input/Text.d.ts +12 -2
  180. package/dist/lib/types/component/input/TextArea.d.ts +2 -0
  181. package/dist/lib/types/component/input/TextField.d.ts +2 -0
  182. package/dist/lib/types/component/input/TextInput.d.ts +4 -0
  183. package/dist/lib/types/component/input/TimePickerDropdown.d.ts +3 -1
  184. package/dist/lib/types/component/input/UsernameField.d.ts +2 -0
  185. package/dist/lib/types/component/input/index.d.ts +2 -0
  186. package/dist/lib/types/component/list/AbstractMarkerList.d.ts +2 -0
  187. package/dist/lib/types/component/list/AbstractSelectableList.d.ts +6 -2
  188. package/dist/lib/types/component/list/ListItem.d.ts +2 -1
  189. package/dist/lib/types/component/menubar/MenuBarButton.d.ts +3 -0
  190. package/dist/lib/types/component/menubar/ToolBar.d.ts +2 -0
  191. package/dist/lib/types/component/table/Body.d.ts +54 -20
  192. package/dist/lib/types/component/table/Column.d.ts +2 -0
  193. package/dist/lib/types/component/table/ColumnConfig.d.ts +1 -0
  194. package/dist/lib/types/component/table/Footer.d.ts +2 -0
  195. package/dist/lib/types/component/table/Header.d.ts +8 -1
  196. package/dist/lib/types/component/table/Row.d.ts +22 -2
  197. package/dist/lib/types/component/table/Table.d.ts +6 -1
  198. package/dist/lib/types/component/table/TableExporter.d.ts +3 -0
  199. package/dist/lib/types/component/table/TablePanel.d.ts +6 -0
  200. package/dist/lib/types/component/table/TreeTablePanel.d.ts +6 -0
  201. package/dist/lib/types/component/table/cell/Cell.d.ts +8 -2
  202. package/dist/lib/types/component/table/cell/Default.d.ts +1 -1
  203. package/dist/lib/types/component/table/cell/Header.d.ts +4 -0
  204. package/dist/lib/types/component/table/cell/ParentHeader.d.ts +4 -0
  205. package/dist/lib/types/component/table/cell/ResizeHandle.d.ts +1 -1
  206. package/dist/lib/types/component/table/cell/renderer/CellRenderer.d.ts +2 -2
  207. package/dist/lib/types/component/table/cell/renderer/String.d.ts +3 -1
  208. package/dist/lib/types/component/table/index.d.ts +1 -1
  209. package/dist/lib/types/component/tree/TreeRow.d.ts +2 -0
  210. package/dist/lib/types/core/AnimatedDropdown.d.ts +2 -0
  211. package/dist/lib/types/core/Binding.d.ts +1 -0
  212. package/dist/lib/types/core/ClassStyleRules.d.ts +69 -4
  213. package/dist/lib/types/core/Component.d.ts +69 -14
  214. package/dist/lib/types/core/DOM.d.ts +11 -1
  215. package/dist/lib/types/core/Diagnostics.d.ts +22 -0
  216. package/dist/lib/types/core/Event.d.ts +7 -0
  217. package/dist/lib/types/core/LayerManager.d.ts +3 -0
  218. package/dist/lib/types/core/ListenerBag.d.ts +1 -0
  219. package/dist/lib/types/core/StyleTarget.d.ts +14 -0
  220. package/dist/lib/types/core/StyleTraits.d.ts +4 -0
  221. package/dist/lib/types/core/Theme.d.ts +6 -2
  222. package/dist/lib/types/core/Util.d.ts +4 -0
  223. package/dist/lib/types/core/index.d.ts +6 -3
  224. package/dist/lib/types/diagnostics/DiagnosticsOverlay.d.ts +29 -0
  225. package/dist/lib/types/diagnostics/DiagnosticsSampler.d.ts +61 -0
  226. package/dist/lib/types/diagnostics/StyleAudit.d.ts +19 -0
  227. package/dist/lib/types/diagnostics/StyleAuditOverlay.d.ts +12 -0
  228. package/dist/lib/types/diagnostics/StyleAuditView.d.ts +13 -0
  229. package/dist/lib/types/diagnostics/index.d.ts +7 -0
  230. package/dist/lib/types/layout/LayoutManager.d.ts +3 -0
  231. package/dist/lib/types/layout/Table.d.ts +3 -0
  232. package/dist/lib/types/overlay/AbstractWindow.d.ts +36 -0
  233. package/dist/lib/types/overlay/ButtonGroup.d.ts +1 -0
  234. package/dist/lib/types/overlay/Dialog.d.ts +1 -0
  235. package/dist/lib/types/overlay/Menu.d.ts +2 -0
  236. package/dist/lib/types/overlay/Notification.d.ts +0 -1
  237. package/dist/lib/types/overlay/PopupPanel.d.ts +2 -0
  238. package/dist/lib/types/overlay/RailHandle.d.ts +4 -5
  239. package/dist/lib/types/overlay/TabWindow.d.ts +3 -0
  240. package/dist/lib/types/overlay/Tooltip.d.ts +1 -0
  241. package/dist/lib/types/overlay/Window.d.ts +4 -1
  242. package/dist/lib/validation.es.js +1 -1
  243. package/llms.txt +2 -0
  244. package/package.json +5 -1
  245. package/dist/lib/AbstractInput-sRNPzWel.js +0 -2
  246. package/dist/lib/AbstractInput-sRNPzWel.js.map +0 -1
  247. package/dist/lib/AnimatedDropdown-H3Rh-YMZ.js +0 -2
  248. package/dist/lib/AnimatedDropdown-H3Rh-YMZ.js.map +0 -1
  249. package/dist/lib/Border-0DJFDiij.js +0 -2
  250. package/dist/lib/Border-0DJFDiij.js.map +0 -1
  251. package/dist/lib/Button-MpMIYBYJ.js +0 -2
  252. package/dist/lib/Button-MpMIYBYJ.js.map +0 -1
  253. package/dist/lib/Checkbox-D0JYK-wc.js +0 -2
  254. package/dist/lib/Checkbox-D0JYK-wc.js.map +0 -1
  255. package/dist/lib/CheckboxMenuRow-CesLhSnp.js +0 -2
  256. package/dist/lib/CheckboxMenuRow-CesLhSnp.js.map +0 -1
  257. package/dist/lib/CodeEditor-N1FQodcF.js +0 -2
  258. package/dist/lib/CodeEditor-N1FQodcF.js.map +0 -1
  259. package/dist/lib/ComboBox-Dx8Tk9yg.js +0 -2
  260. package/dist/lib/ComboBox-Dx8Tk9yg.js.map +0 -1
  261. package/dist/lib/Component-B0ShfPVi.js +0 -2
  262. package/dist/lib/Component-B0ShfPVi.js.map +0 -1
  263. package/dist/lib/Container-abY5Ww3W.js +0 -2
  264. package/dist/lib/DOM-C-Edb3tA.js +0 -2
  265. package/dist/lib/DOM-C-Edb3tA.js.map +0 -1
  266. package/dist/lib/Dialog-cbA9V17e.js +0 -2
  267. package/dist/lib/Dialog-cbA9V17e.js.map +0 -1
  268. package/dist/lib/Glyph-_VeBacS2.js +0 -2
  269. package/dist/lib/Glyph-_VeBacS2.js.map +0 -1
  270. package/dist/lib/GridConstraints-C58LuTqM.js +0 -2
  271. package/dist/lib/GridConstraints-C58LuTqM.js.map +0 -1
  272. package/dist/lib/LayoutSerialization-CMxunLfV.js +0 -2
  273. package/dist/lib/LayoutSerialization-CMxunLfV.js.map +0 -1
  274. package/dist/lib/List-nx8220Fi.js +0 -2
  275. package/dist/lib/List-nx8220Fi.js.map +0 -1
  276. package/dist/lib/ListenerBag-WPdKuuds.js +0 -2
  277. package/dist/lib/ListenerBag-WPdKuuds.js.map +0 -1
  278. package/dist/lib/Menu-Q0bpXXze.js +0 -2
  279. package/dist/lib/Menu-Q0bpXXze.js.map +0 -1
  280. package/dist/lib/Position-BwtxouxK.js.map +0 -1
  281. package/dist/lib/ProgressSpinner-DK8xEQ9y.js +0 -2
  282. package/dist/lib/ProgressSpinner-DK8xEQ9y.js.map +0 -1
  283. package/dist/lib/RadioButton-BEwpqg1k.js +0 -2
  284. package/dist/lib/RadioButton-BEwpqg1k.js.map +0 -1
  285. package/dist/lib/RadioMenuRow-DP5qPyFR.js +0 -2
  286. package/dist/lib/RadioMenuRow-DP5qPyFR.js.map +0 -1
  287. package/dist/lib/Scrollbar-t8fFrUVQ.js +0 -2
  288. package/dist/lib/Scrollbar-t8fFrUVQ.js.map +0 -1
  289. package/dist/lib/Slider-CTbwR6HR.js +0 -2
  290. package/dist/lib/Slider-CTbwR6HR.js.map +0 -1
  291. package/dist/lib/Spacer-srdN2d2b.js +0 -2
  292. package/dist/lib/Spacer-srdN2d2b.js.map +0 -1
  293. package/dist/lib/TabButton-DLoMQzky.js +0 -2
  294. package/dist/lib/TabButton-DLoMQzky.js.map +0 -1
  295. package/dist/lib/TabCloseButton-CY7BGitY.js +0 -2
  296. package/dist/lib/TabCloseButton-CY7BGitY.js.map +0 -1
  297. package/dist/lib/Text-CMKnK9uB.js +0 -2
  298. package/dist/lib/Text-CMKnK9uB.js.map +0 -1
  299. package/dist/lib/Tooltip-CUOJOqQi.js +0 -3
  300. package/dist/lib/Tooltip-CUOJOqQi.js.map +0 -1
  301. package/dist/lib/Tree-C64JNPWJ.js +0 -2
  302. package/dist/lib/Tree-C64JNPWJ.js.map +0 -1
  303. package/dist/lib/core.es.js.map +0 -1
  304. package/dist/lib/primitive.es.js.map +0 -1
  305. package/dist/lib/selectionsEqual-gMG7gCVI.js +0 -2
  306. package/dist/lib/types/component/table/CellGeometry.d.ts +0 -6
@@ -1 +0,0 @@
1
- {"version":3,"file":"Dialog-cbA9V17e.js","names":[],"sources":["../../src/typescript/lib/overlay/Popover.ts","../../src/typescript/lib/component/container/DialogBackdrop.ts","../../src/typescript/lib/overlay/Dialog.ts"],"sourcesContent":["// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component } from \"~/core/Component.js\";\nimport { Event } from \"~/core/Event.js\";\nimport { LayerManager, DismissableLayer, LayerDismissMode } from \"~/core/LayerManager.js\";\nimport { trapWheel, untrapWheel } from \"~/core/WheelTrap.js\";\nimport { Util } from \"~/core/Util.js\";\nimport { fadeShow, fadeHideAndDetach } from \"~/core/OverlayFade.js\";\nimport type { Animation } from \"~/core/Animation.js\";\nimport { Container, ContainerOptions } from \"~/core/Container.js\";\nimport type { Edge } from \"~/primitive/Edge.js\";\nimport { Position } from \"~/primitive/Position.js\";\nimport { Insets } from \"~/primitive/Insets.js\";\nimport { VBox } from \"~/layout/VBox.js\";\nimport { HBox } from \"~/layout/HBox.js\";\nimport { Text } from \"~/component/input/Text.js\";\nimport { Button } from \"~/component/button/Button.js\";\nimport { callable } from \"~/core/Callable.js\";\nimport { DOM, type Rect, type Handle } from \"~/core/DOM.js\";\n\n/** Fallback arrow side length used until the theme token is read. */\nconst DEFAULT_ARROW_SIZE_PX: number = 14;\n\n/**\n * Half of the visual extent of the rotated arrow along either axis. The\n * arrow is a square of side `DEFAULT_ARROW_SIZE_PX` rotated 45°, so its\n * bounding rectangle is `DEFAULT_ARROW_SIZE_PX * sqrt(2)` on each side and\n * each corner sits half that far from the centre.\n */\nconst ARROW_VISUAL_HALF: number = (DEFAULT_ARROW_SIZE_PX / 2) * Math.SQRT2;\n\n/** Pixel gap between the arrow tip and the anchor element. */\nconst ARROW_ANCHOR_GAP_PX: number = 2;\n\n/**\n * Pixel gap between the popover edge and the anchor element. Sized so the\n * arrow tip lands {@link ARROW_ANCHOR_GAP_PX} away from the anchor.\n */\nconst POPOVER_ANCHOR_GAP: number = Math.ceil(ARROW_VISUAL_HALF) + ARROW_ANCHOR_GAP_PX;\n\n/** Pixel inset preserved between the arrow and the popover corner. */\nconst ARROW_EDGE_INSET_PX: number = 6;\n\n/** Pixel inset preserved between the arrow / popover and any viewport edge. */\nconst VIEWPORT_EDGE_INSET_PX: number = 5;\n\n/** Fade duration matched to the rest of the floating-overlay family. */\nconst POPOVER_FADE_DURATION_MS: number = 120;\n\n/**\n * Placement of a {@link Popover} relative to its anchor element. `\"auto\"`\n * picks the side with the most viewport space at `show()` time.\n *\n * @category Core\n */\nexport type PopoverPlacement = Edge | \"auto\";\n\n/**\n * Strategy used to dismiss a {@link Popover}:\n *\n * - `\"click-outside\"`: closes on a `pointerdown` outside both the popover and\n * its anchor element (the anchor is excluded so the trigger click can\n * re-open without immediate re-close).\n * - `\"blur\"`: closes when focus or a pointer leaves the popover subtree —\n * including a portaled descendant layer such as a dropdown opened inside\n * the popover, which now keeps the popover open.\n * - `\"manual\"`: caller drives `hide()` explicitly.\n *\n * @remarks Dismissal is executed by {@link LayerManager}: the popover reports\n * this mode from its {@link DismissableLayer.getDismissMode} and the manager's\n * document-level handlers decide when to call `requestClose`. This is the\n * public option name; it maps 1:1 onto {@link LayerDismissMode}.\n *\n * @category Core\n */\nexport type PopoverDismissMode = \"click-outside\" | \"blur\" | \"manual\";\n\n/**\n * Construction-time options for {@link Popover}.\n *\n * @category Core\n */\nexport interface PopoverOptions extends ContainerOptions {\n /** Resolved placement relative to the anchor. Default `\"auto\"`. */\n placement?: PopoverPlacement;\n /** Dismiss strategy. Default `\"click-outside\"`. */\n dismissOn?: PopoverDismissMode;\n /** When `false`, the arrow tail is not rendered. Default `true`. */\n showArrow?: boolean;\n /** Optional title row rendered above the body. */\n title?: string;\n /** Callback invoked once whenever the popover closes, for any reason\n * (an explicit `hide()` or an outside-click `requestClose()`). Mirrors\n * [`Menu`](/api/overlay/classes/Menu)'s persistent-mode `onClose`. */\n onClose?: () => void;\n}\n\n/**\n * User-overridable visual defaults forwarded to `super` via the options bag.\n * The cascade in `Component`'s constructor dispatches each present setter once\n * with the final value, so any field the caller supplied wins.\n */\nconst _defaultPopoverOptions: Partial<PopoverOptions> = {\n insets: new Insets(5, 5, 5, 5),\n placement: \"auto\",\n dismissOn: \"click-outside\",\n showArrow: true,\n backgroundColor: \"var(--ts-ui-popover-bg, rgb(255, 255, 255))\",\n foregroundColor: \"var(--ts-ui-popover-color, rgb(0, 0, 0))\",\n // Theme-driven chrome.\n border: { border: \"1px solid var(--ts-ui-popover-border, rgb(200, 200, 200))\" },\n borderRadius: \"var(--ts-ui-popover-radius, 6px)\",\n shadow: \"var(--ts-ui-popover-shadow, 2px 4px 12px rgba(0, 0, 0, 0.18))\",\n};\n\n/**\n * An anchored, non-modal floating bubble with a directional arrow tail. Use\n * `Popover` for click-triggered, interactive content (title, body, action\n * buttons, or any arbitrary subtree) — for ephemeral hover hints reach for\n * [`Tooltip`](/api/overlay/classes/Tooltip), and for modal containment reach\n * for [`Dialog`](/api/overlay/classes/Dialog).\n *\n * `Popover` extends {@link Container} so authors can compose freely via\n * `addComponent`; the `setTitle` / `setBody` / `addAction` conveniences are\n * sugar over the same container surface.\n *\n * Positioning is anchor-relative. `attachToComponent(Component)` records the\n * anchor. While the popover is open, `window` `resize` and each scrollable\n * ancestor's `scroll` event trigger a reposition so the bubble follows the\n * anchor.\n *\n * Fade-in / fade-out reuse the shared [`fadeShow`](/api/core/functions/fadeShow)\n * and [`fadeHideAndDetach`](/api/core/functions/fadeHideAndDetach) helpers,\n * inheriting the standard 120 ms `opacity + translateY` transition and the\n * re-entrancy guard against a fresh `show()` mid-fade.\n *\n * @example\n * ```typescript\n * const popover = new Popover({ placement: \"auto\" });\n * popover.setTitle(\"Confirm delete\");\n * popover.setBody(\"This action cannot be undone.\");\n * popover.addAction(\"Delete\", () => doDelete());\n * popover.addAction(\"Cancel\", () => popover.hide());\n *\n * Event.addListener(triggerButton, \"click\", () => {\n * popover.attachToComponent(triggerButton);\n * popover.show();\n * });\n * ```\n *\n * @category Core\n */\nclass Popover extends Container<PopoverOptions> implements DismissableLayer {\n\n // Option-backed fields use `declare` rather than initializers to dodge the\n // class-field super-cascade trap: an initializer runs *after* super()\n // returns, overwriting whatever the cascade-dispatched setter wrote\n // during the super-time `applyOptions` call. The applyOptions override\n // below always dispatches each setter with a fallback so the field is\n // seeded even when no caller option was supplied.\n declare private _placement: PopoverPlacement;\n private _resolvedPlacement: PopoverPlacement = \"bottom\";\n declare private _dismissOn: PopoverDismissMode;\n declare private _showArrow: boolean;\n declare private _title: string | null;\n declare private _titleComponent: Text | null;\n declare private _onClose: (() => void) | null;\n private _bodyComponent: Component | null = null;\n private _actionsRow: Component | null = null;\n\n // In-flight fades, cancelled on teardown so their fallback timers cannot\n // fire against this popover's released element handle.\n private _fadeShowAnimation: Animation.CancelHandle | null = null;\n private _fadeHideAnimation: Animation.CancelHandle | null = null;\n private _anchorElement: Handle | null = null;\n private _arrowComponent: Component | null = null;\n private _isOpen: boolean = false;\n private _scrollAncestors: Handle[] = [];\n\n private readonly _onWindowResize: () => void;\n private readonly _onScroll: () => void;\n\n /**\n * Creates a popover with a 5px layout-side inset and the default chrome\n * wired to the theme tokens.\n *\n * @param options - Optional construction-time options.\n * @param subclassDefaults - Per-subclass default bag layered over this\n * class's defaults; subclasses forward their `_defaultXxxOptions`\n * constant here.\n */\n constructor(options?: PopoverOptions, subclassDefaults?: Partial<PopoverOptions>) {\n super(options as PopoverOptions, { ..._defaultPopoverOptions, ...(subclassDefaults ?? {}) });\n\n const vbox = new VBox();\n\n vbox.setStretching(true);\n this.setLayoutManager(vbox);\n\n // Overlay placement: top-level, viewport-fixed. The z-index is\n // stamped from LayerManager's Popover band at show() time, so no\n // static value is set here.\n this.setPosition(Position.FIXED);\n this.setVisible(false);\n\n // `paint` containment would clip the arrow tail (which straddles the\n // popover edge), so use `layout` containment only. The framework\n // default `overflow: hidden` would also clip the arrow, so opt out.\n this.setContain(\"layout\");\n this.setOverflow(\"visible\");\n this.getAria().setRole(\"dialog\");\n\n this._onWindowResize = () => this._reposition();\n this._onScroll = () => this._reposition();\n\n // Seed the `declare`-d title/onClose fields after the cascade has had\n // its chance to write them via setTitle / applyOptions. Without a\n // `title` (or `onClose`) option the cascade dispatch above skips\n // writing it entirely, so the field would otherwise remain undefined\n // (declare allocates no default).\n this._title ??= null;\n this._titleComponent ??= null;\n this._onClose ??= null;\n }\n\n /**\n * Applies a {@link PopoverOptions} bag, dispatching popover-specific\n * fields after the inherited Container cascade.\n *\n * @param options - The options bag carrying the values to apply.\n * @returns This popover, for method chaining.\n */\n protected applyOptions(options: PopoverOptions): this {\n super.applyOptions(options);\n\n // placement/dismissOn/showArrow carry a class default and seed\n // construction-time state, so always dispatch the caller value or the\n // class default; title has no default.\n this.setPlacement(options.placement ?? this.getPlacement());\n this.setDismissOn(options.dismissOn ?? this.getDismissOn());\n this.setShowArrow(options.showArrow ?? this.isShowArrow());\n if (options.title !== undefined) this.setTitle(options.title);\n // onClose has no setter (it's a plain callback, not a rendered/\n // resolvable field), so it's assigned directly, same as title has no\n // class default to fall back to.\n if (options.onClose !== undefined) this._onClose = options.onClose;\n\n return this;\n }\n\n /**\n * Sets the requested placement relative to the anchor.\n *\n * @param p - One of `\"top\"`, `\"bottom\"`, `\"left\"`, `\"right\"`, or `\"auto\"`.\n * @returns This popover, for method chaining.\n */\n setPlacement(p: PopoverPlacement): this {\n this._placement = p;\n\n return this;\n }\n\n /**\n * Returns the configured placement.\n *\n * @returns The placement set via {@link setPlacement}, or `\"auto\"` by default.\n */\n getPlacement(): PopoverPlacement {\n return this._placement ?? this._defaultOptions.placement!;\n }\n\n /**\n * Sets the dismiss strategy.\n *\n * @param mode - One of `\"click-outside\"`, `\"blur\"`, or `\"manual\"`.\n * @returns This popover, for method chaining.\n */\n setDismissOn(mode: PopoverDismissMode): this {\n this._dismissOn = mode;\n\n return this;\n }\n\n /**\n * Returns the active dismiss strategy.\n *\n * @returns The dismiss strategy set via {@link setDismissOn}.\n */\n getDismissOn(): PopoverDismissMode {\n return this._dismissOn ?? this._defaultOptions.dismissOn!;\n }\n\n /**\n * Enables or disables the arrow tail.\n *\n * @param value - `true` to render the arrow, `false` to hide it.\n * @returns This popover, for method chaining.\n */\n setShowArrow(value: boolean): this {\n this._showArrow = value;\n\n if (this._arrowComponent) {\n this._arrowComponent.setVisible(value);\n }\n\n return this;\n }\n\n /**\n * Returns whether the arrow tail is currently enabled.\n *\n * @returns `true` if the arrow is rendered.\n */\n isShowArrow(): boolean {\n return this._showArrow ?? this._defaultOptions.showArrow!;\n }\n\n /**\n * Sets the title row text. Lazily creates the underlying\n * [`Text`](/api/component/input/classes/Text) child on first call. Passing\n * `null` clears the title.\n *\n * @param text - The title string, or `null` to clear.\n * @returns This popover, for method chaining.\n */\n setTitle(text: string | null): this {\n if (text === null) {\n return this.clearTitle();\n }\n\n this._title = text;\n\n if (!this._titleComponent) {\n this._titleComponent = new Text(text);\n this._titleComponent.setFontWeight(\"bold\");\n\n this.insertComponent(this._titleComponent, 0);\n } else {\n this._titleComponent.setText(text);\n }\n\n this._reflowIfOpen();\n\n return this;\n }\n\n /**\n * Returns the current title string, or `null` if no title is set.\n *\n * @returns The title set via {@link setTitle}, or `null`.\n */\n getTitle(): string | null {\n return this._title;\n }\n\n /**\n * Removes the title row.\n *\n * @returns This popover, for method chaining.\n */\n clearTitle(): this {\n if (this._titleComponent) {\n this.removeComponent(this._titleComponent);\n this._titleComponent = null;\n }\n\n this._title = null;\n\n this._reflowIfOpen();\n\n return this;\n }\n\n /**\n * Sets the body content. A `string` is wrapped in a\n * [`Text`](/api/component/input/classes/Text) child; a `Component` is used\n * directly. Replaces any previous body.\n *\n * @param content - The body string or component.\n * @returns This popover, for method chaining.\n */\n setBody(content: Component | string): this {\n if (this._bodyComponent) {\n this.removeComponent(this._bodyComponent);\n this._bodyComponent = null;\n }\n\n const next: Component = typeof content === \"string\"\n ? new Text(content)\n : content;\n\n this._bodyComponent = next;\n\n // Insert after the title (if any) and before the actions row (if any).\n const titleOffset = this._titleComponent ? 1 : 0;\n\n this.insertComponent(next, titleOffset);\n\n this._reflowIfOpen();\n\n return this;\n }\n\n /**\n * Returns the current body component, or `null` when none has been set.\n *\n * @returns The body component, or `null`.\n */\n getBody(): Component | null {\n return this._bodyComponent;\n }\n\n /**\n * Appends an action button to the actions row. Lazily creates the row\n * (an [`HBox`](/api/layout/classes/HBox)-laid `Panel`) on first call.\n *\n * @param label - The button label.\n * @param onClick - Handler invoked when the button is activated.\n * @returns This popover, for method chaining.\n */\n addAction(label: string, onClick: () => void): this {\n if (!this._actionsRow) {\n this._actionsRow = new Component();\n this._actionsRow.setLayoutManager(new HBox());\n\n this.addComponent(this._actionsRow);\n }\n\n const button = new Button(label);\n\n button.on(\"action\", onClick);\n\n this._actionsRow.addComponent(button);\n\n return this;\n }\n\n /**\n * Removes every action button previously registered via {@link addAction}.\n *\n * @returns This popover, for method chaining.\n */\n clearActions(): this {\n if (this._actionsRow) {\n this.removeComponent(this._actionsRow);\n this._actionsRow = null;\n }\n\n return this;\n }\n\n /**\n * Records the raw DOM element used as the positioning anchor.\n *\n * @param el - The anchor element.\n * @returns This popover, for method chaining.\n */\n private _attachToElement(el: Handle): this {\n this._anchorElement = el;\n\n return this;\n }\n\n /**\n * Records the anchor by resolving the given component's element. Must be\n * called before {@link Popover.show}.\n *\n * @param c - The component whose element should be used as the anchor.\n * @returns This popover, for method chaining.\n */\n attachToComponent(c: Component): this {\n return this._attachToElement(c.getElement(true)!);\n }\n\n /**\n * Mounts the popover on `document.documentElement` (if not already\n * mounted), resolves the final placement, positions the bubble + arrow,\n * fades it in, and wires the dismiss listeners.\n *\n * @returns This popover, for method chaining.\n */\n show(): this {\n if (!this._anchorElement) {\n console.warn(\"Popover.show(): no anchor attached; call attachToComponent first.\");\n return this;\n }\n\n this._isOpen = true;\n\n // Join the central layer tree and mirror its band-based z-stamp so a\n // popover opened from inside a window or dropdown stacks correctly.\n LayerManager.register(this);\n this.setZIndex(LayerManager.getZIndex(this));\n\n const el = this.getElement(true)!;\n\n LayerManager.mount(el);\n\n // Trap wheels no inner scroller claimed so they cannot fall through to\n // scrollable content behind the popover.\n trapWheel(this);\n\n this.ensureArrow();\n this.setVisible(true);\n\n // First measurement pass: compute preferred size so we can resolve\n // placement against the real bubble dimensions.\n this.doLayout();\n this._reposition();\n\n this._fadeShowAnimation?.cancel();\n this._fadeShowAnimation = fadeShow(this, { durationMs: POPOVER_FADE_DURATION_MS });\n\n this.attachRepositionListeners();\n\n return this;\n }\n\n /**\n * Plays the exit fade, detaches the popover from the DOM, removes every\n * dismiss / reposition listener, and fires `onClose` (if configured)\n * once for this open→close transition.\n *\n * @returns This popover, for method chaining.\n */\n hide(): this {\n if (!this._isOpen) {\n return this;\n }\n\n this._isOpen = false;\n\n this.detachRepositionListeners();\n\n LayerManager.unregister(this);\n untrapWheel(this);\n\n this._fadeHideAnimation?.cancel();\n this._fadeHideAnimation = fadeHideAndDetach(this, { durationMs: POPOVER_FADE_DURATION_MS });\n\n // The `_isOpen` guard above already makes this method run at most\n // once per open→close transition, so `onClose` needs no separate\n // re-entrancy guard of its own.\n this._onClose?.();\n\n return this;\n }\n\n /**\n * Returns whether the popover is currently open (showing or fading in).\n *\n * @returns `true` when the popover is open.\n */\n isOpen(): boolean {\n return this._isOpen;\n }\n\n // ----- DismissableLayer -----\n\n /**\n * Returns the popover's root element for the central layer tree.\n *\n * @returns The popover's element, or null when not yet rendered.\n */\n getLayerElement(): Handle | null {\n return this.getElement() ?? null;\n }\n\n /**\n * Returns the dismiss mode the document-level handlers consult, mapping\n * the public {@link PopoverDismissMode} directly onto the manager's\n * vocabulary (the two share the `\"click-outside\"` / `\"blur\"` / `\"manual\"`\n * names). The manager now executes dismissal; the `\"blur\"` mode works for\n * a nested dropdown because the dropdown registers as the popover's child.\n *\n * @returns The layer dismiss mode.\n */\n getDismissMode(): LayerDismissMode {\n return this._dismissOn ?? this._defaultOptions.dismissOn!;\n }\n\n /**\n * Advisory close request from the manager — runs the standard\n * {@link Popover.hide} teardown, which unregisters the layer.\n */\n requestClose(): void {\n this.hide();\n }\n\n /**\n * Returns the anchor element excluded from outside-interaction tests so a\n * click on the trigger does not immediately re-close the popover.\n *\n * @returns The anchor element, or null when none is attached.\n */\n getAnchorElement(): Handle | null {\n return this._anchorElement;\n }\n\n /**\n * Returns the popover's z-index band so an unrelated top-level popover\n * stacks above windows but below dropdowns and dialogs.\n *\n * @returns The popover band base.\n */\n getBand(): number {\n return LayerManager.Band.Popover;\n }\n\n /**\n * Lays out children (delegating to the VBox) and positions the arrow\n * tail along the resolved edge.\n *\n * @returns This popover, for method chaining.\n */\n doLayout(): this {\n super.doLayout();\n\n if (this._arrowComponent && this._showArrow && this._anchorElement) {\n this.positionArrow();\n }\n\n return this;\n }\n\n /**\n * Releases per-instance resources. Closes the popover if it is still\n * open, disposes the raw-appended arrow, then defers to the base class\n * for the rest of teardown.\n */\n protected destructor(): void {\n if (this._isOpen) {\n this.hide();\n }\n\n // `_titleComponent` / `_bodyComponent` / `_actionsRow` are all\n // registered via `insertComponent` / `addComponent`, so\n // `super.destructor()`'s child recursion below already disposes\n // them — an explicit call here would run each one's destructor()\n // a second time. `_arrowComponent`, by contrast, is inserted\n // straight into the DOM via `ensureArrow()` (not registered in\n // `_components`), so recursion can never reach it and it must be\n // disposed explicitly.\n // After `hide()` above, since that starts a fresh fade-out whose\n // fallback timer would otherwise outlive the element handle\n // `super.destructor()` releases below.\n this._fadeShowAnimation?.cancel();\n this._fadeShowAnimation = null;\n this._fadeHideAnimation?.cancel();\n this._fadeHideAnimation = null;\n\n this._arrowComponent?.dispose();\n\n this._anchorElement = null;\n this._titleComponent = null;\n this._bodyComponent = null;\n this._actionsRow = null;\n this._arrowComponent = null;\n this._onClose = null;\n\n super.destructor();\n }\n\n /**\n * Re-measures and repositions the popover after a content mutation\n * (`setTitle` / `clearTitle` / `setBody`) — but only while the popover is\n * currently shown. `insertComponent` / `removeComponent` only *schedule*\n * a layout pass (next animation frame), so without this the bubble keeps\n * its old preferred size — and stays anchored at the old `x`/`y` derived\n * from it — until an unrelated `window` resize or ancestor scroll happens\n * to run `_reposition()` next. Mirrors the same \"measure, then position\"\n * pair `show()` runs on first open. A no-op before the first `show()`,\n * matching every other content setter's tolerance for being called on an\n * unshown popover.\n */\n private _reflowIfOpen(): void {\n if (!this._isOpen) {\n return;\n }\n\n this.doLayout();\n this._reposition();\n }\n\n /**\n * Resolves the requested placement against the viewport, anchor rect, and\n * own preferred size; updates the popover's `setX` / `setY` and the\n * resolved-placement field.\n */\n private _reposition(): void {\n if (!this._anchorElement) {\n return;\n }\n\n const anchorRect = DOM.source.getElementRect(this._anchorElement);\n\n // Anchor removed from the DOM or rendered with zero size — close.\n if (anchorRect.width === 0 && anchorRect.height === 0) {\n this.hide();\n return;\n }\n\n const preferred = this.getPreferredSize();\n const width = preferred?.width ?? this.getWidth();\n const height = preferred?.height ?? this.getHeight();\n const vp = DOM.source.getViewportSize();\n\n const resolved = this.resolvePlacement(anchorRect, width, height, vp);\n\n this._resolvedPlacement = resolved;\n\n let x: number = 0;\n let y: number = 0;\n\n if (resolved === \"top\") {\n x = anchorRect.left + (anchorRect.width - width) / 2;\n y = anchorRect.top - height - POPOVER_ANCHOR_GAP;\n } else if (resolved === \"bottom\") {\n x = anchorRect.left + (anchorRect.width - width) / 2;\n y = anchorRect.bottom + POPOVER_ANCHOR_GAP;\n } else if (resolved === \"left\") {\n x = anchorRect.left - width - POPOVER_ANCHOR_GAP;\n y = anchorRect.top + (anchorRect.height - height) / 2;\n } else { // \"right\"\n x = anchorRect.right + POPOVER_ANCHOR_GAP;\n y = anchorRect.top + (anchorRect.height - height) / 2;\n }\n\n // Clamp into viewport so the bubble stays on-screen. The arrow's\n // independent positioning keeps it pointing at the anchor centre\n // even when the bubble is shifted laterally. On the tip-direction\n // side, leave room for the arrow's outward visual extent so the tip\n // also stays at least VIEWPORT_EDGE_INSET_PX inside the viewport.\n let minX = VIEWPORT_EDGE_INSET_PX;\n let maxX = vp.width - width - VIEWPORT_EDGE_INSET_PX;\n let minY = VIEWPORT_EDGE_INSET_PX;\n let maxY = vp.height - height - VIEWPORT_EDGE_INSET_PX;\n\n if (resolved === \"right\") {\n minX += ARROW_VISUAL_HALF;\n } else if (resolved === \"left\") {\n maxX -= ARROW_VISUAL_HALF;\n } else if (resolved === \"bottom\") {\n minY += ARROW_VISUAL_HALF;\n } else {\n maxY -= ARROW_VISUAL_HALF;\n }\n\n x = Util.clamp(x, minX, maxX);\n y = Util.clamp(y, minY, maxY);\n\n this.setX(x);\n this.setY(y);\n this.setWidth(width);\n this.setHeight(height);\n\n if (this._arrowComponent && this._showArrow) {\n this.positionArrow();\n }\n }\n\n /**\n * Picks the placement to use given the configured value and the available\n * viewport space. `\"auto\"` selects the side with the most room; an\n * explicit side is honoured unless it would overflow, in which case the\n * opposite side is used and a console warning is logged.\n *\n * @param anchor - The anchor's `DOMRect`.\n * @param width - The popover's preferred width in pixels.\n * @param height - The popover's preferred height in pixels.\n * @param vp - The viewport size returned by `DOM.source.getViewportSize`.\n * @returns The resolved placement.\n */\n private resolvePlacement(\n anchor: Rect,\n width: number,\n height: number,\n vp: { width: number; height: number },\n ): PopoverPlacement {\n const spaceTop = anchor.top;\n const spaceBottom = vp.height - anchor.bottom;\n const spaceLeft = anchor.left;\n const spaceRight = vp.width - anchor.right;\n\n if (this._placement === \"auto\") {\n const needsH = height + POPOVER_ANCHOR_GAP;\n const needsV = width + POPOVER_ANCHOR_GAP;\n\n const candidates: Array<{ side: PopoverPlacement; space: number; need: number }> = [\n { side: \"bottom\", space: spaceBottom, need: needsH },\n { side: \"top\", space: spaceTop, need: needsH },\n { side: \"right\", space: spaceRight, need: needsV },\n { side: \"left\", space: spaceLeft, need: needsV },\n ];\n\n // Prefer a side that physically fits; otherwise pick the one\n // with the most absolute space.\n const fitting = candidates.filter(c => c.space >= c.need);\n const pool = fitting.length > 0 ? fitting : candidates;\n\n pool.sort((a, b) => b.space - a.space);\n\n return pool[0].side;\n }\n\n // Explicit placement — honour unless the requested side cannot fit.\n const fits = (side: PopoverPlacement): boolean => {\n if (side === \"top\") { return spaceTop >= height + POPOVER_ANCHOR_GAP; }\n if (side === \"bottom\") { return spaceBottom >= height + POPOVER_ANCHOR_GAP; }\n if (side === \"left\") { return spaceLeft >= width + POPOVER_ANCHOR_GAP; }\n\n return spaceRight >= width + POPOVER_ANCHOR_GAP;\n };\n\n if (fits(this._placement)) {\n return this._placement;\n }\n\n const opposite: Record<Exclude<PopoverPlacement, \"auto\">, Exclude<PopoverPlacement, \"auto\">> = {\n top: \"bottom\",\n bottom: \"top\",\n left: \"right\",\n right: \"left\",\n };\n\n const flipped = opposite[this._placement as Exclude<PopoverPlacement, \"auto\">];\n\n console.warn(`Popover: explicit placement \"${this._placement}\" overflows the viewport; falling back to \"${flipped}\".`);\n\n return flipped;\n }\n\n /**\n * Lazily creates the arrow tail component on first show.\n *\n * @remarks The arrow's element is inserted as the *first* DOM child of\n * the popover (not via `addComponent`) so the VBox layout manager does\n * not size it AND so it paints beneath subsequent sibling content. The\n * outward half of the diamond is still visible because it lies outside\n * the popover's bounds; the inward half is overlaid by the bubble's\n * children, preventing the arrow from obscuring the title/body text.\n */\n private ensureArrow(): void {\n if (this._arrowComponent) {\n return;\n }\n\n const arrow = new Component();\n const size = DEFAULT_ARROW_SIZE_PX;\n\n arrow.setBackgroundColor(\"var(--ts-ui-popover-bg, rgb(255, 255, 255))\");\n arrow.setWidth(size);\n arrow.setHeight(size);\n arrow.setTransform(\"rotate(45deg)\");\n arrow.setPointerEvents(\"none\");\n arrow.setVisible(this._showArrow);\n\n this._arrowComponent = arrow;\n\n const popoverEl = this.getElement(true)!;\n DOM.sink.insertBefore(popoverEl, arrow.getElement(true)!, DOM.source.getFirstChild(popoverEl));\n }\n\n /**\n * Positions the arrow tail along the resolved popover edge so it points\n * at the anchor centre, clamped to keep it within the popover's lateral\n * extent. Also re-applies the directional inset box-shadow that draws the\n * two outward-facing edges of the rotated diamond so the popover outline\n * appears continuous through the arrow.\n */\n private positionArrow(): void {\n if (!this._anchorElement || !this._arrowComponent) {\n return;\n }\n\n const anchorRect = DOM.source.getElementRect(this._anchorElement);\n const size = DEFAULT_ARROW_SIZE_PX;\n const half = size / 2;\n const popoverX = this.getX();\n const popoverY = this.getY();\n const popoverW = this.getWidth();\n const popoverH = this.getHeight();\n\n // High-first clamp (not Util.clamp): when the popover is larger than the\n // viewport, maxLocal < minLocal, and the arrow must pin to the leading\n // inset (minLocal), which the low-first Util.clamp would not do.\n const clamp = (value: number, min: number, max: number): number => Math.max(min, Math.min(value, max));\n\n // Inset box-shadow draws a 1px line on the two outward-facing edges\n // of the rotated diamond. The mapping below is given in\n // pre-rotation coordinates (the element's own CSS axes); after the\n // 45° clockwise rotation, original TOP/RIGHT/BOTTOM/LEFT edges map to\n // the rotated NE/SE/SW/NW edges.\n const borderColor = \"var(--ts-ui-popover-border, rgb(200, 200, 200))\";\n let arrowShadow: string;\n\n if (this._resolvedPlacement === \"bottom\") {\n arrowShadow = `inset 1px 0 0 ${borderColor}, inset 0 1px 0 ${borderColor}`;\n } else if (this._resolvedPlacement === \"top\") {\n arrowShadow = `inset -1px 0 0 ${borderColor}, inset 0 -1px 0 ${borderColor}`;\n } else if (this._resolvedPlacement === \"right\") {\n arrowShadow = `inset 1px 0 0 ${borderColor}, inset 0 -1px 0 ${borderColor}`;\n } else {\n arrowShadow = `inset 0 1px 0 ${borderColor}, inset -1px 0 0 ${borderColor}`;\n }\n\n this._arrowComponent.setShadow(arrowShadow);\n\n const vp = DOM.source.getViewportSize();\n const border = this.getBorderSize();\n\n // `position: absolute` measures from the popover's padding box (i.e.\n // inside the border). Subtracting the border width centres the\n // rotated diamond on the popover's *outer* edge, keeping the tip-to-\n // anchor gap predictable regardless of border thickness.\n if (this._resolvedPlacement === \"top\" || this._resolvedPlacement === \"bottom\") {\n const anchorCentreX = anchorRect.left + anchorRect.width / 2;\n const minLocalX = Math.max(\n ARROW_EDGE_INSET_PX,\n VIEWPORT_EDGE_INSET_PX - popoverX + ARROW_VISUAL_HALF - half,\n );\n const maxLocalX = Math.min(\n popoverW - size - ARROW_EDGE_INSET_PX,\n vp.width - VIEWPORT_EDGE_INSET_PX - popoverX - half - ARROW_VISUAL_HALF,\n );\n const localX = clamp(anchorCentreX - popoverX - half - border.left, minLocalX, maxLocalX);\n\n this._arrowComponent.setX(localX);\n\n // Pull the arrow half its own size outside the body so the\n // rotated diamond reads as a triangle straddling the edge.\n if (this._resolvedPlacement === \"bottom\") {\n this._arrowComponent.setY(-half - border.top);\n } else {\n this._arrowComponent.setY(popoverH - half - border.top);\n }\n } else {\n const anchorCentreY = anchorRect.top + anchorRect.height / 2;\n const minLocalY = Math.max(\n ARROW_EDGE_INSET_PX,\n VIEWPORT_EDGE_INSET_PX - popoverY + ARROW_VISUAL_HALF - half,\n );\n const maxLocalY = Math.min(\n popoverH - size - ARROW_EDGE_INSET_PX,\n vp.height - VIEWPORT_EDGE_INSET_PX - popoverY - half - ARROW_VISUAL_HALF,\n );\n const localY = clamp(anchorCentreY - popoverY - half - border.top, minLocalY, maxLocalY);\n\n this._arrowComponent.setY(localY);\n\n if (this._resolvedPlacement === \"right\") {\n this._arrowComponent.setX(-half - border.left);\n } else {\n this._arrowComponent.setX(popoverW - half - border.left);\n }\n }\n }\n\n /**\n * Registers `window` resize and `scroll` listeners on every scrollable\n * ancestor of the anchor so the popover follows the anchor while open.\n */\n private attachRepositionListeners(): void {\n Event.addViewportListener(this, \"resize\", this._onWindowResize);\n\n if (this._anchorElement) {\n this._scrollAncestors = this.collectScrollAncestors(this._anchorElement);\n\n for (const ancestor of this._scrollAncestors) {\n DOM.sink.addListener(ancestor, \"scroll\", this._onScroll, { passive: true });\n }\n }\n }\n\n /**\n * Detaches every reposition listener registered by {@link attachRepositionListeners}.\n */\n private detachRepositionListeners(): void {\n Event.removeViewportListener(this, \"resize\", this._onWindowResize);\n\n for (const ancestor of this._scrollAncestors) {\n DOM.sink.removeListener(ancestor, \"scroll\", this._onScroll);\n }\n\n this._scrollAncestors = [];\n }\n\n /**\n * Walks the anchor's ancestor chain up to `document.documentElement` and\n * collects every element whose computed `overflow` makes it scrollable.\n *\n * @param node - The starting element.\n * @returns The list of scrollable ancestors plus `document.documentElement`.\n */\n private collectScrollAncestors(node: Handle): Handle[] {\n const out: Handle[] = [];\n let cursor: Handle | null = DOM.source.getParentElement(node);\n\n while (cursor && cursor !== DOM.source.getDocumentElement()) {\n const style = DOM.source.getComputedOverflow(cursor);\n const overflow = style.overflow + style.overflowX + style.overflowY;\n\n if (/(auto|scroll|overlay)/.test(overflow)) {\n out.push(cursor);\n }\n\n cursor = DOM.source.getParentElement(cursor);\n }\n\n out.push(DOM.source.getDocumentElement());\n\n return out;\n }\n}\n\nconst PopoverCallable = callable(Popover);\ntype PopoverCallable = Popover;\nexport {\n Popover as _Popover,\n PopoverCallable as Popover\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component, ComponentOptions } from \"~/core/Component.js\";\nimport { DOM } from \"~/core/DOM.js\";\nimport { Event } from \"~/core/Event.js\";\nimport { Position } from \"~/primitive/Position.js\";\nimport { callable } from \"~/core/Callable.js\";\n\n/**\n * Construction-time options for {@link DialogBackdrop}.\n *\n * @category Components\n */\ninterface DialogBackdropOptions extends ComponentOptions {\n}\n\n/**\n * Empty subclass-default const so the super call follows the framework's\n * `(options, defaults)` shape uniformly.\n */\nconst _defaultDialogBackdropOptions: Partial<DialogBackdropOptions> = {};\n\n/**\n * A full-viewport fixed overlay that visually blocks content behind a modal dialog.\n *\n * Appended to `document.documentElement` as a sibling of the dialog panel at a lower\n * z-index, mirroring the pattern used by [`Notification`](/api/overlay/classes/Notification) and [`Menu`](/api/overlay/classes/Menu).\n */\nclass DialogBackdrop extends Component<DialogBackdropOptions> {\n\n /**\n * Creates the backdrop and applies viewport-filling fixed positioning.\n *\n * @param options - Optional construction options.\n * @param subclassDefaults - Per-subclass default bag layered over this\n * class's defaults; subclasses forward their `_defaultXxxOptions`\n * constant here.\n */\n constructor(options?: DialogBackdropOptions, subclassDefaults?: Partial<DialogBackdropOptions>) {\n super(options, { ..._defaultDialogBackdropOptions, ...(subclassDefaults ?? {}) });\n\n const vp = DOM.source.getViewportSize();\n\n this.setPosition(Position.FIXED);\n this.setX(0);\n this.setY(0);\n this.setWidth(vp.width);\n this.setHeight(vp.height);\n this.setZIndex(10100);\n this.setBackgroundColor(\"var(--ts-ui-dialog-backdrop-bg)\");\n }\n\n /**\n * Registers a click listener on this backdrop element.\n *\n * @param listener - Called when the user clicks the backdrop area.\n */\n addClickListener(listener: Event.Listener): this {\n Event.addListener(this, \"click\", listener);\n\n return this;\n }\n\n /**\n * Updates backdrop dimensions to match the current viewport size.\n */\n resize(): void {\n const vp = DOM.source.getViewportSize();\n\n this.setWidth(vp.width);\n this.setHeight(vp.height);\n }\n\n /**\n * Removes the backdrop from the DOM and runs component cleanup.\n */\n destroy(): void {\n this.removeElement();\n this.destructor();\n }\n}\n\nconst DialogBackdropCallable = callable(DialogBackdrop);\ntype DialogBackdropCallable = DialogBackdrop;\nexport {\n DialogBackdrop as _DialogBackdrop,\n DialogBackdropCallable as DialogBackdrop\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component } from \"~/core/Component.js\";\nimport { Panel } from \"~/core/Panel.js\";\nimport { Animation } from \"~/core/Animation.js\";\nimport { Event } from \"~/core/Event.js\";\nimport { LayerManager, DismissableLayer, LayerDismissMode } from \"~/core/LayerManager.js\";\nimport { trapWheel, untrapWheel } from \"~/core/WheelTrap.js\";\nimport { Position } from \"~/primitive/Position.js\";\nimport { Text } from \"~/component/input/Text.js\";\nimport { Button } from \"~/component/button/Button.js\";\nimport { Glyph } from \"~/component/display/Glyph.js\";\nimport { DialogBackdrop } from \"~/component/container/DialogBackdrop.js\";\nimport { Border as BorderLayout } from \"~/layout/Border.js\";\nimport { Fit } from \"~/layout/Fit.js\";\nimport { Placement } from \"~/primitive/Placement.js\";\nimport { Insets } from \"~/primitive/Insets.js\";\nimport { callable } from \"~/core/Callable.js\";\nimport { xmark } from \"~/glyphs/solid/xmark.js\";\nimport { circle_check } from \"~/glyphs/solid/circle_check.js\";\nimport { circle_info } from \"~/glyphs/solid/circle_info.js\";\nimport { triangle_exclamation } from \"~/glyphs/solid/triangle_exclamation.js\";\nimport { circle_exclamation } from \"~/glyphs/solid/circle_exclamation.js\";\nimport { DOM } from \"~/core/DOM.js\";\nimport type { Handle } from \"~/core/DOM.js\";\n\nGlyph.register(xmark, circle_check, circle_info, triangle_exclamation, circle_exclamation);\n\n/**\n * The result produced when a dialog is dismissed.\n *\n * @category Core\n */\nexport type DialogResult = 'confirm' | 'cancel' | 'close';\n\n/**\n * Configuration for a single button in a dialog's button row.\n *\n * @category Core\n */\nexport interface DialogButtonConfig {\n /** The label text displayed on the button. */\n text : string;\n /** The result value emitted when this button is clicked. Defaults to `'cancel'`. */\n result? : DialogResult;\n /** When true, renders the button with primary (confirm) styling. */\n primary?: boolean;\n /** Optional registry glyph name shown to the left of the button label. */\n glyph? : string;\n /**\n * Optional foreground colour applied to the button's leading glyph. Accepts\n * any CSS colour string — typically a theme variable reference such as\n * `'var(--ts-ui-dialog-confirm-color)'`. When omitted the glyph inherits\n * the button's `currentColor`. The {@link DialogButtons} presets supply\n * the appropriate tint by default; reach for this field at the call site\n * only when overriding a preset or building a one-off button.\n */\n tint? : string;\n}\n\n/**\n * Severity tone for a dialog's title bar, mirroring\n * [`NotificationType`](/api/core/type-aliases/NotificationType). When set it\n * tints the header and shows a matching leading glyph, taking precedence over\n * the tone otherwise derived from the buttons.\n *\n * @category Core\n */\nexport type DialogSeverity = 'info' | 'success' | 'warning' | 'error';\n\n/**\n * Configuration object passed to `new Dialog(config)` or `Dialog.show(config)`.\n *\n * @category Core\n */\nexport interface DialogConfig {\n /** Text displayed in the dialog title bar. */\n title : string;\n /** Plain-text body message. Ignored when `contentComponent` is provided. */\n message? : string;\n /** A custom component rendered in the content area instead of a message label. */\n contentComponent?: Component;\n /**\n * Button definitions for the footer row.\n * Defaults to a single OK button that resolves with `'confirm'`.\n */\n buttons? : DialogButtonConfig[];\n /** Dialog panel width in pixels. Defaults to 480. */\n width? : number;\n /** Dialog panel height in pixels. When omitted the height is computed from content. */\n height? : number;\n /** When true, clicking the backdrop closes the dialog with result `'close'`. Defaults to false. */\n closeOnBackdrop? : boolean;\n /**\n * When `false`, the dialog is a mandatory modal: no title-bar close button,\n * Escape does not close it, and a backdrop click does not close it (regardless\n * of `closeOnBackdrop`). Defaults to `true`.\n */\n dismissable? : boolean;\n /**\n * Optional severity tone for the title bar (`'info'`, `'success'`,\n * `'warning'`, `'error'`). When set it tints the header and shows a matching\n * leading glyph, overriding the tone derived from the buttons. Omit for the\n * default button-derived chrome.\n */\n severity? : DialogSeverity;\n /**\n * Component to receive focus when the dialog opens, overriding the default\n * (the first focusable element in the content region). Use it when the field\n * that should take focus is not the first one — a form whose first control is\n * a read-only summary, say. Ignored when the component has no focusable\n * element on open, which falls back to the default order.\n */\n initialFocus? : Component;\n}\n\n// ---------------------------------------------------------------------------\n// Private constants\n// ---------------------------------------------------------------------------\n\nconst TITLE_HEIGHT : number = 36;\nconst BUTTON_HEIGHT : number = 52;\nconst BUTTON_WIDTH : number = 90;\nconst BUTTON_GAP : number = 8;\nconst BUTTON_V_PAD : number = 11;\nconst CLOSE_SIZE : number = 20;\nconst TITLE_H_PAD : number = 12;\nconst MIN_DIALOG_WIDTH : number = 320;\nconst MIN_DIALOG_HEIGHT: number = 160;\nconst MIN_CONTENT_HEIGHT: number = 80;\n// Minimum gap kept between a content-resized dialog and each viewport edge, so a\n// dialog grown to tall content never runs flush to the top/bottom of the screen.\nconst DIALOG_VIEWPORT_MARGIN: number = 24;\n\n// Leading title-bar glyph per severity tone, mirroring Notification's badges.\nconst SEVERITY_GLYPH: Record<DialogSeverity, string> = {\n info: \"circle-info\",\n success: \"circle-check\",\n warning: \"triangle-exclamation\",\n error: \"circle-exclamation\",\n};\n\n/**\n * Shared duration (ms) for the dialog entrance/exit transition. The backdrop\n * fade and the panel's opacity + scale all run for this many milliseconds.\n */\nconst DIALOG_ANIM_DURATION_MS: number = 150;\n\n/**\n * CSS selector matching the focusable elements inside a dialog — the Tab\n * focus-trap boundary set, the initial-focus candidates, and the primary-button\n * lookup all share it so the notion of \"focusable\" stays single-sourced.\n */\nconst FOCUSABLE_SELECTOR = 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n\n/**\n * Vertical breathing room reserved above and below the title text inside the\n * `TITLE_HEIGHT` row. 4 px on each side: keeps the bold label off the divider\n * border and gives a balanced visual cap height. Used both for the text's\n * line-height (via {@link Text.centerInHeight}) and for its laid-out height\n * inside the bar.\n */\nconst TITLE_V_PAD: number = 4;\n\n/**\n * Horizontal gap between the close button and the right edge of the title\n * bar, plus the gap between the title text and the close button. Two\n * separate offsets share the same value so the close-button column reads as\n * a balanced `[gap][icon][gap]` strip.\n */\nconst TITLE_RIGHT_GAP: number = 4;\n\n/**\n * Horizontal gap between the optional leading glyph and the title text.\n * Matches the 8 px gutter the WindowHeader uses between its title icon and\n * label so the two surfaces feel consistent.\n */\nconst TITLE_GLYPH_TEXT_GAP: number = 8;\n\n// ---------------------------------------------------------------------------\n// Private: DialogTitleBar\n// ---------------------------------------------------------------------------\n\n/**\n * Title bar that occupies the NORTH slot of a Dialog's border layout.\n * Contains a text label on the left, an optional leading glyph, and a glyph\n * close button on the right.\n *\n * @remarks\n * Reach this instance via [`Dialog.getTitleBar()`](/api/overlay/classes/Dialog#gettitlebar) — there is no public\n * constructor. The supported surface is `getTitleText()` (for tinting the\n * title text colour), `setGlyph()` / `getGlyph()` (for the optional leading\n * icon), and any inherited [`Component`](/api/core/classes/Component) setter\n * (e.g. `setBackgroundColor`).\n *\n * @category Core\n */\nclass DialogTitleBar extends Component {\n\n private readonly _titleText : Text;\n private _closeButton: Button | null = null;\n private _titleGlyph: Glyph | null = null;\n\n /**\n * @param title - Text to display in the title bar.\n * @param onClose - Called when the user clicks the close button.\n * @param dismissable - When `false`, the close button is not built at all\n * (mandatory-modal title bar).\n */\n constructor(title: string, onClose: () => void, dismissable: boolean) {\n super();\n\n this.setBackgroundColor(\"var(--ts-ui-body-bg)\");\n this.setBorder({\n border: \"none\",\n borderBottom: \"1px solid var(--ts-ui-dialog-border)\",\n });\n this.setPreferredSize({ width: 0, height: TITLE_HEIGHT });\n\n this._titleText = new Text(title);\n this._titleText.setFontWeight(\"bold\");\n this._titleText.setOverflow(\"hidden\");\n this._titleText.setTextOverflow(\"ellipsis\");\n this._titleText.setWhiteSpace(\"nowrap\");\n // Centre the label within the inner area of the row (TITLE_HEIGHT\n // minus the top + bottom TITLE_V_PAD breathing room).\n this._titleText.centerInHeight(TITLE_HEIGHT - TITLE_V_PAD * 2);\n this.addComponent(this._titleText);\n\n if (dismissable) {\n this._closeButton = new Button({ glyph: \"xmark\" });\n this._closeButton.setInsets(new Insets(0, 0, 0, 0));\n this._closeButton.setBorder(\"none\");\n this._closeButton.clearBackgroundImage();\n this._closeButton.setBackgroundColor(\"transparent\");\n this._closeButton.clearShadow();\n this._closeButton.clearPressedShadow();\n this._closeButton.clearHoverShadow();\n // Hover and pressed background swap out the framework's gray\n // var(--ts-ui-button-hover-bg, …) for a translucent overlay that\n // darkens whatever tinted header sits underneath without\n // imposing its own colour. Also drop the hover gradient so it\n // doesn't double up over the overlay.\n this._closeButton.setHoverBackgroundColor(\"var(--ts-ui-titlebar-btn-hover-bg, rgba(0, 0, 0, 0.08))\");\n this._closeButton.setPressedBackgroundColor(\"var(--ts-ui-titlebar-btn-active-bg, rgba(0, 0, 0, 0.16))\");\n this._closeButton.clearHoverBackgroundImage();\n this._closeButton.clearPressedBackgroundImage();\n this._closeButton.setPreferredSize({ width: CLOSE_SIZE, height: CLOSE_SIZE });\n this.addComponent(this._closeButton);\n\n this._closeButton.on(\"action\", onClose);\n }\n }\n\n /**\n * Returns the title bar's close button, or `null` when the title bar was\n * built non-dismissable (no close affordance).\n *\n * @returns The close [`Button`](/api/component/button/classes/Button), or `null`.\n */\n getCloseButton(): Button | null {\n return this._closeButton;\n }\n\n /**\n * Returns the title-text component, for callers that need to tint or\n * otherwise restyle it from outside the title bar.\n *\n * @returns The internal title [`Text`](/api/component/input/classes/Text) instance.\n */\n getTitleText(): Text {\n return this._titleText;\n }\n\n /**\n * Sets or clears an optional leading glyph shown to the left of the title text.\n *\n * @param name - Registry glyph name to display, or `null` to clear an existing glyph.\n *\n * @returns This component, for method chaining.\n *\n * @remarks\n * The current implementation positions the glyph in `doLayout`; only the\n * notification-detail path uses this slot, and the glyph never coexists with\n * other left-side decoration on a Dialog title bar.\n */\n setGlyph(name: string): this {\n if (this._titleGlyph) {\n this.removeComponent(this._titleGlyph);\n this._titleGlyph = null;\n }\n\n const glyph = new Glyph(name);\n glyph.setPointerEvents(\"none\");\n glyph.setPreferredSize({ width: 16, height: 16 });\n this._titleGlyph = glyph;\n this.addComponent(glyph);\n\n this.doLayout();\n\n return this;\n }\n\n /**\n * Removes the leading title-bar glyph from the dialog, if one is present.\n *\n * @returns This component, for method chaining.\n */\n clearGlyph(): this {\n if (this._titleGlyph) {\n this.removeComponent(this._titleGlyph);\n this._titleGlyph = null;\n this.doLayout();\n }\n\n return this;\n }\n\n /**\n * Returns the optional leading title-glyph component, or null if none is set.\n *\n * @returns The leading [`Glyph`](/api/component/display/classes/Glyph) instance, or null.\n */\n getGlyph(): Glyph | null {\n return this._titleGlyph;\n }\n\n /**\n * Positions the title label, optional leading glyph, and close button within\n * the title bar's content box.\n *\n * @returns This component, for method chaining.\n */\n doLayout(): this {\n super.doLayout();\n\n const box = this.getContentBounds();\n\n if (!box) {\n return this;\n }\n\n const w = box.width;\n const h = box.height;\n const closeX = w - CLOSE_SIZE - TITLE_RIGHT_GAP;\n const centerY = Math.floor((h - CLOSE_SIZE) / 2);\n const rightBound = this._closeButton\n ? closeX // reserve the close-button slot\n : (w - TITLE_H_PAD); // no button: label runs to the right pad\n\n let labelX = TITLE_H_PAD;\n\n if (this._titleGlyph) {\n const glyphSize = this._titleGlyph.getPreferredSize() ?? { width: 16, height: 16 };\n const glyphY = Math.max(0, Math.floor((h - glyphSize.height) / 2));\n\n this._titleGlyph.setX(box.x + TITLE_H_PAD);\n this._titleGlyph.setY(box.y + glyphY);\n this._titleGlyph.setWidth(glyphSize.width);\n this._titleGlyph.setHeight(glyphSize.height);\n\n labelX = TITLE_H_PAD + glyphSize.width + TITLE_GLYPH_TEXT_GAP;\n }\n\n // Reserve TITLE_RIGHT_GAP of space between the label and the close button.\n const labelWidth = Math.max(0, rightBound - labelX - TITLE_RIGHT_GAP);\n const labelH = h - TITLE_V_PAD * 2;\n\n this._titleText.setX(box.x + labelX);\n this._titleText.setY(box.y + TITLE_V_PAD);\n this._titleText.setWidth(labelWidth);\n this._titleText.setHeight(labelH);\n\n if (this._closeButton) {\n this._closeButton.setX(box.x + closeX);\n this._closeButton.setY(box.y + centerY);\n this._closeButton.setWidth(CLOSE_SIZE);\n this._closeButton.setHeight(CLOSE_SIZE);\n // setX/setY/setWidth/setHeight don't cascade — explicitly relayout the\n // close button so its internal Fit layout sizes the times glyph.\n this._closeButton.doLayout();\n }\n\n return this;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Private: DialogButtonRow\n// ---------------------------------------------------------------------------\n\n/**\n * Footer row that occupies the SOUTH slot of a Dialog's border layout.\n * Lays out one or more buttons, right-aligned.\n */\nclass DialogButtonRow extends Component {\n\n private readonly _buttons: Button[] = [];\n\n /**\n * @param configs - Button definitions to render.\n * @param onButton - Called with the resolved [`DialogResult`](/api/overlay/type-aliases/DialogResult) when any button is clicked.\n */\n constructor(configs: DialogButtonConfig[], onButton: (result: DialogResult) => void) {\n super();\n\n this.setBorder({\n border: \"none\",\n borderTop: \"1px solid var(--ts-ui-dialog-border)\",\n });\n this.setBackgroundColor(\"var(--ts-ui-body-bg)\");\n this.setPreferredSize({ width: 0, height: BUTTON_HEIGHT });\n\n for (const cfg of configs) {\n const btn = new Button(cfg.text, cfg.glyph !== undefined ? { glyph: cfg.glyph } : undefined);\n const result = cfg.result ?? 'cancel';\n\n if (cfg.primary) {\n btn.setBackgroundImage(\"var(--ts-ui-toggle-selected-bg, rgb(200, 200, 200))\");\n }\n\n if (cfg.glyph !== undefined) {\n const glyph = btn.getGlyph();\n const tint = cfg.tint;\n\n if (glyph !== null && tint) {\n glyph.setForegroundColor(tint);\n }\n }\n\n btn.on(\"action\", () => onButton(result));\n this._buttons.push(btn);\n this.addComponent(btn);\n }\n }\n\n /**\n * Positions buttons right-aligned within the footer row's content box.\n *\n * @returns This component, for method chaining.\n */\n doLayout(): this {\n super.doLayout();\n\n const box = this.getContentBounds();\n\n if (!box) {\n return this;\n }\n\n const btnH = box.height - BUTTON_V_PAD * 2;\n const totalW = this._buttons.length * BUTTON_WIDTH + (this._buttons.length - 1) * BUTTON_GAP;\n let x = Math.round((box.width - totalW) / 2);\n\n for (const btn of this._buttons) {\n btn.setX(box.x + x);\n btn.setY(box.y + BUTTON_V_PAD);\n btn.setWidth(BUTTON_WIDTH);\n btn.setHeight(btnH);\n\n btn.doLayout();\n\n x += BUTTON_WIDTH + BUTTON_GAP;\n }\n\n return this;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public: Dialog\n// ---------------------------------------------------------------------------\n\n/**\n * Canonical dialog button presets. Spread into the `buttons` array of a\n * {@link DialogConfig} to inherit the standard text / result / glyph mapping\n * for the three universal dismiss-row affordances; override `primary` per\n * call site since which button is default-focused is contextual (Cancel is\n * primary when paired with Confirm; Confirm is primary when it stands alone).\n *\n * Centralising the `glyph` here is the rule that prevents drift — the\n * checkmark/xmark mapping is bound to the button's identity, never re-typed\n * at the call site. {@link Dialog} also inspects the resolved result set to\n * pick the title-bar variant (only `confirm` → info header with leading\n * `circle-info`; `confirm` + `cancel` → affirm header).\n *\n * @category Core\n * @example\n * ```typescript\n * Dialog.show({\n * title: 'Delete record',\n * message: 'This cannot be undone.',\n * buttons: [\n * { ...DialogButtons.Cancel, primary: true },\n * DialogButtons.Confirm,\n * ],\n * });\n * ```\n */\nexport const DialogButtons = {\n /** Affirm an action — emits `'confirm'`, carries the green-tinted `circle-check` glyph. Paired with {@link Cancel} for action prompts. */\n Confirm: { text: 'Confirm', result: 'confirm', glyph: 'circle-check', tint: 'var(--ts-ui-dialog-confirm-color)' },\n /** Acknowledge information — emits `'confirm'`, carries the green-tinted `circle-check` glyph. Stands alone on informational dialogs. */\n Ok: { text: 'Ok', result: 'confirm', glyph: 'circle-check', tint: 'var(--ts-ui-dialog-confirm-color)' },\n /** Reject an action — emits `'cancel'`, carries the red-tinted `xmark` glyph. Paired with {@link Confirm}. */\n Cancel: { text: 'Cancel', result: 'cancel', glyph: 'xmark', tint: 'var(--ts-ui-dialog-cancel-color)' },\n /** Dismiss without choosing — emits `'close'`, carries the red-tinted `xmark` glyph (same icon family as cancel; the result value disambiguates). */\n Close: { text: 'Close', result: 'close', glyph: 'xmark', tint: 'var(--ts-ui-dialog-cancel-color)' },\n} as const satisfies Record<string, DialogButtonConfig>;\n\n/** Default button set when no buttons are supplied in config. */\nconst DEFAULT_BUTTONS: DialogButtonConfig[] = [\n { ...DialogButtons.Ok, primary: true },\n];\n\n/**\n * A modal dialog component with a title bar, scrollable content area, and button row.\n *\n * Use the static `Dialog.show(config)` convenience method for one-shot confirm/cancel\n * prompts, or construct an instance and call `show()` for fine-grained control.\n *\n * @example\n * ```typescript\n * const result = await Dialog.show({\n * title : 'Confirm deletion',\n * message: 'Are you sure you want to delete this record?',\n * buttons: [\n * { text: 'Delete', result: 'confirm', primary: true },\n * { text: 'Cancel', result: 'cancel' },\n * ],\n * });\n * if (result === 'confirm') { ... }\n * ```\n *\n * @category Core\n */\nclass Dialog extends Component implements DismissableLayer {\n\n private readonly _titleBar : DialogTitleBar;\n private readonly _contentContainer: Panel;\n private readonly _buttonRow : DialogButtonRow;\n private readonly _backdrop : DialogBackdrop;\n private readonly _config : DialogConfig;\n\n private _resolvePromise : ((result: DialogResult) => void) | null = null;\n private _previousFocus : Handle | null = null;\n private _boundKeyHandler : (e: KeyboardEvent) => Event.ListenerResult;\n private _boundResizeHandler: () => void;\n\n // In-flight entrance / dismiss animations for the panel and its backdrop,\n // cancelled on teardown so their fallback timers cannot fire against\n // released element handles.\n private _panelInAnimation : Animation.CancelHandle | null = null;\n private _backdropInAnimation : Animation.CancelHandle | null = null;\n private _panelOutAnimation : Animation.CancelHandle | null = null;\n private _backdropOutAnimation: Animation.CancelHandle | null = null;\n\n // True once `hide()`'s finalize has begun. `finalize` calls `destructor()`\n // partway through and finishes the rest afterwards, so the destructor uses\n // this to tell \"reached from a completing hide\" (leave the remainder to\n // finalize) from \"reached from a bare dispose\" (run it here, because the\n // cancelled dismiss animation will never call finalize at all).\n private _finalizing: boolean = false;\n\n /**\n * Constructs a Dialog but does not display it. Call `show()` to open.\n *\n * @param config - Dialog configuration.\n */\n constructor(config: DialogConfig) {\n super();\n\n this._config = config;\n\n const dialogWidth = Math.max(MIN_DIALOG_WIDTH, config.width ?? 480);\n const buttons = config.buttons ?? DEFAULT_BUTTONS;\n const contentHeight = Math.max(MIN_CONTENT_HEIGHT, this.computeContentHeight(config));\n const dialogHeight = Math.max(\n MIN_DIALOG_HEIGHT,\n config.height ?? (TITLE_HEIGHT + contentHeight + BUTTON_HEIGHT)\n );\n\n this.setPosition(Position.FIXED);\n this.setWidth(dialogWidth);\n this.setHeight(dialogHeight);\n // z-index is stamped from LayerManager's Dialog band at open() time\n // so stacked dialogs ascend monotonically; the backdrop is set one\n // below the panel there.\n this.setBackgroundColor(\"var(--ts-ui-body-bg)\");\n this.setBorderRadius(\"var(--ts-ui-border-radius, 4px)\");\n this.setShadow(\"var(--ts-ui-dialog-shadow)\");\n this.setOverflow(\"hidden\");\n // Fixed dimensions, hidden overflow, no escaping descendants — full strict containment.\n this.setContain(\"strict\");\n\n const layout = new BorderLayout();\n layout.setComponentSpacing(0);\n this.setLayoutManager(layout);\n\n this._titleBar = new DialogTitleBar(config.title, () => this.hide('close'), config.dismissable !== false);\n this.addComponent(this._titleBar, { placement: Placement.NORTH });\n\n // An explicit severity tone wins over the tone derived from the buttons,\n // so an error/warning dialog reads as such regardless of its footer.\n if (config.severity) {\n this.applySeverityHeader(config.severity);\n } else {\n this.applyHeaderVariant(this.computeHeaderVariant(buttons));\n }\n\n // A Panel (not a bare Component) so the content area is a real scroll\n // region: `autoScroll: \"y\"` opts it into the framework's overflow\n // handling, and — because Panel does not clamp itself to its content size\n // (`clampsToContentSize` is false) — a dialog capped shorter than its\n // content (see resizeToContent) shrinks this container to the available\n // space and scrolls, instead of a bare Component flooring to its content\n // height and clipping. Vertical only: a horizontal scrollbar would cover\n // the bottom rows of body text and is rarely useful for dialog content.\n // Zero insets so content sits flush, matching the former bare container.\n this._contentContainer = new Panel({\n autoScroll: \"y\",\n layoutManager: new Fit(),\n insets: new Insets(0, 0, 0, 0),\n });\n\n if (config.contentComponent) {\n this._contentContainer.addComponent(config.contentComponent);\n } else {\n const messageText = new Text(config.message ?? '');\n messageText.setWhiteSpace(\"normal\");\n messageText.setWordBreak(\"break-word\");\n messageText.setPadding(new Insets(16, 16, 16, 16));\n messageText.setUserSelect(\"text\");\n messageText.setCursor(\"text\");\n this._contentContainer.addComponent(messageText);\n }\n\n this.addComponent(this._contentContainer, { placement: Placement.CENTER });\n\n this._buttonRow = new DialogButtonRow(buttons, (result) => this.hide(result));\n this.addComponent(this._buttonRow, { placement: Placement.SOUTH });\n\n this._backdrop = new DialogBackdrop();\n\n this._boundKeyHandler = (e: KeyboardEvent) => this.onKeyDown(e);\n this._boundResizeHandler = () => this.onViewportResize();\n }\n\n /**\n * Picks the title-bar tint variant for this dialog by inspecting the set\n * of button results. The variant is derived from the buttons rather than\n * a config flag so callers cannot signal one intent via buttons and a\n * conflicting intent via a separate option.\n *\n * @param buttons - The resolved button configuration array.\n * @returns `'info'` for a single confirm-result button (informational\n * dialog), `'affirm'` when both confirm and cancel are present\n * (affirmative-action dialog), `'plain'` otherwise.\n */\n private computeHeaderVariant(buttons: DialogButtonConfig[]): 'info' | 'affirm' | 'plain' {\n const results = new Set(buttons.map(b => b.result ?? 'cancel'));\n\n if (results.size === 1 && results.has('confirm')) {\n return 'info';\n }\n\n if (results.has('confirm') && results.has('cancel')) {\n return 'affirm';\n }\n\n return 'plain';\n }\n\n /**\n * Applies the chosen header variant's background, title-text foreground,\n * and (for the info variant only) a leading `circle-info` glyph. The\n * close button inside the title bar is intentionally untouched — dismiss\n * affordances stay on `currentColor` per the modal-glyph-theming rule.\n *\n * @param variant - One of `'info'`, `'affirm'`, or `'plain'`.\n */\n private applyHeaderVariant(variant: 'info' | 'affirm' | 'plain'): void {\n if (variant === 'plain') {\n return;\n }\n\n const bgVar = variant === 'info' ? 'var(--ts-ui-dialog-info-bg)' : 'var(--ts-ui-dialog-affirm-bg)';\n const fgVar = variant === 'info' ? 'var(--ts-ui-dialog-info-fg)' : 'var(--ts-ui-dialog-affirm-fg)';\n\n this._titleBar.setBackgroundColor(bgVar);\n this._titleBar.getTitleText().setForegroundColor(fgVar);\n\n if (variant === 'info') {\n this._titleBar.setGlyph('circle-info');\n\n const headerGlyph = this._titleBar.getGlyph();\n\n if (headerGlyph !== null) {\n headerGlyph.setForegroundColor(fgVar);\n }\n }\n }\n\n /**\n * Tints the title bar for an explicit {@link DialogSeverity}, reusing the\n * notification severity palette and leading glyph (matching the\n * notification-detail dialog). The border colour doubles as the title-text\n * and glyph foreground, as it does for a notification.\n *\n * @param severity - The severity tone to apply.\n */\n private applySeverityHeader(severity: DialogSeverity): void {\n const bgVar = `var(--ts-ui-notification-${severity}-bg)`;\n const fgVar = `var(--ts-ui-notification-${severity}-border)`;\n\n this._titleBar.setBackgroundColor(bgVar);\n this._titleBar.getTitleText().setForegroundColor(fgVar);\n this._titleBar.setGlyph(SEVERITY_GLYPH[severity]);\n\n const headerGlyph = this._titleBar.getGlyph();\n\n if (headerGlyph !== null) {\n headerGlyph.setForegroundColor(fgVar);\n }\n }\n\n /**\n * Computes the default content area height based on config.\n *\n * @param config - Dialog configuration.\n * @returns Height in pixels for the content region.\n *\n * @remarks\n * Content whose height depends on its width — a wrapping {@link Text} only\n * knows its line count once laid out — reports a single-line height here,\n * before it has been sized. {@link resizeToContent}, scheduled after the\n * first layout in {@link open}, re-fits the dialog once the content has\n * settled at the dialog width.\n */\n private computeContentHeight(config: DialogConfig): number {\n if (config.contentComponent) {\n const ps = config.contentComponent.getPreferredSize();\n\n if (ps) {\n return ps.height;\n }\n }\n\n return 100;\n }\n\n /**\n * Displays the dialog, attaches event listeners, and returns a promise that\n * resolves when the dialog is dismissed.\n *\n * @returns A promise resolving to the [`DialogResult`](/api/overlay/type-aliases/DialogResult) of the closing action.\n */\n show(): Promise<DialogResult> {\n return new Promise((resolve) => {\n this._resolvePromise = resolve;\n this.open();\n });\n }\n\n /**\n * Re-fits the dialog's height to its content's current preferred size and\n * re-centres it. A dialog's height is otherwise fixed at construction, so a\n * form whose content grows or shrinks after `show()` (e.g. add/remove rows)\n * is stretched or clipped to the original box; call this after mutating the\n * content so the dialog tracks it.\n *\n * The new height is `TITLE_HEIGHT + content + BUTTON_HEIGHT`, floored at the\n * dialog minimum and capped so the panel keeps a margin from the top and\n * bottom viewport edges — past that cap the content area scrolls (its\n * container is already `overflow-y: auto`). No-op before `show()` (nothing to\n * re-centre) and when the height is unchanged. Width is untouched.\n *\n * @returns This dialog, for method chaining.\n */\n resizeToContent(): this {\n if (!this.getElement()) {\n return this;\n }\n\n const contentHeight = Math.max(MIN_CONTENT_HEIGHT, this.computeContentHeight(this._config));\n const target = Math.max(MIN_DIALOG_HEIGHT, TITLE_HEIGHT + contentHeight + BUTTON_HEIGHT);\n\n const vp = DOM.source.getViewportSize();\n const capped = Math.min(target, Math.max(MIN_DIALOG_HEIGHT, vp.height - DIALOG_VIEWPORT_MARGIN * 2));\n\n if (capped === this.getHeight()) {\n return this;\n }\n\n this.setHeight(capped);\n this.scheduleLayout();\n this.center();\n\n return this;\n }\n\n /**\n * Appends backdrop and dialog to the DOM, centers the panel, and captures focus.\n */\n private open(): void {\n this._previousFocus = DOM.source.getActiveElement();\n\n if (this._config.closeOnBackdrop && this._config.dismissable !== false) {\n this._backdrop.addClickListener(() => { this.hide('close'); });\n }\n\n // Join the central layer tree and stamp the panel from the Dialog\n // band; the backdrop sits one below the panel so stacked dialogs keep\n // each panel above its own backdrop.\n LayerManager.register(this);\n\n const panelZ = LayerManager.getZIndex(this);\n this.setZIndex(panelZ);\n this._backdrop.setZIndex(panelZ - 1);\n\n const backdropEl = this._backdrop.getElement(true)!;\n LayerManager.mount(backdropEl);\n\n const dialogEl = this.getElement(true)!;\n LayerManager.mount(dialogEl);\n\n // Trap wheels no inner scroller claimed so the content behind a modal\n // dialog stays inert, matching modality.\n trapWheel(this);\n\n this.scheduleLayout();\n this.center();\n this.animateIn();\n\n // The construction-time height assumed single-line content; once the\n // first layout has sized the content at the dialog width, content whose\n // height depends on width (wrapping Text) has settled, so re-fit to it.\n // A no-op for content whose height did not change (resizeToContent bails\n // when the height is unchanged), so only width-dependent content reflows.\n Component.afterNextLayout(() => this.resizeToContent());\n\n Event.addViewportListener(this, 'keydown', this._boundKeyHandler);\n Event.addViewportListener(this, 'resize', this._boundResizeHandler);\n\n // Deferred past the scheduled layout: focusing synchronously here does\n // land on the right element, but the first layout then wraps the content\n // in its frame and re-parents the subtree into it. Moving a focused\n // element out of the document blurs it — silently, with no blur event —\n // so the focus is undone a frame later and lands nowhere.\n Component.afterNextLayout(() => this.focusFirst());\n }\n\n /**\n * Fades the backdrop in and the dialog panel in from `opacity: 0` +\n * `scale(0.97)` to `opacity: 1` + `scale(1)` over 150ms. No-op when\n * `prefers-reduced-motion: reduce` is set.\n */\n private animateIn(): void {\n const el = this.getElement();\n const bdEl = this._backdrop.getElement();\n\n if (!el) {\n return;\n }\n\n this._panelInAnimation?.cancel();\n this._panelInAnimation = Animation.play(el, {\n from: { opacity: \"0\", transform: \"scale(0.97)\" },\n to: { opacity: \"1\", transform: \"scale(1)\" },\n durationMs: DIALOG_ANIM_DURATION_MS,\n properties: [\"opacity\", \"transform\"],\n });\n\n if (bdEl) {\n this._backdropInAnimation?.cancel();\n this._backdropInAnimation = Animation.play(bdEl, {\n from: { opacity: \"0\" },\n to: { opacity: \"1\" },\n durationMs: DIALOG_ANIM_DURATION_MS,\n properties: [\"opacity\"],\n });\n }\n }\n\n /**\n * Centers the dialog panel within the viewport.\n */\n private center(): void {\n const vp = DOM.source.getViewportSize();\n const x = Math.max(0, Math.round((vp.width - this.getWidth()) / 2));\n const y = Math.max(0, Math.round((vp.height - this.getHeight()) / 2));\n\n this.setX(x);\n this.setY(y);\n }\n\n /**\n * Moves initial focus into the dialog. Prefers the configured\n * `initialFocus` component, then the first focusable element in the content\n * region, so a form field — not the title-bar close button, which is first in\n * DOM order — receives focus on open. Falls back to the primary action\n * button, then to the first focusable element anywhere in the dialog.\n *\n * @remarks Must run after the dialog's first layout, which re-parents the\n * content into its frame and would blur anything focused before it.\n */\n private focusFirst(): void {\n const requested = this.requestedFocusElement();\n\n if (requested) {\n DOM.sink.focus(requested);\n\n return;\n }\n\n const contentEl = this._contentContainer.getElement();\n const inContent = contentEl ? DOM.source.querySelectorAll(contentEl, FOCUSABLE_SELECTOR) : [];\n\n if (inContent.length > 0) {\n DOM.sink.focus(inContent[0]);\n\n return;\n }\n\n const primary = this.primaryButtonElement();\n\n if (primary) {\n DOM.sink.focus(primary);\n\n return;\n }\n\n const el = this.getElement();\n const focusable = el ? DOM.source.querySelectorAll(el, FOCUSABLE_SELECTOR) : [];\n\n if (focusable.length > 0) {\n DOM.sink.focus(focusable[0]);\n }\n }\n\n /**\n * Resolves the configured `initialFocus` component to the element that\n * should take focus: the component's own root element when it is itself\n * focusable (a `TextField` renders as the `<input>`), otherwise its first\n * focusable descendant (a `Panel` wrapping a field).\n *\n * @returns The element to focus, or `null` when no `initialFocus` is\n * configured or it offers nothing focusable — both of which fall through\n * to the default order.\n */\n private requestedFocusElement(): Handle | null {\n const component = this._config.initialFocus;\n const element = component?.getElement();\n\n if (!element) {\n return null;\n }\n\n if (DOM.source.matches(element, FOCUSABLE_SELECTOR)) {\n return element;\n }\n\n return DOM.source.querySelector(element, FOCUSABLE_SELECTOR);\n }\n\n /**\n * Returns the DOM element of the primary action button, used as the initial\n * focus target when the content region has nothing focusable. Resolves by\n * position: the index of the `primary` entry in the resolved button set maps\n * to the same-indexed focusable in the button row.\n *\n * @returns The primary button element, or `null` when none is primary or the\n * row is not yet rendered.\n */\n private primaryButtonElement(): Handle | null {\n const buttons = this._config.buttons ?? DEFAULT_BUTTONS;\n const index = buttons.findIndex(b => b.primary);\n\n if (index < 0) {\n return null;\n }\n\n const rowEl = this._buttonRow.getElement();\n const focusable = rowEl ? DOM.source.querySelectorAll(rowEl, FOCUSABLE_SELECTOR) : [];\n\n return focusable[index] ?? null;\n }\n\n /**\n * Collects all currently focusable elements inside the dialog.\n *\n * @returns An array of focusable elements in DOM order.\n */\n private getFocusable(): Handle[] {\n const el = this.getElement();\n\n if (!el) {\n return [];\n }\n\n return DOM.source.querySelectorAll(el, FOCUSABLE_SELECTOR)\n .filter(el => !DOM.source.hasAttribute(el, 'disabled'));\n }\n\n /**\n * Handles document-level keydown events for Escape and Tab focus trapping.\n *\n * @param e - The keyboard event.\n * @returns A stop-and-prevent disposition when the dialog handles the key (the Tab trap, or Enter); nothing otherwise, so unhandled keys keep propagating.\n */\n private onKeyDown(e: KeyboardEvent): Event.ListenerResult {\n // Escape is owned by LayerManager's keydown handler, which closes the\n // topmost non-manual layer (this dialog when it is on top). The dialog\n // keeps only the Tab focus-trap and the Enter-confirms-the-primary\n // shortcut here.\n if (e.key === 'Enter') {\n return this.onEnter(e);\n }\n\n if (e.key === 'Tab') {\n const focusable = this.getFocusable();\n\n if (focusable.length === 0) {\n return { stop: true, prevent: true };\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n if (e.shiftKey) {\n if (DOM.source.getActiveElement() === first) {\n DOM.sink.focus(last);\n\n return { stop: true, prevent: true };\n }\n } else {\n if (DOM.source.getActiveElement() === last) {\n DOM.sink.focus(first);\n\n return { stop: true, prevent: true };\n }\n }\n }\n\n return;\n }\n\n /**\n * Confirms the dialog on Enter by resolving the primary button's result,\n * so a simple form submits like one without the caller wiring Enter itself.\n *\n * @remarks Deliberately inert when focus is on a `<textarea>` (Enter inserts\n * a newline) or on a `<button>` (the button activates itself on Enter, and\n * hijacking it would fire the wrong action). No-op when no button is marked\n * `primary`, so a dialog with no clear default action does not submit blind.\n *\n * @param _e - The keydown event for the Enter press.\n * @returns `{ stop: true, prevent: true }` when Enter confirms the dialog; nothing when there is nothing to confirm.\n */\n private onEnter(_e: KeyboardEvent): Event.ListenerResult {\n const active = DOM.source.getActiveElement();\n const tag = active ? DOM.source.getTagName(active).toLowerCase() : null;\n\n if (tag === 'textarea' || tag === 'button') {\n return;\n }\n\n const result = this.primaryResult();\n\n if (result === null) {\n return;\n }\n\n this.hide(result);\n\n return { stop: true, prevent: true };\n }\n\n /**\n * Returns the result of the button marked `primary` in this dialog's\n * resolved button set — the action Enter confirms — or `null` when none is\n * primary.\n *\n * @returns The primary button's [`DialogResult`](/api/overlay/type-aliases/DialogResult), or `null`.\n */\n private primaryResult(): DialogResult | null {\n const buttons = this._config.buttons ?? DEFAULT_BUTTONS;\n const primary = buttons.find(b => b.primary);\n\n return primary ? (primary.result ?? 'cancel') : null;\n }\n\n /**\n * Re-fits the dialog to the resized viewport: {@link Dialog.resizeToContent}\n * grows it back toward its content when the viewport gained room, or caps it\n * (so the content area scrolls) when the viewport shrank below the content —\n * keeping the dialog within the viewport instead of overflowing it. The\n * backdrop is resized to the new viewport and the panel re-centred (again\n * unconditionally here, since `resizeToContent` skips re-centring when the\n * height is unchanged).\n */\n private onViewportResize(): void {\n this._backdrop.resize();\n this.resizeToContent();\n this.center();\n }\n\n /**\n * Dismisses the dialog with a brief fade-and-scale animation, restores\n * focus, and resolves the promise.\n *\n * @param result - The result to resolve the promise with.\n *\n * @remarks Honours `prefers-reduced-motion: reduce` — the transition is\n * skipped when motion is reduced.\n */\n hide(result: DialogResult): this {\n Event.removeViewportListener(this, 'keydown', this._boundKeyHandler);\n Event.removeViewportListener(this, 'resize', this._boundResizeHandler);\n\n const finalize = (): void => {\n this._finalizing = true;\n\n this._backdrop.destroy();\n this.removeElement();\n this.destructor();\n\n LayerManager.unregister(this);\n untrapWheel(this);\n\n if (this._previousFocus !== null) {\n DOM.sink.focus(this._previousFocus);\n }\n\n if (this._resolvePromise) {\n this._resolvePromise(result);\n this._resolvePromise = null;\n }\n };\n\n const el = this.getElement();\n const bdEl = this._backdrop.getElement();\n\n if (!el) {\n finalize();\n return this;\n }\n\n this._panelOutAnimation?.cancel();\n this._panelOutAnimation = Animation.play(el, {\n to: { opacity: \"0\", transform: \"scale(0.97)\" },\n durationMs: DIALOG_ANIM_DURATION_MS,\n properties: [\"opacity\", \"transform\"],\n onComplete: finalize,\n });\n\n if (bdEl) {\n this._backdropOutAnimation?.cancel();\n this._backdropOutAnimation = Animation.play(bdEl, {\n to: { opacity: \"0\" },\n durationMs: DIALOG_ANIM_DURATION_MS,\n properties: [\"opacity\"],\n });\n }\n\n return this;\n }\n\n /**\n * Cancels any in-flight panel / backdrop animation, then defers to the base\n * class. Reached from `hide()`'s completion callback as well as from a\n * direct dispose: on that path the dismiss animation is already finished, so\n * cancelling it is a no-op.\n */\n protected destructor(): void {\n this._panelInAnimation?.cancel();\n this._panelInAnimation = null;\n this._backdropInAnimation?.cancel();\n this._backdropInAnimation = null;\n this._panelOutAnimation?.cancel();\n this._panelOutAnimation = null;\n this._backdropOutAnimation?.cancel();\n this._backdropOutAnimation = null;\n\n // A dispose that lands mid-dismiss cancels the animation whose\n // completion callback owns the rest of teardown, so run that work here.\n // The backdrop is a private field rather than a registered child, so the\n // base class's recursion cannot reach it and it would otherwise stay\n // mounted over the whole app; the promise `show()` handed the caller\n // would never settle. Skipped when `finalize` is already running, which\n // reaches this method partway through and completes the rest itself —\n // including resolving with the caller's real result rather than the\n // `\"close\"` stand-in used here.\n if (!this._finalizing) {\n this._backdrop.destroy();\n\n LayerManager.unregister(this);\n untrapWheel(this);\n\n if (this._resolvePromise) {\n this._resolvePromise('close');\n this._resolvePromise = null;\n }\n }\n\n super.destructor();\n }\n\n /**\n * Returns the content container component where custom content is rendered.\n *\n * @returns The content container [`Component`](/api/core/classes/Component).\n */\n getContentComponent(): Component {\n return this._contentContainer;\n }\n\n /**\n * The dialog sizes itself explicitly — its height is computed to fit its\n * content at construction and re-fit (capped to the viewport) in\n * {@link Dialog.resizeToContent} — so it must not additionally floor itself\n * to its content's min-size. If it did, a dialog whose content is taller\n * than the viewport could not shrink to the capped height, and its\n * `autoScroll` content container would never get the constrained space it\n * needs to scroll (it would clip instead). The `MIN_DIALOG_HEIGHT` floor is\n * applied explicitly wherever the height is set.\n */\n protected clampsToContentSize(): boolean {\n return false;\n }\n\n /**\n * Returns the dialog's title-bar component.\n *\n * @returns The internal title-bar instance, exposing `getTitleText()` and\n * `setGlyph()` for callers (e.g. the notification detail dialog)\n * that need to tint or decorate the header.\n *\n * @remarks\n * The `DialogTitleBar` class itself is not exported — callers reach it\n * only through this accessor and interact via its few public methods\n * (`getTitleText`, `setGlyph`, `getGlyph`).\n */\n getTitleBar(): DialogTitleBar {\n return this._titleBar;\n }\n\n // ----- DismissableLayer -----\n\n /**\n * Returns the dialog panel's root element for the central layer tree.\n *\n * @returns The dialog's element, or null when not yet rendered.\n */\n getLayerElement(): Handle | null {\n return this.getElement() ?? null;\n }\n\n /**\n * Returns the dismiss mode the document-level handlers consult. A dialog\n * is `\"modal\"`: the manager neither dismisses ancestors on an outside\n * interaction nor lets one fall through, and it owns the Escape-to-close\n * shortcut. The dialog keeps its own Tab focus-trap.\n *\n * @returns The layer dismiss mode.\n */\n getDismissMode(): LayerDismissMode {\n return \"modal\";\n }\n\n /**\n * Advisory close request from the manager — closes the dialog with the\n * `'close'` result, matching the title-bar close affordance.\n *\n * @remarks No-op when `dismissable` is `false`: this is the Escape path\n * (`LayerManager` routes Escape to the topmost non-`\"manual\"` layer's\n * `requestClose()`), so a mandatory modal swallows Escape rather than\n * closing. `getDismissMode()` deliberately stays `\"modal\"` here — a\n * `\"manual\"` layer would be skipped by the Escape loop, letting Escape\n * fall through to close a layer beneath this one.\n */\n requestClose(): void {\n if (this._config.dismissable === false) {\n return;\n }\n\n this.hide('close');\n }\n\n /**\n * Returns the dialog's z-index band so unrelated dialogs stack above\n * every other overlay family.\n *\n * @returns The dialog band base.\n */\n getBand(): number {\n return LayerManager.Band.Dialog;\n }\n\n /**\n * Displays a modal dialog and returns a promise that resolves on dismissal.\n *\n * @param config - Dialog configuration.\n * @returns A promise resolving to the [`DialogResult`](/api/overlay/type-aliases/DialogResult) of the closing action.\n *\n * @example\n * ```typescript\n * const result = await Dialog.show({ title: 'Confirm', message: 'Proceed?' });\n * ```\n */\n static show(config: DialogConfig): Promise<DialogResult> {\n const dialog = new Dialog(config);\n\n return dialog.show();\n }\n\n /**\n * Displays a confirm/cancel dialog and resolves to `true` when the user confirms.\n *\n * Buttons are ordered Cancel (default focus) then Confirm, so pressing Enter or\n * Escape both safely default to cancellation.\n *\n * @param title - Text displayed in the title bar.\n * @param message - Body message shown in the content area.\n * @returns A promise resolving to `true` if the user clicked Confirm, `false` otherwise.\n *\n * @example\n * ```typescript\n * if (await Dialog.confirm('Delete record', 'This cannot be undone.')) {\n * store.remove(record);\n * }\n * ```\n */\n static async confirm(title: string, message: string): Promise<boolean> {\n const result = await Dialog.show({\n title,\n message,\n buttons: [\n { ...DialogButtons.Cancel, primary: true },\n DialogButtons.Confirm,\n ],\n });\n\n return result === 'confirm';\n }\n\n /**\n * Displays a severity-toned dialog with a single OK button and resolves once\n * the user acknowledges it. Shared by the {@link Dialog.info} /\n * {@link Dialog.success} / {@link Dialog.warning} / {@link Dialog.error}\n * shorthands.\n *\n * @param severity - The title-bar severity tone (see {@link DialogConfig.severity}).\n * @param title - Text displayed in the title bar.\n * @param message - Body message shown in the content area.\n */\n private static async alert(severity: DialogSeverity, title: string, message: string): Promise<void> {\n await Dialog.show({\n title,\n message,\n severity,\n buttons: [{ ...DialogButtons.Ok, primary: true }],\n });\n }\n\n /**\n * Displays an info-toned dialog with a single OK button and resolves once the\n * user acknowledges it.\n *\n * @param title - Text displayed in the title bar.\n * @param message - Body message shown in the content area.\n *\n * @example\n * ```typescript\n * await Dialog.info('Import complete', 'Loaded 1,204 rows.');\n * ```\n */\n static info(title: string, message: string): Promise<void> {\n return Dialog.alert('info', title, message);\n }\n\n /**\n * Displays a success-toned dialog with a single OK button and resolves once\n * the user acknowledges it.\n *\n * @param title - Text displayed in the title bar.\n * @param message - Body message shown in the content area.\n *\n * @example\n * ```typescript\n * await Dialog.success('Saved', 'Your changes have been stored.');\n * ```\n */\n static success(title: string, message: string): Promise<void> {\n return Dialog.alert('success', title, message);\n }\n\n /**\n * Displays a warning-toned dialog with a single OK button and resolves once\n * the user acknowledges it.\n *\n * @param title - Text displayed in the title bar.\n * @param message - Body message shown in the content area.\n *\n * @example\n * ```typescript\n * await Dialog.warning('Unsaved changes', 'They will be lost if you continue.');\n * ```\n */\n static warning(title: string, message: string): Promise<void> {\n return Dialog.alert('warning', title, message);\n }\n\n /**\n * Displays an error-toned dialog with a single OK button and resolves once\n * the user acknowledges it. The title bar carries the error severity tint and\n * glyph (see {@link DialogConfig.severity}).\n *\n * @param title - Text displayed in the title bar.\n * @param message - Body message shown in the content area.\n *\n * @example\n * ```typescript\n * await Dialog.error('Connection failed', 'Host not allowed.');\n * ```\n */\n static error(title: string, message: string): Promise<void> {\n return Dialog.alert('error', title, message);\n }\n}\n\nconst DialogCallable = callable(Dialog);\ntype DialogCallable = Dialog;\nexport {\n Dialog as _Dialog,\n DialogCallable as Dialog,\n DialogTitleBar\n};\n"],"mappings":"0/BAqBA,IAAM,EAAgC,GAQhC,EAA6B,EAAwB,EAAK,KAAK,MAS/D,EAA6B,KAAK,KAAK,CAAiB,EAAI,EAG5D,EAA8B,EAG9B,EAAiC,EAGjC,EAAmC,IAuDnC,EAAkD,CACpD,OAAW,IAAI,EAAO,EAAG,EAAG,EAAG,CAAC,EAChC,UAAW,OACX,UAAW,gBACX,UAAW,GACX,gBAAiB,8CACjB,gBAAiB,2CAEjB,OAAc,CAAE,OAAQ,2DAA4D,EACpF,aAAc,mCACd,OAAc,+DAClB,EAuCM,QAAN,cAAsB,CAAsD,CASxE,mBAAuD,SAMvD,eAAuD,KACvD,YAA+C,KAI/C,mBAA4D,KAC5D,mBAA4D,KAC5D,eAA4C,KAC5C,gBAA+C,KAC/C,QAAsC,GACtC,iBAAuC,CAAC,EAExC,gBACA,UAWA,YAAY,EAA0B,EAA4C,CAC9E,MAAM,EAA2B,CAAE,GAAG,EAAwB,GAAI,GAAoB,CAAC,CAAG,CAAC,EAE3F,IAAM,EAAO,IAAI,EAEjB,EAAK,cAAc,EAAI,EACvB,KAAK,iBAAiB,CAAI,EAK1B,KAAK,YAAY,EAAS,KAAK,EAC/B,KAAK,WAAW,EAAK,EAKrB,KAAK,WAAW,QAAQ,EACxB,KAAK,YAAY,SAAS,EAC1B,KAAK,QAAQ,CAAC,CAAC,QAAQ,QAAQ,EAE/B,KAAK,oBAAwB,KAAK,YAAY,EAC9C,KAAK,cAAwB,KAAK,YAAY,EAO9C,KAAK,SAAoB,KACzB,KAAK,kBAAoB,KACzB,KAAK,WAAoB,IAC7B,CASA,aAAuB,EAA+B,CAelD,OAdA,MAAM,aAAa,CAAO,EAK1B,KAAK,aAAa,EAAQ,WAAa,KAAK,aAAa,CAAC,EAC1D,KAAK,aAAa,EAAQ,WAAa,KAAK,aAAa,CAAC,EAC1D,KAAK,aAAa,EAAQ,WAAa,KAAK,YAAY,CAAC,EACrD,EAAQ,QAAU,IAAA,IAAW,KAAK,SAAS,EAAQ,KAAK,EAIxD,EAAQ,UAAY,IAAA,KAAW,KAAK,SAAW,EAAQ,SAEpD,IACX,CAQA,aAAa,EAA2B,CAGpC,MAFA,MAAK,WAAa,EAEX,IACX,CAOA,cAAiC,CAC7B,OAAO,KAAK,YAAc,KAAK,gBAAgB,SACnD,CAQA,aAAa,EAAgC,CAGzC,MAFA,MAAK,WAAa,EAEX,IACX,CAOA,cAAmC,CAC/B,OAAO,KAAK,YAAc,KAAK,gBAAgB,SACnD,CAQA,aAAa,EAAsB,CAO/B,MANA,MAAK,WAAa,EAEd,KAAK,iBACL,KAAK,gBAAgB,WAAW,CAAK,EAGlC,IACX,CAOA,aAAuB,CACnB,OAAO,KAAK,YAAc,KAAK,gBAAgB,SACnD,CAUA,SAAS,EAA2B,CAkBhC,OAjBI,IAAS,KACF,KAAK,WAAW,GAG3B,KAAK,OAAS,EAET,KAAK,gBAMN,KAAK,gBAAgB,QAAQ,CAAI,GALjC,KAAK,gBAAkB,IAAI,EAAK,CAAI,EACpC,KAAK,gBAAgB,cAAc,MAAM,EAEzC,KAAK,gBAAgB,KAAK,gBAAiB,CAAC,GAKhD,KAAK,cAAc,EAEZ,KACX,CAOA,UAA0B,CACtB,OAAO,KAAK,MAChB,CAOA,YAAmB,CAUf,MATA,CAEI,KAAK,mBADL,KAAK,gBAAgB,KAAK,eAAe,EAClB,MAG3B,KAAK,OAAS,KAEd,KAAK,cAAc,EAEZ,IACX,CAUA,QAAQ,EAAmC,CACvC,AAEI,KAAK,kBADL,KAAK,gBAAgB,KAAK,cAAc,EAClB,MAG1B,IAAM,EAAkB,OAAO,GAAY,SACrC,IAAI,EAAK,CAAO,EAChB,EAEN,KAAK,eAAiB,EAGtB,IAAM,EAAgB,QAAK,gBAM3B,OAJA,KAAK,gBAAgB,EAAM,CAAW,EAEtC,KAAK,cAAc,EAEZ,IACX,CAOA,SAA4B,CACxB,OAAO,KAAK,cAChB,CAUA,UAAU,EAAe,EAA2B,CAC3C,KAAK,cACN,KAAK,YAAc,IAAI,EACvB,KAAK,YAAY,iBAAiB,IAAI,CAAM,EAE5C,KAAK,aAAa,KAAK,WAAW,GAGtC,IAAM,EAAS,IAAI,EAAO,CAAK,EAM/B,OAJA,EAAO,GAAG,SAAU,CAAO,EAE3B,KAAK,YAAY,aAAa,CAAM,EAE7B,IACX,CAOA,cAAqB,CAMjB,MALA,CAEI,KAAK,eADL,KAAK,gBAAgB,KAAK,WAAW,EAClB,MAGhB,IACX,CAQA,iBAAyB,EAAkB,CAGvC,MAFA,MAAK,eAAiB,EAEf,IACX,CASA,kBAAkB,EAAoB,CAClC,OAAO,KAAK,iBAAiB,EAAE,WAAW,EAAI,CAAE,CACpD,CASA,MAAa,CACT,GAAI,CAAC,KAAK,eAEN,OADA,QAAQ,KAAK,mEAAmE,EACzE,KAGX,KAAK,QAAU,GAIf,EAAa,SAAS,IAAI,EAC1B,KAAK,UAAU,EAAa,UAAU,IAAI,CAAC,EAE3C,IAAM,EAAK,KAAK,WAAW,EAAI,EAqB/B,OAnBA,EAAa,MAAM,CAAE,EAIrB,EAAU,IAAI,EAEd,KAAK,YAAY,EACjB,KAAK,WAAW,EAAI,EAIpB,KAAK,SAAS,EACd,KAAK,YAAY,EAEjB,KAAK,oBAAoB,OAAO,EAChC,KAAK,mBAAqB,EAAS,KAAM,CAAE,WAAY,CAAyB,CAAC,EAEjF,KAAK,0BAA0B,EAExB,IACX,CASA,MAAa,CAoBT,OAnBK,KAAK,SAIV,KAAK,QAAU,GAEf,KAAK,0BAA0B,EAE/B,EAAa,WAAW,IAAI,EAC5B,EAAY,IAAI,EAEhB,KAAK,oBAAoB,OAAO,EAChC,KAAK,mBAAqB,EAAkB,KAAM,CAAE,WAAY,CAAyB,CAAC,EAK1F,KAAK,WAAW,EAET,MAlBI,IAmBf,CAOA,QAAkB,CACd,OAAO,KAAK,OAChB,CASA,iBAAiC,CAC7B,OAAO,KAAK,WAAW,GAAK,IAChC,CAWA,gBAAmC,CAC/B,OAAO,KAAK,YAAc,KAAK,gBAAgB,SACnD,CAMA,cAAqB,CACjB,KAAK,KAAK,CACd,CAQA,kBAAkC,CAC9B,OAAO,KAAK,cAChB,CAQA,SAAkB,CACd,OAAO,EAAa,KAAK,OAC7B,CAQA,UAAiB,CAOb,OANA,MAAM,SAAS,EAEX,KAAK,iBAAmB,KAAK,YAAc,KAAK,gBAChD,KAAK,cAAc,EAGhB,IACX,CAOA,YAA6B,CACrB,KAAK,SACL,KAAK,KAAK,EAcd,KAAK,oBAAoB,OAAO,EAChC,KAAK,mBAAqB,KAC1B,KAAK,oBAAoB,OAAO,EAChC,KAAK,mBAAqB,KAE1B,KAAK,iBAAiB,QAAQ,EAE9B,KAAK,eAAmB,KACxB,KAAK,gBAAmB,KACxB,KAAK,eAAmB,KACxB,KAAK,YAAmB,KACxB,KAAK,gBAAmB,KACxB,KAAK,SAAmB,KAExB,MAAM,WAAW,CACrB,CAcA,eAA8B,CACrB,KAAK,UAIV,KAAK,SAAS,EACd,KAAK,YAAY,EACrB,CAOA,aAA4B,CACxB,GAAI,CAAC,KAAK,eACN,OAGJ,IAAM,EAAa,EAAI,OAAO,eAAe,KAAK,cAAc,EAGhE,GAAI,EAAW,QAAU,GAAK,EAAW,SAAW,EAAG,CACnD,KAAK,KAAK,EACV,MACJ,CAEA,IAAM,EAAY,KAAK,iBAAiB,EAClC,EAAY,GAAW,OAAU,KAAK,SAAS,EAC/C,EAAY,GAAW,QAAU,KAAK,UAAU,EAChD,EAAY,EAAI,OAAO,gBAAgB,EAEvC,EAAW,KAAK,iBAAiB,EAAY,EAAO,EAAQ,CAAE,EAEpE,KAAK,mBAAqB,EAE1B,IAAI,EAAY,EACZ,EAAY,EAEZ,IAAa,OACb,EAAI,EAAW,MAAQ,EAAW,MAAS,GAAU,EACrD,EAAI,EAAW,IAAO,EAAS,GACxB,IAAa,UACpB,EAAI,EAAW,MAAQ,EAAW,MAAS,GAAU,EACrD,EAAI,EAAW,OAAS,GACjB,IAAa,QACpB,EAAI,EAAW,KAAO,EAAQ,EAC9B,EAAI,EAAW,KAAQ,EAAW,OAAS,GAAU,IAErD,EAAI,EAAW,MAAQ,EACvB,EAAI,EAAW,KAAS,EAAW,OAAS,GAAU,GAQ1D,IAAI,EAAO,EACP,EAAO,EAAG,MAAQ,EAAQ,EAC1B,EAAO,EACP,EAAO,EAAG,OAAS,EAAS,EAE5B,IAAa,QACb,GAAQ,EACD,IAAa,OACpB,GAAQ,EACD,IAAa,SACpB,GAAQ,EAER,GAAQ,EAGZ,EAAI,EAAK,MAAM,EAAG,EAAM,CAAI,EAC5B,EAAI,EAAK,MAAM,EAAG,EAAM,CAAI,EAE5B,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,CAAC,EACX,KAAK,SAAS,CAAK,EACnB,KAAK,UAAU,CAAM,EAEjB,KAAK,iBAAmB,KAAK,YAC7B,KAAK,cAAc,CAE3B,CAcA,iBACI,EACA,EACA,EACA,EACgB,CAChB,IAAM,EAAc,EAAO,IACrB,EAAc,EAAG,OAAS,EAAO,OACjC,EAAc,EAAO,KACrB,EAAc,EAAG,MAAS,EAAO,MAEvC,GAAI,KAAK,aAAe,OAAQ,CAC5B,IAAM,EAAS,EAAS,EAClB,EAAS,EAAS,EAElB,EAA6E,CAC/E,CAAE,KAAM,SAAU,MAAO,EAAa,KAAM,CAAO,EACnD,CAAE,KAAM,MAAU,MAAO,EAAa,KAAM,CAAO,EACnD,CAAE,KAAM,QAAU,MAAO,EAAa,KAAM,CAAO,EACnD,CAAE,KAAM,OAAU,MAAO,EAAa,KAAM,CAAO,CACvD,EAIM,EAAU,EAAW,OAAO,GAAK,EAAE,OAAS,EAAE,IAAI,EAClD,EAAU,EAAQ,OAAS,EAAI,EAAU,EAI/C,OAFA,EAAK,MAAM,EAAG,IAAM,EAAE,MAAQ,EAAE,KAAK,EAE9B,EAAK,EAAE,CAAC,IACnB,CAGA,IAAM,KAAQ,GACN,IAAS,MAAmB,GAAe,EAAS,EACpD,IAAS,SAAmB,GAAe,EAAS,EACpD,IAAS,OAAmB,GAAe,EAAS,EAEjD,GAAc,EAAQ,EAGjC,GAAI,KAAK,KAAK,UAAU,EACpB,OAAO,KAAK,WAUhB,IAAM,EAAU,CANZ,IAAQ,SACR,OAAQ,MACR,KAAQ,QACR,MAAQ,MAGI,EAAS,KAAK,YAI9B,OAFA,QAAQ,KAAK,gCAAgC,KAAK,WAAW,6CAA6C,EAAQ,GAAG,EAE9G,CACX,CAYA,aAA4B,CACxB,GAAI,KAAK,gBACL,OAGJ,IAAM,EAAQ,IAAI,EACZ,EAAQ,EAEd,EAAM,mBAAmB,6CAA6C,EACtE,EAAM,SAAS,CAAI,EACnB,EAAM,UAAU,CAAI,EACpB,EAAM,aAAa,eAAe,EAClC,EAAM,iBAAiB,MAAM,EAC7B,EAAM,WAAW,KAAK,UAAU,EAEhC,KAAK,gBAAkB,EAEvB,IAAM,EAAY,KAAK,WAAW,EAAI,EACtC,EAAI,KAAK,aAAa,EAAW,EAAM,WAAW,EAAI,EAAI,EAAI,OAAO,cAAc,CAAS,CAAC,CACjG,CASA,eAA8B,CAC1B,GAAI,CAAC,KAAK,gBAAkB,CAAC,KAAK,gBAC9B,OAGJ,IAAM,EAAa,EAAI,OAAO,eAAe,KAAK,cAAc,EAC1D,EAAa,EACb,EAAa,EAAO,EACpB,EAAa,KAAK,KAAK,EACvB,EAAa,KAAK,KAAK,EACvB,EAAa,KAAK,SAAS,EAC3B,EAAa,KAAK,UAAU,EAK5B,OAAS,EAAe,EAAa,IAAwB,KAAK,IAAI,EAAK,KAAK,IAAI,EAAO,CAAG,CAAC,EAO/F,EAAc,kDAChB,EAEJ,AAOI,EAPA,KAAK,qBAAuB,SACd,iBAAiB,EAAY,kBAAkB,IACtD,KAAK,qBAAuB,MACrB,kBAAkB,EAAY,mBAAmB,IACxD,KAAK,qBAAuB,QACrB,iBAAiB,EAAY,mBAAmB,IAEhD,iBAAiB,EAAY,mBAAmB,IAGlE,KAAK,gBAAgB,UAAU,CAAW,EAE1C,IAAM,EAAS,EAAI,OAAO,gBAAgB,EACpC,EAAS,KAAK,cAAc,EAMlC,GAAI,KAAK,qBAAuB,OAAS,KAAK,qBAAuB,SAAU,CAC3E,IAAM,EAAgB,EAAW,KAAO,EAAW,MAAQ,EACrD,EAAgB,KAAK,IACvB,EACA,EAAyB,EAAW,EAAoB,CAC5D,EACM,EAAgB,KAAK,IACvB,EAAW,EAAO,EAClB,EAAG,MAAQ,EAAyB,EAAW,EAAO,CAC1D,EACM,EAAgB,MAAM,EAAgB,EAAW,EAAO,EAAO,KAAM,EAAW,CAAS,EAE/F,KAAK,gBAAgB,KAAK,CAAM,EAI5B,KAAK,qBAAuB,SAC5B,KAAK,gBAAgB,KAAK,GAAQ,EAAO,GAAG,EAE5C,KAAK,gBAAgB,KAAK,EAAW,EAAO,EAAO,GAAG,CAE9D,KAAO,CACH,IAAM,EAAgB,EAAW,IAAM,EAAW,OAAS,EACrD,EAAgB,KAAK,IACvB,EACA,EAAyB,EAAW,EAAoB,CAC5D,EACM,EAAgB,KAAK,IACvB,EAAW,EAAO,EAClB,EAAG,OAAS,EAAyB,EAAW,EAAO,CAC3D,EACM,EAAgB,MAAM,EAAgB,EAAW,EAAO,EAAO,IAAK,EAAW,CAAS,EAE9F,KAAK,gBAAgB,KAAK,CAAM,EAE5B,KAAK,qBAAuB,QAC5B,KAAK,gBAAgB,KAAK,GAAQ,EAAO,IAAI,EAE7C,KAAK,gBAAgB,KAAK,EAAW,EAAO,EAAO,IAAI,CAE/D,CACJ,CAMA,2BAA0C,CAGtC,GAFA,EAAM,oBAAoB,KAAM,SAAU,KAAK,eAAe,EAE1D,KAAK,eAAgB,CACrB,KAAK,iBAAmB,KAAK,uBAAuB,KAAK,cAAc,EAEvE,IAAK,IAAM,KAAY,KAAK,iBACxB,EAAI,KAAK,YAAY,EAAU,SAAU,KAAK,UAAW,CAAE,QAAS,EAAK,CAAC,CAElF,CACJ,CAKA,2BAA0C,CACtC,EAAM,uBAAuB,KAAM,SAAU,KAAK,eAAe,EAEjE,IAAK,IAAM,KAAY,KAAK,iBACxB,EAAI,KAAK,eAAe,EAAU,SAAU,KAAK,SAAS,EAG9D,KAAK,iBAAmB,CAAC,CAC7B,CASA,uBAA+B,EAAwB,CACnD,IAAM,EAAgB,CAAC,EACnB,EAAwB,EAAI,OAAO,iBAAiB,CAAI,EAE5D,KAAO,GAAU,IAAW,EAAI,OAAO,mBAAmB,GAAG,CACzD,IAAM,EAAQ,EAAI,OAAO,oBAAoB,CAAM,EAC7C,EAAW,EAAM,SAAW,EAAM,UAAY,EAAM,UAEtD,wBAAwB,KAAK,CAAQ,GACrC,EAAI,KAAK,CAAM,EAGnB,EAAS,EAAI,OAAO,iBAAiB,CAAM,CAC/C,CAIA,OAFA,EAAI,KAAK,EAAI,OAAO,mBAAmB,CAAC,EAEjC,CACX,CACJ,EAEM,EAAkB,EAAS,OAAO,ECn+BlC,EAAgE,CAAC,EAQjE,eAAN,cAA6B,CAAiC,CAU1D,YAAY,EAAiC,EAAmD,CAC5F,MAAM,EAAS,CAAE,GAAG,EAA+B,GAAI,GAAoB,CAAC,CAAG,CAAC,EAEhF,IAAM,EAAK,EAAI,OAAO,gBAAgB,EAEtC,KAAK,YAAY,EAAS,KAAK,EAC/B,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,CAAC,EACX,KAAK,SAAS,EAAG,KAAK,EACtB,KAAK,UAAU,EAAG,MAAM,EACxB,KAAK,UAAU,KAAK,EACpB,KAAK,mBAAmB,iCAAiC,CAC7D,CAOA,iBAAiB,EAAgC,CAG7C,OAFA,EAAM,YAAY,KAAM,QAAS,CAAQ,EAElC,IACX,CAKA,QAAe,CACX,IAAM,EAAK,EAAI,OAAO,gBAAgB,EAEtC,KAAK,SAAS,EAAG,KAAK,EACtB,KAAK,UAAU,EAAG,MAAM,CAC5B,CAKA,SAAgB,CACZ,KAAK,cAAc,EACnB,KAAK,WAAW,CACpB,CACJ,EAEM,EAAyB,EAAS,cAAc,ECxDtD,EAAM,SAAS,EAAO,EAAc,EAAa,EAAsB,CAAkB,EA8FzF,IAAM,EAAyB,GACzB,EAAyB,GACzB,EAAyB,GACzB,EAAyB,EACzB,EAAyB,GACzB,EAAyB,GACzB,EAAyB,GACzB,EAA4B,IAC5B,EAA4B,IAC5B,EAA6B,GAM7B,EAAiD,CACnD,KAAS,cACT,QAAS,eACT,QAAS,uBACT,MAAS,oBACb,EAMM,EAAkC,IAOlC,EAAqB,2EASrB,GAAsB,EAQtB,EAA0B,EAO1B,GAA+B,EAoB/B,eAAN,cAA6B,CAAU,CAEnC,WACA,aAAsC,KACtC,YAAoC,KAQpC,YAAY,EAAe,EAAqB,EAAsB,CAClE,MAAM,EAEN,KAAK,mBAAmB,sBAAsB,EAC9C,KAAK,UAAU,CACX,OAAc,OACd,aAAc,sCAClB,CAAC,EACD,KAAK,iBAAiB,CAAE,MAAO,EAAG,OAAQ,CAAa,CAAC,EAExD,KAAK,WAAa,IAAI,EAAK,CAAK,EAChC,KAAK,WAAW,cAAc,MAAM,EACpC,KAAK,WAAW,YAAY,QAAQ,EACpC,KAAK,WAAW,gBAAgB,UAAU,EAC1C,KAAK,WAAW,cAAc,QAAQ,EAGtC,KAAK,WAAW,eAAe,EAA8B,EAC7D,KAAK,aAAa,KAAK,UAAU,EAE7B,IACA,KAAK,aAAe,IAAI,EAAO,CAAE,MAAO,OAAQ,CAAC,EACjD,KAAK,aAAa,UAAU,IAAI,EAAO,EAAG,EAAG,EAAG,CAAC,CAAC,EAClD,KAAK,aAAa,UAAU,MAAM,EAClC,KAAK,aAAa,qBAAqB,EACvC,KAAK,aAAa,mBAAmB,aAAa,EAClD,KAAK,aAAa,YAAY,EAC9B,KAAK,aAAa,mBAAmB,EACrC,KAAK,aAAa,iBAAiB,EAMnC,KAAK,aAAa,wBAAwB,yDAAyD,EACnG,KAAK,aAAa,0BAA0B,0DAA0D,EACtG,KAAK,aAAa,0BAA0B,EAC5C,KAAK,aAAa,4BAA4B,EAC9C,KAAK,aAAa,iBAAiB,CAAE,MAAO,EAAY,OAAQ,CAAW,CAAC,EAC5E,KAAK,aAAa,KAAK,YAAY,EAEnC,KAAK,aAAa,GAAG,SAAU,CAAO,EAE9C,CAQA,gBAAgC,CAC5B,OAAO,KAAK,YAChB,CAQA,cAAqB,CACjB,OAAO,KAAK,UAChB,CAcA,SAAS,EAAoB,CACzB,AAEI,KAAK,eADL,KAAK,gBAAgB,KAAK,WAAW,EAClB,MAGvB,IAAM,EAAQ,IAAI,EAAM,CAAI,EAQ5B,OAPA,EAAM,iBAAiB,MAAM,EAC7B,EAAM,iBAAiB,CAAE,MAAO,GAAI,OAAQ,EAAG,CAAC,EAChD,KAAK,YAAc,EACnB,KAAK,aAAa,CAAK,EAEvB,KAAK,SAAS,EAEP,IACX,CAOA,YAAmB,CAOf,OANI,KAAK,cACL,KAAK,gBAAgB,KAAK,WAAW,EACrC,KAAK,YAAc,KACnB,KAAK,SAAS,GAGX,IACX,CAOA,UAAyB,CACrB,OAAO,KAAK,WAChB,CAQA,UAAiB,CACb,MAAM,SAAS,EAEf,IAAM,EAAM,KAAK,iBAAiB,EAElC,GAAI,CAAC,EACD,OAAO,KAGX,IAAM,EAAU,EAAI,MACd,EAAU,EAAI,OACd,EAAU,EAAI,EAAa,EAC3B,EAAU,KAAK,OAAO,EAAI,GAAc,CAAC,EACzC,EAAa,KAAK,aAClB,EACC,EAAI,EAEP,EAAS,EAEb,GAAI,KAAK,YAAa,CAClB,IAAM,EAAY,KAAK,YAAY,iBAAiB,GAAK,CAAE,MAAO,GAAI,OAAQ,EAAG,EAC3E,EAAY,KAAK,IAAI,EAAG,KAAK,OAAO,EAAI,EAAU,QAAU,CAAC,CAAC,EAEpE,KAAK,YAAY,KAAK,EAAI,EAAI,CAAW,EACzC,KAAK,YAAY,KAAK,EAAI,EAAI,CAAM,EACpC,KAAK,YAAY,SAAS,EAAU,KAAK,EACzC,KAAK,YAAY,UAAU,EAAU,MAAM,EAE3C,EAAS,EAAc,EAAU,MAAQ,EAC7C,CAGA,IAAM,EAAa,KAAK,IAAI,EAAG,EAAa,EAAS,CAAe,EAC9D,EAAa,EAAI,EAiBvB,OAfA,KAAK,WAAW,KAAK,EAAI,EAAI,CAAM,EACnC,KAAK,WAAW,KAAK,EAAI,EAAI,EAAW,EACxC,KAAK,WAAW,SAAS,CAAU,EACnC,KAAK,WAAW,UAAU,CAAM,EAE5B,KAAK,eACL,KAAK,aAAa,KAAK,EAAI,EAAI,CAAM,EACrC,KAAK,aAAa,KAAK,EAAI,EAAI,CAAO,EACtC,KAAK,aAAa,SAAS,CAAU,EACrC,KAAK,aAAa,UAAU,CAAU,EAGtC,KAAK,aAAa,SAAS,GAGxB,IACX,CACJ,EAUM,gBAAN,cAA8B,CAAU,CAEpC,SAAsC,CAAC,EAMvC,YAAY,EAA+B,EAA0C,CACjF,MAAM,EAEN,KAAK,UAAU,CACX,OAAW,OACX,UAAW,sCACf,CAAC,EACD,KAAK,mBAAmB,sBAAsB,EAC9C,KAAK,iBAAiB,CAAE,MAAO,EAAG,OAAQ,CAAc,CAAC,EAEzD,IAAK,IAAM,KAAO,EAAS,CACvB,IAAM,EAAS,IAAI,EAAO,EAAI,KAAM,EAAI,QAAU,IAAA,GAAmC,IAAA,GAAvB,CAAE,MAAO,EAAI,KAAM,CAAa,EACxF,EAAS,EAAI,QAAU,SAM7B,GAJI,EAAI,SACJ,EAAI,mBAAmB,qDAAqD,EAG5E,EAAI,QAAU,IAAA,GAAW,CACzB,IAAM,EAAQ,EAAI,SAAS,EACrB,EAAO,EAAI,KAEb,IAAU,MAAQ,GAClB,EAAM,mBAAmB,CAAI,CAErC,CAEA,EAAI,GAAG,aAAgB,EAAS,CAAM,CAAC,EACvC,KAAK,SAAS,KAAK,CAAG,EACtB,KAAK,aAAa,CAAG,CACzB,CACJ,CAOA,UAAiB,CACb,MAAM,SAAS,EAEf,IAAM,EAAM,KAAK,iBAAiB,EAElC,GAAI,CAAC,EACD,OAAO,KAGX,IAAM,EAAY,EAAI,OAAS,GACzB,EAAY,KAAK,SAAS,OAAS,GAAgB,KAAK,SAAS,OAAS,GAAK,EAC/E,EAAY,KAAK,OAAO,EAAI,MAAQ,GAAU,CAAC,EAErD,IAAK,IAAM,KAAO,KAAK,SACnB,EAAI,KAAK,EAAI,EAAI,CAAC,EAClB,EAAI,KAAK,EAAI,EAAI,CAAY,EAC7B,EAAI,SAAS,CAAY,EACzB,EAAI,UAAU,CAAI,EAElB,EAAI,SAAS,EAEb,GAAK,GAGT,OAAO,IACX,CACJ,EAgCa,EAAgB,CAEzB,QAAS,CAAE,KAAM,UAAW,OAAQ,UAAW,MAAO,eAAgB,KAAM,mCAAoC,EAEhH,GAAS,CAAE,KAAM,KAAW,OAAQ,UAAW,MAAO,eAAgB,KAAM,mCAAoC,EAEhH,OAAS,CAAE,KAAM,SAAW,OAAQ,SAAW,MAAO,QAAgB,KAAM,kCAAoC,EAEhH,MAAS,CAAE,KAAM,QAAW,OAAQ,QAAW,MAAO,QAAgB,KAAM,kCAAoC,CACpH,EAGM,EAAwC,CAC1C,CAAE,GAAG,EAAc,GAAI,QAAS,EAAK,CACzC,EAuBM,EAAN,MAAM,eAAe,CAAsC,CAEvD,UACA,kBACA,WACA,UACA,QAEA,gBAAqE,KACrE,eAA2C,KAC3C,iBACA,oBAKA,kBAA+D,KAC/D,qBAA+D,KAC/D,mBAA+D,KAC/D,sBAA+D,KAO/D,YAA+B,GAO/B,YAAY,EAAsB,CAC9B,MAAM,EAEN,KAAK,QAAa,EAElB,IAAM,EAAe,KAAK,IAAI,EAAkB,EAAO,OAAS,GAAG,EAC7D,EAAe,EAAO,SAAW,EACjC,EAAgB,KAAK,IAAI,EAAoB,KAAK,qBAAqB,CAAM,CAAC,EAC9E,EAAgB,KAAK,IACvB,EACA,EAAO,QAAW,EAAe,EAAgB,CACrD,EAEA,KAAK,YAAY,EAAS,KAAK,EAC/B,KAAK,SAAS,CAAW,EACzB,KAAK,UAAU,CAAY,EAI3B,KAAK,mBAAmB,sBAAsB,EAC9C,KAAK,gBAAgB,iCAAiC,EACtD,KAAK,UAAU,4BAA4B,EAC3C,KAAK,YAAY,QAAQ,EAEzB,KAAK,WAAW,QAAQ,EAExB,IAAM,EAAS,IAAI,EA8BnB,GA7BA,EAAO,oBAAoB,CAAC,EAC5B,KAAK,iBAAiB,CAAM,EAE5B,KAAK,UAAY,IAAI,eAAe,EAAO,UAAa,KAAK,KAAK,OAAO,EAAG,EAAO,cAAgB,EAAK,EACxG,KAAK,aAAa,KAAK,UAAW,CAAE,UAAW,EAAU,KAAM,CAAC,EAI5D,EAAO,SACP,KAAK,oBAAoB,EAAO,QAAQ,EAExC,KAAK,mBAAmB,KAAK,qBAAqB,CAAO,CAAC,EAY9D,KAAK,kBAAoB,IAAI,EAAM,CAC/B,WAAe,IACf,cAAe,IAAI,GACnB,OAAe,IAAI,EAAO,EAAG,EAAG,EAAG,CAAC,CACxC,CAAC,EAEG,EAAO,iBACP,KAAK,kBAAkB,aAAa,EAAO,gBAAgB,MACxD,CACH,IAAM,EAAc,IAAI,EAAK,EAAO,SAAW,EAAE,EACjD,EAAY,cAAc,QAAQ,EAClC,EAAY,aAAa,YAAY,EACrC,EAAY,WAAW,IAAI,EAAO,GAAI,GAAI,GAAI,EAAE,CAAC,EACjD,EAAY,cAAc,MAAM,EAChC,EAAY,UAAU,MAAM,EAC5B,KAAK,kBAAkB,aAAa,CAAW,CACnD,CAEA,KAAK,aAAa,KAAK,kBAAmB,CAAE,UAAW,EAAU,MAAO,CAAC,EAEzE,KAAK,WAAa,IAAI,gBAAgB,EAAU,GAAW,KAAK,KAAK,CAAM,CAAC,EAC5E,KAAK,aAAa,KAAK,WAAY,CAAE,UAAW,EAAU,KAAM,CAAC,EAEjE,KAAK,UAAY,IAAI,EAErB,KAAK,iBAAuB,GAAqB,KAAK,UAAU,CAAC,EACjE,KAAK,wBAA4B,KAAK,iBAAiB,CAC3D,CAaA,qBAA6B,EAA4D,CACrF,IAAM,EAAU,IAAI,IAAI,EAAQ,IAAI,GAAK,EAAE,QAAU,QAAQ,CAAC,EAU9D,OARI,EAAQ,OAAS,GAAK,EAAQ,IAAI,SAAS,EACpC,OAGP,EAAQ,IAAI,SAAS,GAAK,EAAQ,IAAI,QAAQ,EACvC,SAGJ,OACX,CAUA,mBAA2B,EAA4C,CACnE,GAAI,IAAY,QACZ,OAGJ,IAAM,EAAQ,IAAY,OAAS,8BAAgC,gCAC7D,EAAQ,IAAY,OAAS,8BAAgC,gCAKnE,GAHA,KAAK,UAAU,mBAAmB,CAAK,EACvC,KAAK,UAAU,aAAa,CAAC,CAAC,mBAAmB,CAAK,EAElD,IAAY,OAAQ,CACpB,KAAK,UAAU,SAAS,aAAa,EAErC,IAAM,EAAc,KAAK,UAAU,SAAS,EAExC,IAAgB,MAChB,EAAY,mBAAmB,CAAK,CAE5C,CACJ,CAUA,oBAA4B,EAAgC,CACxD,IAAM,EAAQ,4BAA4B,EAAS,MAC7C,EAAQ,4BAA4B,EAAS,UAEnD,KAAK,UAAU,mBAAmB,CAAK,EACvC,KAAK,UAAU,aAAa,CAAC,CAAC,mBAAmB,CAAK,EACtD,KAAK,UAAU,SAAS,EAAe,EAAS,EAEhD,IAAM,EAAc,KAAK,UAAU,SAAS,EAExC,IAAgB,MAChB,EAAY,mBAAmB,CAAK,CAE5C,CAeA,qBAA6B,EAA8B,CACvD,GAAI,EAAO,iBAAkB,CACzB,IAAM,EAAK,EAAO,iBAAiB,iBAAiB,EAEpD,GAAI,EACA,OAAO,EAAG,MAElB,CAEA,MAAO,IACX,CAQA,MAA8B,CAC1B,OAAO,IAAI,QAAS,GAAY,CAC5B,KAAK,gBAAkB,EACvB,KAAK,KAAK,CACd,CAAC,CACL,CAiBA,iBAAwB,CACpB,GAAI,CAAC,KAAK,WAAW,EACjB,OAAO,KAGX,IAAM,EAAgB,KAAK,IAAI,EAAoB,KAAK,qBAAqB,KAAK,OAAO,CAAC,EACpF,EAAgB,KAAK,IAAI,EAAmB,EAAe,EAAgB,CAAa,EAExF,EAAS,EAAI,OAAO,gBAAgB,EACpC,EAAS,KAAK,IAAI,EAAQ,KAAK,IAAI,EAAmB,EAAG,OAAS,EAA0B,CAAC,EAUnG,OARI,IAAW,KAAK,UAAU,EACnB,MAGX,KAAK,UAAU,CAAM,EACrB,KAAK,eAAe,EACpB,KAAK,OAAO,EAEL,KACX,CAKA,MAAqB,CACjB,KAAK,eAAiB,EAAI,OAAO,iBAAiB,EAE9C,KAAK,QAAQ,iBAAmB,KAAK,QAAQ,cAAgB,IAC7D,KAAK,UAAU,qBAAuB,CAAE,KAAK,KAAK,OAAO,CAAG,CAAC,EAMjE,EAAa,SAAS,IAAI,EAE1B,IAAM,EAAS,EAAa,UAAU,IAAI,EAC1C,KAAK,UAAU,CAAM,EACrB,KAAK,UAAU,UAAU,EAAS,CAAC,EAEnC,IAAM,EAAa,KAAK,UAAU,WAAW,EAAI,EACjD,EAAa,MAAM,CAAU,EAE7B,IAAM,EAAW,KAAK,WAAW,EAAI,EACrC,EAAa,MAAM,CAAQ,EAI3B,EAAU,IAAI,EAEd,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,KAAK,UAAU,EAOf,EAAU,oBAAsB,KAAK,gBAAgB,CAAC,EAEtD,EAAM,oBAAoB,KAAM,UAAW,KAAK,gBAAgB,EAChE,EAAM,oBAAoB,KAAM,SAAU,KAAK,mBAAmB,EAOlE,EAAU,oBAAsB,KAAK,WAAW,CAAC,CACrD,CAOA,WAA0B,CACtB,IAAM,EAAO,KAAK,WAAW,EACvB,EAAO,KAAK,UAAU,WAAW,EAElC,IAIL,KAAK,mBAAmB,OAAO,EAC/B,KAAK,kBAAoB,EAAU,KAAK,EAAI,CACxC,KAAY,CAAE,QAAS,IAAK,UAAW,aAAc,EACrD,GAAY,CAAE,QAAS,IAAK,UAAW,UAAc,EACrD,WAAY,EACZ,WAAY,CAAC,UAAW,WAAW,CACvC,CAAC,EAEG,IACA,KAAK,sBAAsB,OAAO,EAClC,KAAK,qBAAuB,EAAU,KAAK,EAAM,CAC7C,KAAY,CAAE,QAAS,GAAI,EAC3B,GAAY,CAAE,QAAS,GAAI,EAC3B,WAAY,EACZ,WAAY,CAAC,SAAS,CAC1B,CAAC,GAET,CAKA,QAAuB,CACnB,IAAM,EAAK,EAAI,OAAO,gBAAgB,EAChC,EAAK,KAAK,IAAI,EAAG,KAAK,OAAO,EAAG,MAAS,KAAK,SAAS,GAAM,CAAC,CAAC,EAC/D,EAAK,KAAK,IAAI,EAAG,KAAK,OAAO,EAAG,OAAS,KAAK,UAAU,GAAK,CAAC,CAAC,EAErE,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,CAAC,CACf,CAYA,YAA2B,CACvB,IAAM,EAAY,KAAK,sBAAsB,EAE7C,GAAI,EAAW,CACX,EAAI,KAAK,MAAM,CAAS,EAExB,MACJ,CAEA,IAAM,EAAY,KAAK,kBAAkB,WAAW,EAC9C,EAAY,EAAY,EAAI,OAAO,iBAAiB,EAAW,CAAkB,EAAI,CAAC,EAE5F,GAAI,EAAU,OAAS,EAAG,CACtB,EAAI,KAAK,MAAM,EAAU,EAAE,EAE3B,MACJ,CAEA,IAAM,EAAU,KAAK,qBAAqB,EAE1C,GAAI,EAAS,CACT,EAAI,KAAK,MAAM,CAAO,EAEtB,MACJ,CAEA,IAAM,EAAY,KAAK,WAAW,EAC5B,EAAY,EAAK,EAAI,OAAO,iBAAiB,EAAI,CAAkB,EAAI,CAAC,EAE1E,EAAU,OAAS,GACnB,EAAI,KAAK,MAAM,EAAU,EAAE,CAEnC,CAYA,uBAA+C,CAE3C,IAAM,EADY,KAAK,QAAQ,cACF,WAAW,EAUxC,OARK,EAID,EAAI,OAAO,QAAQ,EAAS,CAAkB,EACvC,EAGJ,EAAI,OAAO,cAAc,EAAS,CAAkB,EAPhD,IAQf,CAWA,sBAA8C,CAE1C,IAAM,GADU,KAAK,QAAQ,SAAW,EAAA,CAChB,UAAU,GAAK,EAAE,OAAO,EAEhD,GAAI,EAAQ,EACR,OAAO,KAGX,IAAM,EAAQ,KAAK,WAAW,WAAW,EAGzC,OAFkB,EAAQ,EAAI,OAAO,iBAAiB,EAAO,CAAkB,EAAI,CAAC,EAAA,CAEnE,IAAU,IAC/B,CAOA,cAAiC,CAC7B,IAAM,EAAK,KAAK,WAAW,EAM3B,OAJK,EAIE,EAAI,OAAO,iBAAiB,EAAI,CAAkB,CAAC,CACrD,OAAO,GAAM,CAAC,EAAI,OAAO,aAAa,EAAI,UAAU,CAAC,EAJ/C,CAAC,CAKhB,CAQA,UAAkB,EAAwC,CAKtD,GAAI,EAAE,MAAQ,QACV,OAAO,KAAK,QAAQ,CAAC,EAGzB,GAAI,EAAE,MAAQ,MAAO,CACjB,IAAM,EAAY,KAAK,aAAa,EAEpC,GAAI,EAAU,SAAW,EACrB,MAAO,CAAE,KAAM,GAAM,QAAS,EAAK,EAGvC,IAAM,EAAQ,EAAU,GAClB,EAAQ,EAAU,EAAU,OAAS,GAE3C,GAAI,EAAE,SACE,IAAA,EAAI,OAAO,iBAAiB,IAAM,EAGlC,OAFA,EAAI,KAAK,MAAM,CAAI,EAEZ,CAAE,KAAM,GAAM,QAAS,EAAK,CACvC,MAEA,GAAI,EAAI,OAAO,iBAAiB,IAAM,EAGlC,OAFA,EAAI,KAAK,MAAM,CAAK,EAEb,CAAE,KAAM,GAAM,QAAS,EAAK,CAG/C,CAGJ,CAcA,QAAgB,EAAyC,CACrD,IAAM,EAAS,EAAI,OAAO,iBAAiB,EACrC,EAAS,EAAS,EAAI,OAAO,WAAW,CAAM,CAAC,CAAC,YAAY,EAAI,KAEtE,GAAI,IAAQ,YAAc,IAAQ,SAC9B,OAGJ,IAAM,EAAS,KAAK,cAAc,EAE9B,OAAW,KAMf,OAFA,KAAK,KAAK,CAAM,EAET,CAAE,KAAM,GAAM,QAAS,EAAK,CACvC,CASA,eAA6C,CAEzC,IAAM,GADU,KAAK,QAAQ,SAAW,EAAA,CAChB,KAAK,GAAK,EAAE,OAAO,EAE3C,OAAO,EAAW,EAAQ,QAAU,SAAY,IACpD,CAWA,kBAAiC,CAC7B,KAAK,UAAU,OAAO,EACtB,KAAK,gBAAgB,EACrB,KAAK,OAAO,CAChB,CAWA,KAAK,EAA4B,CAC7B,EAAM,uBAAuB,KAAM,UAAW,KAAK,gBAAgB,EACnE,EAAM,uBAAuB,KAAM,SAAU,KAAK,mBAAmB,EAErE,IAAM,aAAuB,CACzB,KAAK,YAAc,GAEnB,KAAK,UAAU,QAAQ,EACvB,KAAK,cAAc,EACnB,KAAK,WAAW,EAEhB,EAAa,WAAW,IAAI,EAC5B,EAAY,IAAI,EAEZ,KAAK,iBAAmB,MACxB,EAAI,KAAK,MAAM,KAAK,cAAc,EAGtC,AAEI,KAAK,mBADL,KAAK,gBAAgB,CAAM,EACJ,KAE/B,EAEM,EAAO,KAAK,WAAW,EACvB,EAAO,KAAK,UAAU,WAAW,EAwBvC,OAtBK,GAKL,KAAK,oBAAoB,OAAO,EAChC,KAAK,mBAAqB,EAAU,KAAK,EAAI,CACzC,GAAY,CAAE,QAAS,IAAK,UAAW,aAAc,EACrD,WAAY,EACZ,WAAY,CAAC,UAAW,WAAW,EACnC,WAAY,QAChB,CAAC,EAEG,IACA,KAAK,uBAAuB,OAAO,EACnC,KAAK,sBAAwB,EAAU,KAAK,EAAM,CAC9C,GAAY,CAAE,QAAS,GAAI,EAC3B,WAAY,EACZ,WAAY,CAAC,SAAS,CAC1B,CAAC,GAGE,OArBH,SAAS,EACF,KAqBf,CAQA,YAA6B,CACzB,KAAK,mBAAmB,OAAO,EAC/B,KAAK,kBAAoB,KACzB,KAAK,sBAAsB,OAAO,EAClC,KAAK,qBAAuB,KAC5B,KAAK,oBAAoB,OAAO,EAChC,KAAK,mBAAqB,KAC1B,KAAK,uBAAuB,OAAO,EACnC,KAAK,sBAAwB,KAWxB,KAAK,cACN,KAAK,UAAU,QAAQ,EAEvB,EAAa,WAAW,IAAI,EAC5B,EAAY,IAAI,EAEhB,AAEI,KAAK,mBADL,KAAK,gBAAgB,OAAO,EACL,OAI/B,MAAM,WAAW,CACrB,CAOA,qBAAiC,CAC7B,OAAO,KAAK,iBAChB,CAYA,qBAAyC,CACrC,MAAO,EACX,CAcA,aAA8B,CAC1B,OAAO,KAAK,SAChB,CASA,iBAAiC,CAC7B,OAAO,KAAK,WAAW,GAAK,IAChC,CAUA,gBAAmC,CAC/B,MAAO,OACX,CAaA,cAAqB,CACb,KAAK,QAAQ,cAAgB,IAIjC,KAAK,KAAK,OAAO,CACrB,CAQA,SAAkB,CACd,OAAO,EAAa,KAAK,MAC7B,CAaA,OAAO,KAAK,EAA6C,CAGrD,OAAO,IAFY,OAAO,CAEnB,CAAA,CAAO,KAAK,CACvB,CAmBA,aAAa,QAAQ,EAAe,EAAmC,CAUnE,OAAO,MATc,OAAO,KAAK,CAC7B,QACA,UACA,QAAS,CACL,CAAE,GAAG,EAAc,OAAQ,QAAS,EAAK,EACzC,EAAc,OAClB,CACJ,CAAC,IAEiB,SACtB,CAYA,aAAqB,MAAM,EAA0B,EAAe,EAAgC,CAChG,MAAM,OAAO,KAAK,CACd,QACA,UACA,WACA,QAAS,CAAC,CAAE,GAAG,EAAc,GAAI,QAAS,EAAK,CAAC,CACpD,CAAC,CACL,CAcA,OAAO,KAAK,EAAe,EAAgC,CACvD,OAAO,OAAO,MAAM,OAAQ,EAAO,CAAO,CAC9C,CAcA,OAAO,QAAQ,EAAe,EAAgC,CAC1D,OAAO,OAAO,MAAM,UAAW,EAAO,CAAO,CACjD,CAcA,OAAO,QAAQ,EAAe,EAAgC,CAC1D,OAAO,OAAO,MAAM,UAAW,EAAO,CAAO,CACjD,CAeA,OAAO,MAAM,EAAe,EAAgC,CACxD,OAAO,OAAO,MAAM,QAAS,EAAO,CAAO,CAC/C,CACJ,EAEM,GAAiB,EAAS,CAAM"}
@@ -1,2 +0,0 @@
1
- import{t as e}from"./DOM-C-Edb3tA.js";import{b as t,h as n,t as r,v as i}from"./Component-B0ShfPVi.js";var a=new Map;a.set(`unicode-arrow-up`,{kind:`char`,char:`▲`}),a.set(`unicode-arrow-down`,{kind:`char`,char:`▼`}),a.set(`unicode-arrow-left`,{kind:`char`,char:`◀`}),a.set(`unicode-arrow-right`,{kind:`char`,char:`▶`});var o=`http://www.w3.org/2000/svg`,s=`ts-glyph-`,c=!1,l=null;function registerGlyph(e){a.set(e.name,e),e.kind===`svg`&&c&&_addSymbolToSprite(e.name,e)}function unregisterGlyph(e){let t=a.get(e);a.delete(e),t&&t.kind===`svg`&&c&&_removeSymbolFromSprite(e)}function lookupGlyph(e){return a.get(e)}function ensureGlyphSprite(){if(c)return;let t=e.sink.createElementNS(o,`svg`);e.sink.apply(t,{setAttr:{"aria-hidden":`true`,focusable:`false`},style:{position:`absolute`,width:`0`,height:`0`,overflow:`hidden`}}),e.sink.appendChild(e.source.getBody(),t),l=t,c=!0}function ensureGlyphSymbolMounted(e){if(!c)return;let t=a.get(e);t&&t.kind===`svg`&&_addSymbolToSprite(e,t)}function _addSymbolToSprite(t,n){if(!l||n.kind!==`svg`)return;let r=s+t;if(e.source.querySelector(l,`#${e.source.escapeSelector(r)}`))return;let i=e.sink.createElementNS(o,`symbol`);e.sink.apply(i,{setAttr:{id:r,viewBox:n.viewBox}});let a=e.sink.createElementNS(o,`path`);e.sink.apply(a,{setAttr:{d:n.path}}),e.sink.appendChild(i,a),e.sink.appendChild(l,i)}function _removeSymbolFromSprite(t){if(!l)return;let n=s+t,r=e.source.querySelector(l,`#${e.source.escapeSelector(n)}`);if(r){let t=e.source.querySelector(r,`path`);e.sink.removeChild(l,r),e.sink.release(r),t&&e.sink.release(t)}}var u=`ts-ui-glyph-`,d=new Set,f=!1;function ensureGlyphKeyframes(){f||(f=!0,t.ensureKeyframes(`ts-ui-glyph-spin`,`from { transform: rotate(0deg); } to { transform: rotate(360deg); }`),t.ensureKeyframes(`ts-ui-glyph-pulse`,`0%, 12.5% { transform: rotate(0deg); } 12.5%, 25% { transform: rotate(45deg); } 25%, 37.5% { transform: rotate(90deg); } 37.5%, 50% { transform: rotate(135deg); } 50%, 62.5% { transform: rotate(180deg); } 62.5%, 75% { transform: rotate(225deg); } 75%, 87.5% { transform: rotate(270deg); } 87.5%, 100% { transform: rotate(315deg); }`),t.ensureKeyframes(`ts-ui-glyph-beat`,`0%, 90% { transform: scale(1); } 45% { transform: scale(1.25); }`),new t({scope:`class`,name:`ts-ui-glyph-spin`,styles:{animation:`ts-ui-glyph-spin var(--ts-ui-glyph-spin-duration, 2000ms) linear infinite`}}),new t({scope:`class`,name:`ts-ui-glyph-pulse`,styles:{animation:`ts-ui-glyph-pulse var(--ts-ui-glyph-pulse-duration, 1000ms) steps(8) infinite`}}),new t({scope:`class`,name:`ts-ui-glyph-beat`,styles:{animation:`ts-ui-glyph-beat var(--ts-ui-glyph-beat-duration, 1000ms) ease-in-out infinite`}}))}function _onReducedMotionChange(){for(let e of Array.from(d)){let t=e.deref();if(!t){d.delete(e);continue}t._syncReducedMotion()}}e.source.matchMedia(`(prefers-reduced-motion: reduce)`).addChangeListener(_onReducedMotionChange);var p={preferredSize:{width:16,height:16},tag:`span`},Glyph=class extends r{_name;_def;static register(...e){for(let t of e)registerGlyph(t)}static unregister(e){unregisterGlyph(e)}constructor(e,t,n){let r=lookupGlyph(e);if(!r)throw Error(`Unknown glyph: `+e);super(t,{...p,...n??{}}),this._name=e,this._def=r,r.kind===`char`&&(this._options.lineHeight===void 0&&this.setLineHeight(`1`),this._options.textAlign===void 0&&this.setTextAlign(`center`))}setPreferredSize(e){return super.setPreferredSize(e),super.setMinSize(e),super.setMaxSize(e),this}getBaseline(){let e=this.getPreferredSize();return e?e.height-3:null}getGlyphName(){return this._name}getFontSize(){return this._options.fontSize??null}setFontSize(e){return this._options.fontSize=e,this.setElementCSSRule(`fontSize`,e+`px`),this}getLineHeight(){let e=this._options.lineHeight;return e===void 0?null:typeof e==`number`?e+`px`:e}setLineHeight(e){return this._options.lineHeight=e,this.setElementCSSRule(`lineHeight`,typeof e==`number`?e+`px`:e),this}getTextAlign(){return this._options.textAlign??null}setTextAlign(e){return this._options.textAlign=e,this.setElementCSSRule(`textAlign`,e),this}getAnimated(){return this._glyphAnimation}setAnimated(t){if(this._glyphAnimation===t)return this;let n=this._glyphAnimation;this._glyphAnimation=t;let r=this.getElement();return r&&n&&e.sink.apply(r,{removeClass:[u+n]}),t===null?(this.setElementCSSRule(`animationDuration`,null),this._animatedRef&&=(d.delete(this._animatedRef),null),this):(ensureGlyphKeyframes(),this._animatedRef||(this._animatedRef=new WeakRef(this),d.add(this._animatedRef)),!i.isReducedMotion()&&r&&e.sink.apply(r,{addClass:[u+t]}),this._glyphAnimationDuration>0&&this.setElementCSSRule(`animationDuration`,this._glyphAnimationDuration+`ms`),this)}clearAnimated(){return this.setAnimated(null)}onEffectiveVisibilityChange(e){super.onEffectiveVisibilityChange(e),this._glyphAnimation!=null&&this.setAnimationPlayState(e?null:`paused`)}getAnimationDuration(){return this._glyphAnimationDuration}setAnimationDuration(e){return this._glyphAnimationDuration=e,this._glyphAnimation!=null&&!i.isReducedMotion()&&this.setElementCSSRule(`animationDuration`,e>0?e+`ms`:null),this}_syncReducedMotion(){let t=this._glyphAnimation;if(!t)return;let n=this.getElement(!0),r=u+t;i.isReducedMotion()?(e.sink.apply(n,{removeClass:[r]}),this.setElementCSSRule(`animationDuration`,null)):(e.sink.apply(n,{addClass:[r]}),this._glyphAnimationDuration>0&&this.setElementCSSRule(`animationDuration`,this._glyphAnimationDuration+`ms`))}applyOptions(e){super.applyOptions(e),e.fontSize!==void 0&&this.setFontSize(e.fontSize),e.lineHeight!==void 0&&this.setLineHeight(e.lineHeight),e.textAlign!==void 0&&this.setTextAlign(e.textAlign),e.animationDuration!==void 0&&this.setAnimationDuration(e.animationDuration);let t=this.getPreferredSizeConstraint();return t&&(e.minSize===void 0&&this.setMinSize({width:t.width,height:t.height}),e.maxSize===void 0&&this.setMaxSize({width:t.width,height:t.height})),e.animation!==void 0&&this.setAnimated(e.animation),this}createRootElement(){let t=super.createRootElement();if(this._def.kind!==`svg`)return t;ensureGlyphSprite(),ensureGlyphSymbolMounted(this._name);let n=`http://www.w3.org/2000/svg`,r=e.sink.createElementNS(n,`svg`);e.sink.apply(r,{style:{position:`absolute`,left:`0`,top:`0`,width:`100%`,height:`100%`,display:`block`},setAttr:{fill:`currentColor`,"aria-hidden":`true`,focusable:`false`}});let i=e.sink.createElementNS(n,`use`);return e.sink.apply(i,{setAttr:{href:`#`+s+this._name}}),e.sink.appendChild(r,i),e.sink.appendChild(t,r),this.trackHandle(r),this.trackHandle(i),t}render(){let t=super.render();this._def.kind===`char`&&e.sink.apply(t,{text:this._def.char}),this._glyphAnimation&&!i.isReducedMotion()&&e.sink.apply(t,{addClass:[u+this._glyphAnimation]});let n=this._options.preferredSize;return n&&(this.setElementStyle(`width`,n.width+`px`),this.setElementStyle(`height`,n.height+`px`)),t}},m=n(Glyph);export{m as t};
2
- //# sourceMappingURL=Glyph-_VeBacS2.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Glyph-_VeBacS2.js","names":[],"sources":["../../src/typescript/lib/component/display/Glyphs.ts","../../src/typescript/lib/component/display/Glyph.ts"],"sourcesContent":["// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { DOM } from \"~/core/DOM.js\";\nimport type { Handle } from \"~/core/DOM.js\";\n\n/**\n * Tagged union describing how a glyph is rendered.\n *\n * @remarks\n * - `kind: \"svg\"` entries supply a `viewBox` and an SVG `<path>` `d` attribute.\n * The path data is mounted once into a shared hidden `<svg>` sprite and each\n * Glyph instance references it via `<svg><use href=\"#...\"/></svg>` so the\n * path string is not duplicated in the DOM.\n * - `kind: \"char\"` entries carry a single Unicode character rendered inside a\n * `<span>`; the character follows the inherited text colour.\n */\nexport type GlyphDef =\n | { kind: \"svg\", viewBox: string; path: string }\n | { kind: \"char\", char: string };\n\n/**\n * A {@link GlyphDef} carrying its own registry name. Glyph modules generated\n * from third-party icon sets export values of this shape so they can be\n * registered in a single call to `Glyph.register(...)`.\n */\nexport type NamedGlyphDef = GlyphDef & { name: string };\n\n/**\n * Mutable registry of named glyphs, populated via `registerGlyph` /\n * `Glyph.register`. Starts empty — consumers register the glyphs they need.\n *\n * @internal\n */\nconst _glyphs: Map<string, GlyphDef> = new Map();\n\n// Built-in Unicode-triangle glyphs registered eagerly. Prefixed `unicode-` so\n// user code can register its own `arrow-up` / `arrow-down` SVG glyphs without\n// overwriting these — built-in chrome like Scrollbar's end-cap buttons\n// references the prefixed names directly and stays immune to user overrides.\n// Char-mode entries are tiny (no sprite, no path data) so the always-on cost\n// is negligible; the triangles inherit the surrounding text colour via\n// `currentColor`, so a single foreground-colour write themes them.\n_glyphs.set(\"unicode-arrow-up\", { kind: \"char\", char: \"▲\" });\n_glyphs.set(\"unicode-arrow-down\", { kind: \"char\", char: \"▼\" });\n_glyphs.set(\"unicode-arrow-left\", { kind: \"char\", char: \"◀\" });\n_glyphs.set(\"unicode-arrow-right\", { kind: \"char\", char: \"▶\" });\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n\n/**\n * Prefix applied to every `<symbol>` id inside the sprite. A consumer-supplied\n * registry name `\"xmark\"` becomes the id `\"ts-glyph-xmark\"`, which is what\n * `<use href=\"#ts-glyph-xmark\"/>` references.\n */\nexport const GLYPH_SYMBOL_ID_PREFIX = \"ts-glyph-\";\n\nlet _spriteMounted: boolean = false;\nlet _spriteElement: Handle | null = null;\n\n/**\n * Registers a glyph by name. If the glyph is SVG-mode and the sprite is\n * already mounted, the corresponding `<symbol>` is appended immediately so\n * Glyphs constructed after this call can reference it.\n *\n * @internal\n */\nexport function registerGlyph(def: NamedGlyphDef): void {\n _glyphs.set(def.name, def);\n\n if (def.kind === \"svg\" && _spriteMounted) {\n _addSymbolToSprite(def.name, def);\n }\n}\n\n/**\n * Removes a glyph from the registry by name. If the glyph was SVG-mode and\n * the sprite is mounted, its `<symbol>` is removed from the DOM as well.\n *\n * @internal\n */\nexport function unregisterGlyph(name: string): void {\n const def = _glyphs.get(name);\n _glyphs.delete(name);\n\n if (def && def.kind === \"svg\" && _spriteMounted) {\n _removeSymbolFromSprite(name);\n }\n}\n\n/**\n * Looks up a glyph definition by registry name.\n *\n * @returns The registered {@link GlyphDef}, or `undefined` if not registered.\n *\n * @internal\n */\nexport function lookupGlyph(name: string): GlyphDef | undefined {\n return _glyphs.get(name);\n}\n\n/**\n * Ensures the document carries a single hidden `<svg>` sprite that hosts the\n * `<symbol>` elements for every SVG-mode glyph. Idempotent — subsequent calls\n * are no-ops. The sprite starts empty; entries are appended incrementally\n * either by {@link registerGlyph} (after the sprite is mounted) or by\n * {@link ensureGlyphSymbolMounted} (when a Glyph instance is constructed).\n *\n * @internal\n */\nexport function ensureGlyphSprite(): void {\n if (_spriteMounted) {\n return;\n }\n\n const sprite = DOM.sink.createElementNS(SVG_NS, \"svg\");\n // `sprite` is a raw off-screen SVG element mounted directly on document.body,\n // not a Component, so the Component style setters don't apply here.\n DOM.sink.apply(sprite, {\n setAttr: { \"aria-hidden\": \"true\", focusable: \"false\" },\n style: { position: \"absolute\", width: \"0\", height: \"0\", overflow: \"hidden\" },\n });\n\n DOM.sink.appendChild(DOM.source.getBody(), sprite);\n\n _spriteElement = sprite;\n _spriteMounted = true;\n}\n\n/**\n * Ensures the sprite carries a `<symbol>` for the named SVG-mode glyph,\n * appending it on demand for glyphs registered before the sprite was mounted.\n * Idempotent.\n *\n * @internal\n */\nexport function ensureGlyphSymbolMounted(name: string): void {\n if (!_spriteMounted) {\n return;\n }\n\n const def = _glyphs.get(name);\n if (def && def.kind === \"svg\") {\n _addSymbolToSprite(name, def);\n }\n}\n\n/**\n * Appends a `<symbol>` for the given SVG-mode glyph to the sprite. Idempotent:\n * a no-op when a `<symbol>` with the same id already exists.\n *\n * @internal\n */\nfunction _addSymbolToSprite(name: string, def: GlyphDef): void {\n if (!_spriteElement || def.kind !== \"svg\") {\n return;\n }\n\n const id = GLYPH_SYMBOL_ID_PREFIX + name;\n if (DOM.source.querySelector(_spriteElement, `#${DOM.source.escapeSelector(id)}`)) {\n return;\n }\n\n const symbol = DOM.sink.createElementNS(SVG_NS, \"symbol\");\n DOM.sink.apply(symbol, { setAttr: { id: id, viewBox: def.viewBox } });\n\n const path = DOM.sink.createElementNS(SVG_NS, \"path\");\n DOM.sink.apply(path, { setAttr: { d: def.path } });\n DOM.sink.appendChild(symbol, path);\n\n DOM.sink.appendChild(_spriteElement, symbol);\n}\n\n/**\n * Removes the `<symbol>` for the given glyph name from the sprite, if present.\n *\n * @internal\n */\nfunction _removeSymbolFromSprite(name: string): void {\n if (!_spriteElement) {\n return;\n }\n\n const id = GLYPH_SYMBOL_ID_PREFIX + name;\n const symbol = DOM.source.querySelector(_spriteElement, `#${DOM.source.escapeSelector(id)}`);\n if (symbol) {\n // Release the symbol's retained `<path>` child too — releasing only the\n // symbol would pin the detached path handle in the registry. Queried\n // before removal so it resolves to its canonical retained handle.\n const path = DOM.source.querySelector(symbol, \"path\");\n\n DOM.sink.removeChild(_spriteElement, symbol);\n DOM.sink.release(symbol);\n\n if (path) {\n DOM.sink.release(path);\n }\n }\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Animation } from \"~/core/Animation.js\";\nimport { Component, ComponentOptions } from \"~/core/Component.js\";\nimport { DOM } from \"~/core/DOM.js\";\nimport type { Handle } from \"~/core/DOM.js\";\nimport { StyleRule } from \"~/core/StyleTarget.js\";\nimport { callable } from \"~/core/Callable.js\";\nimport { Size } from \"~/primitive/Size.js\";\nimport {\n ensureGlyphSprite,\n ensureGlyphSymbolMounted,\n GLYPH_SYMBOL_ID_PREFIX,\n GlyphDef,\n lookupGlyph,\n NamedGlyphDef,\n registerGlyph,\n unregisterGlyph,\n} from \"~/component/display/Glyphs.js\";\n\n/**\n * Named animation kinds supported by {@link Glyph.setAnimated}.\n *\n * - `spin` — continuous 360 degree rotate. Loading and refresh affordances.\n * - `pulse` — 8-step rotate. Mechanical, faux-loading tick.\n * - `beat` — transform-scale pulse. Notification dots and attention nudges.\n *\n * Mirrors FontAwesome's `fa-spin` / `fa-pulse` / `fa-beat` vocabulary.\n *\n * @category Components\n */\nexport type GlyphAnimation = \"spin\" | \"pulse\" | \"beat\";\n\n/**\n * CSS class prefix shared by all three animation rules. The full class name\n * is `ts-ui-glyph-<kind>` (e.g. `ts-ui-glyph-spin`).\n */\nconst CLASS_PREFIX = \"ts-ui-glyph-\";\n\n/**\n * Registry of `WeakRef<Glyph>` for currently-animated instances. A single\n * module-level `matchMedia` listener walks this set on OS preference changes\n * and re-applies the class to match. `WeakRef` lets the GC collect unrooted\n * glyphs without an explicit deregister-on-disposal step.\n */\nconst _animatedRefs: Set<WeakRef<Glyph>> = new Set();\n\nlet _keyframesInjected = false;\n\n/**\n * Injects the three `@keyframes` blocks and matching class rules on first\n * use. Idempotent — guarded by the module-level `_keyframesInjected` flag.\n */\nfunction ensureGlyphKeyframes(): void {\n if (_keyframesInjected) {\n return;\n }\n\n _keyframesInjected = true;\n\n StyleRule.ensureKeyframes(\"ts-ui-glyph-spin\",\n \"from { transform: rotate(0deg); } to { transform: rotate(360deg); }\");\n\n StyleRule.ensureKeyframes(\"ts-ui-glyph-pulse\",\n \"0%, 12.5% { transform: rotate(0deg); } \" +\n \"12.5%, 25% { transform: rotate(45deg); } \" +\n \"25%, 37.5% { transform: rotate(90deg); } \" +\n \"37.5%, 50% { transform: rotate(135deg); } \" +\n \"50%, 62.5% { transform: rotate(180deg); } \" +\n \"62.5%, 75% { transform: rotate(225deg); } \" +\n \"75%, 87.5% { transform: rotate(270deg); } \" +\n \"87.5%, 100% { transform: rotate(315deg); }\");\n\n StyleRule.ensureKeyframes(\"ts-ui-glyph-beat\",\n \"0%, 90% { transform: scale(1); } 45% { transform: scale(1.25); }\");\n\n new StyleRule({\n scope: \"class\",\n name: CLASS_PREFIX + \"spin\",\n styles: {\n animation: \"ts-ui-glyph-spin var(--ts-ui-glyph-spin-duration, 2000ms) linear infinite\",\n },\n });\n\n new StyleRule({\n scope: \"class\",\n name: CLASS_PREFIX + \"pulse\",\n styles: {\n animation: \"ts-ui-glyph-pulse var(--ts-ui-glyph-pulse-duration, 1000ms) steps(8) infinite\",\n },\n });\n\n new StyleRule({\n scope: \"class\",\n name: CLASS_PREFIX + \"beat\",\n styles: {\n animation: \"ts-ui-glyph-beat var(--ts-ui-glyph-beat-duration, 1000ms) ease-in-out infinite\",\n },\n });\n}\n\n/**\n * Module-level listener that re-evaluates every animated glyph when the OS\n * `prefers-reduced-motion` preference flips. Dead `WeakRef`s are pruned.\n */\nfunction _onReducedMotionChange(): void {\n for (const ref of Array.from(_animatedRefs)) {\n const glyph = ref.deref();\n if (!glyph) {\n _animatedRefs.delete(ref);\n continue;\n }\n\n glyph._syncReducedMotion();\n }\n}\n\n// The seam's `matchMedia` degrades to an inert result off-browser, so this\n// module-level registration needs no environment guard of its own.\nDOM.source.matchMedia(\"(prefers-reduced-motion: reduce)\").addChangeListener(_onReducedMotionChange);\n\n/**\n * Construction-time options for {@link Glyph}.\n *\n * @category Components\n */\nexport interface GlyphOptions extends ComponentOptions {\n\n /**\n * CSS `font-size` override in pixels. Only meaningful for char-mode\n * glyphs (SVG glyphs paint via `<use>` and ignore font-size). Useful when\n * the inherited font-size produces a line-box taller than the glyph's\n * element box and the Unicode character overflows or gets clipped.\n */\n fontSize?: number;\n\n /**\n * CSS `line-height` override. A number is interpreted as pixels (e.g.\n * `24` → `\"24px\"`); a string is used verbatim (e.g. `\"1\"` for the\n * unitless font-size multiplier used by char-mode glyphs).\n */\n lineHeight?: number | string;\n\n /**\n * CSS `text-align` keyword (e.g. `\"left\"`, `\"center\"`, `\"right\"`).\n * Char-mode glyphs default to `\"center\"`; SVG-mode glyphs leave this\n * unset.\n */\n textAlign?: string;\n\n /**\n * Optional animation kind to play on this glyph from construction.\n */\n animation?: GlyphAnimation;\n\n /**\n * Optional override (ms) for the active animation's duration. Wins over\n * the theme-token default while non-zero. Ignored when `animation` is\n * unset.\n */\n animationDuration?: number;\n}\n\n/**\n * User-overridable defaults forwarded to `super` via the options bag. The\n * cascade dispatches each present setter once with the final value. Only\n * defaults that apply unconditionally for every Glyph kind live here — the\n * char-only `lineHeight`/`textAlign` defaults stay in the constructor body\n * because they depend on the per-instance `def.kind`.\n */\nconst _defaultGlyphOptions: Partial<GlyphOptions> = {\n preferredSize: { width: 16, height: 16 } as GlyphOptions[\"preferredSize\"],\n\n // Always an HTML element, both kinds. An SVG entry paints through an inner\n // `<svg>` rather than being one: Blink refuses to run a transform animation\n // on an SVG element on the compositor, so an `<svg>` root would force a\n // full-document Layerize pass on every frame the glyph animates.\n tag: \"span\",\n};\n\n/**\n * A small icon rendered from the internal `Glyphs` registry.\n *\n * @remarks\n * Each registry entry is either an SVG or a single Unicode character. The root\n * element is a `<span>` either way. An SVG entry hangs an inner\n * `<svg><use href=\"#…\"/></svg>` inside that root, pointing at a hidden sprite\n * mounted once into `document.body`, so the path data lives in the DOM exactly\n * once regardless of how many Glyph instances reference it. A Unicode entry\n * writes its character into the root directly. Both forms render with\n * `currentColor`, so a `Glyph` inherits the surrounding text colour for free.\n * The registry name is fixed at construction and cannot be changed afterwards —\n * to swap glyph, discard the instance and create a new one.\n *\n * Pass any registry name to the constructor; unknown names throw at\n * construction. The default preferred size is 16×16.\n *\n * @example\n * ```typescript\n * import { xmark } from \"~/glyphs/solid/xmark.js\";\n * import { arrow_right } from \"~/glyphs/solid/arrow_right.js\";\n *\n * Glyph.register(xmark, arrow_right);\n *\n * panel.addComponent(new Glyph(\"xmark\"));\n * panel.addComponent(new Glyph(\"arrow-right\"));\n * ```\n *\n * @category Components\n */\nclass Glyph extends Component<GlyphOptions> {\n\n private _name: string;\n private _def: GlyphDef;\n declare private _glyphAnimation: GlyphAnimation | null;\n declare private _glyphAnimationDuration: number;\n declare private _animatedRef: WeakRef<Glyph> | null;\n\n /**\n * Registers one or more glyph definitions so they can be instantiated by\n * name. Pass the named exports from `~/glyphs/<style>/<name>.js` modules.\n *\n * @param defs - One or more {@link NamedGlyphDef} values to register.\n */\n static register(...defs: NamedGlyphDef[]): void {\n for (const def of defs) {\n registerGlyph(def);\n }\n }\n\n /**\n * Removes a previously registered glyph by name.\n *\n * @param name - Registry key to unregister.\n */\n static unregister(name: string): void {\n unregisterGlyph(name);\n }\n\n /**\n * Constructs a Glyph for the registry entry with the given name.\n *\n * @param name - Registry key. Must have been registered via {@link Glyph.register}.\n * @param options - Optional component options bag.\n * @param subclassDefaults - Per-subclass default bag layered over this\n * class's defaults; subclasses forward their `_defaultXxxOptions`\n * constant here.\n */\n constructor(name: string, options?: GlyphOptions, subclassDefaults?: Partial<GlyphOptions>) {\n const def = lookupGlyph(name);\n if (!def) {\n throw new Error(\"Unknown glyph: \" + name);\n }\n\n // Hand the class defaults to Component via the subclass-defaults arg so\n // they land in `_defaultOptions`. Component's super-time cascade applies\n // them; user `options` win because `applyOptions` merges\n // `{...defaults, ...options}` at dispatch time.\n super(options, {\n ..._defaultGlyphOptions,\n ...(subclassDefaults ?? {}),\n });\n\n this._name = name;\n this._def = def;\n\n // Char-mode glyphs need a line-height and text-align that SVG glyphs\n // should not get. Keep these guards in the constructor body since they\n // depend on per-instance `def.kind` rather than a static default.\n if (def.kind === \"char\") {\n if (this._options.lineHeight === undefined) {\n this.setLineHeight(\"1\");\n }\n\n if (this._options.textAlign === undefined) {\n this.setTextAlign(\"center\");\n }\n }\n }\n\n /**\n * Sets the preferred size and pins minSize/maxSize to the same value so\n * the glyph stays rigid in flexible layouts — HBox's shrink-on-overflow\n * logic and any grow path see equal min/pref/max and leave the glyph at\n * its configured size. Callers can still override the lock by calling\n * `setMinSize` / `setMaxSize` explicitly after this method.\n *\n * @param size - The preferred size in pixels.\n *\n * @returns This component, for method chaining.\n */\n setPreferredSize(size: Size): this {\n super.setPreferredSize(size);\n super.setMinSize(size);\n super.setMaxSize(size);\n\n return this;\n }\n\n /**\n * Returns a baseline near the bottom edge so the glyph participates in\n * baseline alignment — sitting with its ink roughly on the surrounding text\n * baseline when placed next to labels — instead of being vertically centred\n * in the row. The anchor is 4px above the bottom edge (vs 2px on the\n * bar-shaped controls), which drops a square icon slightly lower so its ink\n * lands on the text baseline rather than floating above it.\n *\n * @returns The preferred height minus 4, or `null` before a size is set.\n */\n getBaseline(): number | null {\n const size = this.getPreferredSize();\n\n return size ? size.height - 3 : null;\n }\n\n /**\n * Returns the registry name this Glyph was constructed with. Named\n * `getGlyphName` rather than `getName` so it does not shadow\n * [`Component.getName`](/api/core/classes/Component#getname), whose\n * intrinsic `name` is a display label with a different meaning.\n *\n * @returns The registry key supplied to the constructor.\n */\n getGlyphName(): string {\n return this._name;\n }\n\n /**\n * Returns the explicit CSS `font-size` override (in pixels) written by\n * this Glyph, or `null` when no override has been written (the element\n * inherits the parent's font-size).\n *\n * @returns The cached font-size in pixels, or null.\n */\n getFontSize(): number | null {\n return this._options.fontSize ?? null;\n }\n\n /**\n * Overrides the CSS `font-size` of this Glyph's root element. Useful when\n * the ambient inherited font-size produces a line-box taller than the\n * glyph's `preferredSize`, causing the Unicode character to overflow or\n * get clipped by the element's `overflow: hidden`. No-op visually for\n * SVG glyphs (which size via `viewBox`), but the rule is written regardless.\n *\n * @param value - The new font-size in pixels.\n * @returns This Glyph, for method chaining.\n */\n setFontSize(value: number): this {\n this._options.fontSize = value;\n this.setElementCSSRule(\"fontSize\", value + \"px\");\n\n return this;\n }\n\n /**\n * Returns the current CSS `line-height` value written by this Glyph, or\n * `null` if no rule has been written (the element inherits the parent's\n * line-height).\n *\n * @returns The cached line-height CSS value (e.g. `\"1\"`, `\"24px\"`), or null.\n *\n * @remarks\n * Char-mode glyphs construct with `\"1\"`; SVG-mode glyphs default to null.\n * Use this getter rather than reading `element.style.lineHeight` to avoid\n * a forced style read.\n */\n getLineHeight(): string | null {\n const value = this._options.lineHeight;\n if (value === undefined) {\n return null;\n }\n\n return typeof value === \"number\" ? value + \"px\" : value;\n }\n\n /**\n * Overrides the CSS `line-height` of this Glyph's root element.\n *\n * @param value - Pixel number (e.g. `24` → `\"24px\"`) or a raw CSS\n * line-height value (e.g. `\"1\"` for the unitless\n * font-size multiplier used by char-mode glyphs).\n * @returns This Glyph, for method chaining.\n *\n * @remarks\n * Char-mode glyphs construct with `line-height: 1`, which keeps Unicode\n * characters like `▲` / `▼` snug against the top of their box. When a\n * Glyph is sized larger than its natural char height and needs to\n * vertically centre within that box, callers can match the line-height to\n * the element height to push the line-box to the middle. No-op visually\n * for SVG glyphs (which size via `viewBox`), but the rule is written\n * regardless.\n */\n setLineHeight(value: number | string): this {\n this._options.lineHeight = value;\n this.setElementCSSRule(\"lineHeight\", typeof value === \"number\" ? value + \"px\" : value);\n\n return this;\n }\n\n /**\n * Returns the current CSS `text-align` value written by this Glyph, or\n * `null` if no rule has been written (the element inherits the parent's\n * text-align).\n *\n * @returns The cached text-align CSS value (e.g. `\"center\"`), or null.\n *\n * @remarks\n * Char-mode glyphs construct with `\"center\"` to keep the Unicode\n * character horizontally centred within its element box; SVG-mode glyphs\n * default to null. Use this getter rather than reading\n * `element.style.textAlign` to avoid a forced style read.\n */\n getTextAlign(): string | null {\n return this._options.textAlign ?? null;\n }\n\n /**\n * Overrides the CSS `text-align` of this Glyph's root element.\n *\n * @param value - A CSS `text-align` keyword such as `\"left\"`, `\"center\"`,\n * `\"right\"`, `\"start\"`, or `\"end\"`.\n * @returns This Glyph, for method chaining.\n */\n setTextAlign(value: string): this {\n this._options.textAlign = value;\n this.setElementCSSRule(\"textAlign\", value);\n\n return this;\n }\n\n /**\n * Returns the currently-playing animation kind, or `null` when none is\n * active.\n *\n * @returns The active {@link GlyphAnimation}, or `null`.\n */\n getAnimated(): GlyphAnimation | null {\n return this._glyphAnimation;\n }\n\n /**\n * Starts the named animation, or stops the current one when `kind` is\n * `null`. No-op when the requested kind already matches the current one.\n *\n * @param kind - A {@link GlyphAnimation} value or `null` to stop.\n * @returns This Glyph, for method chaining.\n *\n * @remarks\n * Adds the corresponding `ts-ui-glyph-<kind>` class to the root element,\n * which is an HTML `<span>` for every glyph kind so the browser can run the\n * `transform` keyframes on its compositor thread.\n * Honours [`Animation.isReducedMotion`](/api/core/namespaces/Animation/functions/isReducedMotion):\n * when reduced-motion is on, the class is not mounted but the requested\n * kind is cached and a module-level listener re-applies it should the OS\n * preference flip back.\n *\n * No `will-change` hint is set. The hint exists to pre-create a compositor\n * layer so the first frame of motion does not pay for the promotion, which\n * an infinite animation amortises to nothing — and glyphs are numerous\n * enough that hinting each one would push a page past the threshold where\n * browsers start ignoring the hint outright.\n *\n * Differs from the inherited `Component.setAnimation(value: string)`:\n * this is a typed-enum surface that toggles a pre-registered class rule;\n * the inherited setter accepts a raw CSS shorthand and writes a\n * per-component `#id { animation: … }` rule.\n *\n * @example\n * ```typescript\n * const g = new Glyph(\"xmark\");\n * g.setAnimated(\"spin\");\n * g.setAnimated(null); // stop\n * ```\n */\n setAnimated(kind: GlyphAnimation | null): this {\n if (this._glyphAnimation === kind) {\n return this;\n }\n\n const prev = this._glyphAnimation;\n this._glyphAnimation = kind;\n\n const el = this.getElement();\n\n if (el && prev) {\n DOM.sink.apply(el, { removeClass: [CLASS_PREFIX + prev] });\n }\n\n if (kind === null) {\n this.setElementCSSRule(\"animationDuration\", null);\n\n if (this._animatedRef) {\n _animatedRefs.delete(this._animatedRef);\n this._animatedRef = null;\n }\n\n return this;\n }\n\n ensureGlyphKeyframes();\n\n if (!this._animatedRef) {\n this._animatedRef = new WeakRef(this);\n _animatedRefs.add(this._animatedRef);\n }\n\n if (!Animation.isReducedMotion() && el) {\n DOM.sink.apply(el, { addClass: [CLASS_PREFIX + kind] });\n }\n\n if (this._glyphAnimationDuration > 0) {\n this.setElementCSSRule(\"animationDuration\", this._glyphAnimationDuration + \"ms\");\n }\n\n return this;\n }\n\n /**\n * Stops the current animation. Equivalent to `setAnimated(null)`.\n *\n * @returns This Glyph, for method chaining.\n */\n clearAnimated(): this {\n return this.setAnimated(null);\n }\n\n /**\n * Pauses this glyph's animation while it is not effectively visible, and\n * resumes it when it is shown again.\n *\n * The inherited implementation pauses only when\n * {@link Component.getAnimation} is non-null — that is, when the animation\n * was written into the component's own `#uuid` rule by\n * `Component.setAnimation`. A Glyph instead animates from a shared\n * `ts-ui-glyph-<kind>` class rule (one rule for every glyph of that kind,\n * rather than one per instance), so `getAnimation()` is always null here and\n * the base check cannot see the animation. Without this override an animated\n * glyph keeps consuming a compositor frame on every display refresh for as\n * long as the page lives, even on a hidden tab.\n *\n * @param effective - The component's new effective-visibility state.\n */\n protected onEffectiveVisibilityChange(effective: boolean): void {\n super.onEffectiveVisibilityChange(effective);\n\n // Loose comparison: `_glyphAnimation` is a `declare` field, so it has no\n // runtime initializer and reads as `undefined` — not its declared `null`\n // — on a glyph that was never animated. A strict `!== null` would treat\n // that as \"animated\" and park a play-state on every unanimated glyph.\n if (this._glyphAnimation != null) {\n this.setAnimationPlayState(effective ? null : \"paused\");\n }\n }\n\n /**\n * Returns the override duration (ms) set via {@link setAnimationDuration},\n * or `0` when no override is active. Read the active CSS custom property\n * (`--ts-ui-glyph-<kind>-duration`) for the live value when no override\n * is set.\n *\n * @returns The override duration in ms, or `0`.\n */\n getAnimationDuration(): number {\n return this._glyphAnimationDuration;\n }\n\n /**\n * Overrides the active animation's duration. Pass `0` to clear the\n * override and fall back to the theme-token default. No visible effect\n * when no animation is currently set, but the override is cached and\n * will apply on the next {@link setAnimated} call.\n *\n * @param ms - Duration in milliseconds, or `0` to clear.\n * @returns This Glyph, for method chaining.\n */\n setAnimationDuration(ms: number): this {\n this._glyphAnimationDuration = ms;\n\n // Loose comparison: `_glyphAnimation` is a `declare` field with no\n // runtime initializer, so it reads `undefined` — not its declared\n // `null` — on a glyph that was never animated. A strict `!== null`\n // treats that as \"animated\" and writes an orphan duration, which\n // `applyOptions` triggers whenever `animationDuration` is supplied\n // without `animation` (duration is dispatched first).\n if (this._glyphAnimation != null && !Animation.isReducedMotion()) {\n this.setElementCSSRule(\"animationDuration\", ms > 0 ? ms + \"ms\" : null);\n }\n\n return this;\n }\n\n /**\n * Re-applies (or removes) the animation class to match the current\n * `prefers-reduced-motion` state. Called by the module-level listener\n * when the OS preference flips. Internal; not part of the public API.\n */\n _syncReducedMotion(): void {\n const kind = this._glyphAnimation;\n if (!kind) {\n return;\n }\n\n const element = this.getElement(true)!;\n const className = CLASS_PREFIX + kind;\n\n if (Animation.isReducedMotion()) {\n DOM.sink.apply(element, { removeClass: [className] });\n this.setElementCSSRule(\"animationDuration\", null);\n } else {\n DOM.sink.apply(element, { addClass: [className] });\n\n if (this._glyphAnimationDuration > 0) {\n this.setElementCSSRule(\"animationDuration\", this._glyphAnimationDuration + \"ms\");\n }\n }\n }\n\n /**\n * Applies a {@link GlyphOptions} bag by dispatching each present field to\n * its corresponding setter.\n *\n * @param options - The options bag carrying the values to apply.\n * @returns This Glyph, for method chaining.\n */\n protected applyOptions(options: GlyphOptions): this {\n super.applyOptions(options);\n\n if (options.fontSize !== undefined) {\n this.setFontSize(options.fontSize);\n }\n\n if (options.lineHeight !== undefined) {\n this.setLineHeight(options.lineHeight);\n }\n\n if (options.textAlign !== undefined) {\n this.setTextAlign(options.textAlign);\n }\n\n if (options.animationDuration !== undefined) {\n this.setAnimationDuration(options.animationDuration);\n }\n\n // Re-pin minSize / maxSize to the current preferred size so the glyph\n // stays rigid in flexible layouts. The inherited cascade has just\n // overwritten the pin from `setPreferredSize` with Component's `{0,0}`\n // minSize / `{MAX,MAX}` maxSize defaults; restore it here, but honour\n // an explicit `options.minSize` / `options.maxSize` from the caller.\n const pref = this.getPreferredSizeConstraint();\n if (pref) {\n if (options.minSize === undefined) {\n this.setMinSize({ width: pref.width, height: pref.height });\n }\n\n if (options.maxSize === undefined) {\n this.setMaxSize({ width: pref.width, height: pref.height });\n }\n }\n\n if (options.animation !== undefined) {\n this.setAnimated(options.animation);\n }\n\n return this;\n }\n\n /**\n * Creates the root element — always the inherited HTML `<span>`. An SVG\n * registry entry hangs a tracked `<svg><use/></svg>` inside it, referencing\n * a shared sprite symbol rather than inlining the path data.\n *\n * The `<svg>` is a child rather than the root so the animation class lands\n * on an HTML element: Blink will not run a transform animation on an SVG\n * element on the compositor, and an uncomposited glyph animation re-runs a\n * full-document `Layerize` pass every frame. Mirrors\n * {@link AbstractChart.createRootElement}'s raw-SVG-through-the-sink shape.\n *\n * @returns The root `<span>` element for this Glyph.\n */\n protected createRootElement(): Handle {\n const root = super.createRootElement();\n\n if (this._def.kind !== \"svg\") {\n return root;\n }\n\n ensureGlyphSprite();\n ensureGlyphSymbolMounted(this._name);\n\n const svgNs = \"http://www.w3.org/2000/svg\";\n const svg = DOM.sink.createElementNS(svgNs, \"svg\");\n\n // Fill the root's box. A replaced `<svg>` with no intrinsic size falls\n // back to the user agent's 300x150, which the root's `overflow: hidden`\n // would then clip; the percentages resolve against the inline width and\n // height `render` writes on the root.\n DOM.sink.apply(svg, {\n style: { position: \"absolute\", left: \"0\", top: \"0\", width: \"100%\", height: \"100%\", display: \"block\" },\n setAttr: { fill: \"currentColor\", \"aria-hidden\": \"true\", focusable: \"false\" },\n });\n\n const use = DOM.sink.createElementNS(svgNs, \"use\");\n DOM.sink.apply(use, { setAttr: { href: \"#\" + GLYPH_SYMBOL_ID_PREFIX + this._name } });\n DOM.sink.appendChild(svg, use);\n DOM.sink.appendChild(root, svg);\n\n // Track both raw children so they are released with the glyph (the root\n // is tracked by Component.render). Released on destructor or GC.\n this.trackHandle(svg);\n this.trackHandle(use);\n\n return root;\n }\n\n /**\n * Populates the rendered element. For char-mode glyphs the character is\n * written into the span's text content; SVG-mode element children are\n * created by `createRootElement`.\n *\n * Applies `preferredSize` as inline width/height so SVG glyphs appended\n * raw via `glyph.getElement(true)` outside a framework layout don't fall\n * back to the user-agent's 300×150 default replaced-element size.\n *\n * @returns The rendered root element.\n */\n protected render(): Handle {\n const element = super.render();\n\n if (this._def.kind === \"char\") {\n DOM.sink.apply(element, { text: this._def.char });\n }\n\n if (this._glyphAnimation && !Animation.isReducedMotion()) {\n DOM.sink.apply(element, { addClass: [CLASS_PREFIX + this._glyphAnimation] });\n }\n\n const preferredSize = this._options.preferredSize;\n if (preferredSize) {\n this.setElementStyle(\"width\", preferredSize.width + \"px\");\n this.setElementStyle(\"height\", preferredSize.height + \"px\");\n }\n\n return element;\n }\n}\n\nconst GlyphCallable = callable(Glyph);\ntype GlyphCallable = Glyph;\nexport {\n Glyph as _Glyph,\n GlyphCallable as Glyph\n};\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{t as e}from"./DOM-C-Edb3tA.js";import{a as t,l as n,n as r}from"./Position-BwtxouxK.js";import{S as i,b as a,f as o,h as s,p as c,t as l,v as u}from"./Component-B0ShfPVi.js";import{t as d}from"./ListenerBag-WPdKuuds.js";import{r as f}from"./VBox-DfJPWXqc.js";import{a as p,n as m,r as h}from"./RadioMenuRow-DP5qPyFR.js";import{t as g}from"./LayoutConstraints-LIHYYd2F.js";import{n as _}from"./Border-0DJFDiij.js";import{t as v}from"./Button-MpMIYBYJ.js";import{n as y,r as b}from"./DragChain-CYGuT7OA.js";var x=14,S=`▶`,C=null;function ensureAccordionIndicatorClassRule(){C||=new a({scope:`class`,name:`AccordionIndicator`,styles:{textAlign:`center`,pointerEvents:`none`,fontSize:`10px`,color:`var(--ts-ui-accordion-indicator-color, rgb(100,100,100))`,transition:`transform 200ms ease`}})}var AccordionIndicator=class extends l{_lineHeight=null;constructor(e){ensureAccordionIndicatorClassRule(),super({tag:`span`,preferredSize:{width:x,height:x},...e??{}}),this._expanded??=!1,this._character??=S,this.createStyleRule(`.expanded`).set(`transform`,`rotate(90deg)`)}setLineHeight(e){return this._lineHeight===e?this:(this._lineHeight=e,this.setElementCSSRule(`lineHeight`,e+`px`),this)}setHeight(e){return super.setHeight(e),this.setLineHeight(e),this}applyOptions(e){return super.applyOptions(e),e.expanded!==void 0&&this.setExpanded(e.expanded),e.character!==void 0&&this.setCharacter(e.character),this}getCharacter(){return this._character??S}setCharacter(t){this._character=t;let n=this.getElement();return n&&e.sink.apply(n,{text:t}),this}render(){let t=super.render();return e.sink.apply(t,{text:this._character??S}),this._expanded&&e.sink.apply(t,{addClass:[`expanded`]}),t}getExpanded(){return this._expanded}setExpanded(t){this._expanded=t;let n=this.getElement();return n&&e.sink.apply(n,{toggleClass:{expanded:t}}),this}clearExpanded(){return this.setExpanded(!1)}setAnimationTiming(e,t){return this.setTransition(`transform ${e}ms ${t}`),this}},w=s(AccordionIndicator),T=8,E=10,D=4,O=6,k=6,A=2,AccordionHeader=class extends l{_tools=[];_chevronSide=`end`;constructor(e,t){super({tag:`div`,...t}),this._indicator=new w({character:t?.chevronGlyph}),this._title=new v(e,{chromeless:!0,anchor:c.WEST,glyph:t?.glyph}),this._toolGroup=new l,this._toolGroup.setLayoutManager(new f({spacing:D,stretching:!0})),this._toolGroup.setBackgroundColor(`transparent`),this.setLayoutManager(new f({spacing:D,stretching:!0}));let n=new g;n.weight=1,this.addComponent(this._title,n),this.addComponent(this._toolGroup),this._chevronSide=t?.chevronSide??`end`,this.placeIndicator(),this.setExpanded(t?.expanded??!1),this.setCompact(t?.compact??!1)}setCompact(e){let t=e?O:T,n=e?k:E;return this.setInsets(new r(0,n,0,t)),this.getLayoutManager().setComponentSpacing(e?A:D),this._title?.setCompact(e),this.scheduleLayout(),this}placeIndicator(){this.getComponents().includes(this._indicator)&&this.removeComponent(this._indicator),this._chevronSide===`start`?this.insertComponent(this._indicator,0):this.addComponent(this._indicator)}getTitleButton(){return this._title}setExpanded(e){return this._indicator?.setExpanded(e),this._title?.getAria().setExpanded(e),this}isExpanded(){return this._indicator?.getExpanded()??!1}setChevronSide(e){return this._chevronSide===e?this:(this._chevronSide=e,this.placeIndicator(),this.scheduleLayout(),this)}getChevronSide(){return this._chevronSide}setChevronGlyph(e){return this._indicator?.setCharacter(e),this}addTool(e){return e instanceof v&&e.setFlat(!0),this._tools.includes(e)?this:(this._tools.push(e),this._toolGroup.addComponent(e),this.scheduleLayout(),this)}removeTool(e){let t=this._tools.indexOf(e);return t===-1?this:(this._tools.splice(t,1),this._toolGroup.removeComponent(e),this.scheduleLayout(),this)}setToolsRevealed(e){return this._toolGroup.setDisplayed(e),this}setAnimationTiming(e,t){return this._indicator?.setAnimationTiming(e,t),this}},j=s(AccordionHeader),M=`cubic-bezier(0.4, 0, 0.6, 1)`,N=22,P=6,F=`var(--ts-ui-accordion-header-bg, rgb(243,244,246))`,I=`var(--ts-ui-accordion-header-border, 1px solid rgb(214,217,222))`,L=`var(--ts-ui-accordion-header-color, inherit)`,R=`var(--ts-ui-accordion-border, 1px solid rgb(214,217,222))`,Accordion=class extends o{_headers=[];_panelWrappers=[];_openState=[];_singleOpen=!1;_headerHeight=28;_headerHeightExplicit=!1;_compact=!1;_animationDuration=200;_chevronSide=`end`;_chevronGlyph=null;_spacing=0;_themed=!0;_fillHeight=!1;_tools=[];_toolsVisibility=`hover`;_hoveredHeader=-1;_listeners=new d;_resizable=!1;_resizeSizes=new Map;_pendingSectionSizes=null;_resizeFactor=1;_resizePinned=new Set;_resizeGutters=[];_gutterPairs=[];_dragUpper=null;_dragLower=null;_dragLastPointer=0;_dragOpenIndices=[];_dragGutterUpperPos=0;_toggleAnimations=0;_shrinkAnimations=new Map;_wrapperAnimations=new Map;_boundOnGutterDragEnd=()=>this.onGutterDragEnd();constructor(e){super(),e&&this.applyOptions(e)}applyOptions(e){if(super.applyOptions(e),e.headerHeight!==void 0&&this.setHeaderHeight(e.headerHeight),e.animationDuration!==void 0&&this.setAnimationDuration(e.animationDuration),e.chevronSide!==void 0&&this.setChevronSide(e.chevronSide),e.toolsVisibility!==void 0&&this.setToolsVisibility(e.toolsVisibility),e.compact!==void 0&&this.setCompact(e.compact),e.chevronGlyph!==void 0&&this.setChevronGlyph(e.chevronGlyph),e.spacing!==void 0&&this.setSpacing(e.spacing),e.themed!==void 0&&this.setThemed(e.themed),e.fillHeight!==void 0&&this.setFillHeight(e.fillHeight),e.resizable!==void 0&&this.setResizable(e.resizable),e.sectionSizes!==void 0&&(this._pendingSectionSizes=e.sectionSizes.map(e=>({...e}))),e.listeners!==void 0){let t=e.listeners;for(let e of Object.keys(t)){let n=t[e];n!==void 0&&this.on(e,n)}}e.singleOpen!==void 0&&this.setSingleOpen(e.singleOpen)}isSingleOpen(){return this._singleOpen}setSingleOpen(e){if(this._singleOpen=e,!e)return this;let t=!1;for(let e=0;e<this._openState.length;e++)this._openState[e]&&(t?(this.primeWrapper(e),this._openState[e]=!1,this._headers[e].setExpanded(!1),this.emit(`sectiontoggle`,e,!1)):t=!0);return this.relayoutHost(),this}getHeaderHeight(){return this._headerHeight}setHeaderHeight(e){return this._headerHeight=e,this._headerHeightExplicit=!0,this}effectiveHeaderHeight(){return this._compact&&!this._headerHeightExplicit?N:this._headerHeight}isCompact(){return this._compact}setCompact(e){this._compact=e;for(let t of this._headers)t.setCompact(e);return this.relayoutHost(),this}getAnimationDuration(){return this._animationDuration}setAnimationDuration(e){return this._animationDuration=e,this}getChevronSide(){return this._chevronSide}setChevronSide(e){this._chevronSide=e;for(let t of this._headers)t.setChevronSide(e);return this.getContainer()?.scheduleLayout(),this}getChevronGlyph(){return this._chevronGlyph}setChevronGlyph(e){this._chevronGlyph=e;for(let t of this._headers)t.setChevronGlyph(e);return this.getContainer()?.scheduleLayout(),this}getSpacing(){return this._spacing}setSpacing(e){return this._spacing=e,this.relayoutHost(),this}isFillHeight(){return this._fillHeight}setFillHeight(e){return this._fillHeight=e,this.getContainer()?.scheduleLayout(),this}isResizable(){return this._resizable}setResizable(e){return this._resizable=e,this.getContainer()?.scheduleLayout(),this}isThemed(){return this._themed}setThemed(e){this._themed=e,this.applyContainerTheming();for(let e=0;e<this._headers.length;e++)this.applySectionTheming(e);return this.getContainer()?.scheduleLayout(),this}applyContainerTheming(){let e=this.getContainer();e&&(this._themed?e.setBorder({border:R}):e.clearBorder())}applySectionTheming(e){let t=this._headers[e];if(t){if(!this._themed){t.clearBackground(),t.clearForegroundColor(),t.clearBorder();return}t.setBackground(F),t.setForegroundColor(L),t.setBorder({border:`none`,borderBottom:I})}}getToolsVisibility(){return this._toolsVisibility}setToolsVisibility(e){this._toolsVisibility=e;for(let t of this._headers)t.setToolsRevealed(e===`always`);return this}addTool(e){return this._tools.includes(e)?this:(this._tools.push(e),this._hoveredHeader!==-1&&this._headers[this._hoveredHeader]?.addTool(e),this.getContainer()?.scheduleLayout(),this)}removeTool(e){let t=this._tools.indexOf(e);return t===-1?this:(this._tools.splice(t,1),this._hoveredHeader!==-1&&this._headers[this._hoveredHeader]?.removeTool(e),this.getContainer()?.scheduleLayout(),this)}revealHeaderTools(e){let t=this._headers[e];if(t){for(let e of this._tools)t.addTool(e);this._toolsVisibility===`hover`&&t.setToolsRevealed(!0)}}hideHeaderTools(e){let t=this._headers[e];if(t){for(let e of this._tools)t.removeTool(e);this._toolsVisibility===`hover`&&t.setToolsRevealed(!1)}}onHeaderHoverEnter(t,n){let r=this._headers[t]?.getElement();r&&e.source.isNode(n.relatedTarget)&&e.source.contains(r,e.source.intern(n.relatedTarget))||this._hoveredHeader!==t&&(this._hoveredHeader!==-1&&this.hideHeaderTools(this._hoveredHeader),this._hoveredHeader=t,this.revealHeaderTools(t))}onHeaderHoverLeave(t,n){let r=this._headers[t]?.getElement();r&&e.source.isNode(n.relatedTarget)&&e.source.contains(r,e.source.intern(n.relatedTarget))||this._hoveredHeader===t&&(this.hideHeaderTools(t),this._hoveredHeader=-1)}relayoutHost(){let e=this.getContainer();e?.scheduleLayout(),e?.notifyIntrinsicSizeChanged()}openSection(e){if(e<0||e>=this._openState.length)return this;if(this._singleOpen)for(let t=0;t<this._openState.length;t++)t!==e&&this._openState[t]&&(this.primeWrapper(t),this._openState[t]=!1,this._headers[t].setExpanded(!1),this.emit(`sectiontoggle`,t,!1));return this.primeWrapper(e),this._openState[e]=!0,this._headers[e].setExpanded(!0),this.emit(`sectiontoggle`,e,!0),this.relayoutHost(),this}closeSection(e){return e<0||e>=this._openState.length?this:(this.primeWrapper(e),this._openState[e]=!1,this._headers[e].setExpanded(!1),this.emit(`sectiontoggle`,e,!1),this.relayoutHost(),this)}expandAll(){if(this._singleOpen)return this.openSection(0),this;for(let e=0;e<this._openState.length;e++)this.openSection(e);return this}collapseAll(){for(let e=0;e<this._openState.length;e++)this.closeSection(e);return this}isSectionOpen(e){return this._openState[e]??!1}sectionSizeUnits(e){return e.map(e=>this.effectiveWeight(e)===0?`px`:`ratio`)}getSectionSizes(){let e=this.getContainer();if(!e)return[];let t=e.getComponents();if(t.length===0)return[];let n=this.sectionSizeUnits(t);return this._pendingSectionSizes!==null&&h(this._pendingSectionSizes,n)?this._pendingSectionSizes.map(e=>({...e})):p(n,t.map(e=>this._resizeSizes.get(e)??0))}applySectionSizes(e){return this._pendingSectionSizes=e.map(e=>({...e})),this.getContainer()?.scheduleLayout(),this}on(e,t){return this._listeners.add(e,t),this}off(e,t){return this._listeners.remove(e,t),this}emit(e,...t){this._listeners.fire(e,...t)}attach(e){return super.attach(e),this}detach(){let t=this.getContainer();for(let e of this._shrinkAnimations.values())e.cancel();this._shrinkAnimations.clear();for(let e of this._wrapperAnimations.values())e.cancel();this._wrapperAnimations.clear(),this._toggleAnimations>0&&(this._toggleAnimations=0,this.setSectionTransitions(!1),t?.setTransition(null)),this._dragUpper&&this.onGutterDragEnd();for(let n=0;n<this._headers.length;n++){let r=(t?t.getComponents():[])[n];r&&t&&e.sink.appendChild(t.getElement(),r.getElement());let i=r?this.getLayoutConstraints(r)?.tools??[]:[];for(let e of[...this._tools,...i])this._headers[n].removeTool(e);this._headers[n].dispose(),this._panelWrappers[n].dispose()}this._headers=[],this._panelWrappers=[],this._openState=[];for(let t of this._resizeGutters)e.sink.removeElement(t.getElement()),t.dispose();return this._resizeGutters=[],this._resizeSizes.clear(),this._gutterPairs=[],super.detach(),this}getPreferredSize(){let e=this.getContainer();if(!e)return null;let t=e.getPerimeterSize(),n=e.getComponents(),r=t.top+t.bottom,i=0,a=0;for(let e=0;e<n.length;e++)if(n[e].isDisplayed()&&(a>0&&(r+=this._spacing),a+=1,r+=this.effectiveHeaderHeight(),e<this._openState.length?this._openState[e]:this.getLayoutConstraints(n[e])?.initiallyOpen??!1)){let t=n[e].getPreferredSize();t&&(r+=t.height,t.width>i&&(i=t.width))}return{width:i+t.left+t.right,height:r}}getMinSize(){let e=this.getContainer();if(!e)return null;let t=e.getPerimeterSize(),n=e.getComponents(),r=t.top+t.bottom,i=0,a=0;for(let e=0;e<n.length;e++)if(n[e].isDisplayed()&&(a>0&&(r+=this._spacing),a+=1,r+=this.effectiveHeaderHeight(),e<this._openState.length?this._openState[e]:this.getLayoutConstraints(n[e])?.initiallyOpen??!1)){let t=n[e].getMinSize();t&&(r+=t.height,t.width>i&&(i=t.width))}return{width:i+t.left+t.right,height:r}}getMaxSize(){return{width:t,height:t}}createSection(t,n){let r=this.getContainer(),a=this.getLayoutConstraints(t),o=a?.label??t.getId(),s=a?.initiallyOpen??!1,c=new j(o,{chevronSide:this._chevronSide,glyph:a?.glyph??void 0,compact:this._compact,chevronGlyph:this._chevronGlyph??void 0});c.setAnimationTiming(this._animationDuration,M),c.setTransition(`none`);let u=c.getTitleButton();u.on(`action`,()=>this.onHeaderClicked(n)),i.addListener(c,`click`,()=>this.onHeaderClicked(n)),i.addListener(u,`keydown`,e=>this.onHeaderKeyDown(e,n)),i.addSubtreeListener(c,`mouseover`,e=>this.onHeaderHoverEnter(n,e)),i.addSubtreeListener(c,`mouseout`,e=>this.onHeaderHoverLeave(n,e));let d=new l;d.setOverflow(`hidden`),d.setContain(`layout paint`),d.setTransition(`none`),e.sink.appendChild(r.getElement(),c.getElement(!0)),e.sink.appendChild(r.getElement(),d.getElement(!0)),e.sink.appendChild(d.getElement(),t.getElement()),t.setTransition(`none`),this._openState.push(s),this._headers.push(c),this._panelWrappers.push(d),c.setExpanded(s),u.getAria().setControls(d.getId()),d.getAria().setRole(`region`),d.getAria().setLabelledBy(u.getId());for(let e of a?.tools??[])c.addTool(e);this._toolsVisibility===`hover`&&c.setToolsRevealed(!1),this.applySectionTheming(n)}computeTotalMinSize(){let e=this.getContainer();if(!e)return{width:0,height:0};let t=0;for(let n of e.getComponents()){if(!n.isDisplayed())continue;let e=n.getMinSize();e&&(t=Math.max(t,e.width))}return{width:t,height:0}}placeSection(e,t,n,r,i,a,o){let s=this._headers[e],c=this._panelWrappers[e],l=this.effectiveHeaderHeight();s.setX(o),s.setY(n),s.setWidth(a),s.setHeight(l),s.doLayout();let u=n+l;return c.setX(o),c.setY(u),c.setWidth(a),c.setHeight(r),t.setX(0),t.setY(0),t.setWidth(a),t.setHeight(i),u+r}doLayout(){let e=this.getContainer();if(!e||!e.getElement())return;let t=e.getComponents();for(let e=this._headers.length;e<t.length;e++)this.createSection(t[e],e);this.applyContainerTheming();let n=e.getInnerSize(),r=e.getContentInsets(),i=n?n.width:0;if(this.isOverflowingX()){let e=this.computeTotalMinSize();i=Math.max(i,e.width)}let a=this.computeShrinkRatio(t,n),o=this.computeFill(t,n,a),s=this.computeResizableHeights(t,n,a,o);this.layoutSections(t,i,r.getLeft(),r.getTop(),s!==null,(e,n)=>{if(n)return s?.get(e)??this.openContentHeight(t[e],a)+(o.get(e)??0);let r=t[e].getPreferredSize();return r?r.height:100},!0,!0)}layoutSections(e,t,n,r,i,a,o,s){let c=r,l=0,d=null,f=0,p=0;for(let r=0;r<e.length;r++){let m=e[r],h=this._headers[r],g=this._panelWrappers[r],_=this._openState[r];if(!m.isDisplayed()){h.setDisplayed(!1),g.setDisplayed(!1);continue}h.setDisplayed(!0),g.setDisplayed(!0),l>0&&(c+=this._spacing),l+=1;let v=a(r,_),y=_?v:0;_&&i&&d!==null&&(this.placeGutter(p,f,t,n),this._gutterPairs[p]={upper:d,lower:m},p+=1);let b=m.getHeight(),x=_&&o&&!u.isReducedMotion()&&v<b,S=this.placeSection(r,m,c,y,v,t,n);(s||v!==b)&&(x?(this._shrinkAnimations.get(r)?.cancel(),this._shrinkAnimations.set(r,u.afterTransition({component:g,property:`height`,durationMs:this._animationDuration,fallbackBufferMs:40,onComplete:()=>{this._shrinkAnimations.delete(r),m.doLayout()}}))):m.doLayout()),_&&i&&(d=m,f=S),c=S}this._gutterPairs.length=p;for(let e=p;e<this._resizeGutters.length;e++)this._resizeGutters[e].setVisible(!1)}getOrCreateResizeGutter(t){let n=this._resizeGutters[t];if(n)return n;let r=this.getContainer(),i=new _(`vertical`,{collapsible:!1,expandedBackground:`transparent`});return i.setTransition(`none`),i.on(`dragstart`,e=>this.onGutterDragStart(t,e)),i.on(`drag`,e=>this.onGutterDrag(t,e)),e.sink.appendChild(r.getElement(),i.getElement(!0)),this._resizeGutters.push(i),i}placeGutter(e,t,n,r){let i=this.getOrCreateResizeGutter(e);i.setX(r),i.setY(t-P),i.setWidth(n),i.setHeight(P),i.setVisible(!0)}onGutterDragStart(e,t){let n=this._gutterPairs[e];if(!n)return;let r=this.getContainer()?.getComponents()??[];this._dragOpenIndices=[];for(let e=0;e<r.length;e++)r[e].isDisplayed()&&this._openState[e]&&this._dragOpenIndices.push(e);if(this._dragGutterUpperPos=this._dragOpenIndices.indexOf(r.indexOf(n.upper)),this._dragGutterUpperPos===-1)return;this._dragUpper=n.upper,this._dragLower=n.lower,this._dragLastPointer=t;let a=this.getContainer();a&&(i.addViewportListener(a,`mouseup`,this._boundOnGutterDragEnd),i.addViewportListener(a,`touchend`,this._boundOnGutterDragEnd),i.addViewportListener(a,`touchcancel`,this._boundOnGutterDragEnd))}onGutterDrag(e,t){let n=this._gutterPairs[e],r=this.getContainer();if(!n||n.upper!==this._dragUpper||n.lower!==this._dragLower||!r)return;let i=r.getComponents(),a=this._dragOpenIndices,o=this._dragGutterUpperPos,s=t-this._dragLastPointer,c=a.map(e=>i[e].getHeight()),l=a.map(e=>{let t=i[e].getMinSize();return t?t.height:0}),u=a.map(e=>{let t=i[e].getMaxSize();return t?t.height:1/0}),d=[],f=[];for(let e=o;e>=0;e--)d.push(e);for(let e=o+1;e<a.length;e++)f.push(e);let p=s>=0?d:f,m=s>=0?f:d,h=y(p,c,1,l,u),g=y(m,c,-1,l,u),_=Math.max(0,Math.min(Math.abs(s),h,g));this._dragLastPointer+=Math.sign(s)*_;let v=c.slice();b(p,c,_,1,l,u,v),b(m,c,_,-1,l,u,v);let x=new Map;for(let e=0;e<a.length;e++){let t=i[a[e]],n=this._resizePinned.has(t)?1:this._resizeFactor;x.set(a[e],v[e]),this._resizeSizes.set(t,v[e]/n)}let S=r.getContentInsets(),C=this._panelWrappers[a[0]].getWidth();this.layoutSections(i,C,S.getLeft(),S.getTop(),!0,(e,t)=>t?x.get(e)??i[e].getHeight():i[e].getHeight(),!1,!1)}onGutterDragEnd(){let e=this._dragUpper!==null,t=this.getContainer();return t&&(i.removeViewportListener(t,`mouseup`,this._boundOnGutterDragEnd),i.removeViewportListener(t,`touchend`,this._boundOnGutterDragEnd),i.removeViewportListener(t,`touchcancel`,this._boundOnGutterDragEnd)),this._dragUpper=null,this._dragLower=null,e&&this.emit(`sectionresize`,this.getSectionSizes()),!0}computeShrinkRatio(e,t){if(!t)return 0;let n=0,r=0,i=0,a=0;for(let t=0;t<e.length;t++){if(!e[t].isDisplayed()||(a>0&&(n+=this._spacing),a+=1,n+=this.effectiveHeaderHeight(),!this._openState[t]))continue;let o=e[t].getPreferredSize(),s=e[t].getMinSize();r+=o?o.height:100,i+=s?s.height:0}let o=n+r,s=n+i,c=t.height;if(o<=c||s>c)return 0;let l=o-s;return l>0?(o-c)/l:0}openContentHeight(e,t){let n=e.getPreferredSize(),r=n?n.height:100,i=e.getMinSize(),a=i?i.height:0,o=r-t*(r-a),s=e.getMaxSize(),c=s?Math.min(o,s.height):o;return Math.max(c,a)}computeFill(e,t,n){let r=new Map;if(!t)return r;let i=0,a=0,o=[],s=0;for(let t=0;t<e.length;t++)if(e[t].isDisplayed()&&(a>0&&(i+=this._spacing),a+=1,i+=this.effectiveHeaderHeight(),this._openState[t])){let r=this.openContentHeight(e[t],n);i+=r;let a=this.effectiveWeight(e[t]);a>0&&(o.push({index:t,weight:a,headroom:this.fillHeadroom(e[t],r)}),s+=a)}let c=t.height-i;return c<=0||s<=0?r:this.distributeFillWithinMax(o,c)}effectiveWeight(e){let t=this.getLayoutConstraints(e)?.weight??0;return t>0?t:+!!this._fillHeight}resizePinnedSections(e,t,n){let r=[],i=0,a=0;for(let n of t)this.effectiveWeight(e[n])>0?i+=1:(r.push(n),a+=this.clampSectionHeight(e[n],this._resizeSizes.get(e[n])??0));return i===0||a>n?[]:r}clampSectionHeight(e,t){let r=e.getMinSize(),i=e.getMaxSize();return n.clamp(t,r?r.height:0,i?i.height:1/0)}fillHeadroom(e,t){let n=e.getMaxSize();return n?Math.max(0,n.height-t):1/0}distributeFillWithinMax(e,t){let n=new Map,r=new Set(e),i=t;for(;;){let e=0;for(let t of r)e+=t.weight;if(e<=0)break;let t=i/e,a=!1;for(let e of r)if(e.weight*t>e.headroom){n.set(e.index,e.headroom),i-=e.headroom,r.delete(e),a=!0;break}if(!a){for(let e of r)n.set(e.index,e.weight*t);break}if(r.size===0)break}return n}computeResizableHeights(e,t,n,r){if(!this._resizable||!t)return null;for(let t of[...this._resizeSizes.keys()])e.includes(t)||this._resizeSizes.delete(t);let i=0,a=0,o=[];for(let t=0;t<e.length;t++)e[t].isDisplayed()&&(a>0&&(i+=this._spacing),a+=1,i+=this.effectiveHeaderHeight(),this._openState[t]&&o.push(t));if(o.length===0)return null;let s=t.height-i;this.applyPendingSectionSizes(e,s);for(let t of o){let i=e[t];this._resizeSizes.has(i)||this._resizeSizes.set(i,this.openContentHeight(i,n)+(r.get(t)??0))}return this.distributeWithinConstraints(e,o,s)}applyPendingSectionSizes(e,t){let n=this._pendingSectionSizes;if(n===null)return;this._pendingSectionSizes=null;let r=this.sectionSizeUnits(e);if(!h(n,r))return;let i=m(n,t);for(let t=0;t<e.length;t+=1)i[t]>0?this._resizeSizes.set(e[t],i[t]):this._resizeSizes.delete(e[t])}distributeWithinConstraints(e,t,n){let r=new Map,i=new Set(t),a=n,o=1;this._resizePinned.clear();for(let o of this.resizePinnedSections(e,t,n)){let t=this.clampSectionHeight(e[o],this._resizeSizes.get(e[o])??0);r.set(o,t),a-=t,i.delete(o),this._resizePinned.add(e[o])}for(;;){let t=0;for(let n of i)t+=this._resizeSizes.get(e[n])??0;o=t>0?a/t:0;let n=!1;for(let t of i){let s=e[t],c=(this._resizeSizes.get(s)??0)*o,l=s.getMinSize(),u=s.getMaxSize(),d=l?l.height:0,f=u?u.height:1/0;if(c<d){r.set(t,d),a-=d,i.delete(t),n=!0;break}if(c>f){r.set(t,f),a-=f,i.delete(t),n=!0;break}}if(!n){for(let t of i)r.set(t,(this._resizeSizes.get(e[t])??0)*o);break}if(i.size===0)break}return this._resizeFactor=o>0?o:1,r}onHeaderKeyDown(e,t){let n=this._headers.length;if(n===0)return;let r;switch(e.key){case`ArrowDown`:r=(t+1)%n;break;case`ArrowUp`:r=(t-1+n)%n;break;case`Home`:r=0;break;case`End`:r=n-1;break;default:return}return this._headers[r].getTitleButton().focus(),{prevent:!0}}onHeaderClicked(e){let t=this._openState[e];if(this._singleOpen&&!t)for(let t=0;t<this._openState.length;t++)t!==e&&this._openState[t]&&(this.primeWrapper(t),this._openState[t]=!1,this._headers[t].setExpanded(!1),this.emit(`sectiontoggle`,t,!1));let n=!t;this.primeWrapper(e),this._openState[e]=n,this._headers[e].setExpanded(n),this.emit(`sectiontoggle`,e,n),this.relayoutHost()}primeWrapper(t){if(u.isReducedMotion())return;let n=this._panelWrappers[t],r=this.getContainer();this.setSectionTransitions(!0),r?.setTransition(`height ${this._animationDuration}ms ${M}`),n.setWillChange(`height`);let i=r?.getElement();i&&e.source.getElementRect(i);let a=this._wrapperAnimations.get(t);a?(a.cancel(),this._wrapperAnimations.delete(t)):this._toggleAnimations+=1,this._wrapperAnimations.set(t,u.afterTransition({component:n,property:`height`,durationMs:this._animationDuration,fallbackBufferMs:40,onComplete:()=>{this._wrapperAnimations.delete(t),n.setWillChange(null),--this._toggleAnimations,this._toggleAnimations<=0&&(this._toggleAnimations=0,this.setSectionTransitions(!1),r?.setTransition(null),this.relayoutHost())}}))}setSectionTransitions(e){let t=this.getContainer()?.getComponents()??[];for(let n=0;n<this._headers.length;n++)this._headers[n].setTransition(e?this.buildHeaderTransition():`none`),this._panelWrappers[n].setTransition(e?this.buildWrapperTransition():`none`),t[n]?.setTransition(e?this.buildContentTransition():`none`);for(let t of this._resizeGutters)t.setTransition(e?this.buildHeaderTransition():`none`)}buildHeaderTransition(){return`top ${this._animationDuration}ms ${M}`}buildWrapperTransition(){return`height ${this._animationDuration}ms ${M}, top ${this._animationDuration}ms ${M}`}buildContentTransition(){return`height ${this._animationDuration}ms ${M}`}},z=s(Accordion),AccordionConstraints=class extends g{label;initiallyOpen;tools;constructor(e,t,n,r){super(),this.label=e,this.initiallyOpen=t,this.glyph=n??null,this.tools=r}},GridConstraints=class extends g{col;row;rowSpan;colSpan;constructor(){super()}};export{w as a,j as i,AccordionConstraints as n,z as r,GridConstraints as t};
2
- //# sourceMappingURL=GridConstraints-C58LuTqM.js.map