palettecn 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 (460) hide show
  1. package/dist/index.mjs +10 -0
  2. package/dist/web/nitro.json +17 -0
  3. package/dist/web/public/assets/abap-BdvmRIgS.js +1 -0
  4. package/dist/web/public/assets/actionscript-3-et0rQaqm.js +1 -0
  5. package/dist/web/public/assets/ada-DPgrustg.js +1 -0
  6. package/dist/web/public/assets/andromeeda-DJl1yeV_.js +1 -0
  7. package/dist/web/public/assets/angular-html-Dm7s7tSx.js +1 -0
  8. package/dist/web/public/assets/angular-ts-B_ywTULt.js +1 -0
  9. package/dist/web/public/assets/apache-CFpsYX8S.js +1 -0
  10. package/dist/web/public/assets/apex-CN5n6pbI.js +1 -0
  11. package/dist/web/public/assets/apl-Dm11wHHc.js +1 -0
  12. package/dist/web/public/assets/applescript-JrY23hsL.js +1 -0
  13. package/dist/web/public/assets/ara-DR83hn3A.js +1 -0
  14. package/dist/web/public/assets/asciidoc-Dpu9XLB1.js +1 -0
  15. package/dist/web/public/assets/asm-BYI3A31V.js +1 -0
  16. package/dist/web/public/assets/astro-DP1naDCT.js +1 -0
  17. package/dist/web/public/assets/aurora-x-Nav5jnoQ.js +1 -0
  18. package/dist/web/public/assets/awk-BIoTx_w6.js +1 -0
  19. package/dist/web/public/assets/ayu-dark-H5QV5J7K.js +1 -0
  20. package/dist/web/public/assets/ayu-light-BrwTNGnU.js +1 -0
  21. package/dist/web/public/assets/ayu-mirage-Bg6FpF5w.js +1 -0
  22. package/dist/web/public/assets/ballerina-BFvDNd4T.js +1 -0
  23. package/dist/web/public/assets/bat-DtQkx7Ny.js +1 -0
  24. package/dist/web/public/assets/beancount-BIjKALa1.js +1 -0
  25. package/dist/web/public/assets/berry-BPkDN_EZ.js +1 -0
  26. package/dist/web/public/assets/bibtex-Dur2CNW6.js +1 -0
  27. package/dist/web/public/assets/bicep-BMz1bZ7m.js +1 -0
  28. package/dist/web/public/assets/bird2-91rdr9s7.js +1 -0
  29. package/dist/web/public/assets/blade-DD5O596X.js +1 -0
  30. package/dist/web/public/assets/bsl-FmB7U2qd.js +1 -0
  31. package/dist/web/public/assets/bundle-mjs-Bso3xn9x.js +1 -0
  32. package/dist/web/public/assets/c-DqqBLLyl.js +1 -0
  33. package/dist/web/public/assets/c3-CJTbEooS.js +1 -0
  34. package/dist/web/public/assets/cadence-C0GI7BZZ.js +1 -0
  35. package/dist/web/public/assets/cairo-B5JMmIC0.js +1 -0
  36. package/dist/web/public/assets/catppuccin-frappe-D76-cUjK.js +1 -0
  37. package/dist/web/public/assets/catppuccin-latte-DUHNJ_6_.js +1 -0
  38. package/dist/web/public/assets/catppuccin-macchiato-CFhPH2wd.js +1 -0
  39. package/dist/web/public/assets/catppuccin-mocha-BRD0cvUW.js +1 -0
  40. package/dist/web/public/assets/chunk-FRKYWMV7-DUkk3w4h.js +122 -0
  41. package/dist/web/public/assets/clarity-KgUVrNfC.js +1 -0
  42. package/dist/web/public/assets/clojure-BhQuoGIG.js +1 -0
  43. package/dist/web/public/assets/cmake-CA59gUFQ.js +1 -0
  44. package/dist/web/public/assets/cobol-CCFShgGZ.js +1 -0
  45. package/dist/web/public/assets/codeowners-CD36YqjJ.js +1 -0
  46. package/dist/web/public/assets/codeql-CrMosKUt.js +1 -0
  47. package/dist/web/public/assets/coffee-C-Mn3tBT.js +1 -0
  48. package/dist/web/public/assets/common-lisp-DYnOjAFz.js +1 -0
  49. package/dist/web/public/assets/components-DiZ1dSl3.js +77 -0
  50. package/dist/web/public/assets/coq-BaHtq3Qt.js +1 -0
  51. package/dist/web/public/assets/cpp-D8Y73ItU.js +1 -0
  52. package/dist/web/public/assets/crystal-CnXWqbxx.js +1 -0
  53. package/dist/web/public/assets/csharp-D6sghVPa.js +1 -0
  54. package/dist/web/public/assets/css-CUGjdPw_.js +1 -0
  55. package/dist/web/public/assets/csv-DuxyxUAI.js +1 -0
  56. package/dist/web/public/assets/cue-D9NRAX0_.js +1 -0
  57. package/dist/web/public/assets/cypher-HJRdtilF.js +1 -0
  58. package/dist/web/public/assets/d-B4Ont7_X.js +1 -0
  59. package/dist/web/public/assets/dark-plus-DZSBycyp.js +1 -0
  60. package/dist/web/public/assets/dart-Dp4asavE.js +1 -0
  61. package/dist/web/public/assets/dax-DBUubp6S.js +1 -0
  62. package/dist/web/public/assets/desktop-DQ0n6zIQ.js +1 -0
  63. package/dist/web/public/assets/diff-CFHlrffC.js +1 -0
  64. package/dist/web/public/assets/docker-BuefmsF5.js +1 -0
  65. package/dist/web/public/assets/dotenv-BKTsUQ_r.js +1 -0
  66. package/dist/web/public/assets/dracula-MOn9qacs.js +1 -0
  67. package/dist/web/public/assets/dracula-soft-C4r_sC_D.js +1 -0
  68. package/dist/web/public/assets/dream-maker-BNdv5lLS.js +1 -0
  69. package/dist/web/public/assets/edge-C-Mi8Oda.js +1 -0
  70. package/dist/web/public/assets/elixir-CTS5wQtX.js +1 -0
  71. package/dist/web/public/assets/elm-rM310x8D.js +1 -0
  72. package/dist/web/public/assets/emacs-lisp-D9FIGRtM.js +1 -0
  73. package/dist/web/public/assets/erb-oaGjGVGO.js +1 -0
  74. package/dist/web/public/assets/erlang-q4Mkyw3m.js +1 -0
  75. package/dist/web/public/assets/everforest-dark-CNa2QFRn.js +1 -0
  76. package/dist/web/public/assets/everforest-light-DRbUDqJT.js +1 -0
  77. package/dist/web/public/assets/fennel-DpqQTaVZ.js +1 -0
  78. package/dist/web/public/assets/field-1-Ujza0S5j.js +1 -0
  79. package/dist/web/public/assets/fish-hyk5x6Q4.js +1 -0
  80. package/dist/web/public/assets/fluent-DMll-MGX.js +1 -0
  81. package/dist/web/public/assets/fortran-fixed-form-BmdfKovV.js +1 -0
  82. package/dist/web/public/assets/fortran-free-form-MCAifii4.js +1 -0
  83. package/dist/web/public/assets/fsharp-DLlBn9Nl.js +1 -0
  84. package/dist/web/public/assets/gdresource-BzFzBRli.js +1 -0
  85. package/dist/web/public/assets/gdscript-D3R4J0Cv.js +1 -0
  86. package/dist/web/public/assets/gdshader-BAubtqqN.js +1 -0
  87. package/dist/web/public/assets/genie-BnIIX2pC.js +1 -0
  88. package/dist/web/public/assets/gherkin-CL3NUuB1.js +1 -0
  89. package/dist/web/public/assets/git-commit-BYPE8h85.js +1 -0
  90. package/dist/web/public/assets/git-rebase-Bmmgf6eN.js +1 -0
  91. package/dist/web/public/assets/github-dark-default-C6I2oE4c.js +1 -0
  92. package/dist/web/public/assets/github-dark-dimmed-DEqwxg6D.js +1 -0
  93. package/dist/web/public/assets/github-dark-high-contrast-DDt3j0cs.js +1 -0
  94. package/dist/web/public/assets/github-dark-oLN6SDKl.js +1 -0
  95. package/dist/web/public/assets/github-light-DaN-N2Gj.js +1 -0
  96. package/dist/web/public/assets/github-light-default-B3EwMbS7.js +1 -0
  97. package/dist/web/public/assets/github-light-high-contrast-Cl9D0f_e.js +1 -0
  98. package/dist/web/public/assets/gleam-Cvj8QRtQ.js +1 -0
  99. package/dist/web/public/assets/glimmer-js-CahbROb1.js +1 -0
  100. package/dist/web/public/assets/glimmer-ts-JMFYNbot.js +1 -0
  101. package/dist/web/public/assets/global-XWAvxWcA.css +2 -0
  102. package/dist/web/public/assets/glsl-BCuCNM3V.js +1 -0
  103. package/dist/web/public/assets/gn-DxCHSEMl.js +1 -0
  104. package/dist/web/public/assets/gnuplot-CkGXHK7B.js +1 -0
  105. package/dist/web/public/assets/go-B_NLCuTj.js +1 -0
  106. package/dist/web/public/assets/graphql-RXOfHGfI.js +1 -0
  107. package/dist/web/public/assets/groovy-DVge8oRs.js +1 -0
  108. package/dist/web/public/assets/gruvbox-dark-hard-BwZz1yni.js +1 -0
  109. package/dist/web/public/assets/gruvbox-dark-medium-Bqy6jkuO.js +1 -0
  110. package/dist/web/public/assets/gruvbox-dark-soft-DjUvyUfH.js +1 -0
  111. package/dist/web/public/assets/gruvbox-light-hard-BTLmfPdm.js +1 -0
  112. package/dist/web/public/assets/gruvbox-light-medium-DeWqsWs6.js +1 -0
  113. package/dist/web/public/assets/gruvbox-light-soft-BL8ld-1F.js +1 -0
  114. package/dist/web/public/assets/hack-BBQpwyf_.js +1 -0
  115. package/dist/web/public/assets/haml-mWELc9kh.js +1 -0
  116. package/dist/web/public/assets/handlebars-COrUo8cC.js +1 -0
  117. package/dist/web/public/assets/haskell-DRmM8XlQ.js +1 -0
  118. package/dist/web/public/assets/haxe-BEhq8ZEr.js +1 -0
  119. package/dist/web/public/assets/hcl-B5ZIaGS0.js +1 -0
  120. package/dist/web/public/assets/highlighted-body-TPN3WLV5-YJgGFx4e.js +1 -0
  121. package/dist/web/public/assets/hjson-B9uRLqIO.js +1 -0
  122. package/dist/web/public/assets/hlsl-Hv1kKjrS.js +1 -0
  123. package/dist/web/public/assets/horizon-ClXGBjWw.js +1 -0
  124. package/dist/web/public/assets/horizon-bright-CvUCr3ux.js +1 -0
  125. package/dist/web/public/assets/houston-NqkqG60q.js +1 -0
  126. package/dist/web/public/assets/html-cmigv1ou.js +1 -0
  127. package/dist/web/public/assets/html-derivative-B3me0pSu.js +1 -0
  128. package/dist/web/public/assets/http-BojM9cyU.js +1 -0
  129. package/dist/web/public/assets/hurl-BxEmMiGP.js +1 -0
  130. package/dist/web/public/assets/hxml-CoBuVbfs.js +1 -0
  131. package/dist/web/public/assets/hy-CeISYGGU.js +1 -0
  132. package/dist/web/public/assets/imba-xjcDFXUW.js +1 -0
  133. package/dist/web/public/assets/ini-D0ZCSj6e.js +1 -0
  134. package/dist/web/public/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  135. package/dist/web/public/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  136. package/dist/web/public/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  137. package/dist/web/public/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  138. package/dist/web/public/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  139. package/dist/web/public/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  140. package/dist/web/public/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  141. package/dist/web/public/assets/java-BvheClGI.js +1 -0
  142. package/dist/web/public/assets/javascript-DjlJORDg.js +1 -0
  143. package/dist/web/public/assets/jinja-Bi4sG72X.js +1 -0
  144. package/dist/web/public/assets/jison-BTz5Ik2Y.js +1 -0
  145. package/dist/web/public/assets/json-CiTd40Rg.js +1 -0
  146. package/dist/web/public/assets/json5-FR9EyF7a.js +1 -0
  147. package/dist/web/public/assets/jsonc-CHIeFfsD.js +1 -0
  148. package/dist/web/public/assets/jsonl-B4WQkwTf.js +1 -0
  149. package/dist/web/public/assets/jsonnet-vd-gzGkL.js +1 -0
  150. package/dist/web/public/assets/jssm-C_bj1LkZ.js +1 -0
  151. package/dist/web/public/assets/jsx-Bx-RZMFH.js +1 -0
  152. package/dist/web/public/assets/jsx-runtime-n8k0hwt8.js +1 -0
  153. package/dist/web/public/assets/julia-BKcIfSxk.js +1 -0
  154. package/dist/web/public/assets/just-IkZCagAs.js +1 -0
  155. package/dist/web/public/assets/kanagawa-dragon-B3Cz89vt.js +1 -0
  156. package/dist/web/public/assets/kanagawa-lotus-CRe_W5Ft.js +1 -0
  157. package/dist/web/public/assets/kanagawa-wave-BPqZ5XB7.js +1 -0
  158. package/dist/web/public/assets/kdl-BzL_Ak31.js +1 -0
  159. package/dist/web/public/assets/kotlin-BQQFk6ql.js +1 -0
  160. package/dist/web/public/assets/kusto-vWe6OLKV.js +1 -0
  161. package/dist/web/public/assets/laserwave-CwtvEUcj.js +1 -0
  162. package/dist/web/public/assets/latex-9N90_WFU.js +1 -0
  163. package/dist/web/public/assets/lean-CaqenOqv.js +1 -0
  164. package/dist/web/public/assets/less-CERnPzn6.js +1 -0
  165. package/dist/web/public/assets/light-plus-B9_M_OKq.js +1 -0
  166. package/dist/web/public/assets/liquid-CQLPDP7m.js +1 -0
  167. package/dist/web/public/assets/llvm-BylJXvm7.js +1 -0
  168. package/dist/web/public/assets/log-CBBcNcbO.js +1 -0
  169. package/dist/web/public/assets/logo-r-8Jc8Xk.js +1 -0
  170. package/dist/web/public/assets/lua-BBL6LXKd.js +1 -0
  171. package/dist/web/public/assets/luau-B2g7L-zP.js +1 -0
  172. package/dist/web/public/assets/main-0lKVDR64.css +2 -0
  173. package/dist/web/public/assets/main-CcNf0BOb.js +126 -0
  174. package/dist/web/public/assets/make-DK-HzJ2w.js +1 -0
  175. package/dist/web/public/assets/markdown-FgdsukgR.js +1 -0
  176. package/dist/web/public/assets/marko-CLZwt2N2.js +1 -0
  177. package/dist/web/public/assets/material-theme-DOJ9PS4O.js +1 -0
  178. package/dist/web/public/assets/material-theme-darker-DOurH5jT.js +1 -0
  179. package/dist/web/public/assets/material-theme-lighter-BfPWxCP6.js +1 -0
  180. package/dist/web/public/assets/material-theme-ocean-BcO5PKoq.js +1 -0
  181. package/dist/web/public/assets/material-theme-palenight-ClWQBDDd.js +1 -0
  182. package/dist/web/public/assets/matlab-DwyUVNXd.js +1 -0
  183. package/dist/web/public/assets/mdc-Bo8CRPg4.js +1 -0
  184. package/dist/web/public/assets/mdx-3EBShbsD.js +1 -0
  185. package/dist/web/public/assets/mermaid-ByG2-SLz.js +1 -0
  186. package/dist/web/public/assets/mermaid-O7DHMXV3-COAgR3aM.js +1 -0
  187. package/dist/web/public/assets/min-dark-ClJ2x5pc.js +1 -0
  188. package/dist/web/public/assets/min-light-BsOUz5iE.js +1 -0
  189. package/dist/web/public/assets/mipsasm-BKDtQCf3.js +1 -0
  190. package/dist/web/public/assets/mojo-DmEAK7iv.js +1 -0
  191. package/dist/web/public/assets/monokai-BKc3VADO.js +1 -0
  192. package/dist/web/public/assets/moonbit-Qm8v_cKN.js +1 -0
  193. package/dist/web/public/assets/move-CMectUPk.js +1 -0
  194. package/dist/web/public/assets/narrat-Bdm8NaK8.js +1 -0
  195. package/dist/web/public/assets/nextflow-BpSt05nC.js +1 -0
  196. package/dist/web/public/assets/nextflow-groovy-BZ-bqJ-u.js +1 -0
  197. package/dist/web/public/assets/nginx-ChZL5FWE.js +1 -0
  198. package/dist/web/public/assets/night-owl-CbFc5pXO.js +1 -0
  199. package/dist/web/public/assets/night-owl-light-zYbVCVuz.js +1 -0
  200. package/dist/web/public/assets/nim-5JnPAJWa.js +1 -0
  201. package/dist/web/public/assets/nix-P5P-2qHs.js +1 -0
  202. package/dist/web/public/assets/nord-C7hKGudV.js +1 -0
  203. package/dist/web/public/assets/nushell-DKPnC5RG.js +1 -0
  204. package/dist/web/public/assets/objective-c-BPwXtM0v.js +1 -0
  205. package/dist/web/public/assets/objective-cpp-CWYEdWNG.js +1 -0
  206. package/dist/web/public/assets/ocaml-CL7OJ02v.js +1 -0
  207. package/dist/web/public/assets/odin-Dtay25eA.js +1 -0
  208. package/dist/web/public/assets/one-dark-pro-CrdFNNwF.js +1 -0
  209. package/dist/web/public/assets/one-light-BUiz8X4B.js +1 -0
  210. package/dist/web/public/assets/openscad-WD4sXUUp.js +1 -0
  211. package/dist/web/public/assets/pascal-A6-MZnZ8.js +1 -0
  212. package/dist/web/public/assets/perl-Yq3AfnVV.js +1 -0
  213. package/dist/web/public/assets/php-CCj0foPx.js +1 -0
  214. package/dist/web/public/assets/pkl-cmPbg8fI.js +1 -0
  215. package/dist/web/public/assets/plastic-DtQ_LnDB.js +1 -0
  216. package/dist/web/public/assets/plsql-DwmuVd7q.js +1 -0
  217. package/dist/web/public/assets/po-CkVxkZaj.js +1 -0
  218. package/dist/web/public/assets/poimandres-Dt0xZuaa.js +1 -0
  219. package/dist/web/public/assets/polar-hStNz_W2.js +1 -0
  220. package/dist/web/public/assets/postcss-ZIk0AQ7M.js +1 -0
  221. package/dist/web/public/assets/powerquery-D0gqoHHD.js +1 -0
  222. package/dist/web/public/assets/powershell-DXB5HoVh.js +1 -0
  223. package/dist/web/public/assets/prisma-DmTrfxC0.js +1 -0
  224. package/dist/web/public/assets/prolog-CdoyriEj.js +1 -0
  225. package/dist/web/public/assets/proto-4MrN11dS.js +1 -0
  226. package/dist/web/public/assets/pug-svYJKDOQ.js +1 -0
  227. package/dist/web/public/assets/puppet-MEaLGpAP.js +1 -0
  228. package/dist/web/public/assets/purescript-CPxCorqB.js +1 -0
  229. package/dist/web/public/assets/python-f4fp5z0z.js +1 -0
  230. package/dist/web/public/assets/qml-BzEtWdqI.js +1 -0
  231. package/dist/web/public/assets/qmldir-DCjSceJ_.js +1 -0
  232. package/dist/web/public/assets/qss-BdM02NUc.js +1 -0
  233. package/dist/web/public/assets/r-luosIeJH.js +1 -0
  234. package/dist/web/public/assets/racket-D2tfa8Zc.js +1 -0
  235. package/dist/web/public/assets/raku-KeGPJVZg.js +1 -0
  236. package/dist/web/public/assets/razor-Bokxs4Qx.js +1 -0
  237. package/dist/web/public/assets/red-C0qZ-1lN.js +1 -0
  238. package/dist/web/public/assets/reg-DdnswvOj.js +1 -0
  239. package/dist/web/public/assets/regexp-CYC8h6V9.js +1 -0
  240. package/dist/web/public/assets/rel-RhzEfSRc.js +1 -0
  241. package/dist/web/public/assets/riscv-dS5TzX10.js +1 -0
  242. package/dist/web/public/assets/ron-CQjQSCVp.js +1 -0
  243. package/dist/web/public/assets/rose-pine-C89ViLdr.js +1 -0
  244. package/dist/web/public/assets/rose-pine-dawn-Dq2gf0yi.js +1 -0
  245. package/dist/web/public/assets/rose-pine-moon-CBDvXVs_.js +1 -0
  246. package/dist/web/public/assets/rosmsg-nvjuSIGu.js +1 -0
  247. package/dist/web/public/assets/routes-BXqJCOpL.js +542 -0
  248. package/dist/web/public/assets/rst-1xwvVGf7.js +1 -0
  249. package/dist/web/public/assets/ruby-Blad-eDx.js +1 -0
  250. package/dist/web/public/assets/rust-rV8q_xyI.js +1 -0
  251. package/dist/web/public/assets/sas-DUPWtptg.js +1 -0
  252. package/dist/web/public/assets/sass-CuxdoNN0.js +1 -0
  253. package/dist/web/public/assets/scala-Df4L7N3R.js +1 -0
  254. package/dist/web/public/assets/scheme-DalRmAPH.js +1 -0
  255. package/dist/web/public/assets/scss-CYQ8LEwP.js +1 -0
  256. package/dist/web/public/assets/sdbl-B_TmFnGf.js +1 -0
  257. package/dist/web/public/assets/shaderlab-DYEMDY3e.js +1 -0
  258. package/dist/web/public/assets/shellscript-DjKZ34ac.js +1 -0
  259. package/dist/web/public/assets/shellsession-C3kcnBnh.js +1 -0
  260. package/dist/web/public/assets/slack-dark-ak_jOeLl.js +1 -0
  261. package/dist/web/public/assets/slack-ochin-ByiYhLwu.js +1 -0
  262. package/dist/web/public/assets/smalltalk-DTTnjjZJ.js +1 -0
  263. package/dist/web/public/assets/snazzy-light-BBRYeY60.js +1 -0
  264. package/dist/web/public/assets/solarized-dark-BtoLnWkw.js +1 -0
  265. package/dist/web/public/assets/solarized-light-CtzUA7GI.js +1 -0
  266. package/dist/web/public/assets/solidity-CSIHEQ2t.js +1 -0
  267. package/dist/web/public/assets/soy-BN0uzUAI.js +1 -0
  268. package/dist/web/public/assets/sparql-B6k9tA6Q.js +1 -0
  269. package/dist/web/public/assets/splunk-DkRzN7V_.js +1 -0
  270. package/dist/web/public/assets/sql-Bx-WX28V.js +1 -0
  271. package/dist/web/public/assets/ssh-config-Bqp7ng33.js +1 -0
  272. package/dist/web/public/assets/stata-HAj7doU8.js +1 -0
  273. package/dist/web/public/assets/stylus-CdbCxDLX.js +1 -0
  274. package/dist/web/public/assets/surrealql-BkGf0I3k.js +1 -0
  275. package/dist/web/public/assets/svelte-DtWg6ssL.js +1 -0
  276. package/dist/web/public/assets/swift-yRu2dtgr.js +1 -0
  277. package/dist/web/public/assets/synthwave-84-2WIu6MHX.js +1 -0
  278. package/dist/web/public/assets/system-verilog-GUE_oP1V.js +1 -0
  279. package/dist/web/public/assets/systemd-FLIJAQZV.js +1 -0
  280. package/dist/web/public/assets/talonscript-DTR-8ILs.js +1 -0
  281. package/dist/web/public/assets/tasl-WHNWP-1F.js +1 -0
  282. package/dist/web/public/assets/tcl-BaBXNNp6.js +1 -0
  283. package/dist/web/public/assets/templ-Dc9vj00n.js +1 -0
  284. package/dist/web/public/assets/terraform-uJUFpr8t.js +1 -0
  285. package/dist/web/public/assets/tex-DA3dAz55.js +1 -0
  286. package/dist/web/public/assets/tokyo-night-BbogFqAr.js +1 -0
  287. package/dist/web/public/assets/toml-CyR4Gqq1.js +1 -0
  288. package/dist/web/public/assets/ts-tags-BD1j21LH.js +1 -0
  289. package/dist/web/public/assets/tsv-COLVYI6A.js +1 -0
  290. package/dist/web/public/assets/tsx-CFm2E6uK.js +1 -0
  291. package/dist/web/public/assets/turtle-PQwt4gkb.js +1 -0
  292. package/dist/web/public/assets/twig-DrUXy85s.js +1 -0
  293. package/dist/web/public/assets/typescript-Dy-5sXFx.js +1 -0
  294. package/dist/web/public/assets/typespec-Bb7qHV0g.js +1 -0
  295. package/dist/web/public/assets/typst-Bj_JElGz.js +1 -0
  296. package/dist/web/public/assets/v-BTkrtik4.js +1 -0
  297. package/dist/web/public/assets/vala-AXT1CI9v.js +1 -0
  298. package/dist/web/public/assets/vb-DzTKUgW8.js +1 -0
  299. package/dist/web/public/assets/verilog-aI3j5Xj8.js +1 -0
  300. package/dist/web/public/assets/vesper-BmnwIC_B.js +1 -0
  301. package/dist/web/public/assets/vhdl-4IgBB7vO.js +1 -0
  302. package/dist/web/public/assets/viml-D_XMKSR6.js +1 -0
  303. package/dist/web/public/assets/vitesse-black-DhmxIXiA.js +1 -0
  304. package/dist/web/public/assets/vitesse-dark-dvEH_9qt.js +1 -0
  305. package/dist/web/public/assets/vitesse-light-Ca0W2L1O.js +1 -0
  306. package/dist/web/public/assets/vue-DC_yTvy2.js +1 -0
  307. package/dist/web/public/assets/vue-html-Bp8x4gdt.js +1 -0
  308. package/dist/web/public/assets/vue-vine-ZcUkuUUp.js +1 -0
  309. package/dist/web/public/assets/vyper-Dz2f7-FK.js +1 -0
  310. package/dist/web/public/assets/wasm-CuXPCj65.js +1 -0
  311. package/dist/web/public/assets/wasm-DHkXUMsP.js +1 -0
  312. package/dist/web/public/assets/wenyan-BRAtM0Iv.js +1 -0
  313. package/dist/web/public/assets/wgsl-CMpn9jTa.js +1 -0
  314. package/dist/web/public/assets/wikitext-DRmBVmVA.js +1 -0
  315. package/dist/web/public/assets/wit-Drp_HLqJ.js +1 -0
  316. package/dist/web/public/assets/wolfram-C33umj7M.js +1 -0
  317. package/dist/web/public/assets/xml-BHoOtGbO.js +1 -0
  318. package/dist/web/public/assets/xsl-CN1PlFqm.js +1 -0
  319. package/dist/web/public/assets/yaml-DT0mpn8u.js +1 -0
  320. package/dist/web/public/assets/zenscript-BlYQ_Frf.js +1 -0
  321. package/dist/web/public/assets/zig-Buk7I0y-.js +1 -0
  322. package/dist/web/server/_chunks/ssr-renderer.mjs +15 -0
  323. package/dist/web/server/_libs/@ai-sdk/anthropic+[...].mjs +14021 -0
  324. package/dist/web/server/_libs/@ai-sdk/moonshotai+[...].mjs +898 -0
  325. package/dist/web/server/_libs/@ai-sdk/react+[...].mjs +8969 -0
  326. package/dist/web/server/_libs/@emotion/is-prop-valid+[...].mjs +34 -0
  327. package/dist/web/server/_libs/@floating-ui/core+[...].mjs +698 -0
  328. package/dist/web/server/_libs/@floating-ui/dom+[...].mjs +644 -0
  329. package/dist/web/server/_libs/@floating-ui/react-dom+[...].mjs +475 -0
  330. package/dist/web/server/_libs/@lobehub/icons+[...].mjs +3079 -0
  331. package/dist/web/server/_libs/@radix-ui/react-arrow+[...].mjs +184 -0
  332. package/dist/web/server/_libs/@radix-ui/react-collapsible+[...].mjs +374 -0
  333. package/dist/web/server/_libs/@radix-ui/react-dialog+[...].mjs +1503 -0
  334. package/dist/web/server/_libs/@radix-ui/react-menu+[...].mjs +1236 -0
  335. package/dist/web/server/_libs/@radix-ui/react-select+[...].mjs +1007 -0
  336. package/dist/web/server/_libs/@shikijs/core+[...].mjs +9017 -0
  337. package/dist/web/server/_libs/@shikijs/engine-javascript+[...].mjs +3159 -0
  338. package/dist/web/server/_libs/@streamdown/math+[...].mjs +37559 -0
  339. package/dist/web/server/_libs/@tanstack/react-router+[...].mjs +14074 -0
  340. package/dist/web/server/_libs/_.mjs +3 -0
  341. package/dist/web/server/_libs/_2.mjs +3 -0
  342. package/dist/web/server/_libs/_3.mjs +2 -0
  343. package/dist/web/server/_libs/_4.mjs +2 -0
  344. package/dist/web/server/_libs/ai-sdk__gateway+vercel__oidc.mjs +1255 -0
  345. package/dist/web/server/_libs/ai-sdk__google.mjs +1630 -0
  346. package/dist/web/server/_libs/ai-sdk__openai+zod.mjs +4951 -0
  347. package/dist/web/server/_libs/ai-sdk__provider-utils.mjs +411 -0
  348. package/dist/web/server/_libs/ai-sdk__provider.mjs +222 -0
  349. package/dist/web/server/_libs/bail.mjs +13 -0
  350. package/dist/web/server/_libs/character-entities.mjs +2135 -0
  351. package/dist/web/server/_libs/class-variance-authority+clsx.mjs +69 -0
  352. package/dist/web/server/_libs/color+[...].mjs +2185 -0
  353. package/dist/web/server/_libs/copy-text-to-clipboard.mjs +40 -0
  354. package/dist/web/server/_libs/d3-array.mjs +231 -0
  355. package/dist/web/server/_libs/d3-color.mjs +330 -0
  356. package/dist/web/server/_libs/d3-format.mjs +252 -0
  357. package/dist/web/server/_libs/d3-interpolate.mjs +207 -0
  358. package/dist/web/server/_libs/d3-path.mjs +77 -0
  359. package/dist/web/server/_libs/d3-scale+[...].mjs +1907 -0
  360. package/dist/web/server/_libs/d3-shape.mjs +818 -0
  361. package/dist/web/server/_libs/date-fns.mjs +3012 -0
  362. package/dist/web/server/_libs/date-fns__tz.mjs +249 -0
  363. package/dist/web/server/_libs/decimal.js-light.mjs +884 -0
  364. package/dist/web/server/_libs/decode-named-character-reference+[...].mjs +19 -0
  365. package/dist/web/server/_libs/dexie.mjs +3745 -0
  366. package/dist/web/server/_libs/escape-string-regexp.mjs +7 -0
  367. package/dist/web/server/_libs/estree-util-is-identifier-name.mjs +20 -0
  368. package/dist/web/server/_libs/eventemitter3.mjs +237 -0
  369. package/dist/web/server/_libs/extend.mjs +75 -0
  370. package/dist/web/server/_libs/fast-equals.mjs +423 -0
  371. package/dist/web/server/_libs/framer-motion+[...].mjs +9573 -0
  372. package/dist/web/server/_libs/fuzzysort.mjs +621 -0
  373. package/dist/web/server/_libs/h3+rou3+srvx.mjs +1158 -0
  374. package/dist/web/server/_libs/hast-util-raw+[...].mjs +800 -0
  375. package/dist/web/server/_libs/hast-util-sanitize.mjs +780 -0
  376. package/dist/web/server/_libs/hast-util-to-jsx-runtime+[...].mjs +853 -0
  377. package/dist/web/server/_libs/hookable.mjs +41 -0
  378. package/dist/web/server/_libs/html-url-attributes.mjs +44 -0
  379. package/dist/web/server/_libs/is-plain-obj.mjs +8 -0
  380. package/dist/web/server/_libs/lodash.mjs +4532 -0
  381. package/dist/web/server/_libs/lucide-react.mjs +605 -0
  382. package/dist/web/server/_libs/markdown-table.mjs +289 -0
  383. package/dist/web/server/_libs/marked.mjs +1511 -0
  384. package/dist/web/server/_libs/mdast-util-find-and-replace.mjs +198 -0
  385. package/dist/web/server/_libs/mdast-util-from-markdown+[...].mjs +8121 -0
  386. package/dist/web/server/_libs/mdast-util-gfm+[...].mjs +2060 -0
  387. package/dist/web/server/_libs/mdast-util-to-hast+[...].mjs +1770 -0
  388. package/dist/web/server/_libs/micromark-extension-gfm+[...].mjs +2235 -0
  389. package/dist/web/server/_libs/nanoid.mjs +26 -0
  390. package/dist/web/server/_libs/next-themes.mjs +124 -0
  391. package/dist/web/server/_libs/prop-types.mjs +69 -0
  392. package/dist/web/server/_libs/radix-ui__number.mjs +6 -0
  393. package/dist/web/server/_libs/radix-ui__primitive.mjs +9 -0
  394. package/dist/web/server/_libs/radix-ui__react-collection.mjs +80 -0
  395. package/dist/web/server/_libs/radix-ui__react-direction.mjs +11 -0
  396. package/dist/web/server/_libs/radix-ui__react-label.mjs +23 -0
  397. package/dist/web/server/_libs/radix-ui__react-menubar.mjs +400 -0
  398. package/dist/web/server/_libs/radix-ui__react-popover.mjs +251 -0
  399. package/dist/web/server/_libs/radix-ui__react-progress.mjs +81 -0
  400. package/dist/web/server/_libs/radix-ui__react-scroll-area.mjs +669 -0
  401. package/dist/web/server/_libs/radix-ui__react-separator.mjs +32 -0
  402. package/dist/web/server/_libs/radix-ui__react-slider.mjs +464 -0
  403. package/dist/web/server/_libs/radix-ui__react-switch.mjs +120 -0
  404. package/dist/web/server/_libs/radix-ui__react-tabs.mjs +145 -0
  405. package/dist/web/server/_libs/radix-ui__react-tooltip.mjs +494 -0
  406. package/dist/web/server/_libs/react-day-picker.mjs +3510 -0
  407. package/dist/web/server/_libs/react-is.mjs +48 -0
  408. package/dist/web/server/_libs/react-resizable-panels.mjs +1517 -0
  409. package/dist/web/server/_libs/react-smooth.mjs +1024 -0
  410. package/dist/web/server/_libs/recharts+[...].mjs +12998 -0
  411. package/dist/web/server/_libs/rehype-harden.mjs +210 -0
  412. package/dist/web/server/_libs/rehype-raw.mjs +37 -0
  413. package/dist/web/server/_libs/rehype-sanitize.mjs +27 -0
  414. package/dist/web/server/_libs/remark-gfm.mjs +34 -0
  415. package/dist/web/server/_libs/remark-parse.mjs +37 -0
  416. package/dist/web/server/_libs/remark-rehype.mjs +169 -0
  417. package/dist/web/server/_libs/remend.mjs +544 -0
  418. package/dist/web/server/_libs/scule.mjs +55 -0
  419. package/dist/web/server/_libs/shiki+streamdown__code.mjs +1748 -0
  420. package/dist/web/server/_libs/shiki.mjs +16 -0
  421. package/dist/web/server/_libs/shikijs__engine-oniguruma.mjs +387 -0
  422. package/dist/web/server/_libs/shikijs__langs.mjs +1357 -0
  423. package/dist/web/server/_libs/shikijs__themes.mjs +268 -0
  424. package/dist/web/server/_libs/sonner.mjs +909 -0
  425. package/dist/web/server/_libs/streamdown+[...].mjs +5842 -0
  426. package/dist/web/server/_libs/tanstack__history.mjs +342 -0
  427. package/dist/web/server/_libs/tanstack__query-core.mjs +2073 -0
  428. package/dist/web/server/_libs/tanstack__react-query.mjs +146 -0
  429. package/dist/web/server/_libs/tanstack__router-core.mjs +6 -0
  430. package/dist/web/server/_libs/tanstack__zod-adapter.mjs +16 -0
  431. package/dist/web/server/_libs/ufo.mjs +64 -0
  432. package/dist/web/server/_libs/ungap__structured-clone.mjs +197 -0
  433. package/dist/web/server/_libs/use-stick-to-bottom.mjs +410 -0
  434. package/dist/web/server/_libs/vercel__oidc.mjs +393 -0
  435. package/dist/web/server/_libs/zhipu-ai-provider.mjs +13483 -0
  436. package/dist/web/server/_libs/zustand.mjs +48 -0
  437. package/dist/web/server/_runtime.mjs +35 -0
  438. package/dist/web/server/_ssr/components-BzCiScpA.mjs +1452 -0
  439. package/dist/web/server/_ssr/dist-3Mu7PF0n.mjs +137 -0
  440. package/dist/web/server/_ssr/dist-BRaLXgxZ.mjs +17 -0
  441. package/dist/web/server/_ssr/field-1-agM60DBf.mjs +167 -0
  442. package/dist/web/server/_ssr/get-providers-BoYkp0Of.mjs +40 -0
  443. package/dist/web/server/_ssr/initialize-provider-B6W8V5Eg.mjs +19 -0
  444. package/dist/web/server/_ssr/model-list-CDFjdz2P.mjs +60 -0
  445. package/dist/web/server/_ssr/router-BmmOCtJZ.mjs +168 -0
  446. package/dist/web/server/_ssr/routes-CvlpZK4Q.mjs +2630 -0
  447. package/dist/web/server/_ssr/schemas-DsZ5O3zp.mjs +67 -0
  448. package/dist/web/server/_ssr/send-message-DUT1vRvx.mjs +135 -0
  449. package/dist/web/server/_ssr/ssr.mjs +5253 -0
  450. package/dist/web/server/_ssr/start-rewezkfD.mjs +4 -0
  451. package/dist/web/server/_ssr/submit-key-CcCv6-yy.mjs +62 -0
  452. package/dist/web/server/_ssr/suggestions-B0Uc3p7F.mjs +38 -0
  453. package/dist/web/server/_ssr/use-providers-Bwqg2U3N.mjs +1554 -0
  454. package/dist/web/server/_tanstack-start-manifest_v-BMIvh4y6.mjs +60 -0
  455. package/dist/web/server/index.mjs +2531 -0
  456. package/dist/web/server/node_modules/tslib/modules/index.js +70 -0
  457. package/dist/web/server/node_modules/tslib/modules/package.json +3 -0
  458. package/dist/web/server/node_modules/tslib/package.json +47 -0
  459. package/dist/web/server/node_modules/tslib/tslib.js +484 -0
  460. package/package.json +32 -0
