@zaly/tui 0.0.12 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. package/assets/schemas/shiki-language.schema.json +352 -0
  2. package/assets/schemas/shiki-theme.schema.json +71 -0
  3. package/assets/schemas/theme.schema.json +226 -1046
  4. package/assets/themes/andromeeda.json +97 -0
  5. package/assets/themes/ayu-dark.json +31 -25
  6. package/assets/themes/ayu-light.json +106 -0
  7. package/assets/themes/ayu-mirage.json +106 -0
  8. package/assets/themes/catppuccin-frappe.json +43 -40
  9. package/assets/themes/catppuccin-latte.json +43 -40
  10. package/assets/themes/catppuccin-macchiato.json +43 -40
  11. package/assets/themes/catppuccin-mocha.json +43 -40
  12. package/assets/themes/dark-plus.json +99 -0
  13. package/assets/themes/dracula.json +47 -47
  14. package/assets/themes/everforest-dark.json +28 -26
  15. package/assets/themes/everforest-light.json +28 -26
  16. package/assets/themes/github-dark-default.json +107 -0
  17. package/assets/themes/github-dark-dimmed.json +107 -0
  18. package/assets/themes/github-light-default.json +107 -0
  19. package/assets/themes/gruvbox-dark-hard.json +98 -0
  20. package/assets/themes/gruvbox-dark-medium.json +34 -29
  21. package/assets/themes/gruvbox-light-medium.json +98 -0
  22. package/assets/themes/horizon-bright.json +101 -0
  23. package/assets/themes/horizon.json +101 -0
  24. package/assets/themes/iterm2/LICENSE +25 -0
  25. package/assets/themes/iterm2/README.md +28 -0
  26. package/assets/themes/iterm2/catppuccin-latte.json +140 -0
  27. package/assets/themes/iterm2/catppuccin-mocha.json +140 -0
  28. package/assets/themes/iterm2/github-dark.json +140 -0
  29. package/assets/themes/iterm2/github.json +140 -0
  30. package/assets/themes/iterm2/gruvbox-dark.json +140 -0
  31. package/assets/themes/iterm2/gruvbox-light.json +140 -0
  32. package/assets/themes/iterm2/nord.json +140 -0
  33. package/assets/themes/iterm2/tokyonight-day.json +140 -0
  34. package/assets/themes/iterm2/tokyonight-moon.json +140 -0
  35. package/assets/themes/kanagawa-dragon.json +55 -49
  36. package/assets/themes/kanagawa-lotus.json +105 -0
  37. package/assets/themes/kanagawa-wave.json +56 -50
  38. package/assets/themes/light-plus.json +99 -0
  39. package/assets/themes/material-theme-lighter.json +102 -0
  40. package/assets/themes/material-theme-palenight.json +52 -45
  41. package/assets/themes/material-theme.json +102 -0
  42. package/assets/themes/min-dark.json +69 -14
  43. package/assets/themes/min-light.json +68 -17
  44. package/assets/themes/monokai.json +54 -47
  45. package/assets/themes/night-owl-light.json +105 -0
  46. package/assets/themes/night-owl.json +57 -49
  47. package/assets/themes/nord.json +53 -39
  48. package/assets/themes/one-dark-pro.json +46 -38
  49. package/assets/themes/one-light.json +52 -41
  50. package/assets/themes/poimandres.json +51 -49
  51. package/assets/themes/rose-pine-dawn.json +99 -0
  52. package/assets/themes/rose-pine-moon.json +99 -0
  53. package/assets/themes/rose-pine.json +50 -33
  54. package/assets/themes/solarized-dark.json +38 -31
  55. package/assets/themes/solarized-light.json +40 -33
  56. package/assets/themes/synthwave-84.json +47 -30
  57. package/assets/themes/tokyonight-day.json +3 -3
  58. package/assets/themes/tokyonight-moon.json +3 -2
  59. package/assets/themes/tokyonight-night.json +3 -2
  60. package/assets/themes/tokyonight-storm.json +3 -2
  61. package/assets/themes/vesper.json +50 -42
  62. package/assets/themes/vitesse-black.json +103 -0
  63. package/assets/themes/vitesse-dark.json +26 -30
  64. package/assets/themes/vitesse-light.json +26 -30
  65. package/dist/{actions-DEIKF2ts.mjs → actions-AY6avfEV.mjs} +2 -3
  66. package/dist/{actions-DEIKF2ts.mjs.map → actions-AY6avfEV.mjs.map} +1 -1
  67. package/dist/{actions-Dc4D4uSf.d.mts → actions-B0yyZ-Ww.d.mts} +4 -6
  68. package/dist/actions-B0yyZ-Ww.d.mts.map +1 -0
  69. package/dist/{ansi-DZlXaItJ.mjs → ansi-CxgRPLA2.mjs} +4 -33
  70. package/dist/ansi-CxgRPLA2.mjs.map +1 -0
  71. package/dist/ansi.d.mts +1 -3
  72. package/dist/ansi.d.mts.map +1 -1
  73. package/dist/ansi.mjs +1 -1
  74. package/dist/{autocomplete-StW1QJZJ.d.mts → autocomplete-wgceuhLr.d.mts} +5 -7
  75. package/dist/autocomplete-wgceuhLr.d.mts.map +1 -0
  76. package/dist/{box-BkP4MF82.mjs → box-DToDoXlU.mjs} +8 -10
  77. package/dist/{box-BkP4MF82.mjs.map → box-DToDoXlU.mjs.map} +1 -1
  78. package/dist/builder-BdYlK1Ew.mjs +195 -0
  79. package/dist/builder-BdYlK1Ew.mjs.map +1 -0
  80. package/dist/{callbacks-BwWTCqPJ.mjs → callbacks-DW8XKYKy.mjs} +9 -13
  81. package/dist/{callbacks-BwWTCqPJ.mjs.map → callbacks-DW8XKYKy.mjs.map} +1 -1
  82. package/dist/{client-C2GXKfJ1.mjs → client-BWm6dNZF.mjs} +9 -6
  83. package/dist/client-BWm6dNZF.mjs.map +1 -0
  84. package/dist/client-C69qWhMG.mjs +1 -0
  85. package/dist/{clipboard-CNPBTX7j.mjs → clipboard-UEoX9sup.mjs} +2 -3
  86. package/dist/{clipboard-CNPBTX7j.mjs.map → clipboard-UEoX9sup.mjs.map} +1 -1
  87. package/dist/clipboard.d.mts +0 -2
  88. package/dist/clipboard.d.mts.map +1 -1
  89. package/dist/clipboard.mjs +1 -1
  90. package/dist/color-Cr1VoL49.mjs +36 -0
  91. package/dist/color-Cr1VoL49.mjs.map +1 -0
  92. package/dist/ctx-CYEzzH-7.mjs +1 -0
  93. package/dist/{ctx-B7BmPUCD.mjs → ctx-DBeFcZt6.mjs} +4 -5
  94. package/dist/{ctx-B7BmPUCD.mjs.map → ctx-DBeFcZt6.mjs.map} +1 -1
  95. package/dist/{divider-TSx9NhI_.mjs → divider-qEj5prKE.mjs} +3 -4
  96. package/dist/{divider-TSx9NhI_.mjs.map → divider-qEj5prKE.mjs.map} +1 -1
  97. package/dist/{files-BvThQpOf.mjs → files-C3ZnFpvq.mjs} +3 -4
  98. package/dist/{files-BvThQpOf.mjs.map → files-C3ZnFpvq.mjs.map} +1 -1
  99. package/dist/{files-7DUYSeNc.d.mts → files-CdiDnwA_.d.mts} +3 -5
  100. package/dist/files-CdiDnwA_.d.mts.map +1 -0
  101. package/dist/{flex-Bguo-fUe.mjs → flex-CYp4etqn.mjs} +3 -4
  102. package/dist/{flex-Bguo-fUe.mjs.map → flex-CYp4etqn.mjs.map} +1 -1
  103. package/dist/{github-Cy2hfWJ7.mjs → github-CLveT9mq.mjs} +2 -3
  104. package/dist/{github-Cy2hfWJ7.mjs.map → github-CLveT9mq.mjs.map} +1 -1
  105. package/dist/{github-C1KfXk98.d.mts → github-DC0XemKa.d.mts} +3 -5
  106. package/dist/github-DC0XemKa.d.mts.map +1 -0
  107. package/dist/{image-VaT7AN-S.d.mts → image-DdRDv7q6.d.mts} +2 -4
  108. package/dist/image-DdRDv7q6.d.mts.map +1 -0
  109. package/dist/image-M--Bw4bs.mjs +177 -0
  110. package/dist/image-M--Bw4bs.mjs.map +1 -0
  111. package/dist/image.d.mts +1 -3
  112. package/dist/image.d.mts.map +1 -1
  113. package/dist/image.mjs +1 -1
  114. package/dist/index.d.mts +11 -14
  115. package/dist/index.d.mts.map +1 -1
  116. package/dist/index.mjs +12 -14
  117. package/dist/index.mjs.map +1 -1
  118. package/dist/{input-BGTTujDN.mjs → input-BkE4EpBw.mjs} +6 -7
  119. package/dist/{input-BGTTujDN.mjs.map → input-BkE4EpBw.mjs.map} +1 -1
  120. package/dist/{input-BAYux7qo.d.mts → input-C3kfYoEJ.d.mts} +3 -5
  121. package/dist/input-C3kfYoEJ.d.mts.map +1 -0
  122. package/dist/{inspect-jG_W4njH.mjs → inspect-Cli1beu8.mjs} +3 -4
  123. package/dist/{inspect-jG_W4njH.mjs.map → inspect-Cli1beu8.mjs.map} +1 -1
  124. package/dist/{inspect-CfNydMgO.d.mts → inspect-hSl3U2BD.d.mts} +2 -6
  125. package/dist/inspect-hSl3U2BD.d.mts.map +1 -0
  126. package/dist/kitty-0sJ8axU_.mjs +1 -0
  127. package/dist/{kitty-JbCJC0iQ.mjs → kitty-BH_eK6lz.mjs} +2 -3
  128. package/dist/{kitty-JbCJC0iQ.mjs.map → kitty-BH_eK6lz.mjs.map} +1 -1
  129. package/dist/{log-ByKlM4iI.mjs → log-96b1_J6G.mjs} +6 -7
  130. package/dist/{log-ByKlM4iI.mjs.map → log-96b1_J6G.mjs.map} +1 -1
  131. package/dist/{logger-DSQb0sLP.mjs → logger-DwfXp8LF.mjs} +5 -6
  132. package/dist/{logger-DSQb0sLP.mjs.map → logger-DwfXp8LF.mjs.map} +1 -1
  133. package/dist/{markdown-CwRmWuU6.mjs → markdown-CgRZBhIX.mjs} +12 -12
  134. package/dist/markdown-CgRZBhIX.mjs.map +1 -0
  135. package/dist/markdown.d.mts +2 -4
  136. package/dist/markdown.d.mts.map +1 -1
  137. package/dist/markdown.mjs +1 -1
  138. package/dist/math-Dk8hxbmz.mjs +1 -0
  139. package/dist/math-VPuwFCid.mjs +205 -0
  140. package/dist/math-VPuwFCid.mjs.map +1 -0
  141. package/dist/md.bun.d.mts +1 -3
  142. package/dist/md.bun.d.mts.map +1 -1
  143. package/dist/md.bun.mjs +2 -3
  144. package/dist/md.node.d.mts +1 -3
  145. package/dist/md.node.d.mts.map +1 -1
  146. package/dist/md.node.mjs +2 -3
  147. package/dist/{node-BZ7f6HzU.mjs → node-CXNobGaP.mjs} +3 -4
  148. package/dist/{node-BZ7f6HzU.mjs.map → node-CXNobGaP.mjs.map} +1 -1
  149. package/dist/oklch-Boh4YHEc.mjs +98 -0
  150. package/dist/oklch-Boh4YHEc.mjs.map +1 -0
  151. package/dist/{overlay-BnvOKtGT.mjs → overlay-CevDWgSF.mjs} +3 -4
  152. package/dist/{overlay-BnvOKtGT.mjs.map → overlay-CevDWgSF.mjs.map} +1 -1
  153. package/dist/{picker-Dh5IUrTk.mjs → picker-D9WrE3zF.mjs} +11 -16
  154. package/dist/{picker-Dh5IUrTk.mjs.map → picker-D9WrE3zF.mjs.map} +1 -1
  155. package/dist/{picker-DQs_IW77.d.mts → picker-DsB6--GN.d.mts} +6 -8
  156. package/dist/picker-DsB6--GN.d.mts.map +1 -0
  157. package/dist/{queries-B_lOwEiE.mjs → queries-BIniKnLL.mjs} +68 -7
  158. package/dist/queries-BIniKnLL.mjs.map +1 -0
  159. package/dist/{queries-BDX8mcl5.d.mts → queries-Dmd3IjSd.d.mts} +19 -52
  160. package/dist/queries-Dmd3IjSd.d.mts.map +1 -0
  161. package/dist/{reactive-f7NpAi69.mjs → reactive-DkP75TPk.mjs} +2 -3
  162. package/dist/{reactive-f7NpAi69.mjs.map → reactive-DkP75TPk.mjs.map} +1 -1
  163. package/dist/{registry-D-suU3g0.mjs → registry-CQU0VwpM.mjs} +205 -65
  164. package/dist/registry-CQU0VwpM.mjs.map +1 -0
  165. package/dist/{render-DEIUNLkh.mjs → render-Bp2N2i6J.mjs} +4 -5
  166. package/dist/{render-DEIUNLkh.mjs.map → render-Bp2N2i6J.mjs.map} +1 -1
  167. package/dist/{renderer-zDNlAovy.mjs → renderer-B9sAMA10.mjs} +123 -40
  168. package/dist/renderer-B9sAMA10.mjs.map +1 -0
  169. package/dist/{renderer-MQue4Da5.mjs → renderer-BYl2pbdx.mjs} +9 -9
  170. package/dist/renderer-BYl2pbdx.mjs.map +1 -0
  171. package/dist/renderer-Ctz0hv5o.mjs +1 -0
  172. package/dist/{search-FvGnswRl.d.mts → search-DsHzamic.d.mts} +1 -9
  173. package/dist/search-DsHzamic.d.mts.map +1 -0
  174. package/dist/{select-J2KtwxyK.d.mts → select-BZCFXdjp.d.mts} +3 -5
  175. package/dist/select-BZCFXdjp.d.mts.map +1 -0
  176. package/dist/{select-m7NE6Rwa.mjs → select-CUmAFKJh.mjs} +5 -6
  177. package/dist/{select-m7NE6Rwa.mjs.map → select-CUmAFKJh.mjs.map} +1 -1
  178. package/dist/services/logger.d.mts +1 -1
  179. package/dist/services/logger.mjs +1 -1
  180. package/dist/services/notifier.d.mts +1 -3
  181. package/dist/services/notifier.d.mts.map +1 -1
  182. package/dist/services/notifier.mjs +3 -4
  183. package/dist/services/picker.d.mts +5 -7
  184. package/dist/services/picker.d.mts.map +1 -1
  185. package/dist/services/picker.mjs +8 -9
  186. package/dist/services/prompt.d.mts +4 -6
  187. package/dist/services/prompt.d.mts.map +1 -1
  188. package/dist/services/prompt.mjs +7 -8
  189. package/dist/shiki/server.mjs +40 -19
  190. package/dist/shiki/server.mjs.map +1 -1
  191. package/dist/shiki-BAf9PdIc.mjs +19 -0
  192. package/dist/shiki-BAf9PdIc.mjs.map +1 -0
  193. package/dist/shiki-DUUAIE6f.mjs +632 -0
  194. package/dist/shiki-DUUAIE6f.mjs.map +1 -0
  195. package/dist/{show-DR2x1YFc.mjs → show-D5XNXgZf.mjs} +4 -5
  196. package/dist/{show-DR2x1YFc.mjs.map → show-D5XNXgZf.mjs.map} +1 -1
  197. package/dist/{size-D8JogYLy.mjs → size-BHRJuRk9.mjs} +2 -3
  198. package/dist/{size-D8JogYLy.mjs.map → size-BHRJuRk9.mjs.map} +1 -1
  199. package/dist/style-Cw_EuszU.mjs +108 -0
  200. package/dist/style-Cw_EuszU.mjs.map +1 -0
  201. package/dist/style.d.mts +4 -5
  202. package/dist/style.d.mts.map +1 -1
  203. package/dist/style.mjs +4 -4
  204. package/dist/{text-CkQ7Irmt.mjs → text-4arC3odI.mjs} +3 -4
  205. package/dist/{text-CkQ7Irmt.mjs.map → text-4arC3odI.mjs.map} +1 -1
  206. package/dist/{text-XvPfweeg.mjs → text-BArwVVkg.mjs} +5 -6
  207. package/dist/{text-XvPfweeg.mjs.map → text-BArwVVkg.mjs.map} +1 -1
  208. package/dist/{text-CCYs9RB2.d.mts → text-DdkJXgoC.d.mts} +3 -5
  209. package/dist/text-DdkJXgoC.d.mts.map +1 -0
  210. package/dist/text.d.mts +1 -1
  211. package/dist/text.mjs +1 -1
  212. package/dist/theme-B8hb1lPU.mjs +60 -0
  213. package/dist/theme-B8hb1lPU.mjs.map +1 -0
  214. package/dist/theme-BeSaXGNY.mjs +1792 -0
  215. package/dist/theme-BeSaXGNY.mjs.map +1 -0
  216. package/dist/themes.d.mts +211 -77
  217. package/dist/themes.d.mts.map +1 -1
  218. package/dist/themes.mjs +1 -1
  219. package/dist/{tree-DJl5W_B7.d.mts → tree-Berzv8Rz.d.mts} +3 -5
  220. package/dist/tree-Berzv8Rz.d.mts.map +1 -0
  221. package/dist/{tree-Bo1afYhe.mjs → tree-D6NvMQx8.mjs} +5 -6
  222. package/dist/{tree-Bo1afYhe.mjs.map → tree-D6NvMQx8.mjs.map} +1 -1
  223. package/dist/{types-D2EYlzmK.d.mts → types-ByMHEdCF.d.mts} +133 -131
  224. package/dist/types-ByMHEdCF.d.mts.map +1 -0
  225. package/dist/{types-D3jk1rtk.d.mts → types-CUVUJPz6.d.mts} +1 -3
  226. package/dist/types-CUVUJPz6.d.mts.map +1 -0
  227. package/dist/{utils-3M4D_AXZ.mjs → utils-DHXAegVW.mjs} +1 -2
  228. package/dist/{utils-3M4D_AXZ.mjs.map → utils-DHXAegVW.mjs.map} +1 -1
  229. package/dist/{widget-BkMwhY2p.mjs → widget-sFveyrZE.mjs} +3 -4
  230. package/dist/{widget-BkMwhY2p.mjs.map → widget-sFveyrZE.mjs.map} +1 -1
  231. package/dist/{widget-DPqBbB57.d.mts → widget-sPJaKVU2.d.mts} +2 -4
  232. package/dist/widget-sPJaKVU2.d.mts.map +1 -0
  233. package/dist/widgets/autocomplete.d.mts +1 -1
  234. package/dist/widgets/autocomplete.mjs +5 -6
  235. package/dist/widgets/box.d.mts +1 -1
  236. package/dist/widgets/box.mjs +1 -1
  237. package/dist/widgets/code.d.mts +4 -4
  238. package/dist/widgets/code.d.mts.map +1 -1
  239. package/dist/widgets/code.mjs +12 -12
  240. package/dist/widgets/code.mjs.map +1 -1
  241. package/dist/widgets/completions/actions.d.mts +1 -1
  242. package/dist/widgets/completions/actions.mjs +1 -1
  243. package/dist/widgets/completions/files.d.mts +1 -1
  244. package/dist/widgets/completions/files.mjs +1 -1
  245. package/dist/widgets/completions/github.d.mts +1 -1
  246. package/dist/widgets/completions/github.mjs +1 -1
  247. package/dist/widgets/completions/index.d.mts +3 -3
  248. package/dist/widgets/completions/index.mjs +3 -3
  249. package/dist/widgets/diff.d.mts +2 -4
  250. package/dist/widgets/diff.d.mts.map +1 -1
  251. package/dist/widgets/diff.mjs +38 -16
  252. package/dist/widgets/diff.mjs.map +1 -1
  253. package/dist/widgets/divider.d.mts +2 -4
  254. package/dist/widgets/divider.d.mts.map +1 -1
  255. package/dist/widgets/divider.mjs +1 -1
  256. package/dist/widgets/image.d.mts +1 -1
  257. package/dist/widgets/image.mjs +8 -9
  258. package/dist/widgets/image.mjs.map +1 -1
  259. package/dist/widgets/input.d.mts +1 -1
  260. package/dist/widgets/input.mjs +1 -1
  261. package/dist/widgets/log.d.mts +1 -1
  262. package/dist/widgets/log.mjs +1 -1
  263. package/dist/widgets/markdown.d.mts +5 -7
  264. package/dist/widgets/markdown.d.mts.map +1 -1
  265. package/dist/widgets/markdown.mjs +1 -1
  266. package/dist/widgets/overlay.d.mts +1 -1
  267. package/dist/widgets/overlay.mjs +1 -1
  268. package/dist/widgets/picker.d.mts +1 -1
  269. package/dist/widgets/picker.mjs +1 -1
  270. package/dist/widgets/progress.d.mts +2 -4
  271. package/dist/widgets/progress.d.mts.map +1 -1
  272. package/dist/widgets/progress.mjs +4 -5
  273. package/dist/widgets/select.d.mts +1 -1
  274. package/dist/widgets/select.mjs +1 -1
  275. package/dist/widgets/show.d.mts +1 -3
  276. package/dist/widgets/show.d.mts.map +1 -1
  277. package/dist/widgets/show.mjs +1 -1
  278. package/dist/widgets/spinner.d.mts +2 -4
  279. package/dist/widgets/spinner.d.mts.map +1 -1
  280. package/dist/widgets/spinner.mjs +3 -4
  281. package/dist/widgets/text.d.mts +1 -1
  282. package/dist/widgets/text.mjs +1 -1
  283. package/dist/widgets/tree.d.mts +1 -1
  284. package/dist/widgets/tree.mjs +1 -1
  285. package/dist/widgets/widget.d.mts +1 -1
  286. package/dist/widgets/widget.mjs +1 -1
  287. package/dist/{worker-T6SdPzUH.mjs → worker-CtEowucz.mjs} +2 -3
  288. package/dist/{worker-T6SdPzUH.mjs.map → worker-CtEowucz.mjs.map} +1 -1
  289. package/dist/worker-Mqi380Et.mjs +1 -0
  290. package/package.json +5 -7
  291. package/assets/themes/dracula-soft.json +0 -100
  292. package/assets/themes/github-dark.json +0 -104
  293. package/assets/themes/github-light.json +0 -104
  294. package/dist/actions-Dc4D4uSf.d.mts.map +0 -1
  295. package/dist/ansi-DZlXaItJ.mjs.map +0 -1
  296. package/dist/autocomplete-StW1QJZJ.d.mts.map +0 -1
  297. package/dist/builder-1z5ewEWK.mjs +0 -386
  298. package/dist/builder-1z5ewEWK.mjs.map +0 -1
  299. package/dist/client-C2GXKfJ1.mjs.map +0 -1
  300. package/dist/client-bzdHIDL2.mjs +0 -1
  301. package/dist/ctx-D_JgJ8Eo.mjs +0 -1
  302. package/dist/files-7DUYSeNc.d.mts.map +0 -1
  303. package/dist/github-C1KfXk98.d.mts.map +0 -1
  304. package/dist/image-Cm5T-uw-.mjs +0 -108
  305. package/dist/image-Cm5T-uw-.mjs.map +0 -1
  306. package/dist/image-VaT7AN-S.d.mts.map +0 -1
  307. package/dist/input-BAYux7qo.d.mts.map +0 -1
  308. package/dist/inspect-CfNydMgO.d.mts.map +0 -1
  309. package/dist/markdown-CwRmWuU6.mjs.map +0 -1
  310. package/dist/picker-DQs_IW77.d.mts.map +0 -1
  311. package/dist/queries-BDX8mcl5.d.mts.map +0 -1
  312. package/dist/queries-B_lOwEiE.mjs.map +0 -1
  313. package/dist/registry-D-suU3g0.mjs.map +0 -1
  314. package/dist/renderer-DhqbEVVR.mjs +0 -1
  315. package/dist/renderer-MQue4Da5.mjs.map +0 -1
  316. package/dist/renderer-zDNlAovy.mjs.map +0 -1
  317. package/dist/search-FvGnswRl.d.mts.map +0 -1
  318. package/dist/select-J2KtwxyK.d.mts.map +0 -1
  319. package/dist/shiki--ASSYv4_.mjs +0 -12
  320. package/dist/shiki--ASSYv4_.mjs.map +0 -1
  321. package/dist/shiki-D7l5--zz.mjs +0 -432
  322. package/dist/shiki-D7l5--zz.mjs.map +0 -1
  323. package/dist/text-CCYs9RB2.d.mts.map +0 -1
  324. package/dist/theme.config-B3Yx--C2.mjs +0 -855
  325. package/dist/theme.config-B3Yx--C2.mjs.map +0 -1
  326. package/dist/tree-DJl5W_B7.d.mts.map +0 -1
  327. package/dist/types-D2EYlzmK.d.mts.map +0 -1
  328. package/dist/types-D3jk1rtk.d.mts.map +0 -1
  329. package/dist/widget-DPqBbB57.d.mts.map +0 -1
  330. package/dist/worker-C01jK2Ip.mjs +0 -1
