@jimka/typescript-ui 0.1.1 → 0.2.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 (279) hide show
  1. package/dist/lib/{AbstractBooleanInput-C3rj7sje.js → AbstractBooleanInput-BGesvIZy.js} +2 -2
  2. package/dist/lib/{AbstractBooleanInput-C3rj7sje.js.map → AbstractBooleanInput-BGesvIZy.js.map} +1 -1
  3. package/dist/lib/{AbstractInput-CfjW_HM2.js → AbstractInput-BxOtFrER.js} +2 -2
  4. package/dist/lib/{AbstractInput-CfjW_HM2.js.map → AbstractInput-BxOtFrER.js.map} +1 -1
  5. package/dist/lib/AnimatedDropdown-CZQEqQi-.js +2 -0
  6. package/dist/lib/AnimatedDropdown-CZQEqQi-.js.map +1 -0
  7. package/dist/lib/Border-BgaZkc1R.js +2 -0
  8. package/dist/lib/Border-BgaZkc1R.js.map +1 -0
  9. package/dist/lib/{BoxLayout-8ryMD4j5.js → BoxLayout-DrKGfsup.js} +2 -2
  10. package/dist/lib/{BoxLayout-8ryMD4j5.js.map → BoxLayout-DrKGfsup.js.map} +1 -1
  11. package/dist/lib/Button-U1rsP4v8.js +2 -0
  12. package/dist/lib/Button-U1rsP4v8.js.map +1 -0
  13. package/dist/lib/{Card-AKIUAWYS.js → Card-BVwOS8AG.js} +2 -2
  14. package/dist/lib/{Card-AKIUAWYS.js.map → Card-BVwOS8AG.js.map} +1 -1
  15. package/dist/lib/ComboBox-B9EDPu6T.js +2 -0
  16. package/dist/lib/ComboBox-B9EDPu6T.js.map +1 -0
  17. package/dist/lib/Component-DXf5a3g0.js +2 -0
  18. package/dist/lib/Component-DXf5a3g0.js.map +1 -0
  19. package/dist/lib/Container-D5H8VxJK.js +2 -0
  20. package/dist/lib/{Container-3KsvsJ6S.js.map → Container-D5H8VxJK.js.map} +1 -1
  21. package/dist/lib/DOM-CGn7xyTw.js +2 -0
  22. package/dist/lib/DOM-CGn7xyTw.js.map +1 -0
  23. package/dist/lib/{DragManager-c6M_mE3e.js → DragManager-CI4mZQFy.js} +2 -2
  24. package/dist/lib/{DragManager-tPMnbjeO.js.map → DragManager-CI4mZQFy.js.map} +1 -1
  25. package/dist/lib/FieldDecorator-CJs9gwqH.js +2 -0
  26. package/dist/lib/{FieldDecorator-Bl0h9UEF.js.map → FieldDecorator-CJs9gwqH.js.map} +1 -1
  27. package/dist/lib/{Fit-CFIr4P9R.js → Fit-DjRsiwlg.js} +2 -2
  28. package/dist/lib/{Fit-CUS1JXy3.js.map → Fit-DjRsiwlg.js.map} +1 -1
  29. package/dist/lib/Glyph-KEf4nIv2.js +2 -0
  30. package/dist/lib/Glyph-KEf4nIv2.js.map +1 -0
  31. package/dist/lib/{Grid-Czux--Mr.js → Grid-DdL9TVeJ.js} +2 -2
  32. package/dist/lib/{Grid-D8luwRPI.js.map → Grid-DdL9TVeJ.js.map} +1 -1
  33. package/dist/lib/GridConstraints-DkLueyrf.js +2 -0
  34. package/dist/lib/GridConstraints-DkLueyrf.js.map +1 -0
  35. package/dist/lib/{HBox-BWMf9h6r.js → HBox-Ce0GTCJP.js} +2 -2
  36. package/dist/lib/{HBox-BWMf9h6r.js.map → HBox-Ce0GTCJP.js.map} +1 -1
  37. package/dist/lib/{Header-CQjomjo0.js → Header-BQIVpBte.js} +2 -2
  38. package/dist/lib/{Header-CQjomjo0.js.map → Header-BQIVpBte.js.map} +1 -1
  39. package/dist/lib/{IconText-BXJK0MOq.js → IconText-Bo4Qcnot.js} +2 -2
  40. package/dist/lib/{IconText-BXJK0MOq.js.map → IconText-Bo4Qcnot.js.map} +1 -1
  41. package/dist/lib/LayoutConstraints-DkctJZXB.js +2 -0
  42. package/dist/lib/LayoutConstraints-DkctJZXB.js.map +1 -0
  43. package/dist/lib/LayoutSerialization-BT66TY83.js +2 -0
  44. package/dist/lib/LayoutSerialization-BT66TY83.js.map +1 -0
  45. package/dist/lib/LayoutSizes-DU3qSq0w.js +2 -0
  46. package/dist/lib/LayoutSizes-DU3qSq0w.js.map +1 -0
  47. package/dist/lib/List-DtTVTyWW.js +2 -0
  48. package/dist/lib/List-DtTVTyWW.js.map +1 -0
  49. package/dist/lib/Menu-Dz4L7EKJ.js +2 -0
  50. package/dist/lib/Menu-Dz4L7EKJ.js.map +1 -0
  51. package/dist/lib/{MenuButton-D15cSbMf.js → MenuButton-VJ5uC3c1.js} +2 -2
  52. package/dist/lib/{MenuButton-D15cSbMf.js.map → MenuButton-VJ5uC3c1.js.map} +1 -1
  53. package/dist/lib/Panel-DzWdYwq1.js +2 -0
  54. package/dist/lib/Panel-DzWdYwq1.js.map +1 -0
  55. package/dist/lib/{Position-DJKB0N3l.js → Position-A39T7-_1.js} +2 -2
  56. package/dist/lib/{Position-DJKB0N3l.js.map → Position-A39T7-_1.js.map} +1 -1
  57. package/dist/lib/ProgressSpinner-zJKtGyNJ.js +2 -0
  58. package/dist/lib/ProgressSpinner-zJKtGyNJ.js.map +1 -0
  59. package/dist/lib/RadioButton-CYSSv4nV.js +2 -0
  60. package/dist/lib/RadioButton-CYSSv4nV.js.map +1 -0
  61. package/dist/lib/{RovingTabIndex-CFIzIjjU.js → RovingTabIndex-BSZ31Vp5.js} +2 -2
  62. package/dist/lib/{RovingTabIndex-D-zOuptw.js.map → RovingTabIndex-BSZ31Vp5.js.map} +1 -1
  63. package/dist/lib/Scrollbar-BhtOjqkG.js +2 -0
  64. package/dist/lib/Scrollbar-BhtOjqkG.js.map +1 -0
  65. package/dist/lib/Slider-CdXm7E64.js +2 -0
  66. package/dist/lib/Slider-CdXm7E64.js.map +1 -0
  67. package/dist/lib/{Spacer-BVQncB5B.js → Spacer-D9NGW4QG.js} +2 -2
  68. package/dist/lib/{Spacer-BVQncB5B.js.map → Spacer-D9NGW4QG.js.map} +1 -1
  69. package/dist/lib/{TabButton-DqYDfN7P.js → TabButton-CThevdY_.js} +2 -2
  70. package/dist/lib/{TabButton-DqYDfN7P.js.map → TabButton-CThevdY_.js.map} +1 -1
  71. package/dist/lib/Text-gz6qjFfP.js +2 -0
  72. package/dist/lib/Text-gz6qjFfP.js.map +1 -0
  73. package/dist/lib/Tooltip-tkXDk5Bo.js +3 -0
  74. package/dist/lib/Tooltip-tkXDk5Bo.js.map +1 -0
  75. package/dist/lib/{VBox-CdV9VGxR.js → VBox-EIqw85Rh.js} +2 -2
  76. package/dist/lib/{VBox-CdV9VGxR.js.map → VBox-EIqw85Rh.js.map} +1 -1
  77. package/dist/lib/{VirtualRowView-C18j90n5.js → VirtualRowView-BxpHQ_u8.js} +2 -2
  78. package/dist/lib/{VirtualRowView-C18j90n5.js.map → VirtualRowView-BxpHQ_u8.js.map} +1 -1
  79. package/dist/lib/{VirtualScroller-BKMvTisA.js → VirtualScroller-DwEEJE1_.js} +2 -2
  80. package/dist/lib/{VirtualScroller-BKMvTisA.js.map → VirtualScroller-DwEEJE1_.js.map} +1 -1
  81. package/dist/lib/component/button.es.js +1 -1
  82. package/dist/lib/component/button.es.js.map +1 -1
  83. package/dist/lib/component/chart.es.js +1 -1
  84. package/dist/lib/component/chart.es.js.map +1 -1
  85. package/dist/lib/component/container.es.js +1 -1
  86. package/dist/lib/component/container.es.js.map +1 -1
  87. package/dist/lib/component/diagram.es.js +1 -1
  88. package/dist/lib/component/diagram.es.js.map +1 -1
  89. package/dist/lib/component/display.es.js +1 -1
  90. package/dist/lib/component/display.es.js.map +1 -1
  91. package/dist/lib/component/editor.es.js +2 -2
  92. package/dist/lib/component/editor.es.js.map +1 -1
  93. package/dist/lib/component/input.es.js +1 -1
  94. package/dist/lib/component/input.es.js.map +1 -1
  95. package/dist/lib/component/list.es.js +1 -1
  96. package/dist/lib/component/menubar.es.js +1 -1
  97. package/dist/lib/component/menubar.es.js.map +1 -1
  98. package/dist/lib/component/table.es.js +2 -2
  99. package/dist/lib/component/table.es.js.map +1 -1
  100. package/dist/lib/component/tree.es.js +1 -1
  101. package/dist/lib/component/tree.es.js.map +1 -1
  102. package/dist/lib/core.es.js +1 -1
  103. package/dist/lib/core.es.js.map +1 -1
  104. package/dist/lib/layout.es.js +1 -1
  105. package/dist/lib/overlay.es.js +1 -1
  106. package/dist/lib/overlay.es.js.map +1 -1
  107. package/dist/lib/primitive.es.js +1 -1
  108. package/dist/lib/router.es.js +1 -1
  109. package/dist/lib/types/component/button/Button.d.ts +4 -3
  110. package/dist/lib/types/component/chart/AbstractChart.d.ts +1 -1
  111. package/dist/lib/types/component/chart/ChartLegend.d.ts +1 -1
  112. package/dist/lib/types/component/container/DialogBackdrop.d.ts +2 -1
  113. package/dist/lib/types/component/container/MenuItem.d.ts +1 -1
  114. package/dist/lib/types/component/container/ScrollStrip.d.ts +1 -0
  115. package/dist/lib/types/component/container/SplitGutter.d.ts +3 -2
  116. package/dist/lib/types/component/container/TabBar.d.ts +1 -2
  117. package/dist/lib/types/component/container/TabPanel.d.ts +6 -3
  118. package/dist/lib/types/component/container/WindowBorder.d.ts +2 -1
  119. package/dist/lib/types/component/container/WindowHeader.d.ts +2 -1
  120. package/dist/lib/types/component/display/Glyph.d.ts +2 -1
  121. package/dist/lib/types/component/display/Markdown.d.ts +1 -1
  122. package/dist/lib/types/component/display/PaginationBar.d.ts +1 -1
  123. package/dist/lib/types/component/display/SpinnerWrap.d.ts +2 -0
  124. package/dist/lib/types/component/display/Video.d.ts +1 -1
  125. package/dist/lib/types/component/display/VideoPlayer.d.ts +1 -1
  126. package/dist/lib/types/component/editor/CodeEditor.d.ts +2 -1
  127. package/dist/lib/types/component/editor/MarkdownEditor.d.ts +1 -1
  128. package/dist/lib/types/component/input/Checkbox.d.ts +2 -1
  129. package/dist/lib/types/component/input/Link.d.ts +1 -1
  130. package/dist/lib/types/component/input/RadioButton.d.ts +2 -1
  131. package/dist/lib/types/component/input/Slider.d.ts +2 -1
  132. package/dist/lib/types/component/input/Text.d.ts +1 -3
  133. package/dist/lib/types/component/input/TextInput.d.ts +3 -2
  134. package/dist/lib/types/component/list/AbstractSelectableList.d.ts +2 -1
  135. package/dist/lib/types/component/menubar/MenuBarButton.d.ts +1 -1
  136. package/dist/lib/types/core/AnimatedDropdown.d.ts +6 -2
  137. package/dist/lib/types/core/Animation.d.ts +9 -6
  138. package/dist/lib/types/core/Component.d.ts +16 -11
  139. package/dist/lib/types/core/DOM.d.ts +8 -0
  140. package/dist/lib/types/core/Event.d.ts +12 -6
  141. package/dist/lib/types/core/index.d.ts +2 -2
  142. package/dist/lib/types/layout/Accordion.d.ts +2 -0
  143. package/dist/lib/types/layout/Border.d.ts +1 -0
  144. package/dist/lib/types/layout/CollapseSupport.d.ts +5 -1
  145. package/dist/lib/types/layout/LayoutConstraints.d.ts +1 -0
  146. package/dist/lib/types/layout/LayoutManager.d.ts +2 -0
  147. package/dist/lib/types/layout/Split.d.ts +1 -0
  148. package/dist/lib/types/layout/Tab.d.ts +10 -3
  149. package/dist/lib/types/overlay/AbstractWindow.d.ts +9 -2
  150. package/dist/lib/types/overlay/Dialog.d.ts +6 -0
  151. package/dist/lib/types/overlay/Dock.d.ts +12 -2
  152. package/dist/lib/types/overlay/Drawer.d.ts +5 -0
  153. package/dist/lib/types/overlay/Menu.d.ts +3 -1
  154. package/dist/lib/types/overlay/Notification.d.ts +3 -0
  155. package/dist/lib/types/overlay/Popover.d.ts +3 -1
  156. package/dist/lib/types/overlay/Rail.d.ts +7 -0
  157. package/dist/lib/types/overlay/Tooltip.d.ts +3 -0
  158. package/dist/lib/types/overlay/index.d.ts +1 -1
  159. package/dist/lib/validation.es.js +1 -1
  160. package/llms.txt +1 -1
  161. package/package.json +1 -1
  162. package/dist/lib/AbstractBooleanInput-C6CidMMX.js +0 -2
  163. package/dist/lib/AbstractBooleanInput-C6CidMMX.js.map +0 -1
  164. package/dist/lib/AbstractInput-DD-NpicS.js +0 -2
  165. package/dist/lib/AbstractInput-DD-NpicS.js.map +0 -1
  166. package/dist/lib/AnimatedDropdown-BFz-DO7R.js +0 -2
  167. package/dist/lib/AnimatedDropdown-BFz-DO7R.js.map +0 -1
  168. package/dist/lib/AnimatedDropdown-BbGCs70E.js +0 -2
  169. package/dist/lib/AnimatedDropdown-BbGCs70E.js.map +0 -1
  170. package/dist/lib/Border-5Ki2DCWz.js +0 -2
  171. package/dist/lib/Border-5Ki2DCWz.js.map +0 -1
  172. package/dist/lib/Border-oZC_SDy8.js +0 -2
  173. package/dist/lib/Border-oZC_SDy8.js.map +0 -1
  174. package/dist/lib/BoxLayout-DgZukB5_.js +0 -2
  175. package/dist/lib/BoxLayout-DgZukB5_.js.map +0 -1
  176. package/dist/lib/Button-Cdq2ySPL.js +0 -2
  177. package/dist/lib/Button-Cdq2ySPL.js.map +0 -1
  178. package/dist/lib/Button-DEUtBqK4.js +0 -2
  179. package/dist/lib/Button-DEUtBqK4.js.map +0 -1
  180. package/dist/lib/Card-UF0fq8cQ.js +0 -2
  181. package/dist/lib/Card-UF0fq8cQ.js.map +0 -1
  182. package/dist/lib/ComboBox-GOBOAJ1N.js +0 -2
  183. package/dist/lib/ComboBox-GOBOAJ1N.js.map +0 -1
  184. package/dist/lib/ComboBox-e_YVsWBr.js +0 -2
  185. package/dist/lib/ComboBox-e_YVsWBr.js.map +0 -1
  186. package/dist/lib/Component-BR2f0Itb.js +0 -2
  187. package/dist/lib/Component-BR2f0Itb.js.map +0 -1
  188. package/dist/lib/Component-Bs6TvaGZ.js +0 -2
  189. package/dist/lib/Component-Bs6TvaGZ.js.map +0 -1
  190. package/dist/lib/Container-3KsvsJ6S.js +0 -2
  191. package/dist/lib/Container-CzyZeMyZ.js +0 -2
  192. package/dist/lib/Container-CzyZeMyZ.js.map +0 -1
  193. package/dist/lib/DOM-DeF_dWe2.js +0 -2
  194. package/dist/lib/DOM-DeF_dWe2.js.map +0 -1
  195. package/dist/lib/DragManager-c6M_mE3e.js.map +0 -1
  196. package/dist/lib/DragManager-tPMnbjeO.js +0 -2
  197. package/dist/lib/FieldDecorator-Bl0h9UEF.js +0 -2
  198. package/dist/lib/FieldDecorator-E7WzutjO.js +0 -2
  199. package/dist/lib/FieldDecorator-E7WzutjO.js.map +0 -1
  200. package/dist/lib/Fit-CFIr4P9R.js.map +0 -1
  201. package/dist/lib/Fit-CUS1JXy3.js +0 -2
  202. package/dist/lib/Glyph-6Ki3A1_a.js +0 -2
  203. package/dist/lib/Glyph-6Ki3A1_a.js.map +0 -1
  204. package/dist/lib/Glyph-WUqTF_Z9.js +0 -2
  205. package/dist/lib/Glyph-WUqTF_Z9.js.map +0 -1
  206. package/dist/lib/Grid-Czux--Mr.js.map +0 -1
  207. package/dist/lib/Grid-D8luwRPI.js +0 -2
  208. package/dist/lib/GridConstraints-CzC0w4i-.js +0 -2
  209. package/dist/lib/GridConstraints-CzC0w4i-.js.map +0 -1
  210. package/dist/lib/GridConstraints-Q3wvuovN.js +0 -2
  211. package/dist/lib/GridConstraints-Q3wvuovN.js.map +0 -1
  212. package/dist/lib/HBox-Q8y1PHlk.js +0 -2
  213. package/dist/lib/HBox-Q8y1PHlk.js.map +0 -1
  214. package/dist/lib/Header-zPdvC2AX.js +0 -2
  215. package/dist/lib/Header-zPdvC2AX.js.map +0 -1
  216. package/dist/lib/IconText-BvGfu7eq.js +0 -2
  217. package/dist/lib/IconText-BvGfu7eq.js.map +0 -1
  218. package/dist/lib/LayoutConstraints-CHI2lhPd.js +0 -2
  219. package/dist/lib/LayoutConstraints-CHI2lhPd.js.map +0 -1
  220. package/dist/lib/LayoutSerialization-CWU0iEuV.js +0 -2
  221. package/dist/lib/LayoutSerialization-CWU0iEuV.js.map +0 -1
  222. package/dist/lib/LayoutSerialization-C_zcwaN3.js +0 -2
  223. package/dist/lib/LayoutSerialization-C_zcwaN3.js.map +0 -1
  224. package/dist/lib/LayoutSizes-BW4wyGDI.js +0 -2
  225. package/dist/lib/LayoutSizes-BW4wyGDI.js.map +0 -1
  226. package/dist/lib/LayoutSizes-XdhpAOmc.js +0 -2
  227. package/dist/lib/LayoutSizes-XdhpAOmc.js.map +0 -1
  228. package/dist/lib/List-BgxnLWnl.js +0 -2
  229. package/dist/lib/List-BgxnLWnl.js.map +0 -1
  230. package/dist/lib/List-D-GhoVgB.js +0 -2
  231. package/dist/lib/List-D-GhoVgB.js.map +0 -1
  232. package/dist/lib/Menu-BdnwRY0M.js +0 -2
  233. package/dist/lib/Menu-BdnwRY0M.js.map +0 -1
  234. package/dist/lib/Menu-Wz4MK6sA.js +0 -2
  235. package/dist/lib/Menu-Wz4MK6sA.js.map +0 -1
  236. package/dist/lib/MenuButton-JQQaKThJ.js +0 -2
  237. package/dist/lib/MenuButton-JQQaKThJ.js.map +0 -1
  238. package/dist/lib/Panel-DApa7vA6.js +0 -2
  239. package/dist/lib/Panel-DApa7vA6.js.map +0 -1
  240. package/dist/lib/Panel-DIsdaqc2.js +0 -2
  241. package/dist/lib/Panel-DIsdaqc2.js.map +0 -1
  242. package/dist/lib/Position-B-WfZYAJ.js +0 -2
  243. package/dist/lib/Position-B-WfZYAJ.js.map +0 -1
  244. package/dist/lib/ProgressSpinner-CNYcsBhw.js +0 -2
  245. package/dist/lib/ProgressSpinner-CNYcsBhw.js.map +0 -1
  246. package/dist/lib/ProgressSpinner-Dzaka7_c.js +0 -2
  247. package/dist/lib/ProgressSpinner-Dzaka7_c.js.map +0 -1
  248. package/dist/lib/RadioButton-CepkneSA.js +0 -2
  249. package/dist/lib/RadioButton-CepkneSA.js.map +0 -1
  250. package/dist/lib/RadioButton-eI3-vXn3.js +0 -2
  251. package/dist/lib/RadioButton-eI3-vXn3.js.map +0 -1
  252. package/dist/lib/RovingTabIndex-CFIzIjjU.js.map +0 -1
  253. package/dist/lib/RovingTabIndex-D-zOuptw.js +0 -2
  254. package/dist/lib/Scrollbar-DQdCdj94.js +0 -2
  255. package/dist/lib/Scrollbar-DQdCdj94.js.map +0 -1
  256. package/dist/lib/Scrollbar-DchfiFKC.js +0 -2
  257. package/dist/lib/Scrollbar-DchfiFKC.js.map +0 -1
  258. package/dist/lib/Slider-DvDdVvRm.js +0 -2
  259. package/dist/lib/Slider-DvDdVvRm.js.map +0 -1
  260. package/dist/lib/Slider-xRxNSjFN.js +0 -2
  261. package/dist/lib/Slider-xRxNSjFN.js.map +0 -1
  262. package/dist/lib/Spacer-BqiPiCqz.js +0 -2
  263. package/dist/lib/Spacer-BqiPiCqz.js.map +0 -1
  264. package/dist/lib/TabButton-pZKFYg7b.js +0 -2
  265. package/dist/lib/TabButton-pZKFYg7b.js.map +0 -1
  266. package/dist/lib/Text-D1RrBY52.js +0 -2
  267. package/dist/lib/Text-D1RrBY52.js.map +0 -1
  268. package/dist/lib/Text-DJoUHukb.js +0 -2
  269. package/dist/lib/Text-DJoUHukb.js.map +0 -1
  270. package/dist/lib/Tooltip-4lU_tf6r.js +0 -3
  271. package/dist/lib/Tooltip-4lU_tf6r.js.map +0 -1
  272. package/dist/lib/Tooltip-5BR7yYEX.js +0 -3
  273. package/dist/lib/Tooltip-5BR7yYEX.js.map +0 -1
  274. package/dist/lib/VBox-D5B9ecw0.js +0 -2
  275. package/dist/lib/VBox-D5B9ecw0.js.map +0 -1
  276. package/dist/lib/VirtualRowView-Con9SWiU.js +0 -2
  277. package/dist/lib/VirtualRowView-Con9SWiU.js.map +0 -1
  278. package/dist/lib/VirtualScroller-BPDmO1ir.js +0 -2
  279. package/dist/lib/VirtualScroller-BPDmO1ir.js.map +0 -1