@@ -0,0 +1,2630 @@
1
+ import { i as __toESM } from "../_runtime.mjs";
2
+ import { n as DefaultChatTransport, t as useChat, u as require_react } from "../_libs/@ai-sdk/react+[...].mjs";
3
+ import { a as Icons$2, i as Icons$4, n as Icons$3, o as Icons$1, r as Icons, s as require_jsx_runtime, t as Icons$5 } from "../_libs/@lobehub/icons+[...].mjs";
4
+ import { B as ArrowDown, D as Copy, E as CornerDownLeft, F as Check, I as Brain, M as ChevronRight, O as CodeXml, P as ChevronDown, R as ArrowRight, S as LoaderCircle, T as GripVertical, _ as Palette, a as Trash2, b as Moon, c as Sparkle, d as RefreshCcw, f as Plus, g as PanelLeft, h as Pencil, j as ChevronUp, k as Clover, l as Settings2, m as Pipette, n as TypeOutline, o as Sun, p as Play, s as Square, t as X, u as ScanEye, y as MousePointerClick, z as ArrowLeft } from "../_libs/lucide-react.mjs";
5
+ import { n as clsx, t as cva } from "../_libs/class-variance-authority+clsx.mjs";
6
+ import { n as Us } from "../_libs/streamdown+[...].mjs";
7
+ import { a as ItemText, c as ScrollDownButton, d as Value, f as Viewport, i as ItemIndicator, l as ScrollUpButton, n as Icon, o as Portal, r as Item, s as Root2, t as Content2, u as Trigger } from "../_libs/@radix-ui/react-select+[...].mjs";
8
+ import { n as CollapsibleTrigger$1, o as useControllableState, r as Root$1, t as CollapsibleContent$1 } from "../_libs/@radix-ui/react-collapsible+[...].mjs";
9
+ import { a as Portal$1, c as Trigger$1, i as Overlay, n as Content, o as Root$2, r as Description, s as Title, t as Close } from "../_libs/@radix-ui/react-dialog+[...].mjs";
10
+ import { d as isRedirect, u as useRouter } from "../_libs/@tanstack/react-router+[...].mjs";
11
+ import { a as Root3, c as SubTrigger2, i as Portal2, l as Trigger$2, n as Item3, o as Sub2, r as Menu, s as SubContent2, t as Content2$1 } from "../_libs/radix-ui__react-menubar.mjs";
12
+ import { a as Trigger$3, i as Root2$1, n as PopoverClose, r as Portal$2, t as Content2$2 } from "../_libs/radix-ui__react-popover.mjs";
13
+ import { a as Viewport$1, i as ScrollAreaThumb, n as Root$3, r as ScrollAreaScrollbar, t as Corner } from "../_libs/radix-ui__react-scroll-area.mjs";
14
+ import { t as dist_exports } from "../_libs/radix-ui__react-slider.mjs";
15
+ import { n as Thumb$1, t as Root$4 } from "../_libs/radix-ui__react-switch.mjs";
16
+ import { i as Trigger$4, n as List, r as Root2$2, t as Content$1 } from "../_libs/radix-ui__react-tabs.mjs";
17
+ import { a as Root3$1, i as Provider, n as Content2$3, o as Trigger$5, r as Portal$3, t as Arrow2 } from "../_libs/radix-ui__react-tooltip.mjs";
18
+ import { d as Spinner, i as FieldError, l as Input, m as isLocal, n as Field, p as cn, t as Button, u as Separator$1 } from "./field-1-agM60DBf.mjs";
19
+ import { n as AnimatePresence, t as motion } from "../_libs/framer-motion+[...].mjs";
20
+ import { t as createHighlighterCore } from "../_libs/@shikijs/core+[...].mjs";
21
+ import { t as A } from "../_libs/shiki+streamdown__code.mjs";
22
+ import { t as createJavaScriptRegexEngine } from "../_libs/@shikijs/engine-javascript+[...].mjs";
23
+ import { t as h } from "../_libs/@streamdown/math+[...].mjs";
24
+ import { t as createServerFn } from "./ssr.mjs";
25
+ import { n as providers, t as providerDisplay } from "./dist-BRaLXgxZ.mjs";
26
+ import { St as string, ot as _enum, yt as object } from "../_libs/@ai-sdk/anthropic+[...].mjs";
27
+ import { n as shadcnStylesSchema } from "./schemas-DsZ5O3zp.mjs";
28
+ import { n as convert, t as Color } from "../_libs/color+[...].mjs";
29
+ import { a as defaultTheme, c as formatColorName, d as premadeThemes, f as previewColors, h as useThemes, i as createSsrRpc, l as generateCode, m as useProviders, n as applyTheme, o as defaultThemeId, p as useFonts, r as colorSegments, s as displayColor, t as SvgLogo, u as loadFont } from "./use-providers-Bwqg2U3N.mjs";
30
+ import { t as zodValidator } from "../_libs/tanstack__zod-adapter.mjs";
31
+ import { n as z } from "../_libs/next-themes.mjs";
32
+ import { n as toast } from "../_libs/sonner.mjs";
33
+ import { n as useQuery, t as useMutation } from "../_libs/tanstack__react-query.mjs";
34
+ import { n as Zt, r as qt, t as Ut } from "../_libs/react-resizable-panels.mjs";
35
+ import { t as copyTextToClipboard } from "../_libs/copy-text-to-clipboard.mjs";
36
+ import { t as nanoid } from "../_libs/nanoid.mjs";
37
+ import { n as useStickToBottomContext, t as StickToBottom } from "../_libs/use-stick-to-bottom.mjs";
38
+ import { bi as css_default } from "../_libs/shikijs__langs.mjs";
39
+ import { ft as vitesse_light_default, pt as vitesse_black_default } from "../_libs/shikijs__themes.mjs";
40
+ import { t as require_fuzzysort } from "../_libs/fuzzysort.mjs";
41
+ //#region node_modules/.nitro/vite/services/ssr/assets/routes-CvlpZK4Q.js
42
+ var import_react = /* @__PURE__ */ __toESM(require_react());
43
+ var import_jsx_runtime = require_jsx_runtime();
44
+ var import_fuzzysort = /* @__PURE__ */ __toESM(require_fuzzysort());
45
+ function useServerFn(serverFn) {
46
+ const router = useRouter();
47
+ return import_react.useCallback(async (...args) => {
48
+ try {
49
+ const res = await serverFn(...args);
50
+ if (isRedirect(res)) throw res;
51
+ return res;
52
+ } catch (err) {
53
+ if (isRedirect(err)) {
54
+ err.options._fromLocation = router.state.location;
55
+ return router.navigate(router.resolveRedirect(err).options);
56
+ }
57
+ throw err;
58
+ }
59
+ }, [router, serverFn]);
60
+ }
61
+ function ResizablePanelGroup({ className, ...props }) {
62
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Ut, {
63
+ "data-slot": "resizable-panel-group",
64
+ className: cn("flex h-full w-full data-[panel-group-direction=vertical]:flex-col", className),
65
+ ...props
66
+ });
67
+ }
68
+ function ResizablePanel({ ...props }) {
69
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(qt, {
70
+ "data-slot": "resizable-panel",
71
+ ...props
72
+ });
73
+ }
74
+ function ResizableHandle({ withHandle, className, ...props }) {
75
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Zt, {
76
+ "data-slot": "resizable-handle",
77
+ className: cn("bg-border focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 data-[panel-group-direction=vertical]:after:-translate-y-1/2 [&[data-panel-group-direction=vertical]>div]:rotate-90", className),
78
+ ...props,
79
+ children: withHandle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
80
+ className: "bg-border z-10 flex h-4 w-3 items-center justify-center rounded-xs border",
81
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GripVertical, { className: "size-2.5" })
82
+ })
83
+ });
84
+ }
85
+ function Tabs$1({ className, ...props }) {
86
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Root2$2, {
87
+ "data-slot": "tabs",
88
+ className: cn("flex flex-col gap-2", className),
89
+ ...props
90
+ });
91
+ }
92
+ function TabsList({ className, ...props }) {
93
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(List, {
94
+ "data-slot": "tabs-list",
95
+ className: cn("bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]", className),
96
+ ...props
97
+ });
98
+ }
99
+ function TabsTrigger({ className, ...props }) {
100
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trigger$4, {
101
+ "data-slot": "tabs-trigger",
102
+ className: cn("data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
103
+ ...props
104
+ });
105
+ }
106
+ function TabsContent({ className, ...props }) {
107
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Content$1, {
108
+ "data-slot": "tabs-content",
109
+ className: cn("flex-1 outline-none", className),
110
+ ...props
111
+ });
112
+ }
113
+ var ShimmerComponent = ({ children, as: Component = "p", className, duration = 2, spread = 2 }) => {
114
+ const MotionComponent = motion.create(Component);
115
+ const dynamicSpread = (0, import_react.useMemo)(() => (children?.length ?? 0) * spread, [children, spread]);
116
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MotionComponent, {
117
+ animate: { backgroundPosition: "0% center" },
118
+ className: cn("relative inline-block bg-[length:250%_100%,auto] bg-clip-text text-transparent", "[--bg:linear-gradient(90deg,#0000_calc(50%-var(--spread)),var(--color-background),#0000_calc(50%+var(--spread)))] [background-repeat:no-repeat,padding-box]", className),
119
+ initial: { backgroundPosition: "100% center" },
120
+ style: {
121
+ "--spread": `${dynamicSpread}px`,
122
+ backgroundImage: "var(--bg), linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground))"
123
+ },
124
+ transition: {
125
+ repeat: Number.POSITIVE_INFINITY,
126
+ duration,
127
+ ease: "linear"
128
+ },
129
+ children
130
+ });
131
+ };
132
+ var Shimmer = (0, import_react.memo)(ShimmerComponent);
133
+ function Collapsible$1({ ...props }) {
134
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Root$1, {
135
+ "data-slot": "collapsible",
136
+ ...props
137
+ });
138
+ }
139
+ function CollapsibleTrigger({ ...props }) {
140
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollapsibleTrigger$1, {
141
+ "data-slot": "collapsible-trigger",
142
+ ...props
143
+ });
144
+ }
145
+ function CollapsibleContent({ className, children, ...props }) {
146
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollapsibleContent$1, {
147
+ "data-slot": "collapsible-content",
148
+ className: cn("overflow-hidden data-[state=open]:animate-collapsible-down data-[state=closed]:animate-collapsible-up", className),
149
+ ...props,
150
+ children
151
+ });
152
+ }
153
+ var ReasoningContext = (0, import_react.createContext)(null);
154
+ var useReasoning = () => {
155
+ const context = (0, import_react.use)(ReasoningContext);
156
+ if (!context) throw new Error("Reasoning components must be used within Reasoning");
157
+ return context;
158
+ };
159
+ var AUTO_CLOSE_DELAY = 1e3;
160
+ var MS_IN_S = 1e3;
161
+ var Reasoning = (0, import_react.memo)(({ className, isStreaming = false, open, defaultOpen = true, onOpenChange, duration: durationProp, children, ...props }) => {
162
+ const [isOpen, setIsOpen] = useControllableState({
163
+ prop: open,
164
+ defaultProp: defaultOpen,
165
+ onChange: onOpenChange
166
+ });
167
+ const [duration, setDuration] = useControllableState({
168
+ prop: durationProp,
169
+ defaultProp: void 0
170
+ });
171
+ const [hasAutoClosed, setHasAutoClosed] = (0, import_react.useState)(false);
172
+ const [startTime, setStartTime] = (0, import_react.useState)(null);
173
+ (0, import_react.useEffect)(() => {
174
+ if (isStreaming) {
175
+ if (startTime === null) setStartTime(Date.now());
176
+ } else if (startTime !== null) {
177
+ setDuration(Math.ceil((Date.now() - startTime) / MS_IN_S));
178
+ setStartTime(null);
179
+ }
180
+ }, [
181
+ isStreaming,
182
+ startTime,
183
+ setDuration
184
+ ]);
185
+ (0, import_react.useEffect)(() => {
186
+ if (defaultOpen && !isStreaming && isOpen && !hasAutoClosed) {
187
+ const timer = setTimeout(() => {
188
+ setIsOpen(false);
189
+ setHasAutoClosed(true);
190
+ }, AUTO_CLOSE_DELAY);
191
+ return () => clearTimeout(timer);
192
+ }
193
+ }, [
194
+ isStreaming,
195
+ isOpen,
196
+ defaultOpen,
197
+ setIsOpen,
198
+ hasAutoClosed
199
+ ]);
200
+ const handleOpenChange = (newOpen) => {
201
+ setIsOpen(newOpen);
202
+ };
203
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReasoningContext, {
204
+ value: {
205
+ isStreaming,
206
+ isOpen,
207
+ setIsOpen,
208
+ duration
209
+ },
210
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collapsible$1, {
211
+ className: cn("not-prose mb-4", className),
212
+ onOpenChange: handleOpenChange,
213
+ open: isOpen,
214
+ ...props,
215
+ children
216
+ })
217
+ });
218
+ });
219
+ var defaultGetThinkingMessage = (isStreaming, duration) => {
220
+ if (isStreaming || duration === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shimmer, {
221
+ duration: 1,
222
+ children: "Thinking..."
223
+ });
224
+ if (duration === void 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "Thought for a few seconds" });
225
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { children: [
226
+ "Thought for ",
227
+ duration,
228
+ " seconds"
229
+ ] });
230
+ };
231
+ var ReasoningTrigger = (0, import_react.memo)(({ className, children, getThinkingMessage = defaultGetThinkingMessage, ...props }) => {
232
+ const { isStreaming, isOpen, duration } = useReasoning();
233
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollapsibleTrigger, {
234
+ className: cn("flex w-full items-center gap-2 text-muted-foreground text-sm transition-colors hover:text-foreground", className),
235
+ ...props,
236
+ children: children ?? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
237
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Brain, { className: "size-4" }),
238
+ getThinkingMessage(isStreaming, duration),
239
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, { className: cn("size-4 transition-transform", isOpen ? "rotate-180" : "rotate-0") })
240
+ ] })
241
+ });
242
+ });
243
+ var ReasoningContent = (0, import_react.memo)(({ className, children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollapsibleContent, {
244
+ className: cn("mt-4 text-sm", "data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-muted-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in", className),
245
+ ...props,
246
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Us, {
247
+ plugins: {
248
+ code: A,
249
+ math: h
250
+ },
251
+ ...props,
252
+ children
253
+ })
254
+ }));
255
+ Reasoning.displayName = "Reasoning";
256
+ ReasoningTrigger.displayName = "ReasoningTrigger";
257
+ ReasoningContent.displayName = "ReasoningContent";
258
+ function ColorPlaceholder({ className, ...props }) {
259
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
260
+ className: cn("size-4 text-muted-foreground", className),
261
+ fill: "none",
262
+ viewBox: "0 0 24 24",
263
+ stroke: "currentColor",
264
+ ...props,
265
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
266
+ strokeLinecap: "round",
267
+ strokeLinejoin: "round",
268
+ strokeWidth: 1.5,
269
+ d: "M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"
270
+ })
271
+ });
272
+ }
273
+ function ThemeTool({ part, streamedData }) {
274
+ if (part.type !== "tool-generateTheme") return null;
275
+ const { theme } = z();
276
+ const { colorMode, currentTheme, setCurrentTheme } = useThemes();
277
+ const [isCopying, setIsCopying] = (0, import_react.useState)(false);
278
+ const isStreaming = part.state !== "output-available";
279
+ const styles = part.output || streamedData;
280
+ const isApplied = currentTheme?.id === styles?.id;
281
+ const shadcnTheme = styles?.[theme === "dark" ? "dark" : "light"];
282
+ function handleCopy() {
283
+ setIsCopying(true);
284
+ copyTextToClipboard(generateCode(styles));
285
+ setTimeout(() => setIsCopying(false), 3e3);
286
+ }
287
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Collapsible$1, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
288
+ className: "rounded-lg border bg-sidebar p-2 relative",
289
+ children: [
290
+ !!styles?.name && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(motion.p, {
291
+ initial: { y: 30 },
292
+ animate: { y: 0 },
293
+ transition: { duration: .5 },
294
+ className: "capitalize absolute text-xs -top-5 @sm/sidebar:left-4 left-2 -z-1 py-0.5 px-2 border bg-muted rounded-t-sm",
295
+ children: styles?.name
296
+ }),
297
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
298
+ className: "flex justify-between items-center",
299
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollapsibleTrigger, {
300
+ asChild: true,
301
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
302
+ variant: "ghost",
303
+ className: "flex @sm/sidebar:gap-2 gap-1 p-2!",
304
+ children: [previewColors.map((key) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
305
+ style: { backgroundColor: shadcnTheme?.[key] ?? "transparent" },
306
+ className: "rounded-md border size-5 flex items-center justify-center",
307
+ children: !shadcnTheme?.[key] && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
308
+ className: "size-full rounded-md bg-muted flex items-center justify-center",
309
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ColorPlaceholder, {})
310
+ })
311
+ }, key)), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, {
312
+ className: "transition-transform in-data-[state=\"open\"]:rotate-180",
313
+ size: 16
314
+ })]
315
+ })
316
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
317
+ className: "flex items-center gap-0.5",
318
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
319
+ className: clsx(isStreaming && "pointer-events-none"),
320
+ size: "sm",
321
+ variant: "ghost",
322
+ onClick: () => {
323
+ setCurrentTheme(styles);
324
+ },
325
+ disabled: isApplied,
326
+ children: isStreaming ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shimmer, { children: "Generating" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {})] }) : isApplied ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: ["Applied ", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MousePointerClick, {})] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: ["Apply ", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Play, {})] })
327
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
328
+ size: "icon-sm",
329
+ variant: "ghost",
330
+ disabled: isStreaming || isCopying,
331
+ onClick: handleCopy,
332
+ children: isCopying ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Check, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Copy, {})
333
+ })]
334
+ })]
335
+ }),
336
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollapsibleContent, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
337
+ className: "my-4 mx-2 space-y-4 max-h-52 overflow-y-auto",
338
+ children: Object.keys(colorSegments).map((key) => {
339
+ const displayedColors = colorSegments[key];
340
+ if (displayedColors.every((color) => !shadcnTheme?.[color])) return null;
341
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", {
342
+ className: "text-lg",
343
+ children: key
344
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
345
+ className: "flex flex-wrap gap-3",
346
+ children: displayedColors.map((themeKey) => {
347
+ const value = shadcnTheme?.[themeKey];
348
+ if (!value) return null;
349
+ const formattedValue = displayColor(value, colorMode);
350
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
351
+ className: "flex w-52 items-center gap-2 overflow-hidden text-ellipsis",
352
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
353
+ style: { backgroundColor: value },
354
+ className: "border-2 rounded-sm size-12 min-w-10"
355
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
356
+ className: "space-y-0.5",
357
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", {
358
+ className: "text-sm text-ellipsis",
359
+ children: formatColorName(themeKey)
360
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
361
+ className: "text-muted-foreground flex items-center gap-2",
362
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
363
+ className: "text-xs font-mono",
364
+ children: formattedValue
365
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Copy, {
366
+ size: 16,
367
+ onClick: () => copyTextToClipboard(formattedValue),
368
+ className: "hover:opacity-90 cursor-pointer"
369
+ })]
370
+ })]
371
+ })]
372
+ });
373
+ })
374
+ })] }, key);
375
+ })
376
+ }) })
377
+ ]
378
+ }) });
379
+ }
380
+ function ScrollArea$1({ className, children, ...props }) {
381
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Root$3, {
382
+ "data-slot": "scroll-area",
383
+ className: cn("relative", className),
384
+ ...props,
385
+ children: [
386
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Viewport$1, {
387
+ "data-slot": "scroll-area-viewport",
388
+ className: "size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1",
389
+ children
390
+ }),
391
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollBar, {}),
392
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Corner, {})
393
+ ]
394
+ });
395
+ }
396
+ function ScrollBar({ className, orientation = "vertical", ...props }) {
397
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollAreaScrollbar, {
398
+ "data-slot": "scroll-area-scrollbar",
399
+ "data-orientation": orientation,
400
+ orientation,
401
+ className: cn("data-horizontal:h-2.5 data-horizontal:flex-col data-horizontal:border-t data-horizontal:border-t-transparent data-vertical:h-full data-vertical:w-2.5 data-vertical:border-l data-vertical:border-l-transparent flex touch-none p-px transition-colors select-none", className),
402
+ ...props,
403
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollAreaThumb, {
404
+ "data-slot": "scroll-area-thumb",
405
+ className: "rounded-full relative flex-1 bg-border"
406
+ })
407
+ });
408
+ }
409
+ function Dialog$1({ ...props }) {
410
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Root$2, {
411
+ "data-slot": "dialog",
412
+ ...props
413
+ });
414
+ }
415
+ function DialogTrigger({ ...props }) {
416
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trigger$1, {
417
+ "data-slot": "dialog-trigger",
418
+ ...props
419
+ });
420
+ }
421
+ function DialogPortal({ ...props }) {
422
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Portal$1, {
423
+ "data-slot": "dialog-portal",
424
+ ...props
425
+ });
426
+ }
427
+ function DialogOverlay({ className, ...props }) {
428
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Overlay, {
429
+ "data-slot": "dialog-overlay",
430
+ className: cn("data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs fixed inset-0 isolate z-50", className),
431
+ ...props
432
+ });
433
+ }
434
+ function DialogContent({ className, children, showCloseButton = true, ...props }) {
435
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogPortal, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogOverlay, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Content, {
436
+ "data-slot": "dialog-content",
437
+ className: cn("bg-background data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 ring-foreground/10 grid max-w-[calc(100%-2rem)] gap-4 rounded-xl p-4 text-sm ring-1 duration-100 sm:max-w-sm fixed top-1/2 left-1/2 z-50 w-full -translate-x-1/2 -translate-y-1/2 outline-none", className),
438
+ ...props,
439
+ children: [children, showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Close, {
440
+ "data-slot": "dialog-close",
441
+ asChild: true,
442
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
443
+ variant: "ghost",
444
+ className: "absolute top-2 right-2",
445
+ size: "icon-sm",
446
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(X, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
447
+ className: "sr-only",
448
+ children: "Close"
449
+ })]
450
+ })
451
+ })]
452
+ })] });
453
+ }
454
+ function DialogTitle({ className, ...props }) {
455
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Title, {
456
+ "data-slot": "dialog-title",
457
+ className: cn("text-base leading-none font-medium", className),
458
+ ...props
459
+ });
460
+ }
461
+ function DialogDescription({ className, ...props }) {
462
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Description, {
463
+ "data-slot": "dialog-description",
464
+ className: cn("text-muted-foreground *:[a]:hover:text-foreground text-sm *:[a]:underline *:[a]:underline-offset-3", className),
465
+ ...props
466
+ });
467
+ }
468
+ function Textarea({ className, ...props }) {
469
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", {
470
+ "data-slot": "textarea",
471
+ className: cn("border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", className),
472
+ ...props
473
+ });
474
+ }
475
+ function InputGroup({ className, ...props }) {
476
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
477
+ "data-slot": "input-group",
478
+ role: "group",
479
+ className: cn("group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none", "h-9 min-w-0 has-[>textarea]:h-auto", "has-[>[data-align=inline-start]]:[&>input]:pl-2", "has-[>[data-align=inline-end]]:[&>input]:pr-2", "has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3", "has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3", "has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]", "has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40", className),
480
+ ...props
481
+ });
482
+ }
483
+ var inputGroupAddonVariants = cva("text-muted-foreground flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium select-none [&>svg:not([class*='size-'])]:size-4 [&>kbd]:rounded-[calc(var(--radius)-5px)] group-data-[disabled=true]/input-group:opacity-50", {
484
+ variants: { align: {
485
+ "inline-start": "order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]",
486
+ "inline-end": "order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]",
487
+ "block-start": "order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5",
488
+ "block-end": "order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5"
489
+ } },
490
+ defaultVariants: { align: "inline-start" }
491
+ });
492
+ function InputGroupAddon({ className, align = "inline-start", ...props }) {
493
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
494
+ role: "group",
495
+ "data-slot": "input-group-addon",
496
+ "data-align": align,
497
+ className: cn(inputGroupAddonVariants({ align }), className),
498
+ onClick: (e) => {
499
+ if (e.target.closest("button")) return;
500
+ e.currentTarget.parentElement?.querySelector("input")?.focus();
501
+ },
502
+ ...props
503
+ });
504
+ }
505
+ var inputGroupButtonVariants = cva("text-sm shadow-none flex gap-2 items-center", {
506
+ variants: { size: {
507
+ xs: "h-6 gap-1 px-2 rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 has-[>svg]:px-2",
508
+ sm: "h-8 px-2.5 gap-1.5 rounded-md has-[>svg]:px-2.5",
509
+ "icon-xs": "size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0",
510
+ "icon-sm": "size-8 p-0 has-[>svg]:p-0"
511
+ } },
512
+ defaultVariants: { size: "xs" }
513
+ });
514
+ function InputGroupButton({ className, type = "button", variant = "ghost", size = "xs", ...props }) {
515
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
516
+ type,
517
+ "data-size": size,
518
+ variant,
519
+ className: cn(inputGroupButtonVariants({ size }), className),
520
+ ...props
521
+ });
522
+ }
523
+ function InputGroupTextarea({ className, ...props }) {
524
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Textarea, {
525
+ "data-slot": "input-group-control",
526
+ className: cn("flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent", className),
527
+ ...props
528
+ });
529
+ }
530
+ function Select$1({ ...props }) {
531
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Root2, {
532
+ "data-slot": "select",
533
+ ...props
534
+ });
535
+ }
536
+ function SelectValue({ ...props }) {
537
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Value, {
538
+ "data-slot": "select-value",
539
+ ...props
540
+ });
541
+ }
542
+ function SelectTrigger({ className, size = "default", children, ...props }) {
543
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Trigger, {
544
+ "data-slot": "select-trigger",
545
+ "data-size": size,
546
+ className: cn("border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
547
+ ...props,
548
+ children: [children, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, {
549
+ asChild: true,
550
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, { className: "size-4 opacity-50" })
551
+ })]
552
+ });
553
+ }
554
+ function SelectContent({ className, children, position = "item-aligned", align = "center", ...props }) {
555
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Content2, {
556
+ "data-slot": "select-content",
557
+ className: cn("bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className),
558
+ position,
559
+ align,
560
+ ...props,
561
+ children: [
562
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectScrollUpButton, {}),
563
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Viewport, {
564
+ className: cn("p-1", position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"),
565
+ children
566
+ }),
567
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectScrollDownButton, {})
568
+ ]
569
+ }) });
570
+ }
571
+ function SelectItem({ className, children, ...props }) {
572
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Item, {
573
+ "data-slot": "select-item",
574
+ className: cn("focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className),
575
+ ...props,
576
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
577
+ "data-slot": "select-item-indicator",
578
+ className: "absolute right-2 flex size-3.5 items-center justify-center",
579
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Check, { className: "size-4" }) })
580
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ItemText, { children })]
581
+ });
582
+ }
583
+ function SelectScrollUpButton({ className, ...props }) {
584
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollUpButton, {
585
+ "data-slot": "select-scroll-up-button",
586
+ className: cn("flex cursor-default items-center justify-center py-1", className),
587
+ ...props,
588
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronUp, { className: "size-4" })
589
+ });
590
+ }
591
+ function SelectScrollDownButton({ className, ...props }) {
592
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollDownButton, {
593
+ "data-slot": "select-scroll-down-button",
594
+ className: cn("flex cursor-default items-center justify-center py-1", className),
595
+ ...props,
596
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, { className: "size-4" })
597
+ });
598
+ }
599
+ var PromptInputController = (0, import_react.createContext)(null);
600
+ var ProviderAttachmentsContext = (0, import_react.createContext)(null);
601
+ var useOptionalPromptInputController = () => (0, import_react.use)(PromptInputController);
602
+ var useOptionalProviderAttachments = () => (0, import_react.use)(ProviderAttachmentsContext);
603
+ var LocalAttachmentsContext = (0, import_react.createContext)(null);
604
+ var usePromptInputAttachments = () => {
605
+ const provider = useOptionalProviderAttachments();
606
+ const local = (0, import_react.use)(LocalAttachmentsContext);
607
+ const context = provider ?? local;
608
+ if (!context) throw new Error("usePromptInputAttachments must be used within a PromptInput or PromptInputProvider");
609
+ return context;
610
+ };
611
+ var PromptInput = ({ className, accept, multiple, globalDrop, syncHiddenInput, maxFiles, maxFileSize, onError, onSubmit, children, ...props }) => {
612
+ const controller = useOptionalPromptInputController();
613
+ const usingProvider = !!controller;
614
+ const inputRef = (0, import_react.useRef)(null);
615
+ const formRef = (0, import_react.useRef)(null);
616
+ const [items, setItems] = (0, import_react.useState)([]);
617
+ const files = usingProvider ? controller.attachments.files : items;
618
+ const filesRef = (0, import_react.useRef)(files);
619
+ filesRef.current = files;
620
+ const openFileDialogLocal = (0, import_react.useCallback)(() => {
621
+ inputRef.current?.click();
622
+ }, []);
623
+ const matchesAccept = (0, import_react.useCallback)((f) => {
624
+ if (!accept || accept.trim() === "") return true;
625
+ return accept.split(",").map((s) => s.trim()).filter(Boolean).some((pattern) => {
626
+ if (pattern.endsWith("/*")) {
627
+ const prefix = pattern.slice(0, -1);
628
+ return f.type.startsWith(prefix);
629
+ }
630
+ return f.type === pattern;
631
+ });
632
+ }, [accept]);
633
+ const addLocal = (0, import_react.useCallback)((fileList) => {
634
+ const incoming = Array.from(fileList);
635
+ const accepted = incoming.filter((f) => matchesAccept(f));
636
+ if (incoming.length && accepted.length === 0) {
637
+ onError?.({
638
+ code: "accept",
639
+ message: "No files match the accepted types."
640
+ });
641
+ return;
642
+ }
643
+ const withinSize = (f) => maxFileSize ? f.size <= maxFileSize : true;
644
+ const sized = accepted.filter(withinSize);
645
+ if (accepted.length > 0 && sized.length === 0) {
646
+ onError?.({
647
+ code: "max_file_size",
648
+ message: "All files exceed the maximum size."
649
+ });
650
+ return;
651
+ }
652
+ setItems((prev) => {
653
+ const capacity = typeof maxFiles === "number" ? Math.max(0, maxFiles - prev.length) : void 0;
654
+ const capped = typeof capacity === "number" ? sized.slice(0, capacity) : sized;
655
+ if (typeof capacity === "number" && sized.length > capacity) onError?.({
656
+ code: "max_files",
657
+ message: "Too many files. Some were not added."
658
+ });
659
+ const next = [];
660
+ for (const file of capped) next.push({
661
+ id: nanoid(),
662
+ type: "file",
663
+ url: URL.createObjectURL(file),
664
+ mediaType: file.type,
665
+ filename: file.name
666
+ });
667
+ return prev.concat(next);
668
+ });
669
+ }, [
670
+ matchesAccept,
671
+ maxFiles,
672
+ maxFileSize,
673
+ onError
674
+ ]);
675
+ const removeLocal = (0, import_react.useCallback)((id) => setItems((prev) => {
676
+ const found = prev.find((file) => file.id === id);
677
+ if (found?.url) URL.revokeObjectURL(found.url);
678
+ return prev.filter((file) => file.id !== id);
679
+ }), []);
680
+ const clearLocal = (0, import_react.useCallback)(() => setItems((prev) => {
681
+ for (const file of prev) if (file.url) URL.revokeObjectURL(file.url);
682
+ return [];
683
+ }), []);
684
+ const add = usingProvider ? controller.attachments.add : addLocal;
685
+ const remove = usingProvider ? controller.attachments.remove : removeLocal;
686
+ const clear = usingProvider ? controller.attachments.clear : clearLocal;
687
+ const openFileDialog = usingProvider ? controller.attachments.openFileDialog : openFileDialogLocal;
688
+ (0, import_react.useEffect)(() => {
689
+ if (!usingProvider) return;
690
+ controller.__registerFileInput(inputRef, () => inputRef.current?.click());
691
+ }, [usingProvider, controller]);
692
+ (0, import_react.useEffect)(() => {
693
+ if (syncHiddenInput && inputRef.current && files.length === 0) inputRef.current.value = "";
694
+ }, [files, syncHiddenInput]);
695
+ (0, import_react.useEffect)(() => {
696
+ const form = formRef.current;
697
+ if (!form) return;
698
+ if (globalDrop) return;
699
+ const onDragOver = (e) => {
700
+ if (e.dataTransfer?.types?.includes("Files")) e.preventDefault();
701
+ };
702
+ const onDrop = (e) => {
703
+ if (e.dataTransfer?.types?.includes("Files")) e.preventDefault();
704
+ if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) add(e.dataTransfer.files);
705
+ };
706
+ form.addEventListener("dragover", onDragOver);
707
+ form.addEventListener("drop", onDrop);
708
+ return () => {
709
+ form.removeEventListener("dragover", onDragOver);
710
+ form.removeEventListener("drop", onDrop);
711
+ };
712
+ }, [add, globalDrop]);
713
+ (0, import_react.useEffect)(() => {
714
+ if (!globalDrop) return;
715
+ const onDragOver = (e) => {
716
+ if (e.dataTransfer?.types?.includes("Files")) e.preventDefault();
717
+ };
718
+ const onDrop = (e) => {
719
+ if (e.dataTransfer?.types?.includes("Files")) e.preventDefault();
720
+ if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) add(e.dataTransfer.files);
721
+ };
722
+ document.addEventListener("dragover", onDragOver);
723
+ document.addEventListener("drop", onDrop);
724
+ return () => {
725
+ document.removeEventListener("dragover", onDragOver);
726
+ document.removeEventListener("drop", onDrop);
727
+ };
728
+ }, [add, globalDrop]);
729
+ (0, import_react.useEffect)(() => () => {
730
+ if (!usingProvider) {
731
+ for (const f of filesRef.current) if (f.url) URL.revokeObjectURL(f.url);
732
+ }
733
+ }, [usingProvider]);
734
+ const handleChange = (event) => {
735
+ if (event.currentTarget.files) add(event.currentTarget.files);
736
+ event.currentTarget.value = "";
737
+ };
738
+ const convertBlobUrlToDataUrl = async (url) => {
739
+ try {
740
+ const blob = await (await fetch(url)).blob();
741
+ return new Promise((resolve) => {
742
+ const reader = new FileReader();
743
+ reader.onloadend = () => resolve(reader.result);
744
+ reader.onerror = () => resolve(null);
745
+ reader.readAsDataURL(blob);
746
+ });
747
+ } catch {
748
+ return null;
749
+ }
750
+ };
751
+ const ctx = (0, import_react.useMemo)(() => ({
752
+ files: files.map((item) => ({
753
+ ...item,
754
+ id: item.id
755
+ })),
756
+ add,
757
+ remove,
758
+ clear,
759
+ openFileDialog,
760
+ fileInputRef: inputRef
761
+ }), [
762
+ files,
763
+ add,
764
+ remove,
765
+ clear,
766
+ openFileDialog
767
+ ]);
768
+ const handleSubmit = (event) => {
769
+ event.preventDefault();
770
+ const form = event.currentTarget;
771
+ const text = usingProvider ? controller.textInput.value : new FormData(form).get("message") || "";
772
+ if (!usingProvider) form.reset();
773
+ Promise.all(files.map(async ({ id, ...item }) => {
774
+ if (item.url && item.url.startsWith("blob:")) {
775
+ const dataUrl = await convertBlobUrlToDataUrl(item.url);
776
+ return {
777
+ ...item,
778
+ url: dataUrl ?? item.url
779
+ };
780
+ }
781
+ return item;
782
+ })).then((convertedFiles) => {
783
+ try {
784
+ const result = onSubmit({
785
+ text,
786
+ files: convertedFiles
787
+ }, event);
788
+ if (result instanceof Promise) result.then(() => {
789
+ clear();
790
+ if (usingProvider) controller.textInput.clear();
791
+ }).catch(() => {});
792
+ else {
793
+ clear();
794
+ if (usingProvider) controller.textInput.clear();
795
+ }
796
+ } catch {}
797
+ }).catch(() => {});
798
+ };
799
+ const inner = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", {
800
+ accept,
801
+ "aria-label": "Upload files",
802
+ className: "hidden",
803
+ multiple,
804
+ onChange: handleChange,
805
+ ref: inputRef,
806
+ title: "Upload files",
807
+ type: "file"
808
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("form", {
809
+ className: cn("w-full", className),
810
+ onSubmit: handleSubmit,
811
+ ref: formRef,
812
+ ...props,
813
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InputGroup, {
814
+ className: "overflow-hidden",
815
+ children
816
+ })
817
+ })] });
818
+ return usingProvider ? inner : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LocalAttachmentsContext, {
819
+ value: ctx,
820
+ children: inner
821
+ });
822
+ };
823
+ var PromptInputTextarea = ({ onChange, className, placeholder = "What would you like to know?", ...props }) => {
824
+ const controller = useOptionalPromptInputController();
825
+ const attachments = usePromptInputAttachments();
826
+ const [isComposing, setIsComposing] = (0, import_react.useState)(false);
827
+ const handleKeyDown = (e) => {
828
+ if (e.key === "Enter") {
829
+ if (isComposing || e.nativeEvent.isComposing) return;
830
+ if (e.shiftKey) return;
831
+ e.preventDefault();
832
+ const form = e.currentTarget.form;
833
+ if ((form?.querySelector("button[type=\"submit\"]"))?.disabled) return;
834
+ form?.requestSubmit();
835
+ }
836
+ if (e.key === "Backspace" && e.currentTarget.value === "" && attachments.files.length > 0) {
837
+ e.preventDefault();
838
+ const lastAttachment = attachments.files.at(-1);
839
+ if (lastAttachment) attachments.remove(lastAttachment.id);
840
+ }
841
+ };
842
+ const handlePaste = (event) => {
843
+ const items = event.clipboardData?.items;
844
+ if (!items) return;
845
+ const files = [];
846
+ for (const item of items) if (item.kind === "file") {
847
+ const file = item.getAsFile();
848
+ if (file) files.push(file);
849
+ }
850
+ if (files.length > 0) {
851
+ event.preventDefault();
852
+ attachments.add(files);
853
+ }
854
+ };
855
+ const controlledProps = controller ? {
856
+ value: controller.textInput.value,
857
+ onChange: (e) => {
858
+ controller.textInput.setInput(e.currentTarget.value);
859
+ onChange?.(e);
860
+ }
861
+ } : { onChange };
862
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InputGroupTextarea, {
863
+ className: cn("field-sizing-content max-h-48 min-h-16", className),
864
+ name: "message",
865
+ onCompositionEnd: () => setIsComposing(false),
866
+ onCompositionStart: () => setIsComposing(true),
867
+ onKeyDown: handleKeyDown,
868
+ onPaste: handlePaste,
869
+ placeholder,
870
+ ...props,
871
+ ...controlledProps
872
+ });
873
+ };
874
+ var PromptInputFooter = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InputGroupAddon, {
875
+ align: "block-end",
876
+ className: cn("justify-between gap-1", className),
877
+ ...props
878
+ });
879
+ var PromptInputSubmit = ({ className, variant = "default", size = "icon-sm", status, children, ...props }) => {
880
+ let Icon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CornerDownLeft, { className: "size-4" });
881
+ if (status === "submitted") Icon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoaderCircle, { className: "size-4 animate-spin" });
882
+ else if (status === "streaming") Icon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Square, { className: "size-4" });
883
+ else if (status === "error") Icon = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(X, { className: "size-4" });
884
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InputGroupButton, {
885
+ "aria-label": "Submit",
886
+ className: cn(className),
887
+ size,
888
+ type: "submit",
889
+ variant,
890
+ ...props,
891
+ children: children ?? Icon
892
+ });
893
+ };
894
+ var Conversation = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StickToBottom, {
895
+ className: cn("relative flex-1 overflow-y-hidden", className),
896
+ initial: "smooth",
897
+ resize: "smooth",
898
+ role: "log",
899
+ ...props
900
+ });
901
+ var ConversationContent = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StickToBottom.Content, {
902
+ className: cn("flex flex-col gap-8 p-4", className),
903
+ ...props
904
+ });
905
+ var ConversationScrollButton = ({ className, ...props }) => {
906
+ const { isAtBottom, scrollToBottom } = useStickToBottomContext();
907
+ const handleScrollToBottom = (0, import_react.useCallback)(() => {
908
+ scrollToBottom();
909
+ }, [scrollToBottom]);
910
+ return !isAtBottom && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
911
+ className: cn("absolute bottom-4 left-[50%] translate-x-[-50%] rounded-full", className),
912
+ onClick: handleScrollToBottom,
913
+ size: "icon",
914
+ type: "button",
915
+ variant: "outline",
916
+ ...props,
917
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArrowDown, { className: "size-4" })
918
+ });
919
+ };
920
+ cva("flex w-fit items-stretch [&>*]:focus-visible:z-10 [&>*]:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2", {
921
+ variants: { orientation: {
922
+ horizontal: "[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none",
923
+ vertical: "flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none"
924
+ } },
925
+ defaultVariants: { orientation: "horizontal" }
926
+ });
927
+ function TooltipProvider({ delayDuration = 0, ...props }) {
928
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Provider, {
929
+ "data-slot": "tooltip-provider",
930
+ delayDuration,
931
+ ...props
932
+ });
933
+ }
934
+ function Tooltip$1({ ...props }) {
935
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Root3$1, {
936
+ "data-slot": "tooltip",
937
+ ...props
938
+ });
939
+ }
940
+ function TooltipTrigger({ ...props }) {
941
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trigger$5, {
942
+ "data-slot": "tooltip-trigger",
943
+ ...props
944
+ });
945
+ }
946
+ function TooltipContent({ className, sideOffset = 0, children, ...props }) {
947
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Portal$3, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Content2$3, {
948
+ "data-slot": "tooltip-content",
949
+ sideOffset,
950
+ className: cn("data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs has-data-[slot=kbd]:pr-1.5 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm z-50 w-fit max-w-xs origin-(--radix-tooltip-content-transform-origin) bg-foreground text-background", className),
951
+ ...props,
952
+ children: [children, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Arrow2, { className: "size-2.5 rotate-45 rounded-[2px] z-50 translate-y-[calc(-50%_-_2px)] bg-foreground fill-foreground" })]
953
+ }) });
954
+ }
955
+ var Message = ({ className, from, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
956
+ className: cn("group flex w-full max-w-[95%] flex-col gap-2", from === "user" ? "is-user ml-auto justify-end" : "is-assistant", className),
957
+ ...props
958
+ });
959
+ var MessageContent = ({ children, className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
960
+ className: cn("is-user:dark flex w-fit max-w-full min-w-0 flex-col gap-2 overflow-hidden text-sm", "group-[.is-user]:ml-auto group-[.is-user]:rounded-lg group-[.is-user]:bg-secondary group-[.is-user]:px-4 group-[.is-user]:py-3 group-[.is-user]:text-foreground", "group-[.is-assistant]:text-foreground", className),
961
+ ...props,
962
+ children
963
+ });
964
+ var MessageActions = ({ className, children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
965
+ className: cn("flex items-center gap-1", className),
966
+ ...props,
967
+ children
968
+ });
969
+ var MessageAction = ({ tooltip, children, label, variant = "ghost", size = "icon-sm", ...props }) => {
970
+ const button = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
971
+ size,
972
+ type: "button",
973
+ variant,
974
+ ...props,
975
+ children: [children, /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
976
+ className: "sr-only",
977
+ children: label || tooltip
978
+ })]
979
+ });
980
+ if (tooltip) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Tooltip$1, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TooltipTrigger, {
981
+ asChild: true,
982
+ children: button
983
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TooltipContent, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: tooltip }) })] }) });
984
+ return button;
985
+ };
986
+ (0, import_react.createContext)(null);
987
+ var MessageResponse = (0, import_react.memo)(({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Us, {
988
+ className: cn("size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", className),
989
+ ...props
990
+ }), (prevProps, nextProps) => prevProps.children === nextProps.children);
991
+ MessageResponse.displayName = "MessageResponse";
992
+ var generateSuggestions = createServerFn({ method: "POST" }).inputValidator(zodValidator(object({
993
+ shadcn: shadcnStylesSchema,
994
+ provider: _enum(providers),
995
+ model: string()
996
+ }))).handler(createSsrRpc("74c0f93931f897f2d57d57ff71eece1b1d31f77b934ce83ff1dcab0015ddfee6"));
997
+ function Menubar$1({ className, ...props }) {
998
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Root3, {
999
+ "data-slot": "menubar",
1000
+ className: cn("flex h-9 items-center gap-1 rounded-md border bg-background p-1 shadow-xs", className),
1001
+ ...props
1002
+ });
1003
+ }
1004
+ function MenubarMenu({ ...props }) {
1005
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu, {
1006
+ "data-slot": "menubar-menu",
1007
+ ...props
1008
+ });
1009
+ }
1010
+ function MenubarPortal({ ...props }) {
1011
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Portal2, {
1012
+ "data-slot": "menubar-portal",
1013
+ ...props
1014
+ });
1015
+ }
1016
+ function MenubarTrigger({ className, ...props }) {
1017
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trigger$2, {
1018
+ "data-slot": "menubar-trigger",
1019
+ className: cn("flex items-center rounded-sm px-2 py-1 text-sm font-medium outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground", className),
1020
+ ...props
1021
+ });
1022
+ }
1023
+ function MenubarContent({ className, align = "start", alignOffset = -4, sideOffset = 8, ...props }) {
1024
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenubarPortal, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Content2$1, {
1025
+ "data-slot": "menubar-content",
1026
+ align,
1027
+ alignOffset,
1028
+ sideOffset,
1029
+ className: cn("z-50 min-w-[12rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95", className),
1030
+ ...props
1031
+ }) });
1032
+ }
1033
+ function MenubarItem({ className, inset, variant = "default", ...props }) {
1034
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Item3, {
1035
+ "data-slot": "menubar-item",
1036
+ "data-inset": inset,
1037
+ "data-variant": variant,
1038
+ className: cn("relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-[variant=destructive]:*:[svg]:text-destructive!", className),
1039
+ ...props
1040
+ });
1041
+ }
1042
+ function MenubarShortcut({ className, ...props }) {
1043
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1044
+ "data-slot": "menubar-shortcut",
1045
+ className: cn("ml-auto text-xs tracking-widest text-muted-foreground", className),
1046
+ ...props
1047
+ });
1048
+ }
1049
+ function MenubarSub({ ...props }) {
1050
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Sub2, {
1051
+ "data-slot": "menubar-sub",
1052
+ ...props
1053
+ });
1054
+ }
1055
+ function MenubarSubTrigger({ className, inset, children, ...props }) {
1056
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SubTrigger2, {
1057
+ "data-slot": "menubar-sub-trigger",
1058
+ "data-inset": inset,
1059
+ className: cn("flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none focus:bg-accent focus:text-accent-foreground data-[inset]:pl-8 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground", className),
1060
+ ...props,
1061
+ children: [children, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronRight, { className: "ml-auto h-4 w-4" })]
1062
+ });
1063
+ }
1064
+ function MenubarSubContent({ className, ...props }) {
1065
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SubContent2, {
1066
+ "data-slot": "menubar-sub-content",
1067
+ className: cn("z-50 min-w-[8rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95", className),
1068
+ ...props
1069
+ });
1070
+ }
1071
+ var submitApiKey = createServerFn().inputValidator(zodValidator(object({
1072
+ provider: _enum(providers),
1073
+ apiKey: string()
1074
+ }))).handler(createSsrRpc("834a951965bf50d49d9a1f848390ddb1ddef4f162422cf43f1e7fd82726bbe90"));
1075
+ var PROVIDER_ICONS = {
1076
+ chatgpt: Icons,
1077
+ claude: Icons$1,
1078
+ gemini: Icons$2,
1079
+ glm: Icons$3,
1080
+ kimi: Icons$4
1081
+ };
1082
+ function ProviderPicker() {
1083
+ const [tokenDialogState, setTokenDialogState] = (0, import_react.useState)();
1084
+ const { providers: providersState, updateProvider, selectedModel, setSelectedModel } = useProviders();
1085
+ const { mutate: submitKey, isPending, isError, error } = useMutation({
1086
+ mutationKey: ["submitApiKey", tokenDialogState],
1087
+ mutationFn: async (apiKey) => {
1088
+ if (!tokenDialogState) return;
1089
+ const { models } = await submitApiKey({ data: {
1090
+ apiKey,
1091
+ provider: tokenDialogState
1092
+ } });
1093
+ updateProvider(tokenDialogState, {
1094
+ isActive: true,
1095
+ models
1096
+ });
1097
+ setTokenDialogState(void 0);
1098
+ toast(`API key for ${providerDisplay[tokenDialogState]} saved.`);
1099
+ },
1100
+ retry: 1
1101
+ });
1102
+ const selectedModelInfo = (0, import_react.useMemo)(() => {
1103
+ const providerList = Object.keys(providersState);
1104
+ if (!providerList.length) return;
1105
+ for (const provider of providerList) {
1106
+ const providerState = providersState[provider];
1107
+ if (providerState.isActive) {
1108
+ const foundModel = providerState.models.find((model) => model.id === selectedModel);
1109
+ if (foundModel) return foundModel;
1110
+ }
1111
+ }
1112
+ }, [providersState]);
1113
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Dialog$1, {
1114
+ open: !!tokenDialogState,
1115
+ onOpenChange: (open) => setTokenDialogState((prev) => open ? prev : void 0),
1116
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogContent, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogTitle, { children: ["Setup ", providerDisplay[tokenDialogState]] }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", {
1117
+ onSubmit: (event) => {
1118
+ event.preventDefault();
1119
+ submitKey(new FormData(event.target).get("apiKey"));
1120
+ },
1121
+ className: "size-full space-y-2",
1122
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Field, {
1123
+ "data-invalid": isError,
1124
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
1125
+ id: "apiKey",
1126
+ name: "apiKey",
1127
+ type: "password",
1128
+ placeholder: "API key",
1129
+ "aria-invalid": isError,
1130
+ disabled: isPending,
1131
+ required: true
1132
+ }), isError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldError, { children: error.message })]
1133
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
1134
+ type: "submit",
1135
+ className: "w-full",
1136
+ disabled: isPending,
1137
+ children: "Submit"
1138
+ })]
1139
+ })] })
1140
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menubar$1, {
1141
+ asChild: true,
1142
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(MenubarMenu, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenubarTrigger, {
1143
+ asChild: true,
1144
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
1145
+ variant: "ghost",
1146
+ size: "sm",
1147
+ className: "flex items-center gap-x-1",
1148
+ children: [selectedModelInfo ? selectedModelInfo.name : "Select model", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronUp, { size: 16 })]
1149
+ })
1150
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenubarContent, { children: providers.map((provider) => {
1151
+ const Icon = PROVIDER_ICONS[provider];
1152
+ const displayName = providerDisplay[provider];
1153
+ const providerState = providersState?.[provider];
1154
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(MenubarSub, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(MenubarSubTrigger, {
1155
+ className: "capitalize space-x-1",
1156
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, {}), displayName]
1157
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenubarSubContent, { children: providerState?.isActive ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [[...providerState.models].reverse().map((model, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(MenubarItem, {
1158
+ onClick: () => setSelectedModel(model.id, provider),
1159
+ children: [model.name, model.id === selectedModel && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenubarShortcut, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Check, { size: 16 }) })]
1160
+ }, index)), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(MenubarItem, {
1161
+ onClick: () => setTokenDialogState(provider),
1162
+ children: [
1163
+ "Edit ",
1164
+ displayName,
1165
+ " ",
1166
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenubarShortcut, { children: "API KEY" })
1167
+ ]
1168
+ })] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(MenubarItem, {
1169
+ onClick: () => setTokenDialogState(provider),
1170
+ children: [
1171
+ "Setup ",
1172
+ displayName,
1173
+ " ",
1174
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MenubarShortcut, { children: "API KEY" })
1175
+ ]
1176
+ }) })] }, provider);
1177
+ }) })] })
1178
+ })] });
1179
+ }
1180
+ var suggestions = [
1181
+ "Minimalist, high-contrast monochrome",
1182
+ "Midnight executive, deep indigo with soft muted accents",
1183
+ "Autumn forest with browns and burnt orange accents",
1184
+ "Electric lime greens against a dark slate background"
1185
+ ];
1186
+ var Chat = ({ ref }) => {
1187
+ const { selectedModel, selectedProvider } = useProviders();
1188
+ const { currentTheme, setCurrentTheme, appendThemes, setIsGenerating } = useThemes();
1189
+ const [input, setInput] = (0, import_react.useState)("");
1190
+ const [aiSuggestions, setAiSuggestions] = (0, import_react.useState)();
1191
+ const [streamedData, setStreamedData] = (0, import_react.useState)();
1192
+ const getSuggestions = useServerFn(generateSuggestions);
1193
+ const { messages, sendMessage, status, regenerate, setMessages } = useChat({
1194
+ transport: new DefaultChatTransport({
1195
+ prepareSendMessagesRequest(req) {
1196
+ setAiSuggestions([]);
1197
+ return { body: {
1198
+ id: req.id,
1199
+ messages: req.messages,
1200
+ provider: selectedProvider,
1201
+ model: selectedModel,
1202
+ ...req.body
1203
+ } };
1204
+ },
1205
+ api: "/api/chat"
1206
+ }),
1207
+ onData: (dataPart) => {
1208
+ if (dataPart.type === "data-theme") {
1209
+ if (dataPart.data.styles.id?.length === 16) {
1210
+ appendThemes(dataPart.data.styles);
1211
+ setCurrentTheme(dataPart.data.styles);
1212
+ setStreamedData(dataPart.data.styles);
1213
+ }
1214
+ }
1215
+ },
1216
+ onFinish() {
1217
+ if (!selectedProvider || !selectedModel) return;
1218
+ getSuggestions({ data: {
1219
+ shadcn: currentTheme || streamedData,
1220
+ provider: selectedProvider,
1221
+ model: selectedModel
1222
+ } }).then(setAiSuggestions);
1223
+ setStreamedData(void 0);
1224
+ }
1225
+ });
1226
+ const handleSubmit = (message, e) => {
1227
+ e.preventDefault();
1228
+ if (message.text.trim()) {
1229
+ sendMessage({ text: message.text });
1230
+ setInput("");
1231
+ }
1232
+ };
1233
+ (0, import_react.useImperativeHandle)(ref, () => ({ resetChat: () => setMessages([]) }));
1234
+ (0, import_react.useEffect)(() => {
1235
+ if ((messages.at(-1)?.parts.at(-1))?.type === "data-theme" && streamedData?.id) {
1236
+ appendThemes(streamedData);
1237
+ setCurrentTheme(streamedData, false);
1238
+ setStreamedData(void 0);
1239
+ }
1240
+ }, [messages]);
1241
+ (0, import_react.useEffect)(() => {
1242
+ setIsGenerating(!!streamedData);
1243
+ }, [streamedData]);
1244
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1245
+ className: "mx-auto relative flex flex-col justify-end size-full p-4",
1246
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1247
+ className: "flex flex-col size-full",
1248
+ children: [
1249
+ !messages.length && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(motion.div, {
1250
+ className: "flex flex-col justify-center sm:mx-8 gap-y-4 flex-1",
1251
+ initial: { opacity: 0 },
1252
+ animate: { opacity: 1 },
1253
+ transition: { duration: .5 },
1254
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1255
+ className: "flex items-center gap-2 ml-4",
1256
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SvgLogo, { className: "size-6 text-primary" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
1257
+ className: "font-medium",
1258
+ children: "What's on your mind?"
1259
+ })]
1260
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1261
+ className: "flex flex-col gap-y-1",
1262
+ children: suggestions?.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
1263
+ className: "p-2 text-left opacity-90 hover:text-primary cursor-pointer border-b",
1264
+ onClick: () => sendMessage({ text: suggestion }),
1265
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
1266
+ className: "text-xs",
1267
+ children: suggestion
1268
+ })
1269
+ }, index))
1270
+ })]
1271
+ }),
1272
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Conversation, {
1273
+ className: "flex-1 h-full min-h-0",
1274
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConversationContent, { children: messages.map((message, messageIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Fragment, { children: message.parts.map((part, i) => {
1275
+ const isLastMessage = messageIndex === messages.length - 1;
1276
+ switch (part.type) {
1277
+ case "reasoning": return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Reasoning, {
1278
+ className: "w-full",
1279
+ isStreaming: status === "streaming" && i === message.parts.length - 1 && message.id === messages.at(-1)?.id,
1280
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReasoningTrigger, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReasoningContent, { children: part.text })]
1281
+ }, `r-${message.id}-${i}`);
1282
+ case "text":
1283
+ if (!part.text.trim()) return null;
1284
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Message, {
1285
+ from: message.role,
1286
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MessageContent, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MessageResponse, { children: part.text }) })
1287
+ }), message.role === "assistant" && isLastMessage && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(MessageActions, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MessageAction, {
1288
+ onClick: () => regenerate(),
1289
+ label: "Retry",
1290
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RefreshCcw, { className: "size-3" })
1291
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MessageAction, {
1292
+ onClick: () => copyTextToClipboard(part.text),
1293
+ label: "Copy",
1294
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Copy, { className: "size-3" })
1295
+ })] })] }, `${message.id}-${i}`);
1296
+ case "tool-generateTheme": return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeTool, {
1297
+ streamedData,
1298
+ part
1299
+ }, `${message.id}-${i}`);
1300
+ default: return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Fragment, {}, `${message.id}-${i}`);
1301
+ }
1302
+ }) }, message.id)) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConversationScrollButton, {})]
1303
+ }),
1304
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollArea$1, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1305
+ className: "flex flex-wrap gap-2",
1306
+ children: aiSuggestions?.map((suggestion, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
1307
+ variant: "outline",
1308
+ className: "rounded-full cursor-pointer dark:bg-input dark:backdrop-blur-xl text-xs h-auto py-1 px-3",
1309
+ onClick: () => sendMessage({ text: suggestion }),
1310
+ children: suggestion
1311
+ }, index))
1312
+ }) }),
1313
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(PromptInput, {
1314
+ multiple: true,
1315
+ globalDrop: true,
1316
+ className: "mt-4 w-full mx-auto relative flex-col",
1317
+ onSubmit: handleSubmit,
1318
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PromptInputTextarea, {
1319
+ value: input,
1320
+ placeholder: "Say something...",
1321
+ onChange: (e) => setInput(e.currentTarget.value),
1322
+ className: "pr-12"
1323
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(PromptInputFooter, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProviderPicker, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PromptInputSubmit, {
1324
+ status: status === "streaming" ? "streaming" : "ready",
1325
+ disabled: !input.trim() || !selectedModel || !selectedProvider
1326
+ })] })]
1327
+ })
1328
+ ]
1329
+ })
1330
+ });
1331
+ };
1332
+ function Switch$1({ className, size = "default", ...props }) {
1333
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Root$4, {
1334
+ "data-slot": "switch",
1335
+ "data-size": size,
1336
+ className: cn("data-checked:bg-primary data-unchecked:bg-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 dark:data-unchecked:bg-input/80 shrink-0 rounded-full border border-transparent focus-visible:ring-3 aria-invalid:ring-3 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] peer group/switch relative inline-flex items-center transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 data-disabled:cursor-not-allowed data-disabled:opacity-50", className),
1337
+ ...props,
1338
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Thumb$1, {
1339
+ "data-slot": "switch-thumb",
1340
+ className: "bg-background dark:data-unchecked:bg-foreground dark:data-checked:bg-primary-foreground rounded-full group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 pointer-events-none block ring-0 transition-transform"
1341
+ })
1342
+ });
1343
+ }
1344
+ var ThemeSwitch = ({ className, ...props }) => {
1345
+ const { resolvedTheme, setTheme } = z();
1346
+ const setCurrentTheme = useThemes((state) => state.setCurrentTheme);
1347
+ const [checked, setChecked] = (0, import_react.useState)(false);
1348
+ const [mounted, setMounted] = (0, import_react.useState)(false);
1349
+ (0, import_react.useEffect)(() => setMounted(true), []);
1350
+ (0, import_react.useEffect)(() => setChecked(resolvedTheme === "dark"), [resolvedTheme]);
1351
+ const handleCheckedChange = (0, import_react.useCallback)((isChecked) => {
1352
+ const newTheme = isChecked ? "dark" : "light";
1353
+ setChecked(isChecked);
1354
+ setTheme(newTheme);
1355
+ setCurrentTheme(useThemes.getState().currentTheme, true, newTheme);
1356
+ }, [setTheme]);
1357
+ if (!mounted) return null;
1358
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1359
+ className: cn("relative flex items-center justify-center", "h-7 w-14", className),
1360
+ ...props,
1361
+ children: [
1362
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Switch$1, {
1363
+ checked,
1364
+ onCheckedChange: handleCheckedChange,
1365
+ className: clsx("peer absolute inset-0 size-full min-w-14 min-h-7 rounded-full bg-input! transition-colors", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", "[&>span]:size-5! [&>span]:rounded-full [&>span]:bg-background [&>span]:shadow [&>span]:z-10", "data-[state=unchecked]:[&>span]:translate-x-1.5", "data-[state=checked]:[&>span]:translate-x-[28px]")
1366
+ }),
1367
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1368
+ className: cn("pointer-events-none absolute left-2 inset-y-0 z-0", "flex items-center justify-center"),
1369
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Sun, {
1370
+ size: 16,
1371
+ className: cn("transition-all duration-200 ease-out", checked ? "text-muted-foreground/70" : "text-foreground scale-110")
1372
+ })
1373
+ }),
1374
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1375
+ className: cn("pointer-events-none absolute right-2 inset-y-0 z-0", "flex items-center justify-center"),
1376
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Moon, {
1377
+ size: 16,
1378
+ className: cn("transition-all duration-200 ease-out", checked ? "text-foreground scale-110" : "text-muted-foreground/70")
1379
+ })
1380
+ })
1381
+ ]
1382
+ });
1383
+ };
1384
+ function CopyCode(props) {
1385
+ const { currentTheme, isGenerating } = useThemes();
1386
+ const [isCopying, setIsCopying] = (0, import_react.useState)(false);
1387
+ function copyCode() {
1388
+ const code = generateCode(currentTheme);
1389
+ setIsCopying(true);
1390
+ copyTextToClipboard(code);
1391
+ setTimeout(() => setIsCopying(false), 3e3);
1392
+ }
1393
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
1394
+ size: "sm",
1395
+ variant: "secondary",
1396
+ onClick: copyCode,
1397
+ disabled: isGenerating,
1398
+ ...props,
1399
+ children: ["Copy code", isCopying ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Check, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Copy, {})]
1400
+ });
1401
+ }
1402
+ function CodePreview() {
1403
+ const { theme } = z();
1404
+ const { currentTheme, colorMode, setColorMode } = useThemes();
1405
+ const [html, setHtml] = (0, import_react.useState)("");
1406
+ (0, import_react.useEffect)(() => {
1407
+ if (!currentTheme) return;
1408
+ const code = generateCode(currentTheme);
1409
+ const initShiki = async () => {
1410
+ const highlighter = await createHighlighterCore({
1411
+ themes: [vitesse_black_default, vitesse_light_default],
1412
+ langs: [css_default],
1413
+ engine: createJavaScriptRegexEngine()
1414
+ });
1415
+ setHtml(highlighter.codeToHtml(code, {
1416
+ lang: "css",
1417
+ theme: theme === "dark" ? "vitesse-black" : "vitesse-light"
1418
+ }));
1419
+ highlighter.dispose();
1420
+ };
1421
+ initShiki();
1422
+ }, [
1423
+ currentTheme,
1424
+ theme,
1425
+ colorMode
1426
+ ]);
1427
+ if (!currentTheme) return null;
1428
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ScrollArea$1, {
1429
+ className: "size-full relative pb-6",
1430
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1431
+ className: "sticky top-2 w-full flex items-center gap-2 justify-end z-10 pr-4",
1432
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Select$1, {
1433
+ value: colorMode,
1434
+ onValueChange: setColorMode,
1435
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectTrigger, {
1436
+ className: "uppercase backdrop-blur-md",
1437
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectValue, {})
1438
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectContent, { children: [
1439
+ "oklch",
1440
+ "hex",
1441
+ "rgb",
1442
+ "hsl"
1443
+ ].map((colorMode) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItem, {
1444
+ value: colorMode,
1445
+ className: "uppercase",
1446
+ children: colorMode
1447
+ }, colorMode)) })]
1448
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CopyCode, { size: "default" })]
1449
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1450
+ className: "w-full sm:pb-20 mt-4 text-[13px] [&>pre]:px-4 [&>pre]:py-4 **:bg-transparent! [&>pre]:whitespace-pre-wrap [&>pre]:break-words",
1451
+ dangerouslySetInnerHTML: { __html: html }
1452
+ })]
1453
+ });
1454
+ }
1455
+ var GhostTabsTrigger = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsTrigger, {
1456
+ className: clsx("p-2! border-none hover:text-foreground! data-[state=\"active\"]:bg-muted! shadow-none!", className),
1457
+ ...props
1458
+ });
1459
+ var ParticleAnimation = ({ className, particleCount = 500, colors = [
1460
+ "#00b8a9",
1461
+ "#f8f3d4",
1462
+ "#f6416c",
1463
+ "#ffde7d"
1464
+ ], animationDuration = [1, 2], perspective = "10vmin", particleWidth = "30%", particleHeight = "1px" }) => {
1465
+ const [particles, setParticles] = (0, import_react.useState)([]);
1466
+ const random = (min, max) => Math.random() * (max - min) + min;
1467
+ const randomColor = () => colors[Math.floor(Math.random() * colors.length)];
1468
+ const randomRotation = () => random(-180, 180);
1469
+ (0, import_react.useEffect)(() => {
1470
+ setParticles(Array.from({ length: particleCount }, (_, i) => ({
1471
+ id: i,
1472
+ duration: random(animationDuration[0], animationDuration[1]),
1473
+ delay: -random(.1, 2),
1474
+ rotateX: randomRotation(),
1475
+ rotateY: randomRotation(),
1476
+ rotateZ: randomRotation(),
1477
+ gradientStops: Math.floor(random(2, 5)),
1478
+ color: randomColor(),
1479
+ transparentStop: random(50, 100)
1480
+ })));
1481
+ }, [
1482
+ particleCount,
1483
+ animationDuration,
1484
+ colors
1485
+ ]);
1486
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1487
+ className: "relative size-full flex items-center justify-center",
1488
+ style: { perspective },
1489
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1490
+ className: cn("relative flex items-end justify-center", className),
1491
+ children: particles.map((particle) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1492
+ className: "absolute",
1493
+ style: {
1494
+ width: particleWidth,
1495
+ height: particleHeight,
1496
+ willChange: "transform, opacity",
1497
+ transformStyle: "preserve-3d",
1498
+ background: `linear-gradient(to left, ${particle.color}, transparent ${particle.transparentStop}%)`,
1499
+ animation: `move-${particle.id} ${particle.duration}s linear infinite`,
1500
+ animationDelay: `${particle.delay}s`,
1501
+ transformOrigin: "0 center",
1502
+ "--rotateX": `${particle.rotateX}deg`,
1503
+ "--rotateY": `${particle.rotateY}deg`,
1504
+ "--rotateZ": `${particle.rotateZ}deg`
1505
+ }
1506
+ }, particle.id))
1507
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `
1508
+ ${particles.map((particle) => `
1509
+ @keyframes move-${particle.id} {
1510
+ 0% {
1511
+ transform: translateX(50%) rotateX(${particle.rotateX}deg) rotateY(${particle.rotateY}deg) rotateZ(${particle.rotateZ}deg) scale(2);
1512
+ opacity: 0;
1513
+ }
1514
+ 20% {
1515
+ opacity: 1;
1516
+ }
1517
+ 100% {
1518
+ transform: translateX(50%) rotateX(${particle.rotateX}deg) rotateY(${particle.rotateY}deg) rotateZ(${particle.rotateZ}deg) scale(0);
1519
+ opacity: 1;
1520
+ }
1521
+ }
1522
+ `).join("\n")}
1523
+ ` })]
1524
+ });
1525
+ };
1526
+ function WordRotate({ words, duration = 2500, framerProps = {
1527
+ initial: {
1528
+ opacity: 0,
1529
+ y: -50
1530
+ },
1531
+ animate: {
1532
+ opacity: 1,
1533
+ y: 0
1534
+ },
1535
+ exit: {
1536
+ opacity: 0,
1537
+ y: 50
1538
+ },
1539
+ transition: {
1540
+ duration: .25,
1541
+ ease: "easeOut"
1542
+ }
1543
+ }, className }) {
1544
+ const [index, setIndex] = (0, import_react.useState)(0);
1545
+ (0, import_react.useEffect)(() => {
1546
+ const interval = setInterval(() => {
1547
+ setIndex((prevIndex) => (prevIndex + 1) % words.length);
1548
+ }, duration);
1549
+ return () => clearInterval(interval);
1550
+ }, [words, duration]);
1551
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1552
+ className: "overflow-hidden py-2 inline-flex",
1553
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AnimatePresence, {
1554
+ mode: "wait",
1555
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(motion.h1, {
1556
+ className: cn(className),
1557
+ ...framerProps,
1558
+ children: words[index]
1559
+ }, words[index])
1560
+ })
1561
+ });
1562
+ }
1563
+ var Snippet = ({ className, text, width = "100%", onCopy, prompt = true }) => {
1564
+ const [copied, setCopied] = (0, import_react.useState)(false);
1565
+ const timeout = (0, import_react.useRef)(null);
1566
+ const lines = typeof text === "string" ? [text] : text;
1567
+ const onClick = () => {
1568
+ if (timeout.current) clearTimeout(timeout.current);
1569
+ setCopied(true);
1570
+ timeout.current = setTimeout(() => setCopied(false), 2e3);
1571
+ copyTextToClipboard(lines.join("\n"));
1572
+ onCopy?.();
1573
+ };
1574
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1575
+ className: cn("flex items-start gap-3 px-3 py-2.5 rounded-md border border-border bg-muted", className),
1576
+ style: { width },
1577
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1578
+ className: "flex-1",
1579
+ children: lines.map((line) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1580
+ className: clsx("font-mono text-[13px] text-muted-foreground", prompt && "before:content-['$_']"),
1581
+ children: line
1582
+ }, line))
1583
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
1584
+ onClick,
1585
+ className: "cursor-pointer mt-0.5 text-muted-foreground hover:text-foreground transition-colors",
1586
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Check, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Copy, { size: 16 })
1587
+ })]
1588
+ });
1589
+ };
1590
+ var command = "npx palettecn";
1591
+ function LandingPage() {
1592
+ const { theme } = z();
1593
+ const { appendThemes, setCurrentTheme, setIsSidebarCollapsed } = useThemes();
1594
+ const [npxDialogOpen, setNpxDialogOpen] = (0, import_react.useState)(false);
1595
+ function getStarted() {
1596
+ setIsSidebarCollapsed(false);
1597
+ if (!isLocal) setNpxDialogOpen(true);
1598
+ }
1599
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Dialog$1, {
1600
+ open: npxDialogOpen,
1601
+ onOpenChange: setNpxDialogOpen,
1602
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogContent, { children: [
1603
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogTitle, { children: "Setup palettecn" }),
1604
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogDescription, { children: "You must run palettecn locally. Run it using the following command:" }),
1605
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Snippet, { text: command })
1606
+ ] })
1607
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1608
+ className: "relative size-full",
1609
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1610
+ className: "size-full overflow-hidden -z-1 absolute inset-0",
1611
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ParticleAnimation, {
1612
+ particleCount: 500,
1613
+ colors: [
1614
+ "#fff200",
1615
+ "#a855f7",
1616
+ "#f43f5e",
1617
+ "#22c55e"
1618
+ ],
1619
+ animationDuration: [1, 20],
1620
+ className: "size-full opacity-20"
1621
+ })
1622
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1623
+ className: "flex items-center flex-col mt-24 gap-y-2 overflow-hidden",
1624
+ children: [
1625
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h1", {
1626
+ className: "font-extrabold text-3xl sm:text-5xl sm:mr-8 inline text-center",
1627
+ children: [
1628
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WordRotate, {
1629
+ duration: 4e3,
1630
+ words: [
1631
+ "Design",
1632
+ "Create",
1633
+ "Generate"
1634
+ ],
1635
+ className: "sm:w-68 w-40 text-right"
1636
+ }),
1637
+ " ",
1638
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1639
+ className: "text-primary mr-12 sm:mr-0",
1640
+ children: "shadcn/ui"
1641
+ }),
1642
+ " themes with",
1643
+ " ",
1644
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1645
+ className: "bg-primary text-primary-foreground px-2 rounded-sm",
1646
+ children: "AI"
1647
+ })
1648
+ ]
1649
+ }),
1650
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
1651
+ className: "text-muted-foreground text-center px-12 mt-4",
1652
+ children: "Build stunning shadcn themes using premade color palettes and AI."
1653
+ }),
1654
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1655
+ className: "flex gap-2 [&_button]:px-8! mt-4",
1656
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
1657
+ onClick: getStarted,
1658
+ className: "font-bold",
1659
+ children: "Get started"
1660
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
1661
+ href: "https://github.com/mrozio13pl/palettecn",
1662
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
1663
+ className: "font-bold backdrop-blur-sm",
1664
+ variant: "outline",
1665
+ children: ["View on ", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icons$5, {})]
1666
+ })
1667
+ })]
1668
+ }),
1669
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1670
+ className: "flex flex-col items-center gap-y-4 mt-4",
1671
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
1672
+ className: "text-muted-foreground text-center px-12",
1673
+ children: "Run palettecn locally and use your own AI providers."
1674
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Snippet, {
1675
+ text: command,
1676
+ className: "max-w-74"
1677
+ })]
1678
+ }),
1679
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1680
+ className: "opacity-50 sm:w-xl w-3xs flex justify-center items-center [&_svg]:min-w-6 [&_svg]:fill-border text-border my-8",
1681
+ children: [
1682
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Clover, { className: "-rotate-135" }),
1683
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Separator$1, { className: "py-px w-full" }),
1684
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Clover, { className: "rotate-45" })
1685
+ ]
1686
+ }),
1687
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1688
+ className: "sm:px-20 flex justify-center",
1689
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1690
+ className: "max-w-5xl flex flex-wrap justify-center items-center gap-4",
1691
+ children: premadeThemes.map((premadeTheme) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
1692
+ size: "sm",
1693
+ className: "opacity-80 hover:opacity-100 px-1.5",
1694
+ style: {
1695
+ backgroundColor: premadeTheme[theme === "dark" ? "dark" : "light"].background,
1696
+ color: premadeTheme[theme === "dark" ? "dark" : "light"].foreground
1697
+ },
1698
+ onClick: () => {
1699
+ appendThemes(premadeTheme);
1700
+ setCurrentTheme(premadeTheme, true, theme);
1701
+ },
1702
+ children: [previewColors.slice(0, 3).map((colorName) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1703
+ className: "size-6 border rounded-sm",
1704
+ style: { backgroundColor: premadeTheme?.[theme === "dark" ? "dark" : "light"]?.[colorName] }
1705
+ }, colorName)), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
1706
+ className: "ml-2 font-semibold",
1707
+ children: premadeTheme?.name || "Untitled"
1708
+ })]
1709
+ }, premadeTheme.id))
1710
+ })
1711
+ })
1712
+ ]
1713
+ })]
1714
+ })] });
1715
+ }
1716
+ var ComponentsPage = (0, import_react.lazy)(() => import("./components-BzCiScpA.mjs").then((m) => ({ default: m.ComponentsPage })));
1717
+ var fallback = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1718
+ className: "h-full flex justify-center items-center",
1719
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, { className: "size-12 -mt-12" })
1720
+ });
1721
+ function Preview() {
1722
+ const { isSidebarCollapsed } = useThemes();
1723
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Tabs$1, {
1724
+ defaultValue: "landing",
1725
+ className: "size-full flex-col overflow-hidden",
1726
+ children: [
1727
+ !isSidebarCollapsed && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TabsList, {
1728
+ className: "bg-transparent! m-2 gap-4",
1729
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(GhostTabsTrigger, {
1730
+ value: "landing",
1731
+ children: "Landing Page"
1732
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GhostTabsTrigger, {
1733
+ value: "components",
1734
+ children: "Components"
1735
+ })]
1736
+ }),
1737
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsContent, {
1738
+ value: "landing",
1739
+ className: "size-full overflow-x-hidden sm:overflow-hidden",
1740
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LandingPage, {})
1741
+ }),
1742
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsContent, {
1743
+ value: "components",
1744
+ className: "h-full overflow-y-auto sm:pb-20 @container",
1745
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Suspense, {
1746
+ fallback,
1747
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ComponentsPage, {})
1748
+ })
1749
+ })
1750
+ ]
1751
+ });
1752
+ }
1753
+ function Popover$1({ ...props }) {
1754
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Root2$1, {
1755
+ "data-slot": "popover",
1756
+ ...props
1757
+ });
1758
+ }
1759
+ function PopoverTrigger({ ...props }) {
1760
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trigger$3, {
1761
+ "data-slot": "popover-trigger",
1762
+ ...props
1763
+ });
1764
+ }
1765
+ function PopoverContent({ className, align = "center", sideOffset = 4, ...props }) {
1766
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Portal$2, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Content2$2, {
1767
+ "data-slot": "popover-content",
1768
+ align,
1769
+ sideOffset,
1770
+ className: cn("bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 flex flex-col gap-2.5 rounded-lg p-2.5 text-sm shadow-md ring-1 duration-100 z-50 w-72 origin-(--radix-popover-content-transform-origin) outline-hidden", className),
1771
+ ...props
1772
+ }) });
1773
+ }
1774
+ var fontTypes = {
1775
+ all: "All Fonts",
1776
+ display: "Display",
1777
+ handwriting: "Handwriting",
1778
+ monospace: "Monospace",
1779
+ "sans-serif": "Sans Serif",
1780
+ serif: "Serif"
1781
+ };
1782
+ function FontPicker({ font, onFontChange }) {
1783
+ const [query, setQuery] = (0, import_react.useState)("");
1784
+ const [category, setCategory] = (0, import_react.useState)("all");
1785
+ const { loadedFonts, fonts } = useFonts();
1786
+ const hoverTimeoutRef = (0, import_react.useRef)({});
1787
+ const filteredFonts = (0, import_react.useMemo)(() => {
1788
+ if (!fonts) return [];
1789
+ let searchedFonts = fonts;
1790
+ if (query.trim().length) searchedFonts = import_fuzzysort.default.go(query, fonts, { keys: ["id", "family"] }).map(({ obj }) => obj);
1791
+ if (category !== "all") searchedFonts = searchedFonts.filter((searchedFont) => searchedFont.category === category);
1792
+ return searchedFonts;
1793
+ }, [
1794
+ fonts,
1795
+ query,
1796
+ category
1797
+ ]);
1798
+ const handleMouseEnter = (fontId, fontFamily) => {
1799
+ if (hoverTimeoutRef.current[fontId]) clearTimeout(hoverTimeoutRef.current[fontId]);
1800
+ hoverTimeoutRef.current[fontId] = setTimeout(() => {
1801
+ loadFont(fontId, fontFamily);
1802
+ }, 500);
1803
+ };
1804
+ const handleMouseLeave = (fontId) => {
1805
+ if (hoverTimeoutRef.current[fontId]) {
1806
+ clearTimeout(hoverTimeoutRef.current[fontId]);
1807
+ delete hoverTimeoutRef.current[fontId];
1808
+ }
1809
+ };
1810
+ (0, import_react.useEffect)(() => {
1811
+ return () => {
1812
+ Object.values(hoverTimeoutRef.current).forEach(clearTimeout);
1813
+ };
1814
+ }, []);
1815
+ if (!fonts) return null;
1816
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Popover$1, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PopoverTrigger, {
1817
+ asChild: true,
1818
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
1819
+ className: "w-full justify-between",
1820
+ variant: "outline",
1821
+ children: [font ? fonts.find((f) => font === f.id)?.family : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
1822
+ className: "text-muted-foreground",
1823
+ children: "Select font"
1824
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, { className: "size-4 opacity-50" })]
1825
+ })
1826
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(PopoverContent, {
1827
+ className: "w-96 space-y-2",
1828
+ children: [
1829
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
1830
+ placeholder: "Search fonts...",
1831
+ value: query,
1832
+ onChange: (e) => setQuery(e.target.value)
1833
+ }),
1834
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Select$1, {
1835
+ value: category,
1836
+ onValueChange: setCategory,
1837
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectTrigger, {
1838
+ className: "w-full",
1839
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectValue, {})
1840
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectContent, { children: Object.keys(fontTypes).map((type) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItem, {
1841
+ value: type,
1842
+ children: fontTypes[type]
1843
+ }, type)) })]
1844
+ }),
1845
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScrollArea$1, {
1846
+ className: "h-80 space-y-1",
1847
+ children: filteredFonts?.map((fontItem) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PopoverClose, {
1848
+ asChild: true,
1849
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Button, {
1850
+ className: "w-full flex-col items-start gap-y-0! h-auto",
1851
+ variant: "ghost",
1852
+ onClick: () => {
1853
+ loadFont(fontItem.id, fontItem.family);
1854
+ onFontChange(fontItem.id);
1855
+ },
1856
+ onMouseEnter: () => handleMouseEnter(fontItem.id, fontItem.family),
1857
+ onMouseLeave: () => handleMouseLeave(fontItem.id),
1858
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
1859
+ className: "text-lg",
1860
+ style: { fontFamily: loadedFonts.has(fontItem.id) ? fontItem.family : void 0 },
1861
+ children: fontItem.family
1862
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
1863
+ className: "text-muted-foreground text-xs font-normal",
1864
+ children: fontItem.category
1865
+ })]
1866
+ })
1867
+ }, fontItem.id))
1868
+ })
1869
+ ]
1870
+ })] });
1871
+ }
1872
+ function Typography() {
1873
+ const { themes, currentTheme, setThemes, setCurrentTheme } = useThemes();
1874
+ const { theme } = z();
1875
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1876
+ className: "flex flex-col gap-y-4",
1877
+ children: [
1878
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1879
+ className: "space-y-1",
1880
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { children: "Sans-Serif" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FontPicker, {
1881
+ font: currentTheme?.fontSans,
1882
+ onFontChange: (font) => {
1883
+ setCurrentTheme({
1884
+ ...currentTheme,
1885
+ fontSans: font
1886
+ });
1887
+ }
1888
+ })]
1889
+ }),
1890
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1891
+ className: "space-y-1",
1892
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { children: "Serif" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FontPicker, {
1893
+ font: currentTheme?.fontSerif,
1894
+ onFontChange: (font) => {
1895
+ setCurrentTheme({
1896
+ ...currentTheme,
1897
+ fontSerif: font
1898
+ });
1899
+ }
1900
+ })]
1901
+ }),
1902
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1903
+ className: "space-y-1",
1904
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { children: "Monospace" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FontPicker, {
1905
+ font: currentTheme?.fontMono,
1906
+ onFontChange: (font) => {
1907
+ setCurrentTheme({
1908
+ ...currentTheme,
1909
+ fontMono: font
1910
+ });
1911
+ }
1912
+ })]
1913
+ }),
1914
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1915
+ className: "space-y-1",
1916
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { children: "Border radius" }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1917
+ className: "relative flex items-center",
1918
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
1919
+ type: "number",
1920
+ value: currentTheme?.[theme].radius.replace("rem", ""),
1921
+ className: "pr-12",
1922
+ onChange: (e) => {
1923
+ const value = e.target.value;
1924
+ setThemes(themes.map((t) => {
1925
+ if (t.id === currentTheme?.id) {
1926
+ const newTheme = {
1927
+ ...t,
1928
+ dark: {
1929
+ ...t.dark,
1930
+ radius: value + "rem"
1931
+ },
1932
+ light: {
1933
+ ...t.light,
1934
+ radius: value + "rem"
1935
+ }
1936
+ };
1937
+ setCurrentTheme(newTheme);
1938
+ return newTheme;
1939
+ }
1940
+ return t;
1941
+ }));
1942
+ }
1943
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1944
+ className: "absolute right-3 select-none text-sm font-medium text-muted-foreground pointer-events-none",
1945
+ children: "rem"
1946
+ })]
1947
+ })]
1948
+ })
1949
+ ]
1950
+ });
1951
+ }
1952
+ var ColorPickerContext = (0, import_react.createContext)(void 0);
1953
+ var { Range, Root, Thumb, Track } = dist_exports;
1954
+ var useColorPicker = () => {
1955
+ const context = (0, import_react.use)(ColorPickerContext);
1956
+ if (!context) throw new Error("useColorPicker must be used within a ColorPickerProvider");
1957
+ return context;
1958
+ };
1959
+ var ColorPicker = ({ value, defaultValue = "#000000", onChange, className, ...props }) => {
1960
+ const selectedColor = Color(value);
1961
+ const defaultColor = Color(defaultValue);
1962
+ const [hue, setHue] = (0, import_react.useState)(selectedColor.hue() || defaultColor.hue() || 0);
1963
+ const [saturation, setSaturation] = (0, import_react.useState)(selectedColor.saturationl() || defaultColor.saturationl() || 100);
1964
+ const [lightness, setLightness] = (0, import_react.useState)(selectedColor.lightness() || defaultColor.lightness() || 50);
1965
+ const [alpha, setAlpha] = (0, import_react.useState)(selectedColor.alpha() * 100 || defaultColor.alpha() * 100);
1966
+ const [mode, setMode] = (0, import_react.useState)("hex");
1967
+ (0, import_react.useEffect)(() => {
1968
+ if (value) {
1969
+ const color = Color.rgb(value).rgb().object();
1970
+ setHue(color.r);
1971
+ setSaturation(color.g);
1972
+ setLightness(color.b);
1973
+ setAlpha(color.a);
1974
+ }
1975
+ }, [value]);
1976
+ (0, import_react.useEffect)(() => {
1977
+ if (onChange) onChange(Color.hsl(hue, saturation, lightness).alpha(alpha / 100).rgb());
1978
+ }, [
1979
+ hue,
1980
+ saturation,
1981
+ lightness,
1982
+ alpha,
1983
+ onChange
1984
+ ]);
1985
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ColorPickerContext, {
1986
+ value: {
1987
+ hue,
1988
+ saturation,
1989
+ lightness,
1990
+ alpha,
1991
+ mode,
1992
+ setHue,
1993
+ setSaturation,
1994
+ setLightness,
1995
+ setAlpha,
1996
+ setMode
1997
+ },
1998
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1999
+ className: cn("grid w-full gap-4", className),
2000
+ ...props
2001
+ })
2002
+ });
2003
+ };
2004
+ var ColorPickerSelection = ({ className, ...props }) => {
2005
+ const containerRef = (0, import_react.useRef)(null);
2006
+ const [isDragging, setIsDragging] = (0, import_react.useState)(false);
2007
+ const { hue, saturation, lightness, setSaturation, setLightness } = useColorPicker();
2008
+ const [position, setPosition] = (0, import_react.useState)({
2009
+ x: 0,
2010
+ y: 0
2011
+ });
2012
+ (0, import_react.useEffect)(() => {
2013
+ if (isDragging || !containerRef.current) return;
2014
+ const color = Color.hsl(hue, saturation, lightness).hsv();
2015
+ setPosition({
2016
+ x: color.saturationv() / 100,
2017
+ y: 1 - color.value() / 100
2018
+ });
2019
+ }, [
2020
+ containerRef,
2021
+ hue,
2022
+ saturation,
2023
+ lightness
2024
+ ]);
2025
+ const handlePointerMove = (0, import_react.useCallback)((event) => {
2026
+ if (!isDragging || !containerRef.current) return;
2027
+ const rect = containerRef.current.getBoundingClientRect();
2028
+ const x = Math.max(0, Math.min(1, (event.clientX - rect.left) / rect.width));
2029
+ const y = Math.max(0, Math.min(1, (event.clientY - rect.top) / rect.height));
2030
+ const color = Color.hsv(hue, x * 100, (1 - y) * 100).hsl();
2031
+ setPosition({
2032
+ x,
2033
+ y
2034
+ });
2035
+ setSaturation(color.saturationl());
2036
+ setLightness(color.lightness());
2037
+ }, [
2038
+ isDragging,
2039
+ hue,
2040
+ setSaturation,
2041
+ setLightness
2042
+ ]);
2043
+ (0, import_react.useEffect)(() => {
2044
+ if (isDragging) {
2045
+ window.addEventListener("pointermove", handlePointerMove);
2046
+ const handleUp = () => setIsDragging(false);
2047
+ window.addEventListener("pointerup", handleUp);
2048
+ return () => {
2049
+ window.removeEventListener("pointermove", handlePointerMove);
2050
+ window.removeEventListener("pointerup", handleUp);
2051
+ };
2052
+ }
2053
+ }, [isDragging, handlePointerMove]);
2054
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2055
+ ref: containerRef,
2056
+ className: cn("relative aspect-[4/3] w-full cursor-crosshair rounded overflow-hidden", className),
2057
+ style: { background: `
2058
+ linear-gradient(to top, #000, transparent),
2059
+ linear-gradient(to right, #fff, hsl(${hue}, 100%, 50%))
2060
+ ` },
2061
+ onPointerDown: (e) => {
2062
+ e.preventDefault();
2063
+ setIsDragging(true);
2064
+ const rect = containerRef.current.getBoundingClientRect();
2065
+ const x = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
2066
+ const y = Math.max(0, Math.min(1, (e.clientY - rect.top) / rect.height));
2067
+ const color = Color.hsv(hue, x * 100, (1 - y) * 100).hsl();
2068
+ setSaturation(color.saturationl());
2069
+ setLightness(color.lightness());
2070
+ },
2071
+ ...props,
2072
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2073
+ className: "-translate-x-1/2 -translate-y-1/2 pointer-events-none absolute h-4 w-4 rounded-full border-2 border-white shadow-[0_0_0_1px_rgba(0,0,0,0.5)]",
2074
+ style: {
2075
+ left: `${position.x * 100}%`,
2076
+ top: `${position.y * 100}%`
2077
+ }
2078
+ })
2079
+ });
2080
+ };
2081
+ var ColorPickerHue = ({ className, ...props }) => {
2082
+ const { hue, setHue } = useColorPicker();
2083
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Root, {
2084
+ value: [hue],
2085
+ max: 360,
2086
+ step: 1,
2087
+ className: cn("relative flex h-4 w-full touch-none", className),
2088
+ onValueChange: ([hue]) => setHue(hue),
2089
+ ...props,
2090
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Track, {
2091
+ className: "relative my-0.5 h-3 w-full grow rounded-full bg-[linear-gradient(90deg,#FF0000,#FFFF00,#00FF00,#00FFFF,#0000FF,#FF00FF,#FF0000)]",
2092
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Range, { className: "absolute h-full" })
2093
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Thumb, { className: "block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" })]
2094
+ });
2095
+ };
2096
+ var ColorPickerAlpha = ({ className, ...props }) => {
2097
+ const { alpha, setAlpha } = useColorPicker();
2098
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Root, {
2099
+ value: [alpha],
2100
+ max: 100,
2101
+ step: 1,
2102
+ className: cn("relative flex h-4 w-full touch-none", className),
2103
+ onValueChange: ([alpha]) => setAlpha(alpha),
2104
+ ...props,
2105
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Track, {
2106
+ className: "relative my-0.5 h-3 w-full grow rounded-full",
2107
+ style: { background: "url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMUlEQVQ4T2NkYGAQYcAP3uCTZhw1gGGYhAGBZIA/nYDCgBDAm9BGDWAAJyRCgLaBCAAgXwixzAS0pgAAAABJRU5ErkJggg==\") left center" },
2108
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "absolute inset-0 rounded-full bg-gradient-to-r from-transparent to-primary/50" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Range, { className: "absolute h-full rounded-full bg-transparent" })]
2109
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Thumb, { className: "block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" })]
2110
+ });
2111
+ };
2112
+ var ColorPickerEyeDropper = ({ className, ...props }) => {
2113
+ const { setHue, setSaturation, setLightness, setAlpha } = useColorPicker();
2114
+ const handleEyeDropper = async () => {
2115
+ try {
2116
+ const [h, s, l] = Color((await new EyeDropper().open()).sRGBHex).hsl().array();
2117
+ setHue(h);
2118
+ setSaturation(s);
2119
+ setLightness(l);
2120
+ setAlpha(100);
2121
+ } catch (error) {
2122
+ console.error("EyeDropper failed:", error);
2123
+ }
2124
+ };
2125
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
2126
+ variant: "outline",
2127
+ size: "icon",
2128
+ onClick: handleEyeDropper,
2129
+ className: cn("shrink-0 text-muted-foreground", className),
2130
+ ...props,
2131
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pipette, { size: 16 })
2132
+ });
2133
+ };
2134
+ var formats = [
2135
+ "oklch",
2136
+ "hex",
2137
+ "rgb",
2138
+ "css",
2139
+ "hsl"
2140
+ ];
2141
+ var ColorPickerOutput = ({ className, ...props }) => {
2142
+ const { mode, setMode } = useColorPicker();
2143
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Select$1, {
2144
+ value: mode,
2145
+ onValueChange: setMode,
2146
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectTrigger, {
2147
+ className: "h-8 w-[4.5rem] shrink-0 text-xs",
2148
+ ...props,
2149
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectValue, { placeholder: "Mode" })
2150
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectContent, { children: formats.map((format) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItem, {
2151
+ value: format,
2152
+ className: "text-xs",
2153
+ children: format.toUpperCase()
2154
+ }, format)) })]
2155
+ });
2156
+ };
2157
+ var PercentageInput = ({ className, ...props }) => {
2158
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2159
+ className: "relative",
2160
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
2161
+ type: "text",
2162
+ ...props,
2163
+ className: cn("h-8 w-[3.25rem] rounded-l-none bg-secondary px-2 text-xs shadow-none", className)
2164
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2165
+ className: "-translate-y-1/2 absolute top-1/2 right-2 text-muted-foreground text-xs",
2166
+ children: "%"
2167
+ })]
2168
+ });
2169
+ };
2170
+ var ColorPickerFormat = ({ className, ...props }) => {
2171
+ const { hue, saturation, lightness, alpha, mode, setHue, setSaturation, setLightness } = useColorPicker();
2172
+ const color = Color.hsl(hue, saturation, lightness, alpha / 100);
2173
+ if (mode === "hex") {
2174
+ const hex = color.hex();
2175
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2176
+ className: cn("-space-x-px relative flex items-center shadow-sm", className),
2177
+ ...props,
2178
+ children: [
2179
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2180
+ className: "-translate-y-1/2 absolute top-1/2 left-3 text-xs text-muted-foreground",
2181
+ children: "#"
2182
+ }),
2183
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
2184
+ type: "text",
2185
+ value: hex,
2186
+ className: "h-8 rounded-r-none bg-secondary px-2 text-xs shadow-none"
2187
+ }),
2188
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PercentageInput, { value: alpha })
2189
+ ]
2190
+ });
2191
+ }
2192
+ if (mode === "rgb") {
2193
+ const rgb = color.rgb().array().map((value) => Math.round(value));
2194
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2195
+ className: cn("-space-x-px flex items-center shadow-sm", className),
2196
+ ...props,
2197
+ children: [rgb.map((value, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
2198
+ type: "text",
2199
+ value,
2200
+ readOnly: true,
2201
+ className: cn("h-8 rounded-r-none bg-secondary px-2 text-xs shadow-none", index && "rounded-l-none", className)
2202
+ }, index)), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PercentageInput, { value: alpha })]
2203
+ });
2204
+ }
2205
+ if (mode === "css") {
2206
+ const rgb = color.rgb().array().map((value) => Math.round(value));
2207
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2208
+ className: cn("w-full shadow-sm", className),
2209
+ ...props,
2210
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
2211
+ type: "text",
2212
+ className: "h-8 w-full bg-secondary px-2 text-xs shadow-none",
2213
+ value: `rgba(${rgb.join(", ")}, ${alpha}%)`,
2214
+ readOnly: true,
2215
+ ...props
2216
+ })
2217
+ });
2218
+ }
2219
+ if (mode === "hsl") {
2220
+ const hsl = color.hsl().array().map((value) => Math.round(value));
2221
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2222
+ className: cn("-space-x-px flex items-center shadow-sm", className),
2223
+ ...props,
2224
+ children: [hsl.map((value, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
2225
+ type: "text",
2226
+ value,
2227
+ readOnly: true,
2228
+ className: cn("h-8 rounded-r-none bg-secondary px-2 text-xs shadow-none", index && "rounded-l-none", className)
2229
+ }, index)), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PercentageInput, { value: alpha })]
2230
+ });
2231
+ }
2232
+ if (mode === "oklch") {
2233
+ const rgb = color.rgb().array().map((value) => Math.round(value));
2234
+ const oklch = convert.rgb.lch(rgb[0], rgb[1], rgb[2]);
2235
+ const [l, c, h] = oklch.map((value, index) => {
2236
+ return index === 1 ? Math.round(value * 100) / 100 : Math.round(value);
2237
+ });
2238
+ const handleOklchChange = (index, value) => {
2239
+ try {
2240
+ const currentOklch = [...oklch];
2241
+ currentOklch[index] = parseFloat(value) || 0;
2242
+ const newRgb = convert.lch.rgb(currentOklch[0], currentOklch[1], currentOklch[2]);
2243
+ const newHsl = convert.rgb.hsl(newRgb[0], newRgb[1], newRgb[2]);
2244
+ setHue(newHsl[0]);
2245
+ setSaturation(newHsl[1]);
2246
+ setLightness(newHsl[2]);
2247
+ } catch (error) {
2248
+ console.error("Invalid OKLCH color:", error);
2249
+ }
2250
+ };
2251
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2252
+ className: cn("-space-x-px flex items-center shadow-sm", className),
2253
+ ...props,
2254
+ children: [
2255
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
2256
+ type: "text",
2257
+ value: l,
2258
+ onChange: (e) => handleOklchChange(0, e.target.value),
2259
+ className: "h-8 rounded-r-none bg-secondary px-2 text-xs shadow-none",
2260
+ placeholder: "L"
2261
+ }),
2262
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
2263
+ type: "text",
2264
+ value: c,
2265
+ onChange: (e) => handleOklchChange(1, e.target.value),
2266
+ className: "h-8 rounded-none bg-secondary px-2 text-xs shadow-none",
2267
+ placeholder: "C"
2268
+ }),
2269
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
2270
+ type: "text",
2271
+ value: h,
2272
+ onChange: (e) => handleOklchChange(2, e.target.value),
2273
+ className: "h-8 rounded-none bg-secondary px-2 text-xs shadow-none",
2274
+ placeholder: "H"
2275
+ }),
2276
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PercentageInput, { value: alpha })
2277
+ ]
2278
+ });
2279
+ }
2280
+ return null;
2281
+ };
2282
+ function Colors() {
2283
+ const { theme } = z();
2284
+ const { colorMode, currentTheme, setCurrentTheme } = useThemes();
2285
+ const selectedTheme = currentTheme?.[theme === "dark" ? "dark" : "light"];
2286
+ const debounceTimer = (0, import_react.useRef)(null);
2287
+ (0, import_react.useEffect)(() => {
2288
+ return () => {
2289
+ if (debounceTimer.current) clearTimeout(debounceTimer.current);
2290
+ };
2291
+ }, []);
2292
+ const onUpdate = (colorName, rgb) => {
2293
+ if (!currentTheme || !selectedTheme || selectedTheme[colorName] === rgb) return;
2294
+ if (debounceTimer.current) clearTimeout(debounceTimer.current);
2295
+ debounceTimer.current = setTimeout(() => {
2296
+ if (!currentTheme || !selectedTheme || selectedTheme[colorName] === rgb) return;
2297
+ const newTheme = currentTheme;
2298
+ newTheme[theme === "dark" ? "dark" : "light"] = {
2299
+ ...selectedTheme,
2300
+ [colorName]: rgb
2301
+ };
2302
+ setCurrentTheme(newTheme);
2303
+ }, 250);
2304
+ };
2305
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2306
+ className: "space-y-6 overflow-auto h-full pb-24",
2307
+ children: Object.keys(colorSegments).map((segmentName) => {
2308
+ const colors = colorSegments[segmentName];
2309
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Collapsible$1, {
2310
+ className: "border rounded-xl",
2311
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(CollapsibleTrigger, {
2312
+ className: "p-4 in-data-[state='open']:border-b flex justify-between items-center font-bold w-full",
2313
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: segmentName }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, {
2314
+ className: "transition-transform in-data-[state=\"open\"]:rotate-180",
2315
+ size: 16
2316
+ })]
2317
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollapsibleContent, {
2318
+ className: "p-4 space-y-2",
2319
+ children: colors.map((color) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2320
+ className: "flex items-center gap-2",
2321
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Popover$1, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PopoverTrigger, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2322
+ className: "size-12 border-2 rounded-sm overflow-hidden",
2323
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2324
+ className: "text-muted-foreground size-full flex justify-center items-center",
2325
+ style: { backgroundColor: selectedTheme?.[color] },
2326
+ children: !selectedTheme?.[color] ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ColorPlaceholder, { className: "size-6" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pencil, { className: "size-6" })
2327
+ })
2328
+ }) }), !!selectedTheme?.[color] && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PopoverContent, {
2329
+ align: "start",
2330
+ className: "p-0",
2331
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ColorPicker, {
2332
+ className: "w-full max-w-[300px] rounded-md border bg-background p-4 shadow-sm",
2333
+ defaultValue: selectedTheme[color] || "#ffffff",
2334
+ onChange: (rgb) => onUpdate(color, rgb.toString()),
2335
+ children: [
2336
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ColorPickerSelection, {}),
2337
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2338
+ className: "flex items-center gap-4",
2339
+ children: [typeof EyeDropper !== "undefined" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ColorPickerEyeDropper, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2340
+ className: "w-full grid gap-1",
2341
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ColorPickerHue, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ColorPickerAlpha, {})]
2342
+ })]
2343
+ }),
2344
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2345
+ className: "flex items-center gap-2",
2346
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ColorPickerOutput, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ColorPickerFormat, {})]
2347
+ })
2348
+ ]
2349
+ })
2350
+ })] }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2351
+ className: "space-y-1",
2352
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: formatColorName(color) }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2353
+ className: "text-muted-foreground text-xs flex items-center gap-2",
2354
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: displayColor(selectedTheme?.[color] || "", colorMode) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Copy, { className: "size-3 hover:opacity-90 cursor-pointer" })]
2355
+ })]
2356
+ })]
2357
+ }, color))
2358
+ })]
2359
+ }) }, segmentName);
2360
+ })
2361
+ });
2362
+ }
2363
+ function ColorPreview({ theme: currentTheme }) {
2364
+ const { theme } = z();
2365
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [previewColors.map((colorName, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2366
+ className: clsx("sm:size-6 size-4 border", i >= 3 && "hidden sm:block"),
2367
+ style: { backgroundColor: currentTheme?.[theme === "dark" ? "dark" : "light"]?.[colorName] }
2368
+ }, colorName)), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
2369
+ className: "ml-2 font-semibold",
2370
+ children: currentTheme?.name || "Untitled"
2371
+ })] });
2372
+ }
2373
+ function useIsMobile(breakpoint = 768) {
2374
+ const [isMobile, setIsMobile] = (0, import_react.useState)(false);
2375
+ (0, import_react.useEffect)(() => {
2376
+ const checkSize = () => {
2377
+ setIsMobile(window.innerWidth < breakpoint);
2378
+ };
2379
+ checkSize();
2380
+ window.addEventListener("resize", checkSize);
2381
+ return () => window.removeEventListener("resize", checkSize);
2382
+ }, [breakpoint]);
2383
+ return isMobile;
2384
+ }
2385
+ function Sidebar() {
2386
+ const chatRef = (0, import_react.useRef)(null);
2387
+ const { theme } = z();
2388
+ const { themes, currentTheme, setCurrentTheme } = useThemes();
2389
+ const currentThemeIndex = (0, import_react.useMemo)(() => themes.findIndex((_theme) => _theme.id === currentTheme?.id), [currentTheme, theme]);
2390
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2391
+ className: "size-full flex flex-col overflow-hidden",
2392
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2393
+ className: "h-16 sm:flex justify-between border-b hidden",
2394
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2395
+ className: "flex items-center gap-2 p-4",
2396
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SvgLogo, { className: "size-6 text-primary" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", {
2397
+ className: "font-bold text-sm select-none",
2398
+ children: "palettecn"
2399
+ })]
2400
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2401
+ className: "flex [&_button]:cursor-pointer [&_button]:rounded-none [&_button]:p-4 [&_button]:border-l [&_button]:h-full [&_button]:w-16",
2402
+ children: [
2403
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
2404
+ variant: "ghost",
2405
+ onClick: () => {
2406
+ const prev = themes[currentThemeIndex - 1];
2407
+ setCurrentTheme(prev);
2408
+ },
2409
+ disabled: currentThemeIndex === 0,
2410
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArrowLeft, {})
2411
+ }),
2412
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
2413
+ variant: "ghost",
2414
+ onClick: () => {
2415
+ const next = themes[currentThemeIndex + 1];
2416
+ setCurrentTheme(next);
2417
+ },
2418
+ disabled: currentThemeIndex >= themes.length - 1 || currentThemeIndex === -1,
2419
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArrowRight, {})
2420
+ }),
2421
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
2422
+ variant: "ghost",
2423
+ onClick: () => chatRef.current?.resetChat(),
2424
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Plus, {})
2425
+ })
2426
+ ]
2427
+ })]
2428
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Tabs$1, {
2429
+ className: "flex-1 flex-col flex min-h-0",
2430
+ defaultValue: "ai",
2431
+ children: [
2432
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TabsList, {
2433
+ className: "mb-4 sm:mt-4 px-2 w-full bg-transparent!",
2434
+ children: [
2435
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(GhostTabsTrigger, {
2436
+ value: "colors",
2437
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Palette, {}), "Colors"]
2438
+ }),
2439
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(GhostTabsTrigger, {
2440
+ value: "fonts",
2441
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TypeOutline, {}), "Typography"]
2442
+ }),
2443
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(GhostTabsTrigger, {
2444
+ value: "ai",
2445
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Sparkle, {}), "Generate"]
2446
+ }),
2447
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(GhostTabsTrigger, {
2448
+ value: "code",
2449
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CodeXml, {}), "Code"]
2450
+ })
2451
+ ]
2452
+ }),
2453
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsContent, {
2454
+ forceMount: true,
2455
+ className: "hidden w-full flex-1 min-h-0 data-[state=active]:flex flex-col m-0 border-none",
2456
+ value: "ai",
2457
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Chat, { ref: chatRef })
2458
+ }),
2459
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsContent, {
2460
+ className: "flex flex-col m-0 border-none size-full",
2461
+ value: "code",
2462
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CodePreview, {})
2463
+ }),
2464
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsContent, {
2465
+ className: "flex flex-col border-none size-full px-6",
2466
+ value: "fonts",
2467
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Typography, {})
2468
+ }),
2469
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsContent, {
2470
+ className: "flex flex-col border-none size-full px-6",
2471
+ value: "colors",
2472
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Colors, {})
2473
+ })
2474
+ ]
2475
+ })]
2476
+ });
2477
+ }
2478
+ function PreviewComponent() {
2479
+ const { isSidebarCollapsed, setIsSidebarCollapsed, themes, currentTheme, setCurrentTheme, setThemes } = useThemes();
2480
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2481
+ className: "flex flex-col size-full h-full overflow-hidden",
2482
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", {
2483
+ className: "size-full p-4 border-b h-16 -mt-2 sm:mt-0 flex items-center justify-between bg-background/20 backdrop-blur-sm",
2484
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2485
+ className: "flex items-center gap-2",
2486
+ children: [
2487
+ isSidebarCollapsed && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SvgLogo, { className: "size-6 text-primary" }),
2488
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
2489
+ size: "icon",
2490
+ variant: "ghost",
2491
+ className: "text-primary sm:flex hidden",
2492
+ onClick: () => setIsSidebarCollapsed(!isSidebarCollapsed),
2493
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PanelLeft, {})
2494
+ }),
2495
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Select$1, {
2496
+ value: currentTheme?.id,
2497
+ onValueChange: (id) => {
2498
+ const selected = themes.find((t) => t.id === id);
2499
+ if (selected) setCurrentTheme(selected);
2500
+ },
2501
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectTrigger, {
2502
+ className: "w-auto border-none shadow-none focus:ring-0 sm:[&_h3]:block [&_h3]:hidden",
2503
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectValue, {})
2504
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectContent, {
2505
+ position: "popper",
2506
+ children: themes.filter((theme) => Boolean(theme?.id)).map((theme) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectItem, {
2507
+ value: theme.id,
2508
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ColorPreview, { theme })
2509
+ }, theme.id))
2510
+ })]
2511
+ }),
2512
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Dialog$1, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogTrigger, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
2513
+ size: "icon",
2514
+ variant: "ghost",
2515
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Pencil, {})
2516
+ }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogContent, { children: [
2517
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogTitle, { children: "Edit name" }),
2518
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogDescription, { children: "Edit the name of the theme" }),
2519
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
2520
+ placeholder: "Untitled",
2521
+ value: themes.find((theme) => theme.id === currentTheme?.id)?.name,
2522
+ onChange: (e) => {
2523
+ setThemes(themes.map((theme) => {
2524
+ if (theme.id === currentTheme?.id) return {
2525
+ ...currentTheme,
2526
+ name: e.target.value
2527
+ };
2528
+ return theme;
2529
+ }));
2530
+ }
2531
+ })
2532
+ ] })] }),
2533
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
2534
+ size: "icon",
2535
+ variant: "destructive",
2536
+ onClick: () => {
2537
+ const index = themes.findIndex((theme) => theme.id === currentTheme?.id);
2538
+ setThemes(themes.filter((_, i) => index !== i));
2539
+ const updatedThemes = useThemes.getState().themes;
2540
+ if (updatedThemes.length === 0) {
2541
+ setThemes([defaultTheme]);
2542
+ setCurrentTheme(defaultTheme);
2543
+ } else setCurrentTheme(updatedThemes[Math.max(0, index - 1)]);
2544
+ },
2545
+ disabled: themes.length <= 1 && !themes.some((theme) => theme.id !== defaultThemeId),
2546
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trash2, {})
2547
+ })
2548
+ ]
2549
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2550
+ className: "flex items-center gap-4",
2551
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CopyCode, { className: "sm:flex hidden" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeSwitch, {})]
2552
+ })]
2553
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2554
+ className: "size-full p-2 overflow-hidden",
2555
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Preview, {})
2556
+ })]
2557
+ });
2558
+ }
2559
+ function App() {
2560
+ const { theme } = z();
2561
+ const { setFonts } = useFonts();
2562
+ const { initialized, isSidebarCollapsed, currentTheme } = useThemes();
2563
+ const isMobile = useIsMobile();
2564
+ useQuery({
2565
+ queryKey: ["fonts"],
2566
+ queryFn: async () => {
2567
+ setFonts(await (await fetch("https://api.fontsource.org/v1/fonts")).json());
2568
+ },
2569
+ staleTime: 1e3 * 60 * 60 * 24,
2570
+ gcTime: 1e3 * 60 * 60 * 24,
2571
+ refetchOnWindowFocus: false,
2572
+ refetchOnMount: false
2573
+ });
2574
+ (0, import_react.useEffect)(() => {
2575
+ if (currentTheme) applyTheme(currentTheme, theme);
2576
+ }, [currentTheme, theme]);
2577
+ if (!initialized) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2578
+ className: "flex justify-center items-center h-full",
2579
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, { className: "size-12" })
2580
+ });
2581
+ if (isMobile) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Tabs$1, {
2582
+ defaultValue: "editor",
2583
+ className: "size-full",
2584
+ children: [
2585
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TabsList, {
2586
+ className: "bg-transparent! w-full",
2587
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(GhostTabsTrigger, {
2588
+ value: "editor",
2589
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Settings2, {}), "Edit"]
2590
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(GhostTabsTrigger, {
2591
+ value: "preview",
2592
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScanEye, {}), "Preview"]
2593
+ })]
2594
+ }),
2595
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Separator$1, {}),
2596
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsContent, {
2597
+ value: "editor",
2598
+ className: "w-full @container/sidebar",
2599
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Sidebar, {})
2600
+ }),
2601
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TabsContent, {
2602
+ value: "preview",
2603
+ className: "w-full @container overflow-hidden",
2604
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PreviewComponent, {})
2605
+ })
2606
+ ]
2607
+ });
2608
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2609
+ className: "size-full",
2610
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ResizablePanelGroup, {
2611
+ orientation: "horizontal",
2612
+ className: "isolate",
2613
+ children: [
2614
+ !isSidebarCollapsed && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ResizablePanel, {
2615
+ defaultSize: 25,
2616
+ minSize: 400,
2617
+ maxSize: "50%",
2618
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Sidebar, {})
2619
+ }),
2620
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ResizableHandle, { withHandle: true }),
2621
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ResizablePanel, {
2622
+ defaultSize: 75,
2623
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PreviewComponent, {})
2624
+ })
2625
+ ]
2626
+ })
2627
+ });
2628
+ }
2629
+ //#endregion
2630
+ export { App as component };