@openpalm/ui 0.12.47 → 0.12.48

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 (314) hide show
  1. package/build/.openpalm-ui-version +1 -1
  2. package/build/client/_app/immutable/chunks/{Oapx3Kay.js → BSljCbHb.js} +1 -1
  3. package/build/client/_app/immutable/chunks/BSljCbHb.js.br +0 -0
  4. package/build/client/_app/immutable/chunks/BSljCbHb.js.gz +0 -0
  5. package/build/client/_app/immutable/chunks/{Bp6-ciNE.js → C7d4Zd5E.js} +2 -2
  6. package/build/client/_app/immutable/chunks/C7d4Zd5E.js.br +0 -0
  7. package/build/client/_app/immutable/chunks/C7d4Zd5E.js.gz +0 -0
  8. package/build/client/_app/immutable/chunks/{CQMT6iK8.js → DKKh4Y4a.js} +1 -1
  9. package/build/client/_app/immutable/chunks/DKKh4Y4a.js.br +0 -0
  10. package/build/client/_app/immutable/chunks/DKKh4Y4a.js.gz +0 -0
  11. package/build/client/_app/immutable/chunks/bG1zIfF_.js +1 -0
  12. package/build/client/_app/immutable/chunks/bG1zIfF_.js.br +2 -0
  13. package/build/client/_app/immutable/chunks/bG1zIfF_.js.gz +0 -0
  14. package/build/client/_app/immutable/entry/{app.CSv5ANTj.js → app.BWk2gV2e.js} +2 -2
  15. package/build/client/_app/immutable/entry/app.BWk2gV2e.js.br +0 -0
  16. package/build/client/_app/immutable/entry/app.BWk2gV2e.js.gz +0 -0
  17. package/build/client/_app/immutable/entry/start.Byi08gwa.js +1 -0
  18. package/build/client/_app/immutable/entry/start.Byi08gwa.js.br +0 -0
  19. package/build/client/_app/immutable/entry/start.Byi08gwa.js.gz +0 -0
  20. package/build/client/_app/immutable/nodes/{1.BgfOb4Io.js → 1.dpjmQYSB.js} +1 -1
  21. package/build/client/_app/immutable/nodes/1.dpjmQYSB.js.br +1 -0
  22. package/build/client/_app/immutable/nodes/1.dpjmQYSB.js.gz +0 -0
  23. package/build/client/_app/immutable/nodes/{10.v7TDafkp.js → 10.CuEAtoBT.js} +1 -1
  24. package/build/client/_app/immutable/nodes/10.CuEAtoBT.js.br +0 -0
  25. package/build/client/_app/immutable/nodes/10.CuEAtoBT.js.gz +0 -0
  26. package/build/client/_app/immutable/nodes/{4.BlGWSYpW.js → 4.CKTY2J5h.js} +1 -1
  27. package/build/client/_app/immutable/nodes/4.CKTY2J5h.js.br +0 -0
  28. package/build/client/_app/immutable/nodes/{4.BlGWSYpW.js.gz → 4.CKTY2J5h.js.gz} +0 -0
  29. package/build/client/_app/immutable/nodes/{5.C4R8b_rk.js → 5.DtDxrTaA.js} +1 -1
  30. package/build/client/_app/immutable/nodes/5.DtDxrTaA.js.br +0 -0
  31. package/build/client/_app/immutable/nodes/5.DtDxrTaA.js.gz +0 -0
  32. package/build/client/_app/immutable/nodes/{6.jkaKXnUx.js → 6.CkHqFiuF.js} +1 -1
  33. package/build/client/_app/immutable/nodes/6.CkHqFiuF.js.br +0 -0
  34. package/build/client/_app/immutable/nodes/6.CkHqFiuF.js.gz +0 -0
  35. package/build/client/_app/immutable/nodes/{7.BUnJYUcB.js → 7.BvuR2bYn.js} +1 -1
  36. package/build/client/_app/immutable/nodes/7.BvuR2bYn.js.br +0 -0
  37. package/build/client/_app/immutable/nodes/7.BvuR2bYn.js.gz +0 -0
  38. package/build/client/_app/immutable/nodes/{8.BFS_N1wx.js → 8.O8gtu9Sq.js} +1 -1
  39. package/build/client/_app/immutable/nodes/8.O8gtu9Sq.js.br +0 -0
  40. package/build/client/_app/immutable/nodes/8.O8gtu9Sq.js.gz +0 -0
  41. package/build/client/_app/immutable/nodes/{9.CskAvBGO.js → 9.BUZT_OkO.js} +1 -1
  42. package/build/client/_app/immutable/nodes/9.BUZT_OkO.js.br +0 -0
  43. package/build/client/_app/immutable/nodes/9.BUZT_OkO.js.gz +0 -0
  44. package/build/client/_app/version.json +1 -1
  45. package/build/client/_app/version.json.br +1 -1
  46. package/build/client/_app/version.json.gz +0 -0
  47. package/build/server/chunks/1-CqHNSh-j.js +9 -0
  48. package/build/server/chunks/{1-lLcx9Qz5.js.map → 1-CqHNSh-j.js.map} +1 -1
  49. package/build/server/chunks/{10-DVPYoZ9J.js → 10-BXg6hft4.js} +6 -6
  50. package/build/server/chunks/{10-DVPYoZ9J.js.map → 10-BXg6hft4.js.map} +1 -1
  51. package/build/server/chunks/{4-BVfBp23A.js → 4-KZsRPPOf.js} +3 -3
  52. package/build/server/chunks/{4-BVfBp23A.js.map → 4-KZsRPPOf.js.map} +1 -1
  53. package/build/server/chunks/{5-DgJpyjfn.js → 5-C6fXkR20.js} +3 -3
  54. package/build/server/chunks/{5-DgJpyjfn.js.map → 5-C6fXkR20.js.map} +1 -1
  55. package/build/server/chunks/{6-C-05DWaV.js → 6-9ekHlg5v.js} +3 -3
  56. package/build/server/chunks/{6-C-05DWaV.js.map → 6-9ekHlg5v.js.map} +1 -1
  57. package/build/server/chunks/{7-BQQjY_NB.js → 7-BIOkEr9c.js} +3 -3
  58. package/build/server/chunks/{7-BQQjY_NB.js.map → 7-BIOkEr9c.js.map} +1 -1
  59. package/build/server/chunks/{8-Bdp-X93B.js → 8-BXGKwarT.js} +3 -3
  60. package/build/server/chunks/{8-Bdp-X93B.js.map → 8-BXGKwarT.js.map} +1 -1
  61. package/build/server/chunks/{9-q0d9ajgV.js → 9-C1mzMPKT.js} +3 -3
  62. package/build/server/chunks/{9-q0d9ajgV.js.map → 9-C1mzMPKT.js.map} +1 -1
  63. package/build/server/chunks/{Navbar-2VQikbPX.js → Navbar-DAJktqgi.js} +4 -4
  64. package/build/server/chunks/{Navbar-2VQikbPX.js.map → Navbar-DAJktqgi.js.map} +1 -1
  65. package/build/server/chunks/{_page.svelte-_GGCcBaM.js → _page.svelte-CT6Vg3WG.js} +4 -4
  66. package/build/server/chunks/{_page.svelte-_GGCcBaM.js.map → _page.svelte-CT6Vg3WG.js.map} +1 -1
  67. package/build/server/chunks/{_page.svelte-CHJ6-Qiy.js → _page.svelte-CTPgRBok.js} +6 -6
  68. package/build/server/chunks/{_page.svelte-CHJ6-Qiy.js.map → _page.svelte-CTPgRBok.js.map} +1 -1
  69. package/build/server/chunks/{_page.svelte-CXlwalNt.js → _page.svelte-CqSffzxq.js} +2 -2
  70. package/build/server/chunks/{_page.svelte-CXlwalNt.js.map → _page.svelte-CqSffzxq.js.map} +1 -1
  71. package/build/server/chunks/{_page.svelte-BJ1cZ6b5.js → _page.svelte-DHpSPiDh.js} +3 -3
  72. package/build/server/chunks/{_page.svelte-BJ1cZ6b5.js.map → _page.svelte-DHpSPiDh.js.map} +1 -1
  73. package/build/server/chunks/{_page.svelte-CGw9CJIA.js → _page.svelte-DXcLfxnR.js} +6 -6
  74. package/build/server/chunks/{_page.svelte-CGw9CJIA.js.map → _page.svelte-DXcLfxnR.js.map} +1 -1
  75. package/build/server/chunks/{_page.svelte-Ctw14-9S.js → _page.svelte-DvwdOL5E.js} +3 -3
  76. package/build/server/chunks/{_page.svelte-Ctw14-9S.js.map → _page.svelte-DvwdOL5E.js.map} +1 -1
  77. package/build/server/chunks/{_page.svelte-DBt7l4Yv.js → _page.svelte-XgPJ5o1M.js} +6 -6
  78. package/build/server/chunks/{_page.svelte-DBt7l4Yv.js.map → _page.svelte-XgPJ5o1M.js.map} +1 -1
  79. package/build/server/chunks/{_server.ts-Z6Vi83O5.js → _server.ts--_-EyieK.js} +5 -5
  80. package/build/server/chunks/{_server.ts-Z6Vi83O5.js.map → _server.ts--_-EyieK.js.map} +1 -1
  81. package/build/server/chunks/{_server.ts-COwrUSRM.js → _server.ts-1yFBEeKa.js} +5 -5
  82. package/build/server/chunks/{_server.ts-COwrUSRM.js.map → _server.ts-1yFBEeKa.js.map} +1 -1
  83. package/build/server/chunks/{_server.ts-DYhWwSyH.js → _server.ts-7-W_Puzd.js} +6 -6
  84. package/build/server/chunks/{_server.ts-DYhWwSyH.js.map → _server.ts-7-W_Puzd.js.map} +1 -1
  85. package/build/server/chunks/{_server.ts-qjzrpojc.js → _server.ts-79Q6CypH.js} +5 -5
  86. package/build/server/chunks/{_server.ts-qjzrpojc.js.map → _server.ts-79Q6CypH.js.map} +1 -1
  87. package/build/server/chunks/{_server.ts-DqWcdN18.js → _server.ts-8A0i8cFY.js} +2 -2
  88. package/build/server/chunks/{_server.ts-DqWcdN18.js.map → _server.ts-8A0i8cFY.js.map} +1 -1
  89. package/build/server/chunks/{_server.ts-DeSJ541d.js → _server.ts-8nZFRNYc.js} +5 -5
  90. package/build/server/chunks/{_server.ts-DeSJ541d.js.map → _server.ts-8nZFRNYc.js.map} +1 -1
  91. package/build/server/chunks/{_server.ts-U447Wd92.js → _server.ts-9nK4JDPq.js} +5 -5
  92. package/build/server/chunks/{_server.ts-U447Wd92.js.map → _server.ts-9nK4JDPq.js.map} +1 -1
  93. package/build/server/chunks/{_server.ts-H04cuWai.js → _server.ts-B2QiRWcW.js} +6 -6
  94. package/build/server/chunks/{_server.ts-H04cuWai.js.map → _server.ts-B2QiRWcW.js.map} +1 -1
  95. package/build/server/chunks/{_server.ts-BLOz7yXM.js → _server.ts-B3c8XWzi.js} +5 -5
  96. package/build/server/chunks/{_server.ts-BLOz7yXM.js.map → _server.ts-B3c8XWzi.js.map} +1 -1
  97. package/build/server/chunks/{_server.ts-BjIt2ae5.js → _server.ts-B49Yh_UO.js} +5 -5
  98. package/build/server/chunks/{_server.ts-BjIt2ae5.js.map → _server.ts-B49Yh_UO.js.map} +1 -1
  99. package/build/server/chunks/{_server.ts-CbuvzbeK.js → _server.ts-B4WPRV6f.js} +4 -4
  100. package/build/server/chunks/{_server.ts-CbuvzbeK.js.map → _server.ts-B4WPRV6f.js.map} +1 -1
  101. package/build/server/chunks/{_server.ts-BQ33O-O4.js → _server.ts-B8BJxjLf.js} +5 -5
  102. package/build/server/chunks/{_server.ts-BQ33O-O4.js.map → _server.ts-B8BJxjLf.js.map} +1 -1
  103. package/build/server/chunks/{_server.ts-CggPDd67.js → _server.ts-BAojPHXt.js} +6 -6
  104. package/build/server/chunks/{_server.ts-CggPDd67.js.map → _server.ts-BAojPHXt.js.map} +1 -1
  105. package/build/server/chunks/{_server.ts-C-2t0JtE.js → _server.ts-BEXxcj0f.js} +5 -5
  106. package/build/server/chunks/{_server.ts-C-2t0JtE.js.map → _server.ts-BEXxcj0f.js.map} +1 -1
  107. package/build/server/chunks/{_server.ts-DJgRGnd7.js → _server.ts-BGejQaL_.js} +6 -6
  108. package/build/server/chunks/{_server.ts-DJgRGnd7.js.map → _server.ts-BGejQaL_.js.map} +1 -1
  109. package/build/server/chunks/{_server.ts-C9UdEqlE.js → _server.ts-BKqrFVZD.js} +5 -5
  110. package/build/server/chunks/{_server.ts-C9UdEqlE.js.map → _server.ts-BKqrFVZD.js.map} +1 -1
  111. package/build/server/chunks/{_server.ts-DHRbB8-e.js → _server.ts-BQbIG8NC.js} +5 -5
  112. package/build/server/chunks/{_server.ts-DHRbB8-e.js.map → _server.ts-BQbIG8NC.js.map} +1 -1
  113. package/build/server/chunks/{_server.ts-Dtu2mZK5.js → _server.ts-BTkBO7Gc.js} +5 -5
  114. package/build/server/chunks/{_server.ts-Dtu2mZK5.js.map → _server.ts-BTkBO7Gc.js.map} +1 -1
  115. package/build/server/chunks/{_server.ts-C7_6UCUq.js → _server.ts-BVA6XzCh.js} +8 -8
  116. package/build/server/chunks/{_server.ts-C7_6UCUq.js.map → _server.ts-BVA6XzCh.js.map} +1 -1
  117. package/build/server/chunks/{_server.ts-BYIiUyRI.js → _server.ts-Bate3pY0.js} +5 -5
  118. package/build/server/chunks/{_server.ts-BYIiUyRI.js.map → _server.ts-Bate3pY0.js.map} +1 -1
  119. package/build/server/chunks/{_server.ts-BuT5XZcH.js → _server.ts-BgEzu7zt.js} +5 -5
  120. package/build/server/chunks/{_server.ts-BuT5XZcH.js.map → _server.ts-BgEzu7zt.js.map} +1 -1
  121. package/build/server/chunks/{_server.ts-CVFJGijn.js → _server.ts-BgfvREW4.js} +5 -5
  122. package/build/server/chunks/{_server.ts-CVFJGijn.js.map → _server.ts-BgfvREW4.js.map} +1 -1
  123. package/build/server/chunks/{_server.ts-wg-GhA8r.js → _server.ts-BiLR1zvy.js} +5 -5
  124. package/build/server/chunks/{_server.ts-wg-GhA8r.js.map → _server.ts-BiLR1zvy.js.map} +1 -1
  125. package/build/server/chunks/{_server.ts-D7bZBcEC.js → _server.ts-Bjx-exIj.js} +5 -5
  126. package/build/server/chunks/{_server.ts-D7bZBcEC.js.map → _server.ts-Bjx-exIj.js.map} +1 -1
  127. package/build/server/chunks/{_server.ts-obpoYMkT.js → _server.ts-BljXmaSv.js} +5 -5
  128. package/build/server/chunks/{_server.ts-obpoYMkT.js.map → _server.ts-BljXmaSv.js.map} +1 -1
  129. package/build/server/chunks/{_server.ts-Dz9K1opA.js → _server.ts-Bt-r3Grf.js} +2 -2
  130. package/build/server/chunks/{_server.ts-Dz9K1opA.js.map → _server.ts-Bt-r3Grf.js.map} +1 -1
  131. package/build/server/chunks/{_server.ts-DZRfmoGi.js → _server.ts-C0XDsjcy.js} +5 -5
  132. package/build/server/chunks/{_server.ts-DZRfmoGi.js.map → _server.ts-C0XDsjcy.js.map} +1 -1
  133. package/build/server/chunks/{_server.ts-Dw097UgM.js → _server.ts-C4vWRNJX.js} +6 -6
  134. package/build/server/chunks/{_server.ts-Dw097UgM.js.map → _server.ts-C4vWRNJX.js.map} +1 -1
  135. package/build/server/chunks/{_server.ts-CLyxPJYH.js → _server.ts-C6YNI1Tv.js} +7 -7
  136. package/build/server/chunks/{_server.ts-CLyxPJYH.js.map → _server.ts-C6YNI1Tv.js.map} +1 -1
  137. package/build/server/chunks/{_server.ts-BovyMGvt.js → _server.ts-CBlMaLf5.js} +5 -5
  138. package/build/server/chunks/{_server.ts-BovyMGvt.js.map → _server.ts-CBlMaLf5.js.map} +1 -1
  139. package/build/server/chunks/{_server.ts-Bdqla70P.js → _server.ts-CFL8asTr.js} +7 -7
  140. package/build/server/chunks/{_server.ts-Bdqla70P.js.map → _server.ts-CFL8asTr.js.map} +1 -1
  141. package/build/server/chunks/{_server.ts-CO_U660z.js → _server.ts-CS5kzWGg.js} +5 -5
  142. package/build/server/chunks/{_server.ts-CO_U660z.js.map → _server.ts-CS5kzWGg.js.map} +1 -1
  143. package/build/server/chunks/{_server.ts-D9Y3IzHx.js → _server.ts-CWJTn6Ff.js} +5 -5
  144. package/build/server/chunks/{_server.ts-D9Y3IzHx.js.map → _server.ts-CWJTn6Ff.js.map} +1 -1
  145. package/build/server/chunks/{_server.ts-BHvEZqnA.js → _server.ts-Caiz6sJm.js} +5 -5
  146. package/build/server/chunks/{_server.ts-BHvEZqnA.js.map → _server.ts-Caiz6sJm.js.map} +1 -1
  147. package/build/server/chunks/{_server.ts-CQYWv9O5.js → _server.ts-CdX3k5U5.js} +5 -5
  148. package/build/server/chunks/{_server.ts-CQYWv9O5.js.map → _server.ts-CdX3k5U5.js.map} +1 -1
  149. package/build/server/chunks/{_server.ts-ugrBf-_K.js → _server.ts-Ci0QLJnQ.js} +6 -6
  150. package/build/server/chunks/{_server.ts-ugrBf-_K.js.map → _server.ts-Ci0QLJnQ.js.map} +1 -1
  151. package/build/server/chunks/{_server.ts-C5Fui7KU.js → _server.ts-CiP8l1Sa.js} +5 -5
  152. package/build/server/chunks/{_server.ts-C5Fui7KU.js.map → _server.ts-CiP8l1Sa.js.map} +1 -1
  153. package/build/server/chunks/{_server.ts-BvDEik1n.js → _server.ts-CjAYtVAx.js} +5 -5
  154. package/build/server/chunks/{_server.ts-BvDEik1n.js.map → _server.ts-CjAYtVAx.js.map} +1 -1
  155. package/build/server/chunks/{_server.ts-ycCnkTbD.js → _server.ts-Ckg9v3_D.js} +5 -5
  156. package/build/server/chunks/{_server.ts-ycCnkTbD.js.map → _server.ts-Ckg9v3_D.js.map} +1 -1
  157. package/build/server/chunks/{_server.ts-DXAe7eET.js → _server.ts-CkwC82fu.js} +5 -5
  158. package/build/server/chunks/{_server.ts-DXAe7eET.js.map → _server.ts-CkwC82fu.js.map} +1 -1
  159. package/build/server/chunks/{_server.ts-ibeLW7Y-.js → _server.ts-Cnd_37jS.js} +6 -6
  160. package/build/server/chunks/{_server.ts-ibeLW7Y-.js.map → _server.ts-Cnd_37jS.js.map} +1 -1
  161. package/build/server/chunks/{_server.ts-DwLb4jIl.js → _server.ts-CoSu3PLm.js} +2 -2
  162. package/build/server/chunks/{_server.ts-DwLb4jIl.js.map → _server.ts-CoSu3PLm.js.map} +1 -1
  163. package/build/server/chunks/{_server.ts-DOaP8Y20.js → _server.ts-Cx5hjJpv.js} +5 -5
  164. package/build/server/chunks/{_server.ts-DOaP8Y20.js.map → _server.ts-Cx5hjJpv.js.map} +1 -1
  165. package/build/server/chunks/{_server.ts-OM4ZklQD.js → _server.ts-CxFc3CAv.js} +5 -5
  166. package/build/server/chunks/{_server.ts-OM4ZklQD.js.map → _server.ts-CxFc3CAv.js.map} +1 -1
  167. package/build/server/chunks/{_server.ts-NJaC2I3g.js → _server.ts-D0dqJdkN.js} +5 -5
  168. package/build/server/chunks/{_server.ts-NJaC2I3g.js.map → _server.ts-D0dqJdkN.js.map} +1 -1
  169. package/build/server/chunks/{_server.ts-CqyL7vz2.js → _server.ts-D1UiuaM3.js} +6 -6
  170. package/build/server/chunks/{_server.ts-CqyL7vz2.js.map → _server.ts-D1UiuaM3.js.map} +1 -1
  171. package/build/server/chunks/{_server.ts-CRsmED2U.js → _server.ts-D2kWI_aR.js} +5 -5
  172. package/build/server/chunks/{_server.ts-CRsmED2U.js.map → _server.ts-D2kWI_aR.js.map} +1 -1
  173. package/build/server/chunks/{_server.ts-BPo2TCU6.js → _server.ts-D4W1a6jV.js} +5 -5
  174. package/build/server/chunks/{_server.ts-BPo2TCU6.js.map → _server.ts-D4W1a6jV.js.map} +1 -1
  175. package/build/server/chunks/{_server.ts-ZLZo693J.js → _server.ts-D5iO3X1v.js} +7 -7
  176. package/build/server/chunks/{_server.ts-ZLZo693J.js.map → _server.ts-D5iO3X1v.js.map} +1 -1
  177. package/build/server/chunks/{_server.ts-CtonBh5h.js → _server.ts-D6rSH5_n.js} +6 -6
  178. package/build/server/chunks/{_server.ts-CtonBh5h.js.map → _server.ts-D6rSH5_n.js.map} +1 -1
  179. package/build/server/chunks/{_server.ts-CMVhhoJK.js → _server.ts-DANFbo6B.js} +5 -5
  180. package/build/server/chunks/{_server.ts-CMVhhoJK.js.map → _server.ts-DANFbo6B.js.map} +1 -1
  181. package/build/server/chunks/{_server.ts-CXfsU5eK.js → _server.ts-DEry3Hr_.js} +5 -5
  182. package/build/server/chunks/{_server.ts-CXfsU5eK.js.map → _server.ts-DEry3Hr_.js.map} +1 -1
  183. package/build/server/chunks/{_server.ts-DBI21oJT.js → _server.ts-DHK9NPr2.js} +5 -5
  184. package/build/server/chunks/{_server.ts-DBI21oJT.js.map → _server.ts-DHK9NPr2.js.map} +1 -1
  185. package/build/server/chunks/{_server.ts-6QF3FGWo.js → _server.ts-DIUR6YTG.js} +4 -4
  186. package/build/server/chunks/{_server.ts-6QF3FGWo.js.map → _server.ts-DIUR6YTG.js.map} +1 -1
  187. package/build/server/chunks/{_server.ts-D6fP9ySh.js → _server.ts-DPeazA_L.js} +5 -5
  188. package/build/server/chunks/{_server.ts-D6fP9ySh.js.map → _server.ts-DPeazA_L.js.map} +1 -1
  189. package/build/server/chunks/{_server.ts-BgFywWt1.js → _server.ts-DSX0luxw.js} +5 -5
  190. package/build/server/chunks/{_server.ts-BgFywWt1.js.map → _server.ts-DSX0luxw.js.map} +1 -1
  191. package/build/server/chunks/{_server.ts-DBUsWQ6-.js → _server.ts-DZ5caysY.js} +5 -5
  192. package/build/server/chunks/{_server.ts-DBUsWQ6-.js.map → _server.ts-DZ5caysY.js.map} +1 -1
  193. package/build/server/chunks/{_server.ts-D-EVxcc7.js → _server.ts-D_AYcbCF.js} +5 -5
  194. package/build/server/chunks/{_server.ts-D-EVxcc7.js.map → _server.ts-D_AYcbCF.js.map} +1 -1
  195. package/build/server/chunks/{_server.ts-C1n6oV6E.js → _server.ts-Dbn-y0Gg.js} +5 -5
  196. package/build/server/chunks/{_server.ts-C1n6oV6E.js.map → _server.ts-Dbn-y0Gg.js.map} +1 -1
  197. package/build/server/chunks/{_server.ts-BLSj6qnA.js → _server.ts-DeITkG2o.js} +5 -5
  198. package/build/server/chunks/{_server.ts-BLSj6qnA.js.map → _server.ts-DeITkG2o.js.map} +1 -1
  199. package/build/server/chunks/{_server.ts-Dfc-OGF4.js → _server.ts-DmPmuEMq.js} +6 -6
  200. package/build/server/chunks/{_server.ts-Dfc-OGF4.js.map → _server.ts-DmPmuEMq.js.map} +1 -1
  201. package/build/server/chunks/{_server.ts-CAuvdwNy.js → _server.ts-DnT9CPuc.js} +6 -6
  202. package/build/server/chunks/{_server.ts-CAuvdwNy.js.map → _server.ts-DnT9CPuc.js.map} +1 -1
  203. package/build/server/chunks/{_server.ts-CdRrscyk.js → _server.ts-Enobpqdw.js} +5 -5
  204. package/build/server/chunks/{_server.ts-CdRrscyk.js.map → _server.ts-Enobpqdw.js.map} +1 -1
  205. package/build/server/chunks/{_server.ts-DPQghDKg.js → _server.ts-F_Gi_IcU.js} +5 -5
  206. package/build/server/chunks/{_server.ts-DPQghDKg.js.map → _server.ts-F_Gi_IcU.js.map} +1 -1
  207. package/build/server/chunks/{_server.ts-CLcmdjXI.js → _server.ts-HTqPaCti.js} +5 -5
  208. package/build/server/chunks/{_server.ts-CLcmdjXI.js.map → _server.ts-HTqPaCti.js.map} +1 -1
  209. package/build/server/chunks/{_server.ts-AZlYLuCy.js → _server.ts-HyrISdwf.js} +7 -7
  210. package/build/server/chunks/{_server.ts-AZlYLuCy.js.map → _server.ts-HyrISdwf.js.map} +1 -1
  211. package/build/server/chunks/{_server.ts-46hwSqD_.js → _server.ts-I-sVA1uK.js} +2 -2
  212. package/build/server/chunks/{_server.ts-46hwSqD_.js.map → _server.ts-I-sVA1uK.js.map} +1 -1
  213. package/build/server/chunks/{_server.ts-Ofi-HpSp.js → _server.ts-Iy02SSf8.js} +5 -5
  214. package/build/server/chunks/{_server.ts-Ofi-HpSp.js.map → _server.ts-Iy02SSf8.js.map} +1 -1
  215. package/build/server/chunks/{_server.ts-CSSnS5g9.js → _server.ts-JBws5rUr.js} +5 -5
  216. package/build/server/chunks/{_server.ts-CSSnS5g9.js.map → _server.ts-JBws5rUr.js.map} +1 -1
  217. package/build/server/chunks/{_server.ts-C_DKb8Vx.js → _server.ts-JdhSRHov.js} +2 -2
  218. package/build/server/chunks/{_server.ts-C_DKb8Vx.js.map → _server.ts-JdhSRHov.js.map} +1 -1
  219. package/build/server/chunks/{_server.ts-CHJ16CwB.js → _server.ts-PEeOir0p.js} +5 -5
  220. package/build/server/chunks/{_server.ts-CHJ16CwB.js.map → _server.ts-PEeOir0p.js.map} +1 -1
  221. package/build/server/chunks/{_server.ts-CQn8xidg.js → _server.ts-Q62fH5PS.js} +7 -7
  222. package/build/server/chunks/{_server.ts-CQn8xidg.js.map → _server.ts-Q62fH5PS.js.map} +1 -1
  223. package/build/server/chunks/{_server.ts-CSRasqU5.js → _server.ts-VX3J9sTd.js} +5 -5
  224. package/build/server/chunks/{_server.ts-CSRasqU5.js.map → _server.ts-VX3J9sTd.js.map} +1 -1
  225. package/build/server/chunks/{_server.ts-Ce36M1g-.js → _server.ts-W3-ZEGZ_.js} +5 -5
  226. package/build/server/chunks/{_server.ts-Ce36M1g-.js.map → _server.ts-W3-ZEGZ_.js.map} +1 -1
  227. package/build/server/chunks/{_server.ts-B9mgPHqQ.js → _server.ts-_ShpDwBa.js} +5 -5
  228. package/build/server/chunks/{_server.ts-B9mgPHqQ.js.map → _server.ts-_ShpDwBa.js.map} +1 -1
  229. package/build/server/chunks/{_server.ts-CNDEmrr2.js → _server.ts-agywTtcx.js} +6 -6
  230. package/build/server/chunks/{_server.ts-CNDEmrr2.js.map → _server.ts-agywTtcx.js.map} +1 -1
  231. package/build/server/chunks/{_server.ts-kE33aWoB.js → _server.ts-dwFtRXqR.js} +5 -5
  232. package/build/server/chunks/{_server.ts-kE33aWoB.js.map → _server.ts-dwFtRXqR.js.map} +1 -1
  233. package/build/server/chunks/{_server.ts-CqECufvr.js → _server.ts-erYwMN1g.js} +5 -5
  234. package/build/server/chunks/{_server.ts-CqECufvr.js.map → _server.ts-erYwMN1g.js.map} +1 -1
  235. package/build/server/chunks/{_server.ts-BhnyI1Jn.js → _server.ts-iFCSUye9.js} +5 -5
  236. package/build/server/chunks/{_server.ts-BhnyI1Jn.js.map → _server.ts-iFCSUye9.js.map} +1 -1
  237. package/build/server/chunks/{_server.ts-C4IOj12k.js → _server.ts-pFKjfZtt.js} +5 -5
  238. package/build/server/chunks/{_server.ts-C4IOj12k.js.map → _server.ts-pFKjfZtt.js.map} +1 -1
  239. package/build/server/chunks/{_server.ts-6UyMAs0y.js → _server.ts-t7vSQWlK.js} +5 -5
  240. package/build/server/chunks/{_server.ts-6UyMAs0y.js.map → _server.ts-t7vSQWlK.js.map} +1 -1
  241. package/build/server/chunks/{_server.ts-BRSKijcN.js → _server.ts-yjvGciT8.js} +7 -7
  242. package/build/server/chunks/{_server.ts-BRSKijcN.js.map → _server.ts-yjvGciT8.js.map} +1 -1
  243. package/build/server/chunks/{addon-helpers-y3PhPhjF.js → addon-helpers-D7yTgW15.js} +3 -3
  244. package/build/server/chunks/{addon-helpers-y3PhPhjF.js.map → addon-helpers-D7yTgW15.js.map} +1 -1
  245. package/build/server/chunks/{akm-fhbqQJKw.js → akm-D65Qa_U3.js} +2 -2
  246. package/build/server/chunks/{akm-fhbqQJKw.js.map → akm-D65Qa_U3.js.map} +1 -1
  247. package/build/server/chunks/{catalog-CD8wG5gx.js → catalog-BcvIrLCV.js} +5 -5
  248. package/build/server/chunks/{catalog-CD8wG5gx.js.map → catalog-BcvIrLCV.js.map} +1 -1
  249. package/build/server/chunks/{client-HkB3w6k1.js → client-COgKxKys.js} +2 -2
  250. package/build/server/chunks/{client-HkB3w6k1.js.map → client-COgKxKys.js.map} +1 -1
  251. package/build/server/chunks/{config-DnNL_Cz3.js → config-CmjX1hzp.js} +2 -2
  252. package/build/server/chunks/{config-DnNL_Cz3.js.map → config-CmjX1hzp.js.map} +1 -1
  253. package/build/server/chunks/{docker-CftpodUq.js → docker-BrVyK6wt.js} +2 -2
  254. package/build/server/chunks/{docker-CftpodUq.js.map → docker-BrVyK6wt.js.map} +1 -1
  255. package/build/server/chunks/{endpoints-BqhAgS3U.js → endpoints-q4yFkst-.js} +2 -2
  256. package/build/server/chunks/{endpoints-BqhAgS3U.js.map → endpoints-q4yFkst-.js.map} +1 -1
  257. package/build/server/chunks/environment-DqfL567G.js.map +1 -1
  258. package/build/server/chunks/{error.svelte-CtaML9ue.js → error.svelte-pZy9q9Ut.js} +4 -4
  259. package/build/server/chunks/{error.svelte-CtaML9ue.js.map → error.svelte-pZy9q9Ut.js.map} +1 -1
  260. package/build/server/chunks/{helpers-DHXJuxQH.js → helpers-Bl9_H-9s.js} +3 -3
  261. package/build/server/chunks/{helpers-DHXJuxQH.js.map → helpers-Bl9_H-9s.js.map} +1 -1
  262. package/build/server/chunks/{hooks.server-TGfRTd4u.js → hooks.server-DYcQEFvC.js} +6 -6
  263. package/build/server/chunks/{hooks.server-TGfRTd4u.js.map → hooks.server-DYcQEFvC.js.map} +1 -1
  264. package/build/server/chunks/{http-Dk1LCCLh.js → http-D4xHnLe9.js} +2 -2
  265. package/build/server/chunks/{http-Dk1LCCLh.js.map → http-D4xHnLe9.js.map} +1 -1
  266. package/build/server/chunks/{internal-Coz5zGZi.js → internal-DtseYMvl.js} +3 -3
  267. package/build/server/chunks/{internal-Coz5zGZi.js.map → internal-DtseYMvl.js.map} +1 -1
  268. package/build/server/chunks/{paths-DlWaDQW-.js → paths-DlPDtu3K.js} +2 -2
  269. package/build/server/chunks/{paths-DlWaDQW-.js.map → paths-DlPDtu3K.js.map} +1 -1
  270. package/build/server/chunks/{session-cookie-DBwsReGQ.js → session-cookie-B4lO_HPo.js} +2 -2
  271. package/build/server/chunks/{session-cookie-DBwsReGQ.js.map → session-cookie-B4lO_HPo.js.map} +1 -1
  272. package/build/server/chunks/{setup-deploy-CJmxiknj.js → setup-deploy-MOec0Pr9.js} +2 -2
  273. package/build/server/chunks/{setup-deploy-CJmxiknj.js.map → setup-deploy-MOec0Pr9.js.map} +1 -1
  274. package/build/server/chunks/{src-CKB0Ceqf.js → src-DkOWabOs.js} +7 -18
  275. package/build/server/chunks/src-DkOWabOs.js.map +1 -0
  276. package/build/server/chunks/{state-DgtI8baj.js → state-B9EFWmO3.js} +2 -2
  277. package/build/server/chunks/{state-DgtI8baj.js.map → state-B9EFWmO3.js.map} +1 -1
  278. package/build/server/chunks/{state2-CkQSe6ll.js → state2-BpiowCb1.js} +2 -2
  279. package/build/server/chunks/{state2-CkQSe6ll.js.map → state2-BpiowCb1.js.map} +1 -1
  280. package/build/server/index.js +1 -1
  281. package/build/server/manifest.js +91 -91
  282. package/build/server/manifest.js.map +1 -1
  283. package/package.json +2 -2
  284. package/build/client/_app/immutable/chunks/Bp6-ciNE.js.br +0 -0
  285. package/build/client/_app/immutable/chunks/Bp6-ciNE.js.gz +0 -0
  286. package/build/client/_app/immutable/chunks/CQMT6iK8.js.br +0 -0
  287. package/build/client/_app/immutable/chunks/CQMT6iK8.js.gz +0 -0
  288. package/build/client/_app/immutable/chunks/DHoslhhP.js +0 -1
  289. package/build/client/_app/immutable/chunks/DHoslhhP.js.br +0 -2
  290. package/build/client/_app/immutable/chunks/DHoslhhP.js.gz +0 -0
  291. package/build/client/_app/immutable/chunks/Oapx3Kay.js.br +0 -0
  292. package/build/client/_app/immutable/chunks/Oapx3Kay.js.gz +0 -0
  293. package/build/client/_app/immutable/entry/app.CSv5ANTj.js.br +0 -0
  294. package/build/client/_app/immutable/entry/app.CSv5ANTj.js.gz +0 -0
  295. package/build/client/_app/immutable/entry/start.Rl8gGhka.js +0 -1
  296. package/build/client/_app/immutable/entry/start.Rl8gGhka.js.br +0 -0
  297. package/build/client/_app/immutable/entry/start.Rl8gGhka.js.gz +0 -0
  298. package/build/client/_app/immutable/nodes/1.BgfOb4Io.js.br +0 -1
  299. package/build/client/_app/immutable/nodes/1.BgfOb4Io.js.gz +0 -0
  300. package/build/client/_app/immutable/nodes/10.v7TDafkp.js.br +0 -0
  301. package/build/client/_app/immutable/nodes/10.v7TDafkp.js.gz +0 -0
  302. package/build/client/_app/immutable/nodes/4.BlGWSYpW.js.br +0 -0
  303. package/build/client/_app/immutable/nodes/5.C4R8b_rk.js.br +0 -0
  304. package/build/client/_app/immutable/nodes/5.C4R8b_rk.js.gz +0 -0
  305. package/build/client/_app/immutable/nodes/6.jkaKXnUx.js.br +0 -0
  306. package/build/client/_app/immutable/nodes/6.jkaKXnUx.js.gz +0 -0
  307. package/build/client/_app/immutable/nodes/7.BUnJYUcB.js.br +0 -0
  308. package/build/client/_app/immutable/nodes/7.BUnJYUcB.js.gz +0 -0
  309. package/build/client/_app/immutable/nodes/8.BFS_N1wx.js.br +0 -0
  310. package/build/client/_app/immutable/nodes/8.BFS_N1wx.js.gz +0 -0
  311. package/build/client/_app/immutable/nodes/9.CskAvBGO.js.br +0 -0
  312. package/build/client/_app/immutable/nodes/9.CskAvBGO.js.gz +0 -0
  313. package/build/server/chunks/1-lLcx9Qz5.js +0 -9
  314. package/build/server/chunks/src-CKB0Ceqf.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"_page.svelte-CXlwalNt.js","sources":["../../../.svelte-kit/adapter-node/entries/pages/setup/_page.svelte.js"],"sourcesContent":["import { $ as run, U as escape_html, V as attr, a as derived, n as attr_class, o as ensure_array_like, r as attr_style, s as head, u as stringify } from \"../../../chunks/dev.js\";\nimport \"../../../chunks/index-server.js\";\nimport { a as addonProfileId, n as OLLAMA_DEFAULT_CHAT_MODEL, t as KNOWN_EMBEDDING_MODEL_DIMS } from \"../../../chunks/provider-constants.js\";\nimport { t as resolve } from \"../../../chunks/paths.js\";\nimport \"../../../chunks/IconServer.js\";\nimport { t as Spinner } from \"../../../chunks/Spinner.js\";\nimport { t as IconMic } from \"../../../chunks/IconMic.js\";\nimport { t as IconLogo } from \"../../../chunks/IconLogo.js\";\nimport { n as IconAgent, t as IconAlert } from \"../../../chunks/IconAlert.js\";\n//#region src/lib/client/constants.ts\nvar PROVIDERS = [\n\t{\n\t\tid: \"ollama\",\n\t\tname: \"Ollama\",\n\t\tkind: \"local\",\n\t\tgroup: \"recommended\",\n\t\torder: 1,\n\t\ticon: \"🦙\",\n\t\tdesc: \"Run open models on your hardware\",\n\t\tneedsKey: false,\n\t\tplaceholder: \"\",\n\t\tbaseUrl: \"http://localhost:11434\",\n\t\tllmModel: \"llama3.2\",\n\t\tembModel: \"nomic-embed-text\",\n\t\tembDims: 768,\n\t\tcanDetect: true\n\t},\n\t{\n\t\tid: \"huggingface\",\n\t\tname: \"Hugging Face\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"recommended\",\n\t\torder: 2,\n\t\ticon: \"🤗\",\n\t\tdesc: \"10,000+ open models via Inference Providers\",\n\t\tneedsKey: true,\n\t\tplaceholder: \"hf_...\",\n\t\tbaseUrl: \"https://router.huggingface.co/v1\",\n\t\tllmModel: \"Qwen/Qwen3-32B\",\n\t\tembModel: \"intfloat/multilingual-e5-large\",\n\t\tembDims: 1024,\n\t\tkeyPrefix: \"hf_\"\n\t},\n\t{\n\t\tid: \"openai\",\n\t\tname: \"OpenAI\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"recommended\",\n\t\torder: 3,\n\t\ticon: \"◐\",\n\t\tdesc: \"GPT and o-series reasoning models\",\n\t\tneedsKey: true,\n\t\tplaceholder: \"sk-...\",\n\t\tbaseUrl: \"https://api.openai.com\",\n\t\tllmModel: \"gpt-4o\",\n\t\tembModel: \"text-embedding-3-small\",\n\t\tembDims: 1536\n\t},\n\t{\n\t\tid: \"google\",\n\t\tname: \"Google\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"recommended\",\n\t\torder: 4,\n\t\ticon: \"◆\",\n\t\tdesc: \"Gemini models with large context\",\n\t\tneedsKey: true,\n\t\tplaceholder: \"AIza...\",\n\t\tbaseUrl: \"https://generativelanguage.googleapis.com\",\n\t\tllmModel: \"gemini-2.5-flash\",\n\t\tembModel: \"\",\n\t\tembDims: 0,\n\t\tkeyPrefix: \"AI\"\n\t},\n\t{\n\t\tid: \"model-runner\",\n\t\tname: \"Docker Model Runner\",\n\t\tkind: \"local\",\n\t\tgroup: \"local\",\n\t\torder: 1,\n\t\ticon: \"🐳\",\n\t\tdesc: \"Docker-managed model runtime\",\n\t\tneedsKey: false,\n\t\tplaceholder: \"\",\n\t\tbaseUrl: \"http://localhost:12434\",\n\t\tllmModel: \"ai/llama3.2\",\n\t\tembModel: \"ai/mxbai-embed-large-v1\",\n\t\tembDims: 1024,\n\t\tcanDetect: true\n\t},\n\t{\n\t\tid: \"lmstudio\",\n\t\tname: \"LM Studio\",\n\t\tkind: \"local\",\n\t\tgroup: \"local\",\n\t\torder: 2,\n\t\ticon: \"🔬\",\n\t\tdesc: \"Desktop app for local inference\",\n\t\tneedsKey: false,\n\t\tplaceholder: \"\",\n\t\tbaseUrl: \"http://localhost:1234\",\n\t\tllmModel: \"loaded-model\",\n\t\tembModel: \"\",\n\t\tembDims: 0,\n\t\tcanDetect: true\n\t},\n\t{\n\t\tid: \"groq\",\n\t\tname: \"Groq\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"cloud\",\n\t\torder: 1,\n\t\ticon: \"⚡\",\n\t\tdesc: \"Ultra-fast inference\",\n\t\tneedsKey: true,\n\t\tplaceholder: \"gsk_...\",\n\t\tbaseUrl: \"https://api.groq.com/openai\",\n\t\tllmModel: \"llama-3.3-70b-versatile\",\n\t\tembModel: \"\",\n\t\tembDims: 0\n\t},\n\t{\n\t\tid: \"mistral\",\n\t\tname: \"Mistral\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"cloud\",\n\t\torder: 2,\n\t\ticon: \"◆\",\n\t\tdesc: \"Mistral & Codestral models\",\n\t\tneedsKey: true,\n\t\tplaceholder: \"...\",\n\t\tbaseUrl: \"https://api.mistral.ai\",\n\t\tllmModel: \"mistral-large-latest\",\n\t\tembModel: \"mistral-embed\",\n\t\tembDims: 1024\n\t},\n\t{\n\t\tid: \"together\",\n\t\tname: \"Together AI\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"cloud\",\n\t\torder: 3,\n\t\ticon: \"✦\",\n\t\tdesc: \"Open models at scale\",\n\t\tneedsKey: true,\n\t\tplaceholder: \"...\",\n\t\tbaseUrl: \"https://api.together.xyz\",\n\t\tllmModel: \"meta-llama/Llama-3.3-70B-Instruct-Turbo\",\n\t\tembModel: \"\",\n\t\tembDims: 0\n\t},\n\t{\n\t\tid: \"deepseek\",\n\t\tname: \"DeepSeek\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"advanced\",\n\t\torder: 1,\n\t\ticon: \"◎\",\n\t\tdesc: \"DeepSeek chat & reasoning\",\n\t\tneedsKey: true,\n\t\tplaceholder: \"sk-...\",\n\t\tbaseUrl: \"https://api.deepseek.com\",\n\t\tllmModel: \"deepseek-chat\",\n\t\tembModel: \"\",\n\t\tembDims: 0\n\t},\n\t{\n\t\tid: \"xai\",\n\t\tname: \"xAI (Grok)\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"advanced\",\n\t\torder: 2,\n\t\ticon: \"✦\",\n\t\tdesc: \"Grok models\",\n\t\tneedsKey: true,\n\t\tplaceholder: \"xai-...\",\n\t\tbaseUrl: \"https://api.x.ai\",\n\t\tllmModel: \"grok-2\",\n\t\tembModel: \"\",\n\t\tembDims: 0\n\t},\n\t{\n\t\tid: \"openai-compatible\",\n\t\tname: \"Custom API server\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"advanced\",\n\t\torder: 3,\n\t\ticon: \"~\",\n\t\tdesc: \"Connect any AI server that uses the standard OpenAI API format.\",\n\t\tneedsKey: false,\n\t\tneedsUrl: true,\n\t\toptionalKey: true,\n\t\tplaceholder: \"API key (optional)\",\n\t\tbaseUrl: \"\",\n\t\tllmModel: \"\",\n\t\tembModel: \"\",\n\t\tembDims: 0\n\t}\n];\n/** Provider IDs excluded from the setup wizard's OAuth provider list. */\nvar WIZARD_EXCLUDED_PROVIDERS = new Set([\"anthropic\"]);\nvar PORTALS = [\n\t{\n\t\tid: \"api\",\n\t\tname: \"API\",\n\t\ticon: \"🔌\",\n\t\tdesc: \"OpenAI-compatible REST API endpoint\",\n\t\tlocked: true\n\t},\n\t{\n\t\tid: \"discord\",\n\t\tname: \"Discord\",\n\t\ticon: \"🎮\",\n\t\tdesc: \"Connect to a Discord server\",\n\t\tcredentials: [{\n\t\t\tkey: \"botToken\",\n\t\t\tlabel: \"Bot Token\",\n\t\t\tplaceholder: \"Paste Discord bot token\",\n\t\t\trequired: true\n\t\t}, {\n\t\t\tkey: \"applicationId\",\n\t\t\tlabel: \"Application ID\",\n\t\t\tplaceholder: \"Discord application ID\",\n\t\t\tsecret: false\n\t\t}]\n\t},\n\t{\n\t\tid: \"slack\",\n\t\tname: \"Slack\",\n\t\ticon: \"💼\",\n\t\tdesc: \"Access via Slack bot\",\n\t\tcredentials: [{\n\t\t\tkey: \"slackBotToken\",\n\t\t\tlabel: \"Bot Token\",\n\t\t\tplaceholder: \"xoxb-...\",\n\t\t\trequired: true\n\t\t}, {\n\t\t\tkey: \"slackAppToken\",\n\t\t\tlabel: \"App Token\",\n\t\t\tplaceholder: \"xapp-...\",\n\t\t\trequired: true\n\t\t}]\n\t}\n];\n//#endregion\n//#region src/lib/client/helpers.ts\nfunction selectAddonProfileId(profiles, addon, gpuDetected, variant) {\n\tconst avail = (p) => p.available !== false;\n\tconst preferred = addonProfileId(addon, variant ?? (gpuDetected ? \"cuda\" : \"cpu\"));\n\tconst cpu = addonProfileId(addon, \"cpu\");\n\treturn (profiles.find((p) => p.id === preferred && avail(p)) ?? profiles.find((p) => p.default && avail(p)) ?? profiles.find((p) => p.id === cpu && avail(p)) ?? profiles.find((p) => avail(p)))?.id;\n}\n/** Strip an Ollama-style \":tag\" suffix so \"llama3.2\" matches \"llama3.2:latest\". */\nfunction baseModelId(model) {\n\treturn model.replace(/:.*$/, \"\");\n}\n/** True for embedding models — never offered/auto-picked for the chat/small role. */\nfunction isEmbeddingModelId(model) {\n\tconst base = baseModelId(model);\n\tif (KNOWN_EMBEDDING_MODEL_DIMS[model] !== void 0 || KNOWN_EMBEDDING_MODEL_DIMS[base] !== void 0) return true;\n\treturn /(?:^|[-/_.])(embed|embedding|bge|gte|e5|nomic|mxbai|arctic-embed|minilm)/i.test(model);\n}\n/** Heuristic score for a chat ('llm') or 'small' model. Higher = better default. */\nfunction scoreModelForRole(roleId, model) {\n\tconst m = model.toLowerCase();\n\tlet s = 0;\n\tif (/instruct|chat|-it\\b|\\bit\\b/.test(m)) s += 30;\n\tif (/coder|code/.test(m)) s += 8;\n\tconst sizeMatch = m.match(/(\\d+(?:\\.\\d+)?)\\s*x?\\s*b\\b/);\n\tconst sizeB = sizeMatch ? parseFloat(sizeMatch[1]) : 0;\n\tif (roleId === \"llm\") s += Math.min(40, sizeB);\n\telse s += Math.max(0, 20 - Math.min(20, sizeB));\n\treturn s;\n}\nvar LOCAL_PROVIDER_IDS = new Set([\n\t\"ollama\",\n\t\"lmstudio\",\n\t\"model-runner\"\n]);\n/**\n* Build the ranked list of model options for a role across all verified\n* providers. For chat/small: embedding models are excluded and results are\n* ordered best-first (host/cloud before local, provider's declared default,\n* then the role heuristic) so options[0] is the sensible auto-pick. For\n* embedding: only real embedding models are returned (may be empty — akm\n* self-embeds locally, so an empty list is fine and the role is auto-handled).\n*/\nfunction buildModelOptions(roleId, verifiedProviders, providerState) {\n\tconst options = [];\n\tfor (const p of verifiedProviders) {\n\t\tconst st = providerState[p.id];\n\t\tif (!st) continue;\n\t\tconst defaultModel = roleId === \"embedding\" ? p.embModel : p.llmModel;\n\t\tconst models = st.models.length > 0 ? st.models : [];\n\t\tconst matchedDefault = defaultModel ? models.find((m) => m === defaultModel || baseModelId(m) === baseModelId(defaultModel)) : void 0;\n\t\tfor (const m of models) {\n\t\t\tif (roleId !== \"embedding\" && isEmbeddingModelId(m)) continue;\n\t\t\tconst dims = roleId === \"embedding\" ? KNOWN_EMBEDDING_MODEL_DIMS[m] ?? KNOWN_EMBEDDING_MODEL_DIMS[baseModelId(m)] ?? (m === matchedDefault ? p.embDims : 0) ?? 0 : 0;\n\t\t\toptions.push({\n\t\t\t\tid: m,\n\t\t\t\tconnId: p.id,\n\t\t\t\tproviderName: p.name,\n\t\t\t\tbaseUrl: st.baseUrl || p.baseUrl,\n\t\t\t\tisDefault: m === matchedDefault,\n\t\t\t\tdims\n\t\t\t});\n\t\t}\n\t}\n\tif (roleId === \"embedding\") return options.filter((o) => o.isDefault || o.dims > 0);\n\treturn options.sort((a, b) => (LOCAL_PROVIDER_IDS.has(a.connId) ? 1 : 0) - (LOCAL_PROVIDER_IDS.has(b.connId) ? 1 : 0) || (b.isDefault ? 1 : 0) - (a.isDefault ? 1 : 0) || scoreModelForRole(roleId, b.id) - scoreModelForRole(roleId, a.id));\n}\n/**\n* Resolve which voice engine to use for one side (TTS or STT).\n*\n* - An explicit engine in `side` wins unconditionally.\n* - No explicit engine + bundled voice enabled → openpalm-voice.\n* - No explicit engine + bundled voice off → fallback engine (e.g. 'browser-tts').\n*\n* Pass fallbackEngine='' for the \"persisted\" form (nothing saved when untouched).\n* Pass a concrete fallback for the \"displayed\" form so the UI shows the real default.\n*/\nfunction resolveVoiceSide(side, enableVoice, fallbackEngine) {\n\tif (side.engine) return side;\n\tif (enableVoice) return { engine: \"openpalm-voice\" };\n\treturn { engine: fallbackEngine };\n}\nfunction isPortalEnabled(portalSelection, chId, locked) {\n\tif (locked) return true;\n\tconst sel = portalSelection[chId];\n\tif (typeof sel === \"object\" && sel !== null) return sel.enabled;\n\treturn !!sel;\n}\nfunction getCredValue(portalSelection, chId, key) {\n\tconst sel = portalSelection[chId];\n\tif (typeof sel === \"object\" && sel !== null) return String(sel[key] ?? \"\");\n\treturn \"\";\n}\n//#endregion\n//#region src/lib/components/common/FriendlyError.svelte\nfunction FriendlyError($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t/** Render compactly without the technical-details disclosure (inline forms). */\n\t\tlet { error, role = \"alert\", compact = false } = $$props;\n\t\tif (error) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"friendly-error svelte-iqsgzf\"${attr(\"role\", role)}><div class=\"friendly-error-header svelte-iqsgzf\">`);\n\t\t\tIconAlert($$renderer, { size: 18 });\n\t\t\t$$renderer.push(`<!----> <strong class=\"friendly-error-title svelte-iqsgzf\">${escape_html(error.title)}</strong></div> `);\n\t\t\tif (error.body) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<p class=\"friendly-error-body svelte-iqsgzf\">${escape_html(error.body)}</p>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\tif (error.hint) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<p class=\"friendly-error-hint svelte-iqsgzf\">${escape_html(error.hint)}</p>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\tif (error.links && error.links.length > 0) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<div class=\"friendly-error-links svelte-iqsgzf\"><!--[-->`);\n\t\t\t\tconst each_array = ensure_array_like(error.links);\n\t\t\t\tfor (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {\n\t\t\t\t\tlet link = each_array[$$index];\n\t\t\t\t\t$$renderer.push(`<a${attr(\"href\", link.href)} target=\"_blank\" rel=\"noopener noreferrer\" class=\"friendly-error-link svelte-iqsgzf\">${escape_html(link.label)} →</a>`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]--></div>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\tif (!compact && error.raw && error.raw !== error.body) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<details class=\"friendly-error-details svelte-iqsgzf\"><summary class=\"svelte-iqsgzf\">Technical details</summary> <pre class=\"svelte-iqsgzf\">${escape_html(error.raw)}</pre></details>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]-->`);\n\t});\n}\n//#endregion\n//#region src/lib/client/error-messages.ts\nvar DOCKER_LINK = {\n\tlabel: \"Docker setup\",\n\thref: \"https://docs.docker.com/get-docker/\"\n};\nfunction rawText(raw) {\n\tif (!raw) return \"\";\n\tif (raw instanceof Error) return raw.message;\n\tif (typeof raw === \"string\") return raw;\n\ttry {\n\t\treturn JSON.stringify(raw);\n\t} catch {\n\t\treturn String(raw);\n\t}\n}\nfunction friendlyError(raw, context = \"generic\", opts = {}) {\n\tconst text = rawText(raw);\n\tconst lower = text.toLowerCase();\n\tconst providerLabel = opts.providerName ? `${opts.providerName} didn't accept that key` : \"API key rejected\";\n\tif (/\\b(401|403|unauthorized|forbidden|invalid.?api.?key)\\b/i.test(text)) return {\n\t\ttitle: providerLabel,\n\t\tbody: \"The provider rejected the API key.\",\n\t\thint: \"Common causes: extra spaces, wrong account, or the key was revoked. Double-check the key and that it has access to the model you selected. Most providers show the key in their dashboard.\",\n\t\traw: text\n\t};\n\tif (/\\b(ENOTFOUND|ECONNREFUSED|getaddrinfo|EAI_AGAIN|EHOSTUNREACH)\\b/i.test(text)) return {\n\t\ttitle: \"Couldn't reach the host\",\n\t\tbody: text,\n\t\thint: \"Confirm the URL is correct and the service is online. For local providers (Ollama, LM Studio) make sure the server is running on this machine.\",\n\t\traw: text\n\t};\n\tif (/(timeout|timed out|AbortError|ETIMEDOUT)/i.test(text)) return {\n\t\ttitle: \"Request timed out\",\n\t\tbody: \"The provider didn't respond in time.\",\n\t\thint: \"It may be slow or temporarily down. Try again in a moment.\",\n\t\traw: text\n\t};\n\tif (lower.includes(\"docker\") || lower.includes(\"compose\") || lower.includes(\"daemon\")) return {\n\t\ttitle: \"Docker isn't available\",\n\t\tbody: \"OpenPalm needs Docker (with Compose v2) installed and running.\",\n\t\thint: \"Start Docker Desktop (macOS/Windows) or the docker daemon (Linux), then retry.\",\n\t\tlinks: [DOCKER_LINK],\n\t\traw: text\n\t};\n\tif (/EADDRINUSE/i.test(text) || /port.*in.?use/i.test(lower)) return {\n\t\ttitle: \"A required port is already in use\",\n\t\tbody: text,\n\t\thint: \"Another program is using one of OpenPalm's default ports. Quit the conflicting app, or change OpenPalm's port from the Admin Dashboard after setup.\",\n\t\traw: text\n\t};\n\tif (/EACCES|EPERM|permission denied/i.test(text)) return {\n\t\ttitle: \"Permission denied\",\n\t\tbody: text,\n\t\thint: \"OpenPalm couldn't write to its data directory. Check that ~/.openpalm/ is writable by your user.\",\n\t\traw: text\n\t};\n\tswitch (context) {\n\t\tcase \"provider-verify\":\n\t\tcase \"model-fetch\": return {\n\t\t\ttitle: \"Couldn't connect to the provider\",\n\t\t\tbody: text || \"Verification failed.\",\n\t\t\thint: \"Check the API key and base URL, then click Verify again.\",\n\t\t\traw: text\n\t\t};\n\t\tcase \"setup-complete\": return {\n\t\t\ttitle: \"Setup couldn't finish\",\n\t\t\tbody: text || \"Writing configuration failed.\",\n\t\t\thint: \"Check the technical details below, then retry. If the issue persists, the admin dashboard logs may help.\",\n\t\t\traw: text\n\t\t};\n\t\tcase \"deploy\":\n\t\tcase \"deploy-poll\": return {\n\t\t\ttitle: \"Deployment ran into a problem\",\n\t\t\tbody: text || \"One or more services failed to start.\",\n\t\t\thint: \"Image pulls can take several minutes on first install. Retry to attempt again; check Docker logs if it keeps failing.\",\n\t\t\traw: text\n\t\t};\n\t\tcase \"system-check\": return {\n\t\t\ttitle: \"System check failed\",\n\t\t\tbody: text || \"A required dependency is missing.\",\n\t\t\thint: \"Resolve the failing check above, then click Retry.\",\n\t\t\traw: text\n\t\t};\n\t\tcase \"portal\": return {\n\t\t\ttitle: \"Portal credential issue\",\n\t\t\tbody: text || \"A required field is missing or invalid.\",\n\t\t\thint: \"Confirm the bot token and other required fields are correct.\",\n\t\t\traw: text\n\t\t};\n\t\tcase \"port-conflict\": return {\n\t\t\ttitle: \"A required port is already in use\",\n\t\t\tbody: text || \"Another process is using one of OpenPalm's ports.\",\n\t\t\thint: \"Another program is using one of OpenPalm's default ports. Quit the conflicting app, or change OpenPalm's port from the Admin Dashboard after setup.\",\n\t\t\traw: text\n\t\t};\n\t\tdefault: return {\n\t\t\ttitle: \"Something went wrong\",\n\t\t\tbody: text || \"An unexpected error occurred.\",\n\t\t\thint: \"Try again. If the problem persists, check the admin dashboard logs.\",\n\t\t\traw: text\n\t\t};\n\t}\n}\n//#endregion\n//#region src/routes/setup/steps/SystemCheckStep.svelte\nfunction SystemCheckStep($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\tnew Set([\n\t\t\t\"ollama\",\n\t\t\t\"lmstudio\",\n\t\t\t\"model-runner\"\n\t\t]);\n\t\t/** True when re-running an existing install; suppresses misleading\n\t\t* port-conflict warnings that just reflect the running stack itself. */\n\t\tlet { onnext, onpass, ongpudetected, isRerun = false } = $$props;\n\t\tlet loading = true;\n\t\tlet result = null;\n\t\tconst portConflicts = derived(() => isRerun ? [] : []);\n\t\tconst blockingPortConflicts = derived(() => portConflicts().filter((p) => p.blocking));\n\t\tderived(() => blockingPortConflicts().length > 0);\n\t\tderived(() => false);\n\t\t$$renderer.push(`<h2>System Check</h2> <p class=\"step-description\">Let's make sure your machine has everything OpenPalm needs.</p> `);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> <div class=\"syscheck-list svelte-1txhq2p\" aria-live=\"polite\"><div${attr_class(\"syscheck-row svelte-1txhq2p\", void 0, {\n\t\t\t\"syscheck-row--ok\": void 0,\n\t\t\t\"syscheck-row--fail\": result\n\t\t})}><div class=\"syscheck-icon svelte-1txhq2p\">`);\n\t\t$$renderer.push(\"<!--[0-->\");\n\t\tSpinner($$renderer, { size: 16 });\n\t\t$$renderer.push(`<!--]--></div> <div class=\"syscheck-body svelte-1txhq2p\"><div class=\"syscheck-title svelte-1txhq2p\">Docker is installed and running</div> `);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--></div></div> <div${attr_class(\"syscheck-row svelte-1txhq2p\", void 0, {\n\t\t\t\"syscheck-row--ok\": void 0,\n\t\t\t\"syscheck-row--fail\": result\n\t\t})}><div class=\"syscheck-icon svelte-1txhq2p\">`);\n\t\t$$renderer.push(\"<!--[0-->\");\n\t\tSpinner($$renderer, { size: 16 });\n\t\t$$renderer.push(`<!--]--></div> <div class=\"syscheck-body svelte-1txhq2p\"><div class=\"syscheck-title svelte-1txhq2p\">Docker can run multi-container apps</div> `);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--></div></div> `);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--></div> <div class=\"step-actions\"><button class=\"btn btn-secondary\" id=\"btn-syscheck-retry\"${attr(\"disabled\", loading, true)}>${escape_html(\"Checking…\")}</button> <button class=\"btn btn-primary\" id=\"btn-syscheck-next\"${attr(\"disabled\", loading, true)}>Continue</button></div>`);\n\t});\n}\n//#endregion\n//#region src/routes/setup/steps/ProviderOAuthList.svelte\nfunction ProviderOAuthList($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t/**\n\t\t* ProviderOAuthList — OAuth provider list for CloudAttachPanel.\n\t\t*\n\t\t* Renders a compact vertical list of OAuth-capable providers,\n\t\t* filtered through WIZARD_EXCLUDED_PROVIDERS (no Anthropic).\n\t\t*\n\t\t* Props:\n\t\t* opencodeProviders — full list from /api/setup/recommend\n\t\t* opencodeAuth — auth methods per provider id\n\t\t* providerState — current verification state per provider id\n\t\t* onoauthstart — called when the user clicks \"Sign in\" for a provider\n\t\t* onoauthcancel — called when OAuth poll should be aborted\n\t\t*/\n\t\tlet { opencodeProviders, opencodeAuth, providerState, onoauthstart, onoauthcancel } = $$props;\n\t\tconst RECOGNIZABLE_FIRST = [\n\t\t\t\"openai\",\n\t\t\t\"google\",\n\t\t\t\"github-copilot\",\n\t\t\t\"groq\",\n\t\t\t\"mistral\",\n\t\t\t\"huggingface\"\n\t\t];\n\t\tconst filteredProviders = derived(() => opencodeProviders.filter((p) => {\n\t\t\tif (WIZARD_EXCLUDED_PROVIDERS.has(p.id)) return false;\n\t\t\tif (providerState[p.id]?.verified) return false;\n\t\t\treturn (opencodeAuth[p.id] ?? []).some((m) => m.type === \"oauth\");\n\t\t}).sort((a, b) => {\n\t\t\tconst ia = RECOGNIZABLE_FIRST.indexOf(a.id);\n\t\t\tconst ib = RECOGNIZABLE_FIRST.indexOf(b.id);\n\t\t\treturn (ia === -1 ? 99 : ia) - (ib === -1 ? 99 : ib);\n\t\t}));\n\t\tconst OAUTH_CAP = 4;\n\t\tconst visibleOauth = derived(() => filteredProviders().slice(0, OAUTH_CAP));\n\t\tconst hiddenOauthCount = derived(() => Math.max(0, filteredProviders().length - OAUTH_CAP));\n\t\tfunction getState(id) {\n\t\t\treturn providerState[id] ?? {\n\t\t\t\tselected: false,\n\t\t\t\tverified: false,\n\t\t\t\tverifying: false,\n\t\t\t\terror: false,\n\t\t\t\tapiKey: \"\",\n\t\t\t\tbaseUrl: \"\",\n\t\t\t\tmodels: [],\n\t\t\t\tollamaMode: null\n\t\t\t};\n\t\t}\n\t\tfunction oauthMethodIndex(id) {\n\t\t\treturn (opencodeAuth[id] ?? []).findIndex((m) => m.type === \"oauth\");\n\t\t}\n\t\t$$renderer.push(`<div class=\"oauth-list svelte-1kgjxt0\" role=\"list\">`);\n\t\tif (filteredProviders().length === 0) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<p class=\"oauth-empty svelte-1kgjxt0\">Nothing more to add — you're all connected.</p>`);\n\t\t} else {\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--[-->`);\n\t\t\tconst each_array = ensure_array_like(visibleOauth());\n\t\t\tfor (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {\n\t\t\t\tlet provider = each_array[$$index];\n\t\t\t\tconst st = getState(provider.id);\n\t\t\t\toauthMethodIndex(provider.id);\n\t\t\t\t$$renderer.push(`<div class=\"oauth-row svelte-1kgjxt0\" role=\"listitem\"${attr(\"data-provider\", provider.id)}><span class=\"oauth-name svelte-1kgjxt0\">${escape_html(provider.name)}</span> `);\n\t\t\t\tif (st.verified) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`<span class=\"oauth-status oauth-status--ok svelte-1kgjxt0\"${attr(\"aria-label\", `${stringify(provider.name)} connected`)}>Connected ✓</span>`);\n\t\t\t\t} else if (st.oauthPolling) {\n\t\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t\t$$renderer.push(`<div class=\"oauth-polling svelte-1kgjxt0\">`);\n\t\t\t\t\tif (st.oauthUrl) {\n\t\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t\t$$renderer.push(`<a${attr(\"href\", st.oauthUrl)} target=\"_blank\" rel=\"noopener\" class=\"oauth-open-link svelte-1kgjxt0\">Open authorization page →</a>`);\n\t\t\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\t\t\tif (st.oauthInstructions) {\n\t\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t\t$$renderer.push(`<p class=\"oauth-instructions svelte-1kgjxt0\">${escape_html(st.oauthInstructions)}</p>`);\n\t\t\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`<!--]--> <div class=\"oauth-waiting svelte-1kgjxt0\">`);\n\t\t\t\t\tSpinner($$renderer, {});\n\t\t\t\t\t$$renderer.push(`<!----> Waiting for authorization…</div> <button type=\"button\" class=\"btn-oauth-cancel svelte-1kgjxt0\">Cancel</button></div>`);\n\t\t\t\t} else {\n\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`<button type=\"button\" class=\"btn btn-secondary btn-sm\"${attr(\"disabled\", st.verifying, true)}>${escape_html(st.verifying ? \"Signing in…\" : \"Sign in\")}</button>`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\t\tif (st.error && !st.oauthPolling) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`<span class=\"oauth-error svelte-1kgjxt0\" role=\"alert\">${escape_html(st.errorMessage ?? \"Authorization failed\")}</span>`);\n\t\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<!--]--></div>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\tif (hiddenOauthCount() > 0) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<button type=\"button\" class=\"oauth-more svelte-1kgjxt0\">${escape_html(`Show ${hiddenOauthCount()} more services`)}</button>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]-->`);\n\t\t}\n\t\t$$renderer.push(`<!--]--></div>`);\n\t});\n}\n//#endregion\n//#region src/routes/setup/steps/CloudAttachPanel.svelte\nfunction CloudAttachPanel($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t/**\n\t\t* CloudAttachPanel — the simplest possible \"connect your AI\" step.\n\t\t*\n\t\t* Two states only, no jargon:\n\t\t* - An AI account was found on this computer → one \"Use this account\" button.\n\t\t* - Otherwise (or \"use a different account\") → sign-in buttons.\n\t\t*\n\t\t* Deliberately NO provider count/list, NO \"other options\", and NO custom\n\t\t* endpoint / API-key fields — those are power-user concerns that live in the\n\t\t* admin dashboard after setup, not in first-run.\n\t\t*/\n\t\tlet { credentialCount = 0, cloudProviders = [], opencodeProviders = [], opencodeAuth = {}, providerState = {}, hostImporting = false, verifiedCount = 0, onhostimport, onoauthstart, onoauthcancel } = $$props;\n\t\tconst hasFoundAccount = derived(() => credentialCount > 0 || cloudProviders.length > 0);\n\t\tconst connected = derived(() => verifiedCount > 0);\n\t\tlet signInInstead = false;\n\t\tconst showSignIn = derived(() => !hasFoundAccount() || signInInstead);\n\t\t$$renderer.push(`<div class=\"cloud-attach svelte-v318we\">`);\n\t\tif (!showSignIn()) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\tif (connected()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<p class=\"connected svelte-v318we\" role=\"status\"><span class=\"check svelte-v318we\" aria-hidden=\"true\">✓</span> Connected your AI account.</p> <button type=\"button\" class=\"account-link svelte-v318we\">Use a different account</button>`);\n\t\t\t} else if (hostImporting) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`<p class=\"connecting svelte-v318we\" role=\"status\">`);\n\t\t\t\tSpinner($$renderer, {});\n\t\t\t\t$$renderer.push(`<!----> Connecting your AI account…</p>`);\n\t\t\t} else {\n\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<p class=\"lead svelte-v318we\">We found an AI account on this computer.</p> <button type=\"button\" class=\"btn-connect svelte-v318we\" id=\"btn-host-import\">Use this account</button> <button type=\"button\" class=\"account-link svelte-v318we\">Use a different account</button>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]-->`);\n\t\t} else {\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<p class=\"lead svelte-v318we\">Sign in to your AI service:</p> `);\n\t\t\tProviderOAuthList($$renderer, {\n\t\t\t\topencodeProviders,\n\t\t\t\topencodeAuth,\n\t\t\t\tproviderState,\n\t\t\t\tonoauthstart: (id, idx) => onoauthstart?.(id, idx),\n\t\t\t\tonoauthcancel: (id) => onoauthcancel?.(id)\n\t\t\t});\n\t\t\t$$renderer.push(`<!----> `);\n\t\t\tif (hasFoundAccount()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<button type=\"button\" class=\"account-link svelte-v318we\">Use the account on this computer instead</button>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]-->`);\n\t\t}\n\t\t$$renderer.push(`<!--]--></div>`);\n\t});\n}\n//#endregion\n//#region src/routes/setup/steps/LocalModelsStatus.svelte\nfunction LocalModelsStatus($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t/**\n\t\t* LocalModelsStatus — shows the local model runtime state for Screen 1.\n\t\t*\n\t\t* Props:\n\t\t* hostProviders — runtimes already running on the host (ollama / lmstudio / model-runner)\n\t\t* gpuVramMb — detected VRAM in MiB (0 = not detected)\n\t\t* gpuVendor — 'apple' | 'nvidia' | 'amd' | '' (empty = not detected)\n\t\t* gpuName — human-readable GPU name from detection\n\t\t* ollamaEnabled — true when in-stack Ollama will be added\n\t\t* selectedOllamaProfile — Ollama profile id (cuda / rocm / cpu)\n\t\t* onrecheck — called when the user clicks Re-check (re-calls GET /api/setup/recommend)\n\t\t*/\n\t\tlet { hostProviders = [], gpuVramMb = 0, gpuVendor = \"\", gpuName = \"\", ollamaEnabled = false, selectedOllamaProfile = \"\", onrecheck } = $$props;\n\t\tconst isAppleSilicon = derived(() => gpuVendor === \"apple\");\n\t\tconst hasRunningRuntime = derived(() => hostProviders.length > 0);\n\t\tconst gpuGb = derived(() => Math.round(gpuVramMb / 1024));\n\t\tconst profileLabel = derived(() => selectedOllamaProfile.endsWith(\"cuda\") ? \"CUDA\" : selectedOllamaProfile.endsWith(\"rocm\") ? \"ROCm\" : \"CPU\");\n\t\tfunction runtimeLabel(provider) {\n\t\t\tif (provider === \"ollama\") return \"Ollama\";\n\t\t\tif (provider === \"lmstudio\") return \"LM Studio\";\n\t\t\tif (provider === \"model-runner\") return \"Docker Model Runner\";\n\t\t\treturn provider;\n\t\t}\n\t\t$$renderer.push(`<div class=\"local-models-status svelte-1fl6n4z\">`);\n\t\tif (hasRunningRuntime()) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"status-row status-row--running svelte-1fl6n4z\" role=\"status\"><span class=\"status-icon svelte-1fl6n4z\" aria-hidden=\"true\">●</span> <span class=\"status-text svelte-1fl6n4z\">Using ${escape_html(hostProviders.map((p) => runtimeLabel(p.provider)).join(\", \"))} already running on your machine.</span></div>`);\n\t\t} else if (isAppleSilicon()) {\n\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t$$renderer.push(`<div class=\"status-callout status-callout--apple svelte-1fl6n4z\" role=\"note\"><div class=\"callout-icon svelte-1fl6n4z\" aria-hidden=\"true\"><svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg></div> <div class=\"callout-body svelte-1fl6n4z\"><p class=\"callout-title svelte-1fl6n4z\">Apple Silicon detected</p> <p class=\"callout-desc svelte-1fl6n4z\">For best performance, install <a href=\"https://ollama.com/download\" target=\"_blank\" rel=\"noopener\" class=\"svelte-1fl6n4z\">Ollama for macOS</a> and leave it running before continuing. Once Ollama is running, click Re-check to continue.</p> <button class=\"btn-recheck svelte-1fl6n4z\" type=\"button\" id=\"btn-local-recheck\">Re-check</button></div></div>`);\n\t\t} else if (ollamaEnabled && gpuVramMb >= 8192) {\n\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t$$renderer.push(`<div class=\"status-row status-row--will-install svelte-1fl6n4z\" role=\"status\"><span class=\"status-icon svelte-1fl6n4z\" aria-hidden=\"true\">◎</span> <span class=\"status-text svelte-1fl6n4z\">Will install Ollama in the stack `);\n\t\t\tif (gpuName) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`(GPU: ${escape_html(gpuName)}, ${escape_html(gpuGb())} GB, profile: ${escape_html(profileLabel())})`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]-->.\n First pull downloads ~4–8 GB.</span></div>`);\n\t\t} else if (ollamaEnabled) {\n\t\t\t$$renderer.push(\"<!--[3-->\");\n\t\t\t$$renderer.push(`<div class=\"status-row status-row--will-install svelte-1fl6n4z\" role=\"status\"><span class=\"status-icon svelte-1fl6n4z\" aria-hidden=\"true\">◎</span> <span class=\"status-text svelte-1fl6n4z\">Will install Ollama in the stack (CPU mode). First pull downloads ~4–8 GB.</span></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--></div>`);\n\t});\n}\n//#endregion\n//#region src/routes/setup/steps/Screen1ModelsStep.svelte\nfunction Screen1ModelsStep($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t/**\n\t\t* Screen1ModelsStep — \"Connect your AI brain\"\n\t\t*\n\t\t* Redesigned flat RadioRow layout (spec: /tmp/wiz/connect-redesign.html).\n\t\t* Three primary choices in a hairline-divided list:\n\t\t* 1. Detected cloud service (shown only when verifiedCount > 0 or llmProvider set)\n\t\t* 2. Run on this computer (local AI — co-equal primary option)\n\t\t* 3. Sign in to a cloud service (expands ProviderOAuthList inline)\n\t\t*\n\t\t* Props:\n\t\t* modelMode — currently selected mode ('cloud'|'local'|'both')\n\t\t* detectionLoading — true while /api/setup/recommend is in flight\n\t\t* detectionTimedOut — true when detection did not complete within 3s\n\t\t* systemCheckError — non-empty string when SystemCheck failed (shows inline alert)\n\t\t* systemCheckRetrying — true while system check retry is in progress\n\t\t* gpuVramMb — VRAM in MiB (0 = not detected)\n\t\t* gpuVendor — 'apple' | 'nvidia' | 'amd' | '' (empty = none detected)\n\t\t* gpuName — human-readable GPU name\n\t\t* hostProviders — local runtimes running on host\n\t\t* credentialCount — importable host credential count\n\t\t* cloudProviders — provider ids configured on host\n\t\t* opencodeProviders — all OpenCode providers (for OAuth list)\n\t\t* opencodeAuth — auth methods per provider id\n\t\t* providerState — verification state per provider id\n\t\t* ollamaEnabled — whether in-stack Ollama is active\n\t\t* selectedOllamaProfile — ollama profile id (cuda/rocm/cpu)\n\t\t* hostImporting — true while host import is in flight\n\t\t* verifiedCount — number of providers currently verified\n\t\t* allowEmptyInstall — whether \"install without provider\" escape is active\n\t\t* llmModel — selected chat model id\n\t\t* llmProvider — provider name for selected chat model\n\t\t*\n\t\t* Events:\n\t\t* onmodelmodechange — user picked a different model mode\n\t\t* onhostimport — trigger host provider import\n\t\t* onoauthstart — OAuth flow start\n\t\t* onoauthcancel — OAuth flow cancel\n\t\t* onbaseurl — custom base URL changed\n\t\t* onapikey — custom API key changed\n\t\t* onverify — verify custom endpoint\n\t\t* onrecheck — re-call /api/setup/recommend\n\t\t* onsystemcheckretry — retry the system check\n\t\t* onallowemptyinstallchange — toggle empty install escape\n\t\t* onnext — proceed to Screen 2\n\t\t*/\n\t\t/** True while Phase-0 detection is in flight. */\n\t\t/** True when the 3-second detection timeout elapsed. */\n\t\t/** Non-empty string = SystemCheck failed; shown as inline alert on this screen. */\n\t\t/** True while the system check retry is running. */\n\t\t/** VRAM in MiB from detection (0 = not detected). */\n\t\t/** GPU vendor from detection ('apple'|'nvidia'|'amd'|''). */\n\t\t/** Human-readable GPU name. */\n\t\t/** Local runtimes already running on the host. */\n\t\t/** Full OpenCode provider list (for OAuth sub-panel). */\n\t\t/** Auth methods per provider id. */\n\t\t/** Verification state per provider id. */\n\t\t/** Whether in-stack Ollama will be added. */\n\t\t/** Selected Ollama profile (cuda/rocm/cpu). */\n\t\t/** True while host-import is in flight. */\n\t\t/** Number of currently verified providers. */\n\t\t/** Whether the \"install without provider\" escape is checked. */\n\t\t/** Currently selected chat model id. */\n\t\t/** Provider name for the selected chat model (connId). */\n\t\t/** Stable connId of the detected cloud service (persists across local↔cloud switches). */\n\t\tconst MIN_LOCAL_GPU_VRAM_MB = 8192;\n\t\tconst SERVICE_LABELS = {\n\t\t\topenai: \"ChatGPT (OpenAI)\",\n\t\t\tgoogle: \"Gemini (Google)\",\n\t\t\t\"github-copilot\": \"GitHub Copilot\",\n\t\t\tgroq: \"Groq\",\n\t\t\tanthropic: \"Claude (Anthropic)\",\n\t\t\tmistral: \"Mistral\",\n\t\t\tcohere: \"Cohere\"\n\t\t};\n\t\tlet { detectionLoading = false, detectionTimedOut = false, systemCheckError = \"\", systemCheckRetrying = false, gpuVramMb = 0, gpuVendor = \"\", gpuName = \"\", hostProviders = [], opencodeProviders = [], opencodeAuth = {}, providerState = {}, ollamaEnabled = false, selectedOllamaProfile = \"\", hostImporting = false, verifiedCount = 0, allowEmptyInstall = false, llmModel = \"\", llmProvider = \"\", detectedCloudConn = \"\", onmodelmodechange, onhostimport, onoauthstart, onoauthcancel, onrecheck, onsystemcheckretry, onallowemptyinstallchange } = $$props;\n\t\tconst localAvailable = derived(() => gpuVramMb >= MIN_LOCAL_GPU_VRAM_MB || gpuVendor === \"apple\" || hostProviders.length > 0);\n\t\tfunction friendlyServiceLabel(connId) {\n\t\t\tif (SERVICE_LABELS[connId]) return SERVICE_LABELS[connId];\n\t\t\tconst fromProviders = opencodeProviders.find((p) => p.id === connId)?.name;\n\t\t\tif (fromProviders) return fromProviders;\n\t\t\treturn connId;\n\t\t}\n\t\tconst LOCAL_PROVIDER_IDS = new Set([\n\t\t\t\"ollama\",\n\t\t\t\"lmstudio\",\n\t\t\t\"llamacpp\",\n\t\t\t\"localai\",\n\t\t\t\"model-runner\"\n\t\t]);\n\t\tconst detectedConn = derived(() => detectedCloudConn || (llmProvider && !LOCAL_PROVIDER_IDS.has(llmProvider) ? llmProvider : \"\"));\n\t\tconst detectedServiceLabel = derived(() => detectedConn() ? friendlyServiceLabel(detectedConn()) : \"\");\n\t\tconst detectedIsLocal = derived(() => LOCAL_PROVIDER_IDS.has(llmProvider));\n\t\tconst showDetectedRow = derived(() => !!detectedConn() && verifiedCount > 0);\n\t\tlet selectedRow = run(() => showDetectedRow() ? \"detected\" : detectedIsLocal() && llmProvider ? \"local\" : null);\n\t\tconst showLocalPanel = derived(() => selectedRow === \"local\");\n\t\tconst showSignInPanel = derived(() => selectedRow === \"cloud\");\n\t\tconst cloudRowTitle = derived(() => showDetectedRow() ? \"Sign in to a different service\" : \"Sign in to a cloud AI service\");\n\t\tconst cloudRowSub = derived(() => showDetectedRow() ? \"Google Gemini, GitHub Copilot, and others\" : \"OpenAI, Google Gemini, GitHub Copilot, and others\");\n\t\t$$renderer.push(`<div data-testid=\"step-models\" class=\"screen-models svelte-z6usuj\">`);\n\t\tif (systemCheckError) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"s1-alert s1-alert--error svelte-z6usuj\" role=\"alert\"><span class=\"s1-alert-text svelte-z6usuj\">${escape_html(systemCheckError)}</span> <button type=\"button\" class=\"s1-alert-btn svelte-z6usuj\" id=\"btn-syscheck-retry\"${attr(\"disabled\", systemCheckRetrying, true)}>${escape_html(systemCheckRetrying ? \"Checking…\" : \"Retry\")}</button></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (detectionTimedOut && true) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"s1-alert s1-alert--warn svelte-z6usuj\" role=\"alert\"><span class=\"s1-alert-text svelte-z6usuj\">Detection timed out — results may be incomplete.</span> <button type=\"button\" class=\"s1-alert-btn s1-alert-btn--warn svelte-z6usuj\">Re-run detection</button> <button type=\"button\" class=\"s1-dismiss svelte-z6usuj\" aria-label=\"Dismiss\">✕</button></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (detectionLoading || hostImporting) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"s1-shimmer svelte-z6usuj\" aria-busy=\"true\" aria-label=\"Detecting AI services…\"><span class=\"s1-shimmer-bar svelte-z6usuj\"></span> <span class=\"s1-shimmer-bar s1-shimmer-bar--short svelte-z6usuj\"></span> <span class=\"s1-shimmer-bar s1-shimmer-bar--shorter svelte-z6usuj\"></span></div>`);\n\t\t} else {\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\tif (verifiedCount > 0 && showDetectedRow()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<div class=\"s1-detected-banner svelte-z6usuj\" role=\"status\"><div class=\"s1-detected-check svelte-z6usuj\" aria-hidden=\"true\">✓</div> <div class=\"s1-detected-text svelte-z6usuj\"><div class=\"s1-detected-title svelte-z6usuj\">${escape_html(detectedServiceLabel())} is already connected — you're good to go</div> <div class=\"s1-detected-sub svelte-z6usuj\">We found your account on this computer. Just continue, or choose something different below.</div></div></div>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--> <div class=\"s1-choice-list svelte-z6usuj\" role=\"radiogroup\" aria-label=\"Which AI should your assistant use\">`);\n\t\t\tif (showDetectedRow()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<button type=\"button\"${attr_class(\"s1-choice-row svelte-z6usuj\", void 0, { \"s1-choice-row--selected\": selectedRow === \"detected\" })} role=\"radio\"${attr(\"aria-checked\", selectedRow === \"detected\")}><div class=\"s1-radio-dot svelte-z6usuj\"><div class=\"s1-radio-dot-inner svelte-z6usuj\"></div></div> <div class=\"s1-choice-body svelte-z6usuj\"><div class=\"s1-choice-title svelte-z6usuj\">${escape_html(detectedServiceLabel())}</div> <div class=\"s1-choice-sub svelte-z6usuj\">Use your existing ${escape_html(detectedServiceLabel())} subscription</div></div> <span class=\"s1-badge-recommended svelte-z6usuj\">Recommended</span></button>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--> <button type=\"button\"${attr_class(\"s1-choice-row svelte-z6usuj\", void 0, {\n\t\t\t\t\"s1-choice-row--selected\": selectedRow === \"local\",\n\t\t\t\t\"s1-choice-row--unavailable\": !localAvailable()\n\t\t\t})} role=\"radio\"${attr(\"aria-checked\", selectedRow === \"local\")}${attr(\"disabled\", !localAvailable(), true)}><div class=\"s1-radio-dot svelte-z6usuj\"><div class=\"s1-radio-dot-inner svelte-z6usuj\"></div></div> <div class=\"s1-choice-icon svelte-z6usuj\" aria-hidden=\"true\"><svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\" class=\"svelte-z6usuj\"><rect x=\"1.5\" y=\"2.5\" width=\"15\" height=\"10\" rx=\"1.5\" class=\"svelte-z6usuj\"></rect><path d=\"M5.5 15.5h7M9 12.5v3\" stroke-linecap=\"round\" class=\"svelte-z6usuj\"></path><circle cx=\"9\" cy=\"7.5\" r=\"2.5\" class=\"svelte-z6usuj\"></circle></svg></div> <div class=\"s1-choice-body svelte-z6usuj\"><div class=\"s1-choice-title svelte-z6usuj\">Run on this computer</div> <div class=\"s1-choice-sub svelte-z6usuj\">`);\n\t\t\tif (localAvailable()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`Private &amp; free — no account needed, no data leaves your machine`);\n\t\t\t} else {\n\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`Needs a more capable computer — requires 8 GB+ graphics card or Apple Silicon`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--></div></div></button> `);\n\t\t\tif (showLocalPanel()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<div class=\"s1-local-panel svelte-z6usuj\" aria-live=\"polite\">`);\n\t\t\t\tLocalModelsStatus($$renderer, {\n\t\t\t\t\thostProviders,\n\t\t\t\t\tgpuVramMb,\n\t\t\t\t\tgpuVendor,\n\t\t\t\t\tgpuName,\n\t\t\t\t\tollamaEnabled,\n\t\t\t\t\tselectedOllamaProfile,\n\t\t\t\t\tonrecheck\n\t\t\t\t});\n\t\t\t\t$$renderer.push(`<!----></div>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--> <button type=\"button\"${attr_class(\"s1-choice-row svelte-z6usuj\", void 0, { \"s1-choice-row--selected\": selectedRow === \"cloud\" })} role=\"radio\"${attr(\"aria-checked\", selectedRow === \"cloud\")}><div class=\"s1-radio-dot svelte-z6usuj\"><div class=\"s1-radio-dot-inner svelte-z6usuj\"></div></div> <div class=\"s1-choice-body svelte-z6usuj\"><div class=\"s1-choice-title svelte-z6usuj\">${escape_html(cloudRowTitle())}</div> <div class=\"s1-choice-sub svelte-z6usuj\">${escape_html(cloudRowSub())}</div></div></button> `);\n\t\t\tif (showSignInPanel()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<div class=\"s1-signin-panel svelte-z6usuj\" aria-live=\"polite\">`);\n\t\t\t\tCloudAttachPanel($$renderer, {\n\t\t\t\t\tcredentialCount: 0,\n\t\t\t\t\tcloudProviders: [],\n\t\t\t\t\topencodeProviders,\n\t\t\t\t\topencodeAuth,\n\t\t\t\t\tproviderState,\n\t\t\t\t\thostImporting,\n\t\t\t\t\tverifiedCount,\n\t\t\t\t\tonhostimport,\n\t\t\t\t\tonoauthstart: (id, idx) => onoauthstart?.(id, idx),\n\t\t\t\t\tonoauthcancel: (id) => onoauthcancel?.(id)\n\t\t\t\t});\n\t\t\t\t$$renderer.push(`<!----></div>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></div> `);\n\t\t\tif (!llmModel && !allowEmptyInstall) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<div class=\"s1-empty-install-row svelte-z6usuj\"><p class=\"s1-empty-install-hint svelte-z6usuj\">No AI here? You can still continue — connect this app to an assistant\n running on another computer, or add a provider later from your dashboard.</p> <button type=\"button\" class=\"s1-btn-empty-install svelte-z6usuj\">I'll set this up later</button></div>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]-->`);\n\t\t}\n\t\t$$renderer.push(`<!--]--></div>`);\n\t});\n}\n//#endregion\n//#region src/routes/setup/steps/Screen2ExtrasStep.svelte\nfunction Screen2ExtrasStep($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t/**\n\t\t* Screen2ExtrasStep — \"Optional extras\"\n\t\t*\n\t\t* Flat hairline-row layout (spec: /tmp/wiz/extras-finish-redesign.html).\n\t\t* Three rows with inline accordion expansion (no modal, no bordered cards,\n\t\t* no sub-section headings):\n\t\t* 1. Voice — bundled openpalm-voice; toggle drives onvoiceenabledchange + engine defaults\n\t\t* 2. Discord — botToken + applicationId credential fields\n\t\t* 3. Slack — slackBotToken + slackAppToken credential fields\n\t\t*\n\t\t* Props:\n\t\t* modelMode — 'cloud' | 'local' | 'both' — drives voice default selection\n\t\t* voiceEnabled — explicit voice on/off toggle state (OFF by default)\n\t\t* voiceTts — current TTS engine value\n\t\t* voiceStt — current STT engine value\n\t\t* hasOpenAI — true if OpenAI is a verified provider (affects voice default)\n\t\t* voiceProfiles — available voice addon hardware profiles\n\t\t* selectedVoiceProfile — currently selected voice profile id\n\t\t* portalSelection — current portal enable + credential state\n\t\t* onvoiceenabledchange — called when voice toggle flips\n\t\t* onchangetts — called when TTS engine/config changes\n\t\t* onchangestt — called when STT engine/config changes\n\t\t* onvoiceprofilechange — called when voice hardware profile changes\n\t\t* onportaltoggle — called when a portal toggle flips\n\t\t* oncredentialchange — called when a portal credential field changes\n\t\t* onnext — proceed to Screen 3 (always enabled)\n\t\t*/\n\t\t/** Which model mode was chosen on Screen 1. Drives voice default logic. */\n\t\t/**\n\t\t* Explicit voice on/off state — OFF by default.\n\t\t* CRITICAL: must not be derived from engine selection. The parent owns this\n\t\t* as $state(false) and passes it down. Only when this is true should voice\n\t\t* addon be included in the payload.\n\t\t*/\n\t\t/** Current TTS engine value. */\n\t\t/** Current STT engine value. */\n\t\t/** True when OpenAI is a verified provider (affects default engine). */\n\t\t/** Portal enable + credential state (discord, slack). */\n\t\tlet { modelMode, voiceEnabled, voiceTts, voiceStt, hasOpenAI = false, portalSelection = {}, onvoiceenabledchange, onchangetts, onchangestt, onportaltoggle, oncredentialchange } = $$props;\n\t\tfunction isPortalEnabled$2(chId, locked) {\n\t\t\treturn isPortalEnabled(portalSelection, chId, locked);\n\t\t}\n\t\tfunction getCredValue$1(chId, key) {\n\t\t\treturn getCredValue(portalSelection, chId, key);\n\t\t}\n\t\tconst configurablePortals = derived(() => PORTALS.filter((ch) => !ch.locked));\n\t\tconst discordCh = derived(() => configurablePortals().find((ch) => ch.id === \"discord\"));\n\t\tconst slackCh = derived(() => configurablePortals().find((ch) => ch.id === \"slack\"));\n\t\tconst discordOn = derived(() => isPortalEnabled$2(\"discord\"));\n\t\tconst slackOn = derived(() => isPortalEnabled$2(\"slack\"));\n\t\t$$renderer.push(`<div data-testid=\"step-extras\" class=\"addon-list svelte-85kisn\" role=\"list\"><div class=\"addon-row svelte-85kisn\" role=\"listitem\"><div class=\"addon-row-header svelte-85kisn\"><div class=\"addon-icon voice-icon svelte-85kisn\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#3b82f6\" stroke-width=\"1.7\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"svelte-85kisn\"><rect x=\"9\" y=\"3\" width=\"6\" height=\"11\" rx=\"3\"></rect><path d=\"M5 11a7 7 0 0014 0M12 18v3\"></path></svg></div> <div class=\"addon-body svelte-85kisn\"><div class=\"addon-title svelte-85kisn\">Voice</div> <div class=\"addon-sub svelte-85kisn\">Talk to your assistant and hear it reply</div></div> <div class=\"toggle-wrap svelte-85kisn\"><label class=\"toggle svelte-85kisn\" aria-label=\"Enable Voice\"><input type=\"checkbox\"${attr(\"checked\", voiceEnabled, true)} class=\"svelte-85kisn\"/> <div class=\"toggle-track svelte-85kisn\"></div> <div class=\"toggle-thumb svelte-85kisn\"></div></label></div></div> <div${attr_class(\"addon-panel svelte-85kisn\", void 0, { \"open\": voiceEnabled })} aria-live=\"polite\"><div class=\"addon-panel-inner svelte-85kisn\"><p class=\"panel-question svelte-85kisn\">How should your assistant speak?</p> <div class=\"voice-option svelte-85kisn\"><div class=\"voice-option-dot svelte-85kisn\"><div class=\"voice-option-dot-inner svelte-85kisn\"></div></div> <div><div class=\"voice-option-text svelte-85kisn\">Built-in voice — free, runs on this computer</div> <div class=\"voice-option-sub svelte-85kisn\">No internet needed. Sounds natural, works out of the box.</div></div></div></div></div></div> `);\n\t\tif (discordCh()) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"addon-row svelte-85kisn\" role=\"listitem\"><div class=\"addon-row-header svelte-85kisn\"><div class=\"addon-icon discord-icon svelte-85kisn\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"#5865f2\" class=\"svelte-85kisn\"><path d=\"M19 5.3A16 16 0 0015 4l-.2.4a14 14 0 00-4 0L10.5 4a16 16 0 00-4 1.3C4 9 3.3 12.6 3.6 16.2A16 16 0 008.5 18.7c.4-.5.8-1.1 1-1.7a9 9 0 01-1.6-.8l.4-.3a11 11 0 009.4 0l.4.3a9 9 0 01-1.6.8c.3.6.6 1.2 1 1.7a16 16 0 004.9-2.5c.4-4.2-.7-7.8-2.4-10.9zM9 14c-.8 0-1.4-.7-1.4-1.6S8.2 10.8 9 10.8s1.4.7 1.4 1.6S9.8 14 9 14zm6 0c-.8 0-1.4-.7-1.4-1.6s.6-1.6 1.4-1.6 1.4.7 1.4 1.6S15.8 14 15 14z\"></path></svg></div> <div class=\"addon-body svelte-85kisn\"><div class=\"addon-title svelte-85kisn\">Discord</div> <div class=\"addon-sub svelte-85kisn\">Reach your assistant from a Discord server</div></div> <div class=\"toggle-wrap svelte-85kisn\"><label class=\"toggle svelte-85kisn\" aria-label=\"Enable Discord\"><input type=\"checkbox\"${attr(\"checked\", discordOn(), true)} class=\"svelte-85kisn\"/> <div class=\"toggle-track svelte-85kisn\"></div> <div class=\"toggle-thumb svelte-85kisn\"></div></label></div></div> <div${attr_class(\"addon-panel svelte-85kisn\", void 0, { \"open\": discordOn() })} aria-live=\"polite\"><div class=\"addon-panel-inner svelte-85kisn\"><div class=\"field-group svelte-85kisn\"><div><label class=\"field-label svelte-85kisn\" for=\"cred-discord-botToken\">Bot token</label> <input class=\"field-input svelte-85kisn\" type=\"password\" id=\"cred-discord-botToken\" placeholder=\"Paste your bot token here\" autocomplete=\"off\"${attr(\"value\", getCredValue$1(\"discord\", \"botToken\"))}/> <p class=\"field-help svelte-85kisn\"><a href=\"https://discord.com/developers/docs/quick-start/getting-started\" target=\"_blank\" rel=\"noopener\" class=\"svelte-85kisn\">How to create a Discord bot and get your token →</a></p></div> <div><label class=\"field-label svelte-85kisn\" for=\"cred-discord-applicationId\">Application ID</label> <input class=\"field-input svelte-85kisn\" type=\"text\" id=\"cred-discord-applicationId\" placeholder=\"Your app's numeric ID\" autocomplete=\"off\"${attr(\"value\", getCredValue$1(\"discord\", \"applicationId\"))}/> <p class=\"field-help svelte-85kisn\">Found in the Discord Developer Portal under your application's General Information page.</p></div></div></div></div></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (slackCh()) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"addon-row svelte-85kisn\" role=\"listitem\"><div class=\"addon-row-header svelte-85kisn\"><div class=\"addon-icon slack-icon svelte-85kisn\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"svelte-85kisn\"><path fill=\"#36C5F0\" d=\"M9 13.5a2 2 0 11-2-2h2v2z\"></path><path fill=\"#2EB67D\" d=\"M10.5 9a2 2 0 112 2H10.5v-2z\"></path><path fill=\"#ECB22E\" d=\"M15 10.5a2 2 0 112 2h-2v-2z\"></path><path fill=\"#E01E5A\" d=\"M13.5 15a2 2 0 11-2 2v-2h2z\"></path></svg></div> <div class=\"addon-body svelte-85kisn\"><div class=\"addon-title svelte-85kisn\">Slack</div> <div class=\"addon-sub svelte-85kisn\">Reach your assistant from a Slack workspace</div></div> <div class=\"toggle-wrap svelte-85kisn\"><label class=\"toggle svelte-85kisn\" aria-label=\"Enable Slack\"><input type=\"checkbox\"${attr(\"checked\", slackOn(), true)} class=\"svelte-85kisn\"/> <div class=\"toggle-track svelte-85kisn\"></div> <div class=\"toggle-thumb svelte-85kisn\"></div></label></div></div> <div${attr_class(\"addon-panel svelte-85kisn\", void 0, { \"open\": slackOn() })} aria-live=\"polite\"><div class=\"addon-panel-inner svelte-85kisn\"><div class=\"field-group svelte-85kisn\"><div><label class=\"field-label svelte-85kisn\" for=\"cred-slack-slackBotToken\">Bot token</label> <input class=\"field-input svelte-85kisn\" type=\"password\" id=\"cred-slack-slackBotToken\" placeholder=\"xoxb-…\" autocomplete=\"off\"${attr(\"value\", getCredValue$1(\"slack\", \"slackBotToken\"))}/></div> <div><label class=\"field-label svelte-85kisn\" for=\"cred-slack-slackAppToken\">App-level token</label> <input class=\"field-input svelte-85kisn\" type=\"password\" id=\"cred-slack-slackAppToken\" placeholder=\"xapp-…\" autocomplete=\"off\"${attr(\"value\", getCredValue$1(\"slack\", \"slackAppToken\"))}/> <p class=\"field-help svelte-85kisn\"><a href=\"https://api.slack.com/quickstart\" target=\"_blank\" rel=\"noopener\" class=\"svelte-85kisn\">How to create a Slack app and get your tokens →</a></p></div></div></div></div></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--></div>`);\n\t});\n}\n//#endregion\n//#region src/routes/setup/steps/ReviewStep.svelte\nfunction ReviewStep($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t/** Label for the running host provider (e.g. \"Ollama\"). Shown when ollamaEnabled is false. */\n\t\tlet { uiLoginPassword, verifiedProviders, modelSelection, activeTts, activeStt, portalSelection, ollamaEnabled, hostProviderLabel = \"\", payload, installError, isRerun = false, systemCheckPassed = true, oneditmodels, oneditextras } = $$props;\n\t\tconst LOCAL_PROVIDER_IDS = new Set([\n\t\t\t\"ollama\",\n\t\t\t\"lmstudio\",\n\t\t\t\"llamacpp\",\n\t\t\t\"localai\",\n\t\t\t\"model-runner\"\n\t\t]);\n\t\tfunction friendlyProviderName(connId) {\n\t\t\tif (!connId) return \"\";\n\t\t\tif (connId === \"openai\") return \"ChatGPT (OpenAI)\";\n\t\t\tif (connId === \"google\") return \"Gemini (Google)\";\n\t\t\tif (connId === \"github-copilot\") return \"GitHub Copilot\";\n\t\t\tif (connId === \"groq\") return \"Groq\";\n\t\t\tif (LOCAL_PROVIDER_IDS.has(connId)) return \"Runs on this computer\";\n\t\t\treturn PROVIDERS.find((p) => p.id === connId)?.name ?? connId;\n\t\t}\n\t\tfunction isPortalEnabled$1(chId, locked) {\n\t\t\treturn isPortalEnabled(portalSelection, chId, locked);\n\t\t}\n\t\tconst aiLabel = derived(() => {\n\t\t\tconst connId = modelSelection.llm?.connId;\n\t\t\tif (!connId) return \"\";\n\t\t\treturn friendlyProviderName(connId);\n\t\t});\n\t\tconst voiceActive = derived(() => !!(activeTts && !activeTts.startsWith(\"skip-\")) || !!(activeStt && !activeStt.startsWith(\"skip-\")));\n\t\tconst activePortals = derived(() => PORTALS.filter((ch) => !ch.locked && isPortalEnabled$1(ch.id, ch.locked)));\n\t\tlet passwordCopied = false;\n\t\tif (verifiedProviders.length === 0) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"review-note svelte-1q74f52\">No AI set up here yet — that's fine. After install you can connect this app to an\n assistant running on another computer, or add a provider, anytime from your dashboard.</div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (!isRerun) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"password-block svelte-1q74f52\"><p class=\"password-label svelte-1q74f52\">Sign-in password</p> <div class=\"password-row svelte-1q74f52\">`);\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<span class=\"password-value password-value--dots svelte-1q74f52\" aria-label=\"Sign-in password\">••••••••••••••••</span>`);\n\t\t\t$$renderer.push(`<!--]--> <div class=\"password-actions svelte-1q74f52\"><button type=\"button\" class=\"btn-icon svelte-1q74f52\"${attr(\"aria-label\", \"Show password\")}${attr(\"title\", \"Show\")}>`);\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M1 8s2.5-5 7-5 7 5 7 5-2.5 5-7 5-7-5-7-5z\"></path><circle cx=\"8\" cy=\"8\" r=\"2\"></circle></svg>`);\n\t\t\t$$renderer.push(`<!--]--></button> <button type=\"button\"${attr_class(\"btn-icon svelte-1q74f52\", void 0, { \"btn-icon--copied\": passwordCopied })}${attr(\"aria-label\", \"Copy password\")} title=\"Copy\">`);\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"5\" y=\"5\" width=\"8\" height=\"8\" rx=\"1.5\"></rect><path d=\"M3 11V3h8\"></path></svg>`);\n\t\t\t$$renderer.push(`<!--]--></button></div></div> <p class=\"password-note svelte-1q74f52\">Already saved on this computer — keep a copy somewhere safe just in case.</p></div>`);\n\t\t} else {\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<div class=\"password-block svelte-1q74f52\"><p class=\"password-label svelte-1q74f52\">Sign-in password</p> <div class=\"password-row svelte-1q74f52\"><span class=\"password-value password-value--dots svelte-1q74f52\" aria-label=\"Sign-in password\">••••••••</span> <div class=\"password-actions svelte-1q74f52\"><span class=\"rerun-note svelte-1q74f52\">Previously set — not changed.</span></div></div></div>`);\n\t\t}\n\t\t$$renderer.push(`<!--]--> <div class=\"summary-list svelte-1q74f52\" aria-label=\"What's set up\"><p class=\"summary-section-label svelte-1q74f52\">What's being set up</p> `);\n\t\tif (aiLabel()) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"summary-row svelte-1q74f52\"><span class=\"summary-icon svelte-1q74f52\" aria-hidden=\"true\">`);\n\t\t\tIconAgent($$renderer, { size: 16 });\n\t\t\t$$renderer.push(`<!----></span> <div class=\"summary-body svelte-1q74f52\"><div class=\"summary-key svelte-1q74f52\">AI</div> <div class=\"summary-val svelte-1q74f52\">${escape_html(aiLabel())}</div></div> <button type=\"button\" class=\"btn-change svelte-1q74f52\">Change</button></div>`);\n\t\t} else if (verifiedProviders.length > 0) {\n\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t$$renderer.push(`<div class=\"summary-row svelte-1q74f52\"><span class=\"summary-icon svelte-1q74f52\" aria-hidden=\"true\">`);\n\t\t\tIconAgent($$renderer, { size: 16 });\n\t\t\t$$renderer.push(`<!----></span> <div class=\"summary-body svelte-1q74f52\"><div class=\"summary-key svelte-1q74f52\">AI</div> <div class=\"summary-val svelte-1q74f52\">${escape_html(friendlyProviderName(verifiedProviders[0].id))}</div></div> <button type=\"button\" class=\"btn-change svelte-1q74f52\">Change</button></div>`);\n\t\t} else if (ollamaEnabled) {\n\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t$$renderer.push(`<div class=\"summary-row svelte-1q74f52\"><span class=\"summary-icon svelte-1q74f52\" aria-hidden=\"true\">`);\n\t\t\tIconAgent($$renderer, { size: 16 });\n\t\t\t$$renderer.push(`<!----></span> <div class=\"summary-body svelte-1q74f52\"><div class=\"summary-key svelte-1q74f52\">AI</div> <div class=\"summary-val svelte-1q74f52\">Runs on this computer</div></div> <button type=\"button\" class=\"btn-change svelte-1q74f52\">Change</button></div>`);\n\t\t} else if (hostProviderLabel) {\n\t\t\t$$renderer.push(\"<!--[3-->\");\n\t\t\t$$renderer.push(`<div class=\"summary-row svelte-1q74f52\"><span class=\"summary-icon svelte-1q74f52\" aria-hidden=\"true\">`);\n\t\t\tIconAgent($$renderer, { size: 16 });\n\t\t\t$$renderer.push(`<!----></span> <div class=\"summary-body svelte-1q74f52\"><div class=\"summary-key svelte-1q74f52\">AI</div> <div class=\"summary-val svelte-1q74f52\">${escape_html(friendlyProviderName(hostProviderLabel))}</div></div> <button type=\"button\" class=\"btn-change svelte-1q74f52\">Change</button></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (voiceActive()) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"summary-row svelte-1q74f52\"><span class=\"summary-icon svelte-1q74f52\" aria-hidden=\"true\">`);\n\t\t\tIconMic($$renderer, { size: 16 });\n\t\t\t$$renderer.push(`<!----></span> <div class=\"summary-body svelte-1q74f52\"><div class=\"summary-key svelte-1q74f52\">Voice</div> <div class=\"summary-val svelte-1q74f52\">On — built-in voice</div></div> <button type=\"button\" class=\"btn-change svelte-1q74f52\">Change</button></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> <!--[-->`);\n\t\tconst each_array = ensure_array_like(activePortals());\n\t\tfor (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {\n\t\t\tlet ch = each_array[$$index];\n\t\t\t$$renderer.push(`<div class=\"summary-row svelte-1q74f52\"><span class=\"summary-icon svelte-1q74f52\" aria-hidden=\"true\">${escape_html(ch.icon)}</span> <div class=\"summary-body svelte-1q74f52\"><div class=\"summary-key svelte-1q74f52\">Chat app</div> <div class=\"summary-val svelte-1q74f52\">${escape_html(ch.name)}</div></div> <button type=\"button\" class=\"btn-change svelte-1q74f52\">Change</button></div>`);\n\t\t}\n\t\t$$renderer.push(`<!--]--></div> `);\n\t\tif (installError) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\tFriendlyError($$renderer, { error: friendlyError(installError, \"setup-complete\") });\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (!systemCheckPassed) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"review-warning svelte-1q74f52\" role=\"alert\">⚠ System check has not passed yet — Install is disabled until Docker is confirmed available.</div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> <div class=\"review-save-row svelte-1q74f52\"><button type=\"button\" class=\"btn-save svelte-1q74f52\" aria-label=\"Save configuration as JSON file\">Save configuration</button></div>`);\n\t});\n}\n//#endregion\n//#region src/routes/setup/steps/DeployStep.svelte\nfunction DeployStep($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t/** Non-fatal: install used cached images because the registry pull failed. */\n\t\t/** Terminal state reached with non-running rows that are all warnings. */\n\t\tlet { deployData, deployDone, deployHasWarnings = false, deployError, onback, onretry } = $$props;\n\t\tconst warningRows = derived(() => (deployData.deployStatus ?? []).filter((s) => s.status === \"warning\"));\n\t\tconst isElectron = typeof window !== \"undefined\" && !!window.openpalm;\n\t\tconst windowPort = typeof window !== \"undefined\" ? Number(window.location.port) || 3880 : 3880;\n\t\tconst adminPort = derived(() => deployData.ports?.admin ?? windowPort);\n\t\tconst assistantPort = derived(() => deployData.ports?.assistant ?? 3800);\n\t\tconst serviceLinks = derived(() => ({\n\t\t\tassistant: {\n\t\t\t\tport: assistantPort(),\n\t\t\t\tlabel: \"Assistant (OpenCode)\",\n\t\t\t\tpath: \"\"\n\t\t\t},\n\t\t\tadmin: {\n\t\t\t\tport: adminPort(),\n\t\t\t\tlabel: \"Admin Dashboard\",\n\t\t\t\tpath: \"\"\n\t\t\t}\n\t\t}));\n\t\tconst services = derived(() => deployData.deployStatus ?? []);\n\t\tconst total = derived(() => services().length);\n\t\tconst running = derived(() => services().filter((s) => s.status === \"running\").length);\n\t\tconst pct = derived(() => total() > 0 ? Math.round(running() / total() * 100) : 0);\n\t\tconst phase = derived(() => deployData.phase ?? \"writing-config\");\n\t\tconst voiceEnabled = derived(() => services().some((s) => /^voice(-cuda|-rocm)?$/.test(s.service ?? \"\")));\n\t\tconst deployTitle = derived(() => {\n\t\t\tif (deployDone) return deployHasWarnings ? \"Setup Complete (with warnings)\" : \"Setup Complete\";\n\t\t\tif (deployError) return \"Deployment Issue\";\n\t\t\tswitch (phase()) {\n\t\t\t\tcase \"writing-config\": return \"Preparing Configuration…\";\n\t\t\t\tcase \"pulling-images\": return voiceEnabled() ? \"Downloading Images (incl. Voice ~2.4 GB)…\" : \"Downloading Images…\";\n\t\t\t\tcase \"starting\": return \"Starting Services…\";\n\t\t\t\tcase \"starting-voice\": return \"Starting Voice Addon…\";\n\t\t\t\tcase \"ready\": return \"Setup Complete\";\n\t\t\t}\n\t\t\treturn \"Deploying…\";\n\t\t});\n\t\tconst deploySubtitle = derived(() => {\n\t\t\tif (deployDone) return deployHasWarnings ? \"Setup is complete. Some services are still warming up in the background — they will be ready shortly.\" : \"Your OpenPalm stack is up and running.\";\n\t\t\tif (deployError) return \"Setup could not finish starting the stack.\";\n\t\t\tswitch (phase()) {\n\t\t\t\tcase \"writing-config\": return \"Writing config files and validating settings.\";\n\t\t\t\tcase \"pulling-images\": return voiceEnabled() ? \"Downloading container images. The voice model (~2.4 GB) is the largest — on a typical home connection this step can take 10–30 minutes. The wizard will wait — keep this tab open.\" : \"Downloading container images — first install can take 3–8 minutes depending on connection.\";\n\t\t\t\tcase \"starting\": return `${running()} of ${total()} services running.`;\n\t\t\t\tcase \"starting-voice\": return \"Pulling the voice image (~2.4 GB) and warming up Kokoro + Whisper models. First launch can take 5–30 minutes on slow connections — the wizard will wait.\";\n\t\t\t\tcase \"ready\": return \"All services are up.\";\n\t\t\t}\n\t\t\treturn \"Writing configuration and starting services.\";\n\t\t});\n\t\tconst noStartMode = derived(() => deployDone && services().length === 0);\n\t\t$$renderer.push(`<div class=\"deploy-header\"><h2 id=\"deploy-title\">${escape_html(deployTitle())}</h2> <p class=\"step-description\" id=\"deploy-subtitle\">${escape_html(deploySubtitle())}</p></div> <div class=\"deploy-progress-summary\"><div class=\"deploy-progress-meta\"><span class=\"deploy-progress-label\">Progress</span> <span${attr_class(`deploy-progress-value ${deployError ? \"deploy-progress-value--error\" : \"\"}`)} id=\"deploy-progress-value\">`);\n\t\tif (deployError) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`Error`);\n\t\t} else if (deployDone) {\n\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t$$renderer.push(`${escape_html(services().length > 0 ? \"100%\" : \"\")}`);\n\t\t} else {\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`${escape_html(pct())}%`);\n\t\t}\n\t\t$$renderer.push(`<!--]--></span></div> <div class=\"deploy-progress-bar\"><div class=\"deploy-progress-fill\" id=\"deploy-progress-fill\"${attr_style(`width:${stringify(deployDone && services().length > 0 ? 100 : deployDone ? 0 : pct())}%`)}></div></div></div> <div class=\"deploy-services\" id=\"deploy-services\"><!--[-->`);\n\t\tconst each_array = ensure_array_like(services());\n\t\tfor (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {\n\t\t\tlet svc = each_array[$$index];\n\t\t\t$$renderer.push(`<div class=\"deploy-service-row\"><div class=\"deploy-service-indicator\">`);\n\t\t\tif (svc.status === \"running\") {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<span class=\"deploy-check\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"var(--s-moss)\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></span>`);\n\t\t\t} else if (svc.status === \"error\" || svc.status === \"warning\") {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`<span class=\"deploy-warning\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"var(--s-ink-2)\" stroke-width=\"2.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 9v4\"></path><path d=\"M12 17h.01\"></path><path d=\"M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"></path></svg></span>`);\n\t\t\t} else {\n\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<span class=\"deploy-spinner\">`);\n\t\t\t\tSpinner($$renderer, {});\n\t\t\t\t$$renderer.push(`<!----></span>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--></div> <div class=\"deploy-service-info\"><span class=\"deploy-service-name\">${escape_html(svc.service || svc.label || \"\")}</span> <span class=\"deploy-service-status\">${escape_html(svc.label || svc.status)}</span></div> <div class=\"deploy-service-bar\"><div${attr_class(`deploy-bar-fill ${svc.status === \"running\" ? \"complete\" : svc.status === \"ready\" ? \"ready\" : svc.status === \"warning\" ? \"warning\" : svc.status === \"error\" ? \"stopped\" : \"indeterminate\"}`, \"svelte-1orw49v\")}></div></div></div>`);\n\t\t}\n\t\t$$renderer.push(`<!--]--></div> `);\n\t\tif (deployError) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div id=\"deploy-failure\">`);\n\t\t\tFriendlyError($$renderer, { error: friendlyError(deployError, \"deploy\") });\n\t\t\t$$renderer.push(`<!----></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (!deployDone && !deployError) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<aside class=\"deploy-tips\" id=\"deploy-tips\"><div class=\"deploy-tips-header\"><span class=\"deploy-tips-kicker\">Tips</span> <h3>${escape_html(voiceEnabled() ? \"First install may take 10–30 minutes\" : \"First startup takes a few minutes\")}</h3></div> <ul>`);\n\t\t\tif (voiceEnabled()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<li>The OpenPalm Voice image is ~2.4 GB — the largest piece by far. Download speed depends on your internet connection.</li> <li>The wizard waits as long as the download takes. Progress bars below show each service's state.</li>`);\n\t\t\t} else {\n\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<li>Container images are being downloaded for the first time.</li>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--> <li>The admin console will be available once all services are healthy.</li> `);\n\t\t\tif (isElectron) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<li>You can leave this window — we'll let you know when it's ready.</li>`);\n\t\t\t} else {\n\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<li><strong>Keep this tab open while installation runs.</strong></li>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--></ul></aside>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (deployDone) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"done-state\" id=\"deploy-done\"><div class=\"done-icon\"><svg width=\"48\" height=\"48\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"var(--s-moss)\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"></path><polyline points=\"22 4 12 14.01 9 11.01\"></polyline></svg></div> <h2>${escape_html(deployHasWarnings ? \"Setup Complete (with warnings)\" : \"Setup Complete\")}</h2> `);\n\t\t\tif (noStartMode()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<p class=\"done-subtitle\">Configuration saved. Run 'openpalm start' to start services.</p>`);\n\t\t\t} else {\n\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<p class=\"done-subtitle\">${escape_html(deployHasWarnings ? \"Setup is complete. Some services are still warming up in the background.\" : \"Your OpenPalm stack is up and running.\")}</p> `);\n\t\t\t\tif (deployHasWarnings && warningRows().length > 0) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`<div class=\"deploy-warnings-note svelte-1orw49v\" role=\"status\" id=\"deploy-warnings-note\">Still warming up: ${escape_html(warningRows().map((s) => s.label || s.service).join(\", \"))}. You can finish setup now — these will be ready shortly.</div>`);\n\t\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\t\tif (deployData.imageWarning) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`<div class=\"feedback feedback--warning\" role=\"status\" id=\"deploy-image-warning\" style=\"margin-top:12px\"><span>⚠ ${escape_html(deployData.imageWarning)}</span></div>`);\n\t\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\t\tif (!isElectron) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`<p class=\"done-close-hint svelte-1orw49v\">Setup is complete. You can safely close this tab now.</p>`);\n\t\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<!--]--> <ul class=\"service-list\" id=\"deploy-service-list\"><!--[-->`);\n\t\t\t\tconst each_array_1 = ensure_array_like(services());\n\t\t\t\tfor (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {\n\t\t\t\t\tlet svc = each_array_1[$$index_1];\n\t\t\t\t\tconst name = svc.service || svc.label || \"\";\n\t\t\t\t\tconst linkInfo = serviceLinks()[name];\n\t\t\t\t\tconst isWarming = svc.status === \"warning\";\n\t\t\t\t\t$$renderer.push(`<li>`);\n\t\t\t\t\tif (linkInfo) {\n\t\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t\tconst url = \"http://127.0.0.1:\" + linkInfo.port + linkInfo.path;\n\t\t\t\t\t\t$$renderer.push(`<span class=\"deploy-svc-name\">${escape_html(linkInfo.label)}</span> <a${attr(\"href\", url)} target=\"_blank\" rel=\"noopener\" class=\"deploy-svc-link\">${escape_html(url)}</a> <span class=\"deploy-svc-status\">${escape_html(isWarming ? svc.label || \"⚠ Warming up\" : \"✓ Running\")}</span>`);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t\t$$renderer.push(`<span class=\"deploy-svc-name\">${escape_html(name)}</span> <span class=\"deploy-svc-status\">${escape_html(isWarming ? svc.label || \"⚠ Warming up\" : \"✓ Running\")}</span>`);\n\t\t\t\t\t}\n\t\t\t\t\t$$renderer.push(`<!--]--></li>`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]--></ul> <div class=\"done-links\"><a${attr(\"href\", resolve(\"/chat\"))} class=\"btn btn-primary\">Open Chat</a> <a${attr(\"href\", `http://127.0.0.1:${stringify(assistantPort())}`)} target=\"_blank\" rel=\"noopener\" class=\"btn btn-secondary\">OpenCode UI</a> <a${attr(\"href\", resolve(\"/\"))} class=\"btn btn-secondary\">Admin Dashboard</a></div>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (deployError) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"step-actions\" id=\"deploy-error-actions\"><button class=\"btn btn-secondary\" id=\"btn-deploy-back\">Back to Review</button> <button class=\"btn btn-primary\" id=\"btn-deploy-retry\">Retry</button></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]-->`);\n\t});\n}\n//#endregion\n//#region src/routes/setup/+page.svelte\nfunction _page($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\tlet currentStep = 0;\n\t\tlet maxVisitedStep = 0;\n\t\tlet showDeploy = false;\n\t\tlet systemCheckPassed = false;\n\t\tlet modelMode = \"cloud\";\n\t\tlet voiceEnabled = false;\n\t\tlet uiLoginPassword = \"\";\n\t\tlet autoModeImporting = false;\n\t\tlet gpuDetected = false;\n\t\tlet providerState = {};\n\t\tlet detectedHostProviders = [];\n\t\tconst hostLocalLlmRunning = derived(() => providerState[\"ollama\"]?.ollamaMode === \"running\" || detectedHostProviders.some((p) => p.provider === \"ollama\" || p.provider === \"lmstudio\"));\n\t\tlet opencodeProviders = [];\n\t\tlet opencodeAuth = {};\n\t\tlet allowEmptyInstall = false;\n\t\tlet recommendation = null;\n\t\tlet recommendationAlert = \"\";\n\t\tlet recommendationApplied = false;\n\t\tlet detectedGpuVramMb = 0;\n\t\tlet detectedGpuVendor = \"\";\n\t\tlet detectedGpuName = \"\";\n\t\t/** Generation counter per provider — discard stale verify results */\n\t\tconst verifyGeneration = {};\n\t\t/** AbortControllers for in-flight OAuth long-poll requests */\n\t\tconst oauthAbortControllers = {};\n\t\tlet modelSelection = {};\n\t\tlet voiceTts = { engine: \"\" };\n\t\tlet voiceStt = { engine: \"\" };\n\t\tconst enableVoice = derived(() => voiceTts.engine === \"openpalm-voice\" || voiceStt.engine === \"openpalm-voice\");\n\t\tlet voiceProfiles = [];\n\t\tlet selectedVoiceProfile = \"\";\n\t\tlet portalSelection = {\n\t\t\tdiscord: {\n\t\t\t\tenabled: false,\n\t\t\t\tbotToken: \"\",\n\t\t\t\tapplicationId: \"\"\n\t\t\t},\n\t\t\tslack: {\n\t\t\t\tenabled: false,\n\t\t\t\tslackBotToken: \"\",\n\t\t\t\tslackAppToken: \"\"\n\t\t\t}\n\t\t};\n\t\tlet ollamaEnabled = false;\n\t\tlet ollamaProfiles = [];\n\t\tlet selectedOllamaProfile = \"\";\n\t\tlet imageTag = \"\";\n\t\tlet installError = \"\";\n\t\tlet installing = false;\n\t\tlet deployData = {};\n\t\tlet deployDone = false;\n\t\tlet deployHasWarnings = false;\n\t\tlet deployError = null;\n\t\tlet deployTimer = null;\n\t\tlet deployPollErrors = 0;\n\t\tconst verifiedCount = derived(() => {\n\t\t\treturn PROVIDERS.map((p) => p.id).filter((id) => providerState[id]?.verified).length;\n\t\t});\n\t\tconst hasUsableAI = derived(() => !!modelSelection.llm?.model);\n\t\tconst verifiedProviders = derived(() => {\n\t\t\treturn PROVIDERS.filter((p) => providerState[p.id]?.verified);\n\t\t});\n\t\tconst canComplete = derived(() => !!modelSelection.llm?.model || allowEmptyInstall);\n\t\tconst hasOpenAI = derived(() => PROVIDERS.some((p) => p.id === \"openai\" && providerState[p.id]?.verified));\n\t\tconst voiceDefaults = derived(() => hasOpenAI() ? {\n\t\t\ttts: \"openai-tts\",\n\t\t\tstt: \"openai-stt\"\n\t\t} : {\n\t\t\ttts: \"browser-tts\",\n\t\t\tstt: \"browser-stt\"\n\t\t});\n\t\tconst displayedVoiceTts = derived(() => resolveVoiceSide(voiceTts, enableVoice(), voiceDefaults().tts));\n\t\tconst displayedVoiceStt = derived(() => resolveVoiceSide(voiceStt, enableVoice(), voiceDefaults().stt));\n\t\tconst persistedVoiceTts = derived(() => resolveVoiceSide(voiceTts, enableVoice(), \"\"));\n\t\tconst persistedVoiceStt = derived(() => resolveVoiceSide(voiceStt, enableVoice(), \"\"));\n\t\tconst payload = derived(() => {\n\t\t\tconst llm = modelSelection.llm;\n\t\t\tconst emb = modelSelection.embedding;\n\t\t\tconst small = modelSelection.small;\n\t\t\tconst capabilityProviderIds = {};\n\t\t\tif (llm) capabilityProviderIds[llm.connId] = true;\n\t\t\tif (emb) capabilityProviderIds[emb.connId] = true;\n\t\t\tif (small?.model) capabilityProviderIds[small.connId] = true;\n\t\t\tconst capabilities = verifiedProviders().filter((p) => capabilityProviderIds[p.id]).map((p) => {\n\t\t\t\tconst st = providerState[p.id];\n\t\t\t\treturn {\n\t\t\t\t\tid: p.id,\n\t\t\t\t\tname: p.name,\n\t\t\t\t\tprovider: p.id,\n\t\t\t\t\tbaseUrl: st?.baseUrl ?? p.baseUrl,\n\t\t\t\t\tapiKey: st?.apiKey ?? \"\"\n\t\t\t\t};\n\t\t\t});\n\t\t\tconst llmConnId = llm?.connId ?? \"\";\n\t\t\tconst embConnId = emb?.connId ?? \"\";\n\t\t\tconst llmCap = capabilities.find((c) => c.id === llmConnId);\n\t\t\tconst embCap = capabilities.find((c) => c.id === embConnId);\n\t\t\tconst llmProvider = llmCap?.provider ?? \"\";\n\t\t\tconst embProvider = embCap?.provider ?? \"\";\n\t\t\tconst addons = {};\n\t\t\tif (ollamaEnabled && !hostLocalLlmRunning()) addons.ollama = true;\n\t\t\tif (persistedVoiceTts().engine === \"openpalm-voice\" || persistedVoiceStt().engine === \"openpalm-voice\") addons.voice = true;\n\t\t\tconst portalCredentials = {};\n\t\t\tconst portalsConfig = buildPortalsConfig();\n\t\t\tfor (const chId of Object.keys(portalsConfig)) {\n\t\t\t\tconst chVal = portalsConfig[chId];\n\t\t\t\tif (chVal === true) addons[chId] = true;\n\t\t\t\telse if (typeof chVal === \"object\" && chVal !== null) {\n\t\t\t\t\taddons[chId] = true;\n\t\t\t\t\tconst creds = {};\n\t\t\t\t\tfor (const key of Object.keys(chVal)) if (key !== \"enabled\" && chVal[key]) creds[key] = String(chVal[key]);\n\t\t\t\t\tif (Object.keys(creds).length > 0) portalCredentials[chId] = creds;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst result = {\n\t\t\t\tversion: 2,\n\t\t\t\taddons,\n\t\t\t\tsecurity: { uiLoginPassword },\n\t\t\t\tconnections: capabilities\n\t\t\t};\n\t\t\tif (llmProvider && llm?.model) result.llm = {\n\t\t\t\tprovider: llmProvider,\n\t\t\t\tmodel: llm.model,\n\t\t\t\tbaseUrl: llmCap?.baseUrl ?? \"\"\n\t\t\t};\n\t\t\tif (embProvider && emb?.model) result.embedding = {\n\t\t\t\tprovider: embProvider,\n\t\t\t\tmodel: emb.model,\n\t\t\t\tdims: emb.dims ?? 1536,\n\t\t\t\tbaseUrl: embCap?.baseUrl ?? \"\"\n\t\t\t};\n\t\t\tconst voicePayload = (v) => {\n\t\t\t\tif (!v.engine || v.engine.startsWith(\"skip-\")) return void 0;\n\t\t\t\tconst out = {\n\t\t\t\t\tenabled: true,\n\t\t\t\t\tengine: v.engine\n\t\t\t\t};\n\t\t\t\tif (v.provider) out.provider = v.provider;\n\t\t\t\tif (v.baseURL) out.baseURL = v.baseURL;\n\t\t\t\tif (v.model) out.model = v.model;\n\t\t\t\tif (v.voice) out.voice = v.voice;\n\t\t\t\tif (v.language) out.language = v.language;\n\t\t\t\tif (v.apiKey) out.apiKey = v.apiKey;\n\t\t\t\treturn out;\n\t\t\t};\n\t\t\tconst ttsCap = voicePayload(persistedVoiceTts());\n\t\t\tif (ttsCap) result.tts = ttsCap;\n\t\t\tconst sttCap = voicePayload(persistedVoiceStt());\n\t\t\tif (sttCap) result.stt = sttCap;\n\t\t\tif ((persistedVoiceTts().engine === \"openpalm-voice\" || persistedVoiceStt().engine === \"openpalm-voice\") && selectedVoiceProfile) result.voiceProfile = selectedVoiceProfile;\n\t\t\tif (ollamaEnabled && selectedOllamaProfile) result.ollamaProfile = selectedOllamaProfile;\n\t\t\tif (Object.keys(portalCredentials).length > 0) result.portalCredentials = portalCredentials;\n\t\t\tif (imageTag.trim());\n\t\t\treturn result;\n\t\t});\n\t\tfunction buildPortalsConfig() {\n\t\t\tconst result = {};\n\t\t\tfor (const ch of PORTALS) {\n\t\t\t\tconst sel = portalSelection[ch.id];\n\t\t\t\tif (ch.locked) result[ch.id] = true;\n\t\t\t\telse if (typeof sel === \"object\" && sel !== null) {\n\t\t\t\t\tif (sel.enabled) {\n\t\t\t\t\t\tconst entry = { enabled: true };\n\t\t\t\t\t\tif (ch.credentials) for (const cred of ch.credentials) {\n\t\t\t\t\t\t\tconst v = sel[cred.key];\n\t\t\t\t\t\t\tif (v) entry[cred.key] = v;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tresult[ch.id] = entry;\n\t\t\t\t\t}\n\t\t\t\t} else if (sel) result[ch.id] = true;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\tfunction enableRecommendedOllama(variant) {\n\t\t\tollamaEnabled = true;\n\t\t\tconst st = providerState[\"ollama\"];\n\t\t\tif (st) {\n\t\t\t\tst.selected = true;\n\t\t\t\tst.verified = true;\n\t\t\t\tst.ollamaMode = \"instack\";\n\t\t\t\tst.baseUrl = \"http://ollama:11434\";\n\t\t\t\tif (st.models.length === 0) st.models = [OLLAMA_DEFAULT_CHAT_MODEL];\n\t\t\t}\n\t\t\tselectedOllamaProfile = selectAddonProfileId(ollamaProfiles, \"ollama\", gpuDetected, variant) ?? addonProfileId(\"ollama\", variant ?? (gpuDetected ? \"cuda\" : \"cpu\"));\n\t\t}\n\t\tconst LOCAL_PROVIDER_IDS = new Set([\n\t\t\t\"ollama\",\n\t\t\t\"lmstudio\",\n\t\t\t\"llamacpp\",\n\t\t\t\"localai\",\n\t\t\t\"model-runner\"\n\t\t]);\n\t\tlet savedCloudLlm = void 0;\n\t\tlet detectedCloudConn = modelSelection.llm && !LOCAL_PROVIDER_IDS.has(modelSelection.llm.connId) ? modelSelection.llm.connId : \"\";\n\t\tfunction handleConnectModeChange(mode) {\n\t\t\tmodelMode = mode;\n\t\t\tif (mode === \"local\") {\n\t\t\t\tif (modelSelection.llm && !LOCAL_PROVIDER_IDS.has(modelSelection.llm.connId)) savedCloudLlm = modelSelection.llm;\n\t\t\t\tif (!hostLocalLlmRunning()) enableRecommendedOllama();\n\t\t\t\tconst localOpt = getModelOptionsForRole(\"llm\").find((o) => LOCAL_PROVIDER_IDS.has(o.connId));\n\t\t\t\tmodelSelection.llm = localOpt ? {\n\t\t\t\t\tconnId: localOpt.connId,\n\t\t\t\t\tmodel: localOpt.id,\n\t\t\t\t\tdims: localOpt.dims\n\t\t\t\t} : {\n\t\t\t\t\tconnId: \"ollama\",\n\t\t\t\t\tmodel: OLLAMA_DEFAULT_CHAT_MODEL,\n\t\t\t\t\tdims: 0\n\t\t\t\t};\n\t\t\t} else if (mode === \"cloud\") {\n\t\t\t\tif (savedCloudLlm) modelSelection.llm = savedCloudLlm;\n\t\t\t}\n\t\t}\n\t\tasync function fetchAndApplyRecommendation() {\n\t\t\tif (recommendationApplied) return;\n\t\t\tlet rec;\n\t\t\tif (recommendation) rec = recommendation;\n\t\t\telse try {\n\t\t\t\tconst res = await fetch(\"/api/setup/recommend\");\n\t\t\t\tif (!res.ok) return;\n\t\t\t\tconst data = await res.json();\n\t\t\t\tif (!data.ok || !data.recommendation) return;\n\t\t\t\trec = data.recommendation;\n\t\t\t\tif (Array.isArray(data.hostProviders)) detectedHostProviders = data.hostProviders;\n\t\t\t\tif (data.gpu) {\n\t\t\t\t\tdetectedGpuVramMb = data.gpu.vramMb ?? 0;\n\t\t\t\t\tdetectedGpuVendor = data.gpu.vendor ?? \"\";\n\t\t\t\t\tdetectedGpuName = data.gpu.name ?? \"\";\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\trecommendationApplied = true;\n\t\t\trecommendation = rec;\n\t\t\tswitch (rec.action) {\n\t\t\t\tcase \"use-cloud\":\n\t\t\t\t\trecommendationAlert = \"\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"use-host-providers\":\n\t\t\t\t\trecommendationAlert = rec.alert;\n\t\t\t\t\tif (!hostImportTriggered) {\n\t\t\t\t\t\thostImportTriggered = true;\n\t\t\t\t\t\tawait handleHostImport();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"enable-ollama\":\n\t\t\t\t\trecommendationAlert = rec.alert;\n\t\t\t\t\tenableRecommendedOllama(rec.profileVariant);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"connect-manually\":\n\t\t\t\t\trecommendationAlert = rec.alert;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tfunction handleEnableVoiceChange(v) {\n\t\t\tif (v) {\n\t\t\t\tif (voiceTts.engine !== \"openpalm-voice\") voiceTts = { engine: \"openpalm-voice\" };\n\t\t\t\tif (voiceStt.engine !== \"openpalm-voice\") voiceStt = { engine: \"openpalm-voice\" };\n\t\t\t\tif (!selectedVoiceProfile) {\n\t\t\t\t\tconst match = selectAddonProfileId(voiceProfiles, \"voice\", gpuDetected);\n\t\t\t\t\tif (match) selectedVoiceProfile = match;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (voiceTts.engine === \"openpalm-voice\") voiceTts = { engine: \"\" };\n\t\t\t\tif (voiceStt.engine === \"openpalm-voice\") voiceStt = { engine: \"\" };\n\t\t\t}\n\t\t}\n\t\tfunction goToStep(n) {\n\t\t\tif (n < 0 || n > 3) return;\n\t\t\tif (n > 0 && !systemCheckPassed) return;\n\t\t\tcurrentStep = n;\n\t\t\tif (n > maxVisitedStep) maxVisitedStep = n;\n\t\t\tshowDeploy = false;\n\t\t\tif (n === 1 && !isRerun) {\n\t\t\t\tfetchAndApplyRecommendation();\n\t\t\t\tautoSelectModels();\n\t\t\t}\n\t\t}\n\t\tfunction autoSelectModels() {\n\t\t\tfor (const roleId of [\n\t\t\t\t\"llm\",\n\t\t\t\t\"embedding\",\n\t\t\t\t\"small\"\n\t\t\t]) {\n\t\t\t\tif (modelSelection[roleId]) continue;\n\t\t\t\tif (roleId === \"embedding\") continue;\n\t\t\t\tconst options = getModelOptionsForRole(roleId);\n\t\t\t\tif (options.length === 0) continue;\n\t\t\t\tconst best = options[0];\n\t\t\t\tmodelSelection[roleId] = {\n\t\t\t\t\tconnId: best.connId,\n\t\t\t\t\tmodel: best.id,\n\t\t\t\t\tdims: best.dims\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tfunction getModelOptionsForRole(roleId) {\n\t\t\treturn buildModelOptions(roleId, verifiedProviders(), providerState);\n\t\t}\n\t\tasync function apiFetchModels(provider, baseUrl, apiKey) {\n\t\t\tconst url = \"/api/setup/models/\" + encodeURIComponent(provider);\n\t\t\tconst res = await fetch(url, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tapiKey: apiKey ?? \"\",\n\t\t\t\t\tbaseUrl: baseUrl ?? \"\"\n\t\t\t\t})\n\t\t\t});\n\t\t\tconst data = await res.json();\n\t\t\tif (!res.ok || data.status === \"recoverable_error\") throw new Error(data.error ?? \"Failed to fetch models (HTTP \" + res.status + \")\");\n\t\t\treturn data;\n\t\t}\n\t\tasync function verifyProvider(id) {\n\t\t\tconst p = PROVIDERS.find((x) => x.id === id);\n\t\t\tif (!p) return;\n\t\t\tconst st = providerState[id];\n\t\t\tif (!st) return;\n\t\t\tif (id === \"ollama\" && st.ollamaMode === \"instack\") {\n\t\t\t\tst.verified = true;\n\t\t\t\tst.error = false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst gen = (verifyGeneration[id] ?? 0) + 1;\n\t\t\tverifyGeneration[id] = gen;\n\t\t\tst.verifying = true;\n\t\t\tst.error = false;\n\t\t\tconst baseUrl = (st.baseUrl || p.baseUrl).trim();\n\t\t\tconst apiKey = (st.apiKey ?? \"\").trim();\n\t\t\ttry {\n\t\t\t\tconst result = await apiFetchModels(id, baseUrl, apiKey);\n\t\t\t\tif (verifyGeneration[id] !== gen) return;\n\t\t\t\tst.verified = true;\n\t\t\t\tst.error = false;\n\t\t\t\tst.models = result.models ?? [];\n\t\t\t} catch (e) {\n\t\t\t\tif (verifyGeneration[id] !== gen) return;\n\t\t\t\tst.verified = false;\n\t\t\t\tst.error = true;\n\t\t\t\tst.errorMessage = e instanceof Error ? e.message : \"\";\n\t\t\t\tst.models = [];\n\t\t\t}\n\t\t\tst.verifying = false;\n\t\t}\n\t\tasync function startOpenCodeOAuth(providerId, methodIndex) {\n\t\t\tconst st = providerState[providerId];\n\t\t\tif (!st) return;\n\t\t\tst.verifying = true;\n\t\t\tst.error = false;\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(\"/api/setup/opencode/provider/\" + encodeURIComponent(providerId) + \"/oauth/authorize\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\tbody: JSON.stringify({ method: methodIndex })\n\t\t\t\t});\n\t\t\t\tconst oauthRes = await res.json();\n\t\t\t\tif (!res.ok) throw new Error(oauthRes.message ?? \"OAuth failed\");\n\t\t\t\tst.oauthPolling = true;\n\t\t\t\tst.oauthUrl = oauthRes.url ?? \"\";\n\t\t\t\tst.oauthInstructions = oauthRes.instructions ?? \"\";\n\t\t\t\tif (oauthRes.url && oauthRes.method === \"auto\") window.open(oauthRes.url, \"_blank\");\n\t\t\t\tawait pollOpenCodeOAuth(providerId, methodIndex);\n\t\t\t} catch (e) {\n\t\t\t\tst.verifying = false;\n\t\t\t\tst.error = true;\n\t\t\t\tst.errorMessage = e instanceof Error ? e.message : \"OAuth failed\";\n\t\t\t\tst.oauthPolling = false;\n\t\t\t}\n\t\t}\n\t\tasync function pollOpenCodeOAuth(providerId, methodIndex) {\n\t\t\tconst st = providerState[providerId];\n\t\t\tconst ac = new AbortController();\n\t\t\toauthAbortControllers[providerId] = ac;\n\t\t\tconst timeoutSignal = AbortSignal.timeout(10 * 6e4);\n\t\t\tconst combinedSignal = AbortSignal.any ? AbortSignal.any([ac.signal, timeoutSignal]) : ac.signal;\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(\"/api/setup/opencode/provider/\" + encodeURIComponent(providerId) + \"/oauth/callback\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\tbody: JSON.stringify({ method: methodIndex }),\n\t\t\t\t\tsignal: combinedSignal\n\t\t\t\t});\n\t\t\t\tconst data = await res.json().catch(() => null);\n\t\t\t\tif (res.ok && data?.ok) {\n\t\t\t\t\tst.verified = true;\n\t\t\t\t\tst.error = false;\n\t\t\t\t} else {\n\t\t\t\t\tst.error = true;\n\t\t\t\t\tst.errorMessage = data?.message ?? \"Authorization failed\";\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tif (e instanceof Error && e.name === \"AbortError\" && ac.signal.aborted) return;\n\t\t\t\tif (e instanceof Error && e.name === \"AbortError\") {\n\t\t\t\t\tst.error = true;\n\t\t\t\t\tst.errorMessage = \"Authorization timed out. Try again.\";\n\t\t\t\t} else {\n\t\t\t\t\tst.error = true;\n\t\t\t\t\tst.errorMessage = e instanceof Error ? e.message : \"Authorization failed\";\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tdelete oauthAbortControllers[providerId];\n\t\t\t\tst.oauthPolling = false;\n\t\t\t\tst.verifying = false;\n\t\t\t}\n\t\t}\n\t\tfunction stopDeployPolling() {\n\t\t\tif (deployTimer) {\n\t\t\t\tclearInterval(deployTimer);\n\t\t\t\tdeployTimer = null;\n\t\t\t}\n\t\t}\n\t\tasync function pollDeployStatus() {\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(\"/api/setup/deploy-status\");\n\t\t\t\tif (!res.ok) {\n\t\t\t\t\tdeployPollErrors++;\n\t\t\t\t\tif (deployPollErrors >= 5) {\n\t\t\t\t\t\tstopDeployPolling();\n\t\t\t\t\t\tdeployError = \"Lost contact with the installer. Services may still be starting in the background.\";\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst data = await res.json();\n\t\t\t\tdeployPollErrors = 0;\n\t\t\t\tdeployData = data;\n\t\t\t\tif (data.deployError) {\n\t\t\t\t\tstopDeployPolling();\n\t\t\t\t\tdeployError = data.deployError;\n\t\t\t\t} else if (data.setupComplete && data.deployStatus && data.deployStatus.length > 0) {\n\t\t\t\t\tconst rows = data.deployStatus;\n\t\t\t\t\tconst allRunning = rows.every((s) => s.status === \"running\");\n\t\t\t\t\tconst onlyWarningsLeft = !data.deploying && rows.every((s) => s.status === \"running\" || s.status === \"warning\") && rows.some((s) => s.status === \"warning\");\n\t\t\t\t\tif (allRunning) {\n\t\t\t\t\t\tstopDeployPolling();\n\t\t\t\t\t\tdeployDone = true;\n\t\t\t\t\t} else if (onlyWarningsLeft) {\n\t\t\t\t\t\tstopDeployPolling();\n\t\t\t\t\t\tdeployHasWarnings = true;\n\t\t\t\t\t\tdeployDone = true;\n\t\t\t\t\t}\n\t\t\t\t} else if (data.setupComplete && !data.deploying && (!data.deployStatus || data.deployStatus.length === 0)) {\n\t\t\t\t\tstopDeployPolling();\n\t\t\t\t\tdeployDone = true;\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tdeployPollErrors++;\n\t\t\t\tif (deployPollErrors >= 5) {\n\t\t\t\t\tstopDeployPolling();\n\t\t\t\t\tdeployError = err instanceof Error ? `Lost contact with the installer: ${err.message}` : \"Lost contact with the installer.\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfunction handlePortalToggle(id) {\n\t\t\tconst sel = portalSelection[id];\n\t\t\tif (typeof sel === \"object\" && sel !== null) sel.enabled = !sel.enabled;\n\t\t\telse portalSelection[id] = !sel;\n\t\t}\n\t\tfunction handleCredentialChange(chId, credKey, value) {\n\t\t\tconst sel = portalSelection[chId];\n\t\t\tif (typeof sel === \"object\" && sel !== null) sel[credKey] = value;\n\t\t}\n\t\tasync function handleDeployRetry() {\n\t\t\tinstalling = false;\n\t\t\tdeployError = null;\n\t\t\tdeployDone = false;\n\t\t\tdeployHasWarnings = false;\n\t\t\tdeployData = {};\n\t\t\tdeployPollErrors = 0;\n\t\t\tconst res = await fetch(\"/api/setup/retry-deploy\", { method: \"POST\" });\n\t\t\tconst payload = await res.json().catch(() => ({}));\n\t\t\tif (!res.ok || payload?.ok === false) {\n\t\t\t\tdeployError = payload?.message ?? \"Retry failed.\";\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tinstalling = true;\n\t\t\tpollDeployStatus();\n\t\t}\n\t\tfunction handleDeployBack() {\n\t\t\tinstalling = false;\n\t\t\tdeployError = null;\n\t\t\tdeployDone = false;\n\t\t\tdeployHasWarnings = false;\n\t\t\tdeployData = {};\n\t\t\tdeployPollErrors = 0;\n\t\t\tshowDeploy = false;\n\t\t\tcurrentStep = 3;\n\t\t}\n\t\tlet hostImportTriggered = false;\n\t\tlet hostImporting = false;\n\t\tfunction markProviderVerifiedFromImport(id) {\n\t\t\tlet st = providerState[id];\n\t\t\tif (!st) {\n\t\t\t\tst = {\n\t\t\t\t\tselected: true,\n\t\t\t\t\tverified: true,\n\t\t\t\t\tverifying: false,\n\t\t\t\t\terror: false,\n\t\t\t\t\tapiKey: \"\",\n\t\t\t\t\tbaseUrl: \"\",\n\t\t\t\t\tmodels: [],\n\t\t\t\t\tollamaMode: null\n\t\t\t\t};\n\t\t\t\tproviderState[id] = st;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tst.verified = true;\n\t\t\tst.error = false;\n\t\t}\n\t\tasync function handleHostImport() {\n\t\t\thostImporting = true;\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(\"/api/setup/import-host\", { method: \"POST\" });\n\t\t\t\tconst data = await res.json().catch(() => null);\n\t\t\t\tif (!res.ok || !data?.ok) {\n\t\t\t\t\thostImporting = false;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst importedIds = data.importedProviders ?? data.pushedProviders ?? [];\n\t\t\t\tfor (const id of importedIds) markProviderVerifiedFromImport(id);\n\t\t\t\tawait Promise.allSettled(Object.keys(providerState).filter((id) => !providerState[id].verified && PROVIDERS.some((p) => p.id === id)).map((id) => verifyProvider(id)));\n\t\t\t\tautoSelectModels();\n\t\t\t\thostImporting = false;\n\t\t\t\tif (!isRerun) goToStep(1);\n\t\t\t} catch {\n\t\t\t\thostImporting = false;\n\t\t\t}\n\t\t}\n\t\tlet isRerun = false;\n\t\thead(\"g40i6i\", $$renderer, ($$renderer) => {\n\t\t\t$$renderer.title(($$renderer) => {\n\t\t\t\t$$renderer.push(`<title>OpenPalm Setup</title>`);\n\t\t\t});\n\t\t});\n\t\t$$renderer.push(`<main class=\"setup-page\" aria-label=\"Setup wizard\">`);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (currentStep === 0 && !showDeploy) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div style=\"display:none\" aria-hidden=\"true\"><section class=\"step-content step-content--hidden\" id=\"step-0\" data-testid=\"step-system-check\">`);\n\t\t\tSystemCheckStep($$renderer, {\n\t\t\t\tisRerun,\n\t\t\t\tonpass: () => {\n\t\t\t\t\tsystemCheckPassed = true;\n\t\t\t\t\tgoToStep(1);\n\t\t\t\t},\n\t\t\t\tonnext: () => {\n\t\t\t\t\tsystemCheckPassed = true;\n\t\t\t\t\tgoToStep(1);\n\t\t\t\t},\n\t\t\t\tongpudetected: () => {\n\t\t\t\t\tgpuDetected = true;\n\t\t\t\t\tif (voiceProfiles.length > 0 && selectedVoiceProfile !== addonProfileId(\"voice\", \"cuda\")) {\n\t\t\t\t\t\tconst cuda = voiceProfiles.find((p) => p.id === addonProfileId(\"voice\", \"cuda\") && p.available !== false);\n\t\t\t\t\t\tif (cuda) selectedVoiceProfile = cuda.id;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\t$$renderer.push(`<!----></section></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (showDeploy) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div style=\"flex:1; padding: 32px; overflow-y: auto;\">`);\n\t\t\tDeployStep($$renderer, {\n\t\t\t\tdeployData,\n\t\t\t\tdeployDone,\n\t\t\t\tdeployHasWarnings,\n\t\t\t\tdeployError,\n\t\t\t\tonback: handleDeployBack,\n\t\t\t\tonretry: handleDeployRetry\n\t\t\t});\n\t\t\t$$renderer.push(`<!----></div>`);\n\t\t} else if (currentStep >= 1) {\n\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t$$renderer.push(`<header class=\"wiz-topbar\"><div class=\"wiz-wordmark\">`);\n\t\t\tIconLogo($$renderer, { size: 30 });\n\t\t\t$$renderer.push(`<!----> <b>OpenPalm</b><span>setup</span></div> <nav class=\"wiz-ticker\" aria-label=\"Setup steps\"><!--[-->`);\n\t\t\tconst each_array = ensure_array_like([\n\t\t\t\t{\n\t\t\t\t\tn: 1,\n\t\t\t\t\tlabel: \"Connect\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tn: 2,\n\t\t\t\t\tlabel: \"Add-ons\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tn: 3,\n\t\t\t\t\tlabel: \"Finish\"\n\t\t\t\t}\n\t\t\t]);\n\t\t\tfor (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {\n\t\t\t\tlet tick = each_array[$$index];\n\t\t\t\t$$renderer.push(`<div${attr_class(\"wiz-tick\", void 0, {\n\t\t\t\t\t\"wiz-tick--active\": currentStep === tick.n,\n\t\t\t\t\t\"wiz-tick--done\": currentStep > tick.n\n\t\t\t\t})}${attr(\"aria-current\", currentStep === tick.n ? \"step\" : void 0)}>`);\n\t\t\t\tif (currentStep > tick.n) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`<svg viewBox=\"0 0 12 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"12\" height=\"12\" aria-hidden=\"true\"><path d=\"M2 6l3 3 5-5\"></path></svg>`);\n\t\t\t\t} else {\n\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`<span class=\"wiz-tick-num\">${escape_html(tick.n)}</span>`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]--> ${escape_html(tick.label)}</div>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--></nav></header> <div class=\"wiz-stage\"><div class=\"wiz-content\"><div class=\"wiz-content-scroll\"><div class=\"wiz-eyebrow\">`);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`STEP 1 · Connect`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`STEP 2 · Add-ons`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`STEP 3 · Finish`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></div> <h1 class=\"wiz-title\">`);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`Connect your <span class=\"accent\">AI brain</span>`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`Optional <span class=\"accent\">extras</span>`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`You're all <span class=\"accent\">set</span>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></h1> <p class=\"wiz-lede\">`);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\tif (hasUsableAI()) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`We found an AI service already set up. Just continue, or choose something different.`);\n\t\t\t\t} else {\n\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`Your assistant needs a source of intelligence. Pick one and you're set — you can add more later.`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]-->`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`All optional — turn on only what you want now. You can add or remove anything later from your dashboard.`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`OpenPalm is ready to install. Save the password you'll use to sign in.`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></p> `);\n\t\t\tif (recommendationAlert && currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<div class=\"feedback feedback--warning\" role=\"alert\" data-testid=\"recommendation-alert\"><span>${escape_html(recommendationAlert)}</span></div>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<section class=\"step-content\" id=\"step-1\">`);\n\t\t\t\tScreen1ModelsStep($$renderer, {\n\t\t\t\t\tdetectionLoading: autoModeImporting,\n\t\t\t\t\tsystemCheckError: systemCheckPassed ? \"\" : \"\",\n\t\t\t\t\thostProviders: detectedHostProviders,\n\t\t\t\t\topencodeProviders,\n\t\t\t\t\topencodeAuth,\n\t\t\t\t\tproviderState,\n\t\t\t\t\tollamaEnabled,\n\t\t\t\t\tselectedOllamaProfile,\n\t\t\t\t\thostImporting,\n\t\t\t\t\tverifiedCount: verifiedCount(),\n\t\t\t\t\tallowEmptyInstall,\n\t\t\t\t\tllmModel: modelSelection.llm?.model ?? \"\",\n\t\t\t\t\tllmProvider: modelSelection.llm?.connId ?? \"\",\n\t\t\t\t\tdetectedCloudConn,\n\t\t\t\t\tgpuVramMb: detectedGpuVramMb,\n\t\t\t\t\tgpuVendor: detectedGpuVendor,\n\t\t\t\t\tgpuName: detectedGpuName,\n\t\t\t\t\tonmodelmodechange: handleConnectModeChange,\n\t\t\t\t\tonhostimport: () => void handleHostImport(),\n\t\t\t\t\tonoauthstart: startOpenCodeOAuth,\n\t\t\t\t\tonoauthcancel: (id) => {\n\t\t\t\t\t\tconst ac = oauthAbortControllers[id];\n\t\t\t\t\t\tif (ac) {\n\t\t\t\t\t\t\tac.abort();\n\t\t\t\t\t\t\tdelete oauthAbortControllers[id];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst st = providerState[id];\n\t\t\t\t\t\tif (st) {\n\t\t\t\t\t\t\tst.oauthPolling = false;\n\t\t\t\t\t\t\tst.verifying = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tonrecheck: () => void fetchAndApplyRecommendation(),\n\t\t\t\t\tonsystemcheckretry: () => {\n\t\t\t\t\t\tgoToStep(0);\n\t\t\t\t\t},\n\t\t\t\t\tonallowemptyinstallchange: (v) => {\n\t\t\t\t\t\tallowEmptyInstall = v;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t$$renderer.push(`<!----></section>`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`<section class=\"step-content\" id=\"step-2\">`);\n\t\t\t\tScreen2ExtrasStep($$renderer, {\n\t\t\t\t\tmodelMode,\n\t\t\t\t\tvoiceEnabled,\n\t\t\t\t\tvoiceTts: displayedVoiceTts(),\n\t\t\t\t\tvoiceStt: displayedVoiceStt(),\n\t\t\t\t\thasOpenAI: hasOpenAI(),\n\t\t\t\t\tportalSelection,\n\t\t\t\t\tonvoiceenabledchange: (v) => {\n\t\t\t\t\t\tvoiceEnabled = v;\n\t\t\t\t\t\thandleEnableVoiceChange(v);\n\t\t\t\t\t},\n\t\t\t\t\tonchangetts: (v) => {\n\t\t\t\t\t\tvoiceTts = v;\n\t\t\t\t\t},\n\t\t\t\t\tonchangestt: (v) => {\n\t\t\t\t\t\tvoiceStt = v;\n\t\t\t\t\t},\n\t\t\t\t\tonportaltoggle: handlePortalToggle,\n\t\t\t\t\toncredentialchange: handleCredentialChange\n\t\t\t\t});\n\t\t\t\t$$renderer.push(`<!----></section>`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`<section class=\"step-content\" id=\"step-3\" data-testid=\"step-review\">`);\n\t\t\t\tReviewStep($$renderer, {\n\t\t\t\t\tuiLoginPassword,\n\t\t\t\t\tverifiedProviders: verifiedProviders(),\n\t\t\t\t\tmodelSelection,\n\t\t\t\t\tactiveTts: voiceEnabled ? displayedVoiceTts().engine : \"\",\n\t\t\t\t\tactiveStt: voiceEnabled ? displayedVoiceStt().engine : \"\",\n\t\t\t\t\tportalSelection,\n\t\t\t\t\tollamaEnabled,\n\t\t\t\t\thostProviderLabel: detectedHostProviders.length > 0 ? detectedHostProviders[0].provider : \"\",\n\t\t\t\t\tpayload: payload(),\n\t\t\t\t\tinstallError,\n\t\t\t\t\tisRerun,\n\t\t\t\t\tsystemCheckPassed,\n\t\t\t\t\toneditmodels: () => goToStep(1),\n\t\t\t\t\toneditextras: () => goToStep(2)\n\t\t\t\t});\n\t\t\t\t$$renderer.push(`<!----></section>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></div> <footer class=\"wiz-footer\"><div class=\"wiz-footer-left\">`);\n\t\t\tif (currentStep > 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<button class=\"btn btn-secondary\" aria-label=\"Back\">Back</button>`);\n\t\t\t} else {\n\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<div></div>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--></div> <div class=\"wiz-footer-right\">`);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<button class=\"btn btn-primary\" id=\"btn-screen1-next\"${attr(\"disabled\", !canComplete(), true)}>`);\n\t\t\t\tif (modelSelection.llm?.connId && ![\n\t\t\t\t\t\"ollama\",\n\t\t\t\t\t\"lmstudio\",\n\t\t\t\t\t\"llamacpp\",\n\t\t\t\t\t\"localai\",\n\t\t\t\t\t\"model-runner\"\n\t\t\t\t].includes(modelSelection.llm.connId)) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`Use ${escape_html(modelSelection.llm.connId === \"openai\" ? \"ChatGPT\" : modelSelection.llm.connId === \"google\" ? \"Gemini\" : modelSelection.llm.connId === \"github-copilot\" ? \"GitHub Copilot\" : modelSelection.llm.connId === \"groq\" ? \"Groq\" : opencodeProviders.find((p) => p.id === modelSelection.llm.connId)?.name ?? modelSelection.llm.connId)} — Continue`);\n\t\t\t\t} else if (ollamaEnabled || detectedHostProviders.length > 0 || modelSelection.llm?.connId && [\n\t\t\t\t\t\"ollama\",\n\t\t\t\t\t\"lmstudio\",\n\t\t\t\t\t\"llamacpp\",\n\t\t\t\t\t\"localai\",\n\t\t\t\t\t\"model-runner\"\n\t\t\t\t].includes(modelSelection.llm.connId)) {\n\t\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t\t$$renderer.push(`Use local AI — Continue`);\n\t\t\t\t} else {\n\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`Continue`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]--></button>`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`<button class=\"btn btn-primary\" id=\"btn-screen2-next\">Continue</button>`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`<button class=\"btn btn-primary\" id=\"btn-install\"${attr(\"disabled\", !canComplete() || installing, true)}>`);\n\t\t\t\tif (installing) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`Installing...`);\n\t\t\t\t} else {\n\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`${escape_html(\"Install\")}`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]--></button>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></div></footer></div> <aside class=\"wiz-aside\" aria-label=\"Setup guide\"><div class=\"wiz-aside-top\"><img class=\"wiz-mascot\" src=\"/wizard-128.png\" alt=\"OpenPalm setup guide\"/> <div><b class=\"wiz-greet-name\">`);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\tif (hasUsableAI()) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`You're almost done!`);\n\t\t\t\t} else if (modelMode === \"local\" || ollamaEnabled || detectedHostProviders.length > 0) {\n\t\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t\t$$renderer.push(`Great choice.`);\n\t\t\t\t} else {\n\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`Pick what works for you.`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]-->`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`While you're here…`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`You're ready.`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></b> <span class=\"wiz-greet-sub\">`);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`Your setup guide`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`A few optional extras`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`Everything's in order`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></span></div></div> <p class=\"wiz-guide-lede\">`);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\tif (hasUsableAI()) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`We found an AI account on this computer. Just hit <strong>Continue</strong> and your assistant will use it automatically.`);\n\t\t\t\t} else if (modelMode === \"local\" || ollamaEnabled || detectedHostProviders.length > 0) {\n\t\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t\t$$renderer.push(`Running AI locally means your conversations never leave your machine. Perfect for privacy.`);\n\t\t\t\t} else {\n\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`Sign in once and you're set. A browser tab will open for you to log in — come back here when you're done, it connects automatically.`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]-->`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`All of this is optional. Skip this whole step if you want — your assistant works fine without any of these. You can turn them on whenever you're ready from the dashboard.`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`You're ready. Click <strong>Install OpenPalm</strong> and it'll start up in the background. The first launch pulls a few files — this takes a minute or two. When it's done, open your browser, sign in with that password, and you're good to go. Everything can be changed later from the dashboard.`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></p> <div class=\"wiz-guide-bullets\">`);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\tif (hasUsableAI()) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`<div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><path d=\"M9 12l2 2 4-4\"></path><circle cx=\"12\" cy=\"12\" r=\"9\"></circle></svg></div> <div>Your existing connection is ready to use. No extra setup needed — just continue to the next step.</div></div> <div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><path d=\"M12 3l1.5 4.5H18l-3.75 2.7 1.5 4.5L12 12l-3.75 2.7 1.5-4.5L6 7.5h4.5z\"></path></svg></div> <div>Want to use something different? Select another option from the list — you can switch any time from the dashboard.</div></div>`);\n\t\t\t\t} else {\n\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`<div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><circle cx=\"12\" cy=\"8\" r=\"4\"></circle><path d=\"M4 20c0-4 3.6-7 8-7s8 3 8 7\"></path></svg></div> <div><strong>Cloud services</strong> like ChatGPT are fast and easy — you just sign in.</div></div> <div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"12\" rx=\"2\"></rect><path d=\"M8 20h8M12 16v4\"></path></svg></div> <div><strong>Running locally</strong> keeps everything on your computer — private, free, no internet needed.</div></div>`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]-->`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`<div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><rect x=\"9\" y=\"3\" width=\"6\" height=\"11\" rx=\"3\"></rect><path d=\"M5 11a7 7 0 0014 0M12 18v3\"></path></svg></div> <div>Voice runs locally — free, no internet needed. A small model downloads the first time you use it.</div></div> <div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><circle cx=\"12\" cy=\"12\" r=\"9\"></circle><path d=\"M12 8v4l3 3\"></path></svg></div> <div>Setup help: <a href=\"https://discord.com/developers/docs/quick-start/getting-started\" target=\"_blank\" rel=\"noopener\">How to set up a Discord bot →</a></div></div> <div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><path d=\"M3 12h18M3 6h18M3 18h18\"></path></svg></div> <div><a href=\"https://api.slack.com/quickstart\" target=\"_blank\" rel=\"noopener\">How to set up a Slack app →</a></div></div>`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`<div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><rect x=\"3\" y=\"11\" width=\"18\" height=\"10\" rx=\"2\"></rect><path d=\"M7 11V7a5 5 0 0110 0v4\"></path></svg></div> <div>Your sign-in password is already saved on this computer — keep a copy somewhere safe just in case.</div></div> <div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><path d=\"M9 12l2 2 4-4\"></path><circle cx=\"12\" cy=\"12\" r=\"9\"></circle></svg></div> <div>Everything can be changed from the dashboard after install — providers, voice, portals, and more.</div></div>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></div> <div class=\"wiz-guide-privacy\"><svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" aria-hidden=\"true\"><path d=\"M8 1.5L2 4v4c0 3.3 2.5 5.8 6 6.5 3.5-.7 6-3.2 6-6.5V4L8 1.5z\"></path></svg> <span>It's your own assistant, running right here on your computer.</span></div></aside></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--></main>`);\n\t});\n}\n//#endregion\nexport { _page as default };\n"],"names":[],"mappings":";;;;;;AAkeA;AACA;AACA,SAAS,eAAe,CAAC,UAAU,EAAE,OAAO,EAAE;AAC9C,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,UAAU,KAAK;AAStC,EAAE,IAAI,OAAO,GAAG,IAAI;AACpB,EAAE,IAAI,MAAM,GAAG,IAAI;AAKnB,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,kHAAkH,CAAC,CAAC;AACvI,EAAE,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,0EAA0E,EAAE,UAAU,CAAC,6BAA6B,EAAE,MAAM,EAAE;AACjJ,GAAG,kBAAkB,EAAE,MAAM;AAC7B,GAAG,oBAAoB,EAAE;AACzB,GAAG,CAAC,CAAC,2CAA2C,CAAC,CAAC;AAClD,EAAE,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC;AAC9B,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AACnC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,0IAA0I,CAAC,CAAC;AAC/J,EAAE,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,yBAAyB,EAAE,UAAU,CAAC,6BAA6B,EAAE,MAAM,EAAE;AAChG,GAAG,kBAAkB,EAAE,MAAM;AAC7B,GAAG,oBAAoB,EAAE;AACzB,GAAG,CAAC,CAAC,2CAA2C,CAAC,CAAC;AAClD,EAAE,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC;AAC9B,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AACnC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,8IAA8I,CAAC,CAAC;AACnK,EAAE,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC,CAAC;AAC1C,EAAE,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;AAC9B,EAAE,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;AAC9B,EAAE,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,kGAAkG,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC,gEAAgE,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,wBAAwB,CAAC,CAAC;AAC/S,CAAC,CAAC,CAAC;AACH;AA2tBA;AACA;AACA,SAAS,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE;AACpC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,UAAU,KAAK;AA0BtC,EAAE,IAAI,cAAc,GAAG,EAAE;AAgKzB,EAAE,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC;AACrC,GAAG,QAAQ;AACX,GAAG,UAAU;AACb,GAAG,UAAU;AACb,GAAG,SAAS;AACZ,GAAG;AACH,GAAG,CAAC;AAEJ,EAA0B,cAAc,CAAC,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,GAAG;AA+UjI,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,UAAU,KAAK;AAC7C,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,UAAU,KAAK;AACpC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,6BAA6B,CAAC,CAAC;AACpD,GAAG,CAAC,CAAC;AACL,EAAE,CAAC,CAAC;AACJ,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,mDAAmD,CAAC,CAAC;AACxE,EAAE,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;AAC9B,EAAwC;AACxC,GAAG,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC;AAC/B,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,4IAA4I,CAAC,CAAC;AAClK,GAAG,eAAe,CAAC,UAiBf,CAAC;AACL,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,uBAAuB,CAAC,CAAC;AAC7C,EAAE;AACF,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;AAC9B,EAgTS,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;AACtC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,CAAC;AACpC,CAAC,CAAC,CAAC;AACH;;;;"}
1
+ {"version":3,"file":"_page.svelte-CqSffzxq.js","sources":["../../../.svelte-kit/adapter-node/entries/pages/setup/_page.svelte.js"],"sourcesContent":["import { $ as run, U as escape_html, V as attr, a as derived, n as attr_class, o as ensure_array_like, r as attr_style, s as head, u as stringify } from \"../../../chunks/dev.js\";\nimport \"../../../chunks/index-server.js\";\nimport { a as addonProfileId, n as OLLAMA_DEFAULT_CHAT_MODEL, t as KNOWN_EMBEDDING_MODEL_DIMS } from \"../../../chunks/provider-constants.js\";\nimport { t as resolve } from \"../../../chunks/paths.js\";\nimport \"../../../chunks/IconServer.js\";\nimport { t as Spinner } from \"../../../chunks/Spinner.js\";\nimport { t as IconMic } from \"../../../chunks/IconMic.js\";\nimport { t as IconLogo } from \"../../../chunks/IconLogo.js\";\nimport { n as IconAgent, t as IconAlert } from \"../../../chunks/IconAlert.js\";\n//#region src/lib/client/constants.ts\nvar PROVIDERS = [\n\t{\n\t\tid: \"ollama\",\n\t\tname: \"Ollama\",\n\t\tkind: \"local\",\n\t\tgroup: \"recommended\",\n\t\torder: 1,\n\t\ticon: \"🦙\",\n\t\tdesc: \"Run open models on your hardware\",\n\t\tneedsKey: false,\n\t\tplaceholder: \"\",\n\t\tbaseUrl: \"http://localhost:11434\",\n\t\tllmModel: \"llama3.2\",\n\t\tembModel: \"nomic-embed-text\",\n\t\tembDims: 768,\n\t\tcanDetect: true\n\t},\n\t{\n\t\tid: \"huggingface\",\n\t\tname: \"Hugging Face\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"recommended\",\n\t\torder: 2,\n\t\ticon: \"🤗\",\n\t\tdesc: \"10,000+ open models via Inference Providers\",\n\t\tneedsKey: true,\n\t\tplaceholder: \"hf_...\",\n\t\tbaseUrl: \"https://router.huggingface.co/v1\",\n\t\tllmModel: \"Qwen/Qwen3-32B\",\n\t\tembModel: \"intfloat/multilingual-e5-large\",\n\t\tembDims: 1024,\n\t\tkeyPrefix: \"hf_\"\n\t},\n\t{\n\t\tid: \"openai\",\n\t\tname: \"OpenAI\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"recommended\",\n\t\torder: 3,\n\t\ticon: \"◐\",\n\t\tdesc: \"GPT and o-series reasoning models\",\n\t\tneedsKey: true,\n\t\tplaceholder: \"sk-...\",\n\t\tbaseUrl: \"https://api.openai.com\",\n\t\tllmModel: \"gpt-4o\",\n\t\tembModel: \"text-embedding-3-small\",\n\t\tembDims: 1536\n\t},\n\t{\n\t\tid: \"google\",\n\t\tname: \"Google\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"recommended\",\n\t\torder: 4,\n\t\ticon: \"◆\",\n\t\tdesc: \"Gemini models with large context\",\n\t\tneedsKey: true,\n\t\tplaceholder: \"AIza...\",\n\t\tbaseUrl: \"https://generativelanguage.googleapis.com\",\n\t\tllmModel: \"gemini-2.5-flash\",\n\t\tembModel: \"\",\n\t\tembDims: 0,\n\t\tkeyPrefix: \"AI\"\n\t},\n\t{\n\t\tid: \"model-runner\",\n\t\tname: \"Docker Model Runner\",\n\t\tkind: \"local\",\n\t\tgroup: \"local\",\n\t\torder: 1,\n\t\ticon: \"🐳\",\n\t\tdesc: \"Docker-managed model runtime\",\n\t\tneedsKey: false,\n\t\tplaceholder: \"\",\n\t\tbaseUrl: \"http://localhost:12434\",\n\t\tllmModel: \"ai/llama3.2\",\n\t\tembModel: \"ai/mxbai-embed-large-v1\",\n\t\tembDims: 1024,\n\t\tcanDetect: true\n\t},\n\t{\n\t\tid: \"lmstudio\",\n\t\tname: \"LM Studio\",\n\t\tkind: \"local\",\n\t\tgroup: \"local\",\n\t\torder: 2,\n\t\ticon: \"🔬\",\n\t\tdesc: \"Desktop app for local inference\",\n\t\tneedsKey: false,\n\t\tplaceholder: \"\",\n\t\tbaseUrl: \"http://localhost:1234\",\n\t\tllmModel: \"loaded-model\",\n\t\tembModel: \"\",\n\t\tembDims: 0,\n\t\tcanDetect: true\n\t},\n\t{\n\t\tid: \"groq\",\n\t\tname: \"Groq\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"cloud\",\n\t\torder: 1,\n\t\ticon: \"⚡\",\n\t\tdesc: \"Ultra-fast inference\",\n\t\tneedsKey: true,\n\t\tplaceholder: \"gsk_...\",\n\t\tbaseUrl: \"https://api.groq.com/openai\",\n\t\tllmModel: \"llama-3.3-70b-versatile\",\n\t\tembModel: \"\",\n\t\tembDims: 0\n\t},\n\t{\n\t\tid: \"mistral\",\n\t\tname: \"Mistral\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"cloud\",\n\t\torder: 2,\n\t\ticon: \"◆\",\n\t\tdesc: \"Mistral & Codestral models\",\n\t\tneedsKey: true,\n\t\tplaceholder: \"...\",\n\t\tbaseUrl: \"https://api.mistral.ai\",\n\t\tllmModel: \"mistral-large-latest\",\n\t\tembModel: \"mistral-embed\",\n\t\tembDims: 1024\n\t},\n\t{\n\t\tid: \"together\",\n\t\tname: \"Together AI\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"cloud\",\n\t\torder: 3,\n\t\ticon: \"✦\",\n\t\tdesc: \"Open models at scale\",\n\t\tneedsKey: true,\n\t\tplaceholder: \"...\",\n\t\tbaseUrl: \"https://api.together.xyz\",\n\t\tllmModel: \"meta-llama/Llama-3.3-70B-Instruct-Turbo\",\n\t\tembModel: \"\",\n\t\tembDims: 0\n\t},\n\t{\n\t\tid: \"deepseek\",\n\t\tname: \"DeepSeek\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"advanced\",\n\t\torder: 1,\n\t\ticon: \"◎\",\n\t\tdesc: \"DeepSeek chat & reasoning\",\n\t\tneedsKey: true,\n\t\tplaceholder: \"sk-...\",\n\t\tbaseUrl: \"https://api.deepseek.com\",\n\t\tllmModel: \"deepseek-chat\",\n\t\tembModel: \"\",\n\t\tembDims: 0\n\t},\n\t{\n\t\tid: \"xai\",\n\t\tname: \"xAI (Grok)\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"advanced\",\n\t\torder: 2,\n\t\ticon: \"✦\",\n\t\tdesc: \"Grok models\",\n\t\tneedsKey: true,\n\t\tplaceholder: \"xai-...\",\n\t\tbaseUrl: \"https://api.x.ai\",\n\t\tllmModel: \"grok-2\",\n\t\tembModel: \"\",\n\t\tembDims: 0\n\t},\n\t{\n\t\tid: \"openai-compatible\",\n\t\tname: \"Custom API server\",\n\t\tkind: \"cloud\",\n\t\tgroup: \"advanced\",\n\t\torder: 3,\n\t\ticon: \"~\",\n\t\tdesc: \"Connect any AI server that uses the standard OpenAI API format.\",\n\t\tneedsKey: false,\n\t\tneedsUrl: true,\n\t\toptionalKey: true,\n\t\tplaceholder: \"API key (optional)\",\n\t\tbaseUrl: \"\",\n\t\tllmModel: \"\",\n\t\tembModel: \"\",\n\t\tembDims: 0\n\t}\n];\n/** Provider IDs excluded from the setup wizard's OAuth provider list. */\nvar WIZARD_EXCLUDED_PROVIDERS = new Set([\"anthropic\"]);\nvar PORTALS = [\n\t{\n\t\tid: \"api\",\n\t\tname: \"API\",\n\t\ticon: \"🔌\",\n\t\tdesc: \"OpenAI-compatible REST API endpoint\",\n\t\tlocked: true\n\t},\n\t{\n\t\tid: \"discord\",\n\t\tname: \"Discord\",\n\t\ticon: \"🎮\",\n\t\tdesc: \"Connect to a Discord server\",\n\t\tcredentials: [{\n\t\t\tkey: \"botToken\",\n\t\t\tlabel: \"Bot Token\",\n\t\t\tplaceholder: \"Paste Discord bot token\",\n\t\t\trequired: true\n\t\t}, {\n\t\t\tkey: \"applicationId\",\n\t\t\tlabel: \"Application ID\",\n\t\t\tplaceholder: \"Discord application ID\",\n\t\t\tsecret: false\n\t\t}]\n\t},\n\t{\n\t\tid: \"slack\",\n\t\tname: \"Slack\",\n\t\ticon: \"💼\",\n\t\tdesc: \"Access via Slack bot\",\n\t\tcredentials: [{\n\t\t\tkey: \"slackBotToken\",\n\t\t\tlabel: \"Bot Token\",\n\t\t\tplaceholder: \"xoxb-...\",\n\t\t\trequired: true\n\t\t}, {\n\t\t\tkey: \"slackAppToken\",\n\t\t\tlabel: \"App Token\",\n\t\t\tplaceholder: \"xapp-...\",\n\t\t\trequired: true\n\t\t}]\n\t}\n];\n//#endregion\n//#region src/lib/client/helpers.ts\nfunction selectAddonProfileId(profiles, addon, gpuDetected, variant) {\n\tconst avail = (p) => p.available !== false;\n\tconst preferred = addonProfileId(addon, variant ?? (gpuDetected ? \"cuda\" : \"cpu\"));\n\tconst cpu = addonProfileId(addon, \"cpu\");\n\treturn (profiles.find((p) => p.id === preferred && avail(p)) ?? profiles.find((p) => p.default && avail(p)) ?? profiles.find((p) => p.id === cpu && avail(p)) ?? profiles.find((p) => avail(p)))?.id;\n}\n/** Strip an Ollama-style \":tag\" suffix so \"llama3.2\" matches \"llama3.2:latest\". */\nfunction baseModelId(model) {\n\treturn model.replace(/:.*$/, \"\");\n}\n/** True for embedding models — never offered/auto-picked for the chat/small role. */\nfunction isEmbeddingModelId(model) {\n\tconst base = baseModelId(model);\n\tif (KNOWN_EMBEDDING_MODEL_DIMS[model] !== void 0 || KNOWN_EMBEDDING_MODEL_DIMS[base] !== void 0) return true;\n\treturn /(?:^|[-/_.])(embed|embedding|bge|gte|e5|nomic|mxbai|arctic-embed|minilm)/i.test(model);\n}\n/** Heuristic score for a chat ('llm') or 'small' model. Higher = better default. */\nfunction scoreModelForRole(roleId, model) {\n\tconst m = model.toLowerCase();\n\tlet s = 0;\n\tif (/instruct|chat|-it\\b|\\bit\\b/.test(m)) s += 30;\n\tif (/coder|code/.test(m)) s += 8;\n\tconst sizeMatch = m.match(/(\\d+(?:\\.\\d+)?)\\s*x?\\s*b\\b/);\n\tconst sizeB = sizeMatch ? parseFloat(sizeMatch[1]) : 0;\n\tif (roleId === \"llm\") s += Math.min(40, sizeB);\n\telse s += Math.max(0, 20 - Math.min(20, sizeB));\n\treturn s;\n}\nvar LOCAL_PROVIDER_IDS = new Set([\n\t\"ollama\",\n\t\"lmstudio\",\n\t\"model-runner\"\n]);\n/**\n* Build the ranked list of model options for a role across all verified\n* providers. For chat/small: embedding models are excluded and results are\n* ordered best-first (host/cloud before local, provider's declared default,\n* then the role heuristic) so options[0] is the sensible auto-pick. For\n* embedding: only real embedding models are returned (may be empty — akm\n* self-embeds locally, so an empty list is fine and the role is auto-handled).\n*/\nfunction buildModelOptions(roleId, verifiedProviders, providerState) {\n\tconst options = [];\n\tfor (const p of verifiedProviders) {\n\t\tconst st = providerState[p.id];\n\t\tif (!st) continue;\n\t\tconst defaultModel = roleId === \"embedding\" ? p.embModel : p.llmModel;\n\t\tconst models = st.models.length > 0 ? st.models : [];\n\t\tconst matchedDefault = defaultModel ? models.find((m) => m === defaultModel || baseModelId(m) === baseModelId(defaultModel)) : void 0;\n\t\tfor (const m of models) {\n\t\t\tif (roleId !== \"embedding\" && isEmbeddingModelId(m)) continue;\n\t\t\tconst dims = roleId === \"embedding\" ? KNOWN_EMBEDDING_MODEL_DIMS[m] ?? KNOWN_EMBEDDING_MODEL_DIMS[baseModelId(m)] ?? (m === matchedDefault ? p.embDims : 0) ?? 0 : 0;\n\t\t\toptions.push({\n\t\t\t\tid: m,\n\t\t\t\tconnId: p.id,\n\t\t\t\tproviderName: p.name,\n\t\t\t\tbaseUrl: st.baseUrl || p.baseUrl,\n\t\t\t\tisDefault: m === matchedDefault,\n\t\t\t\tdims\n\t\t\t});\n\t\t}\n\t}\n\tif (roleId === \"embedding\") return options.filter((o) => o.isDefault || o.dims > 0);\n\treturn options.sort((a, b) => (LOCAL_PROVIDER_IDS.has(a.connId) ? 1 : 0) - (LOCAL_PROVIDER_IDS.has(b.connId) ? 1 : 0) || (b.isDefault ? 1 : 0) - (a.isDefault ? 1 : 0) || scoreModelForRole(roleId, b.id) - scoreModelForRole(roleId, a.id));\n}\n/**\n* Resolve which voice engine to use for one side (TTS or STT).\n*\n* - An explicit engine in `side` wins unconditionally.\n* - No explicit engine + bundled voice enabled → openpalm-voice.\n* - No explicit engine + bundled voice off → fallback engine (e.g. 'browser-tts').\n*\n* Pass fallbackEngine='' for the \"persisted\" form (nothing saved when untouched).\n* Pass a concrete fallback for the \"displayed\" form so the UI shows the real default.\n*/\nfunction resolveVoiceSide(side, enableVoice, fallbackEngine) {\n\tif (side.engine) return side;\n\tif (enableVoice) return { engine: \"openpalm-voice\" };\n\treturn { engine: fallbackEngine };\n}\nfunction isPortalEnabled(portalSelection, chId, locked) {\n\tif (locked) return true;\n\tconst sel = portalSelection[chId];\n\tif (typeof sel === \"object\" && sel !== null) return sel.enabled;\n\treturn !!sel;\n}\nfunction getCredValue(portalSelection, chId, key) {\n\tconst sel = portalSelection[chId];\n\tif (typeof sel === \"object\" && sel !== null) return String(sel[key] ?? \"\");\n\treturn \"\";\n}\n//#endregion\n//#region src/lib/components/common/FriendlyError.svelte\nfunction FriendlyError($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t/** Render compactly without the technical-details disclosure (inline forms). */\n\t\tlet { error, role = \"alert\", compact = false } = $$props;\n\t\tif (error) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"friendly-error svelte-iqsgzf\"${attr(\"role\", role)}><div class=\"friendly-error-header svelte-iqsgzf\">`);\n\t\t\tIconAlert($$renderer, { size: 18 });\n\t\t\t$$renderer.push(`<!----> <strong class=\"friendly-error-title svelte-iqsgzf\">${escape_html(error.title)}</strong></div> `);\n\t\t\tif (error.body) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<p class=\"friendly-error-body svelte-iqsgzf\">${escape_html(error.body)}</p>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\tif (error.hint) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<p class=\"friendly-error-hint svelte-iqsgzf\">${escape_html(error.hint)}</p>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\tif (error.links && error.links.length > 0) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<div class=\"friendly-error-links svelte-iqsgzf\"><!--[-->`);\n\t\t\t\tconst each_array = ensure_array_like(error.links);\n\t\t\t\tfor (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {\n\t\t\t\t\tlet link = each_array[$$index];\n\t\t\t\t\t$$renderer.push(`<a${attr(\"href\", link.href)} target=\"_blank\" rel=\"noopener noreferrer\" class=\"friendly-error-link svelte-iqsgzf\">${escape_html(link.label)} →</a>`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]--></div>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\tif (!compact && error.raw && error.raw !== error.body) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<details class=\"friendly-error-details svelte-iqsgzf\"><summary class=\"svelte-iqsgzf\">Technical details</summary> <pre class=\"svelte-iqsgzf\">${escape_html(error.raw)}</pre></details>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]-->`);\n\t});\n}\n//#endregion\n//#region src/lib/client/error-messages.ts\nvar DOCKER_LINK = {\n\tlabel: \"Docker setup\",\n\thref: \"https://docs.docker.com/get-docker/\"\n};\nfunction rawText(raw) {\n\tif (!raw) return \"\";\n\tif (raw instanceof Error) return raw.message;\n\tif (typeof raw === \"string\") return raw;\n\ttry {\n\t\treturn JSON.stringify(raw);\n\t} catch {\n\t\treturn String(raw);\n\t}\n}\nfunction friendlyError(raw, context = \"generic\", opts = {}) {\n\tconst text = rawText(raw);\n\tconst lower = text.toLowerCase();\n\tconst providerLabel = opts.providerName ? `${opts.providerName} didn't accept that key` : \"API key rejected\";\n\tif (/\\b(401|403|unauthorized|forbidden|invalid.?api.?key)\\b/i.test(text)) return {\n\t\ttitle: providerLabel,\n\t\tbody: \"The provider rejected the API key.\",\n\t\thint: \"Common causes: extra spaces, wrong account, or the key was revoked. Double-check the key and that it has access to the model you selected. Most providers show the key in their dashboard.\",\n\t\traw: text\n\t};\n\tif (/\\b(ENOTFOUND|ECONNREFUSED|getaddrinfo|EAI_AGAIN|EHOSTUNREACH)\\b/i.test(text)) return {\n\t\ttitle: \"Couldn't reach the host\",\n\t\tbody: text,\n\t\thint: \"Confirm the URL is correct and the service is online. For local providers (Ollama, LM Studio) make sure the server is running on this machine.\",\n\t\traw: text\n\t};\n\tif (/(timeout|timed out|AbortError|ETIMEDOUT)/i.test(text)) return {\n\t\ttitle: \"Request timed out\",\n\t\tbody: \"The provider didn't respond in time.\",\n\t\thint: \"It may be slow or temporarily down. Try again in a moment.\",\n\t\traw: text\n\t};\n\tif (lower.includes(\"docker\") || lower.includes(\"compose\") || lower.includes(\"daemon\")) return {\n\t\ttitle: \"Docker isn't available\",\n\t\tbody: \"OpenPalm needs Docker (with Compose v2) installed and running.\",\n\t\thint: \"Start Docker Desktop (macOS/Windows) or the docker daemon (Linux), then retry.\",\n\t\tlinks: [DOCKER_LINK],\n\t\traw: text\n\t};\n\tif (/EADDRINUSE/i.test(text) || /port.*in.?use/i.test(lower)) return {\n\t\ttitle: \"A required port is already in use\",\n\t\tbody: text,\n\t\thint: \"Another program is using one of OpenPalm's default ports. Quit the conflicting app, or change OpenPalm's port from the Admin Dashboard after setup.\",\n\t\traw: text\n\t};\n\tif (/EACCES|EPERM|permission denied/i.test(text)) return {\n\t\ttitle: \"Permission denied\",\n\t\tbody: text,\n\t\thint: \"OpenPalm couldn't write to its data directory. Check that ~/.openpalm/ is writable by your user.\",\n\t\traw: text\n\t};\n\tswitch (context) {\n\t\tcase \"provider-verify\":\n\t\tcase \"model-fetch\": return {\n\t\t\ttitle: \"Couldn't connect to the provider\",\n\t\t\tbody: text || \"Verification failed.\",\n\t\t\thint: \"Check the API key and base URL, then click Verify again.\",\n\t\t\traw: text\n\t\t};\n\t\tcase \"setup-complete\": return {\n\t\t\ttitle: \"Setup couldn't finish\",\n\t\t\tbody: text || \"Writing configuration failed.\",\n\t\t\thint: \"Check the technical details below, then retry. If the issue persists, the admin dashboard logs may help.\",\n\t\t\traw: text\n\t\t};\n\t\tcase \"deploy\":\n\t\tcase \"deploy-poll\": return {\n\t\t\ttitle: \"Deployment ran into a problem\",\n\t\t\tbody: text || \"One or more services failed to start.\",\n\t\t\thint: \"Image pulls can take several minutes on first install. Retry to attempt again; check Docker logs if it keeps failing.\",\n\t\t\traw: text\n\t\t};\n\t\tcase \"system-check\": return {\n\t\t\ttitle: \"System check failed\",\n\t\t\tbody: text || \"A required dependency is missing.\",\n\t\t\thint: \"Resolve the failing check above, then click Retry.\",\n\t\t\traw: text\n\t\t};\n\t\tcase \"portal\": return {\n\t\t\ttitle: \"Portal credential issue\",\n\t\t\tbody: text || \"A required field is missing or invalid.\",\n\t\t\thint: \"Confirm the bot token and other required fields are correct.\",\n\t\t\traw: text\n\t\t};\n\t\tcase \"port-conflict\": return {\n\t\t\ttitle: \"A required port is already in use\",\n\t\t\tbody: text || \"Another process is using one of OpenPalm's ports.\",\n\t\t\thint: \"Another program is using one of OpenPalm's default ports. Quit the conflicting app, or change OpenPalm's port from the Admin Dashboard after setup.\",\n\t\t\traw: text\n\t\t};\n\t\tdefault: return {\n\t\t\ttitle: \"Something went wrong\",\n\t\t\tbody: text || \"An unexpected error occurred.\",\n\t\t\thint: \"Try again. If the problem persists, check the admin dashboard logs.\",\n\t\t\traw: text\n\t\t};\n\t}\n}\n//#endregion\n//#region src/routes/setup/steps/SystemCheckStep.svelte\nfunction SystemCheckStep($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\tnew Set([\n\t\t\t\"ollama\",\n\t\t\t\"lmstudio\",\n\t\t\t\"model-runner\"\n\t\t]);\n\t\t/** True when re-running an existing install; suppresses misleading\n\t\t* port-conflict warnings that just reflect the running stack itself. */\n\t\tlet { onnext, onpass, ongpudetected, isRerun = false } = $$props;\n\t\tlet loading = true;\n\t\tlet result = null;\n\t\tconst portConflicts = derived(() => isRerun ? [] : []);\n\t\tconst blockingPortConflicts = derived(() => portConflicts().filter((p) => p.blocking));\n\t\tderived(() => blockingPortConflicts().length > 0);\n\t\tderived(() => false);\n\t\t$$renderer.push(`<h2>System Check</h2> <p class=\"step-description\">Let's make sure your machine has everything OpenPalm needs.</p> `);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> <div class=\"syscheck-list svelte-1txhq2p\" aria-live=\"polite\"><div${attr_class(\"syscheck-row svelte-1txhq2p\", void 0, {\n\t\t\t\"syscheck-row--ok\": void 0,\n\t\t\t\"syscheck-row--fail\": result\n\t\t})}><div class=\"syscheck-icon svelte-1txhq2p\">`);\n\t\t$$renderer.push(\"<!--[0-->\");\n\t\tSpinner($$renderer, { size: 16 });\n\t\t$$renderer.push(`<!--]--></div> <div class=\"syscheck-body svelte-1txhq2p\"><div class=\"syscheck-title svelte-1txhq2p\">Docker is installed and running</div> `);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--></div></div> <div${attr_class(\"syscheck-row svelte-1txhq2p\", void 0, {\n\t\t\t\"syscheck-row--ok\": void 0,\n\t\t\t\"syscheck-row--fail\": result\n\t\t})}><div class=\"syscheck-icon svelte-1txhq2p\">`);\n\t\t$$renderer.push(\"<!--[0-->\");\n\t\tSpinner($$renderer, { size: 16 });\n\t\t$$renderer.push(`<!--]--></div> <div class=\"syscheck-body svelte-1txhq2p\"><div class=\"syscheck-title svelte-1txhq2p\">Docker can run multi-container apps</div> `);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--></div></div> `);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--></div> <div class=\"step-actions\"><button class=\"btn btn-secondary\" id=\"btn-syscheck-retry\"${attr(\"disabled\", loading, true)}>${escape_html(\"Checking…\")}</button> <button class=\"btn btn-primary\" id=\"btn-syscheck-next\"${attr(\"disabled\", loading, true)}>Continue</button></div>`);\n\t});\n}\n//#endregion\n//#region src/routes/setup/steps/ProviderOAuthList.svelte\nfunction ProviderOAuthList($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t/**\n\t\t* ProviderOAuthList — OAuth provider list for CloudAttachPanel.\n\t\t*\n\t\t* Renders a compact vertical list of OAuth-capable providers,\n\t\t* filtered through WIZARD_EXCLUDED_PROVIDERS (no Anthropic).\n\t\t*\n\t\t* Props:\n\t\t* opencodeProviders — full list from /api/setup/recommend\n\t\t* opencodeAuth — auth methods per provider id\n\t\t* providerState — current verification state per provider id\n\t\t* onoauthstart — called when the user clicks \"Sign in\" for a provider\n\t\t* onoauthcancel — called when OAuth poll should be aborted\n\t\t*/\n\t\tlet { opencodeProviders, opencodeAuth, providerState, onoauthstart, onoauthcancel } = $$props;\n\t\tconst RECOGNIZABLE_FIRST = [\n\t\t\t\"openai\",\n\t\t\t\"google\",\n\t\t\t\"github-copilot\",\n\t\t\t\"groq\",\n\t\t\t\"mistral\",\n\t\t\t\"huggingface\"\n\t\t];\n\t\tconst filteredProviders = derived(() => opencodeProviders.filter((p) => {\n\t\t\tif (WIZARD_EXCLUDED_PROVIDERS.has(p.id)) return false;\n\t\t\tif (providerState[p.id]?.verified) return false;\n\t\t\treturn (opencodeAuth[p.id] ?? []).some((m) => m.type === \"oauth\");\n\t\t}).sort((a, b) => {\n\t\t\tconst ia = RECOGNIZABLE_FIRST.indexOf(a.id);\n\t\t\tconst ib = RECOGNIZABLE_FIRST.indexOf(b.id);\n\t\t\treturn (ia === -1 ? 99 : ia) - (ib === -1 ? 99 : ib);\n\t\t}));\n\t\tconst OAUTH_CAP = 4;\n\t\tconst visibleOauth = derived(() => filteredProviders().slice(0, OAUTH_CAP));\n\t\tconst hiddenOauthCount = derived(() => Math.max(0, filteredProviders().length - OAUTH_CAP));\n\t\tfunction getState(id) {\n\t\t\treturn providerState[id] ?? {\n\t\t\t\tselected: false,\n\t\t\t\tverified: false,\n\t\t\t\tverifying: false,\n\t\t\t\terror: false,\n\t\t\t\tapiKey: \"\",\n\t\t\t\tbaseUrl: \"\",\n\t\t\t\tmodels: [],\n\t\t\t\tollamaMode: null\n\t\t\t};\n\t\t}\n\t\tfunction oauthMethodIndex(id) {\n\t\t\treturn (opencodeAuth[id] ?? []).findIndex((m) => m.type === \"oauth\");\n\t\t}\n\t\t$$renderer.push(`<div class=\"oauth-list svelte-1kgjxt0\" role=\"list\">`);\n\t\tif (filteredProviders().length === 0) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<p class=\"oauth-empty svelte-1kgjxt0\">Nothing more to add — you're all connected.</p>`);\n\t\t} else {\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--[-->`);\n\t\t\tconst each_array = ensure_array_like(visibleOauth());\n\t\t\tfor (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {\n\t\t\t\tlet provider = each_array[$$index];\n\t\t\t\tconst st = getState(provider.id);\n\t\t\t\toauthMethodIndex(provider.id);\n\t\t\t\t$$renderer.push(`<div class=\"oauth-row svelte-1kgjxt0\" role=\"listitem\"${attr(\"data-provider\", provider.id)}><span class=\"oauth-name svelte-1kgjxt0\">${escape_html(provider.name)}</span> `);\n\t\t\t\tif (st.verified) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`<span class=\"oauth-status oauth-status--ok svelte-1kgjxt0\"${attr(\"aria-label\", `${stringify(provider.name)} connected`)}>Connected ✓</span>`);\n\t\t\t\t} else if (st.oauthPolling) {\n\t\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t\t$$renderer.push(`<div class=\"oauth-polling svelte-1kgjxt0\">`);\n\t\t\t\t\tif (st.oauthUrl) {\n\t\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t\t$$renderer.push(`<a${attr(\"href\", st.oauthUrl)} target=\"_blank\" rel=\"noopener\" class=\"oauth-open-link svelte-1kgjxt0\">Open authorization page →</a>`);\n\t\t\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\t\t\tif (st.oauthInstructions) {\n\t\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t\t$$renderer.push(`<p class=\"oauth-instructions svelte-1kgjxt0\">${escape_html(st.oauthInstructions)}</p>`);\n\t\t\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`<!--]--> <div class=\"oauth-waiting svelte-1kgjxt0\">`);\n\t\t\t\t\tSpinner($$renderer, {});\n\t\t\t\t\t$$renderer.push(`<!----> Waiting for authorization…</div> <button type=\"button\" class=\"btn-oauth-cancel svelte-1kgjxt0\">Cancel</button></div>`);\n\t\t\t\t} else {\n\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`<button type=\"button\" class=\"btn btn-secondary btn-sm\"${attr(\"disabled\", st.verifying, true)}>${escape_html(st.verifying ? \"Signing in…\" : \"Sign in\")}</button>`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\t\tif (st.error && !st.oauthPolling) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`<span class=\"oauth-error svelte-1kgjxt0\" role=\"alert\">${escape_html(st.errorMessage ?? \"Authorization failed\")}</span>`);\n\t\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<!--]--></div>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\tif (hiddenOauthCount() > 0) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<button type=\"button\" class=\"oauth-more svelte-1kgjxt0\">${escape_html(`Show ${hiddenOauthCount()} more services`)}</button>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]-->`);\n\t\t}\n\t\t$$renderer.push(`<!--]--></div>`);\n\t});\n}\n//#endregion\n//#region src/routes/setup/steps/CloudAttachPanel.svelte\nfunction CloudAttachPanel($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t/**\n\t\t* CloudAttachPanel — the simplest possible \"connect your AI\" step.\n\t\t*\n\t\t* Two states only, no jargon:\n\t\t* - An AI account was found on this computer → one \"Use this account\" button.\n\t\t* - Otherwise (or \"use a different account\") → sign-in buttons.\n\t\t*\n\t\t* Deliberately NO provider count/list, NO \"other options\", and NO custom\n\t\t* endpoint / API-key fields — those are power-user concerns that live in the\n\t\t* admin dashboard after setup, not in first-run.\n\t\t*/\n\t\tlet { credentialCount = 0, cloudProviders = [], opencodeProviders = [], opencodeAuth = {}, providerState = {}, hostImporting = false, verifiedCount = 0, onhostimport, onoauthstart, onoauthcancel } = $$props;\n\t\tconst hasFoundAccount = derived(() => credentialCount > 0 || cloudProviders.length > 0);\n\t\tconst connected = derived(() => verifiedCount > 0);\n\t\tlet signInInstead = false;\n\t\tconst showSignIn = derived(() => !hasFoundAccount() || signInInstead);\n\t\t$$renderer.push(`<div class=\"cloud-attach svelte-v318we\">`);\n\t\tif (!showSignIn()) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\tif (connected()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<p class=\"connected svelte-v318we\" role=\"status\"><span class=\"check svelte-v318we\" aria-hidden=\"true\">✓</span> Connected your AI account.</p> <button type=\"button\" class=\"account-link svelte-v318we\">Use a different account</button>`);\n\t\t\t} else if (hostImporting) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`<p class=\"connecting svelte-v318we\" role=\"status\">`);\n\t\t\t\tSpinner($$renderer, {});\n\t\t\t\t$$renderer.push(`<!----> Connecting your AI account…</p>`);\n\t\t\t} else {\n\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<p class=\"lead svelte-v318we\">We found an AI account on this computer.</p> <button type=\"button\" class=\"btn-connect svelte-v318we\" id=\"btn-host-import\">Use this account</button> <button type=\"button\" class=\"account-link svelte-v318we\">Use a different account</button>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]-->`);\n\t\t} else {\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<p class=\"lead svelte-v318we\">Sign in to your AI service:</p> `);\n\t\t\tProviderOAuthList($$renderer, {\n\t\t\t\topencodeProviders,\n\t\t\t\topencodeAuth,\n\t\t\t\tproviderState,\n\t\t\t\tonoauthstart: (id, idx) => onoauthstart?.(id, idx),\n\t\t\t\tonoauthcancel: (id) => onoauthcancel?.(id)\n\t\t\t});\n\t\t\t$$renderer.push(`<!----> `);\n\t\t\tif (hasFoundAccount()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<button type=\"button\" class=\"account-link svelte-v318we\">Use the account on this computer instead</button>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]-->`);\n\t\t}\n\t\t$$renderer.push(`<!--]--></div>`);\n\t});\n}\n//#endregion\n//#region src/routes/setup/steps/LocalModelsStatus.svelte\nfunction LocalModelsStatus($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t/**\n\t\t* LocalModelsStatus — shows the local model runtime state for Screen 1.\n\t\t*\n\t\t* Props:\n\t\t* hostProviders — runtimes already running on the host (ollama / lmstudio / model-runner)\n\t\t* gpuVramMb — detected VRAM in MiB (0 = not detected)\n\t\t* gpuVendor — 'apple' | 'nvidia' | 'amd' | '' (empty = not detected)\n\t\t* gpuName — human-readable GPU name from detection\n\t\t* ollamaEnabled — true when in-stack Ollama will be added\n\t\t* selectedOllamaProfile — Ollama profile id (cuda / rocm / cpu)\n\t\t* onrecheck — called when the user clicks Re-check (re-calls GET /api/setup/recommend)\n\t\t*/\n\t\tlet { hostProviders = [], gpuVramMb = 0, gpuVendor = \"\", gpuName = \"\", ollamaEnabled = false, selectedOllamaProfile = \"\", onrecheck } = $$props;\n\t\tconst isAppleSilicon = derived(() => gpuVendor === \"apple\");\n\t\tconst hasRunningRuntime = derived(() => hostProviders.length > 0);\n\t\tconst gpuGb = derived(() => Math.round(gpuVramMb / 1024));\n\t\tconst profileLabel = derived(() => selectedOllamaProfile.endsWith(\"cuda\") ? \"CUDA\" : selectedOllamaProfile.endsWith(\"rocm\") ? \"ROCm\" : \"CPU\");\n\t\tfunction runtimeLabel(provider) {\n\t\t\tif (provider === \"ollama\") return \"Ollama\";\n\t\t\tif (provider === \"lmstudio\") return \"LM Studio\";\n\t\t\tif (provider === \"model-runner\") return \"Docker Model Runner\";\n\t\t\treturn provider;\n\t\t}\n\t\t$$renderer.push(`<div class=\"local-models-status svelte-1fl6n4z\">`);\n\t\tif (hasRunningRuntime()) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"status-row status-row--running svelte-1fl6n4z\" role=\"status\"><span class=\"status-icon svelte-1fl6n4z\" aria-hidden=\"true\">●</span> <span class=\"status-text svelte-1fl6n4z\">Using ${escape_html(hostProviders.map((p) => runtimeLabel(p.provider)).join(\", \"))} already running on your machine.</span></div>`);\n\t\t} else if (isAppleSilicon()) {\n\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t$$renderer.push(`<div class=\"status-callout status-callout--apple svelte-1fl6n4z\" role=\"note\"><div class=\"callout-icon svelte-1fl6n4z\" aria-hidden=\"true\"><svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line></svg></div> <div class=\"callout-body svelte-1fl6n4z\"><p class=\"callout-title svelte-1fl6n4z\">Apple Silicon detected</p> <p class=\"callout-desc svelte-1fl6n4z\">For best performance, install <a href=\"https://ollama.com/download\" target=\"_blank\" rel=\"noopener\" class=\"svelte-1fl6n4z\">Ollama for macOS</a> and leave it running before continuing. Once Ollama is running, click Re-check to continue.</p> <button class=\"btn-recheck svelte-1fl6n4z\" type=\"button\" id=\"btn-local-recheck\">Re-check</button></div></div>`);\n\t\t} else if (ollamaEnabled && gpuVramMb >= 8192) {\n\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t$$renderer.push(`<div class=\"status-row status-row--will-install svelte-1fl6n4z\" role=\"status\"><span class=\"status-icon svelte-1fl6n4z\" aria-hidden=\"true\">◎</span> <span class=\"status-text svelte-1fl6n4z\">Will install Ollama in the stack `);\n\t\t\tif (gpuName) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`(GPU: ${escape_html(gpuName)}, ${escape_html(gpuGb())} GB, profile: ${escape_html(profileLabel())})`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]-->.\n First pull downloads ~4–8 GB.</span></div>`);\n\t\t} else if (ollamaEnabled) {\n\t\t\t$$renderer.push(\"<!--[3-->\");\n\t\t\t$$renderer.push(`<div class=\"status-row status-row--will-install svelte-1fl6n4z\" role=\"status\"><span class=\"status-icon svelte-1fl6n4z\" aria-hidden=\"true\">◎</span> <span class=\"status-text svelte-1fl6n4z\">Will install Ollama in the stack (CPU mode). First pull downloads ~4–8 GB.</span></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--></div>`);\n\t});\n}\n//#endregion\n//#region src/routes/setup/steps/Screen1ModelsStep.svelte\nfunction Screen1ModelsStep($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t/**\n\t\t* Screen1ModelsStep — \"Connect your AI brain\"\n\t\t*\n\t\t* Redesigned flat RadioRow layout (spec: /tmp/wiz/connect-redesign.html).\n\t\t* Three primary choices in a hairline-divided list:\n\t\t* 1. Detected cloud service (shown only when verifiedCount > 0 or llmProvider set)\n\t\t* 2. Run on this computer (local AI — co-equal primary option)\n\t\t* 3. Sign in to a cloud service (expands ProviderOAuthList inline)\n\t\t*\n\t\t* Props:\n\t\t* modelMode — currently selected mode ('cloud'|'local'|'both')\n\t\t* detectionLoading — true while /api/setup/recommend is in flight\n\t\t* detectionTimedOut — true when detection did not complete within 3s\n\t\t* systemCheckError — non-empty string when SystemCheck failed (shows inline alert)\n\t\t* systemCheckRetrying — true while system check retry is in progress\n\t\t* gpuVramMb — VRAM in MiB (0 = not detected)\n\t\t* gpuVendor — 'apple' | 'nvidia' | 'amd' | '' (empty = none detected)\n\t\t* gpuName — human-readable GPU name\n\t\t* hostProviders — local runtimes running on host\n\t\t* credentialCount — importable host credential count\n\t\t* cloudProviders — provider ids configured on host\n\t\t* opencodeProviders — all OpenCode providers (for OAuth list)\n\t\t* opencodeAuth — auth methods per provider id\n\t\t* providerState — verification state per provider id\n\t\t* ollamaEnabled — whether in-stack Ollama is active\n\t\t* selectedOllamaProfile — ollama profile id (cuda/rocm/cpu)\n\t\t* hostImporting — true while host import is in flight\n\t\t* verifiedCount — number of providers currently verified\n\t\t* allowEmptyInstall — whether \"install without provider\" escape is active\n\t\t* llmModel — selected chat model id\n\t\t* llmProvider — provider name for selected chat model\n\t\t*\n\t\t* Events:\n\t\t* onmodelmodechange — user picked a different model mode\n\t\t* onhostimport — trigger host provider import\n\t\t* onoauthstart — OAuth flow start\n\t\t* onoauthcancel — OAuth flow cancel\n\t\t* onbaseurl — custom base URL changed\n\t\t* onapikey — custom API key changed\n\t\t* onverify — verify custom endpoint\n\t\t* onrecheck — re-call /api/setup/recommend\n\t\t* onsystemcheckretry — retry the system check\n\t\t* onallowemptyinstallchange — toggle empty install escape\n\t\t* onnext — proceed to Screen 2\n\t\t*/\n\t\t/** True while Phase-0 detection is in flight. */\n\t\t/** True when the 3-second detection timeout elapsed. */\n\t\t/** Non-empty string = SystemCheck failed; shown as inline alert on this screen. */\n\t\t/** True while the system check retry is running. */\n\t\t/** VRAM in MiB from detection (0 = not detected). */\n\t\t/** GPU vendor from detection ('apple'|'nvidia'|'amd'|''). */\n\t\t/** Human-readable GPU name. */\n\t\t/** Local runtimes already running on the host. */\n\t\t/** Full OpenCode provider list (for OAuth sub-panel). */\n\t\t/** Auth methods per provider id. */\n\t\t/** Verification state per provider id. */\n\t\t/** Whether in-stack Ollama will be added. */\n\t\t/** Selected Ollama profile (cuda/rocm/cpu). */\n\t\t/** True while host-import is in flight. */\n\t\t/** Number of currently verified providers. */\n\t\t/** Whether the \"install without provider\" escape is checked. */\n\t\t/** Currently selected chat model id. */\n\t\t/** Provider name for the selected chat model (connId). */\n\t\t/** Stable connId of the detected cloud service (persists across local↔cloud switches). */\n\t\tconst MIN_LOCAL_GPU_VRAM_MB = 8192;\n\t\tconst SERVICE_LABELS = {\n\t\t\topenai: \"ChatGPT (OpenAI)\",\n\t\t\tgoogle: \"Gemini (Google)\",\n\t\t\t\"github-copilot\": \"GitHub Copilot\",\n\t\t\tgroq: \"Groq\",\n\t\t\tanthropic: \"Claude (Anthropic)\",\n\t\t\tmistral: \"Mistral\",\n\t\t\tcohere: \"Cohere\"\n\t\t};\n\t\tlet { detectionLoading = false, detectionTimedOut = false, systemCheckError = \"\", systemCheckRetrying = false, gpuVramMb = 0, gpuVendor = \"\", gpuName = \"\", hostProviders = [], opencodeProviders = [], opencodeAuth = {}, providerState = {}, ollamaEnabled = false, selectedOllamaProfile = \"\", hostImporting = false, verifiedCount = 0, allowEmptyInstall = false, llmModel = \"\", llmProvider = \"\", detectedCloudConn = \"\", onmodelmodechange, onhostimport, onoauthstart, onoauthcancel, onrecheck, onsystemcheckretry, onallowemptyinstallchange } = $$props;\n\t\tconst localAvailable = derived(() => gpuVramMb >= MIN_LOCAL_GPU_VRAM_MB || gpuVendor === \"apple\" || hostProviders.length > 0);\n\t\tfunction friendlyServiceLabel(connId) {\n\t\t\tif (SERVICE_LABELS[connId]) return SERVICE_LABELS[connId];\n\t\t\tconst fromProviders = opencodeProviders.find((p) => p.id === connId)?.name;\n\t\t\tif (fromProviders) return fromProviders;\n\t\t\treturn connId;\n\t\t}\n\t\tconst LOCAL_PROVIDER_IDS = new Set([\n\t\t\t\"ollama\",\n\t\t\t\"lmstudio\",\n\t\t\t\"llamacpp\",\n\t\t\t\"localai\",\n\t\t\t\"model-runner\"\n\t\t]);\n\t\tconst detectedConn = derived(() => detectedCloudConn || (llmProvider && !LOCAL_PROVIDER_IDS.has(llmProvider) ? llmProvider : \"\"));\n\t\tconst detectedServiceLabel = derived(() => detectedConn() ? friendlyServiceLabel(detectedConn()) : \"\");\n\t\tconst detectedIsLocal = derived(() => LOCAL_PROVIDER_IDS.has(llmProvider));\n\t\tconst showDetectedRow = derived(() => !!detectedConn() && verifiedCount > 0);\n\t\tlet selectedRow = run(() => showDetectedRow() ? \"detected\" : detectedIsLocal() && llmProvider ? \"local\" : null);\n\t\tconst showLocalPanel = derived(() => selectedRow === \"local\");\n\t\tconst showSignInPanel = derived(() => selectedRow === \"cloud\");\n\t\tconst cloudRowTitle = derived(() => showDetectedRow() ? \"Sign in to a different service\" : \"Sign in to a cloud AI service\");\n\t\tconst cloudRowSub = derived(() => showDetectedRow() ? \"Google Gemini, GitHub Copilot, and others\" : \"OpenAI, Google Gemini, GitHub Copilot, and others\");\n\t\t$$renderer.push(`<div data-testid=\"step-models\" class=\"screen-models svelte-z6usuj\">`);\n\t\tif (systemCheckError) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"s1-alert s1-alert--error svelte-z6usuj\" role=\"alert\"><span class=\"s1-alert-text svelte-z6usuj\">${escape_html(systemCheckError)}</span> <button type=\"button\" class=\"s1-alert-btn svelte-z6usuj\" id=\"btn-syscheck-retry\"${attr(\"disabled\", systemCheckRetrying, true)}>${escape_html(systemCheckRetrying ? \"Checking…\" : \"Retry\")}</button></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (detectionTimedOut && true) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"s1-alert s1-alert--warn svelte-z6usuj\" role=\"alert\"><span class=\"s1-alert-text svelte-z6usuj\">Detection timed out — results may be incomplete.</span> <button type=\"button\" class=\"s1-alert-btn s1-alert-btn--warn svelte-z6usuj\">Re-run detection</button> <button type=\"button\" class=\"s1-dismiss svelte-z6usuj\" aria-label=\"Dismiss\">✕</button></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (detectionLoading || hostImporting) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"s1-shimmer svelte-z6usuj\" aria-busy=\"true\" aria-label=\"Detecting AI services…\"><span class=\"s1-shimmer-bar svelte-z6usuj\"></span> <span class=\"s1-shimmer-bar s1-shimmer-bar--short svelte-z6usuj\"></span> <span class=\"s1-shimmer-bar s1-shimmer-bar--shorter svelte-z6usuj\"></span></div>`);\n\t\t} else {\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\tif (verifiedCount > 0 && showDetectedRow()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<div class=\"s1-detected-banner svelte-z6usuj\" role=\"status\"><div class=\"s1-detected-check svelte-z6usuj\" aria-hidden=\"true\">✓</div> <div class=\"s1-detected-text svelte-z6usuj\"><div class=\"s1-detected-title svelte-z6usuj\">${escape_html(detectedServiceLabel())} is already connected — you're good to go</div> <div class=\"s1-detected-sub svelte-z6usuj\">We found your account on this computer. Just continue, or choose something different below.</div></div></div>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--> <div class=\"s1-choice-list svelte-z6usuj\" role=\"radiogroup\" aria-label=\"Which AI should your assistant use\">`);\n\t\t\tif (showDetectedRow()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<button type=\"button\"${attr_class(\"s1-choice-row svelte-z6usuj\", void 0, { \"s1-choice-row--selected\": selectedRow === \"detected\" })} role=\"radio\"${attr(\"aria-checked\", selectedRow === \"detected\")}><div class=\"s1-radio-dot svelte-z6usuj\"><div class=\"s1-radio-dot-inner svelte-z6usuj\"></div></div> <div class=\"s1-choice-body svelte-z6usuj\"><div class=\"s1-choice-title svelte-z6usuj\">${escape_html(detectedServiceLabel())}</div> <div class=\"s1-choice-sub svelte-z6usuj\">Use your existing ${escape_html(detectedServiceLabel())} subscription</div></div> <span class=\"s1-badge-recommended svelte-z6usuj\">Recommended</span></button>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--> <button type=\"button\"${attr_class(\"s1-choice-row svelte-z6usuj\", void 0, {\n\t\t\t\t\"s1-choice-row--selected\": selectedRow === \"local\",\n\t\t\t\t\"s1-choice-row--unavailable\": !localAvailable()\n\t\t\t})} role=\"radio\"${attr(\"aria-checked\", selectedRow === \"local\")}${attr(\"disabled\", !localAvailable(), true)}><div class=\"s1-radio-dot svelte-z6usuj\"><div class=\"s1-radio-dot-inner svelte-z6usuj\"></div></div> <div class=\"s1-choice-icon svelte-z6usuj\" aria-hidden=\"true\"><svg viewBox=\"0 0 18 18\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\" class=\"svelte-z6usuj\"><rect x=\"1.5\" y=\"2.5\" width=\"15\" height=\"10\" rx=\"1.5\" class=\"svelte-z6usuj\"></rect><path d=\"M5.5 15.5h7M9 12.5v3\" stroke-linecap=\"round\" class=\"svelte-z6usuj\"></path><circle cx=\"9\" cy=\"7.5\" r=\"2.5\" class=\"svelte-z6usuj\"></circle></svg></div> <div class=\"s1-choice-body svelte-z6usuj\"><div class=\"s1-choice-title svelte-z6usuj\">Run on this computer</div> <div class=\"s1-choice-sub svelte-z6usuj\">`);\n\t\t\tif (localAvailable()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`Private &amp; free — no account needed, no data leaves your machine`);\n\t\t\t} else {\n\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`Needs a more capable computer — requires 8 GB+ graphics card or Apple Silicon`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--></div></div></button> `);\n\t\t\tif (showLocalPanel()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<div class=\"s1-local-panel svelte-z6usuj\" aria-live=\"polite\">`);\n\t\t\t\tLocalModelsStatus($$renderer, {\n\t\t\t\t\thostProviders,\n\t\t\t\t\tgpuVramMb,\n\t\t\t\t\tgpuVendor,\n\t\t\t\t\tgpuName,\n\t\t\t\t\tollamaEnabled,\n\t\t\t\t\tselectedOllamaProfile,\n\t\t\t\t\tonrecheck\n\t\t\t\t});\n\t\t\t\t$$renderer.push(`<!----></div>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--> <button type=\"button\"${attr_class(\"s1-choice-row svelte-z6usuj\", void 0, { \"s1-choice-row--selected\": selectedRow === \"cloud\" })} role=\"radio\"${attr(\"aria-checked\", selectedRow === \"cloud\")}><div class=\"s1-radio-dot svelte-z6usuj\"><div class=\"s1-radio-dot-inner svelte-z6usuj\"></div></div> <div class=\"s1-choice-body svelte-z6usuj\"><div class=\"s1-choice-title svelte-z6usuj\">${escape_html(cloudRowTitle())}</div> <div class=\"s1-choice-sub svelte-z6usuj\">${escape_html(cloudRowSub())}</div></div></button> `);\n\t\t\tif (showSignInPanel()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<div class=\"s1-signin-panel svelte-z6usuj\" aria-live=\"polite\">`);\n\t\t\t\tCloudAttachPanel($$renderer, {\n\t\t\t\t\tcredentialCount: 0,\n\t\t\t\t\tcloudProviders: [],\n\t\t\t\t\topencodeProviders,\n\t\t\t\t\topencodeAuth,\n\t\t\t\t\tproviderState,\n\t\t\t\t\thostImporting,\n\t\t\t\t\tverifiedCount,\n\t\t\t\t\tonhostimport,\n\t\t\t\t\tonoauthstart: (id, idx) => onoauthstart?.(id, idx),\n\t\t\t\t\tonoauthcancel: (id) => onoauthcancel?.(id)\n\t\t\t\t});\n\t\t\t\t$$renderer.push(`<!----></div>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></div> `);\n\t\t\tif (!llmModel && !allowEmptyInstall) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<div class=\"s1-empty-install-row svelte-z6usuj\"><p class=\"s1-empty-install-hint svelte-z6usuj\">No AI here? You can still continue — connect this app to an assistant\n running on another computer, or add a provider later from your dashboard.</p> <button type=\"button\" class=\"s1-btn-empty-install svelte-z6usuj\">I'll set this up later</button></div>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]-->`);\n\t\t}\n\t\t$$renderer.push(`<!--]--></div>`);\n\t});\n}\n//#endregion\n//#region src/routes/setup/steps/Screen2ExtrasStep.svelte\nfunction Screen2ExtrasStep($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t/**\n\t\t* Screen2ExtrasStep — \"Optional extras\"\n\t\t*\n\t\t* Flat hairline-row layout (spec: /tmp/wiz/extras-finish-redesign.html).\n\t\t* Three rows with inline accordion expansion (no modal, no bordered cards,\n\t\t* no sub-section headings):\n\t\t* 1. Voice — bundled openpalm-voice; toggle drives onvoiceenabledchange + engine defaults\n\t\t* 2. Discord — botToken + applicationId credential fields\n\t\t* 3. Slack — slackBotToken + slackAppToken credential fields\n\t\t*\n\t\t* Props:\n\t\t* modelMode — 'cloud' | 'local' | 'both' — drives voice default selection\n\t\t* voiceEnabled — explicit voice on/off toggle state (OFF by default)\n\t\t* voiceTts — current TTS engine value\n\t\t* voiceStt — current STT engine value\n\t\t* hasOpenAI — true if OpenAI is a verified provider (affects voice default)\n\t\t* voiceProfiles — available voice addon hardware profiles\n\t\t* selectedVoiceProfile — currently selected voice profile id\n\t\t* portalSelection — current portal enable + credential state\n\t\t* onvoiceenabledchange — called when voice toggle flips\n\t\t* onchangetts — called when TTS engine/config changes\n\t\t* onchangestt — called when STT engine/config changes\n\t\t* onvoiceprofilechange — called when voice hardware profile changes\n\t\t* onportaltoggle — called when a portal toggle flips\n\t\t* oncredentialchange — called when a portal credential field changes\n\t\t* onnext — proceed to Screen 3 (always enabled)\n\t\t*/\n\t\t/** Which model mode was chosen on Screen 1. Drives voice default logic. */\n\t\t/**\n\t\t* Explicit voice on/off state — OFF by default.\n\t\t* CRITICAL: must not be derived from engine selection. The parent owns this\n\t\t* as $state(false) and passes it down. Only when this is true should voice\n\t\t* addon be included in the payload.\n\t\t*/\n\t\t/** Current TTS engine value. */\n\t\t/** Current STT engine value. */\n\t\t/** True when OpenAI is a verified provider (affects default engine). */\n\t\t/** Portal enable + credential state (discord, slack). */\n\t\tlet { modelMode, voiceEnabled, voiceTts, voiceStt, hasOpenAI = false, portalSelection = {}, onvoiceenabledchange, onchangetts, onchangestt, onportaltoggle, oncredentialchange } = $$props;\n\t\tfunction isPortalEnabled$2(chId, locked) {\n\t\t\treturn isPortalEnabled(portalSelection, chId, locked);\n\t\t}\n\t\tfunction getCredValue$1(chId, key) {\n\t\t\treturn getCredValue(portalSelection, chId, key);\n\t\t}\n\t\tconst configurablePortals = derived(() => PORTALS.filter((ch) => !ch.locked));\n\t\tconst discordCh = derived(() => configurablePortals().find((ch) => ch.id === \"discord\"));\n\t\tconst slackCh = derived(() => configurablePortals().find((ch) => ch.id === \"slack\"));\n\t\tconst discordOn = derived(() => isPortalEnabled$2(\"discord\"));\n\t\tconst slackOn = derived(() => isPortalEnabled$2(\"slack\"));\n\t\t$$renderer.push(`<div data-testid=\"step-extras\" class=\"addon-list svelte-85kisn\" role=\"list\"><div class=\"addon-row svelte-85kisn\" role=\"listitem\"><div class=\"addon-row-header svelte-85kisn\"><div class=\"addon-icon voice-icon svelte-85kisn\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#3b82f6\" stroke-width=\"1.7\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"svelte-85kisn\"><rect x=\"9\" y=\"3\" width=\"6\" height=\"11\" rx=\"3\"></rect><path d=\"M5 11a7 7 0 0014 0M12 18v3\"></path></svg></div> <div class=\"addon-body svelte-85kisn\"><div class=\"addon-title svelte-85kisn\">Voice</div> <div class=\"addon-sub svelte-85kisn\">Talk to your assistant and hear it reply</div></div> <div class=\"toggle-wrap svelte-85kisn\"><label class=\"toggle svelte-85kisn\" aria-label=\"Enable Voice\"><input type=\"checkbox\"${attr(\"checked\", voiceEnabled, true)} class=\"svelte-85kisn\"/> <div class=\"toggle-track svelte-85kisn\"></div> <div class=\"toggle-thumb svelte-85kisn\"></div></label></div></div> <div${attr_class(\"addon-panel svelte-85kisn\", void 0, { \"open\": voiceEnabled })} aria-live=\"polite\"><div class=\"addon-panel-inner svelte-85kisn\"><p class=\"panel-question svelte-85kisn\">How should your assistant speak?</p> <div class=\"voice-option svelte-85kisn\"><div class=\"voice-option-dot svelte-85kisn\"><div class=\"voice-option-dot-inner svelte-85kisn\"></div></div> <div><div class=\"voice-option-text svelte-85kisn\">Built-in voice — free, runs on this computer</div> <div class=\"voice-option-sub svelte-85kisn\">No internet needed. Sounds natural, works out of the box.</div></div></div></div></div></div> `);\n\t\tif (discordCh()) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"addon-row svelte-85kisn\" role=\"listitem\"><div class=\"addon-row-header svelte-85kisn\"><div class=\"addon-icon discord-icon svelte-85kisn\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"#5865f2\" class=\"svelte-85kisn\"><path d=\"M19 5.3A16 16 0 0015 4l-.2.4a14 14 0 00-4 0L10.5 4a16 16 0 00-4 1.3C4 9 3.3 12.6 3.6 16.2A16 16 0 008.5 18.7c.4-.5.8-1.1 1-1.7a9 9 0 01-1.6-.8l.4-.3a11 11 0 009.4 0l.4.3a9 9 0 01-1.6.8c.3.6.6 1.2 1 1.7a16 16 0 004.9-2.5c.4-4.2-.7-7.8-2.4-10.9zM9 14c-.8 0-1.4-.7-1.4-1.6S8.2 10.8 9 10.8s1.4.7 1.4 1.6S9.8 14 9 14zm6 0c-.8 0-1.4-.7-1.4-1.6s.6-1.6 1.4-1.6 1.4.7 1.4 1.6S15.8 14 15 14z\"></path></svg></div> <div class=\"addon-body svelte-85kisn\"><div class=\"addon-title svelte-85kisn\">Discord</div> <div class=\"addon-sub svelte-85kisn\">Reach your assistant from a Discord server</div></div> <div class=\"toggle-wrap svelte-85kisn\"><label class=\"toggle svelte-85kisn\" aria-label=\"Enable Discord\"><input type=\"checkbox\"${attr(\"checked\", discordOn(), true)} class=\"svelte-85kisn\"/> <div class=\"toggle-track svelte-85kisn\"></div> <div class=\"toggle-thumb svelte-85kisn\"></div></label></div></div> <div${attr_class(\"addon-panel svelte-85kisn\", void 0, { \"open\": discordOn() })} aria-live=\"polite\"><div class=\"addon-panel-inner svelte-85kisn\"><div class=\"field-group svelte-85kisn\"><div><label class=\"field-label svelte-85kisn\" for=\"cred-discord-botToken\">Bot token</label> <input class=\"field-input svelte-85kisn\" type=\"password\" id=\"cred-discord-botToken\" placeholder=\"Paste your bot token here\" autocomplete=\"off\"${attr(\"value\", getCredValue$1(\"discord\", \"botToken\"))}/> <p class=\"field-help svelte-85kisn\"><a href=\"https://discord.com/developers/docs/quick-start/getting-started\" target=\"_blank\" rel=\"noopener\" class=\"svelte-85kisn\">How to create a Discord bot and get your token →</a></p></div> <div><label class=\"field-label svelte-85kisn\" for=\"cred-discord-applicationId\">Application ID</label> <input class=\"field-input svelte-85kisn\" type=\"text\" id=\"cred-discord-applicationId\" placeholder=\"Your app's numeric ID\" autocomplete=\"off\"${attr(\"value\", getCredValue$1(\"discord\", \"applicationId\"))}/> <p class=\"field-help svelte-85kisn\">Found in the Discord Developer Portal under your application's General Information page.</p></div></div></div></div></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (slackCh()) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"addon-row svelte-85kisn\" role=\"listitem\"><div class=\"addon-row-header svelte-85kisn\"><div class=\"addon-icon slack-icon svelte-85kisn\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" class=\"svelte-85kisn\"><path fill=\"#36C5F0\" d=\"M9 13.5a2 2 0 11-2-2h2v2z\"></path><path fill=\"#2EB67D\" d=\"M10.5 9a2 2 0 112 2H10.5v-2z\"></path><path fill=\"#ECB22E\" d=\"M15 10.5a2 2 0 112 2h-2v-2z\"></path><path fill=\"#E01E5A\" d=\"M13.5 15a2 2 0 11-2 2v-2h2z\"></path></svg></div> <div class=\"addon-body svelte-85kisn\"><div class=\"addon-title svelte-85kisn\">Slack</div> <div class=\"addon-sub svelte-85kisn\">Reach your assistant from a Slack workspace</div></div> <div class=\"toggle-wrap svelte-85kisn\"><label class=\"toggle svelte-85kisn\" aria-label=\"Enable Slack\"><input type=\"checkbox\"${attr(\"checked\", slackOn(), true)} class=\"svelte-85kisn\"/> <div class=\"toggle-track svelte-85kisn\"></div> <div class=\"toggle-thumb svelte-85kisn\"></div></label></div></div> <div${attr_class(\"addon-panel svelte-85kisn\", void 0, { \"open\": slackOn() })} aria-live=\"polite\"><div class=\"addon-panel-inner svelte-85kisn\"><div class=\"field-group svelte-85kisn\"><div><label class=\"field-label svelte-85kisn\" for=\"cred-slack-slackBotToken\">Bot token</label> <input class=\"field-input svelte-85kisn\" type=\"password\" id=\"cred-slack-slackBotToken\" placeholder=\"xoxb-…\" autocomplete=\"off\"${attr(\"value\", getCredValue$1(\"slack\", \"slackBotToken\"))}/></div> <div><label class=\"field-label svelte-85kisn\" for=\"cred-slack-slackAppToken\">App-level token</label> <input class=\"field-input svelte-85kisn\" type=\"password\" id=\"cred-slack-slackAppToken\" placeholder=\"xapp-…\" autocomplete=\"off\"${attr(\"value\", getCredValue$1(\"slack\", \"slackAppToken\"))}/> <p class=\"field-help svelte-85kisn\"><a href=\"https://api.slack.com/quickstart\" target=\"_blank\" rel=\"noopener\" class=\"svelte-85kisn\">How to create a Slack app and get your tokens →</a></p></div></div></div></div></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--></div>`);\n\t});\n}\n//#endregion\n//#region src/routes/setup/steps/ReviewStep.svelte\nfunction ReviewStep($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t/** Label for the running host provider (e.g. \"Ollama\"). Shown when ollamaEnabled is false. */\n\t\tlet { uiLoginPassword, verifiedProviders, modelSelection, activeTts, activeStt, portalSelection, ollamaEnabled, hostProviderLabel = \"\", payload, installError, isRerun = false, systemCheckPassed = true, oneditmodels, oneditextras } = $$props;\n\t\tconst LOCAL_PROVIDER_IDS = new Set([\n\t\t\t\"ollama\",\n\t\t\t\"lmstudio\",\n\t\t\t\"llamacpp\",\n\t\t\t\"localai\",\n\t\t\t\"model-runner\"\n\t\t]);\n\t\tfunction friendlyProviderName(connId) {\n\t\t\tif (!connId) return \"\";\n\t\t\tif (connId === \"openai\") return \"ChatGPT (OpenAI)\";\n\t\t\tif (connId === \"google\") return \"Gemini (Google)\";\n\t\t\tif (connId === \"github-copilot\") return \"GitHub Copilot\";\n\t\t\tif (connId === \"groq\") return \"Groq\";\n\t\t\tif (LOCAL_PROVIDER_IDS.has(connId)) return \"Runs on this computer\";\n\t\t\treturn PROVIDERS.find((p) => p.id === connId)?.name ?? connId;\n\t\t}\n\t\tfunction isPortalEnabled$1(chId, locked) {\n\t\t\treturn isPortalEnabled(portalSelection, chId, locked);\n\t\t}\n\t\tconst aiLabel = derived(() => {\n\t\t\tconst connId = modelSelection.llm?.connId;\n\t\t\tif (!connId) return \"\";\n\t\t\treturn friendlyProviderName(connId);\n\t\t});\n\t\tconst voiceActive = derived(() => !!(activeTts && !activeTts.startsWith(\"skip-\")) || !!(activeStt && !activeStt.startsWith(\"skip-\")));\n\t\tconst activePortals = derived(() => PORTALS.filter((ch) => !ch.locked && isPortalEnabled$1(ch.id, ch.locked)));\n\t\tlet passwordCopied = false;\n\t\tif (verifiedProviders.length === 0) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"review-note svelte-1q74f52\">No AI set up here yet — that's fine. After install you can connect this app to an\n assistant running on another computer, or add a provider, anytime from your dashboard.</div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (!isRerun) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"password-block svelte-1q74f52\"><p class=\"password-label svelte-1q74f52\">Sign-in password</p> <div class=\"password-row svelte-1q74f52\">`);\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<span class=\"password-value password-value--dots svelte-1q74f52\" aria-label=\"Sign-in password\">••••••••••••••••</span>`);\n\t\t\t$$renderer.push(`<!--]--> <div class=\"password-actions svelte-1q74f52\"><button type=\"button\" class=\"btn-icon svelte-1q74f52\"${attr(\"aria-label\", \"Show password\")}${attr(\"title\", \"Show\")}>`);\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M1 8s2.5-5 7-5 7 5 7 5-2.5 5-7 5-7-5-7-5z\"></path><circle cx=\"8\" cy=\"8\" r=\"2\"></circle></svg>`);\n\t\t\t$$renderer.push(`<!--]--></button> <button type=\"button\"${attr_class(\"btn-icon svelte-1q74f52\", void 0, { \"btn-icon--copied\": passwordCopied })}${attr(\"aria-label\", \"Copy password\")} title=\"Copy\">`);\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"5\" y=\"5\" width=\"8\" height=\"8\" rx=\"1.5\"></rect><path d=\"M3 11V3h8\"></path></svg>`);\n\t\t\t$$renderer.push(`<!--]--></button></div></div> <p class=\"password-note svelte-1q74f52\">Already saved on this computer — keep a copy somewhere safe just in case.</p></div>`);\n\t\t} else {\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<div class=\"password-block svelte-1q74f52\"><p class=\"password-label svelte-1q74f52\">Sign-in password</p> <div class=\"password-row svelte-1q74f52\"><span class=\"password-value password-value--dots svelte-1q74f52\" aria-label=\"Sign-in password\">••••••••</span> <div class=\"password-actions svelte-1q74f52\"><span class=\"rerun-note svelte-1q74f52\">Previously set — not changed.</span></div></div></div>`);\n\t\t}\n\t\t$$renderer.push(`<!--]--> <div class=\"summary-list svelte-1q74f52\" aria-label=\"What's set up\"><p class=\"summary-section-label svelte-1q74f52\">What's being set up</p> `);\n\t\tif (aiLabel()) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"summary-row svelte-1q74f52\"><span class=\"summary-icon svelte-1q74f52\" aria-hidden=\"true\">`);\n\t\t\tIconAgent($$renderer, { size: 16 });\n\t\t\t$$renderer.push(`<!----></span> <div class=\"summary-body svelte-1q74f52\"><div class=\"summary-key svelte-1q74f52\">AI</div> <div class=\"summary-val svelte-1q74f52\">${escape_html(aiLabel())}</div></div> <button type=\"button\" class=\"btn-change svelte-1q74f52\">Change</button></div>`);\n\t\t} else if (verifiedProviders.length > 0) {\n\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t$$renderer.push(`<div class=\"summary-row svelte-1q74f52\"><span class=\"summary-icon svelte-1q74f52\" aria-hidden=\"true\">`);\n\t\t\tIconAgent($$renderer, { size: 16 });\n\t\t\t$$renderer.push(`<!----></span> <div class=\"summary-body svelte-1q74f52\"><div class=\"summary-key svelte-1q74f52\">AI</div> <div class=\"summary-val svelte-1q74f52\">${escape_html(friendlyProviderName(verifiedProviders[0].id))}</div></div> <button type=\"button\" class=\"btn-change svelte-1q74f52\">Change</button></div>`);\n\t\t} else if (ollamaEnabled) {\n\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t$$renderer.push(`<div class=\"summary-row svelte-1q74f52\"><span class=\"summary-icon svelte-1q74f52\" aria-hidden=\"true\">`);\n\t\t\tIconAgent($$renderer, { size: 16 });\n\t\t\t$$renderer.push(`<!----></span> <div class=\"summary-body svelte-1q74f52\"><div class=\"summary-key svelte-1q74f52\">AI</div> <div class=\"summary-val svelte-1q74f52\">Runs on this computer</div></div> <button type=\"button\" class=\"btn-change svelte-1q74f52\">Change</button></div>`);\n\t\t} else if (hostProviderLabel) {\n\t\t\t$$renderer.push(\"<!--[3-->\");\n\t\t\t$$renderer.push(`<div class=\"summary-row svelte-1q74f52\"><span class=\"summary-icon svelte-1q74f52\" aria-hidden=\"true\">`);\n\t\t\tIconAgent($$renderer, { size: 16 });\n\t\t\t$$renderer.push(`<!----></span> <div class=\"summary-body svelte-1q74f52\"><div class=\"summary-key svelte-1q74f52\">AI</div> <div class=\"summary-val svelte-1q74f52\">${escape_html(friendlyProviderName(hostProviderLabel))}</div></div> <button type=\"button\" class=\"btn-change svelte-1q74f52\">Change</button></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (voiceActive()) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"summary-row svelte-1q74f52\"><span class=\"summary-icon svelte-1q74f52\" aria-hidden=\"true\">`);\n\t\t\tIconMic($$renderer, { size: 16 });\n\t\t\t$$renderer.push(`<!----></span> <div class=\"summary-body svelte-1q74f52\"><div class=\"summary-key svelte-1q74f52\">Voice</div> <div class=\"summary-val svelte-1q74f52\">On — built-in voice</div></div> <button type=\"button\" class=\"btn-change svelte-1q74f52\">Change</button></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> <!--[-->`);\n\t\tconst each_array = ensure_array_like(activePortals());\n\t\tfor (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {\n\t\t\tlet ch = each_array[$$index];\n\t\t\t$$renderer.push(`<div class=\"summary-row svelte-1q74f52\"><span class=\"summary-icon svelte-1q74f52\" aria-hidden=\"true\">${escape_html(ch.icon)}</span> <div class=\"summary-body svelte-1q74f52\"><div class=\"summary-key svelte-1q74f52\">Chat app</div> <div class=\"summary-val svelte-1q74f52\">${escape_html(ch.name)}</div></div> <button type=\"button\" class=\"btn-change svelte-1q74f52\">Change</button></div>`);\n\t\t}\n\t\t$$renderer.push(`<!--]--></div> `);\n\t\tif (installError) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\tFriendlyError($$renderer, { error: friendlyError(installError, \"setup-complete\") });\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (!systemCheckPassed) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"review-warning svelte-1q74f52\" role=\"alert\">⚠ System check has not passed yet — Install is disabled until Docker is confirmed available.</div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> <div class=\"review-save-row svelte-1q74f52\"><button type=\"button\" class=\"btn-save svelte-1q74f52\" aria-label=\"Save configuration as JSON file\">Save configuration</button></div>`);\n\t});\n}\n//#endregion\n//#region src/routes/setup/steps/DeployStep.svelte\nfunction DeployStep($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t/** Non-fatal: install used cached images because the registry pull failed. */\n\t\t/** Terminal state reached with non-running rows that are all warnings. */\n\t\tlet { deployData, deployDone, deployHasWarnings = false, deployError, onback, onretry } = $$props;\n\t\tconst warningRows = derived(() => (deployData.deployStatus ?? []).filter((s) => s.status === \"warning\"));\n\t\tconst isElectron = typeof window !== \"undefined\" && !!window.openpalm;\n\t\tconst windowPort = typeof window !== \"undefined\" ? Number(window.location.port) || 3880 : 3880;\n\t\tconst adminPort = derived(() => deployData.ports?.admin ?? windowPort);\n\t\tconst assistantPort = derived(() => deployData.ports?.assistant ?? 3800);\n\t\tconst serviceLinks = derived(() => ({\n\t\t\tassistant: {\n\t\t\t\tport: assistantPort(),\n\t\t\t\tlabel: \"Assistant (OpenCode)\",\n\t\t\t\tpath: \"\"\n\t\t\t},\n\t\t\tadmin: {\n\t\t\t\tport: adminPort(),\n\t\t\t\tlabel: \"Admin Dashboard\",\n\t\t\t\tpath: \"\"\n\t\t\t}\n\t\t}));\n\t\tconst services = derived(() => deployData.deployStatus ?? []);\n\t\tconst total = derived(() => services().length);\n\t\tconst running = derived(() => services().filter((s) => s.status === \"running\").length);\n\t\tconst pct = derived(() => total() > 0 ? Math.round(running() / total() * 100) : 0);\n\t\tconst phase = derived(() => deployData.phase ?? \"writing-config\");\n\t\tconst voiceEnabled = derived(() => services().some((s) => /^voice(-cuda|-rocm)?$/.test(s.service ?? \"\")));\n\t\tconst deployTitle = derived(() => {\n\t\t\tif (deployDone) return deployHasWarnings ? \"Setup Complete (with warnings)\" : \"Setup Complete\";\n\t\t\tif (deployError) return \"Deployment Issue\";\n\t\t\tswitch (phase()) {\n\t\t\t\tcase \"writing-config\": return \"Preparing Configuration…\";\n\t\t\t\tcase \"pulling-images\": return voiceEnabled() ? \"Downloading Images (incl. Voice ~2.4 GB)…\" : \"Downloading Images…\";\n\t\t\t\tcase \"starting\": return \"Starting Services…\";\n\t\t\t\tcase \"starting-voice\": return \"Starting Voice Addon…\";\n\t\t\t\tcase \"ready\": return \"Setup Complete\";\n\t\t\t}\n\t\t\treturn \"Deploying…\";\n\t\t});\n\t\tconst deploySubtitle = derived(() => {\n\t\t\tif (deployDone) return deployHasWarnings ? \"Setup is complete. Some services are still warming up in the background — they will be ready shortly.\" : \"Your OpenPalm stack is up and running.\";\n\t\t\tif (deployError) return \"Setup could not finish starting the stack.\";\n\t\t\tswitch (phase()) {\n\t\t\t\tcase \"writing-config\": return \"Writing config files and validating settings.\";\n\t\t\t\tcase \"pulling-images\": return voiceEnabled() ? \"Downloading container images. The voice model (~2.4 GB) is the largest — on a typical home connection this step can take 10–30 minutes. The wizard will wait — keep this tab open.\" : \"Downloading container images — first install can take 3–8 minutes depending on connection.\";\n\t\t\t\tcase \"starting\": return `${running()} of ${total()} services running.`;\n\t\t\t\tcase \"starting-voice\": return \"Pulling the voice image (~2.4 GB) and warming up Kokoro + Whisper models. First launch can take 5–30 minutes on slow connections — the wizard will wait.\";\n\t\t\t\tcase \"ready\": return \"All services are up.\";\n\t\t\t}\n\t\t\treturn \"Writing configuration and starting services.\";\n\t\t});\n\t\tconst noStartMode = derived(() => deployDone && services().length === 0);\n\t\t$$renderer.push(`<div class=\"deploy-header\"><h2 id=\"deploy-title\">${escape_html(deployTitle())}</h2> <p class=\"step-description\" id=\"deploy-subtitle\">${escape_html(deploySubtitle())}</p></div> <div class=\"deploy-progress-summary\"><div class=\"deploy-progress-meta\"><span class=\"deploy-progress-label\">Progress</span> <span${attr_class(`deploy-progress-value ${deployError ? \"deploy-progress-value--error\" : \"\"}`)} id=\"deploy-progress-value\">`);\n\t\tif (deployError) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`Error`);\n\t\t} else if (deployDone) {\n\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t$$renderer.push(`${escape_html(services().length > 0 ? \"100%\" : \"\")}`);\n\t\t} else {\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`${escape_html(pct())}%`);\n\t\t}\n\t\t$$renderer.push(`<!--]--></span></div> <div class=\"deploy-progress-bar\"><div class=\"deploy-progress-fill\" id=\"deploy-progress-fill\"${attr_style(`width:${stringify(deployDone && services().length > 0 ? 100 : deployDone ? 0 : pct())}%`)}></div></div></div> <div class=\"deploy-services\" id=\"deploy-services\"><!--[-->`);\n\t\tconst each_array = ensure_array_like(services());\n\t\tfor (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {\n\t\t\tlet svc = each_array[$$index];\n\t\t\t$$renderer.push(`<div class=\"deploy-service-row\"><div class=\"deploy-service-indicator\">`);\n\t\t\tif (svc.status === \"running\") {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<span class=\"deploy-check\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"var(--s-moss)\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg></span>`);\n\t\t\t} else if (svc.status === \"error\" || svc.status === \"warning\") {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`<span class=\"deploy-warning\"><svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"var(--s-ink-2)\" stroke-width=\"2.3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 9v4\"></path><path d=\"M12 17h.01\"></path><path d=\"M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"></path></svg></span>`);\n\t\t\t} else {\n\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<span class=\"deploy-spinner\">`);\n\t\t\t\tSpinner($$renderer, {});\n\t\t\t\t$$renderer.push(`<!----></span>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--></div> <div class=\"deploy-service-info\"><span class=\"deploy-service-name\">${escape_html(svc.service || svc.label || \"\")}</span> <span class=\"deploy-service-status\">${escape_html(svc.label || svc.status)}</span></div> <div class=\"deploy-service-bar\"><div${attr_class(`deploy-bar-fill ${svc.status === \"running\" ? \"complete\" : svc.status === \"ready\" ? \"ready\" : svc.status === \"warning\" ? \"warning\" : svc.status === \"error\" ? \"stopped\" : \"indeterminate\"}`, \"svelte-1orw49v\")}></div></div></div>`);\n\t\t}\n\t\t$$renderer.push(`<!--]--></div> `);\n\t\tif (deployError) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div id=\"deploy-failure\">`);\n\t\t\tFriendlyError($$renderer, { error: friendlyError(deployError, \"deploy\") });\n\t\t\t$$renderer.push(`<!----></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (!deployDone && !deployError) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<aside class=\"deploy-tips\" id=\"deploy-tips\"><div class=\"deploy-tips-header\"><span class=\"deploy-tips-kicker\">Tips</span> <h3>${escape_html(voiceEnabled() ? \"First install may take 10–30 minutes\" : \"First startup takes a few minutes\")}</h3></div> <ul>`);\n\t\t\tif (voiceEnabled()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<li>The OpenPalm Voice image is ~2.4 GB — the largest piece by far. Download speed depends on your internet connection.</li> <li>The wizard waits as long as the download takes. Progress bars below show each service's state.</li>`);\n\t\t\t} else {\n\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<li>Container images are being downloaded for the first time.</li>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--> <li>The admin console will be available once all services are healthy.</li> `);\n\t\t\tif (isElectron) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<li>You can leave this window — we'll let you know when it's ready.</li>`);\n\t\t\t} else {\n\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<li><strong>Keep this tab open while installation runs.</strong></li>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--></ul></aside>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (deployDone) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"done-state\" id=\"deploy-done\"><div class=\"done-icon\"><svg width=\"48\" height=\"48\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"var(--s-moss)\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"></path><polyline points=\"22 4 12 14.01 9 11.01\"></polyline></svg></div> <h2>${escape_html(deployHasWarnings ? \"Setup Complete (with warnings)\" : \"Setup Complete\")}</h2> `);\n\t\t\tif (noStartMode()) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<p class=\"done-subtitle\">Configuration saved. Run 'openpalm start' to start services.</p>`);\n\t\t\t} else {\n\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<p class=\"done-subtitle\">${escape_html(deployHasWarnings ? \"Setup is complete. Some services are still warming up in the background.\" : \"Your OpenPalm stack is up and running.\")}</p> `);\n\t\t\t\tif (deployHasWarnings && warningRows().length > 0) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`<div class=\"deploy-warnings-note svelte-1orw49v\" role=\"status\" id=\"deploy-warnings-note\">Still warming up: ${escape_html(warningRows().map((s) => s.label || s.service).join(\", \"))}. You can finish setup now — these will be ready shortly.</div>`);\n\t\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\t\tif (deployData.imageWarning) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`<div class=\"feedback feedback--warning\" role=\"status\" id=\"deploy-image-warning\" style=\"margin-top:12px\"><span>⚠ ${escape_html(deployData.imageWarning)}</span></div>`);\n\t\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\t\tif (!isElectron) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`<p class=\"done-close-hint svelte-1orw49v\">Setup is complete. You can safely close this tab now.</p>`);\n\t\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<!--]--> <ul class=\"service-list\" id=\"deploy-service-list\"><!--[-->`);\n\t\t\t\tconst each_array_1 = ensure_array_like(services());\n\t\t\t\tfor (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {\n\t\t\t\t\tlet svc = each_array_1[$$index_1];\n\t\t\t\t\tconst name = svc.service || svc.label || \"\";\n\t\t\t\t\tconst linkInfo = serviceLinks()[name];\n\t\t\t\t\tconst isWarming = svc.status === \"warning\";\n\t\t\t\t\t$$renderer.push(`<li>`);\n\t\t\t\t\tif (linkInfo) {\n\t\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t\tconst url = \"http://127.0.0.1:\" + linkInfo.port + linkInfo.path;\n\t\t\t\t\t\t$$renderer.push(`<span class=\"deploy-svc-name\">${escape_html(linkInfo.label)}</span> <a${attr(\"href\", url)} target=\"_blank\" rel=\"noopener\" class=\"deploy-svc-link\">${escape_html(url)}</a> <span class=\"deploy-svc-status\">${escape_html(isWarming ? svc.label || \"⚠ Warming up\" : \"✓ Running\")}</span>`);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t\t$$renderer.push(`<span class=\"deploy-svc-name\">${escape_html(name)}</span> <span class=\"deploy-svc-status\">${escape_html(isWarming ? svc.label || \"⚠ Warming up\" : \"✓ Running\")}</span>`);\n\t\t\t\t\t}\n\t\t\t\t\t$$renderer.push(`<!--]--></li>`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]--></ul> <div class=\"done-links\"><a${attr(\"href\", resolve(\"/chat\"))} class=\"btn btn-primary\">Open Chat</a> <a${attr(\"href\", `http://127.0.0.1:${stringify(assistantPort())}`)} target=\"_blank\" rel=\"noopener\" class=\"btn btn-secondary\">OpenCode UI</a> <a${attr(\"href\", resolve(\"/\"))} class=\"btn btn-secondary\">Admin Dashboard</a></div>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (deployError) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"step-actions\" id=\"deploy-error-actions\"><button class=\"btn btn-secondary\" id=\"btn-deploy-back\">Back to Review</button> <button class=\"btn btn-primary\" id=\"btn-deploy-retry\">Retry</button></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]-->`);\n\t});\n}\n//#endregion\n//#region src/routes/setup/+page.svelte\nfunction _page($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\tlet currentStep = 0;\n\t\tlet maxVisitedStep = 0;\n\t\tlet showDeploy = false;\n\t\tlet systemCheckPassed = false;\n\t\tlet modelMode = \"cloud\";\n\t\tlet voiceEnabled = false;\n\t\tlet uiLoginPassword = \"\";\n\t\tlet autoModeImporting = false;\n\t\tlet gpuDetected = false;\n\t\tlet providerState = {};\n\t\tlet detectedHostProviders = [];\n\t\tconst hostLocalLlmRunning = derived(() => providerState[\"ollama\"]?.ollamaMode === \"running\" || detectedHostProviders.some((p) => p.provider === \"ollama\" || p.provider === \"lmstudio\"));\n\t\tlet opencodeProviders = [];\n\t\tlet opencodeAuth = {};\n\t\tlet allowEmptyInstall = false;\n\t\tlet recommendation = null;\n\t\tlet recommendationAlert = \"\";\n\t\tlet recommendationApplied = false;\n\t\tlet detectedGpuVramMb = 0;\n\t\tlet detectedGpuVendor = \"\";\n\t\tlet detectedGpuName = \"\";\n\t\t/** Generation counter per provider — discard stale verify results */\n\t\tconst verifyGeneration = {};\n\t\t/** AbortControllers for in-flight OAuth long-poll requests */\n\t\tconst oauthAbortControllers = {};\n\t\tlet modelSelection = {};\n\t\tlet voiceTts = { engine: \"\" };\n\t\tlet voiceStt = { engine: \"\" };\n\t\tconst enableVoice = derived(() => voiceTts.engine === \"openpalm-voice\" || voiceStt.engine === \"openpalm-voice\");\n\t\tlet voiceProfiles = [];\n\t\tlet selectedVoiceProfile = \"\";\n\t\tlet portalSelection = {\n\t\t\tdiscord: {\n\t\t\t\tenabled: false,\n\t\t\t\tbotToken: \"\",\n\t\t\t\tapplicationId: \"\"\n\t\t\t},\n\t\t\tslack: {\n\t\t\t\tenabled: false,\n\t\t\t\tslackBotToken: \"\",\n\t\t\t\tslackAppToken: \"\"\n\t\t\t}\n\t\t};\n\t\tlet ollamaEnabled = false;\n\t\tlet ollamaProfiles = [];\n\t\tlet selectedOllamaProfile = \"\";\n\t\tlet imageTag = \"\";\n\t\tlet installError = \"\";\n\t\tlet installing = false;\n\t\tlet deployData = {};\n\t\tlet deployDone = false;\n\t\tlet deployHasWarnings = false;\n\t\tlet deployError = null;\n\t\tlet deployTimer = null;\n\t\tlet deployPollErrors = 0;\n\t\tconst verifiedCount = derived(() => {\n\t\t\treturn PROVIDERS.map((p) => p.id).filter((id) => providerState[id]?.verified).length;\n\t\t});\n\t\tconst hasUsableAI = derived(() => !!modelSelection.llm?.model);\n\t\tconst verifiedProviders = derived(() => {\n\t\t\treturn PROVIDERS.filter((p) => providerState[p.id]?.verified);\n\t\t});\n\t\tconst canComplete = derived(() => !!modelSelection.llm?.model || allowEmptyInstall);\n\t\tconst hasOpenAI = derived(() => PROVIDERS.some((p) => p.id === \"openai\" && providerState[p.id]?.verified));\n\t\tconst voiceDefaults = derived(() => hasOpenAI() ? {\n\t\t\ttts: \"openai-tts\",\n\t\t\tstt: \"openai-stt\"\n\t\t} : {\n\t\t\ttts: \"browser-tts\",\n\t\t\tstt: \"browser-stt\"\n\t\t});\n\t\tconst displayedVoiceTts = derived(() => resolveVoiceSide(voiceTts, enableVoice(), voiceDefaults().tts));\n\t\tconst displayedVoiceStt = derived(() => resolveVoiceSide(voiceStt, enableVoice(), voiceDefaults().stt));\n\t\tconst persistedVoiceTts = derived(() => resolveVoiceSide(voiceTts, enableVoice(), \"\"));\n\t\tconst persistedVoiceStt = derived(() => resolveVoiceSide(voiceStt, enableVoice(), \"\"));\n\t\tconst payload = derived(() => {\n\t\t\tconst llm = modelSelection.llm;\n\t\t\tconst emb = modelSelection.embedding;\n\t\t\tconst small = modelSelection.small;\n\t\t\tconst capabilityProviderIds = {};\n\t\t\tif (llm) capabilityProviderIds[llm.connId] = true;\n\t\t\tif (emb) capabilityProviderIds[emb.connId] = true;\n\t\t\tif (small?.model) capabilityProviderIds[small.connId] = true;\n\t\t\tconst capabilities = verifiedProviders().filter((p) => capabilityProviderIds[p.id]).map((p) => {\n\t\t\t\tconst st = providerState[p.id];\n\t\t\t\treturn {\n\t\t\t\t\tid: p.id,\n\t\t\t\t\tname: p.name,\n\t\t\t\t\tprovider: p.id,\n\t\t\t\t\tbaseUrl: st?.baseUrl ?? p.baseUrl,\n\t\t\t\t\tapiKey: st?.apiKey ?? \"\"\n\t\t\t\t};\n\t\t\t});\n\t\t\tconst llmConnId = llm?.connId ?? \"\";\n\t\t\tconst embConnId = emb?.connId ?? \"\";\n\t\t\tconst llmCap = capabilities.find((c) => c.id === llmConnId);\n\t\t\tconst embCap = capabilities.find((c) => c.id === embConnId);\n\t\t\tconst llmProvider = llmCap?.provider ?? \"\";\n\t\t\tconst embProvider = embCap?.provider ?? \"\";\n\t\t\tconst addons = {};\n\t\t\tif (ollamaEnabled && !hostLocalLlmRunning()) addons.ollama = true;\n\t\t\tif (persistedVoiceTts().engine === \"openpalm-voice\" || persistedVoiceStt().engine === \"openpalm-voice\") addons.voice = true;\n\t\t\tconst portalCredentials = {};\n\t\t\tconst portalsConfig = buildPortalsConfig();\n\t\t\tfor (const chId of Object.keys(portalsConfig)) {\n\t\t\t\tconst chVal = portalsConfig[chId];\n\t\t\t\tif (chVal === true) addons[chId] = true;\n\t\t\t\telse if (typeof chVal === \"object\" && chVal !== null) {\n\t\t\t\t\taddons[chId] = true;\n\t\t\t\t\tconst creds = {};\n\t\t\t\t\tfor (const key of Object.keys(chVal)) if (key !== \"enabled\" && chVal[key]) creds[key] = String(chVal[key]);\n\t\t\t\t\tif (Object.keys(creds).length > 0) portalCredentials[chId] = creds;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst result = {\n\t\t\t\tversion: 2,\n\t\t\t\taddons,\n\t\t\t\tsecurity: { uiLoginPassword },\n\t\t\t\tconnections: capabilities\n\t\t\t};\n\t\t\tif (llmProvider && llm?.model) result.llm = {\n\t\t\t\tprovider: llmProvider,\n\t\t\t\tmodel: llm.model,\n\t\t\t\tbaseUrl: llmCap?.baseUrl ?? \"\"\n\t\t\t};\n\t\t\tif (embProvider && emb?.model) result.embedding = {\n\t\t\t\tprovider: embProvider,\n\t\t\t\tmodel: emb.model,\n\t\t\t\tdims: emb.dims ?? 1536,\n\t\t\t\tbaseUrl: embCap?.baseUrl ?? \"\"\n\t\t\t};\n\t\t\tconst voicePayload = (v) => {\n\t\t\t\tif (!v.engine || v.engine.startsWith(\"skip-\")) return void 0;\n\t\t\t\tconst out = {\n\t\t\t\t\tenabled: true,\n\t\t\t\t\tengine: v.engine\n\t\t\t\t};\n\t\t\t\tif (v.provider) out.provider = v.provider;\n\t\t\t\tif (v.baseURL) out.baseURL = v.baseURL;\n\t\t\t\tif (v.model) out.model = v.model;\n\t\t\t\tif (v.voice) out.voice = v.voice;\n\t\t\t\tif (v.language) out.language = v.language;\n\t\t\t\tif (v.apiKey) out.apiKey = v.apiKey;\n\t\t\t\treturn out;\n\t\t\t};\n\t\t\tconst ttsCap = voicePayload(persistedVoiceTts());\n\t\t\tif (ttsCap) result.tts = ttsCap;\n\t\t\tconst sttCap = voicePayload(persistedVoiceStt());\n\t\t\tif (sttCap) result.stt = sttCap;\n\t\t\tif ((persistedVoiceTts().engine === \"openpalm-voice\" || persistedVoiceStt().engine === \"openpalm-voice\") && selectedVoiceProfile) result.voiceProfile = selectedVoiceProfile;\n\t\t\tif (ollamaEnabled && selectedOllamaProfile) result.ollamaProfile = selectedOllamaProfile;\n\t\t\tif (Object.keys(portalCredentials).length > 0) result.portalCredentials = portalCredentials;\n\t\t\tif (imageTag.trim());\n\t\t\treturn result;\n\t\t});\n\t\tfunction buildPortalsConfig() {\n\t\t\tconst result = {};\n\t\t\tfor (const ch of PORTALS) {\n\t\t\t\tconst sel = portalSelection[ch.id];\n\t\t\t\tif (ch.locked) result[ch.id] = true;\n\t\t\t\telse if (typeof sel === \"object\" && sel !== null) {\n\t\t\t\t\tif (sel.enabled) {\n\t\t\t\t\t\tconst entry = { enabled: true };\n\t\t\t\t\t\tif (ch.credentials) for (const cred of ch.credentials) {\n\t\t\t\t\t\t\tconst v = sel[cred.key];\n\t\t\t\t\t\t\tif (v) entry[cred.key] = v;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tresult[ch.id] = entry;\n\t\t\t\t\t}\n\t\t\t\t} else if (sel) result[ch.id] = true;\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\tfunction enableRecommendedOllama(variant) {\n\t\t\tollamaEnabled = true;\n\t\t\tconst st = providerState[\"ollama\"];\n\t\t\tif (st) {\n\t\t\t\tst.selected = true;\n\t\t\t\tst.verified = true;\n\t\t\t\tst.ollamaMode = \"instack\";\n\t\t\t\tst.baseUrl = \"http://ollama:11434\";\n\t\t\t\tif (st.models.length === 0) st.models = [OLLAMA_DEFAULT_CHAT_MODEL];\n\t\t\t}\n\t\t\tselectedOllamaProfile = selectAddonProfileId(ollamaProfiles, \"ollama\", gpuDetected, variant) ?? addonProfileId(\"ollama\", variant ?? (gpuDetected ? \"cuda\" : \"cpu\"));\n\t\t}\n\t\tconst LOCAL_PROVIDER_IDS = new Set([\n\t\t\t\"ollama\",\n\t\t\t\"lmstudio\",\n\t\t\t\"llamacpp\",\n\t\t\t\"localai\",\n\t\t\t\"model-runner\"\n\t\t]);\n\t\tlet savedCloudLlm = void 0;\n\t\tlet detectedCloudConn = modelSelection.llm && !LOCAL_PROVIDER_IDS.has(modelSelection.llm.connId) ? modelSelection.llm.connId : \"\";\n\t\tfunction handleConnectModeChange(mode) {\n\t\t\tmodelMode = mode;\n\t\t\tif (mode === \"local\") {\n\t\t\t\tif (modelSelection.llm && !LOCAL_PROVIDER_IDS.has(modelSelection.llm.connId)) savedCloudLlm = modelSelection.llm;\n\t\t\t\tif (!hostLocalLlmRunning()) enableRecommendedOllama();\n\t\t\t\tconst localOpt = getModelOptionsForRole(\"llm\").find((o) => LOCAL_PROVIDER_IDS.has(o.connId));\n\t\t\t\tmodelSelection.llm = localOpt ? {\n\t\t\t\t\tconnId: localOpt.connId,\n\t\t\t\t\tmodel: localOpt.id,\n\t\t\t\t\tdims: localOpt.dims\n\t\t\t\t} : {\n\t\t\t\t\tconnId: \"ollama\",\n\t\t\t\t\tmodel: OLLAMA_DEFAULT_CHAT_MODEL,\n\t\t\t\t\tdims: 0\n\t\t\t\t};\n\t\t\t} else if (mode === \"cloud\") {\n\t\t\t\tif (savedCloudLlm) modelSelection.llm = savedCloudLlm;\n\t\t\t}\n\t\t}\n\t\tasync function fetchAndApplyRecommendation() {\n\t\t\tif (recommendationApplied) return;\n\t\t\tlet rec;\n\t\t\tif (recommendation) rec = recommendation;\n\t\t\telse try {\n\t\t\t\tconst res = await fetch(\"/api/setup/recommend\");\n\t\t\t\tif (!res.ok) return;\n\t\t\t\tconst data = await res.json();\n\t\t\t\tif (!data.ok || !data.recommendation) return;\n\t\t\t\trec = data.recommendation;\n\t\t\t\tif (Array.isArray(data.hostProviders)) detectedHostProviders = data.hostProviders;\n\t\t\t\tif (data.gpu) {\n\t\t\t\t\tdetectedGpuVramMb = data.gpu.vramMb ?? 0;\n\t\t\t\t\tdetectedGpuVendor = data.gpu.vendor ?? \"\";\n\t\t\t\t\tdetectedGpuName = data.gpu.name ?? \"\";\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\trecommendationApplied = true;\n\t\t\trecommendation = rec;\n\t\t\tswitch (rec.action) {\n\t\t\t\tcase \"use-cloud\":\n\t\t\t\t\trecommendationAlert = \"\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"use-host-providers\":\n\t\t\t\t\trecommendationAlert = rec.alert;\n\t\t\t\t\tif (!hostImportTriggered) {\n\t\t\t\t\t\thostImportTriggered = true;\n\t\t\t\t\t\tawait handleHostImport();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"enable-ollama\":\n\t\t\t\t\trecommendationAlert = rec.alert;\n\t\t\t\t\tenableRecommendedOllama(rec.profileVariant);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"connect-manually\":\n\t\t\t\t\trecommendationAlert = rec.alert;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tfunction handleEnableVoiceChange(v) {\n\t\t\tif (v) {\n\t\t\t\tif (voiceTts.engine !== \"openpalm-voice\") voiceTts = { engine: \"openpalm-voice\" };\n\t\t\t\tif (voiceStt.engine !== \"openpalm-voice\") voiceStt = { engine: \"openpalm-voice\" };\n\t\t\t\tif (!selectedVoiceProfile) {\n\t\t\t\t\tconst match = selectAddonProfileId(voiceProfiles, \"voice\", gpuDetected);\n\t\t\t\t\tif (match) selectedVoiceProfile = match;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (voiceTts.engine === \"openpalm-voice\") voiceTts = { engine: \"\" };\n\t\t\t\tif (voiceStt.engine === \"openpalm-voice\") voiceStt = { engine: \"\" };\n\t\t\t}\n\t\t}\n\t\tfunction goToStep(n) {\n\t\t\tif (n < 0 || n > 3) return;\n\t\t\tif (n > 0 && !systemCheckPassed) return;\n\t\t\tcurrentStep = n;\n\t\t\tif (n > maxVisitedStep) maxVisitedStep = n;\n\t\t\tshowDeploy = false;\n\t\t\tif (n === 1 && !isRerun) {\n\t\t\t\tfetchAndApplyRecommendation();\n\t\t\t\tautoSelectModels();\n\t\t\t}\n\t\t}\n\t\tfunction autoSelectModels() {\n\t\t\tfor (const roleId of [\n\t\t\t\t\"llm\",\n\t\t\t\t\"embedding\",\n\t\t\t\t\"small\"\n\t\t\t]) {\n\t\t\t\tif (modelSelection[roleId]) continue;\n\t\t\t\tif (roleId === \"embedding\") continue;\n\t\t\t\tconst options = getModelOptionsForRole(roleId);\n\t\t\t\tif (options.length === 0) continue;\n\t\t\t\tconst best = options[0];\n\t\t\t\tmodelSelection[roleId] = {\n\t\t\t\t\tconnId: best.connId,\n\t\t\t\t\tmodel: best.id,\n\t\t\t\t\tdims: best.dims\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tfunction getModelOptionsForRole(roleId) {\n\t\t\treturn buildModelOptions(roleId, verifiedProviders(), providerState);\n\t\t}\n\t\tasync function apiFetchModels(provider, baseUrl, apiKey) {\n\t\t\tconst url = \"/api/setup/models/\" + encodeURIComponent(provider);\n\t\t\tconst res = await fetch(url, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tapiKey: apiKey ?? \"\",\n\t\t\t\t\tbaseUrl: baseUrl ?? \"\"\n\t\t\t\t})\n\t\t\t});\n\t\t\tconst data = await res.json();\n\t\t\tif (!res.ok || data.status === \"recoverable_error\") throw new Error(data.error ?? \"Failed to fetch models (HTTP \" + res.status + \")\");\n\t\t\treturn data;\n\t\t}\n\t\tasync function verifyProvider(id) {\n\t\t\tconst p = PROVIDERS.find((x) => x.id === id);\n\t\t\tif (!p) return;\n\t\t\tconst st = providerState[id];\n\t\t\tif (!st) return;\n\t\t\tif (id === \"ollama\" && st.ollamaMode === \"instack\") {\n\t\t\t\tst.verified = true;\n\t\t\t\tst.error = false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst gen = (verifyGeneration[id] ?? 0) + 1;\n\t\t\tverifyGeneration[id] = gen;\n\t\t\tst.verifying = true;\n\t\t\tst.error = false;\n\t\t\tconst baseUrl = (st.baseUrl || p.baseUrl).trim();\n\t\t\tconst apiKey = (st.apiKey ?? \"\").trim();\n\t\t\ttry {\n\t\t\t\tconst result = await apiFetchModels(id, baseUrl, apiKey);\n\t\t\t\tif (verifyGeneration[id] !== gen) return;\n\t\t\t\tst.verified = true;\n\t\t\t\tst.error = false;\n\t\t\t\tst.models = result.models ?? [];\n\t\t\t} catch (e) {\n\t\t\t\tif (verifyGeneration[id] !== gen) return;\n\t\t\t\tst.verified = false;\n\t\t\t\tst.error = true;\n\t\t\t\tst.errorMessage = e instanceof Error ? e.message : \"\";\n\t\t\t\tst.models = [];\n\t\t\t}\n\t\t\tst.verifying = false;\n\t\t}\n\t\tasync function startOpenCodeOAuth(providerId, methodIndex) {\n\t\t\tconst st = providerState[providerId];\n\t\t\tif (!st) return;\n\t\t\tst.verifying = true;\n\t\t\tst.error = false;\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(\"/api/setup/opencode/provider/\" + encodeURIComponent(providerId) + \"/oauth/authorize\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\tbody: JSON.stringify({ method: methodIndex })\n\t\t\t\t});\n\t\t\t\tconst oauthRes = await res.json();\n\t\t\t\tif (!res.ok) throw new Error(oauthRes.message ?? \"OAuth failed\");\n\t\t\t\tst.oauthPolling = true;\n\t\t\t\tst.oauthUrl = oauthRes.url ?? \"\";\n\t\t\t\tst.oauthInstructions = oauthRes.instructions ?? \"\";\n\t\t\t\tif (oauthRes.url && oauthRes.method === \"auto\") window.open(oauthRes.url, \"_blank\");\n\t\t\t\tawait pollOpenCodeOAuth(providerId, methodIndex);\n\t\t\t} catch (e) {\n\t\t\t\tst.verifying = false;\n\t\t\t\tst.error = true;\n\t\t\t\tst.errorMessage = e instanceof Error ? e.message : \"OAuth failed\";\n\t\t\t\tst.oauthPolling = false;\n\t\t\t}\n\t\t}\n\t\tasync function pollOpenCodeOAuth(providerId, methodIndex) {\n\t\t\tconst st = providerState[providerId];\n\t\t\tconst ac = new AbortController();\n\t\t\toauthAbortControllers[providerId] = ac;\n\t\t\tconst timeoutSignal = AbortSignal.timeout(10 * 6e4);\n\t\t\tconst combinedSignal = AbortSignal.any ? AbortSignal.any([ac.signal, timeoutSignal]) : ac.signal;\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(\"/api/setup/opencode/provider/\" + encodeURIComponent(providerId) + \"/oauth/callback\", {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t\tbody: JSON.stringify({ method: methodIndex }),\n\t\t\t\t\tsignal: combinedSignal\n\t\t\t\t});\n\t\t\t\tconst data = await res.json().catch(() => null);\n\t\t\t\tif (res.ok && data?.ok) {\n\t\t\t\t\tst.verified = true;\n\t\t\t\t\tst.error = false;\n\t\t\t\t} else {\n\t\t\t\t\tst.error = true;\n\t\t\t\t\tst.errorMessage = data?.message ?? \"Authorization failed\";\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tif (e instanceof Error && e.name === \"AbortError\" && ac.signal.aborted) return;\n\t\t\t\tif (e instanceof Error && e.name === \"AbortError\") {\n\t\t\t\t\tst.error = true;\n\t\t\t\t\tst.errorMessage = \"Authorization timed out. Try again.\";\n\t\t\t\t} else {\n\t\t\t\t\tst.error = true;\n\t\t\t\t\tst.errorMessage = e instanceof Error ? e.message : \"Authorization failed\";\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tdelete oauthAbortControllers[providerId];\n\t\t\t\tst.oauthPolling = false;\n\t\t\t\tst.verifying = false;\n\t\t\t}\n\t\t}\n\t\tfunction stopDeployPolling() {\n\t\t\tif (deployTimer) {\n\t\t\t\tclearInterval(deployTimer);\n\t\t\t\tdeployTimer = null;\n\t\t\t}\n\t\t}\n\t\tasync function pollDeployStatus() {\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(\"/api/setup/deploy-status\");\n\t\t\t\tif (!res.ok) {\n\t\t\t\t\tdeployPollErrors++;\n\t\t\t\t\tif (deployPollErrors >= 5) {\n\t\t\t\t\t\tstopDeployPolling();\n\t\t\t\t\t\tdeployError = \"Lost contact with the installer. Services may still be starting in the background.\";\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst data = await res.json();\n\t\t\t\tdeployPollErrors = 0;\n\t\t\t\tdeployData = data;\n\t\t\t\tif (data.deployError) {\n\t\t\t\t\tstopDeployPolling();\n\t\t\t\t\tdeployError = data.deployError;\n\t\t\t\t} else if (data.setupComplete && data.deployStatus && data.deployStatus.length > 0) {\n\t\t\t\t\tconst rows = data.deployStatus;\n\t\t\t\t\tconst allRunning = rows.every((s) => s.status === \"running\");\n\t\t\t\t\tconst onlyWarningsLeft = !data.deploying && rows.every((s) => s.status === \"running\" || s.status === \"warning\") && rows.some((s) => s.status === \"warning\");\n\t\t\t\t\tif (allRunning) {\n\t\t\t\t\t\tstopDeployPolling();\n\t\t\t\t\t\tdeployDone = true;\n\t\t\t\t\t} else if (onlyWarningsLeft) {\n\t\t\t\t\t\tstopDeployPolling();\n\t\t\t\t\t\tdeployHasWarnings = true;\n\t\t\t\t\t\tdeployDone = true;\n\t\t\t\t\t}\n\t\t\t\t} else if (data.setupComplete && !data.deploying && (!data.deployStatus || data.deployStatus.length === 0)) {\n\t\t\t\t\tstopDeployPolling();\n\t\t\t\t\tdeployDone = true;\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tdeployPollErrors++;\n\t\t\t\tif (deployPollErrors >= 5) {\n\t\t\t\t\tstopDeployPolling();\n\t\t\t\t\tdeployError = err instanceof Error ? `Lost contact with the installer: ${err.message}` : \"Lost contact with the installer.\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfunction handlePortalToggle(id) {\n\t\t\tconst sel = portalSelection[id];\n\t\t\tif (typeof sel === \"object\" && sel !== null) sel.enabled = !sel.enabled;\n\t\t\telse portalSelection[id] = !sel;\n\t\t}\n\t\tfunction handleCredentialChange(chId, credKey, value) {\n\t\t\tconst sel = portalSelection[chId];\n\t\t\tif (typeof sel === \"object\" && sel !== null) sel[credKey] = value;\n\t\t}\n\t\tasync function handleDeployRetry() {\n\t\t\tinstalling = false;\n\t\t\tdeployError = null;\n\t\t\tdeployDone = false;\n\t\t\tdeployHasWarnings = false;\n\t\t\tdeployData = {};\n\t\t\tdeployPollErrors = 0;\n\t\t\tconst res = await fetch(\"/api/setup/retry-deploy\", { method: \"POST\" });\n\t\t\tconst payload = await res.json().catch(() => ({}));\n\t\t\tif (!res.ok || payload?.ok === false) {\n\t\t\t\tdeployError = payload?.message ?? \"Retry failed.\";\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tinstalling = true;\n\t\t\tpollDeployStatus();\n\t\t}\n\t\tfunction handleDeployBack() {\n\t\t\tinstalling = false;\n\t\t\tdeployError = null;\n\t\t\tdeployDone = false;\n\t\t\tdeployHasWarnings = false;\n\t\t\tdeployData = {};\n\t\t\tdeployPollErrors = 0;\n\t\t\tshowDeploy = false;\n\t\t\tcurrentStep = 3;\n\t\t}\n\t\tlet hostImportTriggered = false;\n\t\tlet hostImporting = false;\n\t\tfunction markProviderVerifiedFromImport(id) {\n\t\t\tlet st = providerState[id];\n\t\t\tif (!st) {\n\t\t\t\tst = {\n\t\t\t\t\tselected: true,\n\t\t\t\t\tverified: true,\n\t\t\t\t\tverifying: false,\n\t\t\t\t\terror: false,\n\t\t\t\t\tapiKey: \"\",\n\t\t\t\t\tbaseUrl: \"\",\n\t\t\t\t\tmodels: [],\n\t\t\t\t\tollamaMode: null\n\t\t\t\t};\n\t\t\t\tproviderState[id] = st;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tst.verified = true;\n\t\t\tst.error = false;\n\t\t}\n\t\tasync function handleHostImport() {\n\t\t\thostImporting = true;\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(\"/api/setup/import-host\", { method: \"POST\" });\n\t\t\t\tconst data = await res.json().catch(() => null);\n\t\t\t\tif (!res.ok || !data?.ok) {\n\t\t\t\t\thostImporting = false;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst importedIds = data.importedProviders ?? data.pushedProviders ?? [];\n\t\t\t\tfor (const id of importedIds) markProviderVerifiedFromImport(id);\n\t\t\t\tawait Promise.allSettled(Object.keys(providerState).filter((id) => !providerState[id].verified && PROVIDERS.some((p) => p.id === id)).map((id) => verifyProvider(id)));\n\t\t\t\tautoSelectModels();\n\t\t\t\thostImporting = false;\n\t\t\t\tif (!isRerun) goToStep(1);\n\t\t\t} catch {\n\t\t\t\thostImporting = false;\n\t\t\t}\n\t\t}\n\t\tlet isRerun = false;\n\t\thead(\"g40i6i\", $$renderer, ($$renderer) => {\n\t\t\t$$renderer.title(($$renderer) => {\n\t\t\t\t$$renderer.push(`<title>OpenPalm Setup</title>`);\n\t\t\t});\n\t\t});\n\t\t$$renderer.push(`<main class=\"setup-page\" aria-label=\"Setup wizard\">`);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (currentStep === 0 && !showDeploy) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div style=\"display:none\" aria-hidden=\"true\"><section class=\"step-content step-content--hidden\" id=\"step-0\" data-testid=\"step-system-check\">`);\n\t\t\tSystemCheckStep($$renderer, {\n\t\t\t\tisRerun,\n\t\t\t\tonpass: () => {\n\t\t\t\t\tsystemCheckPassed = true;\n\t\t\t\t\tgoToStep(1);\n\t\t\t\t},\n\t\t\t\tonnext: () => {\n\t\t\t\t\tsystemCheckPassed = true;\n\t\t\t\t\tgoToStep(1);\n\t\t\t\t},\n\t\t\t\tongpudetected: () => {\n\t\t\t\t\tgpuDetected = true;\n\t\t\t\t\tif (voiceProfiles.length > 0 && selectedVoiceProfile !== addonProfileId(\"voice\", \"cuda\")) {\n\t\t\t\t\t\tconst cuda = voiceProfiles.find((p) => p.id === addonProfileId(\"voice\", \"cuda\") && p.available !== false);\n\t\t\t\t\t\tif (cuda) selectedVoiceProfile = cuda.id;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\t$$renderer.push(`<!----></section></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tif (showDeploy) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div style=\"flex:1; padding: 32px; overflow-y: auto;\">`);\n\t\t\tDeployStep($$renderer, {\n\t\t\t\tdeployData,\n\t\t\t\tdeployDone,\n\t\t\t\tdeployHasWarnings,\n\t\t\t\tdeployError,\n\t\t\t\tonback: handleDeployBack,\n\t\t\t\tonretry: handleDeployRetry\n\t\t\t});\n\t\t\t$$renderer.push(`<!----></div>`);\n\t\t} else if (currentStep >= 1) {\n\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t$$renderer.push(`<header class=\"wiz-topbar\"><div class=\"wiz-wordmark\">`);\n\t\t\tIconLogo($$renderer, { size: 30 });\n\t\t\t$$renderer.push(`<!----> <b>OpenPalm</b><span>setup</span></div> <nav class=\"wiz-ticker\" aria-label=\"Setup steps\"><!--[-->`);\n\t\t\tconst each_array = ensure_array_like([\n\t\t\t\t{\n\t\t\t\t\tn: 1,\n\t\t\t\t\tlabel: \"Connect\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tn: 2,\n\t\t\t\t\tlabel: \"Add-ons\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tn: 3,\n\t\t\t\t\tlabel: \"Finish\"\n\t\t\t\t}\n\t\t\t]);\n\t\t\tfor (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {\n\t\t\t\tlet tick = each_array[$$index];\n\t\t\t\t$$renderer.push(`<div${attr_class(\"wiz-tick\", void 0, {\n\t\t\t\t\t\"wiz-tick--active\": currentStep === tick.n,\n\t\t\t\t\t\"wiz-tick--done\": currentStep > tick.n\n\t\t\t\t})}${attr(\"aria-current\", currentStep === tick.n ? \"step\" : void 0)}>`);\n\t\t\t\tif (currentStep > tick.n) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`<svg viewBox=\"0 0 12 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"12\" height=\"12\" aria-hidden=\"true\"><path d=\"M2 6l3 3 5-5\"></path></svg>`);\n\t\t\t\t} else {\n\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`<span class=\"wiz-tick-num\">${escape_html(tick.n)}</span>`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]--> ${escape_html(tick.label)}</div>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--></nav></header> <div class=\"wiz-stage\"><div class=\"wiz-content\"><div class=\"wiz-content-scroll\"><div class=\"wiz-eyebrow\">`);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`STEP 1 · Connect`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`STEP 2 · Add-ons`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`STEP 3 · Finish`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></div> <h1 class=\"wiz-title\">`);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`Connect your <span class=\"accent\">AI brain</span>`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`Optional <span class=\"accent\">extras</span>`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`You're all <span class=\"accent\">set</span>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></h1> <p class=\"wiz-lede\">`);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\tif (hasUsableAI()) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`We found an AI service already set up. Just continue, or choose something different.`);\n\t\t\t\t} else {\n\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`Your assistant needs a source of intelligence. Pick one and you're set — you can add more later.`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]-->`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`All optional — turn on only what you want now. You can add or remove anything later from your dashboard.`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`OpenPalm is ready to install. Save the password you'll use to sign in.`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></p> `);\n\t\t\tif (recommendationAlert && currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<div class=\"feedback feedback--warning\" role=\"alert\" data-testid=\"recommendation-alert\"><span>${escape_html(recommendationAlert)}</span></div>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--> `);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<section class=\"step-content\" id=\"step-1\">`);\n\t\t\t\tScreen1ModelsStep($$renderer, {\n\t\t\t\t\tdetectionLoading: autoModeImporting,\n\t\t\t\t\tsystemCheckError: systemCheckPassed ? \"\" : \"\",\n\t\t\t\t\thostProviders: detectedHostProviders,\n\t\t\t\t\topencodeProviders,\n\t\t\t\t\topencodeAuth,\n\t\t\t\t\tproviderState,\n\t\t\t\t\tollamaEnabled,\n\t\t\t\t\tselectedOllamaProfile,\n\t\t\t\t\thostImporting,\n\t\t\t\t\tverifiedCount: verifiedCount(),\n\t\t\t\t\tallowEmptyInstall,\n\t\t\t\t\tllmModel: modelSelection.llm?.model ?? \"\",\n\t\t\t\t\tllmProvider: modelSelection.llm?.connId ?? \"\",\n\t\t\t\t\tdetectedCloudConn,\n\t\t\t\t\tgpuVramMb: detectedGpuVramMb,\n\t\t\t\t\tgpuVendor: detectedGpuVendor,\n\t\t\t\t\tgpuName: detectedGpuName,\n\t\t\t\t\tonmodelmodechange: handleConnectModeChange,\n\t\t\t\t\tonhostimport: () => void handleHostImport(),\n\t\t\t\t\tonoauthstart: startOpenCodeOAuth,\n\t\t\t\t\tonoauthcancel: (id) => {\n\t\t\t\t\t\tconst ac = oauthAbortControllers[id];\n\t\t\t\t\t\tif (ac) {\n\t\t\t\t\t\t\tac.abort();\n\t\t\t\t\t\t\tdelete oauthAbortControllers[id];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst st = providerState[id];\n\t\t\t\t\t\tif (st) {\n\t\t\t\t\t\t\tst.oauthPolling = false;\n\t\t\t\t\t\t\tst.verifying = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tonrecheck: () => void fetchAndApplyRecommendation(),\n\t\t\t\t\tonsystemcheckretry: () => {\n\t\t\t\t\t\tgoToStep(0);\n\t\t\t\t\t},\n\t\t\t\t\tonallowemptyinstallchange: (v) => {\n\t\t\t\t\t\tallowEmptyInstall = v;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t$$renderer.push(`<!----></section>`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`<section class=\"step-content\" id=\"step-2\">`);\n\t\t\t\tScreen2ExtrasStep($$renderer, {\n\t\t\t\t\tmodelMode,\n\t\t\t\t\tvoiceEnabled,\n\t\t\t\t\tvoiceTts: displayedVoiceTts(),\n\t\t\t\t\tvoiceStt: displayedVoiceStt(),\n\t\t\t\t\thasOpenAI: hasOpenAI(),\n\t\t\t\t\tportalSelection,\n\t\t\t\t\tonvoiceenabledchange: (v) => {\n\t\t\t\t\t\tvoiceEnabled = v;\n\t\t\t\t\t\thandleEnableVoiceChange(v);\n\t\t\t\t\t},\n\t\t\t\t\tonchangetts: (v) => {\n\t\t\t\t\t\tvoiceTts = v;\n\t\t\t\t\t},\n\t\t\t\t\tonchangestt: (v) => {\n\t\t\t\t\t\tvoiceStt = v;\n\t\t\t\t\t},\n\t\t\t\t\tonportaltoggle: handlePortalToggle,\n\t\t\t\t\toncredentialchange: handleCredentialChange\n\t\t\t\t});\n\t\t\t\t$$renderer.push(`<!----></section>`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`<section class=\"step-content\" id=\"step-3\" data-testid=\"step-review\">`);\n\t\t\t\tReviewStep($$renderer, {\n\t\t\t\t\tuiLoginPassword,\n\t\t\t\t\tverifiedProviders: verifiedProviders(),\n\t\t\t\t\tmodelSelection,\n\t\t\t\t\tactiveTts: voiceEnabled ? displayedVoiceTts().engine : \"\",\n\t\t\t\t\tactiveStt: voiceEnabled ? displayedVoiceStt().engine : \"\",\n\t\t\t\t\tportalSelection,\n\t\t\t\t\tollamaEnabled,\n\t\t\t\t\thostProviderLabel: detectedHostProviders.length > 0 ? detectedHostProviders[0].provider : \"\",\n\t\t\t\t\tpayload: payload(),\n\t\t\t\t\tinstallError,\n\t\t\t\t\tisRerun,\n\t\t\t\t\tsystemCheckPassed,\n\t\t\t\t\toneditmodels: () => goToStep(1),\n\t\t\t\t\toneditextras: () => goToStep(2)\n\t\t\t\t});\n\t\t\t\t$$renderer.push(`<!----></section>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></div> <footer class=\"wiz-footer\"><div class=\"wiz-footer-left\">`);\n\t\t\tif (currentStep > 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<button class=\"btn btn-secondary\" aria-label=\"Back\">Back</button>`);\n\t\t\t} else {\n\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`<div></div>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--></div> <div class=\"wiz-footer-right\">`);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<button class=\"btn btn-primary\" id=\"btn-screen1-next\"${attr(\"disabled\", !canComplete(), true)}>`);\n\t\t\t\tif (modelSelection.llm?.connId && ![\n\t\t\t\t\t\"ollama\",\n\t\t\t\t\t\"lmstudio\",\n\t\t\t\t\t\"llamacpp\",\n\t\t\t\t\t\"localai\",\n\t\t\t\t\t\"model-runner\"\n\t\t\t\t].includes(modelSelection.llm.connId)) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`Use ${escape_html(modelSelection.llm.connId === \"openai\" ? \"ChatGPT\" : modelSelection.llm.connId === \"google\" ? \"Gemini\" : modelSelection.llm.connId === \"github-copilot\" ? \"GitHub Copilot\" : modelSelection.llm.connId === \"groq\" ? \"Groq\" : opencodeProviders.find((p) => p.id === modelSelection.llm.connId)?.name ?? modelSelection.llm.connId)} — Continue`);\n\t\t\t\t} else if (ollamaEnabled || detectedHostProviders.length > 0 || modelSelection.llm?.connId && [\n\t\t\t\t\t\"ollama\",\n\t\t\t\t\t\"lmstudio\",\n\t\t\t\t\t\"llamacpp\",\n\t\t\t\t\t\"localai\",\n\t\t\t\t\t\"model-runner\"\n\t\t\t\t].includes(modelSelection.llm.connId)) {\n\t\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t\t$$renderer.push(`Use local AI — Continue`);\n\t\t\t\t} else {\n\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`Continue`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]--></button>`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`<button class=\"btn btn-primary\" id=\"btn-screen2-next\">Continue</button>`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`<button class=\"btn btn-primary\" id=\"btn-install\"${attr(\"disabled\", !canComplete() || installing, true)}>`);\n\t\t\t\tif (installing) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`Installing...`);\n\t\t\t\t} else {\n\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`${escape_html(\"Install\")}`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]--></button>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></div></footer></div> <aside class=\"wiz-aside\" aria-label=\"Setup guide\"><div class=\"wiz-aside-top\"><img class=\"wiz-mascot\" src=\"/wizard-128.png\" alt=\"OpenPalm setup guide\"/> <div><b class=\"wiz-greet-name\">`);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\tif (hasUsableAI()) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`You're almost done!`);\n\t\t\t\t} else if (modelMode === \"local\" || ollamaEnabled || detectedHostProviders.length > 0) {\n\t\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t\t$$renderer.push(`Great choice.`);\n\t\t\t\t} else {\n\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`Pick what works for you.`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]-->`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`While you're here…`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`You're ready.`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></b> <span class=\"wiz-greet-sub\">`);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`Your setup guide`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`A few optional extras`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`Everything's in order`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></span></div></div> <p class=\"wiz-guide-lede\">`);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\tif (hasUsableAI()) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`We found an AI account on this computer. Just hit <strong>Continue</strong> and your assistant will use it automatically.`);\n\t\t\t\t} else if (modelMode === \"local\" || ollamaEnabled || detectedHostProviders.length > 0) {\n\t\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t\t$$renderer.push(`Running AI locally means your conversations never leave your machine. Perfect for privacy.`);\n\t\t\t\t} else {\n\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`Sign in once and you're set. A browser tab will open for you to log in — come back here when you're done, it connects automatically.`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]-->`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`All of this is optional. Skip this whole step if you want — your assistant works fine without any of these. You can turn them on whenever you're ready from the dashboard.`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`You're ready. Click <strong>Install OpenPalm</strong> and it'll start up in the background. The first launch pulls a few files — this takes a minute or two. When it's done, open your browser, sign in with that password, and you're good to go. Everything can be changed later from the dashboard.`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></p> <div class=\"wiz-guide-bullets\">`);\n\t\t\tif (currentStep === 1) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\tif (hasUsableAI()) {\n\t\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t\t$$renderer.push(`<div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><path d=\"M9 12l2 2 4-4\"></path><circle cx=\"12\" cy=\"12\" r=\"9\"></circle></svg></div> <div>Your existing connection is ready to use. No extra setup needed — just continue to the next step.</div></div> <div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><path d=\"M12 3l1.5 4.5H18l-3.75 2.7 1.5 4.5L12 12l-3.75 2.7 1.5-4.5L6 7.5h4.5z\"></path></svg></div> <div>Want to use something different? Select another option from the list — you can switch any time from the dashboard.</div></div>`);\n\t\t\t\t} else {\n\t\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t\t$$renderer.push(`<div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><circle cx=\"12\" cy=\"8\" r=\"4\"></circle><path d=\"M4 20c0-4 3.6-7 8-7s8 3 8 7\"></path></svg></div> <div><strong>Cloud services</strong> like ChatGPT are fast and easy — you just sign in.</div></div> <div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"12\" rx=\"2\"></rect><path d=\"M8 20h8M12 16v4\"></path></svg></div> <div><strong>Running locally</strong> keeps everything on your computer — private, free, no internet needed.</div></div>`);\n\t\t\t\t}\n\t\t\t\t$$renderer.push(`<!--]-->`);\n\t\t\t} else if (currentStep === 2) {\n\t\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t\t$$renderer.push(`<div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><rect x=\"9\" y=\"3\" width=\"6\" height=\"11\" rx=\"3\"></rect><path d=\"M5 11a7 7 0 0014 0M12 18v3\"></path></svg></div> <div>Voice runs locally — free, no internet needed. A small model downloads the first time you use it.</div></div> <div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><circle cx=\"12\" cy=\"12\" r=\"9\"></circle><path d=\"M12 8v4l3 3\"></path></svg></div> <div>Setup help: <a href=\"https://discord.com/developers/docs/quick-start/getting-started\" target=\"_blank\" rel=\"noopener\">How to set up a Discord bot →</a></div></div> <div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><path d=\"M3 12h18M3 6h18M3 18h18\"></path></svg></div> <div><a href=\"https://api.slack.com/quickstart\" target=\"_blank\" rel=\"noopener\">How to set up a Slack app →</a></div></div>`);\n\t\t\t} else if (currentStep === 3) {\n\t\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t\t$$renderer.push(`<div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><rect x=\"3\" y=\"11\" width=\"18\" height=\"10\" rx=\"2\"></rect><path d=\"M7 11V7a5 5 0 0110 0v4\"></path></svg></div> <div>Your sign-in password is already saved on this computer — keep a copy somewhere safe just in case.</div></div> <div class=\"wiz-bullet\"><div class=\"wiz-bullet-icon\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"><path d=\"M9 12l2 2 4-4\"></path><circle cx=\"12\" cy=\"12\" r=\"9\"></circle></svg></div> <div>Everything can be changed from the dashboard after install — providers, voice, portals, and more.</div></div>`);\n\t\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<!--]--></div> <div class=\"wiz-guide-privacy\"><svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" aria-hidden=\"true\"><path d=\"M8 1.5L2 4v4c0 3.3 2.5 5.8 6 6.5 3.5-.7 6-3.2 6-6.5V4L8 1.5z\"></path></svg> <span>It's your own assistant, running right here on your computer.</span></div></aside></div>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--></main>`);\n\t});\n}\n//#endregion\nexport { _page as default };\n"],"names":[],"mappings":";;;;;;AAkeA;AACA;AACA,SAAS,eAAe,CAAC,UAAU,EAAE,OAAO,EAAE;AAC9C,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,UAAU,KAAK;AAStC,EAAE,IAAI,OAAO,GAAG,IAAI;AACpB,EAAE,IAAI,MAAM,GAAG,IAAI;AAKnB,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,kHAAkH,CAAC,CAAC;AACvI,EAAE,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,0EAA0E,EAAE,UAAU,CAAC,6BAA6B,EAAE,MAAM,EAAE;AACjJ,GAAG,kBAAkB,EAAE,MAAM;AAC7B,GAAG,oBAAoB,EAAE;AACzB,GAAG,CAAC,CAAC,2CAA2C,CAAC,CAAC;AAClD,EAAE,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC;AAC9B,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AACnC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,0IAA0I,CAAC,CAAC;AAC/J,EAAE,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,yBAAyB,EAAE,UAAU,CAAC,6BAA6B,EAAE,MAAM,EAAE;AAChG,GAAG,kBAAkB,EAAE,MAAM;AAC7B,GAAG,oBAAoB,EAAE;AACzB,GAAG,CAAC,CAAC,2CAA2C,CAAC,CAAC;AAClD,EAAE,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC;AAC9B,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AACnC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,8IAA8I,CAAC,CAAC;AACnK,EAAE,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC,CAAC;AAC1C,EAAE,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;AAC9B,EAAE,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;AAC9B,EAAE,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,kGAAkG,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC,gEAAgE,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,wBAAwB,CAAC,CAAC;AAC/S,CAAC,CAAC,CAAC;AACH;AA2tBA;AACA;AACA,SAAS,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE;AACpC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,UAAU,KAAK;AA0BtC,EAAE,IAAI,cAAc,GAAG,EAAE;AAgKzB,EAAE,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC;AACrC,GAAG,QAAQ;AACX,GAAG,UAAU;AACb,GAAG,UAAU;AACb,GAAG,SAAS;AACZ,GAAG;AACH,GAAG,CAAC;AAEJ,EAA0B,cAAc,CAAC,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,GAAG;AA+UjI,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,UAAU,KAAK;AAC7C,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,UAAU,KAAK;AACpC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,6BAA6B,CAAC,CAAC;AACpD,GAAG,CAAC,CAAC;AACL,EAAE,CAAC,CAAC;AACJ,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,mDAAmD,CAAC,CAAC;AACxE,EAAE,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;AAC9B,EAAwC;AACxC,GAAG,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC;AAC/B,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,4IAA4I,CAAC,CAAC;AAClK,GAAG,eAAe,CAAC,UAiBf,CAAC;AACL,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,uBAAuB,CAAC,CAAC;AAC7C,EAAE;AACF,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;AAC9B,EAgTS,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC;AACtC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,CAAC;AACpC,CAAC,CAAC,CAAC;AACH;;;;"}