@@ -1,2 +0,0 @@
1
- import{a as e,l as t,t as n,u as r}from"./Position-B-WfZYAJ.js";import{d as i,f as a,l as o,t as s}from"./Component-BR2f0Itb.js";import{t as c}from"./ListenerBag-WPdKuuds.js";import{t as l}from"./Container-3KsvsJ6S.js";import{a as u}from"./Tooltip-4lU_tf6r.js";import{d,i as f,l as p,n as m,o as h,r as g,t as _}from"./LayoutSizes-BW4wyGDI.js";import{i as v,n as y}from"./Border-oZC_SDy8.js";import{t as b}from"./LayoutConstraints-CHI2lhPd.js";import{n as x,r as S,t as C}from"./DragManager-tPMnbjeO.js";var w=4,T=1,Split=class extends o{_orientation=`horizontal`;_sizes=new Map;_gutters=[];_collapsed=new Map;_weights=new Map;_pendingCollapsed=[];_listeners=new c;_pendingSizes=null;_dragOriginPointer=0;_dragOriginLhsSize=0;_dragOriginRhsSize=0;_lastAvailableMain=0;_collapseAnimation=null;constructor(e){super(),e&&this.applyOptions(e)}applyOptions(e){if(super.applyOptions(e),e.orientation!==void 0&&this.setOrientation(e.orientation),e.collapsedPanes!==void 0&&(this._pendingCollapsed=[...e.collapsedPanes]),e.paneSizes!==void 0&&(this._pendingSizes=e.paneSizes.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)}}}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)}isPaneCollapsed(e){let t=this.getContainer();if(!t)return!1;let n=t.getLaidOutComponents()[e];return n?this._collapsed.get(n)??!1:!1}collapsesTowardStart(e){return e===`west`||e===`north`}paneDirection(e){return this.getLayoutConstraints(e)?.collapseDirection??(this._orientation===`horizontal`?`west`:`north`)}paneCollapsible(e){return this.getLayoutConstraints(e)?.collapsible!==!1}gutterTargetPane(e,t){let n=t[e+1];if(n&&this.paneCollapsible(n)&&!this.collapsesTowardStart(this.paneDirection(n)))return e+1;let r=t[e];return r&&this.paneCollapsible(r)&&this.collapsesTowardStart(this.paneDirection(r))?e:-1}paneServingGutter(e,t){let n=this.paneDirection(t[e]);return this.collapsesTowardStart(n)?e<t.length-1&&this.gutterTargetPane(e,t)===e?e:-1:e>0&&this.gutterTargetPane(e-1,t)===e?e-1:-1}setPaneCollapsed(e,t){let n=this.getContainer();if(!n)return this;let r=n.getLaidOutComponents(),i=r[e];if(!i||this.paneServingGutter(e,r)<0||(this._collapsed.get(i)??!1)===t)return this;this._collapsed.set(i,t),this.emit(`panecollapse`,e,t);let a=[...r.map(e=>({component:e,relayout:!0})),...this._gutters.map(e=>({component:e,relayout:!1}))];return this._collapseAnimation=v(n,i,a,this._collapseAnimation,()=>{this._collapseAnimation=null}),this}getOrientation(){return this._orientation}setOrientation(e){return this._orientation=e,this}setPaneSize(e,t){return this._sizes.set(e,t),this}getPaneSize(e){return this._sizes.get(e)}setPaneResizeWeight(e,t){return this._weights.set(e,t),this}getPaneResizeWeight(e){return this._weights.get(e)}effectiveResizeWeight(e,t){return this._weights.get(e)??this.getLayoutConstraints(e)?.weight??t}clampMain(e,n,r){let i=e.getMinSize(),a=e.getMaxSize(),o=i?r?i.width:i.height:0,s=a?r?a.width:a.height:1/0;return t.clamp(n,o,s)}isPinnedMain(e,t){let n=e.getMinSize(),r=e.getMaxSize();return(n?t?n.width:n.height:0)===(r?t?r.width:r.height:1/0)}isResizePinnedMain(e){return this.effectiveResizeWeight(e,T)===0}seedFromPreferred(e,t){for(let n of e){if(this._sizes.has(n))continue;let e=n.getPreferredSizeConstraint();if(!e)continue;let r=t?e.width:e.height;this._sizes.set(n,this.clampMain(n,r,t))}}transferPaneSize(e,t){let n=this._sizes.get(e);if(n===void 0)return this;this._sizes.set(t,n),this._sizes.delete(e);let r=this._collapsed.get(e);r!==void 0&&(this._collapsed.set(t,r),this._collapsed.delete(e));let i=this._weights.get(e);return i!==void 0&&(this._weights.set(t,i),this._weights.delete(e)),this}getPaneRatios(){let e=this.getContainer();if(!e)return[];let t=e.getComponents();return t.length===0?[]:g(t.map(e=>this._sizes.get(e)??0),t.length)}getPreferredSize(){return this.computeContentSize(e=>e.getPreferredSize())}getMinSize(){return this.computeContentSize(e=>e.getMinSize())}getMaxSize(){return{width:e,height:e}}computeContentSize(e){let t=this.getContainer();if(!t)return null;let n=t.getLaidOutComponents(),r=t.getPerimeterSize(),i=this._orientation===`horizontal`,a=0,o=0;for(let t=0;t<n.length;t+=1){let r=e(n[t]);r&&(a+=i?r.width:r.height,o=Math.max(o,i?r.height:r.width))}return a+=this.gutterTotal(n.length),i?{width:a+r.left+r.right,height:o+r.top+r.bottom}:{width:o+r.left+r.right,height:a+r.top+r.bottom}}applyPaneRatios(e){let t=this.getContainer();if(!t)return this;let n=t.getComponents(),r=n.length;if(r===0)return this;let i=g(e,r),a=t.getInnerSize(),o=a?this._orientation===`horizontal`?a.width:a.height:0,s=Math.max(0,o-this.gutterTotal(r)),c=s>0?s:1;return n.forEach((e,t)=>{this._sizes.set(e,i[t]*c)}),this._lastAvailableMain=c,t.scheduleLayout(),this}paneSizeUnits(e){return e.map(e=>this.isResizePinnedMain(e)?`px`:`ratio`)}getPaneSizes(){let e=this.getContainer();if(!e)return[];let t=e.getComponents();if(t.length===0)return[];let n=this.paneSizeUnits(t);return this._pendingSizes!==null&&m(this._pendingSizes,n)?this._pendingSizes.map(e=>({...e})):f(n,t.map(e=>this._sizes.get(e)??0))}applyPaneSizes(e){let t=this.getContainer();if(!t)return this;let n=t.getComponents();if(!m(e,this.paneSizeUnits(n)))return this;let r=t.getInnerSize(),i=r?this._orientation===`horizontal`?r.width:r.height:0,a=Math.max(0,i-this.gutterTotal(n.length)),o=_(e,a);return n.forEach((e,t)=>this.setPaneSize(e,o[t])),this._lastAvailableMain=a>0?a:1,t.scheduleLayout(),this}setPaneCollapsedImmediate(e,t){let n=this.getContainer();if(!n)return this;let r=n.getLaidOutComponents(),i=r[e];return!i||t&&this.paneServingGutter(e,r)<0?this:(this._collapsed.set(i,t),this.emit(`panecollapse`,e,t),n.scheduleLayout(),this)}onDragStart(e,t,n){let r=this._gutters.indexOf(t),i=e.getLaidOutComponents()[r],a=e.getLaidOutComponents()[r+1];this._dragOriginPointer=n,this._orientation===`horizontal`?(this._dragOriginLhsSize=i.getWidth(),this._dragOriginRhsSize=a.getWidth()):(this._dragOriginLhsSize=i.getHeight(),this._dragOriginRhsSize=a.getHeight())}onDrag(e,t,n){let r=this._gutters.indexOf(t),i=e.getLaidOutComponents()[r],a=e.getLaidOutComponents()[r+1],o=this._orientation===`horizontal`,s=this._dragOriginLhsSize+this._dragOriginRhsSize,c=i.getMinSize(),l=a.getMinSize(),u=i.getMaxSize(),d=a.getMaxSize(),f=c?o?c.width:c.height:0,p=l?o?l.width:l.height:0,m=u?o?u.width:u.height:1/0,h=d?o?d.width:d.height:1/0,g=n-this._dragOriginPointer,_=Math.max(f,s-h),v=Math.min(m,s-p),y=this._dragOriginLhsSize+g;y=Math.max(_,Math.min(v,y));let b=s-y,x=y-(o?i.getWidth():i.getHeight());o?(i.setWidth(y),t.setX(t.getX()+x),a.setX(a.getX()+x),a.setWidth(b)):(i.setHeight(y),t.setY(t.getY()+x),a.setY(a.getY()+x),a.setHeight(b)),this._sizes.set(i,y),this._sizes.set(a,b),i.doLayout(),a.doLayout()}onDragEnd(){this.emit(`paneresize`,this.getPaneSizes())}detach(){super.detach();for(let e of this._gutters){let t=e.getElement();r.sink.removeChild(r.source.getParentNode(t),t),e.destroy()}return this._gutters=[],this}gutterTotal(e){return Math.max(0,e-1)*w}computeTotalMinSize(){let e=this.getContainer();if(!e)return{width:0,height:0};let t=e.getLaidOutComponents();if(t.length===0)return{width:0,height:0};let n=t.length-1,r=0,i=0;for(let e=0;e<t.length;e+=1){let a=t[e],o=this._sizes.get(a),s=this._collapsed.get(a)??!1,c=e<n;if(s&&c)r+=18;else{if(!s)if(o!=null)r+=o;else{let e=a.getMinSize();e&&(r+=this._orientation===`horizontal`?e.width:e.height)}c&&(r+=w)}let l=a.getMinSize();l&&(i=Math.max(i,this._orientation===`horizontal`?l.height:l.width))}return this._orientation===`horizontal`?{width:r,height:i}:{width:i,height:r}}doLayout(){let e=this,t=this.getContainer();if(!t)return;let n=t.getInnerSize();if(!n)return;let a=this._orientation===`horizontal`?n.width:n.height;n=this.inflateForOverflow(n);let o=t.getElement(),s=t.getLaidOutComponents(),c=t.getContentInsets(),l=s.length-1;for(let n=this._gutters.length;n<l;n+=1){let i=new y(this._orientation,{expandedBackground:`transparent`}),a=n;i.on(`dragstart`,function(n){e.onDragStart(t,i,n)}),i.on(`drag`,function(n){e.onDrag(t,i,n)}),i.on(`dragend`,()=>this.onDragEnd()),i.on(`collapse`,function(){let n=e.gutterTargetPane(a,t.getLaidOutComponents());n>=0&&e.setPaneCollapsed(n,!e.isPaneCollapsed(n))}),this._gutters.push(i),r.sink.appendChild(o,i.getElement(!0))}let u=c.getLeft(),d=c.getTop();this.recalculateSizes(),this.applyPendingSizes(),this.applyPendingCollapsed(s);let f=this._orientation===`horizontal`,p=f?n.height:n.width,m=this.computeMainAxisSizes(s,a),h=new Set;for(let e=0;e<s.length;e+=1){let t=s[e],n=this.paneServingGutter(e,s);if((this._collapsed.get(t)??!1)&&n>=0){let e=this._gutters[n];e.setCollapseDirection(this.paneDirection(t)),e.setCollapsible(!0),this.placeGutterAsStrip(e,t,u,d,p,f,this.paneDirection(t)),h.add(n),f?u+=18:d+=18;continue}let r=m.get(t);if(t.setVisible(!0),this.placeComponent(t,u,d,f?r:p,f?p:r,i.BOTH),t.setClipPath(n>=0?`inset(0 0 0 0)`:null),f?u+=r:d+=r,e<l){let t=this._gutters[e],n=this.gutterTargetPane(e,s);!(n>=0&&(this._collapsed.get(s[n])??!1)&&this.paneServingGutter(n,s)===e)&&!h.has(e)&&(t.setOpaque(!1),t.setVisible(!0),t.setCollapsible(n>=0),n>=0&&t.setCollapseDirection(this.paneDirection(s[n])),t.setX(u),t.setY(d),f?(t.setWidth(w),t.setHeight(p),u+=w):(t.setWidth(p),t.setHeight(w),d+=w),h.add(e))}}for(let e=0;e<this._gutters.length;e+=1)h.has(e)||this._gutters[e].setVisible(!1)}placeGutterAsStrip(e,t,n,r,a,o,s){e.setOpaque(!0),e.setVisible(!0),e.setX(n),e.setY(r),o?(e.setWidth(18),e.setHeight(a)):(e.setWidth(a),e.setHeight(18));let c=this._sizes.get(t)??18,l=this.collapsesTowardStart(s);if(t.setVisible(!0),o){let e=l?n:n+18-c;this.placeComponent(t,e,r,c,a,i.BOTH)}else{let e=l?r:r+18-c;this.placeComponent(t,n,e,a,c,i.BOTH)}t.setClipPath(this.paneClipInset(s))}paneClipInset(e){switch(e){case`east`:return`inset(0 0 0 100%)`;case`north`:return`inset(0 0 100% 0)`;case`south`:return`inset(100% 0 0 0)`;default:return`inset(0 100% 0 0)`}}applyPendingSizes(){let e=this._pendingSizes;e!==null&&(this._pendingSizes=null,this.applyPaneSizes(e))}applyPendingCollapsed(e){if(this._pendingCollapsed.length!==0){for(let t of this._pendingCollapsed){let n=e[t];n&&this.paneServingGutter(t,e)>=0&&this._collapsed.set(n,!0)}this._pendingCollapsed=[]}}computeMainAxisSizes(e,t){let n=e.length-1,r=0,i=0,a=0;for(let t=0;t<e.length;t+=1){let o=e[t];(this._collapsed.get(o)??!1)&&this.paneServingGutter(t,e)>=0?(i+=1,!this.collapsesTowardStart(this.paneDirection(o))&&t<n&&(a+=1)):r+=this._sizes.get(o)??0}let o=Math.max(0,t-this.gutterTotal(e.length)),s=Math.max(0,o-i*(18-w)+a*w),c=r>0?s/r:0,l=new Map;for(let t=0;t<e.length;t+=1){let n=e[t],r=(this._collapsed.get(n)??!1)&&this.paneServingGutter(t,e)>=0;l.set(n,r?0:(this._sizes.get(n)??0)*c)}return l}recalculateSizes(){let e=this.getContainer();if(!e)return;let t=e.getInnerSize();if(!t)return;let n=e.getComponents();for(let e of[...this._sizes.keys()])n.indexOf(e)<0&&(this._sizes.delete(e),this._collapsed.delete(e));for(let e of[...this._weights.keys()])n.indexOf(e)<0&&this._weights.delete(e);let r=this._orientation===`horizontal`?t.width:t.height,i=Math.max(0,r-this.gutterTotal(n.length)),a=this._orientation===`horizontal`;this.seedFromPreferred(n,a);for(let e of n){let t=this._sizes.get(e);t!==void 0&&this._sizes.set(e,this.clampMain(e,t,a))}if(this._lastAvailableMain>0&&i>0&&i!==this._lastAvailableMain&&this._sizes.size>0){let e=i-this._lastAvailableMain,t=0;for(let e=0;e<n.length;e+=1){let r=n[e];t+=this.effectiveResizeWeight(r,this._sizes.get(r)??0)}if(t>0)for(let r=0;r<n.length;r+=1){let i=n[r],a=this._sizes.get(i);if(a!=null){let n=this.effectiveResizeWeight(i,a);this._sizes.set(i,Math.max(0,a+n/t*e))}}}if(this._lastAvailableMain===0&&i>0&&this._sizes.size>0){let e=0;for(let t=0;t<n.length;t+=1){let r=this.effectiveResizeWeight(n[t],0);r>0&&(e+=r)}if(e>0){let t=0;for(let e=0;e<n.length;e+=1)t+=this._sizes.get(n[e])??0;let r=i-t;for(let t=0;t<n.length;t+=1){let i=n[t],o=this.effectiveResizeWeight(i,0);if(o>0){let t=this._sizes.get(i)??0;this._sizes.set(i,this.clampMain(i,t+o/e*r,a))}}}}let o=0;for(let e=0;e<n.length;e+=1){let t=n[e];this._sizes.has(t)&&(o+=1)}for(let e=0;e<n.length;e+=1){let t=n[e],r=this._sizes.get(t);if(r==null){if(this._sizes.size!=0){r=0;for(let e=0;e<n.length;e+=1){let t=n[e],i=this._sizes.get(t);if(i==null)continue;let a=i*(1/(o+1));r+=a,i-=a,this._sizes.set(t,i)}}else r=i;this._sizes.set(t,r),o+=1}}let s=0,c=0,l=0;for(let e=0;e<n.length;e+=1){let t=n[e],r=this._sizes.get(t)??0;this.isPinnedMain(t,a)?s+=r:this.isResizePinnedMain(t)?c+=r:l+=r}if(i>0){let e=Math.max(0,i-s),t=1,r=1,o=1;l>0&&e>=c?o=(e-c)/l:c>0?(o=0,r=e/c):s>0&&(t=i/s);for(let e=0;e<n.length;e+=1){let i=n[e],s=this._sizes.get(i);if(s==null)continue;let c=this.isPinnedMain(i,a)?t:this.isResizePinnedMain(i)?r:o;c!==1&&this._sizes.set(i,s*c)}}i>0&&(this._lastAvailableMain=i)}},E=a(Split),D=.25,DropZoneHighlight=class extends s{_valid=!0;constructor(){super(),this.setPosition(n.ABSOLUTE),this.setPointerEvents(`none`),this.setBackgroundColor(`var(--ts-ui-drag-dropzone-active-bg)`),this.setVisible(!1)}placeBand(e,t,n,r){this.setX(e),this.setY(t),this.setWidth(n),this.setHeight(r),this.setVisible(!0)}setValid(e){this._valid!==e&&(this._valid=e,this.setBackgroundColor(e?`var(--ts-ui-drag-dropzone-active-bg)`:`var(--ts-ui-drag-dropzone-invalid-bg)`))}hide(){this.setVisible(!1)}},O=u.Band.Window-1,DropZoneOverlay=class extends s{_highlight=new DropZoneHighlight;_zone=null;_valid=!0;constructor(){super(),this.setPosition(n.ABSOLUTE),this.setZIndex(O),this.setPointerEvents(`none`),this.setBackgroundColor(`var(--ts-ui-drag-dropzone-bg)`),this.setBorder({border:`1px solid var(--ts-ui-drag-dropzone-border)`})}attachTo(e){let t=this.getElement(!0);this.setX(0),this.setY(0),this.setWidth(e.getWidth()),this.setHeight(e.getHeight());let n=e.getElement(!0);r.source.getParentElement(t)!==n&&r.sink.appendChild(n,t);let i=this._highlight.getElement(!0);r.source.getParentElement(i)!==t&&r.sink.appendChild(t,i)}setHighlight(e,t=!0){if(e===this._zone&&t===this._valid)return;if(this._zone=e,this._valid=t,e===null){this._highlight.hide();return}this._highlight.setValid(t);let n=this.getWidth(),r=this.getHeight(),i=D,a=0,o=0,s=n,c=r;switch(e){case`top`:a=0,o=0,s=n,c=r*i;break;case`bottom`:a=0,o=r*(1-i),s=n,c=r*i;break;case`left`:a=0,o=0,s=n*i,c=r;break;case`right`:a=n*(1-i),o=0,s=n*i,c=r;break;case`center`:a=n*i,o=r*i,s=n*(1-2*i),c=r*(1-2*i);break}this._highlight.placeBand(a,o,s,c)}highlightFull(){this._zone=null,this._valid=!0,this._highlight.setValid(!0),this._highlight.placeBand(0,0,this.getWidth(),this.getHeight())}detach(){this._zone=null,this._valid=!0,this.removeElement()}},k=a(DropZoneOverlay),DockRegion=class{_region;_overlay=new k;_teardown;_onStructureChanged;_raiseTimer=null;constructor(e,t){this._region=e,this._onStructureChanged=t??null,this._teardown=C.makeDropTarget(e,{accepts:e=>e.dragData.tabDrag===!0,suppressValidityTint:!0,onDragOver:e=>{let t=e.dragData.componentId,n=this.dropZone(e.clientX,e.clientY);return this._overlay.attachTo(this._region),this._overlay.setHighlight(n,this.isLegalDrop(t,n)),this.scheduleSpringRaise(),null},onDragLeave:()=>{this._overlay.detach(),this.clearSpringRaise()},onDrop:e=>{let t=e.dragData.componentId,n=this.dropZone(e.clientX,e.clientY);if(this._overlay.detach(),this.clearSpringRaise(),!this.isLegalDrop(t,n))return!1;let r=S.get(t);if(!r)return!1;n===`center`?this.dockAsTab(r):this.splitOnEdge(r,n),this.raiseHostWindow(),this._onStructureChanged?.()}})}destroy(){this._teardown(),this._overlay.detach(),this.clearSpringRaise()}hostWindow(){for(let e=this._region;e;e=e.getParentComponent())if(e instanceof d)return e;return null}raiseHostWindow(){this.hostWindow()?.bringToFront()}scheduleSpringRaise(){this._raiseTimer===null&&(this._raiseTimer=setTimeout(()=>{this._raiseTimer=null,C.isDragging()&&this.raiseHostWindow()},x))}clearSpringRaise(){this._raiseTimer!==null&&(clearTimeout(this._raiseTimer),this._raiseTimer=null)}dropZone(e,t){return this.isSeedRegion()?`center`:this.computeZone(e,t)}isSeedRegion(){return this._region.getComponents().every(e=>this._region.getLayoutConstraints(e)?.transient===!0)}computeZone(e,t){let n=r.source.getViewportRect(this._region),i=(e-n.left)/n.width,a=(t-n.top)/n.height,o=D,s=i,c=1-i,l=a,u=1-a,d=Math.min(s,c,l,u);return d>=o?`center`:d===s?`left`:d===c?`right`:d===l?`top`:`bottom`}isLegalDrop(e,t){for(let t=this._region;t;t=t.getParentComponent())if(t.getId()===e)return!1;let n=this._region.getComponents();return n.length===1&&n[0].getId()===e?!1:t===`center`?!this.isRedundantCenterDrop(e):!this.isRedundantEdgeDrop(e,t)}isRedundantCenterDrop(e){let t=S.get(e);if(!t)return!1;let n=t.getParentComponent();if(this._region.getLayoutManager()instanceof h)return n===this._region;let r=this._region.getParentComponent();return r?.getLayoutManager()instanceof h&&n===r}isRedundantEdgeDrop(e,t){let n=S.get(e);if(!n)return!1;let r=n.getParentComponent();if(!r||r.getComponents().length!==1)return!1;let i=t===`left`||t===`right`?`horizontal`:`vertical`,a=t===`top`||t===`left`,o=this._region.getLayoutManager();if(o instanceof E&&String(o.getOrientation())===i){if(r.getParentComponent()!==this._region)return!1;let e=this._region.getComponents();return a?e[0]===r:e[e.length-1]===r}let s=this._region.getParentComponent(),c=s?.getLayoutManager()instanceof h?s:this._region,l=c?.getParentComponent();if(!l)return!1;let u=l.getLayoutManager();if(!(u instanceof E&&String(u.getOrientation())===i)||r.getParentComponent()!==l)return!1;let d=l.getComponents(),f=d.indexOf(c),p=d.indexOf(r);return a?p===f-1:p===f+1}splitOnEdge(e,t){let n=t===`left`||t===`right`?`horizontal`:`vertical`,r=t===`top`||t===`left`,i=this.newStack();i.moveComponent(e);let a=this._region.getLayoutManager();if(a instanceof E&&String(a.getOrientation())===n){this._region.moveComponent(i,r?0:this._region.getComponents().length);return}let o=this._region.getParentComponent(),s=o?.getLayoutManager()instanceof h?o:this._region,c=s.getParentComponent();if(!c)return;let u=c.getLayoutManager(),d=c.getComponents().indexOf(s);if(u instanceof E&&String(u.getOrientation())===n){c.moveComponent(i,r?d:d+1);return}let f=new l({layoutManager:new E({orientation:n})});c.moveComponent(f,d);let p=this.ensureStacked(s);f.moveComponent(i,+!r),f.moveComponent(p,+!!r),u instanceof E&&u.transferPaneSize(s,f)}ensureStacked(e){let t=e.getLayoutManager();if(t instanceof h||t instanceof E)return e;let n=this.newStack();return n.moveComponent(e),n}newStack(){let e=new l({layoutManager:new h({reorderable:!0,compact:!0})});return e.getLayoutManager().on(`empty`,()=>this.pruneEmptyStack(e)),e}pruneEmptyStack(e){let t=e.getParentComponent();t&&t.getLayoutManager()instanceof E&&(t.removeComponent(e),this.collapseIfSinglePaneSplit(t))}collapseIfSinglePaneSplit(e){if(!(e.getLayoutManager()instanceof E))return;let t=e.getComponents();if(t.length!==1)return;let n=e.getParentComponent();if(!n)return;let r=n.getComponents().indexOf(e),i=n.getLayoutManager();i instanceof E&&i.transferPaneSize(e,t[0]),n.moveComponent(t[0],r),n.removeComponent(e)}dockAsTab(e){if(this._region.getLayoutManager()instanceof h){this._region.moveComponent(e),this._region.scheduleLayout();return}let t=this._region.getParentComponent();if(!t)return;if(t.getLayoutManager()instanceof h){t.moveComponent(e),t.scheduleLayout();return}let n=t.getComponents().indexOf(this._region),r=this.newStack();t.moveComponent(r,n),r.moveComponent(this._region),r.moveComponent(e),r.scheduleLayout()}};function managerKind(e){let t=e.getLayoutManager();return t?t.getClassName().replace(/^_/,``):``}function panelIdOf(e){return e.getId()}function serializableChildren(e){return e.getComponents().filter(t=>e.getLayoutConstraints(t)?.transient!==!0)}function nodeFor(e){let t=managerKind(e);if(t===`Split`){let t=e.getLayoutManager(),n=e.getComponents().map(nodeFor);return{kind:`split`,orientation:t.getOrientation()===`vertical`?`vertical`:`horizontal`,children:n,ratios:t.getPaneRatios(),collapsed:n.map((e,n)=>t.isPaneCollapsed(n))}}if(t===`Tab`){let t=e.getLayoutManager();return{kind:`tab`,children:serializableChildren(e).map(nodeFor),activeIndex:t.getActiveTabIndex()}}let n=e.getParentComponent()?.getLayoutConstraints(e)?.glyph??null;return{kind:`panel`,panelId:panelIdOf(e),glyph:n}}function windowContentOf(e){return e.getComponents().find(t=>!e.isChromeComponent(t))??null}function windowNodeFor(e){let t=windowContentOf(e);return t?{kind:`window`,content:nodeFor(t),header:e.getTitle(),rect:e.getRect(),state:e.getWindowState(),restoreRect:e.getRestoreRect()}:null}function serializeLayout(e){let t=p.getOpenWindows().map(windowNodeFor).filter(e=>e!==null);return{version:1,root:nodeFor(e),windows:t}}function collectLeaves(e,t){serializableChildren(e).forEach(e=>{let n=managerKind(e);n===`Split`||n===`Tab`?collectLeaves(e,t):t.push(e)})}function parkLeaves(e,t,n){let r=[];collectLeaves(e,r),t.forEach(e=>{let t=windowContentOf(e);if(!t)return;let n=managerKind(t);n===`Split`||n===`Tab`?collectLeaves(t,r):r.push(t)});let i=new Map;return r.forEach(e=>{let t=panelIdOf(e);n(t)===e&&(i.set(t,e),e.getParentComponent()?.removeComponent(e))}),i}function hostsComponent(e,t){for(let n=t;n;n=n.getParentComponent())if(n===e)return!0;return!1}function constraintsFor(e){if(e.kind!==`panel`||!e.glyph)return;let t=new b;return t.glyph=e.glyph,t}function materializeNode(e,t,n){if(e.kind===`panel`){let r=t.get(e.panelId)??n(e.panelId);return r||console.warn(`restoreLayout: no component for panelId "${e.panelId}"; skipping.`),r}let r=new s;return populateContainer(r,e,t,n),r}function populateContainer(e,t,n,r){if(t.kind===`split`){let i=new E({orientation:t.orientation});e.setLayoutManager(i);let a=[];t.children.forEach((i,o)=>{let s=materializeNode(i,n,r);s&&(e.moveComponent(s,void 0,constraintsFor(i)),a.push({ratio:t.ratios[o]??0,collapsed:t.collapsed[o]??!1}))}),i.applyPaneRatios(a.map(e=>e.ratio)),a.forEach((e,t)=>{e.collapsed&&i.setPaneCollapsedImmediate(t,!0)})}else{let i=new h({reorderable:!0,compact:!0});e.setLayoutManager(i),t.children.forEach(t=>{let a=materializeNode(t,n,r);a&&(e.moveComponent(a,void 0,constraintsFor(t)),i.createTab(a))}),i.setActiveTabIndex(t.activeIndex)}}function applyWindow(e,t,n){let r=e.content??(e.panelId?{kind:`panel`,panelId:e.panelId,glyph:null}:null);if(!r){console.warn(`restoreLayout: window node has neither content nor panelId; skipping.`);return}let i=materializeNode(r,t,n);if(!i)return;let a=new p(e.header);a.moveComponent(i,void 0,constraintsFor(r));let o=e.state===`normal`?e.rect:e.restoreRect??e.rect;a.applyRect(o),a.show(),e.state!==`normal`&&a.setWindowState(e.state)}function restoreLayout(e,t,n){let r=p.getOpenWindows().filter(t=>!hostsComponent(t,e)),i=parkLeaves(e,r,n);if(r.forEach(e=>e.onExitAction()),e.removeAllComponents(),t.root.kind===`panel`){let r=materializeNode(t.root,i,n);r&&e.moveComponent(r,void 0,constraintsFor(t.root))}else populateContainer(e,t.root,i,n);t.windows.forEach(e=>applyWindow(e,i,n))}export{E as a,k as i,serializeLayout as n,DockRegion as r,restoreLayout as t};
2
- //# sourceMappingURL=LayoutSerialization-CWU0iEuV.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"LayoutSerialization-CWU0iEuV.js","names":[],"sources":["../../src/typescript/lib/layout/Split.ts","../../src/typescript/lib/overlay/DropZoneOverlay.ts","../../src/typescript/lib/layout/DockRegion.ts","../../src/typescript/lib/layout/LayoutSerialization.ts"],"sourcesContent":["// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { LayoutManager, LayoutManagerOptions } from \"~/layout/LayoutManager.js\";\nimport { SplitGutter } from \"~/component/container/SplitGutter.js\";\nimport { CollapseDirection } from \"~/component/container/CollapseButton.js\";\nimport { Component } from \"~/core/Component.js\";\nimport { Util } from \"~/core/Util.js\";\nimport { FillType } from \"~/layout/FillType.js\";\nimport { Size, UNBOUNDED } from \"~/primitive/Size.js\";\nimport { COLLAPSE_STRIP_SIZE, runCollapse, CollapseParticipant } from \"~/layout/CollapseSupport.js\";\nimport { callable } from \"~/core/Callable.js\";\nimport { DOM } from \"~/core/DOM.js\";\nimport { ListenerBag } from \"~/core/ListenerBag.js\";\nimport { LayoutSize, LayoutSizeUnit, toLayoutSizes, fromLayoutSizes, isRestorableSizes, normalizeRatios } from \"~/layout/LayoutSizes.js\";\nimport type { AxisOrientation } from \"~/primitive/Axis.js\";\n\n// Pixel thickness of a single draggable gutter. The main-axis sizing math\n// subtracts the gutters' combined footprint before dividing space among\n// panes, so this constant is the single source of truth for both the size\n// reservation and the gutter placement in `doLayout`.\nconst GUTTER_SIZE = 4;\n\n// Probe weight for the refill's resize-pin test. Any positive value works: it\n// exists only so a pane with *no* weight set resolves through\n// `effectiveResizeWeight`'s fallback to a non-zero weight and stays flexible,\n// which leaves `=== 0` meaning an explicit pin (`setPaneResizeWeight(pane, 0)`\n// or a `weight: 0` constraint). A `0` probe here would pin every unset pane.\nconst WEIGHT_UNSET_PROBE = 1;\n\n/**\n * String-literal union of the events emitted by {@link Split}.\n *\n * @category Layouts\n */\nexport type SplitEvent = \"paneresize\" | \"panecollapse\";\n\n/**\n * Callback invoked once a completed gutter drag settles a pane's sizes.\n *\n * @param sizes - The panes' sizes after the drag, in child order — the same\n * array {@link Split.getPaneSizes} would return.\n *\n * @category Layouts\n */\nexport type PaneResizeCallback = (sizes: LayoutSize[]) => void;\n\n/**\n * Callback invoked when a pane's collapsed state changes.\n *\n * @param index - Zero-based index of the toggled pane.\n * @param collapsed - True if the pane is now collapsed.\n *\n * @category Layouts\n */\nexport type PaneCollapseCallback = (index: number, collapsed: boolean) => void;\n\n/**\n * Construction-time options for {@link Split}.\n *\n * @category Layouts\n */\nexport interface SplitOptions extends LayoutManagerOptions {\n orientation?: AxisOrientation;\n /** Indices of panes to start collapsed (applied on first layout). */\n collapsedPanes?: number[];\n /** Pane sizes to restore on first layout; discarded whole when stale. */\n paneSizes?: LayoutSize[];\n /**\n * Multi-event listener bag dispatched to {@link Split.on} at\n * construction time.\n */\n listeners?: {\n paneresize?: PaneResizeCallback;\n panecollapse?: PaneCollapseCallback;\n };\n}\n\n/**\n * A layout manager that splits the container into two or more resizable panels\n * separated by draggable gutter elements.\n * The split orientation can be `'horizontal'` (panels side by side) or `'vertical'` (panels stacked).\n *\n * @category Layouts\n */\nclass Split extends LayoutManager {\n\n private _orientation: AxisOrientation = \"horizontal\";\n private _sizes: Map<Component, number> = new Map<Component, number>();\n private _gutters: Array<SplitGutter> = [];\n\n // Per-pane collapsed state, paralleling `_sizes`. A collapsed pane keeps its\n // stored size untouched so a restore returns it to the same ratio; only the\n // displayed geometry in `doLayout` substitutes the strip thickness. The\n // pane's own gutter becomes the visible strip while collapsed.\n private _collapsed: Map<Component, boolean> = new Map<Component, boolean>();\n\n // Per-pane container-resize weight, paralleling `_sizes`. When the container\n // extent changes, the delta is split across the panes in proportion to these\n // weights (weight 0 pins the pane's px size). A pane absent from the map\n // defaults to its current stored size, which makes an all-unset Split split\n // the delta proportionally to size — identical to a uniform rescale. Absence\n // and an explicit `0` therefore mean different things, so only explicitly-set\n // weights are stored.\n private _weights: Map<Component, number> = new Map<Component, number>();\n\n // Pane indices to collapse on the first connected layout, taken from the\n // `collapsedPanes` option. Drained once because pane components aren't\n // resolvable from indices until the container has its children.\n private _pendingCollapsed: number[] = [];\n\n private _listeners: ListenerBag<SplitEvent> = new ListenerBag<SplitEvent>();\n\n // Sizes to restore on the first connected layout, taken from the\n // `paneSizes` option (or a direct `applyPaneSizes` call before the\n // container is attached). Drained once, mirroring `_pendingCollapsed`:\n // panes aren't resolvable from indices until the container has children.\n private _pendingSizes: LayoutSize[] | null = null;\n\n private _dragOriginPointer: number = 0;\n private _dragOriginLhsSize: number = 0;\n private _dragOriginRhsSize: number = 0;\n\n // The available (net-of-gutters) main-axis extent the stored `_sizes`\n // were last normalised against. Lets `recalculateSizes` rescale the\n // frozen pane sizes when the container grows or shrinks, so panes keep\n // filling the container across viewport resizes. `0` until the first\n // connected layout, which correctly suppresses the rescale pass.\n private _lastAvailableMain: number = 0;\n\n // Canceller for the in-flight collapse/restore animation, or null when\n // idle. Calling it stops the rAF loop in place so a rapid re-toggle can\n // re-snapshot the current geometry and retarget without two loops fighting.\n private _collapseAnimation: (() => void) | null = null;\n\n constructor(options?: SplitOptions) {\n // LayoutManager's constructor takes no options; applied via applyOptions below.\n // eslint-disable-next-line local/forward-super-options\n super();\n\n if (options) {\n this.applyOptions(options);\n }\n }\n\n /**\n * Applies a {@link SplitOptions} bag, dispatching the split orientation\n * after the inherited LayoutManager defaults.\n *\n * @param options - The options bag carrying the values to apply.\n */\n protected applyOptions(options: SplitOptions): void {\n super.applyOptions(options);\n\n if (options.orientation !== undefined) {\n this.setOrientation(options.orientation);\n }\n\n if (options.collapsedPanes !== undefined) {\n this._pendingCollapsed = [...options.collapsedPanes];\n }\n\n if (options.paneSizes !== undefined) {\n this._pendingSizes = options.paneSizes.map(size => ({ ...size }));\n }\n\n if (options.listeners !== undefined) {\n const listeners = options.listeners;\n\n for (const event of Object.keys(listeners) as Array<keyof typeof listeners>) {\n const listener = listeners[event];\n\n // A union of two events' callback types no longer narrows to a\n // single `on` overload; the cast mirrors `Component.applyListeners`'\n // own `(this as any).on` — sound for the same reason: `event` and\n // `listener` are still a matched pair from the same options key.\n if (listener !== undefined) {\n (this as any).on(event, listener);\n }\n }\n }\n }\n\n /**\n * Registers a listener for one of this split's events.\n *\n * @param event - `\"paneresize\"` fires once a completed gutter drag\n * settles a pane's sizes, receiving the panes' sizes in child order;\n * `\"panecollapse\"` fires whenever a pane's collapsed state changes,\n * receiving the zero-based pane index and whether it is now collapsed.\n * @param listener - The callback to invoke when the event fires.\n *\n * @returns This split, for method chaining.\n */\n on(event: \"paneresize\", listener: PaneResizeCallback): this;\n on(event: \"panecollapse\", listener: PaneCollapseCallback): this;\n on(event: SplitEvent, listener: Function): this {\n this._listeners.add(event, listener);\n\n return this;\n }\n\n /**\n * Removes a previously registered listener. The exact callback reference\n * must match.\n *\n * @param event - The event the listener was registered for.\n * @param listener - The callback to remove.\n *\n * @returns This split, for method chaining.\n */\n off(event: SplitEvent, listener: Function): this {\n this._listeners.remove(event, listener);\n\n return this;\n }\n\n /**\n * Fires every listener registered for `event` with `payload`, in\n * registration order.\n *\n * @param event - The event to emit.\n * @param payload - Forwarded to each listener.\n */\n protected emit(event: \"paneresize\", sizes: LayoutSize[]): void;\n protected emit(event: \"panecollapse\", index: number, collapsed: boolean): void;\n protected emit(event: SplitEvent, ...payload: unknown[]): void {\n this._listeners.fire(event, ...payload);\n }\n\n /**\n * Returns whether the pane at the given container index is collapsed.\n *\n * @param index - Zero-based pane index.\n * @returns True when the pane is collapsed; false when expanded or the\n * index is out of range.\n */\n isPaneCollapsed(index: number): boolean {\n const container = this.getContainer();\n if (!container) {\n return false;\n }\n\n const pane = container.getLaidOutComponents()[index];\n\n return pane ? (this._collapsed.get(pane) ?? false) : false;\n }\n\n /**\n * Whether a collapse direction heads toward the split's leading edge\n * (`west`/`north`) rather than its trailing edge (`east`/`south`). A\n * leading-collapsing pane tucks into a strip made from the gutter on its\n * trailing side; a trailing-collapsing one uses the gutter on its leading\n * side (which is how the otherwise-gutterless last pane collapses).\n *\n * @param direction - The collapse heading to classify.\n * @returns True for `west`/`north`.\n */\n private collapsesTowardStart(direction: CollapseDirection): boolean {\n return direction === \"west\" || direction === \"north\";\n }\n\n /**\n * Resolves a pane's configured collapse direction, defaulting to the\n * leading direction for the split's axis (`west` horizontal, `north`\n * vertical) when its constraint leaves it unset.\n *\n * @param pane - The pane whose direction to resolve.\n * @returns The effective collapse heading.\n */\n private paneDirection(pane: Component): CollapseDirection {\n const constraints = this.getLayoutConstraints(pane);\n\n return constraints?.collapseDirection ?? (this._orientation === \"horizontal\" ? \"west\" : \"north\");\n }\n\n /**\n * Whether the pane opts into collapsing. Split is opt-**out**: a pane is\n * collapsible unless its constraint sets `collapsible: false`. (Border reads\n * the same {@link LayoutConstraints.collapsible} field opt-**in** —\n * `collapsible ?? false` — so the two managers default `undefined`\n * differently by design.) A non-collapsible pane reports no serving gutter,\n * which suppresses its chevron and every collapse path while leaving the\n * gutter a draggable divider.\n *\n * @param pane - The pane whose collapsibility to resolve.\n * @returns True unless the pane's constraint sets `collapsible: false`.\n */\n private paneCollapsible(pane: Component): boolean {\n return this.getLayoutConstraints(pane)?.collapsible !== false;\n }\n\n /**\n * Returns the index of the pane that gutter `gutterIndex` collapses, or\n * `-1` when it collapses neither neighbour (a plain divider with no\n * chevron). The trailing pane claims the gutter when it opts to collapse\n * toward the end; otherwise the leading pane uses it to collapse toward the\n * start. The two are mutually exclusive, so no pane is served by two gutters.\n *\n * @param gutterIndex - The gutter between panes `gutterIndex` and `gutterIndex + 1`.\n * @param components - The container's current panes.\n * @returns The served pane index, or `-1`.\n */\n private gutterTargetPane(gutterIndex: number, components: Array<Component>): number {\n const next = components[gutterIndex + 1];\n if (next && this.paneCollapsible(next) && !this.collapsesTowardStart(this.paneDirection(next))) {\n return gutterIndex + 1;\n }\n\n const lead = components[gutterIndex];\n if (lead && this.paneCollapsible(lead) && this.collapsesTowardStart(this.paneDirection(lead))) {\n return gutterIndex;\n }\n\n return -1;\n }\n\n /**\n * Returns the index of the gutter that collapses the pane at `index`, or\n * `-1` when the pane cannot collapse — no gutter on the side its direction\n * needs, or that gutter is claimed by the adjacent pane. A leading-collapsing\n * pane uses its trailing gutter; a trailing-collapsing one uses its leading\n * gutter (the mechanism that lets the last pane collapse).\n *\n * @param index - The pane index.\n * @param components - The container's current panes.\n * @returns The serving gutter index, or `-1`.\n */\n private paneServingGutter(index: number, components: Array<Component>): number {\n const direction = this.paneDirection(components[index]);\n\n if (this.collapsesTowardStart(direction)) {\n return index < components.length - 1 && this.gutterTargetPane(index, components) === index ? index : -1;\n }\n\n return index > 0 && this.gutterTargetPane(index - 1, components) === index ? index - 1 : -1;\n }\n\n /**\n * Collapses or restores the pane at the given container index, animating the\n * change. The pane's own gutter slides to the pane's outer edge and widens\n * into the opaque collapse strip (cross-fading its fill) while the pane keeps\n * its full size and reveals via a clip-path; the freed main-axis space is\n * redistributed to the remaining expanded panes. The whole pass is one\n * coordinated animation: the toggled pane clip-reveals while every other pane\n * and the gutters interpolate their geometry — re-laying out their contents\n * each frame — in lockstep (see `CollapseSupport.runCollapse`).\n *\n * The serving gutter depends on the pane's `collapseDirection` constraint: a\n * leading-collapsing pane (the default) uses the gutter on its trailing side,\n * a trailing-collapsing one the gutter on its leading side — which is how the\n * last pane collapses. A pane with no serving gutter cannot collapse.\n *\n * @param index - Zero-based pane index.\n * @param collapsed - True to collapse, false to restore.\n * @returns This layout manager, for method chaining.\n */\n setPaneCollapsed(index: number, collapsed: boolean): this {\n const container = this.getContainer();\n if (!container) {\n return this;\n }\n\n const components = container.getLaidOutComponents();\n const pane = components[index];\n if (!pane) {\n return this;\n }\n\n const gutterIndex = this.paneServingGutter(index, components);\n if (gutterIndex < 0) {\n return this;\n }\n\n const current = this._collapsed.get(pane) ?? false;\n if (current === collapsed) {\n return this;\n }\n\n this._collapsed.set(pane, collapsed);\n this.emit(\"panecollapse\", index, collapsed);\n\n // Every box that moves: the panes (content re-laid-out each frame) and\n // the gutters (geometry only). The toggled pane is among them and also\n // clip-reveals; `runCollapse` coordinates the whole pass.\n const participants: CollapseParticipant[] = [\n ...components.map(component => ({ component, relayout: true })),\n ...this._gutters.map(gutter => ({ component: gutter, relayout: false })),\n ];\n\n this._collapseAnimation = runCollapse(container, pane, participants, this._collapseAnimation, () => {\n this._collapseAnimation = null;\n });\n\n return this;\n }\n\n /**\n * Returns the split orientation.\n *\n * @returns `'horizontal'` or `'vertical'`.\n */\n getOrientation(): AxisOrientation {\n return this._orientation;\n }\n\n /**\n * Sets the split orientation.\n *\n * @param orientation - `'horizontal'` for side-by-side panels, `'vertical'` for stacked panels.\n */\n setOrientation(orientation: AxisOrientation) : this {\n this._orientation = orientation;\n\n return this;\n }\n\n /**\n * Seeds or overrides the stored main-axis size for one pane.\n *\n * Lets a caller that has just inserted a pane (an edge-drop dock, say) give\n * it a specific share instead of the equal division `recalculateSizes`\n * applies to a pane with no stored size. The value is a px main-axis extent\n * — the same unit the gutters store and {@link recalculateSizes} rescales —\n * not a ratio; pass it relative to the other panes' current stored sizes.\n *\n * @param pane - The pane whose stored size to seed or override.\n * @param size - The main-axis extent in px to store for the pane.\n * @returns This layout manager, for method chaining.\n */\n setPaneSize(pane: Component, size: number): this {\n this._sizes.set(pane, size);\n\n return this;\n }\n\n /**\n * Returns a pane's stored main-axis size in px, or `undefined` when the pane\n * has no stored size yet (it has never been laid out, or it was added since\n * the last layout). A pane reporting `undefined` is the one\n * {@link recalculateSizes} gives a proportional share on the next layout.\n *\n * @param pane - The pane whose stored size to read.\n * @returns The stored main-axis extent in px, or `undefined` when unset.\n */\n getPaneSize(pane: Component): number | undefined {\n return this._sizes.get(pane);\n }\n\n /**\n * Sets a pane's container-resize weight — how it shares the size delta when\n * the container's main-axis extent changes (a viewport resize, a host\n * re-layout). `0` pins the pane's px size (it does not move on resize); a\n * positive weight absorbs the delta in proportion to the other panes'\n * weights. A pane with no weight set defaults to its current stored size, so\n * an all-unset `Split` splits the delta proportionally to size — the same\n * proportional rescale as before any weight was set. Gutter-drag (user\n * resize) is unaffected. When the container shrinks below a pinned pane's\n * size the pane cannot keep its full extent — geometry must fill the\n * container — so pure pinning holds only while the container is large enough.\n *\n * This is the runtime override of the pane's `weight` layout constraint: a\n * pane added with `addComponent(pane, { weight: 0 })` is pinned declaratively\n * at construction, and this setter takes precedence over that constraint.\n *\n * @param pane - The pane whose resize weight to set.\n * @param weight - The resize weight; `0` pins, positive absorbs.\n * @returns This layout manager, for method chaining.\n */\n setPaneResizeWeight(pane: Component, weight: number): this {\n this._weights.set(pane, weight);\n\n return this;\n }\n\n /**\n * Returns a pane's explicitly-set resize weight, or `undefined` when unset\n * (the pane defaults to its current size on resize). `undefined` and `0` are\n * distinct: `0` is an explicit pin, `undefined` is \"behave as before\".\n *\n * @param pane - The pane whose resize weight to read.\n * @returns The explicitly-set resize weight, or `undefined` when unset.\n */\n getPaneResizeWeight(pane: Component): number | undefined {\n return this._weights.get(pane);\n }\n\n /**\n * Resolves a pane's effective container-resize weight, in precedence order:\n * an imperative {@link setPaneResizeWeight} entry (runtime override), else\n * the pane's `weight` layout constraint (declarative, construction-time),\n * else the fallback (its current stored size, so an unset pane behaves as a\n * proportional rescale). Reads the raw constraint — unset is `undefined`, not\n * the box managers' `?? 0` — so an unset pane falls through to the fallback\n * rather than being pinned.\n *\n * @param pane - The pane whose resize weight to resolve.\n * @param fallback - The weight to use when neither an explicit weight nor a\n * `weight` constraint is set.\n * @returns The effective resize weight.\n */\n private effectiveResizeWeight(pane: Component, fallback: number): number {\n return this._weights.get(pane) ?? this.getLayoutConstraints(pane)?.weight ?? fallback;\n }\n\n /**\n * Clamps a candidate main-axis px to the pane's `[min, max]` along the split\n * axis. Min wins if a contradictory `min > max` is set.\n *\n * @param pane - The pane whose bounds constrain the value.\n * @param value - The candidate main-axis extent in px.\n * @param horizontal - True when the split's main axis is width.\n * @returns The clamped main-axis extent.\n */\n private clampMain(pane: Component, value: number, horizontal: boolean): number {\n const min = pane.getMinSize();\n const max = pane.getMaxSize();\n const lo = min ? (horizontal ? min.width : min.height) : 0;\n const hi = max ? (horizontal ? max.width : max.height) : Number.POSITIVE_INFINITY;\n\n return Util.clamp(value, lo, hi);\n }\n\n /**\n * True when the pane cannot move on the main axis — its `[min, max]` range is\n * a single point (`min == max`), the collapsed-pin state. An unset max reads\n * as `MAX_SAFE_INTEGER`, never equal to a real min, so an unconstrained pane\n * is never reported pinned.\n *\n * @param pane - The pane to test.\n * @param horizontal - True when the split's main axis is width.\n * @returns True when the pane is pinned to a single main-axis extent.\n */\n private isPinnedMain(pane: Component, horizontal: boolean): boolean {\n const min = pane.getMinSize();\n const max = pane.getMaxSize();\n const lo = min ? (horizontal ? min.width : min.height) : 0;\n const hi = max ? (horizontal ? max.width : max.height) : Number.POSITIVE_INFINITY;\n\n return lo === hi;\n }\n\n /**\n * True when the pane's px size is pinned by an explicit container-resize weight\n * of `0` — the pin the delta-distribution block honours, so the refill must not\n * undo it by rescaling the pane. Distinct from {@link isPinnedMain}: that is a\n * single-point `[min, max]` range (one legal extent, never rescaled), this is a\n * caller preference that yields when the container is too small to hold it.\n *\n * Resolves through the same precedence as the resize block (imperative weight,\n * else `weight` constraint, else fallback), probing with a positive fallback so\n * an unset pane reports flexible and only an explicit `0` reports pinned.\n *\n * @param pane - The pane to test.\n * @returns True when the pane's effective resize weight is an explicit `0`.\n */\n private isResizePinnedMain(pane: Component): boolean {\n return this.effectiveResizeWeight(pane, WEIGHT_UNSET_PROBE) === 0;\n }\n\n /**\n * Seeds a first-layout pane (one with no stored size) from its preferred main\n * extent, clamped to `[min, max]` — the HBox/VBox model. Reads the preferred\n * *constraint* (explicit or class-default), so a content-only pane with no\n * constraint (e.g. a bare dock `Container`) is left unseeded and picks up the\n * equal-division fallback, keeping docks unchanged. Runs once per pane: a\n * pane that already has a stored size is skipped, so a later `setPreferredSize`\n * never re-seeds it.\n *\n * @param components - The container's current panes.\n * @param horizontal - True when the split's main axis is width.\n */\n private seedFromPreferred(components: Array<Component>, horizontal: boolean): void {\n for (const component of components) {\n if (this._sizes.has(component)) {\n continue;\n }\n\n const preferred = component.getPreferredSizeConstraint();\n if (!preferred) {\n continue;\n }\n\n const main = horizontal ? preferred.width : preferred.height;\n this._sizes.set(component, this.clampMain(component, main, horizontal));\n }\n }\n\n /**\n * Moves a pane's stored size (and collapsed state) onto another component,\n * for when a structural change swaps one child for another in the *same* pane\n * slot — a pane wrapped in a nested `Split`, or a single-pane `Split`'s lone\n * child hoisted into the slot the `Split` vacated. Without it the replacement\n * is treated as a brand-new pane and {@link recalculateSizes} re-equalizes the\n * slot, discarding a user-dragged ratio. No-op when `from` has no stored size.\n *\n * @param from - The pane leaving the slot.\n * @param to - The component taking the slot.\n * @returns This layout manager, for method chaining.\n */\n transferPaneSize(from: Component, to: Component): this {\n const size = this._sizes.get(from);\n\n if (size === undefined) {\n return this;\n }\n\n this._sizes.set(to, size);\n this._sizes.delete(from);\n\n const collapsed = this._collapsed.get(from);\n\n if (collapsed !== undefined) {\n this._collapsed.set(to, collapsed);\n this._collapsed.delete(from);\n }\n\n const weight = this._weights.get(from);\n\n if (weight !== undefined) {\n this._weights.set(to, weight);\n this._weights.delete(from);\n }\n\n return this;\n }\n\n /**\n * Returns the stored pane sizes normalised to sum 1.0, in container child\n * order. Captures the user's split ratios for serialization; ratios are\n * viewport-independent, so they survive a restore into a differently-sized\n * container (`Split` rescales px against the live extent on the next layout).\n *\n * @returns One ratio per pane in child order, summing to ~1.0; an equal\n * split when no sizes are stored yet, or `[]` when detached.\n */\n getPaneRatios(): number[] {\n const container = this.getContainer();\n if (!container) {\n return [];\n }\n\n const components = container.getComponents();\n if (components.length === 0) {\n return [];\n }\n\n const sizes = components.map(component => this._sizes.get(component) ?? 0);\n\n return normalizeRatios(sizes, components.length);\n }\n\n /**\n * The split's preferred size, derived from its panes the box-layout way: the\n * panes' preferred extents sum along the split axis (plus the gutter\n * footprint) and the widest/tallest is taken across it, then the container\n * perimeter is added. Panes that report no preferred size contribute\n * nothing, matching [`HBox`](/api/layout/classes/HBox) / [`VBox`](/api/layout/classes/VBox).\n *\n * This is a content hint for the *host* sizing the split's slot; it is\n * independent of the dragged per-pane sizes, which only distribute the\n * split's actual extent among the panes at layout time.\n *\n * @returns The preferred `{width, height}`, or `null` when detached.\n */\n getPreferredSize(): Size | null {\n return this.computeContentSize(component => component.getPreferredSize());\n }\n\n /**\n * The split's minimum size, computed from its panes' minimums exactly as\n * {@link getPreferredSize} computes the preferred size: summed along the\n * split axis (plus gutters), maxed across it, plus the container perimeter.\n *\n * @returns The minimum `{width, height}`, or `null` when detached.\n */\n getMinSize(): Size | null {\n return this.computeContentSize(component => component.getMinSize());\n }\n\n /**\n * The split's maximum size: deliberately unbounded on both axes. A\n * user-resizable split absorbs arbitrary slack — its panes are dragged, so\n * there is no meaningful ceiling. This is *not* derived from the panes'\n * `getMaxSize` by summing their extents: that summation lacks the\n * unbounded-saturation the box managers apply, so a pane\n * reporting an unbounded max would sum to a large *finite* number rather\n * than saturating — a subtly wrong report. Returning unbounded directly is\n * both correct and honest for a container whose purpose is to absorb space.\n *\n * @returns `{ width: UNBOUNDED, height: UNBOUNDED }`.\n */\n getMaxSize(): Size | null {\n return { width: UNBOUNDED, height: UNBOUNDED };\n }\n\n /**\n * Shared core of {@link getPreferredSize} / {@link getMinSize}: sums the\n * panes' sizes (selected by `sizeOf`) along the split axis together with the\n * gutter footprint, takes the largest across it, and adds the container\n * perimeter. Panes reporting no size are skipped, as in the other box\n * managers.\n *\n * @param sizeOf - Selects each pane's preferred or minimum size.\n * @returns The composed `{width, height}`, or `null` when detached.\n */\n private computeContentSize(sizeOf: (component: Component) => Size | null): Size | null {\n const container = this.getContainer();\n if (!container) {\n return null;\n }\n\n const components = container.getLaidOutComponents();\n const perimeter = container.getPerimeterSize();\n const horizontal = this._orientation === \"horizontal\";\n\n let main = 0;\n let cross = 0;\n\n for (let idx = 0; idx < components.length; idx += 1) {\n const size = sizeOf(components[idx]);\n if (!size) {\n continue;\n }\n\n main += horizontal ? size.width : size.height;\n cross = Math.max(cross, horizontal ? size.height : size.width);\n }\n\n main += this.gutterTotal(components.length);\n\n return horizontal\n ? { width: main + perimeter.left + perimeter.right,\n height: cross + perimeter.top + perimeter.bottom }\n : { width: cross + perimeter.left + perimeter.right,\n height: main + perimeter.top + perimeter.bottom };\n }\n\n /**\n * Writes pane ratios captured by {@link getPaneRatios} back onto the live\n * panes, by container child order. The input is treated as relative weights\n * (re-normalised internally), so a caller that dropped a pane on restore can\n * pass a short or non-unit array without skewing the result.\n *\n * @remarks Stored sizes are px, so the ratios are seeded against a positive\n * base extent: the live inner main-axis extent when the container is already\n * sized (no rescale needed next layout), else a unit base that\n * `recalculateSizes` scales up on the first connected layout. `_lastAvailableMain`\n * is reset to that same base so the next layout does not double-rescale the\n * freshly-written sizes.\n *\n * @param ratios - Relative pane weights in child order.\n * @returns This layout manager, for method chaining.\n */\n applyPaneRatios(ratios: number[]): this {\n const container = this.getContainer();\n if (!container) {\n return this;\n }\n\n const components = container.getComponents();\n const count = components.length;\n if (count === 0) {\n return this;\n }\n\n const norm = normalizeRatios(ratios, count);\n\n // Seed the stored px against a positive base. When the container is laid\n // out, use its real net-of-gutters main extent so the next layout needs\n // no rescale; otherwise use 1 and let `recalculateSizes` scale the\n // ratio-invariant sizes up on the first connected layout.\n const innerSize = container.getInnerSize();\n const main = innerSize ? (this._orientation === \"horizontal\" ? innerSize.width : innerSize.height) : 0;\n const available = Math.max(0, main - this.gutterTotal(count));\n const base = available > 0 ? available : 1;\n\n components.forEach((component, idx) => {\n this._sizes.set(component, norm[idx] * base);\n });\n\n this._lastAvailableMain = base;\n\n container.scheduleLayout();\n\n return this;\n }\n\n /**\n * Resolves each pane's persisted unit: `\"px\"` for a resize-pinned pane\n * (explicit `weight: 0`, per {@link isResizePinnedMain}), `\"ratio\"`\n * otherwise. The unit follows the weight, resolved by the same predicate\n * the container-resize refill uses — so a pane the layout holds at its\n * px is the pane persisted as px.\n *\n * @param components - The container's current panes, in child order.\n * @returns One unit per pane, in the same order.\n */\n private paneSizeUnits(components: Component[]): LayoutSizeUnit[] {\n return components.map(pane => (this.isResizePinnedMain(pane) ? \"px\" : \"ratio\"));\n }\n\n /**\n * Returns the panes' sizes in child order, one entry per pane, for\n * cross-session persistence: a resize-pinned pane (explicit `weight: 0`)\n * reports `px`, every other pane reports its `ratio` of the space the\n * px panes leave. This is the persistence surface — {@link getPaneRatios}\n * is the weight-agnostic arrangement surface `LayoutSerialization` uses;\n * do not use this one for same-session topology switching, or that one\n * for cross-session persistence.\n *\n * @returns One {@link LayoutSize} per pane in child order; the pending\n * `paneSizes` when one is still undrained; `[]` when detached or the\n * container has no panes.\n */\n getPaneSizes(): LayoutSize[] {\n const container = this.getContainer();\n\n if (!container) {\n return [];\n }\n\n const components = container.getComponents();\n\n if (components.length === 0) {\n return [];\n }\n\n const units = this.paneSizeUnits(components);\n\n // An undrained restore has not reached `_sizes` yet; reporting the live\n // state here would let a save overwrite the very state being restored.\n if (this._pendingSizes !== null && isRestorableSizes(this._pendingSizes, units)) {\n return this._pendingSizes.map(size => ({ ...size }));\n }\n\n return toLayoutSizes(units, components.map(pane => this._sizes.get(pane) ?? 0));\n }\n\n /**\n * Restores sizes captured by {@link getPaneSizes} onto the live panes, by\n * container child order. Discarded whole unless every entry's unit\n * matches the live pane's weight (see the discard rule on\n * {@link LayoutSize}) — a stale array leaves the panes exactly as though\n * no restore were requested.\n *\n * @param sizes - The persisted array to restore.\n * @returns This layout manager, for method chaining.\n */\n applyPaneSizes(sizes: LayoutSize[]): this {\n const container = this.getContainer();\n\n if (!container) {\n return this;\n }\n\n const components = container.getComponents();\n const units = this.paneSizeUnits(components);\n\n if (!isRestorableSizes(sizes, units)) {\n return this;\n }\n\n const innerSize = container.getInnerSize();\n const main = innerSize ? (this._orientation === \"horizontal\" ? innerSize.width : innerSize.height) : 0;\n const available = Math.max(0, main - this.gutterTotal(components.length));\n const stored = fromLayoutSizes(sizes, available);\n\n components.forEach((pane, idx) => this.setPaneSize(pane, stored[idx]));\n\n // Match `applyPaneRatios`: rebase so the next `recalculateSizes` treats the\n // freshly-written sizes as the baseline instead of double-rescaling them.\n this._lastAvailableMain = available > 0 ? available : 1;\n\n container.scheduleLayout();\n\n return this;\n }\n\n /**\n * Collapses or restores the pane at the given index **without animating** —\n * the geometry change lands on the next layout pass. Unlike\n * {@link setPaneCollapsed} (which runs a coordinated rAF animation), this is\n * for bulk restore, where N concurrent collapse animations would fight over\n * geometry. Sets the collapsed flag directly; `doLayout` substitutes the\n * strip thickness for a collapsed pane that has a serving gutter.\n *\n * @param index - Zero-based pane index.\n * @param collapsed - True to collapse, false to expand.\n * @returns This layout manager, for method chaining.\n */\n setPaneCollapsedImmediate(index: number, collapsed: boolean): this {\n const container = this.getContainer();\n if (!container) {\n return this;\n }\n\n const components = container.getLaidOutComponents();\n const pane = components[index];\n if (!pane) {\n return this;\n }\n\n // A pane with no serving gutter cannot collapse (geometry, or\n // `collapsible: false`). Restoring (collapsed === false) is always\n // allowed so a pane can be reopened even if its flag later changed.\n // This is the one collapse path that bypasses `gutterTargetPane`, so it\n // needs the guard explicitly; the chevron, the gutter \"collapse\" event,\n // and `setPaneCollapsed` all funnel through `gutterTargetPane` already.\n if (collapsed && this.paneServingGutter(index, components) < 0) {\n return this;\n }\n\n this._collapsed.set(pane, collapsed);\n this.emit(\"panecollapse\", index, collapsed);\n\n container.scheduleLayout();\n\n return this;\n }\n\n /**\n * Captures the drag origin when a gutter's drag begins: the absolute\n * pointer coordinate and the current sizes of the two adjacent panels.\n * Subsequent `drag` events derive the new sizes from these origins so\n * over-travel past a panel's minimum is absorbed without decoupling the\n * gutter from the cursor on reversal.\n *\n * @param container - The container component that owns the panels.\n * @param gutter - The gutter whose drag is starting.\n * @param position - The absolute pointer coordinate (`clientX`/`clientY`)\n * in the split axis at the moment the drag began.\n */\n onDragStart(container: Component, gutter: SplitGutter, position: number) {\n let gutterIdx = this._gutters.indexOf(gutter);\n let lhs = container.getLaidOutComponents()[gutterIdx];\n let rhs = container.getLaidOutComponents()[gutterIdx + 1];\n\n this._dragOriginPointer = position;\n\n if (this._orientation === \"horizontal\") {\n this._dragOriginLhsSize = lhs.getWidth();\n this._dragOriginRhsSize = rhs.getWidth();\n } else {\n this._dragOriginLhsSize = lhs.getHeight();\n this._dragOriginRhsSize = rhs.getHeight();\n }\n }\n\n /**\n * Adjusts the sizes of the two panels adjacent to a gutter when it is dragged.\n *\n * @param container - The container component that owns the panels.\n * @param gutter - The gutter being dragged.\n * @param position - The absolute pointer coordinate (`clientX`/`clientY`) in\n * the split axis for this move.\n *\n * @remarks The new panel sizes are computed from the drag origin captured in\n * {@link onDragStart} as `origin + (position − originPointer)`, then clamped\n * against each panel's minimum size while conserving the pair's combined\n * size. Clamping the absolute result (rather than accumulating per-move\n * deltas) means dragging past a panel's minimum is idempotent: the panel\n * stays at its floor until the pointer returns past the boundary\n * coordinate. The stored sizes for both affected panels are updated so the\n * next `doLayout` call preserves the user-defined split ratio.\n */\n onDrag(container: Component, gutter: SplitGutter, position: number) {\n let gutterIdx = this._gutters.indexOf(gutter);\n let lhs = container.getLaidOutComponents()[gutterIdx];\n let rhs = container.getLaidOutComponents()[gutterIdx + 1];\n\n const horizontal = this._orientation === \"horizontal\";\n const total = this._dragOriginLhsSize + this._dragOriginRhsSize;\n\n const lhsMin = lhs.getMinSize();\n const rhsMin = rhs.getMinSize();\n const lhsMax = lhs.getMaxSize();\n const rhsMax = rhs.getMaxSize();\n const minLhs = lhsMin ? (horizontal ? lhsMin.width : lhsMin.height) : 0;\n const minRhs = rhsMin ? (horizontal ? rhsMin.width : rhsMin.height) : 0;\n const maxLhs = lhsMax ? (horizontal ? lhsMax.width : lhsMax.height) : Number.POSITIVE_INFINITY;\n const maxRhs = rhsMax ? (horizontal ? rhsMax.width : rhsMax.height) : Number.POSITIVE_INFINITY;\n\n const offset = position - this._dragOriginPointer;\n\n // Clamp the new lhs size to its own [min, max] AND to the room the\n // partner's [min, max] leaves, keeping the pair's combined size (`total`)\n // constant. `min = max` on either pane pins the gutter.\n const loLhs = Math.max(minLhs, total - maxRhs);\n const hiLhs = Math.min(maxLhs, total - minRhs);\n\n let newLhs = this._dragOriginLhsSize + offset;\n newLhs = Math.max(loLhs, Math.min(hiLhs, newLhs));\n\n const newRhs = total - newLhs;\n const dragAmount = newLhs - (horizontal ? lhs.getWidth() : lhs.getHeight());\n\n if (horizontal) {\n lhs.setWidth(newLhs);\n gutter.setX(gutter.getX() + dragAmount);\n rhs.setX(rhs.getX() + dragAmount);\n rhs.setWidth(newRhs);\n } else {\n lhs.setHeight(newLhs);\n gutter.setY(gutter.getY() + dragAmount);\n rhs.setY(rhs.getY() + dragAmount);\n rhs.setHeight(newRhs);\n }\n\n this._sizes.set(lhs, newLhs);\n this._sizes.set(rhs, newRhs);\n\n lhs.doLayout();\n rhs.doLayout();\n }\n\n /**\n * Fires `paneresize` with the post-drag sizes once a gutter drag ends —\n * the commit-grained signal a consumer persists, as opposed to the\n * per-frame `drag` a gutter itself emits.\n */\n private onDragEnd(): void {\n this.emit(\"paneresize\", this.getPaneSizes());\n }\n\n /**\n * Detaches from the container and removes all gutter elements from the DOM.\n */\n detach() : this {\n super.detach();\n\n for (const gutter of this._gutters) {\n let gutterElement = gutter.getElement()!;\n DOM.sink.removeChild(DOM.source.getParentNode(gutterElement)!, gutterElement);\n gutter.destroy();\n }\n\n this._gutters = [];\n\n return this;\n }\n\n /**\n * Returns the combined pixel footprint of all gutters for a given pane\n * count: one gutter sits between each adjacent pane pair.\n *\n * @param componentCount - The number of panes in the container.\n *\n * @returns The total gutter thickness along the split axis.\n */\n private gutterTotal(componentCount: number): number {\n return Math.max(0, componentCount - 1) * GUTTER_SIZE;\n }\n\n /**\n * Computes the children's combined minSize along this manager's geometry:\n * along the split axis the per-pane `_sizes` are the user's floor (their\n * sum is the total); the cross-axis follows the max child minSize. Used\n * by `doLayout` to inflate the working size when the host has opted into\n * `setOverflowing`.\n *\n * @returns The total min-size; `{ width: 0, height: 0 }` when the\n * container is absent.\n */\n protected computeTotalMinSize(): Size {\n const container = this.getContainer();\n if (!container) {\n return { width: 0, height: 0 };\n }\n\n const components = container.getLaidOutComponents();\n if (components.length === 0) {\n return { width: 0, height: 0 };\n }\n\n const gutterCount = components.length - 1;\n\n let splitTotal = 0;\n let crossMax = 0;\n\n for (let idx = 0; idx < components.length; idx += 1) {\n const component = components[idx];\n const stored = this._sizes.get(component);\n const collapsed = this._collapsed.get(component) ?? false;\n const hasGutter = idx < gutterCount;\n\n if (collapsed && hasGutter) {\n // The gutter→strip covers this pane's whole slot: a single\n // strip thickness, no separate divider.\n splitTotal += COLLAPSE_STRIP_SIZE;\n } else {\n if (!collapsed) {\n if (stored != null) {\n splitTotal += stored;\n } else {\n const min = component.getMinSize();\n if (min) {\n splitTotal += this._orientation === \"horizontal\" ? min.width : min.height;\n }\n }\n }\n\n if (hasGutter) {\n splitTotal += GUTTER_SIZE;\n }\n }\n\n const min = component.getMinSize();\n if (min) {\n crossMax = Math.max(crossMax, this._orientation === \"horizontal\" ? min.height : min.width);\n }\n }\n\n return this._orientation === \"horizontal\"\n ? { width: splitTotal, height: crossMax }\n : { width: crossMax, height: splitTotal };\n }\n\n /**\n * Creates missing gutters, computes panel sizes, and positions all panels and gutters.\n *\n * @remarks New [`SplitGutter`](/api/component/container/classes/SplitGutter) instances are appended to the container's DOM element on first layout.\n * Existing gutters are reused on subsequent layouts.\n */\n doLayout() {\n let me = this;\n let container = this.getContainer();\n if (!container) {\n return;\n }\n\n let containerSize = container.getInnerSize();\n if (!containerSize) {\n return;\n }\n\n // The un-inflated inner main extent the displayed panes share — captured\n // before the overflow inflation below so `computeMainAxisSizes` fills the\n // true viewport (matching the pre-displayed Σ-stored basis).\n const innerMain = this._orientation === \"horizontal\" ? containerSize.width : containerSize.height;\n\n // Universal scroll: see HBox.doLayout for the rationale. When the\n // host has marked the corresponding axis as overflowing, grow the\n // working size past the host's inner rect so trailing panes land\n // past `innerSize` and the host's CSS `overflow: auto` produces a\n // scrollbar.\n containerSize = this.inflateForOverflow(containerSize);\n\n let element = container.getElement()!;\n // The visible layout is driven by the displayed panes: a non-displayed\n // pane (and its gutter) drops out entirely, neighbours reflowing to fill.\n // `recalculateSizes`/`_sizes` bookkeeping below still spans the full child\n // list, so a hidden pane keeps its stored size for a later restore.\n let components = container.getLaidOutComponents();\n let containerInsets = container.getContentInsets();\n\n let componentCount = components.length;\n let gutterCount = componentCount - 1;\n\n for (let i = this._gutters.length; i < gutterCount; i += 1) {\n // Transparent divider track (like Border): only the chevron grip\n // shows in the expanded state; the gutter paints itself only once\n // collapsed into its button-styled strip.\n let gutter = new SplitGutter(this._orientation, { expandedBackground: \"transparent\" });\n let gutterIndex = i;\n\n gutter.on(\"dragstart\", function (position: number) {\n me.onDragStart(<Component>container, gutter, position);\n });\n gutter.on(\"drag\", function (position: number) {\n me.onDrag(<Component>container, gutter, position);\n });\n gutter.on(\"dragend\", () => this.onDragEnd());\n gutter.on(\"collapse\", function () {\n // The chevron toggles whichever neighbour this gutter serves —\n // its leading pane by default, or a trailing pane that opted to\n // collapse toward the end.\n const target = me.gutterTargetPane(gutterIndex, (<Component>container).getLaidOutComponents());\n if (target >= 0) {\n me.setPaneCollapsed(target, !me.isPaneCollapsed(target));\n }\n });\n\n this._gutters.push(gutter);\n\n DOM.sink.appendChild(element, gutter.getElement(true)!);\n }\n\n let x = containerInsets.getLeft();\n let y = containerInsets.getTop();\n\n this.recalculateSizes();\n this.applyPendingSizes();\n this.applyPendingCollapsed(components);\n\n const horizontal = this._orientation === \"horizontal\";\n const crossSize = horizontal ? containerSize.height : containerSize.width;\n const mainSizes = this.computeMainAxisSizes(components, innerMain);\n\n // Gutters placed this pass (as a strip or a divider); the rest are\n // hidden afterward — e.g. the trailing gutter of a pane collapsed\n // toward the end, whose strip is the leading gutter instead.\n const placed = new Set<number>();\n\n for (let idx = 0; idx < components.length; idx += 1) {\n const component = components[idx];\n const servingIdx = this.paneServingGutter(idx, components);\n const collapsed = (this._collapsed.get(component) ?? false) && servingIdx >= 0;\n\n if (collapsed) {\n // The serving gutter becomes the opaque strip in this pane's\n // slot; the pane hides behind it. The strip lands in the same\n // slot whichever side the pane collapses toward — only the\n // chevron heading and which gutter animates differ.\n const gutter = this._gutters[servingIdx];\n\n gutter.setCollapseDirection(this.paneDirection(component));\n gutter.setCollapsible(true);\n this.placeGutterAsStrip(gutter, component, x, y, crossSize, horizontal, this.paneDirection(component));\n placed.add(servingIdx);\n\n if (horizontal) {\n x += COLLAPSE_STRIP_SIZE;\n } else {\n y += COLLAPSE_STRIP_SIZE;\n }\n\n continue;\n }\n\n const mainSize = mainSizes.get(component) as number;\n\n component.setVisible(true);\n\n this.placeComponent(\n component,\n x,\n y,\n horizontal ? mainSize : crossSize,\n horizontal ? crossSize : mainSize,\n FillType.BOTH\n );\n\n // A collapsible pane keeps `inset(0)` as the expanded keyframe so a\n // restore animates its clip back open; a pane that can't collapse\n // carries no clip-path at all.\n component.setClipPath(servingIdx >= 0 ? \"inset(0 0 0 0)\" : null);\n\n if (horizontal) {\n x += mainSize;\n } else {\n y += mainSize;\n }\n\n if (idx < gutterCount) {\n const gutter = this._gutters[idx];\n const target = this.gutterTargetPane(idx, components);\n\n // When this gutter is the strip for a collapsed trailing pane,\n // the strip is placed in that pane's own slot — skip the divider\n // here and let the gutter hide between the strip and this pane.\n const targetIsCollapsedStrip = target >= 0\n && (this._collapsed.get(components[target]) ?? false)\n && this.paneServingGutter(target, components) === idx;\n\n if (!targetIsCollapsedStrip && !placed.has(idx)) {\n // Expanded divider: a thin draggable gutter whose chevron (if\n // any) collapses the neighbour it serves.\n gutter.setOpaque(false);\n gutter.setVisible(true);\n gutter.setCollapsible(target >= 0);\n if (target >= 0) {\n gutter.setCollapseDirection(this.paneDirection(components[target]));\n }\n gutter.setX(x);\n gutter.setY(y);\n\n if (horizontal) {\n gutter.setWidth(GUTTER_SIZE);\n gutter.setHeight(crossSize);\n\n x += GUTTER_SIZE;\n } else {\n gutter.setWidth(crossSize);\n gutter.setHeight(GUTTER_SIZE);\n\n y += GUTTER_SIZE;\n }\n\n placed.add(idx);\n }\n }\n }\n\n for (let i = 0; i < this._gutters.length; i += 1) {\n if (!placed.has(i)) {\n this._gutters[i].setVisible(false);\n }\n }\n }\n\n /**\n * Places a pane's gutter as the opaque collapse strip occupying the pane's\n * slot, and hides the pane behind it. The gutter is the only visible\n * affordance for a collapsed pane; it animates into this geometry from its\n * expanded divider position.\n *\n * @param gutter - The pane's gutter, repurposed as the strip.\n * @param pane - The collapsed pane, clipped away behind the strip.\n * @param x - The slot's left position.\n * @param y - The slot's top position.\n * @param crossSize - The container's cross-axis extent.\n * @param horizontal - Whether the split runs horizontally.\n * @param direction - The pane's collapse heading, fixing the clip edge.\n */\n private placeGutterAsStrip(gutter: SplitGutter, pane: Component, x: number, y: number, crossSize: number, horizontal: boolean, direction: CollapseDirection): void {\n gutter.setOpaque(true);\n gutter.setVisible(true);\n gutter.setX(x);\n gutter.setY(y);\n\n if (horizontal) {\n gutter.setWidth(COLLAPSE_STRIP_SIZE);\n gutter.setHeight(crossSize);\n } else {\n gutter.setWidth(crossSize);\n gutter.setHeight(COLLAPSE_STRIP_SIZE);\n }\n\n // The pane stays visible at its full stored size and clips toward its\n // outer (collapse-direction) edge, retreating into the strip rather than\n // vanishing. It can't shrink past its min-size, so the clip — not a width\n // change — is what hides it. It is anchored at the strip on the side it\n // collapses toward so the retreating edge tucks into the strip.\n const fullMain = this._sizes.get(pane) ?? COLLAPSE_STRIP_SIZE;\n const towardStart = this.collapsesTowardStart(direction);\n\n pane.setVisible(true);\n\n if (horizontal) {\n const paneX = towardStart ? x : x + COLLAPSE_STRIP_SIZE - fullMain;\n this.placeComponent(pane, paneX, y, fullMain, crossSize, FillType.BOTH);\n } else {\n const paneY = towardStart ? y : y + COLLAPSE_STRIP_SIZE - fullMain;\n this.placeComponent(pane, x, paneY, crossSize, fullMain, FillType.BOTH);\n }\n\n pane.setClipPath(this.paneClipInset(direction));\n }\n\n /**\n * Returns the `clip-path` inset that clips a pane toward its outer edge for\n * the given collapse heading, used to animate a collapse into (or expand out\n * of) the strip.\n *\n * @param direction - The collapse heading.\n * @returns A CSS `clip-path` inset string.\n */\n private paneClipInset(direction: CollapseDirection): string {\n switch (direction) {\n case \"east\": return \"inset(0 0 0 100%)\";\n case \"north\": return \"inset(0 0 100% 0)\";\n case \"south\": return \"inset(100% 0 0 0)\";\n default: return \"inset(0 100% 0 0)\";\n }\n }\n\n /**\n * Drains the `paneSizes` option (or a pre-layout {@link applyPaneSizes}\n * call) into `_sizes` on the first layout, where {@link applyPaneSizes}\n * can resolve the live panes and the container's main-axis budget. Runs\n * once: `applyPaneSizes` re-validates against the live units and\n * discards a stale array whole, so the drain needs no check of its own.\n */\n private applyPendingSizes(): void {\n const pending = this._pendingSizes;\n\n if (pending === null) {\n return;\n }\n\n this._pendingSizes = null;\n\n this.applyPaneSizes(pending);\n }\n\n /**\n * Drains the `collapsedPanes` option into `_collapsed` on the first layout\n * where the panes are resolvable. Runs once: pane components can't be looked\n * up from indices until the container has its children.\n *\n * @param components - The container's current child panes.\n */\n private applyPendingCollapsed(components: Array<Component>): void {\n if (this._pendingCollapsed.length === 0) {\n return;\n }\n\n for (const index of this._pendingCollapsed) {\n const pane = components[index];\n\n // Only a pane with a serving gutter can collapse.\n if (pane && this.paneServingGutter(index, components) >= 0) {\n this._collapsed.set(pane, true);\n }\n }\n\n this._pendingCollapsed = [];\n }\n\n /**\n * Computes each expanded pane's main-axis extent. A collapsed pane reports\n * `0` — it is hidden and its gutter, rendered as the opaque strip, occupies\n * the `COLLAPSE_STRIP_SIZE` slot in its place. The space the collapsed panes\n * (and the gutter→strip thickness change) free flows back to the expanded\n * panes in proportion to their stored sizes, so the layout always fills the\n * container and the expanded panes keep their relative ratio.\n *\n * @param components - The container's laid-out (displayed) child panes;\n * non-displayed panes are absent and so neither sized nor gutter-spaced.\n * @param mainInner - The container's inner main-axis extent in px.\n * @returns A map from pane to its displayed main-axis size (`0` when collapsed).\n */\n private computeMainAxisSizes(components: Array<Component>, mainInner: number): Map<Component, number> {\n const gutterCount = components.length - 1;\n\n let expandedStored = 0;\n let strips = 0; // collapsed panes (each turns a gutter into a strip)\n let hiddenDividers = 0; // gutters hidden by a toward-end collapse\n\n for (let idx = 0; idx < components.length; idx += 1) {\n const component = components[idx];\n\n const collapsed = (this._collapsed.get(component) ?? false) && this.paneServingGutter(idx, components) >= 0;\n\n if (collapsed) {\n strips += 1;\n\n // A pane collapsing toward the end uses its *leading* gutter as\n // the strip, leaving its trailing gutter (when it has one)\n // hidden — that 4px divider is reclaimed by the expanded panes.\n if (!this.collapsesTowardStart(this.paneDirection(component)) && idx < gutterCount) {\n hiddenDividers += 1;\n }\n } else {\n expandedStored += this._sizes.get(component) ?? 0;\n }\n }\n\n // The expanded panes share the inner main extent net of the GUTTER_SIZE\n // dividers between displayed panes. Derived from `mainInner` rather than\n // Σ stored, because a hidden pane keeps its stored size (frozen for a\n // later restore) yet is absent from `components` — so its slot and gutter\n // are genuinely reclaimed here, and the expanded panes inflate to fill\n // via `factor` without `_sizes` being rewritten (preserving the ratio a\n // re-shown pane returns to). Each collapsed pane's gutter becomes a\n // `COLLAPSE_STRIP_SIZE` strip in place of its `GUTTER_SIZE` divider, the\n // pane yields its whole slot, and any toward-end-hidden divider is\n // reclaimed — so panes + strips + visible dividers still sum to the inner\n // extent.\n const available = Math.max(0, mainInner - this.gutterTotal(components.length));\n const expandedTotal = Math.max(0, available - strips * (COLLAPSE_STRIP_SIZE - GUTTER_SIZE) + hiddenDividers * GUTTER_SIZE);\n const factor = expandedStored > 0 ? expandedTotal / expandedStored : 0;\n\n const sizes = new Map<Component, number>();\n\n for (let idx = 0; idx < components.length; idx += 1) {\n const component = components[idx];\n const collapsed = (this._collapsed.get(component) ?? false) && this.paneServingGutter(idx, components) >= 0;\n\n sizes.set(component, collapsed ? 0 : (this._sizes.get(component) ?? 0) * factor);\n }\n\n return sizes;\n }\n\n /**\n * Assigns initial sizes to any components that do not yet have a stored size.\n *\n * @remarks When some panels already have stored sizes and a new panel is added,\n * its size is taken proportionally from the existing panels so the total remains constant.\n * When no panels have stored sizes the available container dimension is divided equally.\n */\n recalculateSizes() {\n let container = this.getContainer();\n if (!container) {\n return;\n }\n\n let containerSize = container.getInnerSize();\n if (!containerSize) {\n return;\n }\n\n let components = container.getComponents();\n\n // Drop stored sizes (and collapsed flags) for panes that have left the\n // container. `moveComponent`/`removeComponent` give Split no removal\n // hook, so without this the entries would linger forever — skewing the\n // `_sizes.size` check and the refill total below, and leaking memory.\n for (let pane of [...this._sizes.keys()]) {\n if (components.indexOf(pane) < 0) {\n this._sizes.delete(pane);\n this._collapsed.delete(pane);\n }\n }\n\n // Prune `_weights` in a dedicated pass over its own keys. It cannot ride\n // the `_sizes` loop above: `setPaneResizeWeight` registers a weight\n // independently of `_sizes`, so a pane carrying a weight but no stored\n // size is never visited there and its entry would leak on removal.\n // (`_collapsed` is safe in that loop only because it is never set for a\n // sizeless pane.)\n for (let pane of [...this._weights.keys()]) {\n if (components.indexOf(pane) < 0) {\n this._weights.delete(pane);\n }\n }\n\n // `getInnerSize` already removed the perimeter (insets + border +\n // padding); the only thing the panes don't get is the gutters, so the\n // space to divide is the inner main axis minus the gutter footprint.\n // `doLayout` places panes from `getContentInsets` and advances by this\n // same gutter total, so a pane sum of `available` lands flush with the\n // inner edge — no `gutterCount × GUTTER_SIZE` overflow.\n let main = this._orientation === \"horizontal\" ? containerSize.width : containerSize.height;\n let available = Math.max(0, main - this.gutterTotal(components.length));\n\n const horizontal = this._orientation === \"horizontal\";\n\n // Seed first-layout panes from their preferred constraint (HBox model),\n // then re-clamp every stored size to its current [min, max] so a live\n // min/max change (which does not change `available`, so the resize block\n // below is skipped) still snaps the pane into range.\n this.seedFromPreferred(components, horizontal);\n\n for (const component of components) {\n const stored = this._sizes.get(component);\n if (stored !== undefined) {\n this._sizes.set(component, this.clampMain(component, stored, horizontal));\n }\n }\n\n // Distribute the extent change across the panes by resize weight so they\n // keep filling the container. Each pane's effective weight is its\n // explicit `setPaneResizeWeight` entry, else its `weight` layout\n // constraint, else its current stored size — so an all-unset Split splits\n // the delta proportionally to size, which is algebraically identical to\n // the old uniform-factor rescale (`old·(Σ+Δ)/Σ`) and preserves any split\n // the user dragged. A weight-0 pane keeps its px size (the delta bypasses\n // it). Skipped on the first connected layout (`_lastAvailableMain` is\n // still 0) and when nothing changed. `weightSum === 0` (every pane\n // pinned) leaves the sizes untouched and lets the `Σ == available` refill\n // below fill uniformly — the only sane outcome when the delta has nowhere\n // to go.\n if (this._lastAvailableMain > 0 && available > 0 && available !== this._lastAvailableMain && this._sizes.size > 0) {\n let delta = available - this._lastAvailableMain;\n\n let weightSum = 0;\n for (let idx = 0; idx < components.length; idx += 1) {\n let component = components[idx];\n weightSum += this.effectiveResizeWeight(component, this._sizes.get(component) ?? 0);\n }\n\n if (weightSum > 0) {\n for (let idx = 0; idx < components.length; idx += 1) {\n let component = components[idx];\n let stored = this._sizes.get(component);\n\n if (stored != undefined) {\n let weight = this.effectiveResizeWeight(component, stored);\n this._sizes.set(component, Math.max(0, stored + delta * (weight / weightSum)));\n }\n }\n }\n }\n\n // First-layout slack: after seeding, hand the leftover `available − Σseed`\n // to the positively-weighted panes as `seed + (w/Σw)·slack` (base kept,\n // slack shared by weight — HBox-inspired). Runs only on the first connected\n // layout (`_lastAvailableMain === 0`); the resize block above owns every\n // later layout, so the two never co-fire. The `0` fallback means only\n // panes with an actual positive weight absorb slack here (an unset-weight\n // pane is not treated as weight-bearing at seed time — unlike the resize\n // block, which falls back to stored size for proportional rescale). A\n // weighted pane with no seed (a null-preferred absorber like a dock) is\n // given a size here, so it no longer steals from a seeded sibling in the\n // fallback below. When no pane has a positive weight this is skipped and\n // the pin-aware refill reconciles the sum.\n if (this._lastAvailableMain === 0 && available > 0 && this._sizes.size > 0) {\n let weightSum = 0;\n for (let idx = 0; idx < components.length; idx += 1) {\n let weight = this.effectiveResizeWeight(components[idx], 0);\n if (weight > 0) {\n weightSum += weight;\n }\n }\n\n if (weightSum > 0) {\n let seedTotal = 0;\n for (let idx = 0; idx < components.length; idx += 1) {\n seedTotal += this._sizes.get(components[idx]) ?? 0;\n }\n\n let slack = available - seedTotal;\n\n for (let idx = 0; idx < components.length; idx += 1) {\n let component = components[idx];\n let weight = this.effectiveResizeWeight(component, 0);\n\n if (weight > 0) {\n let seed = this._sizes.get(component) ?? 0;\n this._sizes.set(component, this.clampMain(component, seed + slack * (weight / weightSum), horizontal));\n }\n }\n }\n }\n\n let componentsWithSize = 0;\n\n for (let idx = 0; idx < components.length; idx += 1) {\n let component = components[idx];\n\n if (this._sizes.has(component)) {\n componentsWithSize += 1;\n }\n }\n\n for (let idx = 0; idx < components.length; idx += 1) {\n let component = components[idx];\n let componentSize = this._sizes.get(component);\n\n if (componentSize == undefined) {\n if (this._sizes.size != 0) {\n componentSize = 0;\n\n for (let jdx = 0; jdx < components.length; jdx += 1) {\n let c = components[jdx];\n let cSize = this._sizes.get(c);\n\n if(cSize == undefined) {\n continue;\n }\n\n let sizeFraction = cSize * (1 / (componentsWithSize + 1));\n componentSize += sizeFraction;\n cSize -= sizeFraction;\n\n this._sizes.set(c, cSize);\n }\n } else {\n componentSize = available;\n }\n\n this._sizes.set(component, componentSize);\n componentsWithSize += 1;\n }\n }\n\n // After the steps above every live pane has a stored size, but their\n // sum can fall short of `available` when a pane was *removed* since the\n // last layout (its slot freed but no survivor reclaimed it — e.g. a tab\n // torn off, or a pane moved out while being wrapped in a nested Split), or\n // when a live min/max change re-clamped a pane (the resize block is skipped\n // then, because `available` is unchanged). `computeMainAxisSizes`/`doLayout`\n // place panes at their raw stored sizes, so a short sum strands a trailing\n // gap. Normalise back to the `Σ == available` invariant — but hold the\n // pinned panes and rescale only what can absorb. Panes fall in three\n // tiers: single-point (min == max) pins never move; weight-0 pins hold\n // their px while the container has room for them, and yield\n // proportionally when it does not; everything else flexes. With no\n // pinned pane of either kind this is the original uniform refill,\n // byte-for-byte.\n let pinnedTotal = 0;\n let weightPinnedTotal = 0;\n let flexibleTotal = 0;\n\n for (let idx = 0; idx < components.length; idx += 1) {\n let component = components[idx];\n let stored = this._sizes.get(component) ?? 0;\n\n // A pane that is both single-point and weight-0 counts as single-point:\n // the stronger pin wins, so the cascade below never yields its one extent.\n if (this.isPinnedMain(component, horizontal)) {\n pinnedTotal += stored;\n } else if (this.isResizePinnedMain(component)) {\n weightPinnedTotal += stored;\n } else {\n flexibleTotal += stored;\n }\n }\n\n if (available > 0) {\n // Room left after the single-point pins, which never yield.\n let budget = Math.max(0, available - pinnedTotal);\n\n // Per-tier refill scale; `1` holds the tier at its stored size.\n let pinnedScale = 1;\n let weightPinnedScale = 1;\n let flexibleScale = 1;\n\n if (flexibleTotal > 0 && budget >= weightPinnedTotal) {\n // The budget covers the weight-0 pins: hold every pin and let the\n // flexible panes take the remainder. With no weight-0 pane this is the\n // original `max(0, available − Σpinned) / flexibleTotal`, byte-for-byte.\n flexibleScale = (budget - weightPinnedTotal) / flexibleTotal;\n } else if (weightPinnedTotal > 0) {\n // Either nothing flexible is left, or the weight-0 pins alone overrun\n // the budget. The flexible panes squeeze to 0 and the weight-0 pins\n // yield proportionally — a weight-0 pin holds only while the container\n // is large enough (`setPaneResizeWeight`). When there are no\n // single-point pins and nothing flexible, this is the uniform rescale\n // the all-weights-0 config has always produced.\n flexibleScale = 0;\n weightPinnedScale = budget / weightPinnedTotal;\n } else if (pinnedTotal > 0) {\n // Every pane is single-point pinned: uniform fill — the only sane\n // outcome when nothing can flex.\n pinnedScale = available / pinnedTotal;\n }\n\n for (let idx = 0; idx < components.length; idx += 1) {\n let component = components[idx];\n let stored = this._sizes.get(component);\n\n if (stored == undefined) {\n continue;\n }\n\n let scale = this.isPinnedMain(component, horizontal)\n ? pinnedScale\n : (this.isResizePinnedMain(component) ? weightPinnedScale : flexibleScale);\n\n if (scale !== 1) {\n this._sizes.set(component, stored * scale);\n }\n }\n }\n\n // Only remember a positive extent. If the container collapsed below the\n // gutter footprint (`available == 0`) the stored sizes were left frozen,\n // so keeping the last positive baseline lets the next growth rescale\n // them back to fill instead of stranding the pre-collapse sizes.\n if (available > 0) {\n this._lastAvailableMain = available;\n }\n }\n}\n\nconst SplitCallable = callable(Split);\ntype SplitCallable = Split;\nexport {\n Split as _Split,\n SplitCallable as Split\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component } from \"~/core/Component.js\";\nimport type { Edge } from \"~/primitive/Edge.js\";\nimport { Position } from \"~/primitive/Position.js\";\nimport { callable } from \"~/core/Callable.js\";\nimport { LayerManager } from \"~/core/LayerManager.js\";\nimport { DOM } from \"~/core/DOM.js\";\n\n/**\n * One of the five drop zones a dock gesture resolves the cursor into: the four\n * edge bands plus the central remainder.\n *\n * @category Layouts\n */\nexport type DropZone = Edge | \"center\";\n\n/**\n * Fraction of a region's main/cross extent that counts as an edge band — a\n * quarter, the canonical VS Code / GoldenLayout dock affordance ratio. A\n * fractional band (rather than a fixed pixel inset) keeps small regions usable:\n * a thin region would otherwise be all-edge. Exported because two collaborators\n * must agree on it — `DockRegion`'s hit-test (`computeZone`) and this overlay's\n * band geometry must resolve the same rectangle for a given zone, so the\n * highlight covers exactly the region the drop will occupy. It lives here, in\n * the `core` overlay that paints the band, because `DockRegion` is in `layout`\n * and `core` may not import from `layout`.\n */\nexport const EDGE_BAND_FRACTION = 0.25;\n\n/**\n * The single positioned rectangle a {@link DropZoneOverlay} lights up over the\n * band the cursor resolves to. A nested overlay class (the\n * {@link DropZoneOverlay} analogue of `Tab`'s selection indicator) so its\n * geometry setters — protected on {@link Component} — are driven from within,\n * through {@link placeBand}, rather than reached into from the parent.\n */\nclass DropZoneHighlight extends Component {\n\n // Cached validity so the colour swap in {@link setValid} is a no-op on a\n // repeat call with the same state — the band is re-placed every drag frame.\n private _valid: boolean = true;\n\n /** Builds the highlight rect, hidden until {@link placeBand} positions it. */\n constructor() {\n super();\n\n this.setPosition(Position.ABSOLUTE);\n this.setPointerEvents(\"none\");\n this.setBackgroundColor(\"var(--ts-ui-drag-dropzone-active-bg)\");\n this.setVisible(false);\n }\n\n /**\n * Positions the rect over a band and shows it.\n *\n * @param x - Left offset within the overlay, in px.\n * @param y - Top offset within the overlay, in px.\n * @param width - Band width, in px.\n * @param height - Band height, in px.\n */\n placeBand(x: number, y: number, width: number, height: number): void {\n this.setX(x);\n this.setY(y);\n this.setWidth(width);\n this.setHeight(height);\n this.setVisible(true);\n }\n\n /**\n * Swaps the band colour between the active (valid) and invalid drop tokens —\n * the band itself carries the drop's validity now that the whole-target tint\n * is suppressed for dock regions. Idempotent on repeat calls.\n *\n * @param valid - `true` for the active blue band, `false` for the red one.\n */\n setValid(valid: boolean): void {\n if (this._valid === valid) {\n return;\n }\n\n this._valid = valid;\n\n this.setBackgroundColor(valid\n ? \"var(--ts-ui-drag-dropzone-active-bg)\"\n : \"var(--ts-ui-drag-dropzone-invalid-bg)\");\n }\n\n /** Hides the rect (no zone highlighted). */\n hide(): void {\n this.setVisible(false);\n }\n}\n\n/**\n * Z-order shared with [`DragFeedback`](/api/overlay/classes/DragFeedback) and\n * [`ReorderIndicator`](/api/overlay/classes/ReorderIndicator): just **below** the\n * lowest {@link LayerManager} band (the {@link Window} band) so this drop-zone\n * affordance — drawn over app content that establishes no isolating stacking\n * context — never paints over a floating window, while still sitting above the\n * target's own content. The drag ghost sits above all three at the root.\n */\nconst Z_INDEX = LayerManager.Band.Window - 1;\n\n/**\n * Overlay that marks a region as a dock target during an active drag and\n * highlights the band the cursor currently resolves to. The root is a faint\n * full-bleed tint (the \"this region accepts a dock\" affordance); a single\n * nested rectangle — moved per zone rather than five persistent children —\n * lights up the edge band (or the central remainder) the drop would occupy.\n *\n * Owned by [`DockRegion`](/api/layout/classes/DockRegion) — application code\n * does not instantiate this directly. It composes with the manager's own\n * [`DragFeedback`](/api/overlay/classes/DragFeedback): the tint reports drop\n * *validity*, this overlay reports drop *position*.\n *\n * @category Core\n */\nclass DropZoneOverlay extends Component {\n\n // Single positioned rectangle, re-placed per zone (Internal Structure: one\n // nested child, not five persistent band elements). Created as a field so it\n // exists by the time the constructor body configures it.\n private _highlight: DropZoneHighlight = new DropZoneHighlight();\n\n // Cached current zone and validity so a per-mousemove `setHighlight` with an\n // unchanged zone *and* validity is a no-op — `onDragOver` fires every frame,\n // and re-placing or re-colouring the rect each frame would be needless DOM\n // churn.\n private _zone: DropZone | null = null;\n private _valid: boolean = true;\n\n /**\n * Constructs a dock-zone overlay. The overlay is not attached until\n * {@link attachTo} is called.\n */\n constructor() {\n super();\n\n this.setPosition(Position.ABSOLUTE);\n this.setZIndex(Z_INDEX);\n this.setPointerEvents(\"none\");\n this.setBackgroundColor(\"var(--ts-ui-drag-dropzone-bg)\");\n this.setBorder({ border: \"1px solid var(--ts-ui-drag-dropzone-border)\" });\n }\n\n /**\n * Sizes this overlay to cover `region` and appends it (and its highlight\n * rect) into the region's element. Idempotent — safe to call on every\n * `onDragOver` while the cursor stays inside the region.\n *\n * @param region - The dock target whose body the overlay should cover.\n */\n attachTo(region: Component): void {\n const myEl = this.getElement(true)!;\n\n this.setX(0);\n this.setY(0);\n this.setWidth(region.getWidth());\n this.setHeight(region.getHeight());\n\n const regionEl = region.getElement(true)!;\n if (DOM.source.getParentElement(myEl) !== regionEl) {\n DOM.sink.appendChild(regionEl, myEl);\n }\n\n const highlightEl = this._highlight.getElement(true)!;\n if (DOM.source.getParentElement(highlightEl) !== myEl) {\n DOM.sink.appendChild(myEl, highlightEl);\n }\n }\n\n /**\n * Highlights the band corresponding to `zone`, or clears the highlight when\n * `null`. The lit rectangle is the edge band (an `EDGE_BAND_FRACTION`\n * slice against the relevant axis) for an edge zone, or the central\n * remainder for `\"center\"` — matching the rectangle the drop would occupy.\n * The band is drawn in the active (blue) colour when `valid`, or the invalid\n * (red) colour when not — so an illegal drop is marked on the exact zone it\n * would occupy rather than tinting the whole target. A repeat call with the\n * current zone *and* validity is a no-op.\n *\n * @param zone - The zone to highlight, or `null` to hide the highlight.\n * @param valid - Whether the drop on this zone is legal (defaults to `true`).\n */\n setHighlight(zone: DropZone | null, valid: boolean = true): void {\n if (zone === this._zone && valid === this._valid) {\n return;\n }\n\n this._zone = zone;\n this._valid = valid;\n\n if (zone === null) {\n this._highlight.hide();\n\n return;\n }\n\n this._highlight.setValid(valid);\n\n const w = this.getWidth();\n const h = this.getHeight();\n const f = EDGE_BAND_FRACTION;\n\n let x = 0, y = 0, bw = w, bh = h;\n\n switch (zone) {\n case \"top\": x = 0; y = 0; bw = w; bh = h * f; break;\n case \"bottom\": x = 0; y = h * (1 - f); bw = w; bh = h * f; break;\n case \"left\": x = 0; y = 0; bw = w * f; bh = h; break;\n case \"right\": x = w * (1 - f); y = 0; bw = w * f; bh = h; break;\n case \"center\": x = w * f; y = h * f; bw = w * (1 - 2 * f); bh = h * (1 - 2 * f); break;\n }\n\n this._highlight.placeBand(x, y, bw, bh);\n }\n\n /**\n * Lights up the **entire** region as a single drop zone, leaving no edge\n * bands. For a target with only one possible outcome — an empty dock, where\n * any drop simply becomes the sole region — so the feedback reads as one\n * solid blue area rather than {@link setHighlight}`(\"center\")`'s inset square\n * that implies splittable edges. Cheap to call per `onDragOver`: the underlying\n * geometry setters short-circuit once placed.\n */\n highlightFull(): void {\n this._zone = null;\n this._valid = true;\n\n this._highlight.setValid(true);\n this._highlight.placeBand(0, 0, this.getWidth(), this.getHeight());\n }\n\n /**\n * Removes the overlay element from the DOM and resets the cached zone so a\n * later re-attach starts with no highlight.\n */\n detach(): void {\n this._zone = null;\n this._valid = true;\n this.removeElement();\n }\n}\n\nconst DropZoneOverlayCallable = callable(DropZoneOverlay);\ntype DropZoneOverlayCallable = DropZoneOverlay;\nexport {\n DropZoneOverlay as _DropZoneOverlay,\n DropZoneOverlayCallable as DropZoneOverlay,\n};\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component } from \"~/core/Component.js\";\nimport { Container } from \"~/core/Container.js\";\nimport { DOM } from \"~/core/DOM.js\";\nimport { AbstractWindow } from \"~/overlay/AbstractWindow.js\";\nimport { Split } from \"~/layout/Split.js\";\nimport { Tab } from \"~/layout/Tab.js\";\nimport { DragManager, DragEventDetail, tabDragRegistry, SPRING_RAISE_DELAY_MS } from \"~/overlay/DragManager.js\";\nimport { DropZone, DropZoneOverlay, EDGE_BAND_FRACTION } from \"~/overlay/DropZoneOverlay.js\";\n\n/**\n * Coordinator that turns an edge/center drop onto a region into a structural\n * re-split (edge) or a tab add (center). One instance per dockable region.\n *\n * While a tab is dragged over the region (a source carrying plan #2's\n * [`TabDragData`](/api/overlay/interfaces/TabDragData)), a\n * [`DropZoneOverlay`](/api/overlay/classes/DropZoneOverlay) marks the five drop\n * zones and highlights the one under the cursor. Dropping on an **edge** splits\n * the region — wrapping it in a fresh [`Split`](/api/layout/classes/Split) (or\n * extending an existing same-axis `Split`) and re-homing the dragged panel into\n * a new pane. Dropping on the **center** adds the panel as a tab. The dropped\n * panel always lands inside a reorderable [`Tab`](/api/layout/classes/Tab)\n * stack rather than as a bare pane, so its tab header stays a drag source and\n * the panel can be torn off or re-docked again. Every re-parent goes through\n * [`Component.moveComponent`](/api/core/classes/Component#movecomponent).\n *\n * `DockRegion` is a plain coordinator, not a `Component`: it owns no element,\n * only a drop-target registration (torn down by {@link destroy}) and the\n * overlay it drives. It composes with the manager's own\n * [`DragFeedback`](/api/overlay/classes/DragFeedback) tint — the tint reports drop\n * validity, this overlay reports drop position — by returning `null` from\n * `onDragOver`, which suppresses the manager's reorder line.\n *\n * @category Layouts\n */\nexport class DockRegion {\n\n private _region: Component;\n private _overlay: DropZoneOverlay = new DropZoneOverlay();\n private _teardown: () => void;\n private _onStructureChanged: (() => void) | null;\n // Pending spring-loaded raise of the host window while a tab dwells over this\n // region; cleared the moment the cursor leaves, drops, or the region tears down.\n private _raiseTimer: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Registers `region` as a drop target and wires the five-zone gesture.\n *\n * @param region - The container whose edges/center accept a docked tab.\n * @param onStructureChanged - Optional callback invoked after a drop mutates\n * the tree (an edge split or a centre dock), letting a tree owner such as\n * [`Dock`](/api/overlay/classes/Dock) re-wire the regions a drop just created.\n */\n constructor(region: Component, onStructureChanged?: () => void) {\n this._region = region;\n this._onStructureChanged = onStructureChanged ?? null;\n\n this._teardown = DragManager.makeDropTarget(region, {\n // Accept any tab drag so the manager keeps routing onDragOver/onDrop\n // here even over a zone the drop is *not* legal on — legality is then\n // decided per-zone (see isLegalDrop) and shown by colouring the drop\n // zone blue/red, not by tinting the whole frame. suppressValidityTint\n // turns off the manager's whole-target tint so it does not stack with\n // the per-zone colour.\n accepts: (detail: DragEventDetail): boolean => detail.dragData[\"tabDrag\"] === true,\n suppressValidityTint: true,\n onDragOver: (detail: DragEventDetail): null => {\n const componentId = detail.dragData[\"componentId\"] as string;\n const zone = this.dropZone(detail.clientX, detail.clientY);\n\n this._overlay.attachTo(this._region);\n this._overlay.setHighlight(zone, this.isLegalDrop(componentId, zone));\n\n // Spring-load a raise of the host window: a tab held over a\n // backgrounded float surfaces it after a dwell so the user can aim.\n this.scheduleSpringRaise();\n\n // Suppress the manager's ReorderIndicator — position feedback is\n // the overlay's job here, not a single insertion line.\n return null;\n },\n onDragLeave: (): void => {\n this._overlay.detach();\n this.clearSpringRaise();\n },\n onDrop: (detail: DragEventDetail): boolean | void => {\n const componentId = detail.dragData[\"componentId\"] as string;\n const zone = this.dropZone(detail.clientX, detail.clientY);\n\n this._overlay.detach();\n this.clearSpringRaise();\n\n // An illegal zone (self/ancestor, sole-content, a no-op edge, or\n // a centre drop into the panel's own tab bar) is a no-op:\n // suppress the drop so the source snaps back, exactly as the red\n // zone feedback promised.\n if (!this.isLegalDrop(componentId, zone)) {\n return false;\n }\n\n const panel = tabDragRegistry.get(componentId);\n\n if (!panel) {\n return false;\n }\n\n if (zone === \"center\") {\n this.dockAsTab(panel);\n } else {\n this.splitOnEdge(panel, zone);\n }\n\n // Surface the window the tab just landed in: a cross-window dock\n // onto a backgrounded float promotes and activates it, mirroring\n // the strip-drop raise in `Tab`.\n this.raiseHostWindow();\n this._onStructureChanged?.();\n },\n });\n }\n\n /**\n * Unregisters the drop target, detaches the overlay, and cancels any pending\n * spring-loaded raise.\n */\n destroy(): void {\n this._teardown();\n this._overlay.detach();\n this.clearSpringRaise();\n }\n\n /**\n * The [`AbstractWindow`](/api/overlay/classes/AbstractWindow) this region lives in, or `null` when the region\n * sits directly in the document. Walks the region's ancestor chain.\n *\n * @returns The owning window, or `null`.\n */\n private hostWindow(): AbstractWindow | null {\n for (let node: Component | null = this._region; node; node = node.getParentComponent()) {\n if (node instanceof AbstractWindow) {\n return node;\n }\n }\n\n return null;\n }\n\n /**\n * Raises and activates the region's host window, if any. A no-op for an\n * in-document region and harmless when the window is already frontmost.\n */\n private raiseHostWindow(): void {\n this.hostWindow()?.bringToFront();\n }\n\n /**\n * Arms the spring-loaded host-window raise if one is not already pending, so\n * a tab dwelling over a backgrounded float surfaces it after\n * {@link SPRING_RAISE_DELAY_MS}. Idempotent across the repeated `onDragOver`\n * calls a single hover produces — the timer runs once per dwell.\n */\n private scheduleSpringRaise(): void {\n if (this._raiseTimer !== null) {\n return;\n }\n\n this._raiseTimer = setTimeout(() => {\n this._raiseTimer = null;\n\n // Only raise if the drag is still live: the leave/drop clears cover\n // every reachable end, but guarding here keeps a cancelled drag (or\n // any future end path) from raising a window after the gesture ended.\n if (DragManager.isDragging()) {\n this.raiseHostWindow();\n }\n }, SPRING_RAISE_DELAY_MS);\n }\n\n /**\n * Cancels a pending spring-loaded raise — the cursor left, dropped, or the\n * region tore down before the dwell elapsed.\n */\n private clearSpringRaise(): void {\n if (this._raiseTimer !== null) {\n clearTimeout(this._raiseTimer);\n this._raiseTimer = null;\n }\n }\n\n /**\n * The drop zone for a cursor position, forcing a centre merge on a seed\n * region (see {@link isSeedRegion}) and otherwise delegating to the geometric\n * {@link computeZone}. Used by both the hover overlay and the commit guard so\n * feedback and behaviour agree.\n *\n * @param x - Viewport-relative pointer X.\n * @param y - Viewport-relative pointer Y.\n * @returns The resolved drop zone.\n */\n private dropZone(x: number, y: number): DropZone {\n // A seed region — one holding no real content, either genuinely empty or\n // carrying only transient chrome such as a Dock start-page placeholder —\n // has nothing to split around. Every drop resolves to a centre merge that\n // seeds the region (and, for a placeholder, replaces it) rather than a\n // nonsensical split into `[chrome | panel]`.\n return this.isSeedRegion() ? \"center\" : this.computeZone(x, y);\n }\n\n /**\n * Whether the region holds no real content — genuinely empty, or carrying\n * only transient chrome (a `Dock` placeholder). Such a region is a drop seed:\n * a drop merges in rather than splitting.\n *\n * @returns `true` when every child (if any) is transient chrome.\n */\n private isSeedRegion(): boolean {\n return this._region.getComponents()\n .every(child => this._region.getLayoutConstraints(child)?.transient === true);\n }\n\n /**\n * Resolves a viewport-relative cursor position to one of the five drop\n * zones. The cursor falls in an edge band when it is within\n * `EDGE_BAND_FRACTION` of an edge *and* closer to that edge than to the\n * perpendicular ones (corners resolve to the nearer edge, so there is no dead\n * diagonal); otherwise it is the central remainder. Pure arithmetic on the\n * region's box — no DOM mutation.\n *\n * @param x - Viewport-relative pointer X.\n * @param y - Viewport-relative pointer Y.\n * @returns The resolved drop zone.\n */\n private computeZone(x: number, y: number): DropZone {\n const rect = DOM.source.getViewportRect(this._region);\n\n const fx = (x - rect.left) / rect.width; // 0..1 across\n const fy = (y - rect.top) / rect.height; // 0..1 down\n const f = EDGE_BAND_FRACTION;\n\n const distLeft = fx, distRight = 1 - fx, distTop = fy, distBottom = 1 - fy;\n const nearest = Math.min(distLeft, distRight, distTop, distBottom);\n\n if (nearest >= f) {\n return \"center\";\n }\n\n if (nearest === distLeft) { return \"left\"; }\n if (nearest === distRight) { return \"right\"; }\n if (nearest === distTop) { return \"top\"; }\n\n return \"bottom\";\n }\n\n /**\n * Whether dropping `componentId` on `zone` of this region is a real,\n * structure-changing move — the single predicate behind both the zone\n * colour (`onDragOver`) and the commit guard (`onDrop`). A drop is illegal\n * when it would:\n *\n * - re-home the region into itself or an ancestor (a cycle: the overlay sits\n * on the region, so docking a node that contains the region beneath it\n * would detach the subtree). Reachable since an edge drop wraps the region\n * in a tab stack, making the region draggable by its own tab;\n * - dock a panel onto the edge of the region it is already the sole content\n * of (a split with the same panel on both sides);\n * - reproduce the panel's current layout — an edge drop where the dragged\n * stack is already that edge's neighbour (see {@link isRedundantEdgeDrop}),\n * or a centre drop adding the panel to the tab bar it is already in (see\n * {@link isRedundantCenterDrop}).\n *\n * @param componentId - The dragged content component's id.\n * @param zone - The zone the cursor resolved to.\n * @returns `true` when the drop would change the layout.\n */\n private isLegalDrop(componentId: string, zone: DropZone): boolean {\n for (let node: Component | null = this._region; node; node = node.getParentComponent()) {\n if (node.getId() === componentId) {\n return false;\n }\n }\n\n const children = this._region.getComponents();\n\n if (children.length === 1 && children[0].getId() === componentId) {\n return false;\n }\n\n if (zone === \"center\") {\n return !this.isRedundantCenterDrop(componentId);\n }\n\n return !this.isRedundantEdgeDrop(componentId, zone);\n }\n\n /**\n * Whether a centre drop of `componentId` would add it to the tab bar it is\n * already in — the panel is already a tab there, so the drop changes\n * nothing. Mirrors {@link dockAsTab}'s target resolution: a centre drop adds\n * to the region's own `Tab` (when the region is a stack), or to the region's\n * parent `Tab` (when the region is a tabbed leaf); any other shape wraps the\n * region in a fresh stack and so is never redundant. Redundant exactly when\n * the dragged panel's current stack is that same target stack.\n *\n * @param componentId - The dragged content component's id.\n * @returns `true` when the centre drop would leave the layout unchanged.\n */\n private isRedundantCenterDrop(componentId: string): boolean {\n const dragged = tabDragRegistry.get(componentId);\n\n if (!dragged) {\n return false;\n }\n\n const stack = dragged.getParentComponent();\n\n if (this._region.getLayoutManager() instanceof Tab) {\n return stack === this._region;\n }\n\n const parent = this._region.getParentComponent();\n\n if (parent?.getLayoutManager() instanceof Tab) {\n return stack === parent;\n }\n\n return false;\n }\n\n /**\n * Whether an edge drop of `componentId` on `zone` would reproduce the\n * current layout — i.e. land the dragged panel exactly where it already is.\n * Such a drop is the spatial equivalent of a self-drop and is rejected so it\n * gets red, no-op feedback rather than silently rebuilding the same tree.\n *\n * The redundant case is narrow: the dragged panel is the *sole* tab of a\n * stack that is *already* the immediate neighbour of the split unit on the\n * drop side. A multi-tab stack always changes (a tab is pulled out); a\n * perpendicular or non-adjacent drop always wraps or reorders. The\n * unit/container resolution mirrors {@link splitOnEdge} so this predicts the\n * exact insertion that method would perform, but reads the tree before any\n * mutation.\n *\n * @param componentId - The dragged content component's id.\n * @param zone - The edge the cursor resolved to (never `\"center\"`).\n * @returns `true` when the drop would leave the layout unchanged.\n */\n private isRedundantEdgeDrop(componentId: string, zone: DropZone): boolean {\n const dragged = tabDragRegistry.get(componentId);\n\n if (!dragged) {\n return false;\n }\n\n // Only a single-tab stack relocates wholesale: pulling a tab out of a\n // multi-tab stack always splits it off, which is a real change.\n const stack = dragged.getParentComponent();\n\n if (!stack || stack.getComponents().length !== 1) {\n return false;\n }\n\n const axis = (zone === \"left\" || zone === \"right\") ? \"horizontal\" : \"vertical\";\n const leading = zone === \"top\" || zone === \"left\";\n\n // Branch 1: the region is itself a same-axis Split — the drop appends the\n // stack as the region's first/last child. Redundant when the dragged\n // stack already occupies that boundary slot inside the region.\n const regionLm = this._region.getLayoutManager();\n\n if (regionLm instanceof Split && String(regionLm.getOrientation()) === axis) {\n if (stack.getParentComponent() !== this._region) {\n return false;\n }\n\n const kids = this._region.getComponents();\n\n return leading ? kids[0] === stack : kids[kids.length - 1] === stack;\n }\n\n // Branch 2: the stack inserts adjacent to the split unit (the region, or\n // its whole tab stack) inside a same-axis Split container. Redundant when\n // the dragged stack is already that neighbour. Any other container shape\n // wraps the unit in a fresh Split — never a no-op.\n const parent = this._region.getParentComponent();\n const unit = parent?.getLayoutManager() instanceof Tab ? parent : this._region;\n const container = unit?.getParentComponent();\n\n if (!container) {\n return false;\n }\n\n const containerLm = container.getLayoutManager();\n\n if (!(containerLm instanceof Split && String(containerLm.getOrientation()) === axis)) {\n return false;\n }\n\n if (stack.getParentComponent() !== container) {\n return false;\n }\n\n const kids = container.getComponents();\n const unitIndex = kids.indexOf(unit);\n const stackIndex = kids.indexOf(stack);\n\n return leading ? stackIndex === unitIndex - 1 : stackIndex === unitIndex + 1;\n }\n\n /**\n * Splits on an edge drop. The new panel lands in its own reorderable Tab\n * stack; the question is what that stack splits *against* — the **unit**:\n *\n * - if the region is itself a same-axis `Split`, it is extended directly;\n * - else if the region is a tabbed leaf (its parent is a `Tab`), the unit is\n * that whole tab **stack** — the split happens around the group, never by\n * dropping a `Split` into a tab slot (which would create an anonymous,\n * ever-nesting wrapper tab);\n * - otherwise the unit is the region itself.\n *\n * The unit is then either inserted into its container's existing same-axis\n * `Split` (adjacent — keeping repeated same-axis drops flat) or wrapped in a\n * fresh `Split` (so a perpendicular drop nests by one level, as intended).\n * The new stack is the leading pane for a `\"top\"`/`\"left\"` drop, trailing\n * otherwise. A single-tab stack split this way becomes a `Split` of two\n * stacks — \"the single tab converted into a split with two tabs\".\n *\n * @param panel - The dragged content component to re-home.\n * @param zone - The edge the cursor was released on (never `\"center\"`).\n */\n private splitOnEdge(panel: Component, zone: DropZone): void {\n const axis = (zone === \"left\" || zone === \"right\") ? \"horizontal\" : \"vertical\";\n const leading = zone === \"top\" || zone === \"left\";\n\n // The dropped panel always lands in its own reorderable Tab stack, never\n // as a bare Split pane: a bare pane has no draggable handle, so it could\n // never be detached again. The stack's tab is that handle (tear-off and\n // re-dock come free from the reorderable Tab wiring).\n const stack = this.newStack();\n stack.moveComponent(panel);\n\n // The region is itself a same-axis Split → extend it directly.\n const lm = this._region.getLayoutManager();\n\n if (lm instanceof Split && String(lm.getOrientation()) === axis) {\n this._region.moveComponent(stack, leading ? 0 : this._region.getComponents().length);\n\n return;\n }\n\n // Pick the unit to split: the region's whole Tab stack when the region is\n // a tabbed leaf, else the region itself. Splitting the stack (not the\n // leaf) keeps the Split out of the Tab — a Split in a tab slot is exactly\n // what produced the anonymous, nesting wrapper tab.\n const parent = this._region.getParentComponent();\n const unit = parent?.getLayoutManager() instanceof Tab ? parent : this._region;\n const container = unit.getParentComponent();\n\n if (!container) {\n return;\n }\n\n const containerLm = container.getLayoutManager();\n const unitIndex = container.getComponents().indexOf(unit);\n\n // Container is already a same-axis Split → insert the stack adjacent to\n // the unit, keeping same-axis drops flat instead of nesting.\n if (containerLm instanceof Split && String(containerLm.getOrientation()) === axis) {\n container.moveComponent(stack, leading ? unitIndex : unitIndex + 1);\n\n return;\n }\n\n // Otherwise wrap the unit in a fresh same-axis Split (a perpendicular\n // drop therefore nests by one level, as intended).\n const split = new Container({ layoutManager: new Split({ orientation: axis }) });\n\n container.moveComponent(split, unitIndex);\n\n // Stack the existing pane too when it is a bare leaf, so both sides of\n // the new split are draggable tab stacks — not a tab stack paired with a\n // handle-less bare pane that could never be torn off again.\n const unitPane = this.ensureStacked(unit);\n\n split.moveComponent(stack, leading ? 0 : 1);\n split.moveComponent(unitPane, leading ? 1 : 0);\n\n // The fresh `split` now occupies the slot `unit` held in `container`. When\n // that container is itself a Split, hand the new wrapper the size the unit\n // had so the user's dragged ratio survives the wrap instead of the slot\n // re-equalizing.\n if (containerLm instanceof Split) {\n containerLm.transferPaneSize(unit, split);\n }\n }\n\n /**\n * Returns `unit` wrapped in a fresh reorderable Tab stack when it is a bare\n * leaf, or `unit` unchanged when it is already a stack or a `Split`. Lets a\n * wrap leave *both* panes of the new split as draggable tab stacks — the\n * dropped panel and the pre-existing content alike — rather than pairing a\n * stack with a handle-less bare pane that could never be torn off again.\n *\n * @param unit - The pane about to become one side of a fresh `Split`.\n * @returns A Tab stack containing `unit`, or `unit` itself when it is already\n * a stack or a structural `Split`.\n */\n private ensureStacked(unit: Component): Component {\n const lm = unit.getLayoutManager();\n\n if (lm instanceof Tab || lm instanceof Split) {\n return unit;\n }\n\n const stack = this.newStack();\n stack.moveComponent(unit);\n\n return stack;\n }\n\n /**\n * A fresh, empty reorderable [`Tab`](/api/layout/classes/Tab) stack — the\n * draggable leaf unit edge and centre drops deposit content into. Made\n * `reorderable` so its tab header registers as a drag source: that is what\n * lets a docked panel be torn off or re-docked later. The tab itself is\n * built by `Tab.doLayout`, which creates one for every container child no\n * entry yet owns, so callers only need to `moveComponent` content in.\n *\n * Subscribes the stack's `empty` event to {@link pruneEmptyStack} so that\n * once its last tab leaves (torn off, re-docked, or closed) the now-empty\n * stack removes itself and any single-pane `Split` it leaves behind\n * collapses. The closure captures only `stack`; both are dropped together\n * when the stack is pruned, so no explicit `off` is needed.\n *\n * @returns A `Container` carrying a reorderable `Tab` layout manager.\n */\n private newStack(): Container {\n const stack = new Container({ layoutManager: new Tab({ reorderable: true, compact: true }) });\n const tab = stack.getLayoutManager() as Tab;\n\n tab.on(\"empty\", () => this.pruneEmptyStack(stack));\n\n return stack;\n }\n\n /**\n * Removes an emptied stack from its parent, then collapses the parent if the\n * removal leaves it a single-pane `Split`. The stack is destroyed, not moved,\n * so it leaves via `removeComponent` rather than `moveComponent`.\n *\n * @param stack - The stack whose `empty` event fired.\n */\n private pruneEmptyStack(stack: Component): void {\n const parent = stack.getParentComponent();\n\n if (!parent) {\n return;\n }\n\n // Only a stack sitting in a `Split` is removed here (and the Split then\n // collapses). A stack whose parent is not a Split is the sole content of\n // its container — the dock's own root container, or a float window. It\n // must be kept: removing a promoted-to-root stack would leave the dock\n // with no region and crash the next `addPanel` (the same invariant\n // `Dock.pruneRegion` guards with `parent === this`); an emptied float is\n // closed by the dock's own `pruneRegion` -> `closeFloatIfEmpty` path.\n if (!(parent.getLayoutManager() instanceof Split)) {\n return;\n }\n\n parent.removeComponent(stack);\n this.collapseIfSinglePaneSplit(parent);\n }\n\n /**\n * Collapses a `Split` that has been left with a single child: the lone child\n * is hoisted into the grandparent at the `Split`'s slot via `moveComponent`\n * and the emptied `Split` is dropped. A no-op unless `container` is a `Split`\n * with exactly one child. At the root (no grandparent) the lone child is left\n * in place — a root `Split` with one child simply renders it full-bleed.\n *\n * The hoist swaps one child for another in the grandparent (count unchanged),\n * so the grandparent never itself drops to a single child from this — the\n * collapse does not cascade.\n *\n * @param container - The container that just lost a child.\n */\n private collapseIfSinglePaneSplit(container: Component): void {\n if (!(container.getLayoutManager() instanceof Split)) {\n return;\n }\n\n const children = container.getComponents();\n\n if (children.length !== 1) {\n return;\n }\n\n const grandparent = container.getParentComponent();\n\n if (!grandparent) {\n return;\n }\n\n const index = grandparent.getComponents().indexOf(container);\n\n // The hoisted child takes the slot the collapsing Split vacated; carry the\n // Split's stored size onto it so a single-pane collapse keeps the user's\n // dragged ratio (when the grandparent is itself a Split).\n const grandparentLm = grandparent.getLayoutManager();\n\n if (grandparentLm instanceof Split) {\n grandparentLm.transferPaneSize(container, children[0]);\n }\n\n grandparent.moveComponent(children[0], index);\n grandparent.removeComponent(container);\n }\n\n /**\n * Adds the dragged panel to the region as a tab, choosing the target by what\n * already exists:\n *\n * 1. the region is itself a `Tab` → the panel joins it;\n * 2. the region is already a tabbed leaf (its parent is a `Tab` stack, from a\n * prior centre-drop) → the panel joins that parent stack as a sibling tab;\n * 3. otherwise → the region is wrapped in a fresh `Tab` stack.\n *\n * Case 2 is the fix for repeated centre-drops: without it, the region's own\n * layout manager (a plain leaf) is never a `Tab`, so each drop would wrap it\n * again, nesting stacks and shrinking the content by a tab-strip per drop.\n * The tab itself is materialised by `Tab.doLayout`, which builds one for\n * every container child no entry yet owns.\n *\n * @param panel - The dragged content component to re-home as a tab.\n */\n private dockAsTab(panel: Component): void {\n const lm = this._region.getLayoutManager();\n\n if (lm instanceof Tab) {\n this._region.moveComponent(panel);\n this._region.scheduleLayout();\n\n return;\n }\n\n const parent = this._region.getParentComponent();\n\n if (!parent) {\n return;\n }\n\n if (parent.getLayoutManager() instanceof Tab) {\n parent.moveComponent(panel);\n parent.scheduleLayout();\n\n return;\n }\n\n const index = parent.getComponents().indexOf(this._region);\n const tabContainer = this.newStack();\n\n parent.moveComponent(tabContainer, index);\n tabContainer.moveComponent(this._region);\n tabContainer.moveComponent(panel);\n tabContainer.scheduleLayout();\n }\n}\n","// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0\n\nimport { Component } from \"~/core/Component.js\";\nimport { Window } from \"~/overlay/Window.js\";\nimport { AbstractWindow } from \"~/overlay/AbstractWindow.js\";\nimport { Split } from \"~/layout/Split.js\";\nimport { Tab } from \"~/layout/Tab.js\";\nimport { LayoutConstraints } from \"~/layout/LayoutConstraints.js\";\nimport type { AxisOrientation } from \"~/primitive/Axis.js\";\n\n/**\n * Captures and restores the **arrangement** of the recognised container\n * managers — {@link Split} pane ratios, {@link Tab} order + active index, and\n * floating [`Window`](/api/overlay/classes/Window) rects + state — keyed by stable\n * panel IDs. It does **not** serialize the component tree: leaf content is an\n * arbitrary {@link Component} subclass the framework cannot reconstruct from\n * data, so each leaf is recorded as a bare reference and supplied on restore by\n * a caller-owned {@link LayoutFactory}.\n *\n * @remarks Designed for runtime layout-switching: a caller holds several\n * {@link LayoutState} objects and calls {@link restoreLayout} with any of them\n * at any time. Restore uses a park-and-rebuild model — it parks the live leaf\n * panels (preserving their state), tears down and rebuilds the container tree\n * from the target state, then re-homes the leaves — so switching between\n * arbitrarily different topologies is correct without diff/patch heuristics.\n *\n * @module\n */\n\n/**\n * Serializable rectangle for a {@link WindowNode}.\n *\n * @category Layouts\n */\nexport interface SerializedRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * A recognised arrangement node, or an opaque content leaf.\n *\n * @category Layouts\n */\nexport type LayoutNode = PanelNode | SplitNode | TabNode;\n\n/**\n * Leaf: a single content panel, keyed by its stable panel ID.\n *\n * @category Layouts\n */\nexport interface PanelNode {\n kind: \"panel\";\n panelId: string;\n /**\n * Optional registry glyph name, captured from the leaf's\n * {@link LayoutConstraints.glyph} so a restored tab keeps its glyph (the\n * per-container constraint would otherwise be dropped by the re-home).\n */\n glyph?: string | null;\n}\n\n/**\n * A {@link Split} container: orientation plus per-pane ratios and collapsed flags.\n *\n * @category Layouts\n */\nexport interface SplitNode {\n kind: \"split\";\n orientation: AxisOrientation;\n /** Child arrangement nodes, in pane order. */\n children: LayoutNode[];\n /** One ratio per child, in the same order; sums to ~1.0. */\n ratios: number[];\n /** One collapsed flag per child, in the same order. */\n collapsed: boolean[];\n}\n\n/**\n * A {@link Tab} container: ordered child nodes plus the active index.\n *\n * @category Layouts\n */\nexport interface TabNode {\n kind: \"tab\";\n /** Child arrangement nodes, in tab order. */\n children: LayoutNode[];\n /** Zero-based index of the active tab. */\n activeIndex: number;\n}\n\n/**\n * A floating [`Window`](/api/overlay/classes/Window) and the arrangement it hosts.\n * A dockable float carries a full region {@link content} tree (splits, tab\n * order, active tab); a legacy single-panel float carried only {@link panelId}.\n *\n * @category Layouts\n */\nexport interface WindowNode {\n kind: \"window\";\n /**\n * Legacy single-panel reference. Read on restore for backward-compat with\n * states written before floats became dockable; new states write\n * {@link content} instead.\n */\n panelId?: string;\n /**\n * The float's internal arrangement — a region tree. Present in every\n * newly-serialized state; a single-frame float records a one-tab `tab` node.\n */\n content?: LayoutNode;\n /** Title-bar text — captured so the restored window reproduces its title. */\n header: string;\n rect: SerializedRect;\n state: \"normal\" | \"minimized\" | \"maximized\";\n /** Normal-state geometry to restore to when un-minimizing; null when normal. */\n restoreRect: SerializedRect | null;\n}\n\n/**\n * Top-level captured layout: the in-root tree plus the orthogonal window plane.\n *\n * @category Layouts\n */\nexport interface LayoutState {\n /** Schema version for forward-compatible migration. */\n version: 1;\n /** The arrangement rooted at the serialized container. */\n root: LayoutNode;\n /** Floating windows, captured separately from the root subtree. */\n windows: WindowNode[];\n}\n\n/**\n * Resolves a stable panel ID to the {@link Component} that supplies its content.\n *\n * **Contract:** the factory MUST return the **same Component instance** for a\n * given `panelId` on every call. Restoration parks and re-homes the live panel\n * rather than rebuilding it, so panel state (scroll, form values, table column\n * widths, selection) only survives a runtime layout switch when the factory\n * hands back the identical instance. Returning a fresh instance per call\n * discards that state and makes parking pointless. Return `null` for an ID the\n * caller no longer provides — that leaf is skipped (see {@link restoreLayout}).\n *\n * @category Layouts\n */\nexport type LayoutFactory = (panelId: string) => Component | null;\n\n/**\n * Returns a container's arrangement-manager kind with the callable alias's\n * leading underscore stripped (`_Split` → `\"Split\"`), or `\"\"` when the\n * component has no layout manager. String discrimination avoids importing the\n * manager classes purely for `instanceof`.\n *\n * @param component - The component whose manager to classify.\n * @returns `\"Split\"`, `\"Tab\"`, or another (opaque) manager name.\n */\nfunction managerKind(component: Component): string {\n const manager = component.getLayoutManager();\n\n return manager ? manager.getClassName().replace(/^_/, \"\") : \"\";\n}\n\n/**\n * Resolves a component's stable serialization ID as its {@link Component.getId}.\n * The id is the identity channel: callers that need a layout to round-trip across\n * reloads assign each leaf a stable id via `setId` (a volatile auto-generated id\n * round-trips within a session but not across one).\n *\n * @param component - The leaf component to identify.\n * @returns The component's id.\n */\nfunction panelIdOf(component: Component): string {\n return component.getId();\n}\n\n/**\n * Builds the arrangement node for a component, descending into recognised\n * `Split`/`Tab` containers and recording everything else as an opaque panel\n * leaf.\n *\n * @param component - The component to capture.\n * @returns The arrangement node.\n */\n/**\n * The children of a container that participate in serialization: every child\n * except those marked `transient` in their layout constraints. A transient child\n * is chrome laid out like any other (e.g. a `Dock` empty-state placeholder shown\n * as a non-closeable tab) but is never captured in a saved arrangement.\n *\n * @param component - The container whose children to filter.\n * @returns The serializable children, in order.\n */\nfunction serializableChildren(component: Component): Component[] {\n return component.getComponents()\n .filter(child => component.getLayoutConstraints(child)?.transient !== true);\n}\n\nfunction nodeFor(component: Component): LayoutNode {\n const kind = managerKind(component);\n\n if (kind === \"Split\") {\n const manager = component.getLayoutManager() as Split;\n const children = component.getComponents().map(nodeFor);\n\n return {\n kind: \"split\",\n orientation: manager.getOrientation() === \"vertical\" ? \"vertical\" : \"horizontal\",\n children,\n ratios: manager.getPaneRatios(),\n collapsed: children.map((_, index) => manager.isPaneCollapsed(index)),\n };\n }\n\n if (kind === \"Tab\") {\n const manager = component.getLayoutManager() as Tab;\n\n return {\n kind: \"tab\",\n children: serializableChildren(component).map(nodeFor),\n activeIndex: manager.getActiveTabIndex(),\n };\n }\n\n const glyph = component.getParentComponent()?.getLayoutConstraints(component)?.glyph ?? null;\n\n return { kind: \"panel\", panelId: panelIdOf(component), glyph };\n}\n\n/**\n * Returns a window's content panel — its first non-header child — or `null`\n * when the window has no content yet.\n *\n * @param win - The window to inspect.\n * @returns The content component, or `null`.\n */\nfunction windowContentOf(win: AbstractWindow): Component | null {\n return win.getComponents().find(child => !win.isChromeComponent(child)) ?? null;\n}\n\n/**\n * Builds a {@link WindowNode} for an open window, or `null` when it has no\n * content panel to key on.\n *\n * @param win - The open window to capture.\n * @returns The window node, or `null`.\n */\nfunction windowNodeFor(win: AbstractWindow): WindowNode | null {\n const content = windowContentOf(win);\n\n if (!content) {\n return null;\n }\n\n return {\n kind: \"window\",\n content: nodeFor(content),\n header: win.getTitle(),\n rect: win.getRect(),\n state: win.getWindowState(),\n restoreRect: win.getRestoreRect(),\n };\n}\n\n/**\n * Captures the arrangement of `root` (and every open window) to a plain,\n * serializable object. Only `Split`/`Tab`/`Window` topology and geometry is\n * recorded; each leaf is a bare panel-ID reference whose content the caller\n * rebuilds on restore.\n *\n * @param root - The container whose arrangement to capture.\n * @returns The captured {@link LayoutState}.\n *\n * @category Layouts\n */\nexport function serializeLayout(root: Component): LayoutState {\n const windows = Window.getOpenWindows()\n .map(windowNodeFor)\n .filter((node): node is WindowNode => node !== null);\n\n return {\n version: 1,\n root: nodeFor(root),\n windows,\n };\n}\n\n/**\n * Collects the opaque leaf panels reachable from a component, descending\n * through recognised `Split`/`Tab` containers and treating everything else as a\n * leaf. The component itself is never added — only its descendants — because\n * the caller passes the rebuild-target container, which is never a parkable\n * leaf.\n *\n * @param component - The container whose descendants to walk.\n * @param into - The accumulator the leaves are pushed onto.\n */\nfunction collectLeaves(component: Component, into: Component[]): void {\n serializableChildren(component).forEach(child => {\n const kind = managerKind(child);\n\n if (kind === \"Split\" || kind === \"Tab\") {\n collectLeaves(child, into);\n } else {\n into.push(child);\n }\n });\n}\n\n/**\n * Detaches every factory-known leaf from the live tree and open windows,\n * returning them keyed by panel ID. Honours the stable-instance contract: a\n * leaf is parked only when the factory hands back that very instance, so a\n * misbehaving factory degrades to \"state not preserved\" rather than re-homing a\n * stale orphan. Parked leaves are **not** destroyed — they carry panel state.\n *\n * @param root - The container subtree to park leaves from.\n * @param liveWindows - The open windows whose content to park.\n * @param factory - Resolves a panel ID to its owning component.\n * @returns The parked leaves, keyed by panel ID.\n */\nfunction parkLeaves(root: Component, liveWindows: AbstractWindow[], factory: LayoutFactory): Map<string, Component> {\n const leaves: Component[] = [];\n\n collectLeaves(root, leaves);\n\n liveWindows.forEach(win => {\n const content = windowContentOf(win);\n\n if (!content) {\n return;\n }\n\n // A dockable float's content is a region tree: park every leaf in it so\n // each frame's state survives the restore. A legacy single-frame float\n // has a bare content component — park it directly.\n const kind = managerKind(content);\n\n if (kind === \"Split\" || kind === \"Tab\") {\n collectLeaves(content, leaves);\n } else {\n leaves.push(content);\n }\n });\n\n const parked = new Map<string, Component>();\n\n leaves.forEach(leaf => {\n const id = panelIdOf(leaf);\n\n if (factory(id) === leaf) {\n parked.set(id, leaf);\n leaf.getParentComponent()?.removeComponent(leaf);\n }\n });\n\n return parked;\n}\n\n/**\n * Whether `win` hosts `node` — i.e. `node` lies within `win`'s subtree, so `win`\n * is the window the layout root lives in rather than a torn-off float. Walks\n * `node`'s ancestor chain looking for `win`.\n *\n * @param win - A candidate host window.\n * @param node - The layout root being restored.\n * @returns `true` when `win` contains `node`.\n */\nfunction hostsComponent(win: AbstractWindow, node: Component): boolean {\n for (let n: Component | null = node; n; n = n.getParentComponent()) {\n if (n === win) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Returns the layout constraints to re-home a panel leaf under, carrying its\n * captured `glyph` through so a restored tab keeps its glyph. Identity rides on\n * the component's own id (see {@link panelIdOf}), not a constraint, so no `name`\n * is stamped — that keeps the leaf's visible label (its component name) intact\n * across a restore. Sub-containers and glyph-less leaves carry no constraints.\n *\n * @param node - The child node being placed.\n * @returns The constraints, or `undefined` when none are needed.\n */\nfunction constraintsFor(node: LayoutNode): LayoutConstraints | undefined {\n if (node.kind !== \"panel\" || !node.glyph) {\n return undefined;\n }\n\n const constraints = new LayoutConstraints();\n constraints.glyph = node.glyph;\n\n return constraints;\n}\n\n/**\n * Resolves an arrangement node to a live component: a parked/factory leaf for a\n * panel node, or a freshly-built and populated sub-container for a split/tab\n * node. Returns `null` (with a warning) when a panel's factory yields nothing.\n *\n * @param node - The node to materialize.\n * @param parked - The parked leaves to re-home from.\n * @param factory - Supplies any leaf not already parked.\n * @returns The component, or `null` to skip.\n */\nfunction materializeNode(node: LayoutNode, parked: Map<string, Component>, factory: LayoutFactory): Component | null {\n if (node.kind === \"panel\") {\n const panel = parked.get(node.panelId) ?? factory(node.panelId);\n\n if (!panel) {\n console.warn(`restoreLayout: no component for panelId \"${node.panelId}\"; skipping.`);\n }\n\n return panel;\n }\n\n const container = new Component();\n\n populateContainer(container, node, parked, factory);\n\n return container;\n}\n\n/**\n * Gives a container a fresh `Split`/`Tab` manager matching `node`, re-homes the\n * node's resolvable children into it in order, then applies the recorded\n * geometry (pane ratios + collapsed flags, or the active tab). Children whose\n * factory yields nothing are dropped, and the ratio/collapsed arrays are\n * re-aligned to the panes that actually landed so a missing leaf doesn't skew\n * the rest.\n *\n * @param container - The container to populate.\n * @param node - The split or tab node describing it.\n * @param parked - The parked leaves to re-home from.\n * @param factory - Supplies any leaf not already parked.\n */\nfunction populateContainer(container: Component, node: SplitNode | TabNode, parked: Map<string, Component>, factory: LayoutFactory): void {\n if (node.kind === \"split\") {\n const split = new Split({ orientation: node.orientation });\n container.setLayoutManager(split);\n\n const placed: { ratio: number; collapsed: boolean }[] = [];\n\n node.children.forEach((child, index) => {\n const built = materializeNode(child, parked, factory);\n\n if (built) {\n container.moveComponent(built, undefined, constraintsFor(child));\n placed.push({ ratio: node.ratios[index] ?? 0, collapsed: node.collapsed[index] ?? false });\n }\n });\n\n split.applyPaneRatios(placed.map(entry => entry.ratio));\n\n placed.forEach((entry, index) => {\n if (entry.collapsed) {\n split.setPaneCollapsedImmediate(index, true);\n }\n });\n } else {\n const tab = new Tab({ reorderable: true, compact: true });\n container.setLayoutManager(tab);\n\n node.children.forEach(child => {\n const built = materializeNode(child, parked, factory);\n\n if (built) {\n container.moveComponent(built, undefined, constraintsFor(child));\n\n // Register the tab entry eagerly. The eager-add path otherwise\n // defers tab creation to the next `doLayout`, so `_tabs` would be\n // empty when `setActiveTabIndex` clamps below; `createTab` is the\n // public synchronous registration (doLayout's catch-up then skips\n // the now-owned child).\n tab.createTab(built);\n }\n });\n\n tab.setActiveTabIndex(node.activeIndex);\n }\n}\n\n/**\n * Rebuilds a floating window from a {@link WindowNode}: a fresh window with the\n * recorded title and its materialized content — a region tree for a dockable\n * float, or the single parked/factory panel for a legacy single-frame float. The\n * normal-state geometry is applied first (from `restoreRect` when the saved\n * state isn't normal), then `setWindowState` re-caches it and animates to the\n * saved state.\n *\n * @param node - The window node to rebuild.\n * @param parked - The parked leaves to re-home from.\n * @param factory - Supplies any content panel not parked.\n */\nfunction applyWindow(node: WindowNode, parked: Map<string, Component>, factory: LayoutFactory): void {\n // New states carry a `content` tree; a legacy state carries only `panelId`,\n // restored as a single-panel node through the same materialize path.\n const contentNode: LayoutNode | null = node.content\n ?? (node.panelId ? { kind: \"panel\", panelId: node.panelId, glyph: null } : null);\n\n if (!contentNode) {\n console.warn(\"restoreLayout: window node has neither content nor panelId; skipping.\");\n\n return;\n }\n\n const content = materializeNode(contentNode, parked, factory);\n\n if (!content) {\n return;\n }\n\n const win = new Window(node.header);\n\n // Carry the leaf's glyph (single-panel content only) through the re-home, as\n // for any split/tab pane. The frame's id is its own identity channel, so a\n // later restore still discovers and parks it through the normal leaf path.\n win.moveComponent(content, undefined, constraintsFor(contentNode));\n\n // Apply the geometry BEFORE show(): show() runs the first doLayout, which\n // sizes the content to the window's body — so the rect must already be the\n // final one or the content lays out against the default size and only\n // corrects on a later re-layout. For a minimized/maximized node the normal\n // rect is applied here and setWindowState (after show) animates from it.\n const normalRect = node.state === \"normal\" ? node.rect : (node.restoreRect ?? node.rect);\n win.applyRect(normalRect);\n\n win.show();\n\n if (node.state !== \"normal\") {\n win.setWindowState(node.state);\n }\n}\n\n/**\n * Restores a previously captured `state` onto `root`, sourcing leaves from\n * `factory`. Safe to call repeatedly on a live, already-arranged tree to switch\n * between saved layouts at runtime.\n *\n * @remarks Single-pass park-and-rebuild: it parks every factory-known leaf\n * (detaching but never destroying them, so their state survives), tears down\n * all `Split`/`Tab` containers under `root` and closes all open windows,\n * rebuilds the container tree from `state`, re-homes the parked leaves via\n * [`moveComponent`](/api/core/classes/Component#movecomponent), then applies\n * geometry. Because the container tree is rebuilt from scratch each call,\n * switching A→B→A reproduces A exactly with no residue from B. A panel ID with\n * no factory result is skipped with a warning.\n *\n * @param root - The container to restore the arrangement onto.\n * @param state - A {@link LayoutState} from {@link serializeLayout}.\n * @param factory - Resolves each panel ID to its (same-instance) content.\n *\n * @category Layouts\n */\nexport function restoreLayout(root: Component, state: LayoutState, factory: LayoutFactory): void {\n // Float-plane windows only. A window that *hosts* `root` (the layout lives\n // inside it, e.g. a Dock in a Window) must be left alone — tearing it down\n // would close the very window the restored layout renders into. Only\n // torn-off floats are parked and rebuilt from `state.windows`.\n const liveWindows = Window.getOpenWindows().filter(win => !hostsComponent(win, root));\n\n // 1. PARK every factory-known leaf (detach, never destroy).\n const parked = parkLeaves(root, liveWindows, factory);\n\n // 2. TEAR DOWN the live arrangement: close the float windows (content already\n // parked) and clear the root container subtree wholesale.\n liveWindows.forEach(win => win.onExitAction());\n root.removeAllComponents();\n\n // 3-5. REBUILD the container tree, RE-HOME parked leaves, APPLY geometry.\n if (state.root.kind === \"panel\") {\n const built = materializeNode(state.root, parked, factory);\n\n if (built) {\n root.moveComponent(built, undefined, constraintsFor(state.root));\n }\n } else {\n populateContainer(root, state.root, parked, factory);\n }\n\n state.windows.forEach(node => applyWindow(node, parked, factory));\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{t as e}from"./DOM-DeF_dWe2.js";import{a as t,l as n,t as r}from"./Position-DJKB0N3l.js";import{d as i,f as a,l as o,t as s}from"./Component-Bs6TvaGZ.js";import{t as c}from"./ListenerBag-WPdKuuds.js";import{t as l}from"./Container-CzyZeMyZ.js";import{a as u}from"./Tooltip-5BR7yYEX.js";import{d,i as f,l as p,n as m,o as h,r as g,t as _}from"./LayoutSizes-XdhpAOmc.js";import{i as v,n as y}from"./Border-5Ki2DCWz.js";import{t as b}from"./LayoutConstraints-CHI2lhPd.js";import{n as x,r as S,t as C}from"./DragManager-c6M_mE3e.js";var w=4,T=1,Split=class extends o{_orientation=`horizontal`;_sizes=new Map;_gutters=[];_collapsed=new Map;_weights=new Map;_pendingCollapsed=[];_listeners=new c;_pendingSizes=null;_dragOriginPointer=0;_dragOriginLhsSize=0;_dragOriginRhsSize=0;_lastAvailableMain=0;_collapseAnimation=null;constructor(e){super(),e&&this.applyOptions(e)}applyOptions(e){if(super.applyOptions(e),e.orientation!==void 0&&this.setOrientation(e.orientation),e.collapsedPanes!==void 0&&(this._pendingCollapsed=[...e.collapsedPanes]),e.paneSizes!==void 0&&(this._pendingSizes=e.paneSizes.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)}}}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)}isPaneCollapsed(e){let t=this.getContainer();if(!t)return!1;let n=t.getLaidOutComponents()[e];return n?this._collapsed.get(n)??!1:!1}collapsesTowardStart(e){return e===`west`||e===`north`}paneDirection(e){return this.getLayoutConstraints(e)?.collapseDirection??(this._orientation===`horizontal`?`west`:`north`)}paneCollapsible(e){return this.getLayoutConstraints(e)?.collapsible!==!1}gutterTargetPane(e,t){let n=t[e+1];if(n&&this.paneCollapsible(n)&&!this.collapsesTowardStart(this.paneDirection(n)))return e+1;let r=t[e];return r&&this.paneCollapsible(r)&&this.collapsesTowardStart(this.paneDirection(r))?e:-1}paneServingGutter(e,t){let n=this.paneDirection(t[e]);return this.collapsesTowardStart(n)?e<t.length-1&&this.gutterTargetPane(e,t)===e?e:-1:e>0&&this.gutterTargetPane(e-1,t)===e?e-1:-1}setPaneCollapsed(e,t){let n=this.getContainer();if(!n)return this;let r=n.getLaidOutComponents(),i=r[e];if(!i||this.paneServingGutter(e,r)<0||(this._collapsed.get(i)??!1)===t)return this;this._collapsed.set(i,t),this.emit(`panecollapse`,e,t);let a=[...r.map(e=>({component:e,relayout:!0})),...this._gutters.map(e=>({component:e,relayout:!1}))];return this._collapseAnimation=v(n,i,a,this._collapseAnimation,()=>{this._collapseAnimation=null}),this}getOrientation(){return this._orientation}setOrientation(e){return this._orientation=e,this}setPaneSize(e,t){return this._sizes.set(e,t),this}getPaneSize(e){return this._sizes.get(e)}setPaneResizeWeight(e,t){return this._weights.set(e,t),this}getPaneResizeWeight(e){return this._weights.get(e)}effectiveResizeWeight(e,t){return this._weights.get(e)??this.getLayoutConstraints(e)?.weight??t}clampMain(e,t,r){let i=e.getMinSize(),a=e.getMaxSize(),o=i?r?i.width:i.height:0,s=a?r?a.width:a.height:1/0;return n.clamp(t,o,s)}isPinnedMain(e,t){let n=e.getMinSize(),r=e.getMaxSize();return(n?t?n.width:n.height:0)===(r?t?r.width:r.height:1/0)}isResizePinnedMain(e){return this.effectiveResizeWeight(e,T)===0}seedFromPreferred(e,t){for(let n of e){if(this._sizes.has(n))continue;let e=n.getPreferredSizeConstraint();if(!e)continue;let r=t?e.width:e.height;this._sizes.set(n,this.clampMain(n,r,t))}}transferPaneSize(e,t){let n=this._sizes.get(e);if(n===void 0)return this;this._sizes.set(t,n),this._sizes.delete(e);let r=this._collapsed.get(e);r!==void 0&&(this._collapsed.set(t,r),this._collapsed.delete(e));let i=this._weights.get(e);return i!==void 0&&(this._weights.set(t,i),this._weights.delete(e)),this}getPaneRatios(){let e=this.getContainer();if(!e)return[];let t=e.getComponents();return t.length===0?[]:g(t.map(e=>this._sizes.get(e)??0),t.length)}getPreferredSize(){return this.computeContentSize(e=>e.getPreferredSize())}getMinSize(){return this.computeContentSize(e=>e.getMinSize())}getMaxSize(){return{width:t,height:t}}computeContentSize(e){let t=this.getContainer();if(!t)return null;let n=t.getLaidOutComponents(),r=t.getPerimeterSize(),i=this._orientation===`horizontal`,a=0,o=0;for(let t=0;t<n.length;t+=1){let r=e(n[t]);r&&(a+=i?r.width:r.height,o=Math.max(o,i?r.height:r.width))}return a+=this.gutterTotal(n.length),i?{width:a+r.left+r.right,height:o+r.top+r.bottom}:{width:o+r.left+r.right,height:a+r.top+r.bottom}}applyPaneRatios(e){let t=this.getContainer();if(!t)return this;let n=t.getComponents(),r=n.length;if(r===0)return this;let i=g(e,r),a=t.getInnerSize(),o=a?this._orientation===`horizontal`?a.width:a.height:0,s=Math.max(0,o-this.gutterTotal(r)),c=s>0?s:1;return n.forEach((e,t)=>{this._sizes.set(e,i[t]*c)}),this._lastAvailableMain=c,t.scheduleLayout(),this}paneSizeUnits(e){return e.map(e=>this.isResizePinnedMain(e)?`px`:`ratio`)}getPaneSizes(){let e=this.getContainer();if(!e)return[];let t=e.getComponents();if(t.length===0)return[];let n=this.paneSizeUnits(t);return this._pendingSizes!==null&&m(this._pendingSizes,n)?this._pendingSizes.map(e=>({...e})):f(n,t.map(e=>this._sizes.get(e)??0))}applyPaneSizes(e){let t=this.getContainer();if(!t)return this;let n=t.getComponents();if(!m(e,this.paneSizeUnits(n)))return this;let r=t.getInnerSize(),i=r?this._orientation===`horizontal`?r.width:r.height:0,a=Math.max(0,i-this.gutterTotal(n.length)),o=_(e,a);return n.forEach((e,t)=>this.setPaneSize(e,o[t])),this._lastAvailableMain=a>0?a:1,t.scheduleLayout(),this}setPaneCollapsedImmediate(e,t){let n=this.getContainer();if(!n)return this;let r=n.getLaidOutComponents(),i=r[e];return!i||t&&this.paneServingGutter(e,r)<0?this:(this._collapsed.set(i,t),this.emit(`panecollapse`,e,t),n.scheduleLayout(),this)}onDragStart(e,t,n){let r=this._gutters.indexOf(t),i=e.getLaidOutComponents()[r],a=e.getLaidOutComponents()[r+1];this._dragOriginPointer=n,this._orientation===`horizontal`?(this._dragOriginLhsSize=i.getWidth(),this._dragOriginRhsSize=a.getWidth()):(this._dragOriginLhsSize=i.getHeight(),this._dragOriginRhsSize=a.getHeight())}onDrag(e,t,n){let r=this._gutters.indexOf(t),i=e.getLaidOutComponents()[r],a=e.getLaidOutComponents()[r+1],o=this._orientation===`horizontal`,s=this._dragOriginLhsSize+this._dragOriginRhsSize,c=i.getMinSize(),l=a.getMinSize(),u=i.getMaxSize(),d=a.getMaxSize(),f=c?o?c.width:c.height:0,p=l?o?l.width:l.height:0,m=u?o?u.width:u.height:1/0,h=d?o?d.width:d.height:1/0,g=n-this._dragOriginPointer,_=Math.max(f,s-h),v=Math.min(m,s-p),y=this._dragOriginLhsSize+g;y=Math.max(_,Math.min(v,y));let b=s-y,x=y-(o?i.getWidth():i.getHeight());o?(i.setWidth(y),t.setX(t.getX()+x),a.setX(a.getX()+x),a.setWidth(b)):(i.setHeight(y),t.setY(t.getY()+x),a.setY(a.getY()+x),a.setHeight(b)),this._sizes.set(i,y),this._sizes.set(a,b),i.doLayout(),a.doLayout()}onDragEnd(){this.emit(`paneresize`,this.getPaneSizes())}detach(){super.detach();for(let t of this._gutters){let n=t.getElement();e.sink.removeChild(e.source.getParentNode(n),n),t.destroy()}return this._gutters=[],this}gutterTotal(e){return Math.max(0,e-1)*w}computeTotalMinSize(){let e=this.getContainer();if(!e)return{width:0,height:0};let t=e.getLaidOutComponents();if(t.length===0)return{width:0,height:0};let n=t.length-1,r=0,i=0;for(let e=0;e<t.length;e+=1){let a=t[e],o=this._sizes.get(a),s=this._collapsed.get(a)??!1,c=e<n;if(s&&c)r+=18;else{if(!s)if(o!=null)r+=o;else{let e=a.getMinSize();e&&(r+=this._orientation===`horizontal`?e.width:e.height)}c&&(r+=w)}let l=a.getMinSize();l&&(i=Math.max(i,this._orientation===`horizontal`?l.height:l.width))}return this._orientation===`horizontal`?{width:r,height:i}:{width:i,height:r}}doLayout(){let t=this,n=this.getContainer();if(!n)return;let r=n.getInnerSize();if(!r)return;let a=this._orientation===`horizontal`?r.width:r.height;r=this.inflateForOverflow(r);let o=n.getElement(),s=n.getLaidOutComponents(),c=n.getContentInsets(),l=s.length-1;for(let r=this._gutters.length;r<l;r+=1){let i=new y(this._orientation,{expandedBackground:`transparent`}),a=r;i.on(`dragstart`,function(e){t.onDragStart(n,i,e)}),i.on(`drag`,function(e){t.onDrag(n,i,e)}),i.on(`dragend`,()=>this.onDragEnd()),i.on(`collapse`,function(){let e=t.gutterTargetPane(a,n.getLaidOutComponents());e>=0&&t.setPaneCollapsed(e,!t.isPaneCollapsed(e))}),this._gutters.push(i),e.sink.appendChild(o,i.getElement(!0))}let u=c.getLeft(),d=c.getTop();this.recalculateSizes(),this.applyPendingSizes(),this.applyPendingCollapsed(s);let f=this._orientation===`horizontal`,p=f?r.height:r.width,m=this.computeMainAxisSizes(s,a),h=new Set;for(let e=0;e<s.length;e+=1){let t=s[e],n=this.paneServingGutter(e,s);if((this._collapsed.get(t)??!1)&&n>=0){let e=this._gutters[n];e.setCollapseDirection(this.paneDirection(t)),e.setCollapsible(!0),this.placeGutterAsStrip(e,t,u,d,p,f,this.paneDirection(t)),h.add(n),f?u+=18:d+=18;continue}let r=m.get(t);if(t.setVisible(!0),this.placeComponent(t,u,d,f?r:p,f?p:r,i.BOTH),t.setClipPath(n>=0?`inset(0 0 0 0)`:null),f?u+=r:d+=r,e<l){let t=this._gutters[e],n=this.gutterTargetPane(e,s);!(n>=0&&(this._collapsed.get(s[n])??!1)&&this.paneServingGutter(n,s)===e)&&!h.has(e)&&(t.setOpaque(!1),t.setVisible(!0),t.setCollapsible(n>=0),n>=0&&t.setCollapseDirection(this.paneDirection(s[n])),t.setX(u),t.setY(d),f?(t.setWidth(w),t.setHeight(p),u+=w):(t.setWidth(p),t.setHeight(w),d+=w),h.add(e))}}for(let e=0;e<this._gutters.length;e+=1)h.has(e)||this._gutters[e].setVisible(!1)}placeGutterAsStrip(e,t,n,r,a,o,s){e.setOpaque(!0),e.setVisible(!0),e.setX(n),e.setY(r),o?(e.setWidth(18),e.setHeight(a)):(e.setWidth(a),e.setHeight(18));let c=this._sizes.get(t)??18,l=this.collapsesTowardStart(s);if(t.setVisible(!0),o){let e=l?n:n+18-c;this.placeComponent(t,e,r,c,a,i.BOTH)}else{let e=l?r:r+18-c;this.placeComponent(t,n,e,a,c,i.BOTH)}t.setClipPath(this.paneClipInset(s))}paneClipInset(e){switch(e){case`east`:return`inset(0 0 0 100%)`;case`north`:return`inset(0 0 100% 0)`;case`south`:return`inset(100% 0 0 0)`;default:return`inset(0 100% 0 0)`}}applyPendingSizes(){let e=this._pendingSizes;e!==null&&(this._pendingSizes=null,this.applyPaneSizes(e))}applyPendingCollapsed(e){if(this._pendingCollapsed.length!==0){for(let t of this._pendingCollapsed){let n=e[t];n&&this.paneServingGutter(t,e)>=0&&this._collapsed.set(n,!0)}this._pendingCollapsed=[]}}computeMainAxisSizes(e,t){let n=e.length-1,r=0,i=0,a=0;for(let t=0;t<e.length;t+=1){let o=e[t];(this._collapsed.get(o)??!1)&&this.paneServingGutter(t,e)>=0?(i+=1,!this.collapsesTowardStart(this.paneDirection(o))&&t<n&&(a+=1)):r+=this._sizes.get(o)??0}let o=Math.max(0,t-this.gutterTotal(e.length)),s=Math.max(0,o-i*(18-w)+a*w),c=r>0?s/r:0,l=new Map;for(let t=0;t<e.length;t+=1){let n=e[t],r=(this._collapsed.get(n)??!1)&&this.paneServingGutter(t,e)>=0;l.set(n,r?0:(this._sizes.get(n)??0)*c)}return l}recalculateSizes(){let e=this.getContainer();if(!e)return;let t=e.getInnerSize();if(!t)return;let n=e.getComponents();for(let e of[...this._sizes.keys()])n.indexOf(e)<0&&(this._sizes.delete(e),this._collapsed.delete(e));for(let e of[...this._weights.keys()])n.indexOf(e)<0&&this._weights.delete(e);let r=this._orientation===`horizontal`?t.width:t.height,i=Math.max(0,r-this.gutterTotal(n.length)),a=this._orientation===`horizontal`;this.seedFromPreferred(n,a);for(let e of n){let t=this._sizes.get(e);t!==void 0&&this._sizes.set(e,this.clampMain(e,t,a))}if(this._lastAvailableMain>0&&i>0&&i!==this._lastAvailableMain&&this._sizes.size>0){let e=i-this._lastAvailableMain,t=0;for(let e=0;e<n.length;e+=1){let r=n[e];t+=this.effectiveResizeWeight(r,this._sizes.get(r)??0)}if(t>0)for(let r=0;r<n.length;r+=1){let i=n[r],a=this._sizes.get(i);if(a!=null){let n=this.effectiveResizeWeight(i,a);this._sizes.set(i,Math.max(0,a+n/t*e))}}}if(this._lastAvailableMain===0&&i>0&&this._sizes.size>0){let e=0;for(let t=0;t<n.length;t+=1){let r=this.effectiveResizeWeight(n[t],0);r>0&&(e+=r)}if(e>0){let t=0;for(let e=0;e<n.length;e+=1)t+=this._sizes.get(n[e])??0;let r=i-t;for(let t=0;t<n.length;t+=1){let i=n[t],o=this.effectiveResizeWeight(i,0);if(o>0){let t=this._sizes.get(i)??0;this._sizes.set(i,this.clampMain(i,t+o/e*r,a))}}}}let o=0;for(let e=0;e<n.length;e+=1){let t=n[e];this._sizes.has(t)&&(o+=1)}for(let e=0;e<n.length;e+=1){let t=n[e],r=this._sizes.get(t);if(r==null){if(this._sizes.size!=0){r=0;for(let e=0;e<n.length;e+=1){let t=n[e],i=this._sizes.get(t);if(i==null)continue;let a=i*(1/(o+1));r+=a,i-=a,this._sizes.set(t,i)}}else r=i;this._sizes.set(t,r),o+=1}}let s=0,c=0,l=0;for(let e=0;e<n.length;e+=1){let t=n[e],r=this._sizes.get(t)??0;this.isPinnedMain(t,a)?s+=r:this.isResizePinnedMain(t)?c+=r:l+=r}if(i>0){let e=Math.max(0,i-s),t=1,r=1,o=1;l>0&&e>=c?o=(e-c)/l:c>0?(o=0,r=e/c):s>0&&(t=i/s);for(let e=0;e<n.length;e+=1){let i=n[e],s=this._sizes.get(i);if(s==null)continue;let c=this.isPinnedMain(i,a)?t:this.isResizePinnedMain(i)?r:o;c!==1&&this._sizes.set(i,s*c)}}i>0&&(this._lastAvailableMain=i)}},E=a(Split),D=.25,DropZoneHighlight=class extends s{_valid=!0;constructor(){super(),this.setPosition(r.ABSOLUTE),this.setPointerEvents(`none`),this.setBackgroundColor(`var(--ts-ui-drag-dropzone-active-bg)`),this.setVisible(!1)}placeBand(e,t,n,r){this.setX(e),this.setY(t),this.setWidth(n),this.setHeight(r),this.setVisible(!0)}setValid(e){this._valid!==e&&(this._valid=e,this.setBackgroundColor(e?`var(--ts-ui-drag-dropzone-active-bg)`:`var(--ts-ui-drag-dropzone-invalid-bg)`))}hide(){this.setVisible(!1)}},O=u.Band.Window-1,DropZoneOverlay=class extends s{_highlight=new DropZoneHighlight;_zone=null;_valid=!0;constructor(){super(),this.setPosition(r.ABSOLUTE),this.setZIndex(O),this.setPointerEvents(`none`),this.setBackgroundColor(`var(--ts-ui-drag-dropzone-bg)`),this.setBorder({border:`1px solid var(--ts-ui-drag-dropzone-border)`})}attachTo(t){let n=this.getElement(!0);this.setX(0),this.setY(0),this.setWidth(t.getWidth()),this.setHeight(t.getHeight());let r=t.getElement(!0);e.source.getParentElement(n)!==r&&e.sink.appendChild(r,n);let i=this._highlight.getElement(!0);e.source.getParentElement(i)!==n&&e.sink.appendChild(n,i)}setHighlight(e,t=!0){if(e===this._zone&&t===this._valid)return;if(this._zone=e,this._valid=t,e===null){this._highlight.hide();return}this._highlight.setValid(t);let n=this.getWidth(),r=this.getHeight(),i=D,a=0,o=0,s=n,c=r;switch(e){case`top`:a=0,o=0,s=n,c=r*i;break;case`bottom`:a=0,o=r*(1-i),s=n,c=r*i;break;case`left`:a=0,o=0,s=n*i,c=r;break;case`right`:a=n*(1-i),o=0,s=n*i,c=r;break;case`center`:a=n*i,o=r*i,s=n*(1-2*i),c=r*(1-2*i);break}this._highlight.placeBand(a,o,s,c)}highlightFull(){this._zone=null,this._valid=!0,this._highlight.setValid(!0),this._highlight.placeBand(0,0,this.getWidth(),this.getHeight())}detach(){this._zone=null,this._valid=!0,this.removeElement()}},k=a(DropZoneOverlay),DockRegion=class{_region;_overlay=new k;_teardown;_onStructureChanged;_raiseTimer=null;constructor(e,t){this._region=e,this._onStructureChanged=t??null,this._teardown=C.makeDropTarget(e,{accepts:e=>e.dragData.tabDrag===!0,suppressValidityTint:!0,onDragOver:e=>{let t=e.dragData.componentId,n=this.dropZone(e.clientX,e.clientY);return this._overlay.attachTo(this._region),this._overlay.setHighlight(n,this.isLegalDrop(t,n)),this.scheduleSpringRaise(),null},onDragLeave:()=>{this._overlay.detach(),this.clearSpringRaise()},onDrop:e=>{let t=e.dragData.componentId,n=this.dropZone(e.clientX,e.clientY);if(this._overlay.detach(),this.clearSpringRaise(),!this.isLegalDrop(t,n))return!1;let r=S.get(t);if(!r)return!1;n===`center`?this.dockAsTab(r):this.splitOnEdge(r,n),this.raiseHostWindow(),this._onStructureChanged?.()}})}destroy(){this._teardown(),this._overlay.detach(),this.clearSpringRaise()}hostWindow(){for(let e=this._region;e;e=e.getParentComponent())if(e instanceof d)return e;return null}raiseHostWindow(){this.hostWindow()?.bringToFront()}scheduleSpringRaise(){this._raiseTimer===null&&(this._raiseTimer=setTimeout(()=>{this._raiseTimer=null,C.isDragging()&&this.raiseHostWindow()},x))}clearSpringRaise(){this._raiseTimer!==null&&(clearTimeout(this._raiseTimer),this._raiseTimer=null)}dropZone(e,t){return this.isSeedRegion()?`center`:this.computeZone(e,t)}isSeedRegion(){return this._region.getComponents().every(e=>this._region.getLayoutConstraints(e)?.transient===!0)}computeZone(t,n){let r=e.source.getViewportRect(this._region),i=(t-r.left)/r.width,a=(n-r.top)/r.height,o=D,s=i,c=1-i,l=a,u=1-a,d=Math.min(s,c,l,u);return d>=o?`center`:d===s?`left`:d===c?`right`:d===l?`top`:`bottom`}isLegalDrop(e,t){for(let t=this._region;t;t=t.getParentComponent())if(t.getId()===e)return!1;let n=this._region.getComponents();return n.length===1&&n[0].getId()===e?!1:t===`center`?!this.isRedundantCenterDrop(e):!this.isRedundantEdgeDrop(e,t)}isRedundantCenterDrop(e){let t=S.get(e);if(!t)return!1;let n=t.getParentComponent();if(this._region.getLayoutManager()instanceof h)return n===this._region;let r=this._region.getParentComponent();return r?.getLayoutManager()instanceof h&&n===r}isRedundantEdgeDrop(e,t){let n=S.get(e);if(!n)return!1;let r=n.getParentComponent();if(!r||r.getComponents().length!==1)return!1;let i=t===`left`||t===`right`?`horizontal`:`vertical`,a=t===`top`||t===`left`,o=this._region.getLayoutManager();if(o instanceof E&&String(o.getOrientation())===i){if(r.getParentComponent()!==this._region)return!1;let e=this._region.getComponents();return a?e[0]===r:e[e.length-1]===r}let s=this._region.getParentComponent(),c=s?.getLayoutManager()instanceof h?s:this._region,l=c?.getParentComponent();if(!l)return!1;let u=l.getLayoutManager();if(!(u instanceof E&&String(u.getOrientation())===i)||r.getParentComponent()!==l)return!1;let d=l.getComponents(),f=d.indexOf(c),p=d.indexOf(r);return a?p===f-1:p===f+1}splitOnEdge(e,t){let n=t===`left`||t===`right`?`horizontal`:`vertical`,r=t===`top`||t===`left`,i=this.newStack();i.moveComponent(e);let a=this._region.getLayoutManager();if(a instanceof E&&String(a.getOrientation())===n){this._region.moveComponent(i,r?0:this._region.getComponents().length);return}let o=this._region.getParentComponent(),s=o?.getLayoutManager()instanceof h?o:this._region,c=s.getParentComponent();if(!c)return;let u=c.getLayoutManager(),d=c.getComponents().indexOf(s);if(u instanceof E&&String(u.getOrientation())===n){c.moveComponent(i,r?d:d+1);return}let f=new l({layoutManager:new E({orientation:n})});c.moveComponent(f,d);let p=this.ensureStacked(s);f.moveComponent(i,+!r),f.moveComponent(p,+!!r),u instanceof E&&u.transferPaneSize(s,f)}ensureStacked(e){let t=e.getLayoutManager();if(t instanceof h||t instanceof E)return e;let n=this.newStack();return n.moveComponent(e),n}newStack(){let e=new l({layoutManager:new h({reorderable:!0,compact:!0})});return e.getLayoutManager().on(`empty`,()=>this.pruneEmptyStack(e)),e}pruneEmptyStack(e){let t=e.getParentComponent();t&&t.getLayoutManager()instanceof E&&(t.removeComponent(e),this.collapseIfSinglePaneSplit(t))}collapseIfSinglePaneSplit(e){if(!(e.getLayoutManager()instanceof E))return;let t=e.getComponents();if(t.length!==1)return;let n=e.getParentComponent();if(!n)return;let r=n.getComponents().indexOf(e),i=n.getLayoutManager();i instanceof E&&i.transferPaneSize(e,t[0]),n.moveComponent(t[0],r),n.removeComponent(e)}dockAsTab(e){if(this._region.getLayoutManager()instanceof h){this._region.moveComponent(e),this._region.scheduleLayout();return}let t=this._region.getParentComponent();if(!t)return;if(t.getLayoutManager()instanceof h){t.moveComponent(e),t.scheduleLayout();return}let n=t.getComponents().indexOf(this._region),r=this.newStack();t.moveComponent(r,n),r.moveComponent(this._region),r.moveComponent(e),r.scheduleLayout()}};function managerKind(e){let t=e.getLayoutManager();return t?t.getClassName().replace(/^_/,``):``}function panelIdOf(e){return e.getId()}function serializableChildren(e){return e.getComponents().filter(t=>e.getLayoutConstraints(t)?.transient!==!0)}function nodeFor(e){let t=managerKind(e);if(t===`Split`){let t=e.getLayoutManager(),n=e.getComponents().map(nodeFor);return{kind:`split`,orientation:t.getOrientation()===`vertical`?`vertical`:`horizontal`,children:n,ratios:t.getPaneRatios(),collapsed:n.map((e,n)=>t.isPaneCollapsed(n))}}if(t===`Tab`){let t=e.getLayoutManager();return{kind:`tab`,children:serializableChildren(e).map(nodeFor),activeIndex:t.getActiveTabIndex()}}let n=e.getParentComponent()?.getLayoutConstraints(e)?.glyph??null;return{kind:`panel`,panelId:panelIdOf(e),glyph:n}}function windowContentOf(e){return e.getComponents().find(t=>!e.isChromeComponent(t))??null}function windowNodeFor(e){let t=windowContentOf(e);return t?{kind:`window`,content:nodeFor(t),header:e.getTitle(),rect:e.getRect(),state:e.getWindowState(),restoreRect:e.getRestoreRect()}:null}function serializeLayout(e){let t=p.getOpenWindows().map(windowNodeFor).filter(e=>e!==null);return{version:1,root:nodeFor(e),windows:t}}function collectLeaves(e,t){serializableChildren(e).forEach(e=>{let n=managerKind(e);n===`Split`||n===`Tab`?collectLeaves(e,t):t.push(e)})}function parkLeaves(e,t,n){let r=[];collectLeaves(e,r),t.forEach(e=>{let t=windowContentOf(e);if(!t)return;let n=managerKind(t);n===`Split`||n===`Tab`?collectLeaves(t,r):r.push(t)});let i=new Map;return r.forEach(e=>{let t=panelIdOf(e);n(t)===e&&(i.set(t,e),e.getParentComponent()?.removeComponent(e))}),i}function hostsComponent(e,t){for(let n=t;n;n=n.getParentComponent())if(n===e)return!0;return!1}function constraintsFor(e){if(e.kind!==`panel`||!e.glyph)return;let t=new b;return t.glyph=e.glyph,t}function materializeNode(e,t,n){if(e.kind===`panel`){let r=t.get(e.panelId)??n(e.panelId);return r||console.warn(`restoreLayout: no component for panelId "${e.panelId}"; skipping.`),r}let r=new s;return populateContainer(r,e,t,n),r}function populateContainer(e,t,n,r){if(t.kind===`split`){let i=new E({orientation:t.orientation});e.setLayoutManager(i);let a=[];t.children.forEach((i,o)=>{let s=materializeNode(i,n,r);s&&(e.moveComponent(s,void 0,constraintsFor(i)),a.push({ratio:t.ratios[o]??0,collapsed:t.collapsed[o]??!1}))}),i.applyPaneRatios(a.map(e=>e.ratio)),a.forEach((e,t)=>{e.collapsed&&i.setPaneCollapsedImmediate(t,!0)})}else{let i=new h({reorderable:!0,compact:!0});e.setLayoutManager(i),t.children.forEach(t=>{let a=materializeNode(t,n,r);a&&(e.moveComponent(a,void 0,constraintsFor(t)),i.createTab(a))}),i.setActiveTabIndex(t.activeIndex)}}function applyWindow(e,t,n){let r=e.content??(e.panelId?{kind:`panel`,panelId:e.panelId,glyph:null}:null);if(!r){console.warn(`restoreLayout: window node has neither content nor panelId; skipping.`);return}let i=materializeNode(r,t,n);if(!i)return;let a=new p(e.header);a.moveComponent(i,void 0,constraintsFor(r));let o=e.state===`normal`?e.rect:e.restoreRect??e.rect;a.applyRect(o),a.show(),e.state!==`normal`&&a.setWindowState(e.state)}function restoreLayout(e,t,n){let r=p.getOpenWindows().filter(t=>!hostsComponent(t,e)),i=parkLeaves(e,r,n);if(r.forEach(e=>e.onExitAction()),e.removeAllComponents(),t.root.kind===`panel`){let r=materializeNode(t.root,i,n);r&&e.moveComponent(r,void 0,constraintsFor(t.root))}else populateContainer(e,t.root,i,n);t.windows.forEach(e=>applyWindow(e,i,n))}export{E as a,k as i,serializeLayout as n,DockRegion as r,restoreLayout as t};
2
- //# sourceMappingURL=LayoutSerialization-C_zcwaN3.js.map