@zaly/tui 0.0.11 → 0.1.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 (260) 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 +227 -732
  4. package/assets/themes/andromeeda.json +97 -0
  5. package/assets/themes/ayu-dark.json +31 -44
  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 +44 -60
  9. package/assets/themes/catppuccin-latte.json +44 -60
  10. package/assets/themes/catppuccin-macchiato.json +44 -60
  11. package/assets/themes/catppuccin-mocha.json +44 -60
  12. package/assets/themes/dark-plus.json +99 -0
  13. package/assets/themes/dracula.json +47 -66
  14. package/assets/themes/everforest-dark.json +28 -45
  15. package/assets/themes/everforest-light.json +28 -45
  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 -48
  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 -68
  36. package/assets/themes/kanagawa-lotus.json +105 -0
  37. package/assets/themes/kanagawa-wave.json +55 -68
  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 -64
  41. package/assets/themes/material-theme.json +102 -0
  42. package/assets/themes/min-dark.json +67 -28
  43. package/assets/themes/min-light.json +67 -32
  44. package/assets/themes/monokai.json +55 -67
  45. package/assets/themes/night-owl-light.json +105 -0
  46. package/assets/themes/night-owl.json +57 -68
  47. package/assets/themes/nord.json +53 -55
  48. package/assets/themes/one-dark-pro.json +46 -57
  49. package/assets/themes/one-light.json +52 -59
  50. package/assets/themes/poimandres.json +51 -68
  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 +51 -50
  54. package/assets/themes/solarized-dark.json +39 -51
  55. package/assets/themes/solarized-light.json +40 -52
  56. package/assets/themes/synthwave-84.json +48 -50
  57. package/assets/themes/tokyonight-day.json +6 -7
  58. package/assets/themes/tokyonight-moon.json +6 -6
  59. package/assets/themes/tokyonight-night.json +6 -6
  60. package/assets/themes/tokyonight-storm.json +6 -6
  61. package/assets/themes/vesper.json +51 -58
  62. package/assets/themes/vitesse-black.json +103 -0
  63. package/assets/themes/vitesse-dark.json +26 -49
  64. package/assets/themes/vitesse-light.json +26 -49
  65. package/dist/{actions-DFboj3g5.d.mts → actions--ODlgCQ5.d.mts} +4 -4
  66. package/dist/{actions-DFboj3g5.d.mts.map → actions--ODlgCQ5.d.mts.map} +1 -1
  67. package/dist/{ansi-Clq0ozyA.mjs → ansi-CMv71xVr.mjs} +38 -31
  68. package/dist/ansi-CMv71xVr.mjs.map +1 -0
  69. package/dist/ansi.d.mts +3 -1
  70. package/dist/ansi.d.mts.map +1 -1
  71. package/dist/ansi.mjs +1 -1
  72. package/dist/{autocomplete-CxzetPOo.d.mts → autocomplete-CD30kSe_.d.mts} +4 -4
  73. package/dist/{autocomplete-CxzetPOo.d.mts.map → autocomplete-CD30kSe_.d.mts.map} +1 -1
  74. package/dist/{box-DLEcEvDH.mjs → box-C_N_7ChP.mjs} +2 -2
  75. package/dist/box-C_N_7ChP.mjs.map +1 -0
  76. package/dist/builder-Chwtk0nQ.mjs +196 -0
  77. package/dist/builder-Chwtk0nQ.mjs.map +1 -0
  78. package/dist/{callbacks-D132G8dy.mjs → callbacks-DLecWn7G.mjs} +4 -4
  79. package/dist/{callbacks-D132G8dy.mjs.map → callbacks-DLecWn7G.mjs.map} +1 -1
  80. package/dist/client-CNGt-dOt.mjs +1 -0
  81. package/dist/{client-C2GXKfJ1.mjs → client-D7qz4TZt.mjs} +7 -3
  82. package/dist/client-D7qz4TZt.mjs.map +1 -0
  83. package/dist/color-DBMQLv4Y.mjs +37 -0
  84. package/dist/color-DBMQLv4Y.mjs.map +1 -0
  85. package/dist/{ctx-8Nuf5BrN.mjs → ctx-BaQ2hP5u.mjs} +3 -3
  86. package/dist/{ctx-8Nuf5BrN.mjs.map → ctx-BaQ2hP5u.mjs.map} +1 -1
  87. package/dist/ctx-CndlTp1T.mjs +1 -0
  88. package/dist/{divider-l0-JPEIm.mjs → divider-BlNNN2OS.mjs} +2 -2
  89. package/dist/divider-BlNNN2OS.mjs.map +1 -0
  90. package/dist/{files-BUsa-RVl.d.mts → files-B_5HDBPp.d.mts} +3 -3
  91. package/dist/{files-BUsa-RVl.d.mts.map → files-B_5HDBPp.d.mts.map} +1 -1
  92. package/dist/github-Cy2hfWJ7.mjs.map +1 -1
  93. package/dist/{github-D89A3F9U.d.mts → github-CyRwUQ3y.d.mts} +3 -3
  94. package/dist/{github-D89A3F9U.d.mts.map → github-CyRwUQ3y.d.mts.map} +1 -1
  95. package/dist/{image-34bU73bW.d.mts → image-BLls2F4t.d.mts} +2 -2
  96. package/dist/{image-34bU73bW.d.mts.map → image-BLls2F4t.d.mts.map} +1 -1
  97. package/dist/image-Cqtj3yRA.mjs +178 -0
  98. package/dist/image-Cqtj3yRA.mjs.map +1 -0
  99. package/dist/image.d.mts +1 -1
  100. package/dist/index.d.mts +13 -4
  101. package/dist/index.d.mts.map +1 -1
  102. package/dist/index.mjs +8 -7
  103. package/dist/index.mjs.map +1 -1
  104. package/dist/{input-D7fQEUdt.mjs → input-ET2YEMcl.mjs} +16 -11
  105. package/dist/input-ET2YEMcl.mjs.map +1 -0
  106. package/dist/{input-Dylds_sI.d.mts → input-NuD8TH8N.d.mts} +3 -3
  107. package/dist/{input-Dylds_sI.d.mts.map → input-NuD8TH8N.d.mts.map} +1 -1
  108. package/dist/{inspect-DPLRum7L.d.mts → inspect-B1uXxdKC.d.mts} +11 -15
  109. package/dist/inspect-B1uXxdKC.d.mts.map +1 -0
  110. package/dist/{inspect-CcgiZ_F9.mjs → inspect-Cxzs-W0g.mjs} +2 -2
  111. package/dist/{inspect-CcgiZ_F9.mjs.map → inspect-Cxzs-W0g.mjs.map} +1 -1
  112. package/dist/kitty-DKQYsQfH.mjs +1 -0
  113. package/dist/{log-Dy_QnPZF.mjs → log-B4djzy2m.mjs} +5 -5
  114. package/dist/log-B4djzy2m.mjs.map +1 -0
  115. package/dist/{logger-DvuX9DPS.mjs → logger-CvJCITzP.mjs} +3 -3
  116. package/dist/{logger-DvuX9DPS.mjs.map → logger-CvJCITzP.mjs.map} +1 -1
  117. package/dist/{markdown-BGPa7UzD.mjs → markdown-D3ZtRn6C.mjs} +9 -8
  118. package/dist/markdown-D3ZtRn6C.mjs.map +1 -0
  119. package/dist/markdown.d.mts +1 -1
  120. package/dist/markdown.d.mts.map +1 -1
  121. package/dist/markdown.mjs +1 -1
  122. package/dist/math-CU0wmC9N.mjs +1 -0
  123. package/dist/math-Dd7a1irv.mjs +206 -0
  124. package/dist/math-Dd7a1irv.mjs.map +1 -0
  125. package/dist/oklch-Bsh5swbC.mjs +99 -0
  126. package/dist/oklch-Bsh5swbC.mjs.map +1 -0
  127. package/dist/{overlay-9WXYiGgW.mjs → overlay-LvOjG7kn.mjs} +2 -2
  128. package/dist/{overlay-9WXYiGgW.mjs.map → overlay-LvOjG7kn.mjs.map} +1 -1
  129. package/dist/{picker-JL8lZfRH.d.mts → picker-B-OxKKnD.d.mts} +5 -5
  130. package/dist/{picker-JL8lZfRH.d.mts.map → picker-B-OxKKnD.d.mts.map} +1 -1
  131. package/dist/{picker-BqHINl_a.mjs → picker-f6xjgACX.mjs} +2 -2
  132. package/dist/{picker-BqHINl_a.mjs.map → picker-f6xjgACX.mjs.map} +1 -1
  133. package/dist/{queries-B_lOwEiE.mjs → queries-BUkBxkuM.mjs} +66 -3
  134. package/dist/queries-BUkBxkuM.mjs.map +1 -0
  135. package/dist/{queries-Cvalgu6P.d.mts → queries-C75-wG1B.d.mts} +42 -11
  136. package/dist/queries-C75-wG1B.d.mts.map +1 -0
  137. package/dist/{registry-3hLzS4ks.mjs → registry-DUWpSPoo.mjs} +208 -68
  138. package/dist/registry-DUWpSPoo.mjs.map +1 -0
  139. package/dist/{render-f7M2856V.mjs → render-B7LfNM5K.mjs} +2 -2
  140. package/dist/{render-f7M2856V.mjs.map → render-B7LfNM5K.mjs.map} +1 -1
  141. package/dist/{renderer-V6AGjbyf.mjs → renderer-BLsd-wrG.mjs} +167 -20
  142. package/dist/renderer-BLsd-wrG.mjs.map +1 -0
  143. package/dist/renderer-YHbR7JZ4.mjs +1 -0
  144. package/dist/{renderer-DesbRwjQ.mjs → renderer-aAtkFgll.mjs} +8 -7
  145. package/dist/renderer-aAtkFgll.mjs.map +1 -0
  146. package/dist/{select-zGd5pbiB.d.mts → select-BKE5LzdN.d.mts} +3 -3
  147. package/dist/{select-zGd5pbiB.d.mts.map → select-BKE5LzdN.d.mts.map} +1 -1
  148. package/dist/services/logger.d.mts +1 -1
  149. package/dist/services/logger.mjs +1 -1
  150. package/dist/services/notifier.d.mts +1 -1
  151. package/dist/services/notifier.mjs +2 -2
  152. package/dist/services/picker.d.mts +5 -5
  153. package/dist/services/picker.mjs +6 -6
  154. package/dist/services/prompt.d.mts +4 -4
  155. package/dist/services/prompt.mjs +5 -5
  156. package/dist/shiki/server.mjs +37 -14
  157. package/dist/shiki/server.mjs.map +1 -1
  158. package/dist/shiki-B4U0s8jT.mjs +635 -0
  159. package/dist/shiki-B4U0s8jT.mjs.map +1 -0
  160. package/dist/shiki-CJauRusM.mjs +20 -0
  161. package/dist/shiki-CJauRusM.mjs.map +1 -0
  162. package/dist/style-DslRHzI4.mjs +109 -0
  163. package/dist/style-DslRHzI4.mjs.map +1 -0
  164. package/dist/style.d.mts +4 -3
  165. package/dist/style.d.mts.map +1 -1
  166. package/dist/style.mjs +4 -4
  167. package/dist/{text-CRZD9KTN.mjs → text-BoJdKXLU.mjs} +2 -2
  168. package/dist/{text-CRZD9KTN.mjs.map → text-BoJdKXLU.mjs.map} +1 -1
  169. package/dist/{text-BefiXAFW.d.mts → text-CmxbA8lk.d.mts} +3 -3
  170. package/dist/{text-BefiXAFW.d.mts.map → text-CmxbA8lk.d.mts.map} +1 -1
  171. package/dist/{text-BLz1tRoC.mjs → text-DPrhma4x.mjs} +2 -2
  172. package/dist/text-DPrhma4x.mjs.map +1 -0
  173. package/dist/text.d.mts +1 -1
  174. package/dist/text.mjs +1 -1
  175. package/dist/theme-C8LkcoaK.mjs +61 -0
  176. package/dist/theme-C8LkcoaK.mjs.map +1 -0
  177. package/dist/theme-DVX8dvGG.mjs +1794 -0
  178. package/dist/theme-DVX8dvGG.mjs.map +1 -0
  179. package/dist/themes.d.mts +213 -73
  180. package/dist/themes.d.mts.map +1 -1
  181. package/dist/themes.mjs +1 -1
  182. package/dist/{tree-CArtDRec.d.mts → tree-CTvSpF9b.d.mts} +3 -3
  183. package/dist/{tree-CArtDRec.d.mts.map → tree-CTvSpF9b.d.mts.map} +1 -1
  184. package/dist/{types-C0EOLZDc.d.mts → types-C9ceMsbJ.d.mts} +137 -137
  185. package/dist/types-C9ceMsbJ.d.mts.map +1 -0
  186. package/dist/{widget-DtJU2-BJ.d.mts → widget-DlF32PRp.d.mts} +2 -2
  187. package/dist/{widget-DtJU2-BJ.d.mts.map → widget-DlF32PRp.d.mts.map} +1 -1
  188. package/dist/widgets/autocomplete.d.mts +1 -1
  189. package/dist/widgets/autocomplete.mjs +2 -2
  190. package/dist/widgets/box.d.mts +1 -1
  191. package/dist/widgets/box.mjs +1 -1
  192. package/dist/widgets/code.d.mts +4 -2
  193. package/dist/widgets/code.d.mts.map +1 -1
  194. package/dist/widgets/code.mjs +8 -7
  195. package/dist/widgets/code.mjs.map +1 -1
  196. package/dist/widgets/completions/actions.d.mts +1 -1
  197. package/dist/widgets/completions/files.d.mts +1 -1
  198. package/dist/widgets/completions/github.d.mts +1 -1
  199. package/dist/widgets/completions/index.d.mts +3 -3
  200. package/dist/widgets/diff.d.mts +2 -2
  201. package/dist/widgets/diff.d.mts.map +1 -1
  202. package/dist/widgets/diff.mjs +35 -12
  203. package/dist/widgets/diff.mjs.map +1 -1
  204. package/dist/widgets/divider.d.mts +3 -3
  205. package/dist/widgets/divider.mjs +1 -1
  206. package/dist/widgets/image.d.mts +1 -1
  207. package/dist/widgets/image.mjs +4 -4
  208. package/dist/widgets/image.mjs.map +1 -1
  209. package/dist/widgets/input.d.mts +1 -1
  210. package/dist/widgets/input.mjs +1 -1
  211. package/dist/widgets/log.d.mts +1 -1
  212. package/dist/widgets/log.mjs +1 -1
  213. package/dist/widgets/markdown.d.mts +4 -4
  214. package/dist/widgets/markdown.d.mts.map +1 -1
  215. package/dist/widgets/markdown.mjs +1 -1
  216. package/dist/widgets/overlay.d.mts +1 -1
  217. package/dist/widgets/overlay.mjs +1 -1
  218. package/dist/widgets/picker.d.mts +1 -1
  219. package/dist/widgets/picker.mjs +1 -1
  220. package/dist/widgets/progress.d.mts +4 -4
  221. package/dist/widgets/progress.mjs.map +1 -1
  222. package/dist/widgets/select.d.mts +1 -1
  223. package/dist/widgets/show.d.mts +1 -1
  224. package/dist/widgets/spinner.d.mts +2 -2
  225. package/dist/widgets/text.d.mts +1 -1
  226. package/dist/widgets/text.mjs +1 -1
  227. package/dist/widgets/tree.d.mts +1 -1
  228. package/dist/widgets/widget.d.mts +1 -1
  229. package/package.json +5 -7
  230. package/assets/themes/dracula-soft.json +0 -119
  231. package/assets/themes/github-dark.json +0 -123
  232. package/assets/themes/github-light.json +0 -123
  233. package/dist/ansi-Clq0ozyA.mjs.map +0 -1
  234. package/dist/box-DLEcEvDH.mjs.map +0 -1
  235. package/dist/builder-DC9byAmK.mjs +0 -386
  236. package/dist/builder-DC9byAmK.mjs.map +0 -1
  237. package/dist/client-C2GXKfJ1.mjs.map +0 -1
  238. package/dist/client-bzdHIDL2.mjs +0 -1
  239. package/dist/ctx-k0wTqeql.mjs +0 -1
  240. package/dist/divider-l0-JPEIm.mjs.map +0 -1
  241. package/dist/image-Cm5T-uw-.mjs +0 -108
  242. package/dist/image-Cm5T-uw-.mjs.map +0 -1
  243. package/dist/input-D7fQEUdt.mjs.map +0 -1
  244. package/dist/inspect-DPLRum7L.d.mts.map +0 -1
  245. package/dist/log-Dy_QnPZF.mjs.map +0 -1
  246. package/dist/markdown-BGPa7UzD.mjs.map +0 -1
  247. package/dist/queries-B_lOwEiE.mjs.map +0 -1
  248. package/dist/queries-Cvalgu6P.d.mts.map +0 -1
  249. package/dist/registry-3hLzS4ks.mjs.map +0 -1
  250. package/dist/renderer-BSMOuiLM.mjs +0 -1
  251. package/dist/renderer-DesbRwjQ.mjs.map +0 -1
  252. package/dist/renderer-V6AGjbyf.mjs.map +0 -1
  253. package/dist/shiki--ASSYv4_.mjs +0 -12
  254. package/dist/shiki--ASSYv4_.mjs.map +0 -1
  255. package/dist/shiki-D7l5--zz.mjs +0 -432
  256. package/dist/shiki-D7l5--zz.mjs.map +0 -1
  257. package/dist/text-BLz1tRoC.mjs.map +0 -1
  258. package/dist/theme.config-BKXX_noZ.mjs +0 -863
  259. package/dist/theme.config-BKXX_noZ.mjs.map +0 -1
  260. package/dist/types-C0EOLZDc.d.mts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oklch-Bsh5swbC.mjs","names":[],"sources":["../src/style/oklch.ts"],"sourcesContent":["/**\n * OKLCH-based tonal scale generation for theme colors.\n *\n * Given a base hex color, `variant(hex, step)` returns a hex variant at\n * the Tailwind-v4-ish step (50..950). The base color's hue and chroma\n * are preserved; only lightness moves. When the resulting color falls\n * outside sRGB, chroma is reduced via binary search (CSS Color Level 4\n * \"MinDE chroma reduction\") until the color fits — that avoids the\n * saturation blowout you get from naive HSL lightening at the extremes.\n *\n * Matrix constants come from Björn Ottosson's reference OKLab spec:\n * https://bottosson.github.io/posts/oklab/\n */\n\nimport type { HexColor } from \"./types.ts\"\n\nimport { clamp } from \"@zaly/shared\"\nimport { parseHex, toHex } from \"./color.ts\"\n\nexport interface OKLCH {\n L: number\n C: number\n h: number\n}\n\nconst cache = new Map<string, HexColor>()\n\n// ---------- conversions ----------\n\nfunction srgbToLinear(c: number): number {\n return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4\n}\n\nfunction linearToSrgb(c: number): number {\n return c <= 0.0031308 ? c * 12.92 : 1.055 * c ** (1 / 2.4) - 0.055\n}\n\nexport function hexToOklch(hex: HexColor): OKLCH {\n const [r8, g8, b8] = parseHex(hex)\n const r = srgbToLinear(r8 / 255)\n const g = srgbToLinear(g8 / 255)\n const b = srgbToLinear(b8 / 255)\n\n const l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b\n const m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b\n const s = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b\n const lp = Math.cbrt(l)\n const mp = Math.cbrt(m)\n const sp = Math.cbrt(s)\n const L = 0.2104542553 * lp + 0.793617785 * mp - 0.0040720468 * sp\n const a = 1.9779984951 * lp - 2.428592205 * mp + 0.4505937099 * sp\n const b2 = 0.0259040371 * lp + 0.7827717662 * mp - 0.808675766 * sp\n const C = Math.hypot(a, b2)\n const h = ((Math.atan2(b2, a) * 180) / Math.PI + 360) % 360\n return { C, L, h }\n}\n\n/** Convert OKLCH → linear sRGB (unclamped — callers can test for gamut). */\nfunction oklchToLinearRgb({ L, C, h }: OKLCH): [number, number, number] {\n const hr = (h * Math.PI) / 180\n const a = C * Math.cos(hr)\n const b2 = C * Math.sin(hr)\n const lp = L + 0.3963377774 * a + 0.2158037573 * b2\n const mp = L - 0.1055613458 * a - 0.0638541728 * b2\n const sp = L - 0.0894841775 * a - 1.291485548 * b2\n const l = lp ** 3\n const m = mp ** 3\n const s = sp ** 3\n const r = 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s\n const g = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s\n const b = -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s\n return [r, g, b]\n}\n\nfunction inGamut([r, g, b]: [number, number, number], eps = 0.001): boolean {\n return r >= -eps && r <= 1 + eps && g >= -eps && g <= 1 + eps && b >= -eps && b <= 1 + eps\n}\n\n/**\n * Convert OKLCH → hex, reducing chroma via binary search when the\n * straightforward conversion falls outside sRGB. The search keeps `L`\n * and `h` fixed and shrinks `C` toward the achromatic axis until the\n * color fits, which is the CSS Color Level 4-recommended behavior.\n */\nexport function oklchToHex(oklch: OKLCH): HexColor {\n let rgb = oklchToLinearRgb(oklch)\n if (!inGamut(rgb)) {\n // Binary-search on C.\n let lo = 0\n let hi = oklch.C\n for (let i = 0; i < 24; i++) {\n const mid = (lo + hi) / 2\n if (inGamut(oklchToLinearRgb({ ...oklch, C: mid }))) lo = mid\n else hi = mid\n }\n rgb = oklchToLinearRgb({ ...oklch, C: lo })\n }\n const [r, g, b] = rgb.map((c) => linearToSrgb(Math.max(0, Math.min(1, c)))) as [\n number,\n number,\n number,\n ]\n return toHex(r * 255, g * 255, b * 255)\n}\n\nexport function shiftLightness(hex: HexColor, delta: number): HexColor {\n const key = `${hex}:${delta}`\n let ret = cache.get(key)\n if (ret) return ret\n\n const okl = hexToOklch(hex)\n const L = clamp(okl.L + delta, 0, 1)\n // Pull chroma toward 0 as L approaches an extreme. Keeps near-white\n // and near-black from going out of gamut.\n const margin = Math.min(L, 1 - L)\n const C = okl.C * Math.min(1, margin / 0.1)\n cache.set(key, (ret = oklchToHex({ ...okl, C, L })))\n return ret\n}\n\nexport function isDark(hex: HexColor): boolean {\n const oklch = hexToOklch(hex)\n return oklch.L < 0.6\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { n as box } from "./box-DLEcEvDH.mjs";
