@jheavenknows/bluerouter 1.0.48 → 1.0.50

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 (414) hide show
  1. package/app/.next-cli-build/BUILD_ID +1 -1
  2. package/app/.next-cli-build/build-manifest.json +2 -2
  3. package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
  4. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page.js.nft.json +1 -1
  5. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
  6. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page.js.nft.json +1 -1
  7. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  8. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  9. package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
  10. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page.js.nft.json +1 -1
  11. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  12. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
  13. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
  14. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
  15. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
  16. package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
  17. package/app/.next-cli-build/server/app/(dashboard)/dashboard/ollama-nodes/page.js +1 -1
  18. package/app/.next-cli-build/server/app/(dashboard)/dashboard/ollama-nodes/page_client-reference-manifest.js +1 -1
  19. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page.js.nft.json +1 -1
  20. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  21. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  22. package/app/.next-cli-build/server/app/(dashboard)/dashboard/prompt-logs/page_client-reference-manifest.js +1 -1
  23. package/app/.next-cli-build/server/app/(dashboard)/dashboard/provider-health/page_client-reference-manifest.js +1 -1
  24. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  25. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  26. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  27. package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
  28. package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
  29. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
  30. package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  31. package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  32. package/app/.next-cli-build/server/app/(dashboard)/dashboard/virtual-combos/page_client-reference-manifest.js +1 -1
  33. package/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
  34. package/app/.next-cli-build/server/app/_global-error.html +1 -1
  35. package/app/.next-cli-build/server/app/_global-error.rsc +1 -1
  36. package/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
  37. package/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  38. package/app/.next-cli-build/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  39. package/app/.next-cli-build/server/app/_global-error.segments/_head.segment.rsc +1 -1
  40. package/app/.next-cli-build/server/app/_global-error.segments/_index.segment.rsc +1 -1
  41. package/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  42. package/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
  43. package/app/.next-cli-build/server/app/_not-found.html +1 -1
  44. package/app/.next-cli-build/server/app/_not-found.rsc +3 -3
  45. package/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +3 -3
  46. package/app/.next-cli-build/server/app/_not-found.segments/_head.segment.rsc +1 -1
  47. package/app/.next-cli-build/server/app/_not-found.segments/_index.segment.rsc +3 -3
  48. package/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  49. package/app/.next-cli-build/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  50. package/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  51. package/app/.next-cli-build/server/app/api/auth/ldap/test/route.js.nft.json +1 -1
  52. package/app/.next-cli-build/server/app/api/auth/ldap/users/route.js.nft.json +1 -1
  53. package/app/.next-cli-build/server/app/api/auth/login/route.js.nft.json +1 -1
  54. package/app/.next-cli-build/server/app/api/auth/logout/route.js.nft.json +1 -1
  55. package/app/.next-cli-build/server/app/api/auth/oidc/callback/route.js.nft.json +1 -1
  56. package/app/.next-cli-build/server/app/api/auth/oidc/start/route.js.nft.json +1 -1
  57. package/app/.next-cli-build/server/app/api/auth/oidc/test/route.js.nft.json +1 -1
  58. package/app/.next-cli-build/server/app/api/auth/status/route.js.nft.json +1 -1
  59. package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js.nft.json +1 -1
  60. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/alias/route.js.nft.json +1 -1
  61. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/autostart/route.js.nft.json +1 -1
  62. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/prompt-log-db/route.js.nft.json +1 -1
  63. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/root-ca/route.js.nft.json +1 -1
  64. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/route.js.nft.json +1 -1
  65. package/app/.next-cli-build/server/app/api/cli-tools/copilot-settings/route.js.nft.json +1 -1
  66. package/app/.next-cli-build/server/app/api/cli-tools/cowork-settings/route.js.nft.json +1 -1
  67. package/app/.next-cli-build/server/app/api/combos/[id]/route.js.nft.json +1 -1
  68. package/app/.next-cli-build/server/app/api/combos/route.js.nft.json +1 -1
  69. package/app/.next-cli-build/server/app/api/dashboard/prompt-logs/[id]/route.js.nft.json +1 -1
  70. package/app/.next-cli-build/server/app/api/dashboard/prompt-logs/route.js.nft.json +1 -1
  71. package/app/.next-cli-build/server/app/api/keys/[id]/route.js.nft.json +1 -1
  72. package/app/.next-cli-build/server/app/api/keys/route.js.nft.json +1 -1
  73. package/app/.next-cli-build/server/app/api/mcp/[plugin]/message/route.js.nft.json +1 -1
  74. package/app/.next-cli-build/server/app/api/mcp/[plugin]/sse/route.js.nft.json +1 -1
  75. package/app/.next-cli-build/server/app/api/media-providers/tts/deepgram/voices/route.js.nft.json +1 -1
  76. package/app/.next-cli-build/server/app/api/media-providers/tts/elevenlabs/voices/route.js.nft.json +1 -1
  77. package/app/.next-cli-build/server/app/api/media-providers/tts/inworld/voices/route.js.nft.json +1 -1
  78. package/app/.next-cli-build/server/app/api/media-providers/tts/minimax/voices/route.js.nft.json +1 -1
  79. package/app/.next-cli-build/server/app/api/models/alias/route.js.nft.json +1 -1
  80. package/app/.next-cli-build/server/app/api/models/availability/route.js.nft.json +1 -1
  81. package/app/.next-cli-build/server/app/api/models/custom/route.js.nft.json +1 -1
  82. package/app/.next-cli-build/server/app/api/models/disabled/route.js.nft.json +1 -1
  83. package/app/.next-cli-build/server/app/api/models/route.js +1 -1
  84. package/app/.next-cli-build/server/app/api/models/route.js.nft.json +1 -1
  85. package/app/.next-cli-build/server/app/api/models/test/route.js +1 -1
  86. package/app/.next-cli-build/server/app/api/models/test/route.js.nft.json +1 -1
  87. package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js.nft.json +1 -1
  88. package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js.nft.json +1 -1
  89. package/app/.next-cli-build/server/app/api/oauth/cursor/auto-import/route.js.nft.json +1 -1
  90. package/app/.next-cli-build/server/app/api/oauth/cursor/import/route.js.nft.json +1 -1
  91. package/app/.next-cli-build/server/app/api/oauth/gitlab/pat/route.js.nft.json +1 -1
  92. package/app/.next-cli-build/server/app/api/oauth/iflow/cookie/route.js.nft.json +1 -1
  93. package/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js.nft.json +1 -1
  94. package/app/.next-cli-build/server/app/api/oauth/kiro/social-exchange/route.js.nft.json +1 -1
  95. package/app/.next-cli-build/server/app/api/pricing/route.js.nft.json +1 -1
  96. package/app/.next-cli-build/server/app/api/provider-nodes/[id]/route.js.nft.json +1 -1
  97. package/app/.next-cli-build/server/app/api/provider-nodes/route.js.nft.json +1 -1
  98. package/app/.next-cli-build/server/app/api/providers/[id]/models/route.js.nft.json +1 -1
  99. package/app/.next-cli-build/server/app/api/providers/[id]/route.js.nft.json +1 -1
  100. package/app/.next-cli-build/server/app/api/providers/[id]/test/route.js.nft.json +1 -1
  101. package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js +1 -1
  102. package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js.nft.json +1 -1
  103. package/app/.next-cli-build/server/app/api/providers/client/route.js.nft.json +1 -1
  104. package/app/.next-cli-build/server/app/api/providers/route.js +1 -1
  105. package/app/.next-cli-build/server/app/api/providers/route.js.nft.json +1 -1
  106. package/app/.next-cli-build/server/app/api/providers/test-batch/route.js.nft.json +1 -1
  107. package/app/.next-cli-build/server/app/api/providers/validate/route.js.nft.json +1 -1
  108. package/app/.next-cli-build/server/app/api/proxy-pools/[id]/route.js.nft.json +1 -1
  109. package/app/.next-cli-build/server/app/api/proxy-pools/[id]/test/route.js.nft.json +1 -1
  110. package/app/.next-cli-build/server/app/api/proxy-pools/cloudflare-deploy/route.js.nft.json +1 -1
  111. package/app/.next-cli-build/server/app/api/proxy-pools/deno-deploy/route.js.nft.json +1 -1
  112. package/app/.next-cli-build/server/app/api/proxy-pools/route.js.nft.json +1 -1
  113. package/app/.next-cli-build/server/app/api/proxy-pools/vercel-deploy/route.js.nft.json +1 -1
  114. package/app/.next-cli-build/server/app/api/settings/database/route.js.nft.json +1 -1
  115. package/app/.next-cli-build/server/app/api/settings/require-login/route.js.nft.json +1 -1
  116. package/app/.next-cli-build/server/app/api/settings/route.js.nft.json +1 -1
  117. package/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
  118. package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
  119. package/app/.next-cli-build/server/app/api/translator/send/route.js.nft.json +1 -1
  120. package/app/.next-cli-build/server/app/api/translator/translate/route.js.nft.json +1 -1
  121. package/app/.next-cli-build/server/app/api/tunnel/disable/route.js.nft.json +1 -1
  122. package/app/.next-cli-build/server/app/api/tunnel/enable/route.js.nft.json +1 -1
  123. package/app/.next-cli-build/server/app/api/tunnel/status/route.js.nft.json +1 -1
  124. package/app/.next-cli-build/server/app/api/tunnel/tailscale-check/route.js.nft.json +1 -1
  125. package/app/.next-cli-build/server/app/api/tunnel/tailscale-disable/route.js.nft.json +1 -1
  126. package/app/.next-cli-build/server/app/api/tunnel/tailscale-enable/route.js.nft.json +1 -1
  127. package/app/.next-cli-build/server/app/api/tunnel/tailscale-install/route.js.nft.json +1 -1
  128. package/app/.next-cli-build/server/app/api/tunnel/tailscale-login/route.js.nft.json +1 -1
  129. package/app/.next-cli-build/server/app/api/tunnel/tailscale-start-daemon/route.js.nft.json +1 -1
  130. package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js.nft.json +1 -1
  131. package/app/.next-cli-build/server/app/api/usage/chart/route.js.nft.json +1 -1
  132. package/app/.next-cli-build/server/app/api/usage/history/route.js.nft.json +1 -1
  133. package/app/.next-cli-build/server/app/api/usage/providers/route.js.nft.json +1 -1
  134. package/app/.next-cli-build/server/app/api/usage/request-details/route.js.nft.json +1 -1
  135. package/app/.next-cli-build/server/app/api/usage/request-logs/route.js.nft.json +1 -1
  136. package/app/.next-cli-build/server/app/api/usage/stats/route.js.nft.json +1 -1
  137. package/app/.next-cli-build/server/app/api/usage/stream/route.js.nft.json +1 -1
  138. package/app/.next-cli-build/server/app/api/v1/api/chat/route.js.nft.json +1 -1
  139. package/app/.next-cli-build/server/app/api/v1/audio/speech/route.js.nft.json +1 -1
  140. package/app/.next-cli-build/server/app/api/v1/audio/transcriptions/route.js.nft.json +1 -1
  141. package/app/.next-cli-build/server/app/api/v1/chat/completions/route.js.nft.json +1 -1
  142. package/app/.next-cli-build/server/app/api/v1/embeddings/route.js.nft.json +1 -1
  143. package/app/.next-cli-build/server/app/api/v1/images/generations/route.js.nft.json +1 -1
  144. package/app/.next-cli-build/server/app/api/v1/messages/route.js.nft.json +1 -1
  145. package/app/.next-cli-build/server/app/api/v1/models/[kind]/route.js.nft.json +1 -1
  146. package/app/.next-cli-build/server/app/api/v1/models/route.js.nft.json +1 -1
  147. package/app/.next-cli-build/server/app/api/v1/responses/compact/route.js.nft.json +1 -1
  148. package/app/.next-cli-build/server/app/api/v1/responses/route.js.nft.json +1 -1
  149. package/app/.next-cli-build/server/app/api/v1/route.js.nft.json +1 -1
  150. package/app/.next-cli-build/server/app/api/v1/search/route.js.nft.json +1 -1
  151. package/app/.next-cli-build/server/app/api/v1/web/fetch/route.js.nft.json +1 -1
  152. package/app/.next-cli-build/server/app/api/v1beta/models/[...path]/route.js.nft.json +1 -1
  153. package/app/.next-cli-build/server/app/api/version/route.js +1 -1
  154. package/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
  155. package/app/.next-cli-build/server/app/api/version/shutdown/route.js.nft.json +1 -1
  156. package/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
  157. package/app/.next-cli-build/server/app/api/version/update/route.js.nft.json +1 -1
  158. package/app/.next-cli-build/server/app/api/virtual-combos/[id]/route.js.nft.json +1 -1
  159. package/app/.next-cli-build/server/app/api/virtual-combos/route.js.nft.json +1 -1
  160. package/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
  161. package/app/.next-cli-build/server/app/callback.html +1 -1
  162. package/app/.next-cli-build/server/app/callback.rsc +3 -3
  163. package/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +3 -3
  164. package/app/.next-cli-build/server/app/callback.segments/_head.segment.rsc +1 -1
  165. package/app/.next-cli-build/server/app/callback.segments/_index.segment.rsc +3 -3
  166. package/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +1 -1
  167. package/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
  168. package/app/.next-cli-build/server/app/callback.segments/callback.segment.rsc +1 -1
  169. package/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
  170. package/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +5 -5
  171. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +2 -2
  172. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat.segment.rsc +1 -1
  173. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  174. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  175. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +5 -5
  176. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_head.segment.rsc +1 -1
  177. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_index.segment.rsc +3 -3
  178. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +1 -1
  179. package/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
  180. package/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +5 -5
  181. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
  182. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
  183. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  184. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  185. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +5 -5
  186. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
  187. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_index.segment.rsc +3 -3
  188. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +1 -1
  189. package/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
  190. package/app/.next-cli-build/server/app/dashboard/combos.rsc +5 -5
  191. package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
  192. package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
  193. package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  194. package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  195. package/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +5 -5
  196. package/app/.next-cli-build/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
  197. package/app/.next-cli-build/server/app/dashboard/combos.segments/_index.segment.rsc +3 -3
  198. package/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +1 -1
  199. package/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
  200. package/app/.next-cli-build/server/app/dashboard/endpoint.rsc +6 -6
  201. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +3 -3
  202. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
  203. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  204. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  205. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +6 -6
  206. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
  207. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_index.segment.rsc +3 -3
  208. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +1 -1
  209. package/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
  210. package/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +5 -5
  211. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +2 -2
  212. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web.segment.rsc +1 -1
  213. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers.segment.rsc +1 -1
  214. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  215. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  216. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +5 -5
  217. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_head.segment.rsc +1 -1
  218. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_index.segment.rsc +3 -3
  219. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +1 -1
  220. package/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
  221. package/app/.next-cli-build/server/app/dashboard/mitm.rsc +5 -5
  222. package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +2 -2
  223. package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm.segment.rsc +1 -1
  224. package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  225. package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  226. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +5 -5
  227. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_head.segment.rsc +1 -1
  228. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_index.segment.rsc +3 -3
  229. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +1 -1
  230. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.html +1 -1
  231. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.rsc +5 -5
  232. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/!KGRhc2hib2FyZCk/dashboard/ollama-nodes/__PAGE__.segment.rsc +2 -2
  233. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/!KGRhc2hib2FyZCk/dashboard/ollama-nodes.segment.rsc +1 -1
  234. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  235. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  236. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/_full.segment.rsc +5 -5
  237. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/_head.segment.rsc +1 -1
  238. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/_index.segment.rsc +3 -3
  239. package/app/.next-cli-build/server/app/dashboard/ollama-nodes.segments/_tree.segment.rsc +1 -1
  240. package/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
  241. package/app/.next-cli-build/server/app/dashboard/profile.rsc +4 -4
  242. package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +1 -1
  243. package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
  244. package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  245. package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  246. package/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +4 -4
  247. package/app/.next-cli-build/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
  248. package/app/.next-cli-build/server/app/dashboard/profile.segments/_index.segment.rsc +3 -3
  249. package/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +1 -1
  250. package/app/.next-cli-build/server/app/dashboard/prompt-logs.html +1 -1
  251. package/app/.next-cli-build/server/app/dashboard/prompt-logs.rsc +4 -4
  252. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk/dashboard/prompt-logs/__PAGE__.segment.rsc +1 -1
  253. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk/dashboard/prompt-logs.segment.rsc +1 -1
  254. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  255. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  256. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_full.segment.rsc +4 -4
  257. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_head.segment.rsc +1 -1
  258. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_index.segment.rsc +3 -3
  259. package/app/.next-cli-build/server/app/dashboard/prompt-logs.segments/_tree.segment.rsc +1 -1
  260. package/app/.next-cli-build/server/app/dashboard/provider-health.html +1 -1
  261. package/app/.next-cli-build/server/app/dashboard/provider-health.rsc +4 -4
  262. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk/dashboard/provider-health/__PAGE__.segment.rsc +1 -1
  263. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk/dashboard/provider-health.segment.rsc +1 -1
  264. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  265. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  266. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_full.segment.rsc +4 -4
  267. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_head.segment.rsc +1 -1
  268. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_index.segment.rsc +3 -3
  269. package/app/.next-cli-build/server/app/dashboard/provider-health.segments/_tree.segment.rsc +1 -1
  270. package/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
  271. package/app/.next-cli-build/server/app/dashboard/providers/new.rsc +5 -5
  272. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
  273. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
  274. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  275. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  276. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  277. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +5 -5
  278. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
  279. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_index.segment.rsc +3 -3
  280. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +1 -1
  281. package/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
  282. package/app/.next-cli-build/server/app/dashboard/providers.rsc +5 -5
  283. package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
  284. package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  285. package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  286. package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  287. package/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +5 -5
  288. package/app/.next-cli-build/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
  289. package/app/.next-cli-build/server/app/dashboard/providers.segments/_index.segment.rsc +3 -3
  290. package/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +1 -1
  291. package/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
  292. package/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +5 -5
  293. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +2 -2
  294. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools.segment.rsc +1 -1
  295. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  296. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  297. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +5 -5
  298. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_head.segment.rsc +1 -1
  299. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_index.segment.rsc +3 -3
  300. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +1 -1
  301. package/app/.next-cli-build/server/app/dashboard/quota.html +2 -2
  302. package/app/.next-cli-build/server/app/dashboard/quota.rsc +6 -6
  303. package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +3 -3
  304. package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota.segment.rsc +1 -1
  305. package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  306. package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  307. package/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +6 -6
  308. package/app/.next-cli-build/server/app/dashboard/quota.segments/_head.segment.rsc +1 -1
  309. package/app/.next-cli-build/server/app/dashboard/quota.segments/_index.segment.rsc +3 -3
  310. package/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +1 -1
  311. package/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  312. package/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
  313. package/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +3 -3
  314. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +3 -3
  315. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
  316. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +3 -3
  317. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +1 -1
  318. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
  319. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
  320. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
  321. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
  322. package/app/.next-cli-build/server/app/dashboard/skills.html +1 -1
  323. package/app/.next-cli-build/server/app/dashboard/skills.rsc +5 -5
  324. package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills/__PAGE__.segment.rsc +2 -2
  325. package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills.segment.rsc +1 -1
  326. package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  327. package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  328. package/app/.next-cli-build/server/app/dashboard/skills.segments/_full.segment.rsc +5 -5
  329. package/app/.next-cli-build/server/app/dashboard/skills.segments/_head.segment.rsc +1 -1
  330. package/app/.next-cli-build/server/app/dashboard/skills.segments/_index.segment.rsc +3 -3
  331. package/app/.next-cli-build/server/app/dashboard/skills.segments/_tree.segment.rsc +1 -1
  332. package/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
  333. package/app/.next-cli-build/server/app/dashboard/translator.rsc +5 -5
  334. package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
  335. package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
  336. package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  337. package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  338. package/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +5 -5
  339. package/app/.next-cli-build/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
  340. package/app/.next-cli-build/server/app/dashboard/translator.segments/_index.segment.rsc +3 -3
  341. package/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +1 -1
  342. package/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
  343. package/app/.next-cli-build/server/app/dashboard/usage.rsc +5 -5
  344. package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
  345. package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
  346. package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  347. package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  348. package/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +5 -5
  349. package/app/.next-cli-build/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
  350. package/app/.next-cli-build/server/app/dashboard/usage.segments/_index.segment.rsc +3 -3
  351. package/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +1 -1
  352. package/app/.next-cli-build/server/app/dashboard/virtual-combos.html +2 -2
  353. package/app/.next-cli-build/server/app/dashboard/virtual-combos.rsc +4 -4
  354. package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/!KGRhc2hib2FyZCk/dashboard/virtual-combos/__PAGE__.segment.rsc +1 -1
  355. package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/!KGRhc2hib2FyZCk/dashboard/virtual-combos.segment.rsc +1 -1
  356. package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  357. package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  358. package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/_full.segment.rsc +4 -4
  359. package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/_head.segment.rsc +1 -1
  360. package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/_index.segment.rsc +3 -3
  361. package/app/.next-cli-build/server/app/dashboard/virtual-combos.segments/_tree.segment.rsc +1 -1
  362. package/app/.next-cli-build/server/app/dashboard.html +1 -1
  363. package/app/.next-cli-build/server/app/dashboard.rsc +5 -5
  364. package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
  365. package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  366. package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  367. package/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +5 -5
  368. package/app/.next-cli-build/server/app/dashboard.segments/_head.segment.rsc +1 -1
  369. package/app/.next-cli-build/server/app/dashboard.segments/_index.segment.rsc +3 -3
  370. package/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +1 -1
  371. package/app/.next-cli-build/server/app/index.html +1 -1
  372. package/app/.next-cli-build/server/app/index.rsc +3 -3
  373. package/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  374. package/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +3 -3
  375. package/app/.next-cli-build/server/app/index.segments/_head.segment.rsc +1 -1
  376. package/app/.next-cli-build/server/app/index.segments/_index.segment.rsc +3 -3
  377. package/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +1 -1
  378. package/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
  379. package/app/.next-cli-build/server/app/landing.html +1 -1
  380. package/app/.next-cli-build/server/app/landing.rsc +3 -3
  381. package/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +3 -3
  382. package/app/.next-cli-build/server/app/landing.segments/_head.segment.rsc +1 -1
  383. package/app/.next-cli-build/server/app/landing.segments/_index.segment.rsc +3 -3
  384. package/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +1 -1
  385. package/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +1 -1
  386. package/app/.next-cli-build/server/app/landing.segments/landing.segment.rsc +1 -1
  387. package/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
  388. package/app/.next-cli-build/server/app/login.html +1 -1
  389. package/app/.next-cli-build/server/app/login.rsc +3 -3
  390. package/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +3 -3
  391. package/app/.next-cli-build/server/app/login.segments/_head.segment.rsc +1 -1
  392. package/app/.next-cli-build/server/app/login.segments/_index.segment.rsc +3 -3
  393. package/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +1 -1
  394. package/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
  395. package/app/.next-cli-build/server/app/login.segments/login.segment.rsc +1 -1
  396. package/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
  397. package/app/.next-cli-build/server/chunks/3110.js +1 -1
  398. package/app/.next-cli-build/server/chunks/4746.js +1 -1
  399. package/app/.next-cli-build/server/chunks/7153.js +1 -1
  400. package/app/.next-cli-build/server/chunks/9526.js +1 -1
  401. package/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
  402. package/app/.next-cli-build/server/pages/404.html +1 -1
  403. package/app/.next-cli-build/server/pages/500.html +1 -1
  404. package/app/.next-cli-build/static/chunks/{1321-eedabf7e81f1c3b6.js → 1321-09507c0582fc3eea.js} +1 -1
  405. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/ollama-nodes/page-e8196c3a0d081fe2.js +1 -0
  406. package/app/cli/.build-home/AppData/Roaming/bluerouter/db/data.sqlite-shm +0 -0
  407. package/app/cli/.build-home/AppData/Roaming/bluerouter/db/data.sqlite-wal +0 -0
  408. package/app/package.json +1 -1
  409. package/package.json +1 -1
  410. package/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/ollama-nodes/page-a71722eadbda34b2.js +0 -1
  411. /package/app/.next-cli-build/static/{MLU9CMPXOlzdMDuh1Lkh- → paC9DUfj776NJyfY2fHFW}/_buildManifest.js +0 -0
  412. /package/app/.next-cli-build/static/{MLU9CMPXOlzdMDuh1Lkh- → paC9DUfj776NJyfY2fHFW}/_ssgManifest.js +0 -0
  413. /package/app/cli/.build-home/AppData/Roaming/bluerouter/db/backups/{upgrade-1.0.43-to-1.0.44-1.0.44-20260526-215241 → upgrade-1.0.48-to-1.0.49-1.0.49-20260526-233719}/data.sqlite +0 -0
  414. /package/app/cli/.build-home/AppData/Roaming/bluerouter/db/backups/{upgrade-1.0.44-to-1.0.45-1.0.45-20260526-220813 → upgrade-1.0.49-to-1.0.50-1.0.50-20260526-234400}/data.sqlite +0 -0
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1088],{72546:(e,a,r)=>{Promise.resolve().then(r.bind(r,99296))},99296:(e,a,r)=>{"use strict";r.r(a),r.d(a,{default:()=>C});var l=r(95155),t=r(12115),s=r(35497),n=r(65921);let d={"qwen3:1.7b":{minRamFreeMb:2048,minVramFreeMb:0,loadedRamFreeMb:512,loadedVramFreeMb:0,safetyMarginMb:512,notes:"small text model"},"qwen3:4b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:512,notes:"small/medium text model"},"qwen3:8b":{minRamFreeMb:6144,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"8B text model"},"qwen3:14b":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"14B class model"},"qwen3:32b":{minRamFreeMb:4096,minVramFreeMb:16e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"32B class model, GPU preferred"},"qwen3-coder:30b":{minRamFreeMb:8192,minVramFreeMb:24e3,loadedRamFreeMb:2048,loadedVramFreeMb:3072,safetyMarginMb:2048,notes:"30B coder, fits under 32GB VRAM with margin"},"qwen3-coder:latest":{minRamFreeMb:8192,minVramFreeMb:24e3,loadedRamFreeMb:2048,loadedVramFreeMb:3072,safetyMarginMb:2048,notes:"qwen3 coder latest, treat as 30B unless overridden"},"qwen2.5-coder:14b":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"14B coder"},"qwen2.5vl:7b":{minRamFreeMb:8192,minVramFreeMb:8e3,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"7B vision-language"},"qwen2.5vl:latest":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"vision-language latest, conservative"},"qwen3-ijs-k4-translate-vn2jp:latest":{minRamFreeMb:6144,minVramFreeMb:8e3,loadedRamFreeMb:1024,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"custom translate model, non-f16"},"qwen3-ijs-k4-translate:latest":{minRamFreeMb:6144,minVramFreeMb:8e3,loadedRamFreeMb:1024,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"custom translate model, non-f16"},"qwen3-jp-vi-k2-translate-f16:latest":{minRamFreeMb:8192,minVramFreeMb:16e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"custom f16 translate model"},"qwen3-mail-translate-f16:latest":{minRamFreeMb:8192,minVramFreeMb:16e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"custom f16 translate model"},"qwen3-prc-sc-k2-translate-jp2vn:latest":{minRamFreeMb:6144,minVramFreeMb:12e3,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"custom translate model"},"qwen3-jp-vi-translate:latest":{minRamFreeMb:6144,minVramFreeMb:8e3,loadedRamFreeMb:1024,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"custom translate model"},"bge-m3:latest":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:512,loadedVramFreeMb:0,safetyMarginMb:512,notes:"embedding model"},"deepseek-coder:6.7b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"6.7B coder"},"gemma4:e4b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:1024,notes:"small Gemma variant"},"gemma:7b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:1024,notes:"7B text model"},"glm-4.7-flash:latest":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"flash/local text model"},"gpt-oss:20b":{minRamFreeMb:8192,minVramFreeMb:12e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"20B class model, GPU preferred"},"llama3.1:8b":{minRamFreeMb:6144,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"8B text model"},"llama3.2-vision:latest":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"vision model"},"bge-m3:*":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:512,loadedVramFreeMb:0,safetyMarginMb:512,notes:"embedding model wildcard"},"gemma*:e4b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:1024,notes:"Gemma E4B wildcard"},"gemma*:7b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:1024,notes:"Gemma 7B wildcard"},"glm-4.7-flash:*":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"GLM flash wildcard"},"gpt-oss:20b*":{minRamFreeMb:8192,minVramFreeMb:12e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"GPT-OSS 20B wildcard"},"llama3.1:8b*":{minRamFreeMb:6144,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"Llama 3.1 8B wildcard"},"llama3.2-vision:*":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"Llama vision wildcard"},"qwen2.5-coder:14b*":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"Qwen2.5 coder 14B wildcard"},"qwen2.5vl:*":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"Qwen2.5 VL wildcard"},"qwen3-coder:30b*":{minRamFreeMb:8192,minVramFreeMb:24e3,loadedRamFreeMb:2048,loadedVramFreeMb:3072,safetyMarginMb:2048,notes:"Qwen3 coder 30B wildcard"},"qwen3-*-translate-f16:*":{minRamFreeMb:8192,minVramFreeMb:16e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"custom Qwen3 f16 translate wildcard"},"qwen3-*-translate*:latest":{minRamFreeMb:6144,minVramFreeMb:8e3,loadedRamFreeMb:1024,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"custom Qwen3 translate wildcard"},"*:1.7b":{minRamFreeMb:2048,minVramFreeMb:0,loadedRamFreeMb:512,loadedVramFreeMb:0,safetyMarginMb:512,notes:"generic 1.7B fallback"},"*:4b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:512,notes:"generic 4B fallback"},"*:6.7b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"generic 6-7B fallback"},"*:7b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"generic 7B fallback"},"*:8b":{minRamFreeMb:6144,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"generic 8B fallback"},"*:14b":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"generic 14B fallback"},"*:20b":{minRamFreeMb:8192,minVramFreeMb:12e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"generic 20B fallback"},"*:30b":{minRamFreeMb:8192,minVramFreeMb:24e3,loadedRamFreeMb:2048,loadedVramFreeMb:3072,safetyMarginMb:2048,notes:"generic 30B fallback"},"*:32b":{minRamFreeMb:4096,minVramFreeMb:16e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"generic 32B fallback"}},o=["minRamFreeMb","minVramFreeMb","loadedRamFreeMb","loadedVramFreeMb","safetyMarginMb"],i={minRamFreeMb:"Wake RAM MB (sleep)",minVramFreeMb:"Wake VRAM MB (sleep)",loadedRamFreeMb:"Loaded RAM MB (loaded)",loadedVramFreeMb:"Loaded VRAM MB (loaded)",safetyMarginMb:"Safety MB (buffer)"},m={minRamFreeMb:"RAM free before wake",minVramFreeMb:"VRAM free before wake",loadedRamFreeMb:"RAM overhead if loaded",loadedVramFreeMb:"VRAM overhead if loaded",safetyMarginMb:"extra safety buffer"},c={model:"",minRamFreeMb:"4096",minVramFreeMb:"0",loadedRamFreeMb:"1024",loadedVramFreeMb:"0",safetyMarginMb:"1024"},b={model:"",overrideEnabled:!1,minRamFreeMb:"",minVramFreeMb:"",loadedRamFreeMb:"",loadedVramFreeMb:"",safetyMarginMb:""};function u(e){return null!=e&&""!==String(e).trim()}function x(e){return u(e)?String(e):""}function M(e){return[...new Set(Array.isArray(e)?e.map(e=>Number(e)).filter(e=>Number.isFinite(e)&&e>0):String(e||"11434").split(/[\s,;]+/).map(e=>Number(String(e).trim())).filter(e=>Number.isFinite(e)&&e>0))]}function h(e,a){return a||`ollama-${e||"default"}`}function p(e,a={}){let r=Number(e)||Number(a.port)||11434;return{id:a.id||`ollama-${r}`,name:a.name||`Ollama :${r}`,port:r,enabled:!1!==a.enabled,gpuMode:a.gpuMode||"auto",gpuIndices:Array.isArray(a.gpuIndices)?a.gpuIndices:[],allowMultiGpuSplit:!0===a.allowMultiGpuSplit,tags:Array.isArray(a.tags)?a.tags:[],modelMemoryRequirements:a.modelMemoryRequirements||{}}}function g(e={},{overrideRows:a=!1}={}){return Object.entries(e||{}).map(([e,r])=>({model:e,overrideEnabled:!a||r?.enabled!==!1,minRamFreeMb:x(r?.minRamFreeMb),minVramFreeMb:x(r?.minVramFreeMb),loadedRamFreeMb:x(r?.loadedRamFreeMb),loadedVramFreeMb:x(r?.loadedVramFreeMb),safetyMarginMb:x(r?.safetyMarginMb)}))}function f(e=[]){let a={};for(let r of e){let e=String(r.model||"").trim();if(!e||!0!==r.overrideEnabled)continue;let l={enabled:!0};for(let e of o)u(r[e])&&(l[e]=Math.max(0,Number(r[e]||0)));a[e]=l}return a}function v(e,a=[]){return function(e={},a=[]){let r=new Map;for(let e of a||[])e&&r.set(e,{...b,model:e,overrideEnabled:!1});for(let a of g(e||{},{overrideRows:!0})){let e=String(a.model||"").trim();e&&r.set(e,{...b,...a,model:e,overrideEnabled:!1!==a.overrideEnabled})}return[...r.values()].sort((e,a)=>String(e.model).localeCompare(String(a.model)))}(e?.modelMemoryRequirements||{},a)}function j(){return{name:"",host:"",sshUser:"root",sshPort:22,useSudo:!1,agentPort:19999,agentToken:"",ollamaPorts:"11434",refreshIntervalMs:15e3,ufwAllowFrom:"",enabled:!0,useGlobalModelMemory:!0,instances:[p(11434)],notes:""}}function F(e){if(!e)return"Never";let a=new Date(e);return Number.isNaN(a.getTime())?"Never":a.toLocaleString()}function y(e){let a=Number(e||0);return Number.isFinite(a)?a>=1024?`${(a/1024).toFixed(1)} GB`:`${Math.round(a)} MB`:"-"}function w(e){let a=new Set;for(let r of e?.models||[])a.add(r);return[...a].sort()}function N(e,a){let r=e?.lastStatus?.instances||[],l=Number(a?.port);return r.find(e=>Number(e.port)===l)||null}function R({children:e,variant:a="muted"}){return(0,l.jsx)("div",{className:`mt-1 truncate text-[10px] leading-4 ${"override"===a?"text-blue-600":"warning"===a?"text-amber-600":"text-text-muted"}`,children:e})}function V({value:e,onChange:a,disabled:r=!1,globalValue:t,globalEnabled:s=!0}){let n=u(e),d=u(t)?t:"none";return(0,l.jsxs)("div",{className:"min-w-[130px]",children:[(0,l.jsx)("input",{value:e??"",disabled:r,placeholder:s&&u(t)?String(t):"0",onChange:e=>a(e.target.value),className:`w-full rounded-md border border-border px-2 py-1.5 text-xs outline-none focus:border-primary ${r?"bg-surface-2 text-text-muted":"bg-background text-text-main"}`}),s?(0,l.jsxs)(R,{variant:n?"override":"muted",children:["Global: ",d,n?" \xb7 override":" \xb7 using global"]}):(0,l.jsx)(R,{variant:"warning",children:"Global disabled"})]})}function S({row:e,globalRule:a,useGlobal:r}){if(e.overrideEnabled){let a=o.filter(a=>u(e[a])).length;return(0,l.jsxs)(s.Ex,{variant:"warning",children:["override ",a,"/5"]})}return r&&a?(0,l.jsx)(s.Ex,{variant:"success",children:"global"}):r?(0,l.jsx)(s.Ex,{variant:"error",children:"no rule"}):(0,l.jsx)(s.Ex,{variant:"default",children:"global off"})}function k({instance:e}){return e?"cpu"===e.gpuMode?(0,l.jsx)(s.Ex,{children:"CPU only"}):"specific"===e.gpuMode?(0,l.jsxs)(s.Ex,{variant:"warning",children:["GPU ",(e.gpuIndices||[]).join(",")||"?"]}):"all"===e.gpuMode?(0,l.jsxs)(s.Ex,{variant:"success",children:["All GPUs",e.allowMultiGpuSplit?" \xb7 split":" \xb7 best one"]}):(0,l.jsx)(s.Ex,{children:"GPU auto"}):null}function C(){let e=(0,n.i)(),[a,r]=(0,t.useState)([]),[u,x]=(0,t.useState)(g(d)),[C,E]=(0,t.useState)(null),[A,P]=(0,t.useState)(!0),[G,$]=(0,t.useState)("nodes"),[q,O]=(0,t.useState)(!1),[B,I]=(0,t.useState)(!1),[U,T]=(0,t.useState)(null),[L,D]=(0,t.useState)(null),[H,_]=(0,t.useState)(j()),[z,Q]=(0,t.useState)(""),[W,J]=(0,t.useState)(""),[Z,K]=(0,t.useState)(!1),[X,Y]=(0,t.useState)(null),[ee,ea]=(0,t.useState)(""),[er,el]=(0,t.useState)(null),[et,es]=(0,t.useState)(!1),en=(0,t.useCallback)(async()=>{try{let e=await fetch("/api/ollama-model-memory",{cache:"no-store"}),a=await e.json();e.ok&&(x(g(a.requirements||a.modelMemoryRequirements||d)),E(a.updatedAt||null))}catch{e.error("Failed to load global model memory map")}},[e]),ed=(0,t.useCallback)(async()=>{try{let e=await fetch("/api/ollama-nodes",{cache:"no-store"}),a=await e.json();e.ok&&r(a.nodes||[])}catch{e.error("Failed to load Ollama nodes")}finally{P(!1)}},[e]),eo=(0,t.useCallback)(async(a,r=!1)=>{Y(a);try{let l=await fetch(`/api/ollama-nodes/${a}/status`,{method:"POST"}),t=await l.json();l.ok||r||e.error(t.error||"Refresh failed"),await ed(),l.ok&&!r&&e.success("Status refreshed")}catch{r||e.error("Refresh failed")}finally{Y(null)}},[ed,e]);(0,t.useEffect)(()=>{en(),ed()},[en,ed]),(0,t.useEffect)(()=>{let e=setInterval(()=>{let e=Date.now();a.forEach(a=>{if(!a.enabled)return;let r=a.lastStatusAt?new Date(a.lastStatusAt).getTime():0,l=Math.max(5e3,Number(a.refreshIntervalMs||15e3));(!r||e-r>=l)&&eo(a.id,!0)})},5e3);return()=>clearInterval(e)},[a,eo]);let ei=(0,t.useMemo)(()=>a.filter(e=>e.lastStatus?.ok&&!e.lastError).length,[a]),em=e=>{_(a=>({...a,instances:"function"==typeof e?e(a.instances||[]):e}))},ec=(e,a)=>{em(r=>r.map(r=>h(r.port,r.id)===e?{...r,...a}:r))},eb=(e,a,r,l)=>{em(t=>t.map(t=>{if(h(t.port,t.id)!==e)return t;let s=U?w(N(U,t)):[],n=v(t,s).map((e,t)=>t===a?{...e,[r]:"overrideEnabled"===r?!0===l||"true"===l||1===l||"1"===l:l}:e);return{...t,modelMemoryRequirements:f(n)}}))},eu=()=>{T(null),_(j()),O(!0)},ex=async()=>{if(!H.host.trim())return void e.warning("Host/IP is required");let a=(H.instances||[]).map(e=>p(e.port,{...e,gpuIndices:[...new Set(String(e.gpuIndices||"").split(/[\s,;]+/).map(e=>Number(e)).filter(e=>Number.isInteger(e)&&e>=0))],modelMemoryRequirements:e.modelMemoryRequirements||{}}));if(!1===H.useGlobalModelMemory&&!a.some(e=>Object.keys(e.modelMemoryRequirements||{}).length))return void e.warning("Global map is disabled. Enable at least one instance override rule or turn global fallback back on.");K(!0);try{let r={...H,ollamaPorts:M(H.ollamaPorts),instances:a,modelMemoryRequirements:{}},l=await fetch(U?`/api/ollama-nodes/${U.id}`:"/api/ollama-nodes",{method:U?"PUT":"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)}),t=await l.json();if(!l.ok)throw Error(t.error||"Save failed");O(!1),await ed(),e.success(U?"Ollama node updated":"Ollama node added")}catch(a){e.error(a.message||"Save failed")}finally{K(!1)}},eM=async()=>{if(L){Y(L.id),ea("Installing...\n");try{let a=await fetch(`/api/ollama-nodes/${L.id}/install`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sshPassword:z,sudoPassword:W,ufwAllowFrom:L.ufwAllowFrom})}),r=await a.json(),l=r.result?[r.result.stdout,r.result.stderr].filter(Boolean).join("\n"):r.error||"";if(ea(l),!a.ok)throw Error(r.error||"Install failed");e.success("Agent installed"),await eo(L.id,!0)}catch(a){e.error(a.message||"Install failed")}finally{Y(null)}}},eh=(e,a,r)=>x(l=>l.map((l,t)=>t===e?{...l,[a]:r}:l)),ep=async()=>{es(!0);try{let a=function(e=[]){let a={};for(let r of e){let e=String(r.model||"").trim();if(e)for(let l of(a[e]={},o))a[e][l]=Math.max(0,Number(r[l]||0))}return a}(u),r=await fetch("/api/ollama-model-memory",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({requirements:a})}),l=await r.json();if(!r.ok)throw Error(l.error||"Save global map failed");E(l.updatedAt||new Date().toISOString()),e.success("Global model memory map saved"),await ed()}catch(a){e.error(a.message||"Save global map failed")}finally{es(!1)}};return A?(0,l.jsx)(s.Qv,{}):(0,l.jsxs)("div",{className:"space-y-6",children:[(0,l.jsxs)("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h1",{className:"text-2xl font-semibold text-text-main",children:"Ollama Nodes"}),(0,l.jsx)("p",{className:"text-sm text-text-muted",children:"Remote install and monitor LAN Ollama hardware agents for hardware-aware routing."})]}),(0,l.jsxs)("div",{className:"flex items-center gap-2",children:[(0,l.jsxs)(s.Ex,{children:["Total: ",a.length]}),(0,l.jsxs)(s.Ex,{variant:"success",children:["Online: ",ei]}),(0,l.jsx)(s.$n,{icon:"add",onClick:eu,children:"Add Ollama Node"})]})]}),(0,l.jsxs)("div",{className:"rounded-2xl border border-border bg-surface-1 p-1",children:[(0,l.jsx)("button",{type:"button",onClick:()=>$("nodes"),className:`rounded-xl px-4 py-2 text-sm ${"nodes"===G?"bg-primary text-white":"text-text-muted hover:bg-surface-2"}`,children:"Nodes"}),(0,l.jsx)("button",{type:"button",onClick:()=>$("global"),className:`rounded-xl px-4 py-2 text-sm ${"global"===G?"bg-primary text-white":"text-text-muted hover:bg-surface-2"}`,children:"Global Model Memory Map"})]}),"global"===G?(0,l.jsxs)(s.Zp,{className:"p-5",children:[(0,l.jsxs)("div",{className:"mb-4 flex flex-wrap items-start justify-between gap-3",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h2",{className:"text-lg font-semibold text-text-main",children:"Global Model Memory Map"}),(0,l.jsx)("p",{className:"text-sm text-text-muted",children:"Global default RAM/VRAM thresholds shared by all nodes and all Ollama instances. Instance Override rules win only when Override is ON for that model."}),(0,l.jsxs)("p",{className:"text-xs text-text-muted",children:["Patterns with * are supported, for example ",(0,l.jsx)("span",{className:"font-mono",children:"gemma*"})," or ",(0,l.jsx)("span",{className:"font-mono",children:"bge-m3:*"}),". Last saved: ",F(C)]})]}),(0,l.jsxs)("div",{className:"flex flex-wrap gap-2",children:[(0,l.jsx)(s.$n,{variant:"secondary",icon:"add",onClick:()=>((e="")=>x(a=>[...a,{...c,model:e}]))(),children:"Add Rule"}),(0,l.jsx)(s.$n,{variant:"secondary",icon:"download",onClick:()=>{let r=function(e=[]){let a=[],r=new Set;for(let l of e)for(let e of function(e){let a=new Set,r=e?.lastStatus||{};for(let e of r.instances||[])for(let r of e.models||[])a.add(r);for(let e of r.ollama?.models||[])a.add(e);return[...a].sort()}(l))a.push(e),r.add(e);return{raw:a,unique:[...r].sort()}}(a);if(!r.unique.length)return void e.warning("No detected models found yet. Refresh one or more nodes first.");let l=new Set(u.map(e=>String(e.model||"").trim()).filter(Boolean)),t=r.unique.filter(e=>!l.has(e)).map(e=>({...c,model:e}));t.length?(x(e=>[...e,...t]),e.success(`Detected ${r.raw.length} entries, ${r.unique.length} unique. Added ${t.length}, skipped ${r.unique.length-t.length}.`)):e.success(`Detected ${r.raw.length} entries, ${r.unique.length} unique. All already exist in the global map.`)},children:"Import Detected"}),(0,l.jsx)(s.$n,{variant:"secondary",icon:"auto_fix_high",onClick:()=>{x(g(d)),e.success("Loaded default model memory presets")},children:"Presets"}),(0,l.jsx)(s.$n,{loading:et,onClick:ep,children:et?"Saving...":"Save Global Map"})]})]}),(0,l.jsx)("div",{className:"overflow-x-auto rounded-xl border border-border",children:(0,l.jsxs)("table",{className:"w-full min-w-[1120px] text-left text-sm",children:[(0,l.jsx)("thead",{className:"bg-surface-2 text-xs uppercase text-text-muted",children:(0,l.jsxs)("tr",{children:[(0,l.jsx)("th",{className:"px-3 py-2",children:"Model / Pattern"}),o.map(e=>(0,l.jsxs)("th",{className:"px-3 py-2",children:[(0,l.jsx)("div",{children:i[e]}),(0,l.jsx)("div",{className:"normal-case text-[11px]",children:m[e]})]},e)),(0,l.jsx)("th",{className:"px-3 py-2 text-right",children:"Action"})]})}),(0,l.jsx)("tbody",{children:u.map((e,a)=>(0,l.jsxs)("tr",{className:"border-t border-border",children:[(0,l.jsx)("td",{className:"px-3 py-2",children:(0,l.jsx)("input",{value:e.model,onChange:e=>eh(a,"model",e.target.value),placeholder:"qwen3:8b or gemma*",className:"w-full rounded-md border border-border bg-background px-2 py-1.5 font-mono text-xs outline-none focus:border-primary"})}),o.map(r=>(0,l.jsx)("td",{className:"px-3 py-2",children:(0,l.jsx)("input",{value:e[r]??"",onChange:e=>eh(a,r,e.target.value),className:"w-32 rounded-md border border-border bg-background px-2 py-1.5 text-xs outline-none focus:border-primary"})},r)),(0,l.jsx)("td",{className:"px-3 py-2 text-right",children:(0,l.jsx)("button",{type:"button",onClick:()=>x(e=>e.filter((e,r)=>r!==a)),className:"rounded-md px-2 py-1 text-red-500 hover:bg-red-500/10",title:"Remove rule",children:(0,l.jsx)("span",{className:"material-icons text-base",children:"delete"})})})]},`${e.model}-${a}`))})]})}),(0,l.jsxs)("div",{className:"mt-4 grid gap-3 md:grid-cols-3",children:[(0,l.jsxs)("div",{className:"rounded-xl bg-surface-2 p-3 text-xs text-text-muted",children:[(0,l.jsx)("b",{className:"text-text-main",children:"Wake:"})," sleeping model needs Wake RAM/VRAM + Safety before BlueRouter should wake it."]}),(0,l.jsxs)("div",{className:"rounded-xl bg-surface-2 p-3 text-xs text-text-muted",children:[(0,l.jsx)("b",{className:"text-text-main",children:"Loaded:"})," loaded model only needs smaller overhead memory."]}),(0,l.jsxs)("div",{className:"rounded-xl bg-surface-2 p-3 text-xs text-text-muted",children:[(0,l.jsx)("b",{className:"text-text-main",children:"Instance override:"})," specific port rules have priority over global rules."]})]})]}):0===a.length?(0,l.jsxs)(s.Zp,{className:"p-8 text-center",children:[(0,l.jsx)("h2",{className:"text-lg font-semibold text-text-main",children:"No Ollama nodes yet"}),(0,l.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Add a LAN Ollama machine, then install the hardware status agent from this dashboard."}),(0,l.jsx)(s.$n,{className:"mt-4",icon:"add",onClick:eu,children:"Add Ollama Node"})]}):(0,l.jsx)("div",{className:"grid gap-4",children:a.map(a=>{let r=a.lastStatus||{},t=a.lastEvaluation||{},n=r.hardware?.gpus||[],d=r.hardware?.ram||{};return(0,l.jsxs)(s.Zp,{className:"p-5",children:[(0,l.jsxs)("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,l.jsx)("h2",{className:"text-lg font-semibold text-text-main",children:a.name}),(0,l.jsx)(s.Ex,{variant:a.lastError?"error":a.lastStatus?.ok?"success":"default",children:a.lastError?"error":r.ok?"online":"unknown"}),t.hasBlockedSleepingModels?(0,l.jsx)(s.Ex,{variant:"error",children:"blocked sleeping models"}):null,(0,l.jsx)(s.Ex,{variant:a.enabled?"success":"default",children:a.enabled?"enabled":"disabled"}),(0,l.jsx)(s.Ex,{variant:!1===a.useGlobalModelMemory?"warning":"success",children:!1===a.useGlobalModelMemory?"global off":"global on"})]}),(0,l.jsxs)("p",{className:"mt-1 text-sm text-text-muted",children:[a.host,":",a.agentPort," \xb7 Ollama ports ",(a.ollamaPorts||[]).join(", ")," \xb7 Refresh ",a.refreshIntervalMs,"ms"]}),(0,l.jsxs)("p",{className:"mt-1 text-xs text-text-muted",children:["Last status: ",F(a.lastStatusAt),a.lastError?` \xb7 ${a.lastError}`:""]})]}),(0,l.jsxs)("div",{className:"flex flex-wrap gap-2",children:[(0,l.jsx)(s.$n,{size:"sm",variant:"secondary",icon:"refresh",onClick:()=>eo(a.id),disabled:X===a.id,children:X===a.id?"Working...":"Refresh"}),(0,l.jsx)(s.$n,{size:"sm",variant:"secondary",icon:"terminal",onClick:()=>{D(a),Q(""),J(""),ea(""),I(!0)},children:"Install Agent"}),(0,l.jsx)(s.$n,{size:"sm",variant:"ghost",icon:"edit",onClick:()=>{let e,r,l;return T(a),e=M(a?.ollamaPorts||[11434]),r=new Map((Array.isArray(a?.instances)?a.instances:[]).map(e=>[Number(e.port),e])),l=e.map(e=>{let a=r.get(Number(e))||{};return p(e,a)}),void(_({...j(),...a,ollamaPorts:(a.ollamaPorts||l.map(e=>e.port)||[11434]).join(","),useGlobalModelMemory:!1!==a.useGlobalModelMemory,instances:l}),O(!0))},children:"Edit"}),(0,l.jsx)(s.$n,{size:"sm",variant:"ghost",icon:"delete",onClick:()=>{el({title:"Delete Ollama Node",message:`Delete node "${a.name}"?`,onConfirm:async()=>{el(null),(await fetch(`/api/ollama-nodes/${a.id}`,{method:"DELETE"})).ok?(await ed(),e.success("Node deleted")):e.error("Delete failed")}})},children:"Delete"})]})]}),(0,l.jsxs)("div",{className:"mt-4 grid gap-4 md:grid-cols-2",children:[(0,l.jsxs)("div",{className:"rounded-xl border border-border p-4",children:[(0,l.jsx)("div",{className:"text-sm text-text-muted",children:"RAM"}),(0,l.jsxs)("div",{className:"mt-1 text-xl font-semibold text-text-main",children:[y(d.availableMb)," free"]}),(0,l.jsxs)("div",{className:"text-sm text-text-muted",children:["Total ",y(d.totalMb)," \xb7 Used ",d.usedPercent??"-","%"]})]}),(0,l.jsxs)("div",{className:"rounded-xl border border-border p-4",children:[(0,l.jsx)("div",{className:"text-sm text-text-muted",children:"GPU"}),n.length?n.map((e,a)=>(0,l.jsxs)("div",{className:"mt-2 flex flex-wrap items-center gap-2 text-sm",children:[(0,l.jsxs)("span",{className:"font-medium text-text-main",children:["GPU ",e.index??a," \xb7 ",e.name]}),(0,l.jsxs)(s.Ex,{children:["VRAM ",y(e.vramFreeMb)," / ",y(e.vramTotalMb)," free"]}),(0,l.jsxs)(s.Ex,{children:["GPU ",e.gpuUsagePercent,"%"]}),(0,l.jsxs)(s.Ex,{variant:Number(e.temperatureC)>=80?"error":"success",children:[e.temperatureC,"\xb0C"]})]},`${e.name}-${a}`)):(0,l.jsx)("div",{className:"mt-2 text-sm text-text-muted",children:"No NVIDIA GPU detected"})]})]}),(0,l.jsx)("div",{className:"mt-4 space-y-3",children:(t.instances||[]).map(e=>(0,l.jsxs)("div",{className:"rounded-xl border border-border p-4",children:[(0,l.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,l.jsxs)("h3",{className:"font-semibold text-text-main",children:["Ollama :",e.port||"default"]}),(0,l.jsx)(s.Ex,{variant:e.alive?"success":"error",children:e.alive?"alive":"down"}),(0,l.jsx)("span",{className:"text-xs text-text-muted",children:e.baseUrl}),(0,l.jsxs)(s.Ex,{children:["VRAM scope ",y(e.hardwareScope?.vramFreeMb)," free"]}),e.hardwareScope?.gpuIndices?.length?(0,l.jsxs)(s.Ex,{children:["GPU ",e.hardwareScope.gpuIndices.join(",")]}):null]}),e.modelReadiness?.length?(0,l.jsx)("div",{className:"mt-3 grid gap-2 md:grid-cols-2 xl:grid-cols-3",children:e.modelReadiness.map(e=>{var a;return(0,l.jsxs)("div",{className:"rounded-lg bg-surface-2 p-3 text-sm",children:[(0,l.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,l.jsx)("span",{className:"font-mono text-xs text-text-main",children:e.model}),(0,l.jsx)(s.Ex,{variant:e.loaded?"success":"default",children:e.loaded?"loaded":"sleeping"}),(0,l.jsx)(s.Ex,{variant:(a=e.status)?a.includes("insufficient")||a.includes("low")?"error":a.includes("unconfigured")?"warning":"success":"default",children:e.status}),(0,l.jsx)(s.Ex,{variant:e.ruleSource?.includes("instance")?"warning":e.ruleSource?.includes("global")?"success":"default",children:e.ruleSource||"none"})]}),(0,l.jsx)("p",{className:"mt-1 text-xs text-text-muted",children:e.reason})]},e.model)})}):(0,l.jsx)("div",{className:"mt-3 text-sm text-text-muted",children:"No models reported for this instance."})]},e.id||e.port||e.baseUrl))})]},a.id)})}),(0,l.jsx)(s.aF,{isOpen:q,onClose:()=>O(!1),title:U?"Edit Ollama Node":"Add Ollama Node",size:"full",className:"w-[calc(100vw-32px)] max-w-none xl:w-[96vw]",footer:(0,l.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,l.jsx)(s.$n,{onClick:ex,loading:Z,children:Z?"Saving...":"Save"}),(0,l.jsx)(s.$n,{variant:"ghost",onClick:()=>O(!1),disabled:Z,children:"Cancel"})]}),children:(0,l.jsxs)("div",{className:"max-h-[75vh] space-y-5 overflow-y-auto pr-2",children:[(0,l.jsxs)("div",{className:"grid gap-3 md:grid-cols-3",children:[(0,l.jsx)(s.pd,{label:"Name",value:H.name,onChange:e=>_(a=>({...a,name:e.target.value})),placeholder:"A2 node"}),(0,l.jsx)(s.pd,{label:"Host/IP",value:H.host,onChange:e=>_(a=>({...a,host:e.target.value})),placeholder:"192.168.1.10"}),(0,l.jsx)(s.pd,{label:"SSH User",value:H.sshUser,onChange:e=>_(a=>({...a,sshUser:e.target.value})),placeholder:"root or ubuntu"}),(0,l.jsx)(s.pd,{label:"SSH Port",value:H.sshPort,onChange:e=>_(a=>({...a,sshPort:e.target.value})),placeholder:"22"}),(0,l.jsx)(s.pd,{label:"Agent Port",value:H.agentPort,onChange:e=>_(a=>({...a,agentPort:e.target.value})),placeholder:"19999"}),(0,l.jsx)(s.pd,{label:"Agent Token",value:H.agentToken,onChange:e=>_(a=>({...a,agentToken:e.target.value})),placeholder:"auto if empty"}),(0,l.jsx)(s.pd,{label:"Ollama Ports",value:H.ollamaPorts,onChange:e=>{var a;return a=e.target.value,void _(e=>({...e,ollamaPorts:a,instances:function(e=[],a="11434"){let r=M(a),l=new Map((e||[]).map(e=>[Number(e.port),e]));return r.map(e=>p(e,l.get(Number(e))||{}))}(e.instances||[],a)}))},placeholder:"11434,11435"}),(0,l.jsx)(s.pd,{label:"Refresh Interval MS",value:H.refreshIntervalMs,onChange:e=>_(a=>({...a,refreshIntervalMs:e.target.value})),placeholder:"15000"}),(0,l.jsx)(s.pd,{label:"UFW Allow From",value:H.ufwAllowFrom,onChange:e=>_(a=>({...a,ufwAllowFrom:e.target.value})),placeholder:"192.168.1.0/24"})]}),(0,l.jsxs)("div",{className:"grid gap-3 md:grid-cols-2",children:[(0,l.jsx)("div",{className:"rounded-xl border border-border p-4",children:(0,l.jsxs)("div",{className:"flex items-center justify-between gap-3",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h3",{className:"font-semibold text-text-main",children:"Use sudo"}),(0,l.jsx)("p",{className:"text-sm text-text-muted",children:"Enable when SSH user is not root but has sudo rights."})]}),(0,l.jsx)(s.lM,{checked:!!H.useSudo,onChange:()=>_(e=>({...e,useSudo:!e.useSudo}))})]})}),(0,l.jsx)("div",{className:"rounded-xl border border-border p-4",children:(0,l.jsxs)("div",{className:"flex items-center justify-between gap-3",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h3",{className:"font-semibold text-text-main",children:"Use Global Model Memory Map"}),(0,l.jsx)("p",{className:"text-sm text-text-muted",children:"Global rules are fallback values. Per-instance overrides can still override them."})]}),(0,l.jsx)(s.lM,{checked:!1!==H.useGlobalModelMemory,onChange:()=>_(e=>({...e,useGlobalModelMemory:!1===e.useGlobalModelMemory}))})]})})]}),(0,l.jsxs)("div",{className:"rounded-xl border border-border p-4",children:[(0,l.jsxs)("div",{className:"mb-3",children:[(0,l.jsx)("h3",{className:"font-semibold text-text-main",children:"Per-instance Ollama Config"}),(0,l.jsx)("p",{className:"text-sm text-text-muted",children:"Each Ollama port is a separate routing target. Configure GPU binding and overrides per instance, not per physical machine."})]}),(0,l.jsx)("div",{className:"space-y-4",children:(H.instances||[]).map(e=>{var a;let r,t,n=h(e.port,e.id),d=U?N(U,e):null,c=U?(r=U?.lastEvaluation?.instances||[],t=Number(e?.port),r.find(e=>Number(e.port)===t)||null):null,x=v(e,w(d)),M=U?.lastStatus?.hardware?.gpus||[];return(0,l.jsxs)("div",{className:"rounded-2xl border border-border bg-surface-1 p-4",children:[(0,l.jsxs)("div",{className:"mb-3 flex flex-wrap items-center justify-between gap-3",children:[(0,l.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,l.jsx)("h4",{className:"font-semibold text-text-main",children:e.name||`Ollama :${e.port}`}),(0,l.jsx)(s.Ex,{variant:!1!==e.enabled?"success":"default",children:!1!==e.enabled?"enabled":"disabled"}),d?(0,l.jsx)(s.Ex,{variant:d.alive?"success":"error",children:d.alive?"alive":"down"}):null,(0,l.jsx)(k,{instance:e}),c?.hardwareScope?(0,l.jsxs)(s.Ex,{children:["Effective VRAM ",y(c.hardwareScope.vramFreeMb)," free"]}):null]}),(0,l.jsx)(s.lM,{checked:!1!==e.enabled,onChange:()=>ec(n,{enabled:!1===e.enabled})})]}),(0,l.jsxs)("div",{className:"mb-3 grid gap-3 md:grid-cols-4",children:[(0,l.jsx)(s.pd,{label:"Instance Name",value:e.name||"",onChange:e=>ec(n,{name:e.target.value}),placeholder:`Ollama :${e.port}`}),(0,l.jsx)(s.pd,{label:"Port",value:e.port,onChange:a=>ec(n,{port:Number(a.target.value)||e.port}),placeholder:"11434"}),(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("div",{className:"mb-1 text-sm font-medium text-text-main",children:"GPU Mode"}),(0,l.jsxs)("select",{value:e.gpuMode||"auto",onChange:e=>ec(n,{gpuMode:e.target.value}),className:"w-full rounded-lg border border-border bg-background px-3 py-2 text-sm outline-none focus:border-primary",children:[(0,l.jsx)("option",{value:"auto",children:"Auto / best available GPU"}),(0,l.jsx)("option",{value:"cpu",children:"CPU only"}),(0,l.jsx)("option",{value:"specific",children:"Specific GPU index"}),(0,l.jsx)("option",{value:"all",children:"All GPUs"})]})]}),(0,l.jsx)(s.pd,{label:"GPU Indices",value:Array.isArray(a=e.gpuIndices)?a.join(","):String(a||""),onChange:e=>ec(n,{gpuIndices:e.target.value}),placeholder:M.length?M.map((e,a)=>e.index??a).join(","):"0,1"})]}),(0,l.jsxs)("div",{className:"mb-3 flex flex-wrap items-center gap-3",children:[(0,l.jsxs)("label",{className:"flex items-center gap-2 text-sm text-text-muted",children:[(0,l.jsx)(s.lM,{checked:!0===e.allowMultiGpuSplit,onChange:()=>ec(n,{allowMultiGpuSplit:!0!==e.allowMultiGpuSplit})}),"Allow multi-GPU split / aggregate VRAM"]}),(0,l.jsx)("span",{className:"text-xs text-text-muted",children:"Auto/specific normally uses the best single GPU. Enable split only if this Ollama instance can actually split model layers across GPUs."})]}),(0,l.jsxs)("div",{className:"mb-2 flex flex-wrap items-center justify-between gap-2",children:[(0,l.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,l.jsx)(s.Ex,{variant:"warning",children:"instance overrides"}),(0,l.jsx)(s.Ex,{variant:!1===H.useGlobalModelMemory?"warning":"success",children:!1===H.useGlobalModelMemory?"global disabled":"global fallback on"}),(0,l.jsxs)("span",{className:"text-xs text-text-muted",children:["Models shown here belong to port ",e.port," only."]})]}),(0,l.jsxs)("div",{className:"flex gap-2",children:[(0,l.jsx)(s.$n,{size:"sm",variant:"secondary",icon:"add",onClick:()=>{em(e=>e.map(e=>{if(h(e.port,e.id)!==n)return e;let a=v(e,U?w(N(U,e)):[]);return a.push({...b,overrideEnabled:!0}),{...e,modelMemoryRequirements:f(a)}}))},children:"Add Override"}),(0,l.jsx)(s.$n,{size:"sm",variant:"secondary",icon:"cleaning_services",onClick:()=>{em(e=>e.map(e=>h(e.port,e.id)===n?{...e,modelMemoryRequirements:{}}:e))},children:"Clear"})]})]}),(0,l.jsx)("div",{className:"overflow-x-auto rounded-xl border border-border",children:(0,l.jsxs)("table",{className:"w-full min-w-[1320px] text-left text-sm",children:[(0,l.jsx)("thead",{className:"bg-surface-2 text-xs uppercase text-text-muted",children:(0,l.jsxs)("tr",{children:[(0,l.jsx)("th",{className:"px-3 py-2",children:"Model / Pattern"}),(0,l.jsx)("th",{className:"px-3 py-2",children:"Override"}),(0,l.jsx)("th",{className:"px-3 py-2",children:"Source"}),o.map(e=>(0,l.jsxs)("th",{className:"px-3 py-2",children:[(0,l.jsx)("div",{children:i[e]}),(0,l.jsx)("div",{className:"normal-case text-[11px]",children:m[e]})]},e)),(0,l.jsx)("th",{className:"px-3 py-2 text-right",children:"Action"})]})}),(0,l.jsxs)("tbody",{children:[x.map((e,a)=>{let r=!1===H.useGlobalModelMemory?null:function(e=[],a){let r=String(a||"").trim();if(!r)return null;let l=e.find(e=>String(e.model||"")===r);if(l)return{row:l,key:l.model,matchType:"exact"};let t=r.toLowerCase(),s=e.find(e=>String(e.model||"").toLowerCase()===t);if(s)return{row:s,key:s.model,matchType:"case-insensitive"};let n=e.find(e=>{let a;return String(e.model||"").includes("*")&&(a=String(e.model||"").split("*").map(e=>e.replace(/[|\\{}()[\]^$+?.]/g,"\\$&")).join(".*"),RegExp(`^${a}$`,"i")).test(r)});return n?{row:n,key:n.model,matchType:"wildcard"}:null}(u,e.model),t=r?.row||null,d=!0!==e.overrideEnabled;return(0,l.jsxs)("tr",{className:"border-t border-border",children:[(0,l.jsxs)("td",{className:"px-3 py-2 align-top",children:[(0,l.jsx)("input",{value:e.model,onChange:e=>eb(n,a,"model",e.target.value),placeholder:"qwen3:8b",className:"w-full rounded-md border border-border bg-background px-2 py-1.5 font-mono text-xs outline-none focus:border-primary"}),r?.matchType==="wildcard"?(0,l.jsxs)(R,{children:["Matched global pattern: ",r.key]}):null]}),(0,l.jsx)("td",{className:"px-3 py-2 align-top",children:(0,l.jsx)(s.lM,{checked:!0===e.overrideEnabled,onChange:()=>eb(n,a,"overrideEnabled",!0!==e.overrideEnabled)})}),(0,l.jsx)("td",{className:"px-3 py-2 align-top",children:(0,l.jsx)(S,{row:e,globalRule:t,useGlobal:!1!==H.useGlobalModelMemory})}),o.map(r=>(0,l.jsx)("td",{className:"px-3 py-2 align-top",children:(0,l.jsx)(V,{value:e[r]??"",disabled:d,globalValue:t?.[r],globalEnabled:!1!==H.useGlobalModelMemory,onChange:e=>eb(n,a,r,e)})},r)),(0,l.jsx)("td",{className:"px-3 py-2 text-right align-top",children:(0,l.jsx)("button",{type:"button",onClick:()=>{em(e=>e.map(e=>{if(h(e.port,e.id)!==n)return e;let r=v(e,U?w(N(U,e)):[]).filter((e,r)=>r!==a);return{...e,modelMemoryRequirements:f(r)}}))},className:"rounded-md px-2 py-1 text-red-500 hover:bg-red-500/10",title:"Remove row",children:(0,l.jsx)("span",{className:"material-icons text-base",children:"delete"})})})]},`${e.model}-${a}`)}),0===x.length?(0,l.jsx)("tr",{children:(0,l.jsx)("td",{colSpan:9,className:"px-3 py-6 text-center text-sm text-text-muted",children:"No models detected for this instance yet. Refresh status or add an override manually."})}):null]})]})})]},n)})})]})]})}),(0,l.jsx)(s.aF,{isOpen:B,onClose:()=>I(!1),title:`Install agent: ${L?.name||""}`,children:(0,l.jsxs)("div",{className:"space-y-4",children:[(0,l.jsx)("div",{className:"rounded-xl border border-amber-300 bg-amber-50 p-3 text-sm text-amber-800",children:"Passwords are used only for this install request and are not stored. The server running BlueRouter needs ssh or sshpass installed for password-based SSH."}),(0,l.jsx)(s.pd,{label:"SSH Password",value:z,onChange:e=>Q(e.target.value),type:"password",placeholder:"leave empty for SSH key"}),L?.useSudo?(0,l.jsx)(s.pd,{label:"Sudo Password",value:W,onChange:e=>J(e.target.value),type:"password",placeholder:"leave empty to reuse SSH password or passwordless sudo"}):null,(0,l.jsxs)("div",{className:"flex gap-2",children:[(0,l.jsx)(s.$n,{onClick:eM,disabled:X===L?.id,children:X===L?.id?"Installing...":"Install / Update Agent"}),(0,l.jsx)(s.$n,{variant:"ghost",onClick:()=>I(!1),disabled:X===L?.id,children:"Close"})]}),ee?(0,l.jsx)("pre",{className:"max-h-64 overflow-auto rounded-xl bg-surface-2 p-3 text-xs text-text-main",children:ee}):null]})}),(0,l.jsx)(s.uo,{isOpen:!!er,onClose:()=>el(null),onConfirm:er?.onConfirm,title:er?.title||"Confirm",message:er?.message,variant:"danger"})]})}}},e=>{e.O(0,[2574,3862,1051,1321,5497,8441,3794,7358],()=>e(e.s=72546)),_N_E=e.O()}]);
package/app/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bluerouter-app",
3
- "version": "1.0.48",
3
+ "version": "1.0.50",
4
4
  "description": "Router web dashboard",
5
5
  "private": true,
6
6
  "scripts": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jheavenknows/bluerouter",
3
- "version": "1.0.48",
3
+ "version": "1.0.50",
4
4
  "description": "Bluerouter CLI - Start and manage Bluerouter server",
5
5
  "bin": {
6
6
  "bluerouter": "./cli.js"
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[1088],{72546:(e,a,r)=>{Promise.resolve().then(r.bind(r,99296))},99296:(e,a,r)=>{"use strict";r.r(a),r.d(a,{default:()=>C});var l=r(95155),t=r(12115),s=r(35497),n=r(65921);let d={"qwen3:1.7b":{minRamFreeMb:2048,minVramFreeMb:0,loadedRamFreeMb:512,loadedVramFreeMb:0,safetyMarginMb:512,notes:"small text model"},"qwen3:4b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:512,notes:"small/medium text model"},"qwen3:8b":{minRamFreeMb:6144,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"8B text model"},"qwen3:14b":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"14B class model"},"qwen3:32b":{minRamFreeMb:4096,minVramFreeMb:16e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"32B class model, GPU preferred"},"qwen3-coder:30b":{minRamFreeMb:8192,minVramFreeMb:24e3,loadedRamFreeMb:2048,loadedVramFreeMb:3072,safetyMarginMb:2048,notes:"30B coder, fits under 32GB VRAM with margin"},"qwen3-coder:latest":{minRamFreeMb:8192,minVramFreeMb:24e3,loadedRamFreeMb:2048,loadedVramFreeMb:3072,safetyMarginMb:2048,notes:"qwen3 coder latest, treat as 30B unless overridden"},"qwen2.5-coder:14b":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"14B coder"},"qwen2.5vl:7b":{minRamFreeMb:8192,minVramFreeMb:8e3,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"7B vision-language"},"qwen2.5vl:latest":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"vision-language latest, conservative"},"qwen3-ijs-k4-translate-vn2jp:latest":{minRamFreeMb:6144,minVramFreeMb:8e3,loadedRamFreeMb:1024,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"custom translate model, non-f16"},"qwen3-ijs-k4-translate:latest":{minRamFreeMb:6144,minVramFreeMb:8e3,loadedRamFreeMb:1024,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"custom translate model, non-f16"},"qwen3-jp-vi-k2-translate-f16:latest":{minRamFreeMb:8192,minVramFreeMb:16e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"custom f16 translate model"},"qwen3-mail-translate-f16:latest":{minRamFreeMb:8192,minVramFreeMb:16e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"custom f16 translate model"},"qwen3-prc-sc-k2-translate-jp2vn:latest":{minRamFreeMb:6144,minVramFreeMb:12e3,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"custom translate model"},"qwen3-jp-vi-translate:latest":{minRamFreeMb:6144,minVramFreeMb:8e3,loadedRamFreeMb:1024,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"custom translate model"},"bge-m3:latest":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:512,loadedVramFreeMb:0,safetyMarginMb:512,notes:"embedding model"},"deepseek-coder:6.7b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"6.7B coder"},"gemma4:e4b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:1024,notes:"small Gemma variant"},"gemma:7b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:1024,notes:"7B text model"},"glm-4.7-flash:latest":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"flash/local text model"},"gpt-oss:20b":{minRamFreeMb:8192,minVramFreeMb:12e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"20B class model, GPU preferred"},"llama3.1:8b":{minRamFreeMb:6144,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"8B text model"},"llama3.2-vision:latest":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"vision model"},"bge-m3:*":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:512,loadedVramFreeMb:0,safetyMarginMb:512,notes:"embedding model wildcard"},"gemma*:e4b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:1024,notes:"Gemma E4B wildcard"},"gemma*:7b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:1024,notes:"Gemma 7B wildcard"},"glm-4.7-flash:*":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"GLM flash wildcard"},"gpt-oss:20b*":{minRamFreeMb:8192,minVramFreeMb:12e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"GPT-OSS 20B wildcard"},"llama3.1:8b*":{minRamFreeMb:6144,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"Llama 3.1 8B wildcard"},"llama3.2-vision:*":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"Llama vision wildcard"},"qwen2.5-coder:14b*":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"Qwen2.5 coder 14B wildcard"},"qwen2.5vl:*":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"Qwen2.5 VL wildcard"},"qwen3-coder:30b*":{minRamFreeMb:8192,minVramFreeMb:24e3,loadedRamFreeMb:2048,loadedVramFreeMb:3072,safetyMarginMb:2048,notes:"Qwen3 coder 30B wildcard"},"qwen3-*-translate-f16:*":{minRamFreeMb:8192,minVramFreeMb:16e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"custom Qwen3 f16 translate wildcard"},"qwen3-*-translate*:latest":{minRamFreeMb:6144,minVramFreeMb:8e3,loadedRamFreeMb:1024,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"custom Qwen3 translate wildcard"},"*:1.7b":{minRamFreeMb:2048,minVramFreeMb:0,loadedRamFreeMb:512,loadedVramFreeMb:0,safetyMarginMb:512,notes:"generic 1.7B fallback"},"*:4b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:0,safetyMarginMb:512,notes:"generic 4B fallback"},"*:6.7b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"generic 6-7B fallback"},"*:7b":{minRamFreeMb:4096,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"generic 7B fallback"},"*:8b":{minRamFreeMb:6144,minVramFreeMb:0,loadedRamFreeMb:1024,loadedVramFreeMb:512,safetyMarginMb:1024,notes:"generic 8B fallback"},"*:14b":{minRamFreeMb:8192,minVramFreeMb:1e4,loadedRamFreeMb:2048,loadedVramFreeMb:1024,safetyMarginMb:1024,notes:"generic 14B fallback"},"*:20b":{minRamFreeMb:8192,minVramFreeMb:12e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"generic 20B fallback"},"*:30b":{minRamFreeMb:8192,minVramFreeMb:24e3,loadedRamFreeMb:2048,loadedVramFreeMb:3072,safetyMarginMb:2048,notes:"generic 30B fallback"},"*:32b":{minRamFreeMb:4096,minVramFreeMb:16e3,loadedRamFreeMb:2048,loadedVramFreeMb:2048,safetyMarginMb:2048,notes:"generic 32B fallback"}},o=["minRamFreeMb","minVramFreeMb","loadedRamFreeMb","loadedVramFreeMb","safetyMarginMb"],i={minRamFreeMb:"Wake RAM MB (sleep)",minVramFreeMb:"Wake VRAM MB (sleep)",loadedRamFreeMb:"Loaded RAM MB (loaded)",loadedVramFreeMb:"Loaded VRAM MB (loaded)",safetyMarginMb:"Safety MB (buffer)"},m={minRamFreeMb:"RAM free before wake",minVramFreeMb:"VRAM free before wake",loadedRamFreeMb:"RAM overhead if loaded",loadedVramFreeMb:"VRAM overhead if loaded",safetyMarginMb:"extra safety buffer"},c={model:"",minRamFreeMb:"4096",minVramFreeMb:"0",loadedRamFreeMb:"1024",loadedVramFreeMb:"0",safetyMarginMb:"1024"},b={model:"",overrideEnabled:!1,minRamFreeMb:"",minVramFreeMb:"",loadedRamFreeMb:"",loadedVramFreeMb:"",safetyMarginMb:""};function u(e){return null!=e&&""!==String(e).trim()}function x(e){return u(e)?String(e):""}function M(e){return[...new Set(Array.isArray(e)?e.map(e=>Number(e)).filter(e=>Number.isFinite(e)&&e>0):String(e||"11434").split(/[\s,;]+/).map(e=>Number(String(e).trim())).filter(e=>Number.isFinite(e)&&e>0))]}function p(e,a){return a||`ollama-${e||"default"}`}function h(e,a={}){let r=Number(e)||Number(a.port)||11434;return{id:a.id||`ollama-${r}`,name:a.name||`Ollama :${r}`,port:r,enabled:!1!==a.enabled,gpuMode:a.gpuMode||"auto",gpuIndices:Array.isArray(a.gpuIndices)?a.gpuIndices:[],allowMultiGpuSplit:!0===a.allowMultiGpuSplit,tags:Array.isArray(a.tags)?a.tags:[],modelMemoryRequirements:a.modelMemoryRequirements||{}}}function g(e={},{overrideRows:a=!1}={}){return Object.entries(e||{}).map(([e,r])=>({model:e,overrideEnabled:!a||r?.enabled!==!1,minRamFreeMb:x(r?.minRamFreeMb),minVramFreeMb:x(r?.minVramFreeMb),loadedRamFreeMb:x(r?.loadedRamFreeMb),loadedVramFreeMb:x(r?.loadedVramFreeMb),safetyMarginMb:x(r?.safetyMarginMb)}))}function f(e=[]){let a={};for(let r of e){let e=String(r.model||"").trim();if(!e||!0!==r.overrideEnabled)continue;let l={enabled:!0};for(let e of o)u(r[e])&&(l[e]=Math.max(0,Number(r[e]||0)));o.some(e=>Object.prototype.hasOwnProperty.call(l,e))&&(a[e]=l)}return a}function v(e,a=[]){return function(e={},a=[]){let r=new Map;for(let e of a||[])e&&r.set(e,{...b,model:e,overrideEnabled:!1});for(let a of g(e||{},{overrideRows:!0})){let e=String(a.model||"").trim();e&&r.set(e,{...b,...a,model:e,overrideEnabled:!1!==a.overrideEnabled})}return[...r.values()].sort((e,a)=>String(e.model).localeCompare(String(a.model)))}(e?.modelMemoryRequirements||{},a)}function j(){return{name:"",host:"",sshUser:"root",sshPort:22,useSudo:!1,agentPort:19999,agentToken:"",ollamaPorts:"11434",refreshIntervalMs:15e3,ufwAllowFrom:"",enabled:!0,useGlobalModelMemory:!0,instances:[h(11434)],notes:""}}function F(e){if(!e)return"Never";let a=new Date(e);return Number.isNaN(a.getTime())?"Never":a.toLocaleString()}function y(e){let a=Number(e||0);return Number.isFinite(a)?a>=1024?`${(a/1024).toFixed(1)} GB`:`${Math.round(a)} MB`:"-"}function w(e){let a=new Set;for(let r of e?.models||[])a.add(r);return[...a].sort()}function N(e,a){let r=e?.lastStatus?.instances||[],l=Number(a?.port);return r.find(e=>Number(e.port)===l)||null}function R({children:e,variant:a="muted"}){return(0,l.jsx)("div",{className:`mt-1 truncate text-[10px] leading-4 ${"override"===a?"text-blue-600":"warning"===a?"text-amber-600":"text-text-muted"}`,children:e})}function V({value:e,onChange:a,disabled:r=!1,globalValue:t,globalEnabled:s=!0}){let n=u(e),d=u(t)?t:"none";return(0,l.jsxs)("div",{className:"min-w-[130px]",children:[(0,l.jsx)("input",{value:e??"",disabled:r,placeholder:s&&u(t)?String(t):"0",onChange:e=>a(e.target.value),className:`w-full rounded-md border border-border px-2 py-1.5 text-xs outline-none focus:border-primary ${r?"bg-surface-2 text-text-muted":"bg-background text-text-main"}`}),s?(0,l.jsxs)(R,{variant:n?"override":"muted",children:["Global: ",d,n?" \xb7 override":" \xb7 using global"]}):(0,l.jsx)(R,{variant:"warning",children:"Global disabled"})]})}function S({row:e,globalRule:a,useGlobal:r}){if(e.overrideEnabled){let a=o.filter(a=>u(e[a])).length;return(0,l.jsxs)(s.Ex,{variant:"warning",children:["override ",a,"/5"]})}return r&&a?(0,l.jsx)(s.Ex,{variant:"success",children:"global"}):r?(0,l.jsx)(s.Ex,{variant:"error",children:"no rule"}):(0,l.jsx)(s.Ex,{variant:"default",children:"global off"})}function k({instance:e}){return e?"cpu"===e.gpuMode?(0,l.jsx)(s.Ex,{children:"CPU only"}):"specific"===e.gpuMode?(0,l.jsxs)(s.Ex,{variant:"warning",children:["GPU ",(e.gpuIndices||[]).join(",")||"?"]}):"all"===e.gpuMode?(0,l.jsxs)(s.Ex,{variant:"success",children:["All GPUs",e.allowMultiGpuSplit?" \xb7 split":" \xb7 best one"]}):(0,l.jsx)(s.Ex,{children:"GPU auto"}):null}function C(){let e=(0,n.i)(),[a,r]=(0,t.useState)([]),[u,x]=(0,t.useState)(g(d)),[C,E]=(0,t.useState)(null),[A,P]=(0,t.useState)(!0),[G,$]=(0,t.useState)("nodes"),[q,O]=(0,t.useState)(!1),[B,I]=(0,t.useState)(!1),[U,T]=(0,t.useState)(null),[L,D]=(0,t.useState)(null),[H,_]=(0,t.useState)(j()),[z,Q]=(0,t.useState)(""),[W,J]=(0,t.useState)(""),[Z,K]=(0,t.useState)(!1),[X,Y]=(0,t.useState)(null),[ee,ea]=(0,t.useState)(""),[er,el]=(0,t.useState)(null),[et,es]=(0,t.useState)(!1),en=(0,t.useCallback)(async()=>{try{let e=await fetch("/api/ollama-model-memory",{cache:"no-store"}),a=await e.json();e.ok&&(x(g(a.requirements||a.modelMemoryRequirements||d)),E(a.updatedAt||null))}catch{e.error("Failed to load global model memory map")}},[e]),ed=(0,t.useCallback)(async()=>{try{let e=await fetch("/api/ollama-nodes",{cache:"no-store"}),a=await e.json();e.ok&&r(a.nodes||[])}catch{e.error("Failed to load Ollama nodes")}finally{P(!1)}},[e]),eo=(0,t.useCallback)(async(a,r=!1)=>{Y(a);try{let l=await fetch(`/api/ollama-nodes/${a}/status`,{method:"POST"}),t=await l.json();l.ok||r||e.error(t.error||"Refresh failed"),await ed(),l.ok&&!r&&e.success("Status refreshed")}catch{r||e.error("Refresh failed")}finally{Y(null)}},[ed,e]);(0,t.useEffect)(()=>{en(),ed()},[en,ed]),(0,t.useEffect)(()=>{let e=setInterval(()=>{let e=Date.now();a.forEach(a=>{if(!a.enabled)return;let r=a.lastStatusAt?new Date(a.lastStatusAt).getTime():0,l=Math.max(5e3,Number(a.refreshIntervalMs||15e3));(!r||e-r>=l)&&eo(a.id,!0)})},5e3);return()=>clearInterval(e)},[a,eo]);let ei=(0,t.useMemo)(()=>a.filter(e=>e.lastStatus?.ok&&!e.lastError).length,[a]),em=e=>{_(a=>({...a,instances:"function"==typeof e?e(a.instances||[]):e}))},ec=(e,a)=>{em(r=>r.map(r=>p(r.port,r.id)===e?{...r,...a}:r))},eb=(e,a,r,l)=>{em(t=>t.map(t=>{if(p(t.port,t.id)!==e)return t;let s=U?w(N(U,t)):[],n=v(t,s).map((e,t)=>t===a?{...e,[r]:"overrideEnabled"===r?!0===l||"true"===l||1===l||"1"===l:l}:e);return{...t,modelMemoryRequirements:f(n)}}))},eu=()=>{T(null),_(j()),O(!0)},ex=async()=>{if(!H.host.trim())return void e.warning("Host/IP is required");let a=(H.instances||[]).map(e=>h(e.port,{...e,gpuIndices:[...new Set(String(e.gpuIndices||"").split(/[\s,;]+/).map(e=>Number(e)).filter(e=>Number.isInteger(e)&&e>=0))],modelMemoryRequirements:e.modelMemoryRequirements||{}}));if(!1===H.useGlobalModelMemory&&!a.some(e=>Object.keys(e.modelMemoryRequirements||{}).length))return void e.warning("Global map is disabled. Enable at least one instance override rule or turn global fallback back on.");K(!0);try{let r={...H,ollamaPorts:M(H.ollamaPorts),instances:a,modelMemoryRequirements:{}},l=await fetch(U?`/api/ollama-nodes/${U.id}`:"/api/ollama-nodes",{method:U?"PUT":"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)}),t=await l.json();if(!l.ok)throw Error(t.error||"Save failed");O(!1),await ed(),e.success(U?"Ollama node updated":"Ollama node added")}catch(a){e.error(a.message||"Save failed")}finally{K(!1)}},eM=async()=>{if(L){Y(L.id),ea("Installing...\n");try{let a=await fetch(`/api/ollama-nodes/${L.id}/install`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sshPassword:z,sudoPassword:W,ufwAllowFrom:L.ufwAllowFrom})}),r=await a.json(),l=r.result?[r.result.stdout,r.result.stderr].filter(Boolean).join("\n"):r.error||"";if(ea(l),!a.ok)throw Error(r.error||"Install failed");e.success("Agent installed"),await eo(L.id,!0)}catch(a){e.error(a.message||"Install failed")}finally{Y(null)}}},ep=(e,a,r)=>x(l=>l.map((l,t)=>t===e?{...l,[a]:r}:l)),eh=async()=>{es(!0);try{let a=function(e=[]){let a={};for(let r of e){let e=String(r.model||"").trim();if(e)for(let l of(a[e]={},o))a[e][l]=Math.max(0,Number(r[l]||0))}return a}(u),r=await fetch("/api/ollama-model-memory",{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({requirements:a})}),l=await r.json();if(!r.ok)throw Error(l.error||"Save global map failed");E(l.updatedAt||new Date().toISOString()),e.success("Global model memory map saved"),await ed()}catch(a){e.error(a.message||"Save global map failed")}finally{es(!1)}};return A?(0,l.jsx)(s.Qv,{}):(0,l.jsxs)("div",{className:"space-y-6",children:[(0,l.jsxs)("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h1",{className:"text-2xl font-semibold text-text-main",children:"Ollama Nodes"}),(0,l.jsx)("p",{className:"text-sm text-text-muted",children:"Remote install and monitor LAN Ollama hardware agents for hardware-aware routing."})]}),(0,l.jsxs)("div",{className:"flex items-center gap-2",children:[(0,l.jsxs)(s.Ex,{children:["Total: ",a.length]}),(0,l.jsxs)(s.Ex,{variant:"success",children:["Online: ",ei]}),(0,l.jsx)(s.$n,{icon:"add",onClick:eu,children:"Add Ollama Node"})]})]}),(0,l.jsxs)("div",{className:"rounded-2xl border border-border bg-surface-1 p-1",children:[(0,l.jsx)("button",{type:"button",onClick:()=>$("nodes"),className:`rounded-xl px-4 py-2 text-sm ${"nodes"===G?"bg-primary text-white":"text-text-muted hover:bg-surface-2"}`,children:"Nodes"}),(0,l.jsx)("button",{type:"button",onClick:()=>$("global"),className:`rounded-xl px-4 py-2 text-sm ${"global"===G?"bg-primary text-white":"text-text-muted hover:bg-surface-2"}`,children:"Global Model Memory Map"})]}),"global"===G?(0,l.jsxs)(s.Zp,{className:"p-5",children:[(0,l.jsxs)("div",{className:"mb-4 flex flex-wrap items-start justify-between gap-3",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h2",{className:"text-lg font-semibold text-text-main",children:"Global Model Memory Map"}),(0,l.jsx)("p",{className:"text-sm text-text-muted",children:"Global default RAM/VRAM thresholds shared by all nodes and all Ollama instances. Instance Override rules win only when Override is ON for that model."}),(0,l.jsxs)("p",{className:"text-xs text-text-muted",children:["Patterns with * are supported, for example ",(0,l.jsx)("span",{className:"font-mono",children:"gemma*"})," or ",(0,l.jsx)("span",{className:"font-mono",children:"bge-m3:*"}),". Last saved: ",F(C)]})]}),(0,l.jsxs)("div",{className:"flex flex-wrap gap-2",children:[(0,l.jsx)(s.$n,{variant:"secondary",icon:"add",onClick:()=>((e="")=>x(a=>[...a,{...c,model:e}]))(),children:"Add Rule"}),(0,l.jsx)(s.$n,{variant:"secondary",icon:"download",onClick:()=>{let r=function(e=[]){let a=[],r=new Set;for(let l of e)for(let e of function(e){let a=new Set,r=e?.lastStatus||{};for(let e of r.instances||[])for(let r of e.models||[])a.add(r);for(let e of r.ollama?.models||[])a.add(e);return[...a].sort()}(l))a.push(e),r.add(e);return{raw:a,unique:[...r].sort()}}(a);if(!r.unique.length)return void e.warning("No detected models found yet. Refresh one or more nodes first.");let l=new Set(u.map(e=>String(e.model||"").trim()).filter(Boolean)),t=r.unique.filter(e=>!l.has(e)).map(e=>({...c,model:e}));t.length?(x(e=>[...e,...t]),e.success(`Detected ${r.raw.length} entries, ${r.unique.length} unique. Added ${t.length}, skipped ${r.unique.length-t.length}.`)):e.success(`Detected ${r.raw.length} entries, ${r.unique.length} unique. All already exist in the global map.`)},children:"Import Detected"}),(0,l.jsx)(s.$n,{variant:"secondary",icon:"auto_fix_high",onClick:()=>{x(g(d)),e.success("Loaded default model memory presets")},children:"Presets"}),(0,l.jsx)(s.$n,{loading:et,onClick:eh,children:et?"Saving...":"Save Global Map"})]})]}),(0,l.jsx)("div",{className:"overflow-x-auto rounded-xl border border-border",children:(0,l.jsxs)("table",{className:"w-full min-w-[1120px] text-left text-sm",children:[(0,l.jsx)("thead",{className:"bg-surface-2 text-xs uppercase text-text-muted",children:(0,l.jsxs)("tr",{children:[(0,l.jsx)("th",{className:"px-3 py-2",children:"Model / Pattern"}),o.map(e=>(0,l.jsxs)("th",{className:"px-3 py-2",children:[(0,l.jsx)("div",{children:i[e]}),(0,l.jsx)("div",{className:"normal-case text-[11px]",children:m[e]})]},e)),(0,l.jsx)("th",{className:"px-3 py-2 text-right",children:"Action"})]})}),(0,l.jsx)("tbody",{children:u.map((e,a)=>(0,l.jsxs)("tr",{className:"border-t border-border",children:[(0,l.jsx)("td",{className:"px-3 py-2",children:(0,l.jsx)("input",{value:e.model,onChange:e=>ep(a,"model",e.target.value),placeholder:"qwen3:8b or gemma*",className:"w-full rounded-md border border-border bg-background px-2 py-1.5 font-mono text-xs outline-none focus:border-primary"})}),o.map(r=>(0,l.jsx)("td",{className:"px-3 py-2",children:(0,l.jsx)("input",{value:e[r]??"",onChange:e=>ep(a,r,e.target.value),className:"w-32 rounded-md border border-border bg-background px-2 py-1.5 text-xs outline-none focus:border-primary"})},r)),(0,l.jsx)("td",{className:"px-3 py-2 text-right",children:(0,l.jsx)("button",{type:"button",onClick:()=>x(e=>e.filter((e,r)=>r!==a)),className:"rounded-md px-2 py-1 text-red-500 hover:bg-red-500/10",title:"Remove rule",children:(0,l.jsx)("span",{className:"material-icons text-base",children:"delete"})})})]},`${e.model}-${a}`))})]})}),(0,l.jsxs)("div",{className:"mt-4 grid gap-3 md:grid-cols-3",children:[(0,l.jsxs)("div",{className:"rounded-xl bg-surface-2 p-3 text-xs text-text-muted",children:[(0,l.jsx)("b",{className:"text-text-main",children:"Wake:"})," sleeping model needs Wake RAM/VRAM + Safety before BlueRouter should wake it."]}),(0,l.jsxs)("div",{className:"rounded-xl bg-surface-2 p-3 text-xs text-text-muted",children:[(0,l.jsx)("b",{className:"text-text-main",children:"Loaded:"})," loaded model only needs smaller overhead memory."]}),(0,l.jsxs)("div",{className:"rounded-xl bg-surface-2 p-3 text-xs text-text-muted",children:[(0,l.jsx)("b",{className:"text-text-main",children:"Instance override:"})," specific port rules have priority over global rules."]})]})]}):0===a.length?(0,l.jsxs)(s.Zp,{className:"p-8 text-center",children:[(0,l.jsx)("h2",{className:"text-lg font-semibold text-text-main",children:"No Ollama nodes yet"}),(0,l.jsx)("p",{className:"mt-1 text-sm text-text-muted",children:"Add a LAN Ollama machine, then install the hardware status agent from this dashboard."}),(0,l.jsx)(s.$n,{className:"mt-4",icon:"add",onClick:eu,children:"Add Ollama Node"})]}):(0,l.jsx)("div",{className:"grid gap-4",children:a.map(a=>{let r=a.lastStatus||{},t=a.lastEvaluation||{},n=r.hardware?.gpus||[],d=r.hardware?.ram||{};return(0,l.jsxs)(s.Zp,{className:"p-5",children:[(0,l.jsxs)("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[(0,l.jsxs)("div",{children:[(0,l.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,l.jsx)("h2",{className:"text-lg font-semibold text-text-main",children:a.name}),(0,l.jsx)(s.Ex,{variant:a.lastError?"error":a.lastStatus?.ok?"success":"default",children:a.lastError?"error":r.ok?"online":"unknown"}),t.hasBlockedSleepingModels?(0,l.jsx)(s.Ex,{variant:"error",children:"blocked sleeping models"}):null,(0,l.jsx)(s.Ex,{variant:a.enabled?"success":"default",children:a.enabled?"enabled":"disabled"}),(0,l.jsx)(s.Ex,{variant:!1===a.useGlobalModelMemory?"warning":"success",children:!1===a.useGlobalModelMemory?"global off":"global on"})]}),(0,l.jsxs)("p",{className:"mt-1 text-sm text-text-muted",children:[a.host,":",a.agentPort," \xb7 Ollama ports ",(a.ollamaPorts||[]).join(", ")," \xb7 Refresh ",a.refreshIntervalMs,"ms"]}),(0,l.jsxs)("p",{className:"mt-1 text-xs text-text-muted",children:["Last status: ",F(a.lastStatusAt),a.lastError?` \xb7 ${a.lastError}`:""]})]}),(0,l.jsxs)("div",{className:"flex flex-wrap gap-2",children:[(0,l.jsx)(s.$n,{size:"sm",variant:"secondary",icon:"refresh",onClick:()=>eo(a.id),disabled:X===a.id,children:X===a.id?"Working...":"Refresh"}),(0,l.jsx)(s.$n,{size:"sm",variant:"secondary",icon:"terminal",onClick:()=>{D(a),Q(""),J(""),ea(""),I(!0)},children:"Install Agent"}),(0,l.jsx)(s.$n,{size:"sm",variant:"ghost",icon:"edit",onClick:()=>{let e,r,l;return T(a),e=M(a?.ollamaPorts||[11434]),r=new Map((Array.isArray(a?.instances)?a.instances:[]).map(e=>[Number(e.port),e])),l=e.map(e=>{let a=r.get(Number(e))||{};return h(e,a)}),void(_({...j(),...a,ollamaPorts:(a.ollamaPorts||l.map(e=>e.port)||[11434]).join(","),useGlobalModelMemory:!1!==a.useGlobalModelMemory,instances:l}),O(!0))},children:"Edit"}),(0,l.jsx)(s.$n,{size:"sm",variant:"ghost",icon:"delete",onClick:()=>{el({title:"Delete Ollama Node",message:`Delete node "${a.name}"?`,onConfirm:async()=>{el(null),(await fetch(`/api/ollama-nodes/${a.id}`,{method:"DELETE"})).ok?(await ed(),e.success("Node deleted")):e.error("Delete failed")}})},children:"Delete"})]})]}),(0,l.jsxs)("div",{className:"mt-4 grid gap-4 md:grid-cols-2",children:[(0,l.jsxs)("div",{className:"rounded-xl border border-border p-4",children:[(0,l.jsx)("div",{className:"text-sm text-text-muted",children:"RAM"}),(0,l.jsxs)("div",{className:"mt-1 text-xl font-semibold text-text-main",children:[y(d.availableMb)," free"]}),(0,l.jsxs)("div",{className:"text-sm text-text-muted",children:["Total ",y(d.totalMb)," \xb7 Used ",d.usedPercent??"-","%"]})]}),(0,l.jsxs)("div",{className:"rounded-xl border border-border p-4",children:[(0,l.jsx)("div",{className:"text-sm text-text-muted",children:"GPU"}),n.length?n.map((e,a)=>(0,l.jsxs)("div",{className:"mt-2 flex flex-wrap items-center gap-2 text-sm",children:[(0,l.jsxs)("span",{className:"font-medium text-text-main",children:["GPU ",e.index??a," \xb7 ",e.name]}),(0,l.jsxs)(s.Ex,{children:["VRAM ",y(e.vramFreeMb)," / ",y(e.vramTotalMb)," free"]}),(0,l.jsxs)(s.Ex,{children:["GPU ",e.gpuUsagePercent,"%"]}),(0,l.jsxs)(s.Ex,{variant:Number(e.temperatureC)>=80?"error":"success",children:[e.temperatureC,"\xb0C"]})]},`${e.name}-${a}`)):(0,l.jsx)("div",{className:"mt-2 text-sm text-text-muted",children:"No NVIDIA GPU detected"})]})]}),(0,l.jsx)("div",{className:"mt-4 space-y-3",children:(t.instances||[]).map(e=>(0,l.jsxs)("div",{className:"rounded-xl border border-border p-4",children:[(0,l.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,l.jsxs)("h3",{className:"font-semibold text-text-main",children:["Ollama :",e.port||"default"]}),(0,l.jsx)(s.Ex,{variant:e.alive?"success":"error",children:e.alive?"alive":"down"}),(0,l.jsx)("span",{className:"text-xs text-text-muted",children:e.baseUrl}),(0,l.jsxs)(s.Ex,{children:["VRAM scope ",y(e.hardwareScope?.vramFreeMb)," free"]}),e.hardwareScope?.gpuIndices?.length?(0,l.jsxs)(s.Ex,{children:["GPU ",e.hardwareScope.gpuIndices.join(",")]}):null]}),e.modelReadiness?.length?(0,l.jsx)("div",{className:"mt-3 grid gap-2 md:grid-cols-2 xl:grid-cols-3",children:e.modelReadiness.map(e=>{var a;return(0,l.jsxs)("div",{className:"rounded-lg bg-surface-2 p-3 text-sm",children:[(0,l.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,l.jsx)("span",{className:"font-mono text-xs text-text-main",children:e.model}),(0,l.jsx)(s.Ex,{variant:e.loaded?"success":"default",children:e.loaded?"loaded":"sleeping"}),(0,l.jsx)(s.Ex,{variant:(a=e.status)?a.includes("insufficient")||a.includes("low")?"error":a.includes("unconfigured")?"warning":"success":"default",children:e.status}),(0,l.jsx)(s.Ex,{variant:e.ruleSource?.includes("instance")?"warning":e.ruleSource?.includes("global")?"success":"default",children:e.ruleSource||"none"})]}),(0,l.jsx)("p",{className:"mt-1 text-xs text-text-muted",children:e.reason})]},e.model)})}):(0,l.jsx)("div",{className:"mt-3 text-sm text-text-muted",children:"No models reported for this instance."})]},e.id||e.port||e.baseUrl))})]},a.id)})}),(0,l.jsx)(s.aF,{isOpen:q,onClose:()=>O(!1),title:U?"Edit Ollama Node":"Add Ollama Node",size:"full",className:"w-[calc(100vw-32px)] max-w-none xl:w-[96vw]",footer:(0,l.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,l.jsx)(s.$n,{onClick:ex,loading:Z,children:Z?"Saving...":"Save"}),(0,l.jsx)(s.$n,{variant:"ghost",onClick:()=>O(!1),disabled:Z,children:"Cancel"})]}),children:(0,l.jsxs)("div",{className:"max-h-[75vh] space-y-5 overflow-y-auto pr-2",children:[(0,l.jsxs)("div",{className:"grid gap-3 md:grid-cols-3",children:[(0,l.jsx)(s.pd,{label:"Name",value:H.name,onChange:e=>_(a=>({...a,name:e.target.value})),placeholder:"A2 node"}),(0,l.jsx)(s.pd,{label:"Host/IP",value:H.host,onChange:e=>_(a=>({...a,host:e.target.value})),placeholder:"192.168.1.10"}),(0,l.jsx)(s.pd,{label:"SSH User",value:H.sshUser,onChange:e=>_(a=>({...a,sshUser:e.target.value})),placeholder:"root or ubuntu"}),(0,l.jsx)(s.pd,{label:"SSH Port",value:H.sshPort,onChange:e=>_(a=>({...a,sshPort:e.target.value})),placeholder:"22"}),(0,l.jsx)(s.pd,{label:"Agent Port",value:H.agentPort,onChange:e=>_(a=>({...a,agentPort:e.target.value})),placeholder:"19999"}),(0,l.jsx)(s.pd,{label:"Agent Token",value:H.agentToken,onChange:e=>_(a=>({...a,agentToken:e.target.value})),placeholder:"auto if empty"}),(0,l.jsx)(s.pd,{label:"Ollama Ports",value:H.ollamaPorts,onChange:e=>{var a;return a=e.target.value,void _(e=>({...e,ollamaPorts:a,instances:function(e=[],a="11434"){let r=M(a),l=new Map((e||[]).map(e=>[Number(e.port),e]));return r.map(e=>h(e,l.get(Number(e))||{}))}(e.instances||[],a)}))},placeholder:"11434,11435"}),(0,l.jsx)(s.pd,{label:"Refresh Interval MS",value:H.refreshIntervalMs,onChange:e=>_(a=>({...a,refreshIntervalMs:e.target.value})),placeholder:"15000"}),(0,l.jsx)(s.pd,{label:"UFW Allow From",value:H.ufwAllowFrom,onChange:e=>_(a=>({...a,ufwAllowFrom:e.target.value})),placeholder:"192.168.1.0/24"})]}),(0,l.jsxs)("div",{className:"grid gap-3 md:grid-cols-2",children:[(0,l.jsx)("div",{className:"rounded-xl border border-border p-4",children:(0,l.jsxs)("div",{className:"flex items-center justify-between gap-3",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h3",{className:"font-semibold text-text-main",children:"Use sudo"}),(0,l.jsx)("p",{className:"text-sm text-text-muted",children:"Enable when SSH user is not root but has sudo rights."})]}),(0,l.jsx)(s.lM,{checked:!!H.useSudo,onChange:()=>_(e=>({...e,useSudo:!e.useSudo}))})]})}),(0,l.jsx)("div",{className:"rounded-xl border border-border p-4",children:(0,l.jsxs)("div",{className:"flex items-center justify-between gap-3",children:[(0,l.jsxs)("div",{children:[(0,l.jsx)("h3",{className:"font-semibold text-text-main",children:"Use Global Model Memory Map"}),(0,l.jsx)("p",{className:"text-sm text-text-muted",children:"Global rules are fallback values. Per-instance overrides can still override them."})]}),(0,l.jsx)(s.lM,{checked:!1!==H.useGlobalModelMemory,onChange:()=>_(e=>({...e,useGlobalModelMemory:!1===e.useGlobalModelMemory}))})]})})]}),(0,l.jsxs)("div",{className:"rounded-xl border border-border p-4",children:[(0,l.jsxs)("div",{className:"mb-3",children:[(0,l.jsx)("h3",{className:"font-semibold text-text-main",children:"Per-instance Ollama Config"}),(0,l.jsx)("p",{className:"text-sm text-text-muted",children:"Each Ollama port is a separate routing target. Configure GPU binding and overrides per instance, not per physical machine."})]}),(0,l.jsx)("div",{className:"space-y-4",children:(H.instances||[]).map(e=>{var a;let r,t,n=p(e.port,e.id),d=U?N(U,e):null,c=U?(r=U?.lastEvaluation?.instances||[],t=Number(e?.port),r.find(e=>Number(e.port)===t)||null):null,x=v(e,w(d)),M=U?.lastStatus?.hardware?.gpus||[];return(0,l.jsxs)("div",{className:"rounded-2xl border border-border bg-surface-1 p-4",children:[(0,l.jsxs)("div",{className:"mb-3 flex flex-wrap items-center justify-between gap-3",children:[(0,l.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,l.jsx)("h4",{className:"font-semibold text-text-main",children:e.name||`Ollama :${e.port}`}),(0,l.jsx)(s.Ex,{variant:!1!==e.enabled?"success":"default",children:!1!==e.enabled?"enabled":"disabled"}),d?(0,l.jsx)(s.Ex,{variant:d.alive?"success":"error",children:d.alive?"alive":"down"}):null,(0,l.jsx)(k,{instance:e}),c?.hardwareScope?(0,l.jsxs)(s.Ex,{children:["Effective VRAM ",y(c.hardwareScope.vramFreeMb)," free"]}):null]}),(0,l.jsx)(s.lM,{checked:!1!==e.enabled,onChange:()=>ec(n,{enabled:!1===e.enabled})})]}),(0,l.jsxs)("div",{className:"mb-3 grid gap-3 md:grid-cols-4",children:[(0,l.jsx)(s.pd,{label:"Instance Name",value:e.name||"",onChange:e=>ec(n,{name:e.target.value}),placeholder:`Ollama :${e.port}`}),(0,l.jsx)(s.pd,{label:"Port",value:e.port,onChange:a=>ec(n,{port:Number(a.target.value)||e.port}),placeholder:"11434"}),(0,l.jsxs)("label",{className:"block",children:[(0,l.jsx)("div",{className:"mb-1 text-sm font-medium text-text-main",children:"GPU Mode"}),(0,l.jsxs)("select",{value:e.gpuMode||"auto",onChange:e=>ec(n,{gpuMode:e.target.value}),className:"w-full rounded-lg border border-border bg-background px-3 py-2 text-sm outline-none focus:border-primary",children:[(0,l.jsx)("option",{value:"auto",children:"Auto / best available GPU"}),(0,l.jsx)("option",{value:"cpu",children:"CPU only"}),(0,l.jsx)("option",{value:"specific",children:"Specific GPU index"}),(0,l.jsx)("option",{value:"all",children:"All GPUs"})]})]}),(0,l.jsx)(s.pd,{label:"GPU Indices",value:Array.isArray(a=e.gpuIndices)?a.join(","):String(a||""),onChange:e=>ec(n,{gpuIndices:e.target.value}),placeholder:M.length?M.map((e,a)=>e.index??a).join(","):"0,1"})]}),(0,l.jsxs)("div",{className:"mb-3 flex flex-wrap items-center gap-3",children:[(0,l.jsxs)("label",{className:"flex items-center gap-2 text-sm text-text-muted",children:[(0,l.jsx)(s.lM,{checked:!0===e.allowMultiGpuSplit,onChange:()=>ec(n,{allowMultiGpuSplit:!0!==e.allowMultiGpuSplit})}),"Allow multi-GPU split / aggregate VRAM"]}),(0,l.jsx)("span",{className:"text-xs text-text-muted",children:"Auto/specific normally uses the best single GPU. Enable split only if this Ollama instance can actually split model layers across GPUs."})]}),(0,l.jsxs)("div",{className:"mb-2 flex flex-wrap items-center justify-between gap-2",children:[(0,l.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,l.jsx)(s.Ex,{variant:"warning",children:"instance overrides"}),(0,l.jsx)(s.Ex,{variant:!1===H.useGlobalModelMemory?"warning":"success",children:!1===H.useGlobalModelMemory?"global disabled":"global fallback on"}),(0,l.jsxs)("span",{className:"text-xs text-text-muted",children:["Models shown here belong to port ",e.port," only."]})]}),(0,l.jsxs)("div",{className:"flex gap-2",children:[(0,l.jsx)(s.$n,{size:"sm",variant:"secondary",icon:"add",onClick:()=>{em(e=>e.map(e=>{if(p(e.port,e.id)!==n)return e;let a=v(e,U?w(N(U,e)):[]);return a.push({...b,overrideEnabled:!0}),{...e,modelMemoryRequirements:f(a)}}))},children:"Add Override"}),(0,l.jsx)(s.$n,{size:"sm",variant:"secondary",icon:"cleaning_services",onClick:()=>{em(e=>e.map(e=>p(e.port,e.id)===n?{...e,modelMemoryRequirements:{}}:e))},children:"Clear"})]})]}),(0,l.jsx)("div",{className:"overflow-x-auto rounded-xl border border-border",children:(0,l.jsxs)("table",{className:"w-full min-w-[1320px] text-left text-sm",children:[(0,l.jsx)("thead",{className:"bg-surface-2 text-xs uppercase text-text-muted",children:(0,l.jsxs)("tr",{children:[(0,l.jsx)("th",{className:"px-3 py-2",children:"Model / Pattern"}),(0,l.jsx)("th",{className:"px-3 py-2",children:"Override"}),(0,l.jsx)("th",{className:"px-3 py-2",children:"Source"}),o.map(e=>(0,l.jsxs)("th",{className:"px-3 py-2",children:[(0,l.jsx)("div",{children:i[e]}),(0,l.jsx)("div",{className:"normal-case text-[11px]",children:m[e]})]},e)),(0,l.jsx)("th",{className:"px-3 py-2 text-right",children:"Action"})]})}),(0,l.jsxs)("tbody",{children:[x.map((e,a)=>{let r=!1===H.useGlobalModelMemory?null:function(e=[],a){let r=String(a||"").trim();if(!r)return null;let l=e.find(e=>String(e.model||"")===r);if(l)return{row:l,key:l.model,matchType:"exact"};let t=r.toLowerCase(),s=e.find(e=>String(e.model||"").toLowerCase()===t);if(s)return{row:s,key:s.model,matchType:"case-insensitive"};let n=e.find(e=>{let a;return String(e.model||"").includes("*")&&(a=String(e.model||"").split("*").map(e=>e.replace(/[|\\{}()[\]^$+?.]/g,"\\$&")).join(".*"),RegExp(`^${a}$`,"i")).test(r)});return n?{row:n,key:n.model,matchType:"wildcard"}:null}(u,e.model),t=r?.row||null,d=!0!==e.overrideEnabled;return(0,l.jsxs)("tr",{className:"border-t border-border",children:[(0,l.jsxs)("td",{className:"px-3 py-2 align-top",children:[(0,l.jsx)("input",{value:e.model,onChange:e=>eb(n,a,"model",e.target.value),placeholder:"qwen3:8b",className:"w-full rounded-md border border-border bg-background px-2 py-1.5 font-mono text-xs outline-none focus:border-primary"}),r?.matchType==="wildcard"?(0,l.jsxs)(R,{children:["Matched global pattern: ",r.key]}):null]}),(0,l.jsx)("td",{className:"px-3 py-2 align-top",children:(0,l.jsx)(s.lM,{checked:!0===e.overrideEnabled,onChange:()=>eb(n,a,"overrideEnabled",!0!==e.overrideEnabled)})}),(0,l.jsx)("td",{className:"px-3 py-2 align-top",children:(0,l.jsx)(S,{row:e,globalRule:t,useGlobal:!1!==H.useGlobalModelMemory})}),o.map(r=>(0,l.jsx)("td",{className:"px-3 py-2 align-top",children:(0,l.jsx)(V,{value:e[r]??"",disabled:d,globalValue:t?.[r],globalEnabled:!1!==H.useGlobalModelMemory,onChange:e=>eb(n,a,r,e)})},r)),(0,l.jsx)("td",{className:"px-3 py-2 text-right align-top",children:(0,l.jsx)("button",{type:"button",onClick:()=>{em(e=>e.map(e=>{if(p(e.port,e.id)!==n)return e;let r=v(e,U?w(N(U,e)):[]).filter((e,r)=>r!==a);return{...e,modelMemoryRequirements:f(r)}}))},className:"rounded-md px-2 py-1 text-red-500 hover:bg-red-500/10",title:"Remove row",children:(0,l.jsx)("span",{className:"material-icons text-base",children:"delete"})})})]},`${e.model}-${a}`)}),0===x.length?(0,l.jsx)("tr",{children:(0,l.jsx)("td",{colSpan:9,className:"px-3 py-6 text-center text-sm text-text-muted",children:"No models detected for this instance yet. Refresh status or add an override manually."})}):null]})]})})]},n)})})]})]})}),(0,l.jsx)(s.aF,{isOpen:B,onClose:()=>I(!1),title:`Install agent: ${L?.name||""}`,children:(0,l.jsxs)("div",{className:"space-y-4",children:[(0,l.jsx)("div",{className:"rounded-xl border border-amber-300 bg-amber-50 p-3 text-sm text-amber-800",children:"Passwords are used only for this install request and are not stored. The server running BlueRouter needs ssh or sshpass installed for password-based SSH."}),(0,l.jsx)(s.pd,{label:"SSH Password",value:z,onChange:e=>Q(e.target.value),type:"password",placeholder:"leave empty for SSH key"}),L?.useSudo?(0,l.jsx)(s.pd,{label:"Sudo Password",value:W,onChange:e=>J(e.target.value),type:"password",placeholder:"leave empty to reuse SSH password or passwordless sudo"}):null,(0,l.jsxs)("div",{className:"flex gap-2",children:[(0,l.jsx)(s.$n,{onClick:eM,disabled:X===L?.id,children:X===L?.id?"Installing...":"Install / Update Agent"}),(0,l.jsx)(s.$n,{variant:"ghost",onClick:()=>I(!1),disabled:X===L?.id,children:"Close"})]}),ee?(0,l.jsx)("pre",{className:"max-h-64 overflow-auto rounded-xl bg-surface-2 p-3 text-xs text-text-main",children:ee}):null]})}),(0,l.jsx)(s.uo,{isOpen:!!er,onClose:()=>el(null),onConfirm:er?.onConfirm,title:er?.title||"Confirm",message:er?.message,variant:"danger"})]})}}},e=>{e.O(0,[2574,3862,1051,1321,5497,8441,3794,7358],()=>e(e.s=72546)),_N_E=e.O()}]);