@@ -1,4 +1,4 @@
1
- import { n as ActionsSourceOptions, r as actionsSource, t as ActionCompletionItem } from "../../actions-Dc4D4uSf.mjs";
2
- import { n as filesSource, t as FilesSourceOptions } from "../../files-7DUYSeNc.mjs";
3
- import { a as githubSource, i as GithubState, n as GithubItem, r as GithubSourceOptions, t as GithubFetcher } from "../../github-C1KfXk98.mjs";
1
+ import { n as ActionsSourceOptions, r as actionsSource, t as ActionCompletionItem } from "../../actions-B0yyZ-Ww.mjs";
2
+ import { n as filesSource, t as FilesSourceOptions } from "../../files-CdiDnwA_.mjs";
3
+ import { a as githubSource, i as GithubState, n as GithubItem, r as GithubSourceOptions, t as GithubFetcher } from "../../github-DC0XemKa.mjs";
4
4
  export { ActionCompletionItem, ActionsSourceOptions, FilesSourceOptions, GithubFetcher, GithubItem, GithubSourceOptions, GithubState, actionsSource, filesSource, githubSource };
@@ -1,4 +1,4 @@
1
- import { t as actionsSource } from "../../actions-DEIKF2ts.mjs";
2
- import { t as filesSource } from "../../files-BvThQpOf.mjs";
3
- import { t as githubSource } from "../../github-Cy2hfWJ7.mjs";
1
+ import { t as actionsSource } from "../../actions-AY6avfEV.mjs";
2
+ import { t as filesSource } from "../../files-C3ZnFpvq.mjs";
3
+ import { t as githubSource } from "../../github-CLveT9mq.mjs";
4
4
  export { actionsSource, filesSource, githubSource };