1
+ import { n as box } from "./box-C_N_7ChP.mjs";
2
2
  //#region src/widgets/overlay.ts
3
3
  function overlay(state, ...children) {
4
4
  const node = box({
@@ -15,4 +15,4 @@ function overlay(state, ...children) {
15
15
  //#endregion
16
16
  export { overlay as t };
17
17
 
18
- //# sourceMappingURL=overlay-9WXYiGgW.mjs.map
18
+ //# sourceMappingURL=overlay-LvOjG7kn.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"overlay-9WXYiGgW.mjs","names":[],"sources":["../src/widgets/overlay.ts"],"sourcesContent":["import type { Emitter } from \"@zaly/shared\"\nimport type { Node } from \"../core/node.ts\"\nimport type { State } from \"../core/state.ts\"\nimport type { Box, BoxStyle } from \"./box.ts\"\n\nimport { box } from \"./box.ts\"\n\nexport interface OverlayState {\n /** Absolute column (1-based) of the overlay's left edge. */\n x: number\n /** Absolute row (1-based) of the overlay's top edge. */\n y: number\n /** Higher zIndex paints on top. Default: 0. */\n zIndex?: number\n verticalAnchor?: \"top\" | \"center\" | \"bottom\"\n horizontalAnchor?: \"left\" | \"center\" | \"right\"\n relative?: \"screen\" | \"ui\" | \"stream\"\n /** If true, the overlay will be automatically removed from the renderer when closed.\n * When false, the overlay will remain in the renderer but will be hidden.\n * Default: true. */\n removeOnClose?: boolean\n}\n\ntype OverlayEvents = {\n close: {}\n}\n\nexport type Overlay<T extends Node[] = Node[]> = Box<OverlayState> & {\n children: T\n} & Emitter<OverlayEvents>\n\nexport function overlay<T extends Node[] = Node[]>(\n state: State<OverlayState & BoxStyle>,\n ...children: T\n): Overlay<T> {\n const node = box({ visible: false, ...state }, ...children) as Overlay<T>\n node.withActions({\n \"overlay.close\": {\n desc: \"Close overlay\",\n fn: () => ((node.state.removeOnClose ?? true) ? node.ctx?.overlay.remove(node) : node.hide()),\n keys: [\"esc\", \"ctrl-c\"],\n },\n })\n return node\n}\n"],"mappings":";;AA+BA,SAAgB,QACd,OACA,GAAG,UACS;CACZ,MAAM,OAAO,IAAI;EAAE,SAAS;EAAO,GAAG;CAAM,GAAG,GAAG,QAAQ;CAC1D,KAAK,YAAY,EACf,iBAAiB;EACf,MAAM;EACN,UAAY,KAAK,MAAM,iBAAiB,OAAQ,KAAK,KAAK,QAAQ,OAAO,IAAI,IAAI,KAAK,KAAK;EAC3F,MAAM,CAAC,OAAO,QAAQ;CACxB,EACF,CAAC;CACD,OAAO;AACT"}
1
+ {"version":3,"file":"overlay-LvOjG7kn.mjs","names":[],"sources":["../src/widgets/overlay.ts"],"sourcesContent":["import type { Emitter } from \"@zaly/shared\"\nimport type { Node } from \"../core/node.ts\"\nimport type { State } from \"../core/state.ts\"\nimport type { Box, BoxStyle } from \"./box.ts\"\n\nimport { box } from \"./box.ts\"\n\nexport interface OverlayState {\n /** Absolute column (1-based) of the overlay's left edge. */\n x: number\n /** Absolute row (1-based) of the overlay's top edge. */\n y: number\n /** Higher zIndex paints on top. Default: 0. */\n zIndex?: number\n verticalAnchor?: \"top\" | \"center\" | \"bottom\"\n horizontalAnchor?: \"left\" | \"center\" | \"right\"\n relative?: \"screen\" | \"ui\" | \"stream\"\n /** If true, the overlay will be automatically removed from the renderer when closed.\n * When false, the overlay will remain in the renderer but will be hidden.\n * Default: true. */\n removeOnClose?: boolean\n}\n\ntype OverlayEvents = {\n close: {}\n}\n\nexport type Overlay<T extends Node[] = Node[]> = Box<OverlayState> & {\n children: T\n} & Emitter<OverlayEvents>\n\nexport function overlay<T extends Node[] = Node[]>(\n state: State<OverlayState & BoxStyle>,\n ...children: T\n): Overlay<T> {\n const node = box({ visible: false, ...state }, ...children) as Overlay<T>\n node.withActions({\n \"overlay.close\": {\n desc: \"Close overlay\",\n fn: () => ((node.state.removeOnClose ?? true) ? node.ctx?.overlay.remove(node) : node.hide()),\n keys: [\"esc\", \"ctrl-c\"],\n },\n })\n return node\n}\n"],"mappings":";;AA+BA,SAAgB,QACd,OACA,GAAG,UACS;CACZ,MAAM,OAAO,IAAI;EAAE,SAAS;EAAO,GAAG;CAAM,GAAG,GAAG,QAAQ;CAC1D,KAAK,YAAY,EACf,iBAAiB;EACf,MAAM;EACN,UAAY,KAAK,MAAM,iBAAiB,OAAQ,KAAK,KAAK,QAAQ,OAAO,IAAI,IAAI,KAAK,KAAK;EAC3F,MAAM,CAAC,OAAO,QAAQ;CACxB,EACF,CAAC;CACD,OAAO;AACT"}
@@ -1,8 +1,8 @@
1
- import { Ut as NodeActionMap, X as State, nt as Reactive, rt as Ref } from "./queries-Cvalgu6P.mjs";
2
- import { t as Input } from "./input-Dylds_sI.mjs";
1
+ import { Gt as NodeActionMap, Q as State, at as Ref, it as Reactive } from "./queries-C75-wG1B.mjs";
2
+ import { t as Input } from "./input-NuD8TH8N.mjs";
3
3
  import { n as SearchOptions, r as SearchItem, t as SearchItems } from "./search-FvGnswRl.mjs";
4
- import { i as Select, o as SelectState, t as Option } from "./select-zGd5pbiB.mjs";
5
- import { r as TreeProps, t as TreeItem } from "./tree-CArtDRec.mjs";
4
+ import { i as Select, o as SelectState, t as Option } from "./select-BKE5LzdN.mjs";
5
+ import { r as TreeProps, t as TreeItem } from "./tree-CTvSpF9b.mjs";
6
6
  //#region src/widgets/picker.d.ts
7
7
  type PickerItem = Option & SearchItem;
8
8
  type PickerActions = keyof ReturnType<typeof picker>["actions"];
@@ -33,4 +33,4 @@ declare const picker: <T extends PickerItem = PickerItem>(props: State<PickerSel
33
33
  };
34
34
  //#endregion
35
35
  export { picker as a, PickerTreeProps as i, PickerItem as n, PickerSelectProps as r, PickerActions as t };
36
- //# sourceMappingURL=picker-JL8lZfRH.d.mts.map
36
+ //# sourceMappingURL=picker-B-OxKKnD.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"picker-JL8lZfRH.d.mts","names":[],"sources":["../src/widgets/picker.ts"],"mappings":";;;;;;KAgBY,aAAa,SAAS;KACtB,sBAAsB,kBAAkB;KAE/C,gBAAgB,UAAU,aAAa,cAAc,cAAc;;;;;;;EAOtE,QAAQ,QAAQ,IAAI;EACpB,UAAU;EACV;EACA,UAAU,cAAc,OAAO;;KAGrB,kBAAkB,UAAU,aAAa,cAAc,gBAAgB,KACjF,KAAK,YAAY;EACf,OAAO,SAAS,YAAY;EAC5B;;KAGQ,gBAAgB,UAAU,WAAW,YAAY,gBAAgB,KAC3E,UAAU;EACR;;cASS,SACV,UAAU,aAAU,YAAA,OAAsB,MAAM,kBAAkB,KAAK,gBAAgB,QAAG,OAAA"}
1
+ {"version":3,"file":"picker-B-OxKKnD.d.mts","names":[],"sources":["../src/widgets/picker.ts"],"mappings":";;;;;;KAgBY,aAAa,SAAS;KACtB,sBAAsB,kBAAkB;KAE/C,gBAAgB,UAAU,aAAa,cAAc,cAAc;;;;;;;EAOtE,QAAQ,QAAQ,IAAI;EACpB,UAAU;EACV;EACA,UAAU,cAAc,OAAO;;KAGrB,kBAAkB,UAAU,aAAa,cAAc,gBAAgB,KACjF,KAAK,YAAY;EACf,OAAO,SAAS,YAAY;EAC5B;;KAGQ,gBAAgB,UAAU,WAAW,YAAY,gBAAgB,KAC3E,UAAU;EACR;;cASS,SACV,UAAU,aAAU,YAAA,OAAsB,MAAM,kBAAkB,KAAK,gBAAgB,QAAG,OAAA"}
@@ -1,6 +1,6 @@
1
1
  import { S as unwrap, f as effect, h as memo, s as createProgressive, x as untrack } from "./reactive-f7NpAi69.mjs";
2
2
  import { t as widget } from "./widget-BkMwhY2p.mjs";
3
- import { t as Input } from "./input-D7fQEUdt.mjs";
3
+ import { t as Input } from "./input-ET2YEMcl.mjs";
4
4
  import { n as select } from "./select-m7NE6Rwa.mjs";
5
5
  import { t as tree } from "./tree-Bo1afYhe.mjs";
6
6
  import { sliceAnsi, stripAnsi } from "@zaly/shared/ansi";
@@ -618,4 +618,4 @@ const picker = widget((props) => {
618
618
  //#endregion
619
619
  export { picker as t };
620
620
 
621
- //# sourceMappingURL=picker-BqHINl_a.mjs.map
621
+ //# sourceMappingURL=picker-f6xjgACX.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"picker-BqHINl_a.mjs","names":[],"sources":["../src/search/score.ts","../src/search/matcher.ts","../src/search/sort.ts","../src/search/search.ts","../src/widgets/picker.ts"],"sourcesContent":["export type ScoreOptions = {\n filenameBonus?: boolean\n historyBonus?: boolean\n}\n\nconst SCORE_MATCH = 16\nconst SCORE_GAP_START = -3\nconst SCORE_GAP_EXTENSION = -1\n\nconst BONUS_BOUNDARY = SCORE_MATCH / 2\nconst BONUS_NONWORD = SCORE_MATCH / 2\nconst BONUS_CAMEL_123 = BONUS_BOUNDARY - 1\nconst BONUS_CONSECUTIVE = -(SCORE_GAP_START + SCORE_GAP_EXTENSION)\nconst BONUS_FIRST_CHAR_MULTIPLIER = 2\nconst BONUS_NO_PATH_SEP = BONUS_BOUNDARY - 2\n\nconst CHAR_WHITE = 0\nconst CHAR_NONWORD = 1\nconst CHAR_DELIMITER = 2\nconst CHAR_LOWER = 3\nconst CHAR_UPPER = 4\nconst CHAR_LETTER = 5\nconst CHAR_NUMBER = 6\n\nconst PATH_SEPS = new Set([\"/\", \"\\\\\"])\n\nconst CHAR_CLASS = Array.from({ length: 256 }, (_, b) => {\n const ch = String.fromCharCode(b)\n if (/\\s/.test(ch)) return CHAR_WHITE\n if (String.raw`/\\,:;|`.includes(ch)) return CHAR_DELIMITER\n if (b >= 48 && b <= 57) return CHAR_NUMBER\n if (b >= 65 && b <= 90) return CHAR_UPPER\n if (b >= 97 && b <= 122) return CHAR_LOWER\n return CHAR_NONWORD\n})\n\nfunction charClass(str: string, pos: number): number {\n const code = str.charCodeAt(pos)\n return code <= 255 ? (CHAR_CLASS[code] ?? CHAR_NONWORD) : CHAR_LETTER\n}\n\nexport class Score {\n readonly #opts: ScoreOptions\n readonly #bonusMatrix: number[][] = []\n readonly #bonusBoundaryWhite: number\n readonly #bonusBoundaryDelimiter: number\n\n #consecutive = 0\n #firstBonus = 0\n #prev: number | undefined\n #prevClass = CHAR_WHITE\n #score = 0\n #str = \"\"\n\n isFile = false\n\n constructor(opts: ScoreOptions = {}) {\n this.#opts = opts\n this.#bonusBoundaryWhite = opts.historyBonus ? BONUS_BOUNDARY : BONUS_BOUNDARY + 2\n this.#bonusBoundaryDelimiter = opts.historyBonus ? BONUS_BOUNDARY : BONUS_BOUNDARY + 1\n for (let prev = 0; prev <= 6; prev++) {\n this.#bonusMatrix[prev] = []\n for (let curr = 0; curr <= 6; curr++) {\n this.#bonusMatrix[prev][curr] = this.#computeBonus(prev, curr)\n }\n }\n }\n\n get score(): number {\n return this.#score\n }\n\n isLeftBoundary(str: string, pos: number): boolean {\n return pos === 0 || charClass(str, pos - 1) < CHAR_LOWER\n }\n\n isRightBoundary(str: string, pos: number): boolean {\n return pos === str.length - 1 || charClass(str, pos + 1) < CHAR_LOWER\n }\n\n init(str: string, first: number): void {\n this.#str = str\n this.#score = 0\n this.#consecutive = 0\n this.#prevClass = first > 0 ? charClass(str, first - 1) : CHAR_WHITE\n this.#prev = undefined\n this.#firstBonus = 0\n\n if (this.isFile && this.#opts.filenameBonus && !hasPathSepAfter(str, first)) {\n this.#score += BONUS_NO_PATH_SEP\n }\n this.update(first)\n }\n\n update(pos: number): void {\n const cls = charClass(this.#str, pos)\n const gap = this.#prev === undefined ? 0 : pos - this.#prev - 1\n let bonus = 0\n\n if (gap > 0) {\n this.#prevClass = charClass(this.#str, pos - 1)\n bonus = this.#bonusMatrix[this.#prevClass]?.[cls] ?? 0\n this.#score += SCORE_GAP_START + (gap - 1) * SCORE_GAP_EXTENSION\n this.#consecutive = 0\n this.#firstBonus = 0\n } else {\n bonus = this.#bonusMatrix[this.#prevClass]?.[cls] ?? 0\n if (this.#consecutive === 0) {\n this.#firstBonus = bonus\n } else {\n if (bonus >= BONUS_BOUNDARY && bonus > this.#firstBonus) this.#firstBonus = bonus\n bonus = Math.max(bonus, this.#firstBonus, BONUS_CONSECUTIVE)\n }\n this.#consecutive++\n }\n\n if (this.#prev === undefined) bonus *= BONUS_FIRST_CHAR_MULTIPLIER\n this.#score += SCORE_MATCH + bonus\n this.#prevClass = cls\n this.#prev = pos\n }\n\n get(str: string, from: number, to: number): number {\n this.init(str, from)\n for (let i = from + 1; i <= to; i++) this.update(i)\n return this.#score\n }\n\n #computeBonus(prev: number, curr: number): number {\n if (curr > CHAR_NONWORD) {\n if (prev === CHAR_WHITE) return this.#bonusBoundaryWhite\n if (prev === CHAR_DELIMITER) return this.#bonusBoundaryDelimiter\n if (prev === CHAR_NONWORD) return BONUS_BOUNDARY\n }\n if (\n (prev === CHAR_LOWER && curr === CHAR_UPPER) ||\n (prev !== CHAR_NUMBER && curr === CHAR_NUMBER)\n ) {\n return BONUS_CAMEL_123\n }\n if (curr === CHAR_NONWORD || curr === CHAR_DELIMITER) return BONUS_NONWORD\n if (curr === CHAR_WHITE) return BONUS_BOUNDARY + 2\n return 0\n }\n}\n\nfunction hasPathSepAfter(str: string, first: number): boolean {\n for (let i = first + 1; i < str.length; i++) if (PATH_SEPS.has(str[i])) return true\n return false\n}\n","import type { ScoreOptions } from \"./score.ts\"\n\nimport { Score } from \"./score.ts\"\n\nexport type SearchItem = {\n idx?: number\n score?: number\n file?: string\n text: string\n}\n\nexport type ScoredItem<T extends SearchItem = SearchItem> = T & {\n score: number\n topk?: boolean\n}\n\nexport type MatcherOptions = ScoreOptions & {\n fuzzy?: boolean\n ignorecase?: boolean\n regex?: boolean\n smartcase?: boolean\n}\n\ntype Mod = {\n chars: string[]\n entropy: number\n exactPrefix?: boolean\n exactSuffix?: boolean\n field?: string\n fuzzy?: boolean\n ignorecase?: boolean\n inverse?: boolean\n pattern: string\n re?: RegExp\n regex?: boolean\n word?: boolean\n}\n\ntype Match = {\n from: number\n score: number\n search: string\n str: string\n to: number\n}\n\nexport class Matcher<T extends SearchItem = SearchItem> {\n readonly opts: Required<Pick<MatcherOptions, \"fuzzy\" | \"ignorecase\" | \"smartcase\">> &\n MatcherOptions\n readonly score: Score\n mods: Mod[][] = []\n one: Mod | undefined\n pattern = \"\"\n tick = 0\n\n constructor(opts: MatcherOptions = {}) {\n this.opts = {\n fuzzy: true,\n ignorecase: true,\n smartcase: true,\n ...opts,\n }\n this.score = new Score(opts)\n }\n\n empty(): boolean {\n return this.mods.length === 0\n }\n\n init(pattern: string): boolean {\n pattern = pattern.trim()\n if (pattern === this.pattern) return false\n\n this.pattern = pattern\n this.tick++\n this.mods = []\n this.one = undefined\n if (pattern === \"\") return true\n\n if (this.opts.regex) {\n this.mods = [[this.#prepare(pattern)]]\n } else {\n let isOr = false\n for (const part of pattern.split(/ +/)) {\n if (part === \"|\") {\n isOr = true\n continue\n }\n const mod = this.#prepare(part)\n if (mod.pattern === \"\") continue\n if (isOr && this.mods.length > 0) this.mods.at(-1)?.push(mod)\n else this.mods.push([mod])\n isOr = false\n }\n }\n\n this.mods = this.mods.map((ors) => ors.toSorted((a, b) => a.entropy - b.entropy))\n this.mods = this.mods.toSorted((a, b) => (b[0]?.entropy ?? 0) - (a[0]?.entropy ?? 0))\n if (this.mods.length === 1 && this.mods[0]?.length === 1) this.one = this.mods[0][0]\n return true\n }\n\n match(input: T | string): number {\n if (this.empty()) return 1000\n const item = typeof input === \"string\" ? { text: input } : input\n if (this.one) return this.#match(item, this.one)?.score ?? 0\n\n let score = 0\n for (const any of this.mods) {\n let match: Match | undefined\n for (const mod of any) {\n match = this.#match(item, mod)\n if (match) break\n }\n if (!match) return 0\n score += match.score\n }\n return score\n }\n\n update(item: T): ScoredItem<T> {\n const score = this.match(item)\n const it = item as ScoredItem<T>\n it.score = score\n return it\n }\n\n positions(input: T | string): number[] {\n if (this.empty()) return []\n const item = typeof input === \"string\" ? { text: input } : input\n const ret: number[] = []\n const all = this.mods.flat()\n for (const mod of all) {\n const match = this.#match(item, mod)\n if (!match) continue\n if (mod.fuzzy) ret.push(...this.#fuzzyPositions(match.search, mod.chars, match.from))\n else for (let i = match.from; i <= match.to; i++) ret.push(i)\n }\n return [...new Set(ret)].toSorted((a, b) => a - b)\n }\n\n fields(): string[] {\n const ret = new Set<string>()\n for (const mod of this.mods.flat()) ret.add(mod.field ?? \"text\")\n return [...ret]\n }\n\n #prepare(pattern: string): Mod {\n const mod: Mod = { chars: [], entropy: 0, pattern }\n\n if (this.opts.regex) {\n mod.regex = true\n const isLower = mod.pattern.toLowerCase() === mod.pattern\n mod.ignorecase = this.opts.smartcase ? isLower : this.opts.ignorecase\n try {\n mod.re = new RegExp(mod.pattern, mod.ignorecase ? \"i\" : undefined)\n } catch {\n mod.re = undefined\n }\n } else {\n const file = parseFilePattern(pattern)\n if (file) {\n mod.field = \"file\"\n mod.pattern = `${file}$`\n }\n\n const field = mod.pattern.match(/^([\\w_][\\w_]+):(.*)$/)\n if (field) {\n mod.field = field[1]\n mod.pattern = field[2]\n }\n\n mod.ignorecase = this.opts.ignorecase\n const isLower = mod.pattern.toLowerCase() === mod.pattern\n if (this.opts.smartcase) mod.ignorecase = isLower\n mod.fuzzy = this.opts.fuzzy\n if (!mod.fuzzy) mod.entropy += 10\n\n if (mod.pattern.startsWith(\"!\")) {\n mod.fuzzy = false\n mod.inverse = true\n mod.pattern = mod.pattern.slice(1)\n mod.entropy -= 1\n }\n if (mod.pattern.startsWith(\"'\")) {\n mod.fuzzy = false\n mod.pattern = mod.pattern.slice(1)\n mod.entropy += 10\n if (mod.pattern.endsWith(\"'\")) {\n mod.word = true\n mod.pattern = mod.pattern.slice(0, -1)\n mod.entropy += 10\n }\n } else if (mod.pattern.startsWith(\"^\")) {\n mod.fuzzy = false\n mod.exactPrefix = true\n mod.pattern = mod.pattern.slice(1)\n mod.entropy += 20\n }\n if (mod.pattern.endsWith(\"$\")) {\n mod.fuzzy = false\n mod.exactSuffix = true\n mod.pattern = mod.pattern.slice(0, -1)\n mod.entropy += 20\n }\n\n const rareChars = (mod.pattern.match(/[^\\w\\s]/g) ?? []).length\n mod.entropy += Math.min(mod.pattern.length, 20) + rareChars * 2\n if (!mod.ignorecase && !isLower) mod.entropy *= 2\n if (mod.ignorecase) mod.pattern = mod.pattern.toLowerCase()\n }\n\n // oxlint-disable-next-line typescript/no-misused-spread\n mod.chars = [...mod.pattern]\n return mod\n }\n\n #match(item: SearchItem, mod: Mod): Match | undefined {\n this.score.isFile = itemField(item, \"file\") !== undefined\n let str = item.text\n\n if (mod.field) {\n const value = itemField(item, mod.field)\n if (value === undefined)\n return mod.inverse ? { from: 0, score: 1000, search: str, str, to: 0 } : undefined\n str = value\n }\n\n const original = str\n if (mod.ignorecase) str = str.toLowerCase()\n\n if (mod.regex) return this.#regex(original, mod)\n if (mod.fuzzy) return this.#fuzzy(str, original, mod.chars)\n\n let from = -1\n let to = -1\n if (mod.exactPrefix) {\n if (str.startsWith(mod.pattern)) {\n from = 0\n to = mod.pattern.length - 1\n }\n } else if (mod.exactSuffix) {\n if (str.endsWith(mod.pattern)) {\n from = str.length - mod.pattern.length\n to = str.length - 1\n }\n } else {\n from = str.indexOf(mod.pattern)\n to = from + mod.pattern.length - 1\n while (mod.word && from >= 0) {\n if (this.score.isLeftBoundary(str, from) && this.score.isRightBoundary(str, to)) break\n from = str.indexOf(mod.pattern, to + 1)\n to = from + mod.pattern.length - 1\n }\n }\n\n if (mod.inverse)\n return from === -1 ? { from: 0, score: 1000, search: str, str: original, to: 0 } : undefined\n if (from >= 0)\n return { from, score: this.score.get(original, from, to), search: str, str: original, to }\n return undefined\n }\n\n #regex(str: string, mod: Mod): Match | undefined {\n const match = mod.re?.exec(str)\n if (!match?.[0]) return undefined\n const from = match.index\n const to = from + match[0].length - 1\n return { from, score: this.score.get(str, from, to), search: str, str, to }\n }\n\n #fuzzyFind(\n str: string,\n original: string,\n pattern: string[],\n init = 0\n ): Pick<Match, \"from\" | \"to\" | \"score\"> | undefined {\n const from = str.indexOf(pattern[0] ?? \"\", init)\n if (from === -1) return undefined\n this.score.init(original, from)\n let last = from\n for (let i = 1; i < pattern.length; i++) {\n last = str.indexOf(pattern[i], last + 1)\n // Bail before reading the score: a partial accumulation never\n // escapes this method, so `#fuzzy` only ever sees a score that\n // corresponds to a fully-matched window.\n if (last === -1) return undefined\n this.score.update(last)\n }\n return { from, score: this.score.score, to: last }\n }\n\n #fuzzy(str: string, original: string, pattern: string[]): Match | undefined {\n // Anchor on every occurrence of the first char and keep the\n // highest-scoring window. The score rides in the return value rather\n // than being read off the shared `this.score`, so there's no\n // \"is the accumulator aligned with `best` right now?\" invariant.\n let best = this.#fuzzyFind(str, original, pattern)\n if (!best) return undefined\n for (\n let next = this.#fuzzyFind(str, original, pattern, best.from + 1);\n next;\n next = this.#fuzzyFind(str, original, pattern, next.from + 1)\n ) {\n if (next.score > best.score) best = next\n }\n return { from: best.from, score: best.score, search: str, str: original, to: best.to }\n }\n\n #fuzzyPositions(str: string, pattern: string[], from: number): number[] {\n const ret = [from]\n let last = from\n for (let i = 1; i < pattern.length; i++) {\n last = str.indexOf(pattern[i], last + 1)\n if (last === -1) break\n ret.push(last)\n }\n return ret\n }\n}\n\nfunction itemField(item: SearchItem, field: string): string | undefined {\n const value = item[field as keyof SearchItem] as unknown\n if (value === undefined || value === null) return undefined\n if (typeof value === \"string\") return value\n if (typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\")\n return String(value)\n if (Array.isArray(value)) return value.join(\" \")\n return\n}\n\nfunction parseFilePattern(pattern: string): string | undefined {\n return (\n pattern.match(/^(.*[/\\\\].*):\\d*:?:?\\d*$/)?.[1] ??\n pattern.match(/^(.+\\.[a-z_]+):\\d*:?:?\\d*$/)?.[1]\n )\n}\n","import type { ScoredItem, SearchItem } from \"./matcher.ts\"\n\ntype SortKey<T extends SearchItem> = Extract<keyof (ScoredItem<T> & SearchItem), string>\n\nexport type SortField<T extends SearchItem = SearchItem> =\n | SortKey<T>\n | `#${SortKey<T>}`\n | `${SortKey<T>}:desc`\n\nexport type ParsedField<T extends SearchItem = SearchItem> = {\n desc?: boolean\n len?: boolean\n name: SortKey<T>\n}\n\nexport type Sorter<T extends SearchItem = SearchItem> = (\n a: ScoredItem<T>,\n b: ScoredItem<T>\n) => number\n\nfunction parse<T extends SearchItem>(field: SortField<T>): ParsedField<T> {\n const len = field.startsWith(\"#\")\n const desc = field.endsWith(\":desc\")\n const name = field.replace(/^#/, \"\").replace(/:desc$/, \"\") as SortKey<T>\n return { desc, len, name }\n}\n\nexport function sorter<T extends SearchItem>(\n fields: readonly SortField<T>[] = [\"score:desc\", \"#text\", \"idx\"]\n): Sorter<T> {\n const parsed: ParsedField<T>[] = fields.map(parse)\n return (a, b) => {\n for (const field of parsed) {\n let av: unknown = a[field.name]\n let bv: unknown = b[field.name]\n if (av === undefined || bv === undefined) continue\n if (field.len) {\n av = typeof av === \"string\" || Array.isArray(av) ? av.length : 0\n bv = typeof bv === \"string\" || Array.isArray(bv) ? bv.length : 0\n }\n if (av === bv) continue\n if (typeof av === \"boolean\" && typeof bv === \"boolean\") {\n av = av ? 0 : 1\n bv = bv ? 0 : 1\n }\n return compare(av, bv) * (field.desc ? -1 : 1)\n }\n return 0\n }\n}\n\nfunction compare(a: unknown, b: unknown): number {\n if (typeof a === \"number\" && typeof b === \"number\") return a - b\n if (typeof a === \"string\" && typeof b === \"string\") return a.localeCompare(b)\n return String(a).localeCompare(String(b))\n}\n","// oxlint-disable no-await-in-loop\nimport type { MaybePromise } from \"@zaly/shared\"\nimport type { MatcherOptions, ScoredItem, SearchItem } from \"./matcher.ts\"\nimport type { Sorter, SortField } from \"./sort.ts\"\n\nimport { TopK } from \"@zaly/shared/minheap\"\nimport { Matcher } from \"./matcher.ts\"\nimport { sorter } from \"./sort.ts\"\n\nexport type SearchOptions<T extends SearchItem = SearchItem> = MatcherOptions & {\n sort?: boolean | readonly SortField<T>[]\n filter?: boolean\n sortEmpty?: boolean\n frecency?: () => (file: string) => number\n limit?: number\n throttle?: number\n}\n\nexport type SearchFn<T extends SearchItem = SearchItem> = (\n query: string,\n match: Match<T>\n) => MaybePromise<ScoredItem<T>[]>\n\nexport type SearchItems<T extends SearchItem = SearchItem> = readonly T[] | SearchFn<T>\n\n/** Match function handed to `complete`. Returns `0` for no match,\n * positive integer otherwise — so both `match(s) > 0` and the\n * idiomatic `.filter(match(s))` work (0 is falsy). The magnitude is a\n * score the source can use to rank its own candidates when it cares\n * about order. */\nexport type Match<T extends SearchItem = SearchItem> = (s: string | T) => number\n\nconst BONUS_FRECENCY = 8\nconst SEARCH_LIMIT = 1000\nconst aborted = Symbol(\"search.aborted\")\n\nexport class Searcher<T extends SearchItem = SearchItem> {\n #opts: SearchOptions<T>\n #sorter?: Sorter<T>\n #matcher: Matcher<T>\n #ac?: AbortController\n\n constructor(opts: SearchOptions<T>) {\n this.#opts = opts\n const sortOpts = opts.sort === true ? undefined : opts.sort\n this.#sorter = sortOpts === false ? undefined : sorter(sortOpts)\n this.#matcher = new Matcher(opts)\n }\n\n /** Create a match function bound to the current pattern. If the\n * matcher has been updated since the search started, match will\n * return `0` to indicate no match, to prevent stale results */\n createMatch(opts: { signal: AbortSignal }): Match<T> {\n const m = this.#matcher\n return (s: string | T) => (opts.signal.aborted ? 0 : m.match(s))\n }\n\n async search(\n items: SearchItems<T>,\n query = \"\",\n opts: { progress?: (results: ScoredItem<T>[]) => MaybePromise } = {}\n ): Promise<ScoredItem<T>[]> {\n try {\n return await this.#search(items, query, opts)\n } catch (error) {\n if (error === aborted) return []\n throw error\n }\n }\n\n get limit(): number {\n return this.#opts.limit ?? (this.#sorter ? SEARCH_LIMIT : Infinity)\n }\n\n async #search(\n items: SearchItems<T>,\n query = \"\",\n opts: { progress?: (results: ScoredItem<T>[]) => MaybePromise } = {}\n ): Promise<ScoredItem<T>[]> {\n this.#ac?.abort(aborted)\n // oxlint-disable-next-line no-multi-assign\n const ac = (this.#ac = new AbortController())\n\n const m = this.#matcher\n m.init(query)\n const f = this.#opts.frecency?.()\n const s = this.#sorter\n const limit = this.limit\n const ret: ScoredItem<T>[] = []\n let match = (item: T) => this.#matcher.update(item)\n const topk =\n s && (this.#opts.sortEmpty || !m.empty())\n ? new TopK<ScoredItem<T>>(limit, (a, b) => -s(a, b))\n : undefined\n\n if (typeof items === \"function\") {\n match = (item: T) => item as ScoredItem<T>\n items = await items(query, this.createMatch({ signal: ac.signal }))\n ac.signal.throwIfAborted()\n }\n\n if (items.length === 0) return []\n\n const results = () => topk?.sorted() ?? ret\n\n // Process items in three phases, so that the results in the UI stabilize faster:\n // - previous topk results (topk)\n // - scored items (score)\n // - unscored items (rest)\n const todo: [T[], T[], T[]] = [[], [], []]\n let idx = 0\n if (!topk) todo[0] = items as T[]\n else {\n for (const item of items) {\n item.idx = idx++\n const it = item as ScoredItem<T>\n if (it.topk) todo[0].push(item)\n else if (it.score) todo[1].push(item)\n else todo[2].push(item)\n }\n }\n\n const doFilter = !m.empty() && (this.#opts.filter ?? true)\n\n let lastYield = performance.now()\n let dirty = false\n let count = 0\n\n loop: for (const todos of todo) {\n for (const item of todos) {\n ac.signal.throwIfAborted()\n if (count++ % 256 === 0) {\n const now = performance.now()\n if (now - lastYield >= (this.#opts.throttle ?? 16)) {\n lastYield = now\n await new Promise((r) => setImmediate(r))\n if (opts.progress && dirty) {\n dirty = false\n await opts.progress(results())\n }\n }\n }\n const si = match(item)\n if (si.file && si.score && f) {\n const frecency = f(si.file)\n si.score += (1 - 1 / (1 + frecency)) * BONUS_FRECENCY\n }\n if (doFilter && si.score === 0) continue\n if (topk) {\n si.topk = false\n const ta = topk.add(si)\n if (ta.added) {\n si.topk = true\n dirty = true\n if (ta.evicted) ta.evicted.topk = false\n }\n } else {\n ret.push(si)\n dirty = true\n if (ret.length >= limit) break loop\n }\n }\n }\n\n return results()\n }\n\n positions(s: string | T): number[] {\n return this.#matcher.positions(s)\n }\n}\n","import type { Reactive, Ref } from \"../core/reactive.ts\"\nimport type { State } from \"../core/state.ts\"\nimport type { NodeActionMap } from \"../input/actions.ts\"\nimport type { ScoredItem, SearchItem } from \"../search/matcher.ts\"\nimport type { SearchItems, SearchOptions } from \"../search/search.ts\"\nimport type { Option, Select, SelectState } from \"./select.ts\"\nimport type { TreeItem, TreeProps } from \"./tree.ts\"\n\nimport { sliceAnsi, stripAnsi } from \"@zaly/shared/ansi\"\nimport { createProgressive, effect, memo, untrack, unwrap } from \"../core/reactive.ts\"\nimport { Searcher } from \"../search/search.ts\"\nimport { Input } from \"./input.ts\"\nimport { select } from \"./select.ts\"\nimport { tree } from \"./tree.ts\"\nimport { widget } from \"./widget.ts\"\n\nexport type PickerItem = Option & SearchItem\nexport type PickerActions = keyof ReturnType<typeof picker>[\"actions\"]\n\ntype PickerBaseProps<T extends PickerItem = PickerItem> = SearchOptions<T> & {\n /** The `Input` to watch. Pass the node directly, or a `Ref<Input>`\n * populated by `node.ref(ref)` elsewhere in the tree — the latter\n * enables fully inline composition where the input doesn't need a\n * local binding. The ref is dereferenced on mount, so wiring is\n * type-safe and ordering-flexible (autocomplete can be constructed\n * before the Input is). */\n input?: Input | Ref<Input>\n pattern?: Reactive<string>\n reverse?: boolean\n actions?: NodeActionMap<Select<T>>\n}\n\nexport type PickerSelectProps<T extends PickerItem = PickerItem> = PickerBaseProps<T> &\n Omit<SelectState<T>, \"items\"> & {\n items: Reactive<SearchItems<T>>\n tree?: never\n }\n\nexport type PickerTreeProps<T extends TreeItem = TreeItem> = PickerBaseProps<T> &\n TreeProps<T> & {\n items?: never\n }\n\nfunction isTree<T extends Option = Option>(\n props: PickerTreeProps<T> | PickerSelectProps<T>\n): props is PickerTreeProps<T> {\n return \"tree\" in props\n}\n\nexport const picker = widget(\n <T extends PickerItem = PickerItem>(props: State<PickerSelectProps<T> | PickerTreeProps<T>>) => {\n const pattern = memo(() => {\n if (props.pattern !== undefined) return unwrap(props.pattern)\n const inp = props.input instanceof Input ? props.input : props.input?.()\n return inp?.state.value ?? \"\"\n })\n\n let node: Select<T>\n let items: Reactive<SearchItems<T>>\n if (isTree(props)) {\n props = { filter: false, fuzzy: false, sort: false, ...props }\n const t = tree(props)\n node = t\n items = t.items\n } else {\n node = select({ ...props, items: [] })\n items = props.items\n }\n const searcher = new Searcher<T>(props)\n\n node.extendRenderer((prev) => (item, ctx) => {\n let row = prev(item, ctx)\n if (!item.score) return row\n const stripped = stripAnsi(row)\n const positions = searcher.positions(stripped).toSorted((a, b) => b - a)\n while (positions.length > 0) {\n const from = positions.pop()!\n let to = from\n while (positions.length && positions.at(-1) === to + 1) to = positions.pop()!\n row =\n sliceAnsi(row, 0, from) +\n ctx.style.accent(stripped.slice(from, to + 1)) +\n sliceAnsi(row, to + 1)\n }\n return row\n })\n\n const results = createProgressive<ScoredItem<T>[]>(\n async ({ set }) =>\n await searcher.search(unwrap(items), pattern(), { progress: (r) => set(r) }),\n {\n initialValue: [],\n }\n )\n node.state.items = results\n if (props.input) node.bind(props.input)\n\n const matches = () =>\n unwrap(node.state.items)\n .map((item, i) => [item, i] as const)\n .filter(([item]) => item.score)\n .map(([, i]) => i)\n\n effect(() => {\n const m = matches()\n node.state.more = m.length >= searcher.limit\n if (m.length === 0 || pattern() === \"\") return\n untrack(() => {\n // When filtering, go to the first (best) match.\n // When not filtering, go to the first match that is at or after the current active index, or the first match if none are after.\n if (props.filter === false) {\n const active = node.active\n node.active = m.find((i) => i >= active) ?? m[0]\n } else node.active = 0\n })\n })\n\n return node.withActions({\n ...props.actions,\n \"picker.next\": () => {\n const active = node.active\n const m = matches()\n if (m.length === 0) return node.action(\"select.next\")\n node.active = node.state.reverse\n ? (m.toReversed().find((i) => i < active) ?? m.at(-1)!)\n : (m.find((i) => i > active) ?? m[0])\n },\n \"picker.prev\": () => {\n const active = node.active\n const m = matches()\n if (m.length === 0) return node.action(\"select.prev\")\n node.active = node.state.reverse\n ? (m.find((i) => i > active) ?? m[0])\n : (m.toReversed().find((i) => i < active) ?? m.at(-1)!)\n },\n })\n }\n)\n"],"mappings":"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"}
1
+ {"version":3,"file":"picker-f6xjgACX.mjs","names":[],"sources":["../src/search/score.ts","../src/search/matcher.ts","../src/search/sort.ts","../src/search/search.ts","../src/widgets/picker.ts"],"sourcesContent":["export type ScoreOptions = {\n filenameBonus?: boolean\n historyBonus?: boolean\n}\n\nconst SCORE_MATCH = 16\nconst SCORE_GAP_START = -3\nconst SCORE_GAP_EXTENSION = -1\n\nconst BONUS_BOUNDARY = SCORE_MATCH / 2\nconst BONUS_NONWORD = SCORE_MATCH / 2\nconst BONUS_CAMEL_123 = BONUS_BOUNDARY - 1\nconst BONUS_CONSECUTIVE = -(SCORE_GAP_START + SCORE_GAP_EXTENSION)\nconst BONUS_FIRST_CHAR_MULTIPLIER = 2\nconst BONUS_NO_PATH_SEP = BONUS_BOUNDARY - 2\n\nconst CHAR_WHITE = 0\nconst CHAR_NONWORD = 1\nconst CHAR_DELIMITER = 2\nconst CHAR_LOWER = 3\nconst CHAR_UPPER = 4\nconst CHAR_LETTER = 5\nconst CHAR_NUMBER = 6\n\nconst PATH_SEPS = new Set([\"/\", \"\\\\\"])\n\nconst CHAR_CLASS = Array.from({ length: 256 }, (_, b) => {\n const ch = String.fromCharCode(b)\n if (/\\s/.test(ch)) return CHAR_WHITE\n if (String.raw`/\\,:;|`.includes(ch)) return CHAR_DELIMITER\n if (b >= 48 && b <= 57) return CHAR_NUMBER\n if (b >= 65 && b <= 90) return CHAR_UPPER\n if (b >= 97 && b <= 122) return CHAR_LOWER\n return CHAR_NONWORD\n})\n\nfunction charClass(str: string, pos: number): number {\n const code = str.charCodeAt(pos)\n return code <= 255 ? (CHAR_CLASS[code] ?? CHAR_NONWORD) : CHAR_LETTER\n}\n\nexport class Score {\n readonly #opts: ScoreOptions\n readonly #bonusMatrix: number[][] = []\n readonly #bonusBoundaryWhite: number\n readonly #bonusBoundaryDelimiter: number\n\n #consecutive = 0\n #firstBonus = 0\n #prev: number | undefined\n #prevClass = CHAR_WHITE\n #score = 0\n #str = \"\"\n\n isFile = false\n\n constructor(opts: ScoreOptions = {}) {\n this.#opts = opts\n this.#bonusBoundaryWhite = opts.historyBonus ? BONUS_BOUNDARY : BONUS_BOUNDARY + 2\n this.#bonusBoundaryDelimiter = opts.historyBonus ? BONUS_BOUNDARY : BONUS_BOUNDARY + 1\n for (let prev = 0; prev <= 6; prev++) {\n this.#bonusMatrix[prev] = []\n for (let curr = 0; curr <= 6; curr++) {\n this.#bonusMatrix[prev][curr] = this.#computeBonus(prev, curr)\n }\n }\n }\n\n get score(): number {\n return this.#score\n }\n\n isLeftBoundary(str: string, pos: number): boolean {\n return pos === 0 || charClass(str, pos - 1) < CHAR_LOWER\n }\n\n isRightBoundary(str: string, pos: number): boolean {\n return pos === str.length - 1 || charClass(str, pos + 1) < CHAR_LOWER\n }\n\n init(str: string, first: number): void {\n this.#str = str\n this.#score = 0\n this.#consecutive = 0\n this.#prevClass = first > 0 ? charClass(str, first - 1) : CHAR_WHITE\n this.#prev = undefined\n this.#firstBonus = 0\n\n if (this.isFile && this.#opts.filenameBonus && !hasPathSepAfter(str, first)) {\n this.#score += BONUS_NO_PATH_SEP\n }\n this.update(first)\n }\n\n update(pos: number): void {\n const cls = charClass(this.#str, pos)\n const gap = this.#prev === undefined ? 0 : pos - this.#prev - 1\n let bonus = 0\n\n if (gap > 0) {\n this.#prevClass = charClass(this.#str, pos - 1)\n bonus = this.#bonusMatrix[this.#prevClass]?.[cls] ?? 0\n this.#score += SCORE_GAP_START + (gap - 1) * SCORE_GAP_EXTENSION\n this.#consecutive = 0\n this.#firstBonus = 0\n } else {\n bonus = this.#bonusMatrix[this.#prevClass]?.[cls] ?? 0\n if (this.#consecutive === 0) {\n this.#firstBonus = bonus\n } else {\n if (bonus >= BONUS_BOUNDARY && bonus > this.#firstBonus) this.#firstBonus = bonus\n bonus = Math.max(bonus, this.#firstBonus, BONUS_CONSECUTIVE)\n }\n this.#consecutive++\n }\n\n if (this.#prev === undefined) bonus *= BONUS_FIRST_CHAR_MULTIPLIER\n this.#score += SCORE_MATCH + bonus\n this.#prevClass = cls\n this.#prev = pos\n }\n\n get(str: string, from: number, to: number): number {\n this.init(str, from)\n for (let i = from + 1; i <= to; i++) this.update(i)\n return this.#score\n }\n\n #computeBonus(prev: number, curr: number): number {\n if (curr > CHAR_NONWORD) {\n if (prev === CHAR_WHITE) return this.#bonusBoundaryWhite\n if (prev === CHAR_DELIMITER) return this.#bonusBoundaryDelimiter\n if (prev === CHAR_NONWORD) return BONUS_BOUNDARY\n }\n if (\n (prev === CHAR_LOWER && curr === CHAR_UPPER) ||\n (prev !== CHAR_NUMBER && curr === CHAR_NUMBER)\n ) {\n return BONUS_CAMEL_123\n }\n if (curr === CHAR_NONWORD || curr === CHAR_DELIMITER) return BONUS_NONWORD\n if (curr === CHAR_WHITE) return BONUS_BOUNDARY + 2\n return 0\n }\n}\n\nfunction hasPathSepAfter(str: string, first: number): boolean {\n for (let i = first + 1; i < str.length; i++) if (PATH_SEPS.has(str[i])) return true\n return false\n}\n","import type { ScoreOptions } from \"./score.ts\"\n\nimport { Score } from \"./score.ts\"\n\nexport type SearchItem = {\n idx?: number\n score?: number\n file?: string\n text: string\n}\n\nexport type ScoredItem<T extends SearchItem = SearchItem> = T & {\n score: number\n topk?: boolean\n}\n\nexport type MatcherOptions = ScoreOptions & {\n fuzzy?: boolean\n ignorecase?: boolean\n regex?: boolean\n smartcase?: boolean\n}\n\ntype Mod = {\n chars: string[]\n entropy: number\n exactPrefix?: boolean\n exactSuffix?: boolean\n field?: string\n fuzzy?: boolean\n ignorecase?: boolean\n inverse?: boolean\n pattern: string\n re?: RegExp\n regex?: boolean\n word?: boolean\n}\n\ntype Match = {\n from: number\n score: number\n search: string\n str: string\n to: number\n}\n\nexport class Matcher<T extends SearchItem = SearchItem> {\n readonly opts: Required<Pick<MatcherOptions, \"fuzzy\" | \"ignorecase\" | \"smartcase\">> &\n MatcherOptions\n readonly score: Score\n mods: Mod[][] = []\n one: Mod | undefined\n pattern = \"\"\n tick = 0\n\n constructor(opts: MatcherOptions = {}) {\n this.opts = {\n fuzzy: true,\n ignorecase: true,\n smartcase: true,\n ...opts,\n }\n this.score = new Score(opts)\n }\n\n empty(): boolean {\n return this.mods.length === 0\n }\n\n init(pattern: string): boolean {\n pattern = pattern.trim()\n if (pattern === this.pattern) return false\n\n this.pattern = pattern\n this.tick++\n this.mods = []\n this.one = undefined\n if (pattern === \"\") return true\n\n if (this.opts.regex) {\n this.mods = [[this.#prepare(pattern)]]\n } else {\n let isOr = false\n for (const part of pattern.split(/ +/)) {\n if (part === \"|\") {\n isOr = true\n continue\n }\n const mod = this.#prepare(part)\n if (mod.pattern === \"\") continue\n if (isOr && this.mods.length > 0) this.mods.at(-1)?.push(mod)\n else this.mods.push([mod])\n isOr = false\n }\n }\n\n this.mods = this.mods.map((ors) => ors.toSorted((a, b) => a.entropy - b.entropy))\n this.mods = this.mods.toSorted((a, b) => (b[0]?.entropy ?? 0) - (a[0]?.entropy ?? 0))\n if (this.mods.length === 1 && this.mods[0]?.length === 1) this.one = this.mods[0][0]\n return true\n }\n\n match(input: T | string): number {\n if (this.empty()) return 1000\n const item = typeof input === \"string\" ? { text: input } : input\n if (this.one) return this.#match(item, this.one)?.score ?? 0\n\n let score = 0\n for (const any of this.mods) {\n let match: Match | undefined\n for (const mod of any) {\n match = this.#match(item, mod)\n if (match) break\n }\n if (!match) return 0\n score += match.score\n }\n return score\n }\n\n update(item: T): ScoredItem<T> {\n const score = this.match(item)\n const it = item as ScoredItem<T>\n it.score = score\n return it\n }\n\n positions(input: T | string): number[] {\n if (this.empty()) return []\n const item = typeof input === \"string\" ? { text: input } : input\n const ret: number[] = []\n const all = this.mods.flat()\n for (const mod of all) {\n const match = this.#match(item, mod)\n if (!match) continue\n if (mod.fuzzy) ret.push(...this.#fuzzyPositions(match.search, mod.chars, match.from))\n else for (let i = match.from; i <= match.to; i++) ret.push(i)\n }\n return [...new Set(ret)].toSorted((a, b) => a - b)\n }\n\n fields(): string[] {\n const ret = new Set<string>()\n for (const mod of this.mods.flat()) ret.add(mod.field ?? \"text\")\n return [...ret]\n }\n\n #prepare(pattern: string): Mod {\n const mod: Mod = { chars: [], entropy: 0, pattern }\n\n if (this.opts.regex) {\n mod.regex = true\n const isLower = mod.pattern.toLowerCase() === mod.pattern\n mod.ignorecase = this.opts.smartcase ? isLower : this.opts.ignorecase\n try {\n mod.re = new RegExp(mod.pattern, mod.ignorecase ? \"i\" : undefined)\n } catch {\n mod.re = undefined\n }\n } else {\n const file = parseFilePattern(pattern)\n if (file) {\n mod.field = \"file\"\n mod.pattern = `${file}$`\n }\n\n const field = mod.pattern.match(/^([\\w_][\\w_]+):(.*)$/)\n if (field) {\n mod.field = field[1]\n mod.pattern = field[2]\n }\n\n mod.ignorecase = this.opts.ignorecase\n const isLower = mod.pattern.toLowerCase() === mod.pattern\n if (this.opts.smartcase) mod.ignorecase = isLower\n mod.fuzzy = this.opts.fuzzy\n if (!mod.fuzzy) mod.entropy += 10\n\n if (mod.pattern.startsWith(\"!\")) {\n mod.fuzzy = false\n mod.inverse = true\n mod.pattern = mod.pattern.slice(1)\n mod.entropy -= 1\n }\n if (mod.pattern.startsWith(\"'\")) {\n mod.fuzzy = false\n mod.pattern = mod.pattern.slice(1)\n mod.entropy += 10\n if (mod.pattern.endsWith(\"'\")) {\n mod.word = true\n mod.pattern = mod.pattern.slice(0, -1)\n mod.entropy += 10\n }\n } else if (mod.pattern.startsWith(\"^\")) {\n mod.fuzzy = false\n mod.exactPrefix = true\n mod.pattern = mod.pattern.slice(1)\n mod.entropy += 20\n }\n if (mod.pattern.endsWith(\"$\")) {\n mod.fuzzy = false\n mod.exactSuffix = true\n mod.pattern = mod.pattern.slice(0, -1)\n mod.entropy += 20\n }\n\n const rareChars = (mod.pattern.match(/[^\\w\\s]/g) ?? []).length\n mod.entropy += Math.min(mod.pattern.length, 20) + rareChars * 2\n if (!mod.ignorecase && !isLower) mod.entropy *= 2\n if (mod.ignorecase) mod.pattern = mod.pattern.toLowerCase()\n }\n\n // oxlint-disable-next-line typescript/no-misused-spread\n mod.chars = [...mod.pattern]\n return mod\n }\n\n #match(item: SearchItem, mod: Mod): Match | undefined {\n this.score.isFile = itemField(item, \"file\") !== undefined\n let str = item.text\n\n if (mod.field) {\n const value = itemField(item, mod.field)\n if (value === undefined)\n return mod.inverse ? { from: 0, score: 1000, search: str, str, to: 0 } : undefined\n str = value\n }\n\n const original = str\n if (mod.ignorecase) str = str.toLowerCase()\n\n if (mod.regex) return this.#regex(original, mod)\n if (mod.fuzzy) return this.#fuzzy(str, original, mod.chars)\n\n let from = -1\n let to = -1\n if (mod.exactPrefix) {\n if (str.startsWith(mod.pattern)) {\n from = 0\n to = mod.pattern.length - 1\n }\n } else if (mod.exactSuffix) {\n if (str.endsWith(mod.pattern)) {\n from = str.length - mod.pattern.length\n to = str.length - 1\n }\n } else {\n from = str.indexOf(mod.pattern)\n to = from + mod.pattern.length - 1\n while (mod.word && from >= 0) {\n if (this.score.isLeftBoundary(str, from) && this.score.isRightBoundary(str, to)) break\n from = str.indexOf(mod.pattern, to + 1)\n to = from + mod.pattern.length - 1\n }\n }\n\n if (mod.inverse)\n return from === -1 ? { from: 0, score: 1000, search: str, str: original, to: 0 } : undefined\n if (from >= 0)\n return { from, score: this.score.get(original, from, to), search: str, str: original, to }\n return undefined\n }\n\n #regex(str: string, mod: Mod): Match | undefined {\n const match = mod.re?.exec(str)\n if (!match?.[0]) return undefined\n const from = match.index\n const to = from + match[0].length - 1\n return { from, score: this.score.get(str, from, to), search: str, str, to }\n }\n\n #fuzzyFind(\n str: string,\n original: string,\n pattern: string[],\n init = 0\n ): Pick<Match, \"from\" | \"to\" | \"score\"> | undefined {\n const from = str.indexOf(pattern[0] ?? \"\", init)\n if (from === -1) return undefined\n this.score.init(original, from)\n let last = from\n for (let i = 1; i < pattern.length; i++) {\n last = str.indexOf(pattern[i], last + 1)\n // Bail before reading the score: a partial accumulation never\n // escapes this method, so `#fuzzy` only ever sees a score that\n // corresponds to a fully-matched window.\n if (last === -1) return undefined\n this.score.update(last)\n }\n return { from, score: this.score.score, to: last }\n }\n\n #fuzzy(str: string, original: string, pattern: string[]): Match | undefined {\n // Anchor on every occurrence of the first char and keep the\n // highest-scoring window. The score rides in the return value rather\n // than being read off the shared `this.score`, so there's no\n // \"is the accumulator aligned with `best` right now?\" invariant.\n let best = this.#fuzzyFind(str, original, pattern)\n if (!best) return undefined\n for (\n let next = this.#fuzzyFind(str, original, pattern, best.from + 1);\n next;\n next = this.#fuzzyFind(str, original, pattern, next.from + 1)\n ) {\n if (next.score > best.score) best = next\n }\n return { from: best.from, score: best.score, search: str, str: original, to: best.to }\n }\n\n #fuzzyPositions(str: string, pattern: string[], from: number): number[] {\n const ret = [from]\n let last = from\n for (let i = 1; i < pattern.length; i++) {\n last = str.indexOf(pattern[i], last + 1)\n if (last === -1) break\n ret.push(last)\n }\n return ret\n }\n}\n\nfunction itemField(item: SearchItem, field: string): string | undefined {\n const value = item[field as keyof SearchItem] as unknown\n if (value === undefined || value === null) return undefined\n if (typeof value === \"string\") return value\n if (typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\")\n return String(value)\n if (Array.isArray(value)) return value.join(\" \")\n return\n}\n\nfunction parseFilePattern(pattern: string): string | undefined {\n return (\n pattern.match(/^(.*[/\\\\].*):\\d*:?:?\\d*$/)?.[1] ??\n pattern.match(/^(.+\\.[a-z_]+):\\d*:?:?\\d*$/)?.[1]\n )\n}\n","import type { ScoredItem, SearchItem } from \"./matcher.ts\"\n\ntype SortKey<T extends SearchItem> = Extract<keyof (ScoredItem<T> & SearchItem), string>\n\nexport type SortField<T extends SearchItem = SearchItem> =\n | SortKey<T>\n | `#${SortKey<T>}`\n | `${SortKey<T>}:desc`\n\nexport type ParsedField<T extends SearchItem = SearchItem> = {\n desc?: boolean\n len?: boolean\n name: SortKey<T>\n}\n\nexport type Sorter<T extends SearchItem = SearchItem> = (\n a: ScoredItem<T>,\n b: ScoredItem<T>\n) => number\n\nfunction parse<T extends SearchItem>(field: SortField<T>): ParsedField<T> {\n const len = field.startsWith(\"#\")\n const desc = field.endsWith(\":desc\")\n const name = field.replace(/^#/, \"\").replace(/:desc$/, \"\") as SortKey<T>\n return { desc, len, name }\n}\n\nexport function sorter<T extends SearchItem>(\n fields: readonly SortField<T>[] = [\"score:desc\", \"#text\", \"idx\"]\n): Sorter<T> {\n const parsed: ParsedField<T>[] = fields.map(parse)\n return (a, b) => {\n for (const field of parsed) {\n let av: unknown = a[field.name]\n let bv: unknown = b[field.name]\n if (av === undefined || bv === undefined) continue\n if (field.len) {\n av = typeof av === \"string\" || Array.isArray(av) ? av.length : 0\n bv = typeof bv === \"string\" || Array.isArray(bv) ? bv.length : 0\n }\n if (av === bv) continue\n if (typeof av === \"boolean\" && typeof bv === \"boolean\") {\n av = av ? 0 : 1\n bv = bv ? 0 : 1\n }\n return compare(av, bv) * (field.desc ? -1 : 1)\n }\n return 0\n }\n}\n\nfunction compare(a: unknown, b: unknown): number {\n if (typeof a === \"number\" && typeof b === \"number\") return a - b\n if (typeof a === \"string\" && typeof b === \"string\") return a.localeCompare(b)\n return String(a).localeCompare(String(b))\n}\n","// oxlint-disable no-await-in-loop\nimport type { MaybePromise } from \"@zaly/shared\"\nimport type { MatcherOptions, ScoredItem, SearchItem } from \"./matcher.ts\"\nimport type { Sorter, SortField } from \"./sort.ts\"\n\nimport { TopK } from \"@zaly/shared/minheap\"\nimport { Matcher } from \"./matcher.ts\"\nimport { sorter } from \"./sort.ts\"\n\nexport type SearchOptions<T extends SearchItem = SearchItem> = MatcherOptions & {\n sort?: boolean | readonly SortField<T>[]\n filter?: boolean\n sortEmpty?: boolean\n frecency?: () => (file: string) => number\n limit?: number\n throttle?: number\n}\n\nexport type SearchFn<T extends SearchItem = SearchItem> = (\n query: string,\n match: Match<T>\n) => MaybePromise<ScoredItem<T>[]>\n\nexport type SearchItems<T extends SearchItem = SearchItem> = readonly T[] | SearchFn<T>\n\n/** Match function handed to `complete`. Returns `0` for no match,\n * positive integer otherwise — so both `match(s) > 0` and the\n * idiomatic `.filter(match(s))` work (0 is falsy). The magnitude is a\n * score the source can use to rank its own candidates when it cares\n * about order. */\nexport type Match<T extends SearchItem = SearchItem> = (s: string | T) => number\n\nconst BONUS_FRECENCY = 8\nconst SEARCH_LIMIT = 1000\nconst aborted = Symbol(\"search.aborted\")\n\nexport class Searcher<T extends SearchItem = SearchItem> {\n #opts: SearchOptions<T>\n #sorter?: Sorter<T>\n #matcher: Matcher<T>\n #ac?: AbortController\n\n constructor(opts: SearchOptions<T>) {\n this.#opts = opts\n const sortOpts = opts.sort === true ? undefined : opts.sort\n this.#sorter = sortOpts === false ? undefined : sorter(sortOpts)\n this.#matcher = new Matcher(opts)\n }\n\n /** Create a match function bound to the current pattern. If the\n * matcher has been updated since the search started, match will\n * return `0` to indicate no match, to prevent stale results */\n createMatch(opts: { signal: AbortSignal }): Match<T> {\n const m = this.#matcher\n return (s: string | T) => (opts.signal.aborted ? 0 : m.match(s))\n }\n\n async search(\n items: SearchItems<T>,\n query = \"\",\n opts: { progress?: (results: ScoredItem<T>[]) => MaybePromise } = {}\n ): Promise<ScoredItem<T>[]> {\n try {\n return await this.#search(items, query, opts)\n } catch (error) {\n if (error === aborted) return []\n throw error\n }\n }\n\n get limit(): number {\n return this.#opts.limit ?? (this.#sorter ? SEARCH_LIMIT : Infinity)\n }\n\n async #search(\n items: SearchItems<T>,\n query = \"\",\n opts: { progress?: (results: ScoredItem<T>[]) => MaybePromise } = {}\n ): Promise<ScoredItem<T>[]> {\n this.#ac?.abort(aborted)\n // oxlint-disable-next-line no-multi-assign\n const ac = (this.#ac = new AbortController())\n\n const m = this.#matcher\n m.init(query)\n const f = this.#opts.frecency?.()\n const s = this.#sorter\n const limit = this.limit\n const ret: ScoredItem<T>[] = []\n let match = (item: T) => this.#matcher.update(item)\n const topk =\n s && (this.#opts.sortEmpty || !m.empty())\n ? new TopK<ScoredItem<T>>(limit, (a, b) => -s(a, b))\n : undefined\n\n if (typeof items === \"function\") {\n match = (item: T) => item as ScoredItem<T>\n items = await items(query, this.createMatch({ signal: ac.signal }))\n ac.signal.throwIfAborted()\n }\n\n if (items.length === 0) return []\n\n const results = () => topk?.sorted() ?? ret\n\n // Process items in three phases, so that the results in the UI stabilize faster:\n // - previous topk results (topk)\n // - scored items (score)\n // - unscored items (rest)\n const todo: [T[], T[], T[]] = [[], [], []]\n let idx = 0\n if (!topk) todo[0] = items as T[]\n else {\n for (const item of items) {\n item.idx = idx++\n const it = item as ScoredItem<T>\n if (it.topk) todo[0].push(item)\n else if (it.score) todo[1].push(item)\n else todo[2].push(item)\n }\n }\n\n const doFilter = !m.empty() && (this.#opts.filter ?? true)\n\n let lastYield = performance.now()\n let dirty = false\n let count = 0\n\n loop: for (const todos of todo) {\n for (const item of todos) {\n ac.signal.throwIfAborted()\n if (count++ % 256 === 0) {\n const now = performance.now()\n if (now - lastYield >= (this.#opts.throttle ?? 16)) {\n lastYield = now\n await new Promise((r) => setImmediate(r))\n if (opts.progress && dirty) {\n dirty = false\n await opts.progress(results())\n }\n }\n }\n const si = match(item)\n if (si.file && si.score && f) {\n const frecency = f(si.file)\n si.score += (1 - 1 / (1 + frecency)) * BONUS_FRECENCY\n }\n if (doFilter && si.score === 0) continue\n if (topk) {\n si.topk = false\n const ta = topk.add(si)\n if (ta.added) {\n si.topk = true\n dirty = true\n if (ta.evicted) ta.evicted.topk = false\n }\n } else {\n ret.push(si)\n dirty = true\n if (ret.length >= limit) break loop\n }\n }\n }\n\n return results()\n }\n\n positions(s: string | T): number[] {\n return this.#matcher.positions(s)\n }\n}\n","import type { Reactive, Ref } from \"../core/reactive.ts\"\nimport type { State } from \"../core/state.ts\"\nimport type { NodeActionMap } from \"../input/actions.ts\"\nimport type { ScoredItem, SearchItem } from \"../search/matcher.ts\"\nimport type { SearchItems, SearchOptions } from \"../search/search.ts\"\nimport type { Option, Select, SelectState } from \"./select.ts\"\nimport type { TreeItem, TreeProps } from \"./tree.ts\"\n\nimport { sliceAnsi, stripAnsi } from \"@zaly/shared/ansi\"\nimport { createProgressive, effect, memo, untrack, unwrap } from \"../core/reactive.ts\"\nimport { Searcher } from \"../search/search.ts\"\nimport { Input } from \"./input.ts\"\nimport { select } from \"./select.ts\"\nimport { tree } from \"./tree.ts\"\nimport { widget } from \"./widget.ts\"\n\nexport type PickerItem = Option & SearchItem\nexport type PickerActions = keyof ReturnType<typeof picker>[\"actions\"]\n\ntype PickerBaseProps<T extends PickerItem = PickerItem> = SearchOptions<T> & {\n /** The `Input` to watch. Pass the node directly, or a `Ref<Input>`\n * populated by `node.ref(ref)` elsewhere in the tree — the latter\n * enables fully inline composition where the input doesn't need a\n * local binding. The ref is dereferenced on mount, so wiring is\n * type-safe and ordering-flexible (autocomplete can be constructed\n * before the Input is). */\n input?: Input | Ref<Input>\n pattern?: Reactive<string>\n reverse?: boolean\n actions?: NodeActionMap<Select<T>>\n}\n\nexport type PickerSelectProps<T extends PickerItem = PickerItem> = PickerBaseProps<T> &\n Omit<SelectState<T>, \"items\"> & {\n items: Reactive<SearchItems<T>>\n tree?: never\n }\n\nexport type PickerTreeProps<T extends TreeItem = TreeItem> = PickerBaseProps<T> &\n TreeProps<T> & {\n items?: never\n }\n\nfunction isTree<T extends Option = Option>(\n props: PickerTreeProps<T> | PickerSelectProps<T>\n): props is PickerTreeProps<T> {\n return \"tree\" in props\n}\n\nexport const picker = widget(\n <T extends PickerItem = PickerItem>(props: State<PickerSelectProps<T> | PickerTreeProps<T>>) => {\n const pattern = memo(() => {\n if (props.pattern !== undefined) return unwrap(props.pattern)\n const inp = props.input instanceof Input ? props.input : props.input?.()\n return inp?.state.value ?? \"\"\n })\n\n let node: Select<T>\n let items: Reactive<SearchItems<T>>\n if (isTree(props)) {\n props = { filter: false, fuzzy: false, sort: false, ...props }\n const t = tree(props)\n node = t\n items = t.items\n } else {\n node = select({ ...props, items: [] })\n items = props.items\n }\n const searcher = new Searcher<T>(props)\n\n node.extendRenderer((prev) => (item, ctx) => {\n let row = prev(item, ctx)\n if (!item.score) return row\n const stripped = stripAnsi(row)\n const positions = searcher.positions(stripped).toSorted((a, b) => b - a)\n while (positions.length > 0) {\n const from = positions.pop()!\n let to = from\n while (positions.length && positions.at(-1) === to + 1) to = positions.pop()!\n row =\n sliceAnsi(row, 0, from) +\n ctx.style.accent(stripped.slice(from, to + 1)) +\n sliceAnsi(row, to + 1)\n }\n return row\n })\n\n const results = createProgressive<ScoredItem<T>[]>(\n async ({ set }) =>\n await searcher.search(unwrap(items), pattern(), { progress: (r) => set(r) }),\n {\n initialValue: [],\n }\n )\n node.state.items = results\n if (props.input) node.bind(props.input)\n\n const matches = () =>\n unwrap(node.state.items)\n .map((item, i) => [item, i] as const)\n .filter(([item]) => item.score)\n .map(([, i]) => i)\n\n effect(() => {\n const m = matches()\n node.state.more = m.length >= searcher.limit\n if (m.length === 0 || pattern() === \"\") return\n untrack(() => {\n // When filtering, go to the first (best) match.\n // When not filtering, go to the first match that is at or after the current active index, or the first match if none are after.\n if (props.filter === false) {\n const active = node.active\n node.active = m.find((i) => i >= active) ?? m[0]\n } else node.active = 0\n })\n })\n\n return node.withActions({\n ...props.actions,\n \"picker.next\": () => {\n const active = node.active\n const m = matches()\n if (m.length === 0) return node.action(\"select.next\")\n node.active = node.state.reverse\n ? (m.toReversed().find((i) => i < active) ?? m.at(-1)!)\n : (m.find((i) => i > active) ?? m[0])\n },\n \"picker.prev\": () => {\n const active = node.active\n const m = matches()\n if (m.length === 0) return node.action(\"select.prev\")\n node.active = node.state.reverse\n ? (m.find((i) => i > active) ?? m[0])\n : (m.toReversed().find((i) => i < active) ?? m.at(-1)!)\n },\n })\n }\n)\n"],"mappings":"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"}
@@ -136,6 +136,7 @@ var TerminalQueries = class {
136
136
  this.#terminal = terminal;
137
137
  }
138
138
  query(query) {
139
+ if (query.signal?.aborted) return Promise.resolve(void 0);
139
140
  const timeout = query.timeout ?? 200;
140
141
  const ac = new AbortController();
141
142
  return new Promise((resolve) => {
@@ -143,17 +144,69 @@ var TerminalQueries = class {
143
144
  if (ac.signal.aborted) return;
144
145
  ac.abort();
145
146
  clearTimeout(timer);
147
+ query.signal?.removeEventListener("abort", cancel);
146
148
  resolve(value);
147
149
  };
148
- const timer = setTimeout(() => finish(), timeout);
150
+ const cancel = () => finish();
151
+ const timer = setTimeout(cancel, timeout);
149
152
  timer.unref();
150
153
  this.#router.on("term-response", ({ event }) => {
151
154
  const value = query.match(event);
152
155
  if (value !== void 0) finish(value);
153
156
  }, { signal: ac.signal });
157
+ query.signal?.addEventListener("abort", cancel, { once: true });
154
158
  this.#terminal.write(query.wrap?.(query.request) ?? query.request);
155
159
  });
156
160
  }
161
+ color(index, opts = {}) {
162
+ if (typeof index === "number" && (!Number.isInteger(index) || index < 0 || index > 255)) throw new RangeError("Palette index must be an integer between 0 and 255");
163
+ const prefix = typeof index === "number" ? `4;${index};` : `${{
164
+ bg: 11,
165
+ fg: 10,
166
+ selectionBg: 17,
167
+ selectionFg: 19
168
+ }[index]};`;
169
+ return this.query({
170
+ ...opts,
171
+ match: (event) => {
172
+ if (event.kind !== "osc") return;
173
+ if (typeof index === "number" && event.payload.startsWith("4;")) {
174
+ const parts = event.payload.slice(2).split(";");
175
+ for (let i = 0; i + 1 < parts.length; i += 2) if (parts[i] === String(index)) return parseTerminalColor(parts[i + 1]);
176
+ return;
177
+ }
178
+ if (event.payload.startsWith(prefix)) return parseTerminalColor(event.payload.slice(prefix.length));
179
+ },
180
+ request: `\x1b]${prefix}?\x1b\\`
181
+ });
182
+ }
183
+ colorScheme(opts = {}) {
184
+ return this.query({
185
+ ...opts,
186
+ match: (event) => {
187
+ if (event.kind !== "csi" || event.final !== "n") return;
188
+ if (event.params === "?997;1") return "dark";
189
+ if (event.params === "?997;2") return "light";
190
+ },
191
+ request: "\x1B[?996n"
192
+ });
193
+ }
194
+ async palette(opts = {}) {
195
+ const colorOpts = {
196
+ ...opts,
197
+ timeout: opts.timeout ?? 100
198
+ };
199
+ const [ansi, fg, bg] = await Promise.all([
200
+ Promise.all(Array.from({ length: 16 }, (_, i) => this.color(i, colorOpts))),
201
+ this.color("fg", colorOpts),
202
+ this.color("bg", colorOpts)
203
+ ]);
204
+ return {
205
+ ansi,
206
+ bg,
207
+ fg
208
+ };
209
+ }
157
210
  primaryDeviceAttributes(opts = {}) {
158
211
  return this.query({
159
212
  match: (ev) => ev.kind === "csi" && ev.final === "c" && ev.params.startsWith("?") ? {
@@ -191,10 +244,20 @@ var TerminalQueries = class {
191
244
  });
192
245
  }
193
246
  };
247
+ /** OSC replies use X11 rgb components, with one to four hex digits per channel. */
248
+ function parseTerminalColor(value) {
249
+ let parts = /^rgb:([\da-f]{1,4})\/([\da-f]{1,4})\/([\da-f]{1,4})$/i.exec(value)?.slice(1);
250
+ if (!parts && /^#(?:[\da-f]{3}|[\da-f]{6}|[\da-f]{9}|[\da-f]{12})$/i.test(value)) {
251
+ const size = (value.length - 1) / 3;
252
+ parts = Array.from({ length: 3 }, (_, i) => value.slice(1 + i * size, 1 + (i + 1) * size));
253
+ }
254
+ if (!parts) return;
255
+ return `#${parts.map((part) => Math.round(Number.parseInt(part, 16) / (16 ** part.length - 1) * 255).toString(16).padStart(2, "0")).join("")}`;
256
+ }
194
257
  function parseAttrs(params) {
195
258
  return params.slice(1).split(";").map((n) => Number.parseInt(n, 10)).filter(Number.isFinite);
196
259
  }
197
260
  //#endregion
198
- export { isKeyPattern as a, canonical as i, parseAttrs as n, keyMatches as o, KeyPatternError as r, TerminalQueries as t };
261
+ export { canonical as a, KeyPatternError as i, parseAttrs as n, isKeyPattern as o, parseTerminalColor as r, keyMatches as s, TerminalQueries as t };
199
262
 
200
- //# sourceMappingURL=queries-B_lOwEiE.mjs.map
263
+ //# sourceMappingURL=queries-BUkBxkuM.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries-BUkBxkuM.mjs","names":[],"sources":["../src/input/keys.ts","../src/input/queries.ts"],"sourcesContent":["/**\n * Keyboard event shape + pattern-based matcher.\n *\n * `KeyEvent.name` is a canonical name:\n * - Single characters for printable keys: `\"a\"`, `\"A\"`, `\" \"`, `\"!\"`. The\n * `name` reflects the raw character the decoder produced — so `Shift+A`\n * arrives as `{ name: \"A\", shift: true }` (terminals already fold\n * shift into the uppercase byte for letters).\n * - Named constants for non-printing keys: `\"enter\"`, `\"tab\"`, `\"esc\"`,\n * `\"backspace\"`, `\"delete\"`, `\"space\"`, arrows `\"up\"/\"down\"/\"left\"/\n * \"right\"`, navigation `\"home\"/\"end\"/\"pageup\"/\"pagedown\"/\"insert\"`,\n * function keys `\"f1\"` .. `\"f12\"`.\n *\n * Patterns for `keyMatches` are dash-separated modifier prefixes plus the\n * name: `\"a\"`, `\"ctrl-c\"`, `\"shift-tab\"`, `\"ctrl-shift-x\"`. Unknown\n * prefixes are treated as literal characters in the name, so\n * `\"something-foo\"` is interpreted as the name `\"something-foo\"` rather\n * than a missing-modifier error.\n *\n * Modifier prefixes (order-independent):\n * - `ctrl-`\n * - `alt-`\n * - `shift-`\n * - `meta-` (a.k.a. super / cmd)\n */\n\nexport interface KeyEvent {\n /** Canonical key name — raw character or one of the named constants above. */\n name: string\n /**\n * The literal text the keystroke would insert, when that makes sense.\n * For printable chars this is the char itself; for Enter, Tab, etc. it's\n * undefined. Widgets use this to decide whether to insert content vs.\n * treat the key as a command.\n */\n text?: string\n ctrl: boolean\n alt: boolean\n shift: boolean\n meta: boolean\n}\n\n/** Canonical modifier names used in `KeyPattern`. */\nexport type KeyModifier = \"ctrl\" | \"alt\" | \"shift\" | \"meta\"\n\n/**\n * Named keys the decoder emits for non-printable keystrokes. Bindings\n * reference these directly (`\"enter\"`, `\"f5\"`, `\"pageup\"`, …).\n */\nexport type SpecialKeyName = (typeof specialKeys)[number]\n\ndeclare const KeyPatternBrand: unique symbol\n\n/** A validated, canonical key binding string. */\nexport type KeyPattern = string & { readonly [KeyPatternBrand]: true }\n\nconst MOD_NAMES = new Set<string>([\"ctrl\", \"alt\", \"shift\", \"meta\"])\nconst specialKeys = [\n \"enter\",\n \"tab\",\n \"backspace\",\n \"delete\",\n \"space\",\n \"esc\",\n \"up\",\n \"down\",\n \"left\",\n \"right\",\n \"home\",\n \"end\",\n \"pageup\",\n \"pagedown\",\n \"insert\",\n \"f1\",\n \"f2\",\n \"f3\",\n \"f4\",\n \"f5\",\n \"f6\",\n \"f7\",\n \"f8\",\n \"f9\",\n \"f10\",\n \"f11\",\n \"f12\",\n] as const\nconst SPECIAL_KEY_NAMES = new Set<string>(specialKeys)\n\ninterface ParsedPattern {\n name: string\n ctrl: boolean\n alt: boolean\n shift: boolean\n meta: boolean\n}\n\nexport class KeyPatternError extends Error {\n constructor(pattern: string, reason: string) {\n super(`invalid key pattern ${JSON.stringify(pattern)}: ${reason}`)\n this.name = \"KeyPatternError\"\n }\n}\n\nfunction parsePattern(pattern: string): ParsedPattern {\n const mods = { alt: false, ctrl: false, meta: false, shift: false }\n let name = pattern\n while (name.length > 0) {\n const dash = name.indexOf(\"-\")\n if (dash <= 0) break\n const mod = name.slice(0, dash)\n if (!MOD_NAMES.has(mod)) throw new KeyPatternError(pattern, `unknown modifier: ${mod}`)\n if (mods[mod as KeyModifier]) throw new KeyPatternError(pattern, `duplicate modifier: ${mod}`)\n mods[mod as KeyModifier] = true\n name = name.slice(dash + 1)\n }\n\n const ret = normalizeKey({ ...mods, name })\n name = ret.name\n if (name === \"\") throw new KeyPatternError(pattern, \"missing key name\")\n if (name.includes(\"-\") && name !== \"-\") throw new KeyPatternError(pattern, \"too many keys\")\n if (!isPrintableKeyName(name)) throw new KeyPatternError(pattern, `unknown key name: ${name}`)\n if (mods.shift && !canUseShiftModifier(name)) {\n throw new KeyPatternError(\n pattern,\n `shift-${name} will not trigger; bind the shifted character instead`\n )\n }\n return ret\n}\n\nfunction normalizeKey(p: ParsedPattern): ParsedPattern {\n if (/^[A-Z]$/.test(p.name)) return { ...p, name: p.name.toLowerCase(), shift: true }\n if (p.name === \" \") return { ...p, name: \"space\" }\n return p\n}\n\nfunction isPrintableKeyName(s: string): boolean {\n // oxlint-disable-next-line typescript/no-misused-spread\n return SPECIAL_KEY_NAMES.has(s) || ([...s].length === 1 && !/[\\p{C}]/u.test(s))\n}\n\nfunction canUseShiftModifier(name: string): boolean {\n return /^[a-zA-Z]$/.test(name) || SPECIAL_KEY_NAMES.has(name)\n}\n\nexport function isKeyPattern(s: string): s is KeyPattern {\n try {\n canonical(s)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Canonical string form of a pattern or event — modifiers in a fixed\n * alphabetical order, then the key name, joined by `-`. Used by the\n * router to build a pattern index whose keys match regardless of how\n * the user spelled the modifier order (`\"ctrl-shift-a\"` and\n * `\"shift-ctrl-a\"` both canonicalize to `\"ctrl-shift-a\"`).\n */\nexport function canonical(patternOrEvent: string | KeyEvent): KeyPattern {\n const p =\n typeof patternOrEvent === \"string\" ? parsePattern(patternOrEvent) : normalizeKey(patternOrEvent)\n const parts: string[] = []\n if (p.alt) parts.push(\"alt\")\n if (p.ctrl) parts.push(\"ctrl\")\n if (p.meta) parts.push(\"meta\")\n if (p.shift) parts.push(\"shift\")\n parts.push(p.name)\n return parts.join(\"-\") as KeyPattern\n}\n\n/**\n * Test whether an event matches a pattern (or any of a list of patterns).\n * Unspecified modifiers in the pattern must be *absent* on the event —\n * matching is strict, not inclusive, so `\"a\"` only matches a bare `a`\n * (no ctrl/alt/etc.).\n */\nexport function keyMatches(ev: KeyEvent, pattern: string | readonly string[]): boolean {\n if (Array.isArray(pattern)) {\n for (const p of pattern) if (keyMatches(ev, p)) return true\n return false\n }\n const p = parsePattern(pattern as string)\n const e = normalizeKey(ev)\n return (\n e.name === p.name &&\n e.ctrl === p.ctrl &&\n e.alt === p.alt &&\n e.shift === p.shift &&\n e.meta === p.meta\n )\n}\n","import type { HexColor } from \"../style/types.ts\"\nimport type { TerminalResponseEvent } from \"./decoder.ts\"\nimport type { InputRouter } from \"./router.ts\"\n\nexport type TerminalQuery<T = TerminalResponseEvent> = TerminalQueryOpts & {\n request: string\n match: (event: TerminalResponseEvent) => T | undefined\n}\n\nexport type TerminalQueryOpts = {\n signal?: AbortSignal\n timeout?: number\n wrap?: (seq: string) => string\n}\n\ntype TerminalQueryWriter = {\n write: (seq: string) => void\n}\n\nexport class TerminalQueries {\n readonly #router: InputRouter\n readonly #terminal: TerminalQueryWriter\n\n constructor(router: InputRouter, terminal: TerminalQueryWriter) {\n this.#router = router\n this.#terminal = terminal\n }\n\n query<T>(query: TerminalQuery<T>): Promise<T | undefined> {\n if (query.signal?.aborted) return Promise.resolve(undefined)\n const timeout = query.timeout ?? 200\n const ac = new AbortController()\n return new Promise((resolve) => {\n const finish = (value?: T) => {\n if (ac.signal.aborted) return\n ac.abort()\n clearTimeout(timer)\n query.signal?.removeEventListener(\"abort\", cancel)\n resolve(value)\n }\n const cancel = () => finish()\n const timer = setTimeout(cancel, timeout)\n timer.unref()\n this.#router.on(\n \"term-response\",\n ({ event }) => {\n const value = query.match(event)\n if (value !== undefined) finish(value)\n },\n { signal: ac.signal }\n )\n query.signal?.addEventListener(\"abort\", cancel, { once: true })\n this.#terminal.write(query.wrap?.(query.request) ?? query.request)\n })\n }\n\n color(index: number | \"fg\" | \"bg\" | \"selectionBg\" | \"selectionFg\", opts: TerminalQueryOpts = {}) {\n if (typeof index === \"number\" && (!Number.isInteger(index) || index < 0 || index > 255)) {\n throw new RangeError(\"Palette index must be an integer between 0 and 255\")\n }\n const dynamic = { bg: 11, fg: 10, selectionBg: 17, selectionFg: 19 }\n const prefix = typeof index === \"number\" ? `4;${index};` : `${dynamic[index]};`\n return this.query<HexColor>({\n ...opts,\n match: (event) => {\n if (event.kind !== \"osc\") return\n if (typeof index === \"number\" && event.payload.startsWith(\"4;\")) {\n const parts = event.payload.slice(2).split(\";\")\n for (let i = 0; i + 1 < parts.length; i += 2) {\n if (parts[i] === String(index)) return parseTerminalColor(parts[i + 1])\n }\n return\n }\n if (event.payload.startsWith(prefix))\n return parseTerminalColor(event.payload.slice(prefix.length))\n },\n request: `\\x1b]${prefix}?\\x1b\\\\`,\n })\n }\n\n colorScheme(opts: TerminalQueryOpts = {}) {\n return this.query<\"dark\" | \"light\">({\n ...opts,\n match: (event) => {\n if (event.kind !== \"csi\" || event.final !== \"n\") return\n if (event.params === \"?997;1\") return \"dark\"\n if (event.params === \"?997;2\") return \"light\"\n },\n request: \"\\x1b[?996n\",\n })\n }\n\n async palette(opts: TerminalQueryOpts = {}): Promise<TerminalPaletteSnapshot> {\n const colorOpts = { ...opts, timeout: opts.timeout ?? 100 }\n const [ansi, fg, bg] = await Promise.all([\n Promise.all(Array.from({ length: 16 }, (_, i) => this.color(i, colorOpts))),\n this.color(\"fg\", colorOpts),\n this.color(\"bg\", colorOpts),\n ])\n return { ansi, bg, fg }\n }\n\n primaryDeviceAttributes(opts: TerminalQueryOpts = {}) {\n return this.query<TerminalResponseEvent & { attrs: number[] }>({\n match: (ev) =>\n ev.kind === \"csi\" && ev.final === \"c\" && ev.params.startsWith(\"?\")\n ? { ...ev, attrs: parseAttrs(ev.params) }\n : undefined,\n request: \"\\x1b[c\",\n ...opts,\n })\n }\n\n secondaryDeviceAttributes(opts: TerminalQueryOpts = {}) {\n return this.query<TerminalResponseEvent & { attrs: number[] }>({\n match: (ev) =>\n ev.kind === \"csi\" && ev.final === \"c\" && ev.params.startsWith(\">\")\n ? { ...ev, attrs: parseAttrs(ev.params) }\n : undefined,\n request: \"\\x1b[>c\",\n ...opts,\n })\n }\n\n xtVersion(opts: TerminalQueryOpts = {}) {\n return this.query<TerminalResponseEvent & { name: string; version?: string }>({\n match: (ev) => {\n if (ev.kind !== \"dcs\" || !ev.payload.startsWith(\">|\")) return\n const payload = ev.payload.slice(2)\n const m = payload.match(/^([^\\s]+)\\(([^\\s]+)\\)$/) ?? payload.match(/^([^\\s]+)\\s+([^\\s]+)$/)\n return { ...ev, name: m?.[1] ?? payload, version: m?.[2] }\n },\n request: \"\\x1b[>q\",\n ...opts,\n })\n }\n}\n\nexport interface TerminalPaletteSnapshot {\n ansi: (HexColor | undefined)[]\n bg?: HexColor\n fg?: HexColor\n selectionBg?: HexColor\n selectionFg?: HexColor\n}\n\n/** OSC replies use X11 rgb components, with one to four hex digits per channel. */\nexport function parseTerminalColor(value: string): HexColor | undefined {\n let parts = /^rgb:([\\da-f]{1,4})\\/([\\da-f]{1,4})\\/([\\da-f]{1,4})$/i.exec(value)?.slice(1)\n if (!parts && /^#(?:[\\da-f]{3}|[\\da-f]{6}|[\\da-f]{9}|[\\da-f]{12})$/i.test(value)) {\n const size = (value.length - 1) / 3\n parts = Array.from({ length: 3 }, (_, i) => value.slice(1 + i * size, 1 + (i + 1) * size))\n }\n if (!parts) return\n return `#${parts\n .map((part) =>\n Math.round((Number.parseInt(part, 16) / (16 ** part.length - 1)) * 255)\n .toString(16)\n .padStart(2, \"0\")\n )\n .join(\"\")}`\n}\n\nexport function parseAttrs(params: string): number[] {\n return params\n .slice(1)\n .split(\";\")\n .map((n) => Number.parseInt(n, 10))\n .filter(Number.isFinite)\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { c as Color, f as Style, t as Theme } from "./types-C0EOLZDc.mjs";
2
- import { a as StyleBuilder, t as InspectOpts } from "./inspect-DPLRum7L.mjs";
1
+ import { c as HexColor, f as Theme, i as AnyStyle, o as Color, u as Style, x as ShikiSelection } from "./types-C9ceMsbJ.mjs";
2
+ import { a as StyleBuilder, t as InspectOpts } from "./inspect-B1uXxdKC.mjs";
3
3
  import { Emitter, MaybePromise } from "@zaly/shared";
4
4
  import { LogEntry, LogLevel, LogReporter, Logger, TryResult } from "@zaly/shared/logger";
5
5
  import { ArgsOpts, ArgsResult } from "@zaly/shared/args";
@@ -771,7 +771,7 @@ type State<T extends object = object> = T & BaseState;
771
771
  * interfaces extend this so base-state concerns and pure styling stay
772
772
  * cleanly separated at the type level without each widget having to
773
773
  * compose the two manually. */
774
- type StyleState = Style;
774
+ type StyleState = Style<false>;
775
775
  interface LayoutState {
776
776
  visible?: Reactive<boolean>;
777
777
  }
@@ -843,7 +843,7 @@ type TitleAlign = "left" | "center" | "right";
843
843
  * ```
844
844
  */
845
845
  type TextContent = Reactive<string> | ((ctx: RenderCtx) => MaybePromise<Reactive<string>>);
846
- interface TextStyle extends Style {
846
+ interface TextStyle extends Style<false> {
847
847
  content: TextContent;
848
848
  wrap?: "word" | "char" | "none";
849
849
  }
@@ -895,12 +895,12 @@ interface BoxStyle extends Style {
895
895
  * via the active theme) or an inline `Style`. Defaults to the `"border"`
896
896
  * theme slot when a border is drawn.
897
897
  */
898
- borderStyle?: string | Style;
898
+ borderStyle?: AnyStyle;
899
899
  /**
900
900
  * Style applied to the border title. Defaults to the `"borderTitle"` theme
901
901
  * slot when a title is set.
902
902
  */
903
- borderTitleStyle?: string | Style;
903
+ borderTitleStyle?: AnyStyle;
904
904
  }
905
905
  declare class Box<T extends object = {}> extends Node<BoxStyle & T> {
906
906
  #private;
@@ -1048,11 +1048,11 @@ interface LogState {
1048
1048
  /** Single-glyph icon for `icon` / `prompt` styles. */
1049
1049
  icon?: string;
1050
1050
  /** Theme slot or color name used to tint the prefix. */
1051
- color?: Color;
1051
+ color?: Color<false>;
1052
1052
  /** Extra plain text prepended to the auto prefix (unstyled). */
1053
1053
  prefix?: string;
1054
1054
  /** Theme slot or color name for the body text. Defaults by level, except */
1055
- textColor?: Color;
1055
+ textColor?: Color<false>;
1056
1056
  markdown?: boolean;
1057
1057
  }
1058
1058
  /**
@@ -1221,6 +1221,8 @@ type LineSlice = {
1221
1221
  declare class Frame {
1222
1222
  #private;
1223
1223
  readonly terminal: Terminal;
1224
+ get defaultStyle(): string;
1225
+ setDefaultStyle(fg: string, bg: string): void;
1224
1226
  constructor(terminal: Terminal);
1225
1227
  reset(rows?: number): void;
1226
1228
  begin(): RenderFrame;
@@ -1231,7 +1233,14 @@ declare class RenderFrame {
1231
1233
  readonly terminal: Terminal;
1232
1234
  readonly current: (string | undefined)[];
1233
1235
  readonly base: (string | undefined)[];
1234
- constructor(terminal: Terminal, current: (string | undefined)[], base: (string | undefined)[]);
1236
+ readonly defaults: {
1237
+ bg: string;
1238
+ fg: string;
1239
+ };
1240
+ constructor(terminal: Terminal, current: (string | undefined)[], base: (string | undefined)[], defaults?: {
1241
+ bg: string;
1242
+ fg: string;
1243
+ });
1235
1244
  get(row: number): string;
1236
1245
  set(row: number, content: string): void;
1237
1246
  clear(row: number): void;
@@ -1568,6 +1577,11 @@ interface RendererOptions {
1568
1577
  stdout?: TerminalWriter;
1569
1578
  images?: Reactive<boolean>;
1570
1579
  theme?: Theme;
1580
+ /** Syntax highlighting selection, independent of the UI theme. */
1581
+ shiki?: ShikiSelection;
1582
+ transparent?: Reactive<boolean>;
1583
+ /** Base colors for painted rows and cleared cells, resolved against the theme. */
1584
+ defaultStyle?: Pick<Style, "fg" | "bg">;
1571
1585
  /** Baseline footer height in rows — the size the footer occupies in
1572
1586
  * "steady state" (no autocomplete, no transient widget growth).
1573
1587
  * Stream uses `terminal.rows - fixedFooterHeight` as its commit
@@ -1673,6 +1687,10 @@ declare class Renderer extends Emitter<RenderEvents> {
1673
1687
  set theme(theme: Theme);
1674
1688
  /** Get the current theme. (tracked) */
1675
1689
  get theme(): Theme;
1690
+ /** Inherit the terminal background instead of painting the base background. */
1691
+ set transparent(transparent: boolean);
1692
+ /** Current transparency setting. (tracked) */
1693
+ get transparent(): boolean;
1676
1694
  start(): void;
1677
1695
  stop(): void;
1678
1696
  /** Look up a node by its `id`. Returns `undefined` if nothing matches. */
@@ -1936,6 +1954,7 @@ type TerminalQuery<T = TerminalResponseEvent> = TerminalQueryOpts & {
1936
1954
  match: (event: TerminalResponseEvent) => T | undefined;
1937
1955
  };
1938
1956
  type TerminalQueryOpts = {
1957
+ signal?: AbortSignal;
1939
1958
  timeout?: number;
1940
1959
  wrap?: (seq: string) => string;
1941
1960
  };
@@ -1946,6 +1965,9 @@ declare class TerminalQueries {
1946
1965
  #private;
1947
1966
  constructor(router: InputRouter, terminal: TerminalQueryWriter);
1948
1967
  query<T>(query: TerminalQuery<T>): Promise<T | undefined>;
1968
+ color(index: number | "fg" | "bg" | "selectionBg" | "selectionFg", opts?: TerminalQueryOpts): Promise<`#${string}` | undefined>;
1969
+ colorScheme(opts?: TerminalQueryOpts): Promise<"dark" | "light" | undefined>;
1970
+ palette(opts?: TerminalQueryOpts): Promise<TerminalPaletteSnapshot>;
1949
1971
  primaryDeviceAttributes(opts?: TerminalQueryOpts): Promise<(TerminalResponseEvent & {
1950
1972
  attrs: number[];
1951
1973
  }) | undefined>;
@@ -1957,7 +1979,16 @@ declare class TerminalQueries {
1957
1979
  version?: string;
1958
1980
  }) | undefined>;
1959
1981
  }
1982
+ interface TerminalPaletteSnapshot {
1983
+ ansi: (HexColor | undefined)[];
1984
+ bg?: HexColor;
1985
+ fg?: HexColor;
1986
+ selectionBg?: HexColor;
1987
+ selectionFg?: HexColor;
1988
+ }
1989
+ /** OSC replies use X11 rgb components, with one to four hex digits per channel. */
1990
+ declare function parseTerminalColor(value: string): HexColor | undefined;
1960
1991
  declare function parseAttrs(params: string): number[];
1961
1992
  //#endregion
1962
- export { Context as $, LogState as A, useContext as At, Padding as B, Actions as Bt, OverlaySurface as C, peek as Ct, LoggerStream as D, untrack as Dt, LogStyleOverride as E, toAccessor as Et, Overlay as F, ActionCtx as Ft, text as G, KeyModifier as Gt, Text as H, NodeAction as Ht, OverlayState as I, ActionDef as It, Layout as J, SpecialKeyName as Jt, textContent as K, KeyPattern as Kt, overlay as L, ActionFilter as Lt, log as M, withOwner as Mt, MountCtx as N, Size as Nt, TuiReporter as O, unwrap as Ot, RenderCtx as P, Action as Pt, Accessor as Q, Box as R, ActionFn as Rt, Stream as S, onCleanup as St, LogEntryFactory as T, signal as Tt, TextContent as U, NodeActionMap as Ut, box as V, KeyBinding as Vt, TextStyle as W, KeyEvent as Wt, State as X, isKeyPattern as Xt, LayoutState as Y, canonical as Yt, StyleState as Z, keyMatches as Zt, RenderStats as _, createSuspenseBoundary as _t, InputRouter as a, Signal as at, SurfaceType as b, isAccessor as bt, KeyPatterns as c, SuspenseContext as ct, RoutedPaste as d, createIterable as dt, Owner as et, BaseEvents as f, createNode as ft, RenderEvents as g, createStore as gt, NodeVisitor as h, createRoot as ht, parseAttrs as i, Setter as it, LogStyle as j, withActiveNode as jt, TuiReporterOpts as k, useActiveOwner as kt, KeymapEntry as l, createAsync as lt, isNode as m, createRef as mt, TerminalQuery as n, Reactive as nt, InputRouterEvents as o, SignalStore as ot, Node as p, createProgressive as pt, FlexState as q, KeyPatternError as qt, TerminalQueryOpts as r, Ref as rt, KeyHandler as s, SuspenseBoundary as st, TerminalQueries as t, Progressive as tt, RoutedKey as u, createContext as ut, Renderer as v, effect as vt, Terminal as w, provideContext as wt, UI as x, memo as xt, RendererOptions as y, inRenderContextOf as yt, BoxStyle as z, ActionMap as zt };
1963
- //# sourceMappingURL=queries-Cvalgu6P.d.mts.map
1993
+ export { StyleState as $, keyMatches as $t, TuiReporter as A, unwrap as At, Box as B, ActionFn as Bt, UI as C, memo as Ct, LogEntryFactory as D, signal as Dt, Terminal as E, provideContext as Et, MountCtx as F, Size as Ft, TextContent as G, NodeActionMap as Gt, Padding as H, Actions as Ht, RenderCtx as I, Action as It, textContent as J, KeyPattern as Jt, TextStyle as K, KeyEvent as Kt, Overlay as L, ActionCtx as Lt, LogState as M, useContext as Mt, LogStyle as N, withActiveNode as Nt, LogStyleOverride as O, toAccessor as Ot, log as P, withOwner as Pt, State as Q, isKeyPattern as Qt, OverlayState as R, ActionDef as Rt, SurfaceType as S, isAccessor as St, OverlaySurface as T, peek as Tt, box as U, KeyBinding as Ut, BoxStyle as V, ActionMap as Vt, Text as W, NodeAction as Wt, Layout as X, SpecialKeyName as Xt, FlexState as Y, KeyPatternError as Yt, LayoutState as Z, canonical as Zt, NodeVisitor as _, createRoot as _t, parseAttrs as a, Ref as at, Renderer as b, effect as bt, InputRouterEvents as c, SignalStore as ct, KeymapEntry as d, createAsync as dt, Accessor as et, RoutedKey as f, createContext as ft, isNode as g, createRef as gt, Node as h, createProgressive as ht, TerminalQueryOpts as i, Reactive as it, TuiReporterOpts as j, useActiveOwner as jt, LoggerStream as k, untrack as kt, KeyHandler as l, SuspenseBoundary as lt, BaseEvents as m, createNode as mt, TerminalQueries as n, Owner as nt, parseTerminalColor as o, Setter as ot, RoutedPaste as p, createIterable as pt, text as q, KeyModifier as qt, TerminalQuery as r, Progressive as rt, InputRouter as s, Signal as st, TerminalPaletteSnapshot as t, Context as tt, KeyPatterns as u, SuspenseContext as ut, RenderEvents as v, createStore as vt, Stream as w, onCleanup as wt, RendererOptions as x, inRenderContextOf as xt, RenderStats as y, createSuspenseBoundary as yt, overlay as z, ActionFilter as zt };
1994
+ //# sourceMappingURL=queries-C75-wG1B.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries-C75-wG1B.d.mts","names":["_$___core_state_ts0.Layout","_$__box_ts0.Box","_$__terminal_ts0.Terminal"],"sources":["../src/input/keys.ts","../src/input/decoder.ts","../src/input/actions.ts","../src/layout/size.ts","../src/core/reactive.ts","../src/core/state.ts","../src/layout/border.ts","../src/widgets/text.ts","../src/widgets/box.ts","../src/widgets/overlay.ts","../src/core/ctx.ts","../src/widgets/log.ts","../src/services/logger.ts","../src/renderer/terminal.ts","../src/renderer/frame.ts","../src/renderer/surface.ts","../src/renderer/overlay.ts","../src/renderer/selection.ts","../src/renderer/stream.ts","../src/renderer/ui.ts","../src/renderer/renderer.ts","../src/core/node.ts","../src/input/router.ts","../src/input/queries.ts"],"mappings":"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"}