@@ -1,6 +1,5 @@
1
- import { J as Layout, P as RenderCtx, X as State, nt as Reactive, p as Node } from "../queries-BDX8mcl5.mjs";
2
- import { t as WrapMode } from "../text-CCYs9RB2.mjs";
3
- //#region src/widgets/diff.d.ts
1
+ import { I as RenderCtx, Q as State, X as Layout, h as Node, it as Reactive } from "../queries-Dmd3IjSd.mjs";
2
+ import { t as WrapMode } from "../text-DdkJXgoC.mjs";
4
3
  export interface DiffState {
5
4
  /** Pre-state file content. Plain string or reactive accessor —
6
5
  * pass a signal to live-update the diff as either side changes. */
@@ -52,5 +51,4 @@ export declare class Diff extends Node<DiffState> {
52
51
  * ```
53
52
  */
54
53
  export declare function diff(state: State<DiffState>): Diff;
55
- //#endregion
56
54
  //# sourceMappingURL=diff.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"diff.d.mts","names":[],"sources":["../../src/widgets/diff.ts"],"mappings":";;;iBAeiB;;;EAGf,UAAU;;;EAGV,UAAU;;;;EAIV,OAAO;;;EAGP;;EAEA;EACA,OAAO;;;;;;;;;;;;;qBAuBI,aAAa,KAAK;;EAI7B,YAAY,OAAO;MA+Bf;IAAW;IAAkB;;YAOjB,QAAQ,KAAK,YAAY;EAmBhC,UAAU;;;;;;;;;;;;;wBA4BL,KAAK,OAAO,MAAM,aAAa"}
1
+ {"version":3,"file":"diff.d.mts","names":[],"sources":["../../src/widgets/diff.ts"],"mappings":";;iBAgBiB;;;EAGf,UAAU;;;EAGV,UAAU;;;;EAIV,OAAO;;;EAGP;;EAEA;EACA,OAAO;;;;;;;;;;;;;qBA2BI,aAAa,KAAK;;EAI7B,YAAY,OAAO;MA+Bf;IAAW;IAAkB;;YAOjB,QAAQ,KAAK,YAAY;EAqBhC,UAAU;;;;;;;;;;;;;wBA+BL,KAAK,OAAO,MAAM,aAAa"}
@@ -1,11 +1,13 @@
1
- import { S as unwrap, h as memo, r as createAsync, w as useContext } from "../reactive-f7NpAi69.mjs";
2
- import { t as Node } from "../node-BZ7f6HzU.mjs";
3
- import { r as countLines, t as calcLayout } from "../text-CkQ7Irmt.mjs";
4
- import { t as RenderContext } from "../render-DEIUNLkh.mjs";
5
- import { t as codeToAnsi } from "../shiki--ASSYv4_.mjs";
1
+ import { S as unwrap, h as memo, r as createAsync, w as useContext } from "../reactive-DkP75TPk.mjs";
2
+ import { t as Node } from "../node-CXNobGaP.mjs";
3
+ import { t as calcLayout } from "../text-4arC3odI.mjs";
4
+ import { t as RenderContext } from "../render-Bp2N2i6J.mjs";
5
+ import { t as codeToAnsi } from "../shiki-BAf9PdIc.mjs";
6
+ import { t as shikiTheme } from "../theme-B8hb1lPU.mjs";
6
7
  import { splitAnsi, stringWidth, wrapAnsi } from "@zaly/shared/ansi";
7
8
  import { basename, extname } from "pathe";
8
- //#region src/widgets/diff.ts
9
+ // src/widgets/diff.ts
10
+ const NO_NEWLINE = String.raw``;
9
11
  /**
10
12
  * Show a unified diff between two file contents with syntax-highlighted
11
13
  * rows. Added rows carry a green backdrop and `+` prefix; removed rows
@@ -34,7 +36,7 @@ var Diff = class extends Node {
34
36
  const lang = this.#lang();
35
37
  const input = this.input;
36
38
  if (!lang) return input;
37
- const theme = context?.style().theme.shiki;
39
+ const theme = context ? shikiTheme(context.style().theme) : void 0;
38
40
  const [original, modified] = await Promise.all([codeToAnsi(input.original, lang, { theme }), codeToAnsi(input.modified, lang, { theme })]);
39
41
  return {
40
42
  modified,
@@ -56,16 +58,18 @@ var Diff = class extends Node {
56
58
  const input = this.input;
57
59
  const layout = this.layout();
58
60
  const width = Math.min(ctx.width, layout.width);
61
+ const original = splitLines(input.original);
62
+ const modified = splitLines(input.modified);
59
63
  const opts = {
60
64
  context: this.state.context ?? 3,
61
65
  ctx: {
62
66
  ...ctx,
63
67
  width
64
68
  },
65
- modified: input.modified.split("\n"),
66
- modifiedHi: highlighted.modified.split("\n"),
67
- original: input.original.split("\n"),
68
- originalHi: highlighted.original.split("\n")
69
+ modified,
70
+ modifiedHi: splitAnsi(highlighted.modified).slice(0, modified.length),
71
+ original,
72
+ originalHi: splitAnsi(highlighted.original).slice(0, original.length)
69
73
  };
70
74
  this.state.wrap ??= "word";
71
75
  return await buildDiffRows(opts);
@@ -74,10 +78,12 @@ var Diff = class extends Node {
74
78
  const input = this.input;
75
79
  const original = calcLayout(input.original, { wrap: this.state.wrap });
76
80
  const modified = calcLayout(input.modified, { wrap: this.state.wrap });
77
- const padding = Math.max(1, countLines(unwrap(this.state.original)), countLines(unwrap(this.state.modified))).toString().length * 2 + 4 + 4;
81
+ const numWidth = Math.max(1, splitLines(input.original).length, splitLines(input.modified).length).toString().length;
82
+ const markerWidth = [input.original, input.modified].some((s) => s !== "" && !s.endsWith("\n")) ? stringWidth(NO_NEWLINE) : 0;
83
+ const padding = numWidth * 2 + 4 + 4;
78
84
  return {
79
85
  minWidth: Math.max(original.minWidth, modified.minWidth) + padding,
80
- width: Math.max(original.width, modified.width) + padding
86
+ width: Math.max(original.width, modified.width, markerWidth) + padding
81
87
  };
82
88
  }
83
89
  };
@@ -95,10 +101,20 @@ var Diff = class extends Node {
95
101
  function diff(state) {
96
102
  return new Diff(state);
97
103
  }
104
+ function splitLines(text) {
105
+ if (text === "") return [];
106
+ const terminated = text.endsWith("\n");
107
+ const lines = text.split("\n");
108
+ if (terminated) lines.pop();
109
+ return lines.map((line, i) => ({
110
+ terminated: i < lines.length - 1 || terminated,
111
+ text: line
112
+ }));
113
+ }
98
114
  async function buildDiffRows(opts) {
99
115
  const context = opts.context;
100
116
  const { diffArrays } = await import("diff");
101
- const segments = diffArrays(opts.original, opts.modified);
117
+ const segments = diffArrays(opts.original, opts.modified, { comparator: (a, b) => a.text === b.text && a.terminated === b.terminated });
102
118
  const { original: origLines, modified: modLines, originalHi: origHi, modifiedHi: modHi, ctx } = opts;
103
119
  const ann = [];
104
120
  let oI = 0;
@@ -136,16 +152,19 @@ async function buildDiffRows(opts) {
136
152
  content: modHi[a.modIdx] ?? origHi[a.origIdx] ?? "",
137
153
  newNum: a.modIdx + 1,
138
154
  origNum: a.origIdx + 1,
155
+ terminated: modLines[a.modIdx].terminated,
139
156
  type: "context"
140
157
  });
141
158
  else if (a.kind === "remove") rows.push({
142
159
  content: origHi[a.origIdx] ?? "",
143
160
  origNum: a.origIdx + 1,
161
+ terminated: origLines[a.origIdx].terminated,
144
162
  type: "remove"
145
163
  });
146
164
  else rows.push({
147
165
  content: modHi[a.modIdx] ?? "",
148
166
  newNum: a.modIdx + 1,
167
+ terminated: modLines[a.modIdx].terminated,
149
168
  type: "add"
150
169
  });
151
170
  }
@@ -166,7 +185,7 @@ function renderRows(ctx, rows, origTotal, modTotal) {
166
185
  for (const r of rows) {
167
186
  const origStr = r.type === "add" ? "" : String(r.origNum);
168
187
  const newStr = r.type === "remove" ? "" : String(r.newNum);
169
- const gutterStyle = s.bg(`${styles[r.type]}+10`);
188
+ const gutterStyle = s[`${styles[r.type]}Num`] ?? ((x) => x);
170
189
  const gutter = gutterStyle(` ${pad(origStr, numWidth)} ${pad(newStr, numWidth)} `);
171
190
  const prefix = r.type === "add" ? " + " : r.type === "remove" ? " - " : " ";
172
191
  const innerWidth = Math.max(0, contentWidth - stringWidth(prefix) - 1);
@@ -179,6 +198,10 @@ function renderRows(ctx, rows, origTotal, modTotal) {
179
198
  const styledBody = rowStyle?.(bodyLine) ?? bodyLine;
180
199
  out.push((i === 0 ? gutter : gutterStyle(blankGutter)) + styledBody);
181
200
  }
201
+ if (!r.terminated) {
202
+ const marker = wrapAnsi(NO_NEWLINE, Math.max(1, contentWidth), { mode: "word" });
203
+ for (const line of splitAnsi(marker)) out.push(" ".repeat(gutterWidth) + s.dim(line));
204
+ }
182
205
  }
183
206
  return out;
184
207
  }
@@ -193,7 +216,6 @@ function langFromPath(path) {
193
216
  if (ext) return ext;
194
217
  return basename(path).toLowerCase() || void 0;
195
218
  }
196
- //#endregion
197
219
  export { Diff, diff };
198
220
 
199
221
  //# sourceMappingURL=diff.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"diff.mjs","names":[],"sources":["../../src/widgets/diff.ts"],"sourcesContent":["import type { RenderCtx } from \"../core/ctx.ts\"\nimport type { Accessor, Reactive } from \"../core/reactive.ts\"\nimport type { Layout, State } from \"../core/state.ts\"\nimport type { WrapMode } from \"../layout/text.ts\"\n\nimport { splitAnsi, stringWidth, wrapAnsi } from \"@zaly/shared/ansi\"\nimport { basename, extname } from \"pathe\"\n// oxlint-disable no-nested-ternary\n// oxlint-disable typescript/no-unnecessary-condition\nimport { Node } from \"../core/node.ts\"\nimport { createAsync, memo, unwrap, useContext } from \"../core/reactive.ts\"\nimport { RenderContext } from \"../core/render.ts\"\nimport { calcLayout, countLines } from \"../layout/text.ts\"\nimport { codeToAnsi } from \"../shiki/shiki.ts\"\n\nexport interface DiffState {\n /** Pre-state file content. Plain string or reactive accessor —\n * pass a signal to live-update the diff as either side changes. */\n original: Reactive<string>\n /** Post-state file content. The widget runs `diffLines` between\n * `original` and `modified` and renders the resulting hunks. */\n modified: Reactive<string>\n /** Optional file path. Drives the default `lang` (extension or\n * basename — shiki recognises both `.ts` and `Dockerfile`-style\n * names) and `title` when those aren't set explicitly. */\n path?: Reactive<string>\n /** Language for syntax highlighting (any shiki-bundled name or\n * alias). Defaults from `path` when set. */\n lang?: string\n /** Lines of surrounding context per hunk. Default: 3. */\n context?: number\n wrap?: WrapMode\n}\n\ntype DiffOpts = {\n original: string[]\n originalHi: string[]\n modified: string[]\n modifiedHi: string[]\n context: number\n ctx: RenderCtx\n}\n\n/**\n * Show a unified diff between two file contents with syntax-highlighted\n * rows. Added rows carry a green backdrop and `+` prefix; removed rows\n * carry a red backdrop and `-` prefix; context rows show both line\n * numbers with a neutral gutter.\n *\n * Both sides are highlighted as complete files (via shiki) before the\n * diff is assembled, so context around an edit tokenizes the way it\n * would in the actual file — multi-line strings, block comments, etc.\n * don't get truncated by the hunk window.\n */\nexport class Diff extends Node<DiffState> {\n #lang: Accessor<string | undefined>\n #highlighted: Accessor<{ original: string; modified: string }>\n\n constructor(state: DiffState) {\n super({ wrap: \"word\", ...state })\n\n this.#lang = memo(() => {\n const path = unwrap(this.state.path)\n return this.state.lang ?? (path !== undefined ? langFromPath(path) : undefined)\n })\n\n const context = useContext(RenderContext)\n this.#highlighted = createAsync(\n async () => {\n const lang = this.#lang()\n const input = this.input\n if (!lang) return input\n const theme = context?.style().theme.shiki\n const [original, modified] = await Promise.all([\n codeToAnsi(input.original, lang, { theme }),\n codeToAnsi(input.modified, lang, { theme }),\n ])\n return { modified, original }\n },\n {\n initialValue: this.input,\n }\n )\n }\n\n #norm(s: string): string {\n return s.replaceAll(\"\\r\\n\", \"\\n\").replaceAll(\"\\r\", \"\")\n }\n\n get input(): { original: string; modified: string } {\n return {\n modified: this.#norm(unwrap(this.state.modified)),\n original: this.#norm(unwrap(this.state.original)),\n }\n }\n\n protected async _render(ctx: RenderCtx): Promise<string[]> {\n const highlighted = this.#highlighted()\n const input = this.input\n const layout = this.layout()\n const width = Math.min(ctx.width, layout.width)\n\n const opts: DiffOpts = {\n context: this.state.context ?? 3,\n ctx: { ...ctx, width },\n modified: input.modified.split(\"\\n\"),\n modifiedHi: highlighted.modified.split(\"\\n\"),\n original: input.original.split(\"\\n\"),\n originalHi: highlighted.original.split(\"\\n\"),\n }\n\n this.state.wrap ??= \"word\"\n return await buildDiffRows(opts)\n }\n\n override layout(): Layout {\n const input = this.input\n const original = calcLayout(input.original, { wrap: this.state.wrap })\n const modified = calcLayout(input.modified, { wrap: this.state.wrap })\n const numWidth = Math.max(\n 1,\n countLines(unwrap(this.state.original)),\n countLines(unwrap(this.state.modified))\n ).toString().length\n const padding = numWidth * 2 + 4 + 4\n return {\n minWidth: Math.max(original.minWidth, modified.minWidth) + padding,\n width: Math.max(original.width, modified.width) + padding,\n }\n }\n}\n\n/**\n * Factory for `Diff`.\n *\n * ```ts\n * diff({\n * original: \"function foo() {}\\n\",\n * modified: \"function foo(x) {}\\n\",\n * path: \"foo.ts\",\n * })\n * ```\n */\nexport function diff(state: State<DiffState>): Diff {\n return new Diff(state)\n}\n\n// ---------- internals ----------\n\ntype DiffRow =\n | { type: \"context\"; origNum: number; newNum: number; content: string }\n | { type: \"remove\"; origNum: number; content: string }\n | { type: \"add\"; newNum: number; content: string }\n\nasync function buildDiffRows(opts: DiffOpts): Promise<string[]> {\n const context = opts.context\n // Async-import keeps cold start snappy — only the diff widget pulls\n // in the library, and it lands at first render rather than at module\n // load.\n const { diffArrays } = await import(\"diff\")\n const segments = diffArrays(opts.original, opts.modified)\n const {\n original: origLines,\n modified: modLines,\n originalHi: origHi,\n modifiedHi: modHi,\n ctx,\n } = opts\n\n // Annotate each line in the diff with its kind + (orig, mod) indices.\n // The flattened list is the row-order the diff would print without\n // any hunking; we compute hunks (with surrounding context) on top.\n interface Annotated {\n kind: \"equal\" | \"remove\" | \"add\"\n origIdx?: number\n modIdx?: number\n }\n const ann: Annotated[] = []\n let oI = 0\n let mI = 0\n for (const seg of segments) {\n if (seg.added) {\n for (const _ of seg.value) ann.push({ kind: \"add\", modIdx: mI++ })\n } else if (seg.removed) {\n for (const _ of seg.value) ann.push({ kind: \"remove\", origIdx: oI++ })\n } else {\n for (const _ of seg.value) ann.push({ kind: \"equal\", modIdx: mI++, origIdx: oI++ })\n }\n }\n\n // Find hunks: ranges around each non-equal line, expanded by `context`,\n // merged when adjacent ranges touch.\n const ranges: { start: number; end: number }[] = []\n for (let i = 0; i < ann.length; i++) {\n if (ann[i].kind === \"equal\") continue\n const start = Math.max(0, i - context)\n const end = Math.min(ann.length - 1, i + context)\n const last = ranges.at(-1)\n if (last && start <= last.end + 1) last.end = Math.max(last.end, end)\n else ranges.push({ end, start })\n }\n if (ranges.length === 0) return [] // nothing changed\n\n // Emit rows for each hunk. (Between hunks we just skip the equal\n // lines — a `…` divider is a future polish.)\n const rows: DiffRow[] = []\n for (const r of ranges) {\n for (let i = r.start; i <= r.end; i++) {\n const a = ann[i]\n if (a.kind === \"equal\") {\n rows.push({\n content: modHi[a.modIdx!] ?? origHi[a.origIdx!] ?? \"\",\n newNum: a.modIdx! + 1,\n origNum: a.origIdx! + 1,\n type: \"context\",\n })\n } else if (a.kind === \"remove\") {\n rows.push({\n content: origHi[a.origIdx!] ?? \"\",\n origNum: a.origIdx! + 1,\n type: \"remove\",\n })\n } else {\n rows.push({\n content: modHi[a.modIdx!] ?? \"\",\n newNum: a.modIdx! + 1,\n type: \"add\",\n })\n }\n }\n }\n\n return renderRows(ctx, rows, origLines.length, modLines.length)\n}\n\nfunction renderRows(\n ctx: RenderCtx,\n rows: DiffRow[],\n origTotal: number,\n modTotal: number\n): string[] {\n const numWidth = Math.max(String(origTotal).length, String(modTotal).length, 1)\n const s = ctx.style\n\n // Two-column gutter: original line number | new line number | space.\n // - Context rows show both numbers.\n // - Remove rows show only the original number; new column blank.\n // - Add rows show only the new number; original column blank.\n // Wrapped continuation lines reuse the row style but emit a blank\n // gutter so the line number isn't repeated per visual row.\n const gutterWidth = numWidth * 2 + 4 // \"<orig> <new> \"\n const contentWidth = Math.max(0, ctx.width - gutterWidth)\n const blankGutter = \" \".repeat(gutterWidth - 2) + s.dim(\"↪ \")\n\n const styles = {\n add: \"diffAdd\",\n context: \"diffContext\",\n remove: \"diffDel\",\n } as const\n\n const out: string[] = []\n for (const r of rows) {\n const origStr = r.type === \"add\" ? \"\" : String(r.origNum)\n const newStr = r.type === \"remove\" ? \"\" : String(r.newNum)\n const gutterStyle = s.bg(`${styles[r.type]}+10`)\n const gutter = gutterStyle(` ${pad(origStr, numWidth)} ${pad(newStr, numWidth)} `)\n\n const prefix = r.type === \"add\" ? \" + \" : r.type === \"remove\" ? \" - \" : \" \"\n const innerWidth = Math.max(0, contentWidth - stringWidth(prefix) - 1)\n\n // Hard-wrap the content. Char-wrap (vs. word-wrap) keeps code\n // diffs honest — splitting by word boundaries would shift columns\n // mid-line and make alignment confusing.\n const wrapped =\n innerWidth > 0 && stringWidth(r.content) > innerWidth\n ? splitAnsi(wrapAnsi(r.content, innerWidth, { mode: \"word\" }))\n : [r.content]\n\n const rowStyle = s.bg(styles[r.type])\n for (let i = 0; i < wrapped.length; i++) {\n const wline = wrapped[i]\n const pw = Math.max(0, innerWidth - stringWidth(wline) + 1)\n const bodyLine = (i === 0 ? prefix : \" \") + wline + \" \".repeat(pw)\n const styledBody = rowStyle?.(bodyLine) ?? bodyLine\n out.push((i === 0 ? gutter : gutterStyle(blankGutter)) + styledBody)\n }\n }\n return out\n}\n\nfunction pad(s: string, width: number): string {\n return s.length >= width ? s : \" \".repeat(width - s.length) + s\n}\n\n/** Resolve a file path to a shiki language identifier. Falls back from\n * extension to basename — shiki natively recognises `dockerfile`,\n * `makefile`, `cmakelists.txt`, etc. */\nfunction langFromPath(path: string): string | undefined {\n const ext = extname(path).slice(1).toLowerCase()\n if (ext) return ext\n const base = basename(path).toLowerCase()\n return base || undefined\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"diff.mjs","names":[],"sources":["../../src/widgets/diff.ts"],"sourcesContent":["import type { RenderCtx } from \"../core/ctx.ts\"\nimport type { Accessor, Reactive } from \"../core/reactive.ts\"\nimport type { Layout, State } from \"../core/state.ts\"\nimport type { WrapMode } from \"../layout/text.ts\"\n\nimport { splitAnsi, stringWidth, wrapAnsi } from \"@zaly/shared/ansi\"\nimport { basename, extname } from \"pathe\"\n// oxlint-disable no-nested-ternary\n// oxlint-disable typescript/no-unnecessary-condition\nimport { Node } from \"../core/node.ts\"\nimport { createAsync, memo, unwrap, useContext } from \"../core/reactive.ts\"\nimport { RenderContext } from \"../core/render.ts\"\nimport { calcLayout } from \"../layout/text.ts\"\nimport { codeToAnsi } from \"../shiki/shiki.ts\"\nimport { shikiTheme } from \"../shiki/theme.ts\"\n\nexport interface DiffState {\n /** Pre-state file content. Plain string or reactive accessor —\n * pass a signal to live-update the diff as either side changes. */\n original: Reactive<string>\n /** Post-state file content. The widget runs `diffLines` between\n * `original` and `modified` and renders the resulting hunks. */\n modified: Reactive<string>\n /** Optional file path. Drives the default `lang` (extension or\n * basename — shiki recognises both `.ts` and `Dockerfile`-style\n * names) and `title` when those aren't set explicitly. */\n path?: Reactive<string>\n /** Language for syntax highlighting (any shiki-bundled name or\n * alias). Defaults from `path` when set. */\n lang?: string\n /** Lines of surrounding context per hunk. Default: 3. */\n context?: number\n wrap?: WrapMode\n}\n\nconst NO_NEWLINE = String.raw`\`\n\ntype DiffLine = { text: string; terminated: boolean }\n\ntype DiffOpts = {\n original: DiffLine[]\n originalHi: string[]\n modified: DiffLine[]\n modifiedHi: string[]\n context: number\n ctx: RenderCtx\n}\n\n/**\n * Show a unified diff between two file contents with syntax-highlighted\n * rows. Added rows carry a green backdrop and `+` prefix; removed rows\n * carry a red backdrop and `-` prefix; context rows show both line\n * numbers with a neutral gutter.\n *\n * Both sides are highlighted as complete files (via shiki) before the\n * diff is assembled, so context around an edit tokenizes the way it\n * would in the actual file — multi-line strings, block comments, etc.\n * don't get truncated by the hunk window.\n */\nexport class Diff extends Node<DiffState> {\n #lang: Accessor<string | undefined>\n #highlighted: Accessor<{ original: string; modified: string }>\n\n constructor(state: DiffState) {\n super({ wrap: \"word\", ...state })\n\n this.#lang = memo(() => {\n const path = unwrap(this.state.path)\n return this.state.lang ?? (path !== undefined ? langFromPath(path) : undefined)\n })\n\n const context = useContext(RenderContext)\n this.#highlighted = createAsync(\n async () => {\n const lang = this.#lang()\n const input = this.input\n if (!lang) return input\n const theme = context ? shikiTheme(context.style().theme) : undefined\n const [original, modified] = await Promise.all([\n codeToAnsi(input.original, lang, { theme }),\n codeToAnsi(input.modified, lang, { theme }),\n ])\n return { modified, original }\n },\n {\n initialValue: this.input,\n }\n )\n }\n\n #norm(s: string): string {\n return s.replaceAll(\"\\r\\n\", \"\\n\").replaceAll(\"\\r\", \"\")\n }\n\n get input(): { original: string; modified: string } {\n return {\n modified: this.#norm(unwrap(this.state.modified)),\n original: this.#norm(unwrap(this.state.original)),\n }\n }\n\n protected async _render(ctx: RenderCtx): Promise<string[]> {\n const highlighted = this.#highlighted()\n const input = this.input\n const layout = this.layout()\n const width = Math.min(ctx.width, layout.width)\n\n const original = splitLines(input.original)\n const modified = splitLines(input.modified)\n const opts: DiffOpts = {\n context: this.state.context ?? 3,\n ctx: { ...ctx, width },\n modified,\n modifiedHi: splitAnsi(highlighted.modified).slice(0, modified.length),\n original,\n originalHi: splitAnsi(highlighted.original).slice(0, original.length),\n }\n\n this.state.wrap ??= \"word\"\n return await buildDiffRows(opts)\n }\n\n override layout(): Layout {\n const input = this.input\n const original = calcLayout(input.original, { wrap: this.state.wrap })\n const modified = calcLayout(input.modified, { wrap: this.state.wrap })\n const numWidth = Math.max(\n 1,\n splitLines(input.original).length,\n splitLines(input.modified).length\n ).toString().length\n const markerWidth = [input.original, input.modified].some((s) => s !== \"\" && !s.endsWith(\"\\n\"))\n ? stringWidth(NO_NEWLINE)\n : 0\n const padding = numWidth * 2 + 4 + 4\n return {\n minWidth: Math.max(original.minWidth, modified.minWidth) + padding,\n width: Math.max(original.width, modified.width, markerWidth) + padding,\n }\n }\n}\n\n/**\n * Factory for `Diff`.\n *\n * ```ts\n * diff({\n * original: \"function foo() {}\\n\",\n * modified: \"function foo(x) {}\\n\",\n * path: \"foo.ts\",\n * })\n * ```\n */\nexport function diff(state: State<DiffState>): Diff {\n return new Diff(state)\n}\n\n// ---------- internals ----------\n\nfunction splitLines(text: string): DiffLine[] {\n if (text === \"\") return []\n const terminated = text.endsWith(\"\\n\")\n const lines = text.split(\"\\n\")\n if (terminated) lines.pop()\n return lines.map((line, i) => ({ terminated: i < lines.length - 1 || terminated, text: line }))\n}\n\ntype DiffRow = { terminated: boolean } & (\n | { type: \"context\"; origNum: number; newNum: number; content: string }\n | { type: \"remove\"; origNum: number; content: string }\n | { type: \"add\"; newNum: number; content: string }\n)\n\nasync function buildDiffRows(opts: DiffOpts): Promise<string[]> {\n const context = opts.context\n // Async-import keeps cold start snappy — only the diff widget pulls\n // in the library, and it lands at first render rather than at module\n // load.\n const { diffArrays } = await import(\"diff\")\n const segments = diffArrays(opts.original, opts.modified, {\n comparator: (a, b) => a.text === b.text && a.terminated === b.terminated,\n })\n const {\n original: origLines,\n modified: modLines,\n originalHi: origHi,\n modifiedHi: modHi,\n ctx,\n } = opts\n\n // Annotate each line in the diff with its kind + (orig, mod) indices.\n // The flattened list is the row-order the diff would print without\n // any hunking; we compute hunks (with surrounding context) on top.\n interface Annotated {\n kind: \"equal\" | \"remove\" | \"add\"\n origIdx?: number\n modIdx?: number\n }\n const ann: Annotated[] = []\n let oI = 0\n let mI = 0\n for (const seg of segments) {\n if (seg.added) {\n for (const _ of seg.value) ann.push({ kind: \"add\", modIdx: mI++ })\n } else if (seg.removed) {\n for (const _ of seg.value) ann.push({ kind: \"remove\", origIdx: oI++ })\n } else {\n for (const _ of seg.value) ann.push({ kind: \"equal\", modIdx: mI++, origIdx: oI++ })\n }\n }\n\n // Find hunks: ranges around each non-equal line, expanded by `context`,\n // merged when adjacent ranges touch.\n const ranges: { start: number; end: number }[] = []\n for (let i = 0; i < ann.length; i++) {\n if (ann[i].kind === \"equal\") continue\n const start = Math.max(0, i - context)\n const end = Math.min(ann.length - 1, i + context)\n const last = ranges.at(-1)\n if (last && start <= last.end + 1) last.end = Math.max(last.end, end)\n else ranges.push({ end, start })\n }\n if (ranges.length === 0) return [] // nothing changed\n\n // Emit rows for each hunk. (Between hunks we just skip the equal\n // lines — a `…` divider is a future polish.)\n const rows: DiffRow[] = []\n for (const r of ranges) {\n for (let i = r.start; i <= r.end; i++) {\n const a = ann[i]\n if (a.kind === \"equal\") {\n rows.push({\n content: modHi[a.modIdx!] ?? origHi[a.origIdx!] ?? \"\",\n newNum: a.modIdx! + 1,\n origNum: a.origIdx! + 1,\n terminated: modLines[a.modIdx!].terminated,\n type: \"context\",\n })\n } else if (a.kind === \"remove\") {\n rows.push({\n content: origHi[a.origIdx!] ?? \"\",\n origNum: a.origIdx! + 1,\n terminated: origLines[a.origIdx!].terminated,\n type: \"remove\",\n })\n } else {\n rows.push({\n content: modHi[a.modIdx!] ?? \"\",\n newNum: a.modIdx! + 1,\n terminated: modLines[a.modIdx!].terminated,\n type: \"add\",\n })\n }\n }\n }\n\n return renderRows(ctx, rows, origLines.length, modLines.length)\n}\n\nfunction renderRows(\n ctx: RenderCtx,\n rows: DiffRow[],\n origTotal: number,\n modTotal: number\n): string[] {\n const numWidth = Math.max(String(origTotal).length, String(modTotal).length, 1)\n const s = ctx.style\n\n // Two-column gutter: original line number | new line number | space.\n // - Context rows show both numbers.\n // - Remove rows show only the original number; new column blank.\n // - Add rows show only the new number; original column blank.\n // Wrapped continuation lines reuse the row style but emit a blank\n // gutter so the line number isn't repeated per visual row.\n const gutterWidth = numWidth * 2 + 4 // \"<orig> <new> \"\n const contentWidth = Math.max(0, ctx.width - gutterWidth)\n const blankGutter = \" \".repeat(gutterWidth - 2) + s.dim(\"↪ \")\n\n const styles = {\n add: \"diffAdd\",\n context: \"diffContext\",\n remove: \"diffDel\",\n } as const\n\n const out: string[] = []\n for (const r of rows) {\n const origStr = r.type === \"add\" ? \"\" : String(r.origNum)\n const newStr = r.type === \"remove\" ? \"\" : String(r.newNum)\n\n const gutterStyle = s[`${styles[r.type]}Num`] ?? ((x: string) => x)\n const gutter = gutterStyle(` ${pad(origStr, numWidth)} ${pad(newStr, numWidth)} `)\n\n const prefix = r.type === \"add\" ? \" + \" : r.type === \"remove\" ? \" - \" : \" \"\n const innerWidth = Math.max(0, contentWidth - stringWidth(prefix) - 1)\n\n // Hard-wrap the content. Char-wrap (vs. word-wrap) keeps code\n // diffs honest — splitting by word boundaries would shift columns\n // mid-line and make alignment confusing.\n const wrapped =\n innerWidth > 0 && stringWidth(r.content) > innerWidth\n ? splitAnsi(wrapAnsi(r.content, innerWidth, { mode: \"word\" }))\n : [r.content]\n\n const rowStyle = s.bg(styles[r.type])\n for (let i = 0; i < wrapped.length; i++) {\n const wline = wrapped[i]\n const pw = Math.max(0, innerWidth - stringWidth(wline) + 1)\n const bodyLine = (i === 0 ? prefix : \" \") + wline + \" \".repeat(pw)\n const styledBody = rowStyle?.(bodyLine) ?? bodyLine\n out.push((i === 0 ? gutter : gutterStyle(blankGutter)) + styledBody)\n }\n if (!r.terminated) {\n const marker = wrapAnsi(NO_NEWLINE, Math.max(1, contentWidth), { mode: \"word\" })\n for (const line of splitAnsi(marker)) out.push(\" \".repeat(gutterWidth) + s.dim(line))\n }\n }\n return out\n}\n\nfunction pad(s: string, width: number): string {\n return s.length >= width ? s : \" \".repeat(width - s.length) + s\n}\n\n/** Resolve a file path to a shiki language identifier. Falls back from\n * extension to basename — shiki natively recognises `dockerfile`,\n * `makefile`, `cmakelists.txt`, etc. */\nfunction langFromPath(path: string): string | undefined {\n const ext = extname(path).slice(1).toLowerCase()\n if (ext) return ext\n const base = basename(path).toLowerCase()\n return base || undefined\n}\n"],"mappings":"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"}
@@ -1,10 +1,8 @@
1
- import { H as Text } from "../queries-BDX8mcl5.mjs";
2
- import { f as Style } from "../types-D2EYlzmK.mjs";
3
- //#region src/widgets/divider.d.ts
1
+ import { u as Style } from "../types-ByMHEdCF.mjs";
2
+ import { W as Text } from "../queries-Dmd3IjSd.mjs";
4
3
  export type DividerState = Style<false> & {
5
4
  char?: string;
6
5
  length?: number;
7
6
  };
8
7
  export declare function divider(state?: DividerState): Text;
9
- //#endregion
10
8
  //# sourceMappingURL=divider.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"divider.d.mts","names":[],"sources":["../../src/widgets/divider.ts"],"mappings":";;;YAKY,eAAe;EACzB;EACA;;wBAGc,QAAQ,QAAO,eAAsC"}
1
+ {"version":3,"file":"divider.d.mts","names":[],"sources":["../../src/widgets/divider.ts"],"mappings":";;YAKY,eAAe;EACzB;EACA;;wBAGc,QAAQ,QAAO,eAAsC"}
@@ -1 +1 @@
1
- export { t as divider } from "../divider-TSx9NhI_.mjs";
1
+ export { t as divider } from "../divider-qEj5prKE.mjs";
@@ -1,2 +1,2 @@
1
- import { n as ImageState, r as image, t as Image } from "../image-VaT7AN-S.mjs";
1
+ import { n as ImageState, r as image, t as Image } from "../image-DdRDv7q6.mjs";
2
2
  export { Image, ImageState, image };
@@ -1,10 +1,10 @@
1
- import { S as unwrap, w as useContext } from "../reactive-f7NpAi69.mjs";
2
- import { t as Node } from "../node-BZ7f6HzU.mjs";
3
- import { t as RenderContext } from "../render-DEIUNLkh.mjs";
4
- import { s as loadKittyGraphics } from "../kitty-JbCJC0iQ.mjs";
1
+ import { S as unwrap, w as useContext } from "../reactive-DkP75TPk.mjs";
2
+ import { t as Node } from "../node-CXNobGaP.mjs";
3
+ import { t as RenderContext } from "../render-Bp2N2i6J.mjs";
4
+ import { s as loadKittyGraphics } from "../kitty-BH_eK6lz.mjs";
5
5
  import { fileDetect } from "@zaly/shared/detect";
6
6
  import { imageInfo } from "@zaly/shared/image";
7
- //#region src/widgets/image.ts
7
+ // src/widgets/image.ts
8
8
  var Image = class extends Node {
9
9
  #delete;
10
10
  #enabled;
@@ -31,7 +31,7 @@ var Image = class extends Node {
31
31
  const detected = await fileDetect(this.state.src);
32
32
  if (detected?.type !== "image") return this.fallback;
33
33
  const img = await imageInfo(detected);
34
- const { cols, rows } = dims(this.state, img, Math.min(ctx.width, 80));
34
+ const { cols, rows } = dims(this.state, img, ctx.width);
35
35
  const t = await kitty.transmitOnce(img);
36
36
  if (!t) return this.fallback;
37
37
  const p = kitty.placement(t.imageId, {
@@ -61,9 +61,9 @@ function image(first, style) {
61
61
  function dims(state, meta, available) {
62
62
  const cellAspect = state.cellAspect ?? 2;
63
63
  const aspect = meta.height / meta.width;
64
- let cols = state.width;
64
+ let cols = state.width === void 0 ? void 0 : Math.max(1, Math.min(state.width, available));
65
65
  let rows = state.height;
66
- if (cols === void 0 && rows === void 0) cols = Math.max(1, available);
66
+ if (cols === void 0 && rows === void 0) cols = Math.max(1, Math.min(available, 80));
67
67
  if (cols !== void 0 && rows === void 0) rows = Math.max(1, Math.round(cols * aspect / cellAspect));
68
68
  else if (rows !== void 0 && cols === void 0) cols = Math.max(1, Math.round(rows * cellAspect / aspect));
69
69
  return {
@@ -71,7 +71,6 @@ function dims(state, meta, available) {
71
71
  rows: rows ?? 1
72
72
  };
73
73
  }
74
- //#endregion
75
74
  export { Image, image };
76
75
 
77
76
  //# sourceMappingURL=image.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"image.mjs","names":[],"sources":["../../src/widgets/image.ts"],"sourcesContent":["import type { RenderCtx } from \"../core/ctx.ts\"\nimport type { Accessor } from \"../core/reactive.ts\"\nimport type { Layout } from \"../core/state.ts\"\n\nimport { fileDetect } from \"@zaly/shared/detect\"\nimport { imageInfo } from \"@zaly/shared/image\"\nimport { Node } from \"../core/node.ts\"\nimport { unwrap, useContext } from \"../core/reactive.ts\"\nimport { RenderContext } from \"../core/render.ts\"\nimport { loadKittyGraphics } from \"../image/kitty.ts\"\n\nexport interface ImageState {\n /**\n * Path to an image file. PNG passes through with zero decoding; other\n * formats (JPEG/WebP/GIF/AVIF/SVG) are read via image-meta for\n * dimensions and — for KGP terminals — converted once to a cached\n * temp PNG via sharp. iTerm2 accepts all formats natively.\n */\n src: string\n /** Display width in terminal cells. Defaults to `ctx.width`. */\n width?: number\n /**\n * Display height in terminal cells. When omitted, computed from the\n * source aspect ratio + `cellAspect`.\n */\n height?: number\n /** Fallback text shown on terminals without an image protocol. */\n alt?: string\n /**\n * Character cell aspect ratio (cellHeight / cellWidth). Most terminals\n * land around 2.0. Tweak if aspect-preserved images look stretched.\n */\n cellAspect?: number\n}\n\nexport class Image extends Node<ImageState> {\n #delete?: () => void\n #enabled?: Accessor<boolean>\n\n constructor(state: ImageState) {\n super(state)\n this.on(\"unmount\", () => this.#delete?.())\n const context = useContext(RenderContext)\n this.#enabled = context?.images\n }\n\n get fallback(): string[] {\n return [this.state.alt ?? `[Image: ${this.state.src}]`]\n }\n\n override layout(): Layout {\n return { minWidth: 50, width: 100 }\n }\n\n protected async _render(ctx: RenderCtx): Promise<string[]> {\n if (unwrap(this.#enabled) === false) return this.fallback\n\n const queries = this.ctx?.input.queries\n const kitty = queries ? await loadKittyGraphics(queries) : undefined\n if (!kitty?.supported) return this.fallback\n\n const detected = await fileDetect(this.state.src)\n if (detected?.type !== \"image\") return this.fallback\n const img = await imageInfo(detected)\n\n const { cols, rows } = dims(this.state, img, Math.min(ctx.width, 80))\n\n const t = await kitty.transmitOnce(img)\n if (!t) return this.fallback\n const p = kitty.placement(t.imageId, { cols, rows })\n if (!p) return this.fallback\n this.#delete = () =>\n p.placementId ? kitty.deletePlacement(t.imageId, p.placementId) : undefined\n // Route the transmit bytes through the side-channel queue (mount\n // ctx → terminal). Cached rows then hold pure placement ANSI,\n // which is safe to reuse across repaints. If we're rendering\n // before mount (rare — tests, headless previews), fall back to\n // inlining the transmit into the lead so the picture still\n // shows correctly the first time.\n if (t.transmit) {\n ctx.transmit(t.transmit)\n if (p.inline) ctx.transmit(p.seq)\n }\n\n if (p.inline) return p.data\n\n const ret = [...p.data]\n if (!ret.length) return this.fallback\n ret[0] = p.seq + ret[0]\n return ret\n }\n}\n\nexport function image(src: string, style?: Omit<ImageState, \"src\">): Image\nexport function image(state: ImageState): Image\nexport function image(first: string | ImageState, style?: Omit<ImageState, \"src\">): Image {\n if (typeof first === \"string\") return new Image({ src: first, ...style })\n return new Image(first)\n}\n\nfunction dims(\n state: ImageState,\n meta: { width: number; height: number },\n available: number\n): { cols: number; rows: number } {\n const cellAspect = state.cellAspect ?? 2\n const aspect = meta.height / meta.width\n let cols = state.width\n let rows = state.height\n if (cols === undefined && rows === undefined) cols = Math.max(1, available)\n if (cols !== undefined && rows === undefined) {\n rows = Math.max(1, Math.round((cols * aspect) / cellAspect))\n } else if (rows !== undefined && cols === undefined) {\n cols = Math.max(1, Math.round((rows * cellAspect) / aspect))\n }\n return { cols: cols ?? available, rows: rows ?? 1 }\n}\n"],"mappings":";;;;;;;AAmCA,IAAa,QAAb,cAA2B,KAAiB;CAC1C;CACA;CAEA,YAAY,OAAmB;EAC7B,MAAM,KAAK;EACX,KAAK,GAAG,iBAAiB,KAAK,UAAU,CAAC;EACzC,MAAM,UAAU,WAAW,aAAa;EACxC,KAAK,WAAW,SAAS;CAC3B;CAEA,IAAI,WAAqB;EACvB,OAAO,CAAC,KAAK,MAAM,OAAO,WAAW,KAAK,MAAM,IAAI,EAAE;CACxD;CAEA,SAA0B;EACxB,OAAO;GAAE,UAAU;GAAI,OAAO;EAAI;CACpC;CAEA,MAAgB,QAAQ,KAAmC;EACzD,IAAI,OAAO,KAAK,QAAQ,MAAM,OAAO,OAAO,KAAK;EAEjD,MAAM,UAAU,KAAK,KAAK,MAAM;EAChC,MAAM,QAAQ,UAAU,MAAM,kBAAkB,OAAO,IAAI,KAAA;EAC3D,IAAI,CAAC,OAAO,WAAW,OAAO,KAAK;EAEnC,MAAM,WAAW,MAAM,WAAW,KAAK,MAAM,GAAG;EAChD,IAAI,UAAU,SAAS,SAAS,OAAO,KAAK;EAC5C,MAAM,MAAM,MAAM,UAAU,QAAQ;EAEpC,MAAM,EAAE,MAAM,SAAS,KAAK,KAAK,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,EAAE,CAAC;EAEpE,MAAM,IAAI,MAAM,MAAM,aAAa,GAAG;EACtC,IAAI,CAAC,GAAG,OAAO,KAAK;EACpB,MAAM,IAAI,MAAM,UAAU,EAAE,SAAS;GAAE;GAAM;EAAK,CAAC;EACnD,IAAI,CAAC,GAAG,OAAO,KAAK;EACpB,KAAK,gBACH,EAAE,cAAc,MAAM,gBAAgB,EAAE,SAAS,EAAE,WAAW,IAAI,KAAA;EAOpE,IAAI,EAAE,UAAU;GACd,IAAI,SAAS,EAAE,QAAQ;GACvB,IAAI,EAAE,QAAQ,IAAI,SAAS,EAAE,GAAG;EAClC;EAEA,IAAI,EAAE,QAAQ,OAAO,EAAE;EAEvB,MAAM,MAAM,CAAC,GAAG,EAAE,IAAI;EACtB,IAAI,CAAC,IAAI,QAAQ,OAAO,KAAK;EAC7B,IAAI,KAAK,EAAE,MAAM,IAAI;EACrB,OAAO;CACT;AACF;AAIA,SAAgB,MAAM,OAA4B,OAAwC;CACxF,IAAI,OAAO,UAAU,UAAU,OAAO,IAAI,MAAM;EAAE,KAAK;EAAO,GAAG;CAAM,CAAC;CACxE,OAAO,IAAI,MAAM,KAAK;AACxB;AAEA,SAAS,KACP,OACA,MACA,WACgC;CAChC,MAAM,aAAa,MAAM,cAAc;CACvC,MAAM,SAAS,KAAK,SAAS,KAAK;CAClC,IAAI,OAAO,MAAM;CACjB,IAAI,OAAO,MAAM;CACjB,IAAI,SAAS,KAAA,KAAa,SAAS,KAAA,GAAW,OAAO,KAAK,IAAI,GAAG,SAAS;CAC1E,IAAI,SAAS,KAAA,KAAa,SAAS,KAAA,GACjC,OAAO,KAAK,IAAI,GAAG,KAAK,MAAO,OAAO,SAAU,UAAU,CAAC;MACtD,IAAI,SAAS,KAAA,KAAa,SAAS,KAAA,GACxC,OAAO,KAAK,IAAI,GAAG,KAAK,MAAO,OAAO,aAAc,MAAM,CAAC;CAE7D,OAAO;EAAE,MAAM,QAAQ;EAAW,MAAM,QAAQ;CAAE;AACpD"}
1
+ {"version":3,"file":"image.mjs","names":[],"sources":["../../src/widgets/image.ts"],"sourcesContent":["import type { RenderCtx } from \"../core/ctx.ts\"\nimport type { Accessor } from \"../core/reactive.ts\"\nimport type { Layout } from \"../core/state.ts\"\n\nimport { fileDetect } from \"@zaly/shared/detect\"\nimport { imageInfo } from \"@zaly/shared/image\"\nimport { Node } from \"../core/node.ts\"\nimport { unwrap, useContext } from \"../core/reactive.ts\"\nimport { RenderContext } from \"../core/render.ts\"\nimport { loadKittyGraphics } from \"../image/kitty.ts\"\n\nexport interface ImageState {\n /**\n * Path to an image file. PNG passes through with zero decoding; other\n * formats (JPEG/WebP/GIF/AVIF/SVG) are read via image-meta for\n * dimensions and — for KGP terminals — converted once to a cached\n * temp PNG via sharp. iTerm2 accepts all formats natively.\n */\n src: string\n /** Display width in terminal cells. Defaults to `ctx.width`. */\n width?: number\n /**\n * Display height in terminal cells. When omitted, computed from the\n * source aspect ratio + `cellAspect`.\n */\n height?: number\n /** Fallback text shown on terminals without an image protocol. */\n alt?: string\n /**\n * Character cell aspect ratio (cellHeight / cellWidth). Most terminals\n * land around 2.0. Tweak if aspect-preserved images look stretched.\n */\n cellAspect?: number\n}\n\nexport class Image extends Node<ImageState> {\n #delete?: () => void\n #enabled?: Accessor<boolean>\n\n constructor(state: ImageState) {\n super(state)\n this.on(\"unmount\", () => this.#delete?.())\n const context = useContext(RenderContext)\n this.#enabled = context?.images\n }\n\n get fallback(): string[] {\n return [this.state.alt ?? `[Image: ${this.state.src}]`]\n }\n\n override layout(): Layout {\n return { minWidth: 50, width: 100 }\n }\n\n protected async _render(ctx: RenderCtx): Promise<string[]> {\n if (unwrap(this.#enabled) === false) return this.fallback\n\n const queries = this.ctx?.input.queries\n const kitty = queries ? await loadKittyGraphics(queries) : undefined\n if (!kitty?.supported) return this.fallback\n\n const detected = await fileDetect(this.state.src)\n if (detected?.type !== \"image\") return this.fallback\n const img = await imageInfo(detected)\n\n const { cols, rows } = dims(this.state, img, ctx.width)\n\n const t = await kitty.transmitOnce(img)\n if (!t) return this.fallback\n const p = kitty.placement(t.imageId, { cols, rows })\n if (!p) return this.fallback\n this.#delete = () =>\n p.placementId ? kitty.deletePlacement(t.imageId, p.placementId) : undefined\n // Route the transmit bytes through the side-channel queue (mount\n // ctx → terminal). Cached rows then hold pure placement ANSI,\n // which is safe to reuse across repaints. If we're rendering\n // before mount (rare — tests, headless previews), fall back to\n // inlining the transmit into the lead so the picture still\n // shows correctly the first time.\n if (t.transmit) {\n ctx.transmit(t.transmit)\n if (p.inline) ctx.transmit(p.seq)\n }\n\n if (p.inline) return p.data\n\n const ret = [...p.data]\n if (!ret.length) return this.fallback\n ret[0] = p.seq + ret[0]\n return ret\n }\n}\n\nexport function image(src: string, style?: Omit<ImageState, \"src\">): Image\nexport function image(state: ImageState): Image\nexport function image(first: string | ImageState, style?: Omit<ImageState, \"src\">): Image {\n if (typeof first === \"string\") return new Image({ src: first, ...style })\n return new Image(first)\n}\n\nfunction dims(\n state: ImageState,\n meta: { width: number; height: number },\n available: number\n): { cols: number; rows: number } {\n const cellAspect = state.cellAspect ?? 2\n const aspect = meta.height / meta.width\n let cols = state.width === undefined ? undefined : Math.max(1, Math.min(state.width, available))\n let rows = state.height\n if (cols === undefined && rows === undefined) cols = Math.max(1, Math.min(available, 80))\n if (cols !== undefined && rows === undefined) {\n rows = Math.max(1, Math.round((cols * aspect) / cellAspect))\n } else if (rows !== undefined && cols === undefined) {\n cols = Math.max(1, Math.round((rows * cellAspect) / aspect))\n }\n return { cols: cols ?? available, rows: rows ?? 1 }\n}\n"],"mappings":";;;;;;;AAmCA,IAAa,QAAb,cAA2B,KAAiB;CAC1C;CACA;CAEA,YAAY,OAAmB;EAC7B,MAAM,KAAK;EACX,KAAK,GAAG,iBAAiB,KAAK,UAAU,CAAC;EACzC,MAAM,UAAU,WAAW,aAAa;EACxC,KAAK,WAAW,SAAS;CAC3B;CAEA,IAAI,WAAqB;EACvB,OAAO,CAAC,KAAK,MAAM,OAAO,WAAW,KAAK,MAAM,IAAI,EAAE;CACxD;CAEA,SAA0B;EACxB,OAAO;GAAE,UAAU;GAAI,OAAO;EAAI;CACpC;CAEA,MAAgB,QAAQ,KAAmC;EACzD,IAAI,OAAO,KAAK,QAAQ,MAAM,OAAO,OAAO,KAAK;EAEjD,MAAM,UAAU,KAAK,KAAK,MAAM;EAChC,MAAM,QAAQ,UAAU,MAAM,kBAAkB,OAAO,IAAI,KAAA;EAC3D,IAAI,CAAC,OAAO,WAAW,OAAO,KAAK;EAEnC,MAAM,WAAW,MAAM,WAAW,KAAK,MAAM,GAAG;EAChD,IAAI,UAAU,SAAS,SAAS,OAAO,KAAK;EAC5C,MAAM,MAAM,MAAM,UAAU,QAAQ;EAEpC,MAAM,EAAE,MAAM,SAAS,KAAK,KAAK,OAAO,KAAK,IAAI,KAAK;EAEtD,MAAM,IAAI,MAAM,MAAM,aAAa,GAAG;EACtC,IAAI,CAAC,GAAG,OAAO,KAAK;EACpB,MAAM,IAAI,MAAM,UAAU,EAAE,SAAS;GAAE;GAAM;EAAK,CAAC;EACnD,IAAI,CAAC,GAAG,OAAO,KAAK;EACpB,KAAK,gBACH,EAAE,cAAc,MAAM,gBAAgB,EAAE,SAAS,EAAE,WAAW,IAAI,KAAA;EAOpE,IAAI,EAAE,UAAU;GACd,IAAI,SAAS,EAAE,QAAQ;GACvB,IAAI,EAAE,QAAQ,IAAI,SAAS,EAAE,GAAG;EAClC;EAEA,IAAI,EAAE,QAAQ,OAAO,EAAE;EAEvB,MAAM,MAAM,CAAC,GAAG,EAAE,IAAI;EACtB,IAAI,CAAC,IAAI,QAAQ,OAAO,KAAK;EAC7B,IAAI,KAAK,EAAE,MAAM,IAAI;EACrB,OAAO;CACT;AACF;AAIA,SAAgB,MAAM,OAA4B,OAAwC;CACxF,IAAI,OAAO,UAAU,UAAU,OAAO,IAAI,MAAM;EAAE,KAAK;EAAO,GAAG;CAAM,CAAC;CACxE,OAAO,IAAI,MAAM,KAAK;AACxB;AAEA,SAAS,KACP,OACA,MACA,WACgC;CAChC,MAAM,aAAa,MAAM,cAAc;CACvC,MAAM,SAAS,KAAK,SAAS,KAAK;CAClC,IAAI,OAAO,MAAM,UAAU,KAAA,IAAY,KAAA,IAAY,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,OAAO,SAAS,CAAC;CAC/F,IAAI,OAAO,MAAM;CACjB,IAAI,SAAS,KAAA,KAAa,SAAS,KAAA,GAAW,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,WAAW,EAAE,CAAC;CACxF,IAAI,SAAS,KAAA,KAAa,SAAS,KAAA,GACjC,OAAO,KAAK,IAAI,GAAG,KAAK,MAAO,OAAO,SAAU,UAAU,CAAC;MACtD,IAAI,SAAS,KAAA,KAAa,SAAS,KAAA,GACxC,OAAO,KAAK,IAAI,GAAG,KAAK,MAAO,OAAO,aAAc,MAAM,CAAC;CAE7D,OAAO;EAAE,MAAM,QAAQ;EAAW,MAAM,QAAQ;CAAE;AACpD"}
@@ -1,2 +1,2 @@
1
- import { a as InputValue, i as InputState, n as InputAttachment, o as input, r as InputEvents, t as Input } from "../input-BAYux7qo.mjs";
1
+ import { a as InputValue, i as InputState, n as InputAttachment, o as input, r as InputEvents, t as Input } from "../input-C3kfYoEJ.mjs";
2
2
  export { Input, InputAttachment, InputEvents, InputState, InputValue, input };
@@ -1 +1 @@
1
- export { t as Input, n as input } from "../input-BGTTujDN.mjs";
1
+ export { t as Input, n as input } from "../input-BkE4EpBw.mjs";
@@ -1,2 +1,2 @@
1
- import { A as LogState, M as log, j as LogStyle } from "../queries-BDX8mcl5.mjs";
1
+ import { M as LogState, N as LogStyle, P as log } from "../queries-Dmd3IjSd.mjs";
2
2
  export { LogState, LogStyle, log };
@@ -1 +1 @@
1
- export { t as log } from "../log-ByKlM4iI.mjs";
1
+ export { t as log } from "../log-96b1_J6G.mjs";
@@ -1,9 +1,8 @@
1
- import { J as Layout, P as RenderCtx, U as TextContent, X as State, p as Node } from "../queries-BDX8mcl5.mjs";
2
- import { o as AnyStyle } from "../types-D2EYlzmK.mjs";
3
- import { t as WrapMode } from "../text-CCYs9RB2.mjs";
4
- import { n as MdOptions } from "../types-D3jk1rtk.mjs";
5
- import { t as Image } from "../image-VaT7AN-S.mjs";
6
- //#region src/widgets/markdown.d.ts
1
+ import { i as AnyStyle } from "../types-ByMHEdCF.mjs";
2
+ import { G as TextContent, I as RenderCtx, Q as State, X as Layout, h as Node } from "../queries-Dmd3IjSd.mjs";
3
+ import { t as WrapMode } from "../text-DdkJXgoC.mjs";
4
+ import { n as MdOptions } from "../types-CUVUJPz6.mjs";
5
+ import { t as Image } from "../image-DdRDv7q6.mjs";
7
6
  export interface MarkdownState {
8
7
  /** Markdown source. Accepts a plain string or a reactive accessor —
9
8
  * pass `signal()` / `memo()` for streaming content that re-parses on
@@ -40,5 +39,4 @@ export declare class Markdown extends Node<MarkdownState> {
40
39
  */
41
40
  export declare function markdown(content: TextContent, style?: Omit<State<MarkdownState>, "content">): Markdown;
42
41
  export declare function markdown(state: State<MarkdownState>): Markdown;
43
- //#endregion
44
42
  //# sourceMappingURL=markdown.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.mts","names":["_$___core_state_ts0.Layout"],"sources":["../../src/widgets/markdown.ts"],"mappings":";;;;;;iBAoBiB;;;;EAIf,SAAS;;EAET,UAAU;;;;;;;EAOV;EACA,OAAO;EACP,QAAQ;;qBAcG,iBAAiB,KAAK;;WAKxB,QAAM,YAAA;EASf,YAAY,OAAO,MAAM;YAwDT,QAAQ,KAAK,YAAY;EA0C1B,OAAO,KAAK,YAAS,QAATA;;;;;;;;;;;;wBAeb,SACd,SAAS,aACT,QAAQ,KAAK,MAAM,6BAClB;wBACa,SAAS,OAAO,MAAM,iBAAiB"}
1
+ {"version":3,"file":"markdown.d.mts","names":["_$___core_state_ts0.Layout"],"sources":["../../src/widgets/markdown.ts"],"mappings":";;;;;iBAqBiB;;;;EAIf,SAAS;;EAET,UAAU;;;;;;;EAOV;EACA,OAAO;EACP,QAAQ;;qBAcG,iBAAiB,KAAK;;WAKxB,QAAM,YAAA;EASf,YAAY,OAAO,MAAM;YAwDT,QAAQ,KAAK,YAAY;EA0C1B,OAAO,KAAK,YAAS,QAATA;;;;;;;;;;;;wBAeb,SACd,SAAS,aACT,QAAQ,KAAK,MAAM,6BAClB;wBACa,SAAS,OAAO,MAAM,iBAAiB"}
@@ -1 +1 @@
1
- export { t as Markdown, n as markdown } from "../markdown-CwRmWuU6.mjs";
1
+ export { t as Markdown, n as markdown } from "../markdown-CgRZBhIX.mjs";
@@ -1,2 +1,2 @@
1
- import { F as Overlay, I as OverlayState, L as overlay } from "../queries-BDX8mcl5.mjs";
1
+ import { L as Overlay, R as OverlayState, z as overlay } from "../queries-Dmd3IjSd.mjs";
2
2
  export { Overlay, OverlayState, overlay };
@@ -1 +1 @@
1
- export { t as overlay } from "../overlay-BnvOKtGT.mjs";
1
+ export { t as overlay } from "../overlay-CevDWgSF.mjs";
@@ -1,2 +1,2 @@
1
- import { a as picker, i as PickerTreeProps, n as PickerItem, r as PickerSelectProps, t as PickerActions } from "../picker-DQs_IW77.mjs";
1
+ import { a as picker, i as PickerTreeProps, n as PickerItem, r as PickerSelectProps, t as PickerActions } from "../picker-DsB6--GN.mjs";
2
2
  export { PickerActions, PickerItem, PickerSelectProps, PickerTreeProps, picker };
@@ -1 +1 @@
1
- export { t as picker } from "../picker-Dh5IUrTk.mjs";
1
+ export { t as picker } from "../picker-D9WrE3zF.mjs";
@@ -1,6 +1,5 @@
1
- import { Nt as Size, P as RenderCtx, X as State, nt as Reactive, p as Node } from "../queries-BDX8mcl5.mjs";
2
- import { c as Color } from "../types-D2EYlzmK.mjs";
3
- //#region src/widgets/progress.d.ts
1
+ import { o as Color } from "../types-ByMHEdCF.mjs";
2
+ import { Ft as Size, I as RenderCtx, Q as State, h as Node, it as Reactive } from "../queries-Dmd3IjSd.mjs";
4
3
  export interface ProgressState {
5
4
  /** Current value. Clamped to `[0, total]`. Accepts a signal accessor
6
5
  * so callers can drive the bar from reactive state without manual
@@ -43,5 +42,4 @@ export declare class Progress extends Node<ProgressState> {
43
42
  * ```
44
43
  */
45
44
  export declare function progress(state: State<ProgressState>): Progress;
46
- //#endregion
47
45
  //# sourceMappingURL=progress.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"progress.d.mts","names":[],"sources":["../../src/widgets/progress.ts"],"mappings":";;;iBAWiB;;;;EAIf,OAAO;;EAEP,QAAQ;;;;;EAKR,QAAQ;;;;;;EAMR,mBAAmB,KAAK,WAAW;;EAEnC,QAAQ;;EAER,aAAa;;EAEb;;EAEA;;qBAGW,iBAAiB,KAAK;YACvB,QAAQ,KAAK;;;;;;;;;;;;;wBAwCT,SAAS,OAAO,MAAM,iBAAiB"}
1
+ {"version":3,"file":"progress.d.mts","names":[],"sources":["../../src/widgets/progress.ts"],"mappings":";;iBAWiB;;;;EAIf,OAAO;;EAEP,QAAQ;;;;;EAKR,QAAQ;;;;;;EAMR,mBAAmB,KAAK,WAAW;;EAEnC,QAAQ;;EAER,aAAa;;EAEb;;EAEA;;qBAGW,iBAAiB,KAAK;YACvB,QAAQ,KAAK;;;;;;;;;;;;;wBAwCT,SAAS,OAAO,MAAM,iBAAiB"}
@@ -1,8 +1,8 @@
1
- import { S as unwrap } from "../reactive-f7NpAi69.mjs";
2
- import { t as Node } from "../node-BZ7f6HzU.mjs";
3
- import { n as resolveSize } from "../size-D8JogYLy.mjs";
1
+ import { S as unwrap } from "../reactive-DkP75TPk.mjs";
2
+ import { t as Node } from "../node-CXNobGaP.mjs";
3
+ import { n as resolveSize } from "../size-BHRJuRk9.mjs";
4
4
  import { stringWidth } from "@zaly/shared/ansi";
5
- //#region src/widgets/progress.ts
5
+ // src/widgets/progress.ts
6
6
  var Progress = class extends Node {
7
7
  _render(ctx) {
8
8
  const total = unwrap(this.state.total ?? 1);
@@ -42,7 +42,6 @@ function resolveLabel(label, ctx, fraction) {
42
42
  if (label === "auto") return `${Math.round(fraction * 100)}%`;
43
43
  return label;
44
44
  }
45
- //#endregion
46
45
  export { Progress, progress };
47
46
 
48
47
  //# sourceMappingURL=progress.mjs.map
@@ -1,2 +1,2 @@
1
- import { a as SelectEvents, i as Select, n as OptionRender, o as SelectState, r as OptionRenderCtx, s as select, t as Option } from "../select-J2KtwxyK.mjs";
1
+ import { a as SelectEvents, i as Select, n as OptionRender, o as SelectState, r as OptionRenderCtx, s as select, t as Option } from "../select-BZCFXdjp.mjs";
2
2
  export { Option, OptionRender, OptionRenderCtx, Select, SelectEvents, SelectState, select };
@@ -1 +1 @@
1
- export { t as Select, n as select } from "../select-m7NE6Rwa.mjs";
1
+ export { t as Select, n as select } from "../select-CUmAFKJh.mjs";
@@ -1,5 +1,4 @@
1
- import { P as RenderCtx, nt as Reactive, p as Node } from "../queries-BDX8mcl5.mjs";
2
- //#region src/widgets/show.d.ts
1
+ import { I as RenderCtx, h as Node, it as Reactive } from "../queries-Dmd3IjSd.mjs";
3
2
  export type ShowGate = {
4
3
  when: Reactive<unknown>;
5
4
  };
@@ -50,6 +49,5 @@ declare class Show extends Node {
50
49
  * ```
51
50
  */
52
51
  export declare function show(...spec: ShowSpec): Show;
53
- //#endregion
54
52
  export type { Show };
55
53
  //# sourceMappingURL=show.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"show.d.mts","names":[],"sources":["../../src/widgets/show.ts"],"mappings":";;YAMY;EAAa,MAAM;;YACnB;EAAe,MAAM;EAAmB,KAAK;;YAC7C,qBAAqB,OAAO;YAC5B,YAAY,WAAW,qBAAqB,WAAW,eAAe;;;;;;;;;cAkB5E,aAAa;;EAIjB,YAAY,MAAM;EAqBT,2BAA2B;;;;YAepB,QAAQ,KAAK,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;wBA8B3B,QAAQ,MAAM,WAAW"}
1
+ {"version":3,"file":"show.d.mts","names":[],"sources":["../../src/widgets/show.ts"],"mappings":";YAMY;EAAa,MAAM;;YACnB;EAAe,MAAM;EAAmB,KAAK;;YAC7C,qBAAqB,OAAO;YAC5B,YAAY,WAAW,qBAAqB,WAAW,eAAe;;;;;;;;;cAkB5E,aAAa;;EAIjB,YAAY,MAAM;EAqBT,2BAA2B;;;;YAepB,QAAQ,KAAK,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;wBA8B3B,QAAQ,MAAM,WAAW"}
@@ -1 +1 @@
1
- export { t as show } from "../show-DR2x1YFc.mjs";
1
+ export { t as show } from "../show-D5XNXgZf.mjs";
@@ -1,6 +1,5 @@
1
- import { P as RenderCtx, X as State, nt as Reactive, p as Node } from "../queries-BDX8mcl5.mjs";
2
- import { o as AnyStyle } from "../types-D2EYlzmK.mjs";
3
- //#region src/widgets/spinner.d.ts
1
+ import { i as AnyStyle } from "../types-ByMHEdCF.mjs";
2
+ import { I as RenderCtx, Q as State, h as Node, it as Reactive } from "../queries-Dmd3IjSd.mjs";
4
3
  /**
5
4
  * Frame sets from the common terminal-spinner vocabulary. Pick one to taste.
6
5
  * @internal
@@ -60,5 +59,4 @@ export declare class Spinner extends Node<SpinnerState> {
60
59
  * gives you the braille `dots` set at 80ms in the theme's `primary` color.
61
60
  */
62
61
  export declare function spinner(state?: State<SpinnerState>): Spinner;
63
- //#endregion
64
62
  //# sourceMappingURL=spinner.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"spinner.d.mts","names":[],"sources":["../../src/widgets/spinner.ts"],"mappings":";;;;;;;qBAaa;WACX;WACA;WACA;WACA;WACA;;YAGU,4BAA4B;iBAEvB;;EAEf,SAAS;;EAET,QAAQ,SAAS;;;;;EAKjB,UAAU;EACV;;;;;;;;;;;;;;;;;;;;;qBA4DW,gBAAgB,KAAK;;EAChC,YAAY,OAAO;;SAYZ,KAAK;;EAKZ;;EAMA;YAcU,QAAQ,KAAK;;;;;;wBAoBT,QAAQ,QAAO,MAAM,gBAAqB"}
1
+ {"version":3,"file":"spinner.d.mts","names":[],"sources":["../../src/widgets/spinner.ts"],"mappings":";;;;;;qBAaa;WACX;WACA;WACA;WACA;WACA;;YAGU,4BAA4B;iBAEvB;;EAEf,SAAS;;EAET,QAAQ,SAAS;;;;;EAKjB,UAAU;EACV;;;;;;;;;;;;;;;;;;;;;qBA4DW,gBAAgB,KAAK;;EAChC,YAAY,OAAO;;SAYZ,KAAK;;EAKZ;;EAMA;YAcU,QAAQ,KAAK;;;;;;wBAoBT,QAAQ,QAAO,MAAM,gBAAqB"}
@@ -1,7 +1,7 @@
1
- import { S as unwrap, f as effect, x as untrack } from "../reactive-f7NpAi69.mjs";
2
- import { t as Node } from "../node-BZ7f6HzU.mjs";
1
+ import { S as unwrap, f as effect, x as untrack } from "../reactive-DkP75TPk.mjs";
2
+ import { t as Node } from "../node-CXNobGaP.mjs";
3
3
  import { stringWidth } from "@zaly/shared/ansi";
4
- //#region src/widgets/spinner.ts
4
+ // src/widgets/spinner.ts
5
5
  /**
6
6
  * Frame sets from the common terminal-spinner vocabulary. Pick one to taste.
7
7
  * @internal
@@ -141,7 +141,6 @@ var Spinner = class Spinner extends Node {
141
141
  function spinner(state = {}) {
142
142
  return new Spinner(state);
143
143
  }
144
- //#endregion
145
144
  export { Spinner, spinner, spinnerFrames };
146
145
 
147
146
  //# sourceMappingURL=spinner.mjs.map
@@ -1,2 +1,2 @@
1
- import { G as text, H as Text, K as textContent, U as TextContent, W as TextStyle } from "../queries-BDX8mcl5.mjs";
1
+ import { G as TextContent, J as textContent, K as TextStyle, W as Text, q as text } from "../queries-Dmd3IjSd.mjs";
2
2
  export { Text, TextContent, TextStyle, text, textContent };
@@ -1 +1 @@
1
- export { t as Text, n as text, r as textContent } from "../text-XvPfweeg.mjs";
1
+ export { t as Text, n as text, r as textContent } from "../text-BArwVVkg.mjs";
@@ -1,2 +1,2 @@
1
- import { i as tree, n as TreeNode, r as TreeProps, t as TreeItem } from "../tree-DJl5W_B7.mjs";
1
+ import { i as tree, n as TreeNode, r as TreeProps, t as TreeItem } from "../tree-Berzv8Rz.mjs";
2
2
  export { TreeItem, TreeNode, TreeProps, tree };
@@ -1 +1 @@
1
- export { t as tree } from "../tree-Bo1afYhe.mjs";
1
+ export { t as tree } from "../tree-D6NvMQx8.mjs";
@@ -1,2 +1,2 @@
1
- import { n as Widget, r as widget, t as Props } from "../widget-DPqBbB57.mjs";
1
+ import { n as Widget, r as widget, t as Props } from "../widget-sPJaKVU2.mjs";
2
2
  export { Props, Widget, widget };
@@ -1 +1 @@
1
- export { t as widget } from "../widget-BkMwhY2p.mjs";
1
+ export { t as widget } from "../widget-sFveyrZE.mjs";
@@ -1,4 +1,4 @@
1
- //#region src/shiki/worker.ts
1
+ // src/shiki/worker.ts
2
2
  const workerHost = {
3
3
  onMessage: (handler) => {
4
4
  if (typeof globalThis.addEventListener === "function") {
@@ -46,7 +46,6 @@ async function createWorker() {
46
46
  terminate: () => void worker.terminate()
47
47
  };
48
48
  }
49
- //#endregion
50
49
  export { workerHost as n, createWorker as t };
51
50
 
52
- //# sourceMappingURL=worker-T6SdPzUH.mjs.map
51
+ //# sourceMappingURL=worker-CtEowucz.mjs.map