zevairouter 1.0.131 → 1.0.133

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 (337) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/cli/app/.next-cli-build/BUILD_ID +1 -1
  3. package/cli/app/.next-cli-build/app-path-routes-manifest.json +8 -8
  4. package/cli/app/.next-cli-build/build-manifest.json +2 -2
  5. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/automation/page_client-reference-manifest.js +1 -1
  6. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
  7. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
  8. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  9. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  10. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
  11. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/context/page_client-reference-manifest.js +1 -1
  12. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  13. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
  14. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
  15. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
  16. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
  17. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
  18. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  19. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/playground/page_client-reference-manifest.js +1 -1
  20. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page.js +1 -1
  21. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  22. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  23. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  24. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  25. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
  26. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
  27. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
  28. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/terminal/page_client-reference-manifest.js +1 -1
  29. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
  30. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  31. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  32. package/cli/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
  33. package/cli/app/.next-cli-build/server/app/_global-error.html +1 -1
  34. package/cli/app/.next-cli-build/server/app/_global-error.rsc +1 -1
  35. package/cli/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
  36. package/cli/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  37. package/cli/app/.next-cli-build/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  38. package/cli/app/.next-cli-build/server/app/_global-error.segments/_head.segment.rsc +1 -1
  39. package/cli/app/.next-cli-build/server/app/_global-error.segments/_index.segment.rsc +1 -1
  40. package/cli/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  41. package/cli/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
  42. package/cli/app/.next-cli-build/server/app/_not-found.html +1 -1
  43. package/cli/app/.next-cli-build/server/app/_not-found.rsc +3 -3
  44. package/cli/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +3 -3
  45. package/cli/app/.next-cli-build/server/app/_not-found.segments/_head.segment.rsc +1 -1
  46. package/cli/app/.next-cli-build/server/app/_not-found.segments/_index.segment.rsc +3 -3
  47. package/cli/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  48. package/cli/app/.next-cli-build/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  49. package/cli/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  50. package/cli/app/.next-cli-build/server/app/api/models/route.js +1 -1
  51. package/cli/app/.next-cli-build/server/app/api/oauth/cloudflare-ai/bulk-import/[jobId]/cancel/route.js +1 -1
  52. package/cli/app/.next-cli-build/server/app/api/oauth/cloudflare-ai/bulk-import/[jobId]/manual/[workerId]/route.js +1 -1
  53. package/cli/app/.next-cli-build/server/app/api/oauth/cloudflare-ai/bulk-import/[jobId]/route.js +1 -1
  54. package/cli/app/.next-cli-build/server/app/api/oauth/cloudflare-ai/bulk-import/latest/route.js +1 -1
  55. package/cli/app/.next-cli-build/server/app/api/oauth/cloudflare-ai/bulk-import/route.js +1 -1
  56. package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/[jobId]/cancel/route.js +1 -1
  57. package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/[jobId]/manual/[workerId]/route.js +1 -1
  58. package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/[jobId]/route.js +1 -1
  59. package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/latest/route.js +1 -1
  60. package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/route.js +1 -1
  61. package/cli/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js +1 -1
  62. package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/[jobId]/cancel/route.js +1 -1
  63. package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/[jobId]/manual/[workerId]/route.js +1 -1
  64. package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/[jobId]/route.js +1 -1
  65. package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/latest/route.js +1 -1
  66. package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/route.js +1 -1
  67. package/cli/app/.next-cli-build/server/app/api/providers/route.js +1 -1
  68. package/cli/app/.next-cli-build/server/app/api/providers/validate/route.js +1 -1
  69. package/cli/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
  70. package/cli/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
  71. package/cli/app/.next-cli-build/server/app/api/version/route.js +1 -1
  72. package/cli/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
  73. package/cli/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
  74. package/cli/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
  75. package/cli/app/.next-cli-build/server/app/callback.html +1 -1
  76. package/cli/app/.next-cli-build/server/app/callback.rsc +3 -3
  77. package/cli/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +3 -3
  78. package/cli/app/.next-cli-build/server/app/callback.segments/_head.segment.rsc +1 -1
  79. package/cli/app/.next-cli-build/server/app/callback.segments/_index.segment.rsc +3 -3
  80. package/cli/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +1 -1
  81. package/cli/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
  82. package/cli/app/.next-cli-build/server/app/callback.segments/callback.segment.rsc +1 -1
  83. package/cli/app/.next-cli-build/server/app/dashboard/automation.html +1 -1
  84. package/cli/app/.next-cli-build/server/app/dashboard/automation.rsc +5 -5
  85. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard/automation/__PAGE__.segment.rsc +2 -2
  86. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard/automation.segment.rsc +1 -1
  87. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  88. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  89. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_full.segment.rsc +5 -5
  90. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_head.segment.rsc +1 -1
  91. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_index.segment.rsc +3 -3
  92. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_tree.segment.rsc +1 -1
  93. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
  94. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +5 -5
  95. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +2 -2
  96. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat.segment.rsc +1 -1
  97. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  98. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  99. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +5 -5
  100. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_head.segment.rsc +1 -1
  101. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_index.segment.rsc +3 -3
  102. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +1 -1
  103. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
  104. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +5 -5
  105. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
  106. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
  107. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  108. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  109. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +5 -5
  110. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
  111. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_index.segment.rsc +3 -3
  112. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +1 -1
  113. package/cli/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
  114. package/cli/app/.next-cli-build/server/app/dashboard/combos.rsc +5 -5
  115. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
  116. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
  117. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  118. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  119. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +5 -5
  120. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
  121. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_index.segment.rsc +3 -3
  122. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +1 -1
  123. package/cli/app/.next-cli-build/server/app/dashboard/context.html +1 -1
  124. package/cli/app/.next-cli-build/server/app/dashboard/context.rsc +5 -5
  125. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard/context/__PAGE__.segment.rsc +2 -2
  126. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard/context.segment.rsc +1 -1
  127. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  128. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  129. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_full.segment.rsc +5 -5
  130. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_head.segment.rsc +1 -1
  131. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_index.segment.rsc +3 -3
  132. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_tree.segment.rsc +1 -1
  133. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
  134. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.rsc +5 -5
  135. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +2 -2
  136. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
  137. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  138. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  139. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +5 -5
  140. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
  141. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_index.segment.rsc +3 -3
  142. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +1 -1
  143. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
  144. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +5 -5
  145. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +2 -2
  146. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web.segment.rsc +1 -1
  147. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers.segment.rsc +1 -1
  148. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  149. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  150. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +5 -5
  151. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_head.segment.rsc +1 -1
  152. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_index.segment.rsc +3 -3
  153. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +1 -1
  154. package/cli/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
  155. package/cli/app/.next-cli-build/server/app/dashboard/mitm.rsc +5 -5
  156. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +2 -2
  157. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm.segment.rsc +1 -1
  158. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  159. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  160. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +5 -5
  161. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_head.segment.rsc +1 -1
  162. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_index.segment.rsc +3 -3
  163. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +1 -1
  164. package/cli/app/.next-cli-build/server/app/dashboard/playground.html +1 -1
  165. package/cli/app/.next-cli-build/server/app/dashboard/playground.rsc +5 -5
  166. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard/playground/__PAGE__.segment.rsc +2 -2
  167. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard/playground.segment.rsc +1 -1
  168. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  169. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  170. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_full.segment.rsc +5 -5
  171. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_head.segment.rsc +1 -1
  172. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_index.segment.rsc +3 -3
  173. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_tree.segment.rsc +1 -1
  174. package/cli/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
  175. package/cli/app/.next-cli-build/server/app/dashboard/profile.rsc +5 -5
  176. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +2 -2
  177. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
  178. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  179. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  180. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +5 -5
  181. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
  182. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_index.segment.rsc +3 -3
  183. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +1 -1
  184. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
  185. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.rsc +5 -5
  186. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
  187. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
  188. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  189. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  190. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  191. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +5 -5
  192. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
  193. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_index.segment.rsc +3 -3
  194. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +1 -1
  195. package/cli/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
  196. package/cli/app/.next-cli-build/server/app/dashboard/providers.rsc +5 -5
  197. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
  198. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  199. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  200. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  201. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +5 -5
  202. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
  203. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_index.segment.rsc +3 -3
  204. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +1 -1
  205. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
  206. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +5 -5
  207. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +2 -2
  208. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools.segment.rsc +1 -1
  209. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  210. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  211. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +5 -5
  212. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_head.segment.rsc +1 -1
  213. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_index.segment.rsc +3 -3
  214. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +1 -1
  215. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.html +1 -1
  216. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.rsc +5 -5
  217. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe/__PAGE__.segment.rsc +2 -2
  218. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe.segment.rsc +1 -1
  219. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  220. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  221. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_full.segment.rsc +5 -5
  222. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_head.segment.rsc +1 -1
  223. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_index.segment.rsc +3 -3
  224. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_tree.segment.rsc +1 -1
  225. package/cli/app/.next-cli-build/server/app/dashboard/quota.html +2 -2
  226. package/cli/app/.next-cli-build/server/app/dashboard/quota.rsc +6 -6
  227. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +3 -3
  228. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota.segment.rsc +1 -1
  229. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  230. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  231. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +6 -6
  232. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_head.segment.rsc +1 -1
  233. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_index.segment.rsc +3 -3
  234. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +1 -1
  235. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  236. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
  237. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +3 -3
  238. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +3 -3
  239. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
  240. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +3 -3
  241. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +1 -1
  242. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
  243. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
  244. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
  245. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
  246. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.html +1 -1
  247. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.rsc +5 -5
  248. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +2 -2
  249. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver.segment.rsc +1 -1
  250. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  251. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  252. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_full.segment.rsc +5 -5
  253. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_head.segment.rsc +1 -1
  254. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_index.segment.rsc +3 -3
  255. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_tree.segment.rsc +1 -1
  256. package/cli/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
  257. package/cli/app/.next-cli-build/server/app/dashboard/translator.rsc +5 -5
  258. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
  259. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
  260. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  261. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  262. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +5 -5
  263. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
  264. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_index.segment.rsc +3 -3
  265. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +1 -1
  266. package/cli/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
  267. package/cli/app/.next-cli-build/server/app/dashboard/usage.rsc +5 -5
  268. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
  269. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
  270. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  271. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  272. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +5 -5
  273. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
  274. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_index.segment.rsc +3 -3
  275. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +1 -1
  276. package/cli/app/.next-cli-build/server/app/dashboard.html +1 -1
  277. package/cli/app/.next-cli-build/server/app/dashboard.rsc +5 -5
  278. package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
  279. package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  280. package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  281. package/cli/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +5 -5
  282. package/cli/app/.next-cli-build/server/app/dashboard.segments/_head.segment.rsc +1 -1
  283. package/cli/app/.next-cli-build/server/app/dashboard.segments/_index.segment.rsc +3 -3
  284. package/cli/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +1 -1
  285. package/cli/app/.next-cli-build/server/app/index.html +1 -1
  286. package/cli/app/.next-cli-build/server/app/index.rsc +3 -3
  287. package/cli/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  288. package/cli/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +3 -3
  289. package/cli/app/.next-cli-build/server/app/index.segments/_head.segment.rsc +1 -1
  290. package/cli/app/.next-cli-build/server/app/index.segments/_index.segment.rsc +3 -3
  291. package/cli/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +1 -1
  292. package/cli/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
  293. package/cli/app/.next-cli-build/server/app/landing.html +1 -1
  294. package/cli/app/.next-cli-build/server/app/landing.rsc +3 -3
  295. package/cli/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +3 -3
  296. package/cli/app/.next-cli-build/server/app/landing.segments/_head.segment.rsc +1 -1
  297. package/cli/app/.next-cli-build/server/app/landing.segments/_index.segment.rsc +3 -3
  298. package/cli/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +1 -1
  299. package/cli/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +1 -1
  300. package/cli/app/.next-cli-build/server/app/landing.segments/landing.segment.rsc +1 -1
  301. package/cli/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
  302. package/cli/app/.next-cli-build/server/app/login.html +1 -1
  303. package/cli/app/.next-cli-build/server/app/login.rsc +4 -4
  304. package/cli/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +4 -4
  305. package/cli/app/.next-cli-build/server/app/login.segments/_head.segment.rsc +1 -1
  306. package/cli/app/.next-cli-build/server/app/login.segments/_index.segment.rsc +3 -3
  307. package/cli/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +1 -1
  308. package/cli/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
  309. package/cli/app/.next-cli-build/server/app/login.segments/login.segment.rsc +1 -1
  310. package/cli/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
  311. package/cli/app/.next-cli-build/server/app-paths-manifest.json +8 -8
  312. package/cli/app/.next-cli-build/server/chunks/3155.js +1 -1
  313. package/cli/app/.next-cli-build/server/chunks/4746.js +1 -1
  314. package/cli/app/.next-cli-build/server/chunks/5307.js +1 -1
  315. package/cli/app/.next-cli-build/server/chunks/5949.js +28 -3
  316. package/cli/app/.next-cli-build/server/chunks/601.js +2 -2
  317. package/cli/app/.next-cli-build/server/chunks/6269.js +1 -1
  318. package/cli/app/.next-cli-build/server/chunks/8157.js +1 -1
  319. package/cli/app/.next-cli-build/server/chunks/8306.js +1 -1
  320. package/cli/app/.next-cli-build/server/chunks/8371.js +1 -1
  321. package/cli/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
  322. package/cli/app/.next-cli-build/server/pages/404.html +1 -1
  323. package/cli/app/.next-cli-build/server/pages/500.html +1 -1
  324. package/cli/app/.next-cli-build/static/chunks/{85-1fbc9677e7128a92.js → 85-b496e2f905629179.js} +1 -1
  325. package/cli/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/profile/page-3daabb58a77d3b0d.js +1 -0
  326. package/cli/app/CHANGELOG.md +5 -0
  327. package/cli/app/package.json +1 -1
  328. package/cli/package.json +1 -1
  329. package/package.json +1 -1
  330. package/src/app/(dashboard)/dashboard/profile/page.js +10 -2
  331. package/src/lib/db/index.js +16 -1
  332. package/src/lib/oauth/services/bulkImportBrowserEngine.js +105 -3
  333. package/src/lib/oauth/services/codebuddyCnBulkImportManager.js +6 -0
  334. package/src/lib/oauth/services/kiroBulkImportManager.js +32 -0
  335. package/cli/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/profile/page-e95034d5b34bc360.js +0 -1
  336. /package/cli/app/.next-cli-build/static/{IZKVv4XNKaho0UIkGWpE8 → UnNGaGzVlBj-k5XHKskcV}/_buildManifest.js +0 -0
  337. /package/cli/app/.next-cli-build/static/{IZKVv4XNKaho0UIkGWpE8 → UnNGaGzVlBj-k5XHKskcV}/_ssgManifest.js +0 -0
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3471],{52424:(e,t,s)=>{Promise.resolve().then(s.bind(s,64561))},64561:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>p});var a=s(95155),r=s(12115),o=s(73321),l=s(35497),i=s(81127),n=s(21931),d=s(1620),c=s(31474),m=s(90620),x=s(93308),u=s(38202);function p(){let e=(0,o.useRouter)(),{theme:t,setTheme:s,isDark:p}=(0,d.D)(),[h,b]=(0,r.useState)("en"),[g,y]=(0,r.useState)(!1),[f,j]=(0,r.useState)(!1),[N,w]=(0,r.useState)(!1),[v,C]=(0,r.useState)({fallbackStrategy:"fill-first"}),[k,S]=(0,r.useState)(!0),[P,O]=(0,r.useState)({current:"",new:"",confirm:""}),[I,L]=(0,r.useState)({type:"",message:""}),[T,R]=(0,r.useState)(!1),[D,U]=(0,r.useState)(!1),[M,A]=(0,r.useState)({type:"",message:""}),[E,$]=(0,r.useState)({authMode:"password",oidcIssuerUrl:"",oidcClientId:"",oidcScopes:"openid profile email",oidcLoginLabel:"Sign in with OIDC"}),[q,F]=(0,r.useState)(""),[J,H]=(0,r.useState)({type:"",message:""}),[_,W]=(0,r.useState)(!1),[z,B]=(0,r.useState)(!1),[Z,K]=(0,r.useState)({type:"",message:""}),[Q,V]=(0,r.useState)("/api/auth/oidc/callback"),[G,Y]=(0,r.useState)(!1),X=(0,r.useRef)(null),[ee,et]=(0,r.useState)({outboundProxyEnabled:!1,outboundProxyUrl:"",outboundNoProxy:""}),[es,ea]=(0,r.useState)({type:"",message:""}),[er,eo]=(0,r.useState)(!1),[el,ei]=(0,r.useState)(!1);(0,r.useEffect)(()=>{b(function(){if("u"<typeof document)return"en";let e=document.cookie.split(";").find(e=>e.trim().startsWith(`${x.CL}=`)),t=e?decodeURIComponent(e.split("=")[1]):"en";return(0,x.QC)(t)}())},[g]),(0,r.useEffect)(()=>{fetch("/api/settings").then(e=>e.json()).then(e=>{C(e),$({authMode:e?.authMode||"password",oidcIssuerUrl:e?.oidcIssuerUrl||"",oidcClientId:e?.oidcClientId||"",oidcScopes:e?.oidcScopes||"openid profile email",oidcLoginLabel:e?.oidcLoginLabel||"Sign in with OIDC"}),F(""),(e?.authMode==="oidc"||e?.authMode==="both")&&Y(!0),et({outboundProxyEnabled:e?.outboundProxyEnabled===!0,outboundProxyUrl:e?.outboundProxyUrl||"",outboundNoProxy:e?.outboundNoProxy||""}),S(!1)}).catch(e=>{console.error("Failed to fetch settings:",e),S(!1)})},[]),(0,r.useEffect)(()=>{V(`${window.location.origin}/api/auth/oidc/callback`)},[]);let en=async e=>{if(e.preventDefault(),!0===v.outboundProxyEnabled){eo(!0),ea({type:"",message:""});try{let e=await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({outboundProxyUrl:ee.outboundProxyUrl,outboundNoProxy:ee.outboundNoProxy})}),t=await e.json();e.ok?(C(e=>({...e,...t})),ea({type:"success",message:"Proxy settings applied"})):ea({type:"error",message:t.error||"Failed to update proxy settings"})}catch(e){ea({type:"error",message:"An error occurred"})}finally{eo(!1)}}},ed=async()=>{if(!0!==v.outboundProxyEnabled)return;let e=(ee.outboundProxyUrl||"").trim();if(!e)return void ea({type:"error",message:"Please enter a Proxy URL to test"});ei(!0),ea({type:"",message:""});try{let t=await fetch("/api/settings/proxy-test",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({proxyUrl:e})}),s=await t.json();t.ok&&s?.ok?ea({type:"success",message:`Proxy test OK (${s.status}) in ${s.elapsedMs}ms`}):ea({type:"error",message:s?.error||"Proxy test failed"})}catch(e){ea({type:"error",message:"An error occurred"})}finally{ei(!1)}},ec=async e=>{eo(!0),ea({type:"",message:""});try{let t=await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({outboundProxyEnabled:e})}),s=await t.json();t.ok?(C(e=>({...e,...s})),et(e=>({...e,outboundProxyEnabled:s?.outboundProxyEnabled===!0})),ea({type:"success",message:e?"Proxy enabled":"Proxy disabled"})):ea({type:"error",message:s.error||"Failed to update proxy settings"})}catch(e){ea({type:"error",message:"An error occurred"})}finally{eo(!1)}},em=async e=>{if(e.preventDefault(),P.new!==P.confirm)return void L({type:"error",message:"Passwords do not match"});R(!0),L({type:"",message:""});try{let e=await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({currentPassword:P.current,newPassword:P.new})}),t=await e.json();e.ok?(L({type:"success",message:"Password updated successfully"}),O({current:"",new:"",confirm:""})):L({type:"error",message:t.error||"Failed to update password"})}catch(e){L({type:"error",message:"An error occurred"})}finally{R(!1)}},ex=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({fallbackStrategy:e})})).ok&&C(t=>({...t,fallbackStrategy:e}))}catch(e){console.error("Failed to update settings:",e)}},eu=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({responseCacheEnabled:e})})).ok&&C(t=>({...t,responseCacheEnabled:e}))}catch(e){console.error("Failed to update settings:",e)}},ep=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})).ok&&C(t=>({...t,...e}))}catch(e){console.error("Failed to update alert settings:",e)}},eh=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({comboStrategy:e})})).ok&&C(t=>({...t,comboStrategy:e}))}catch(e){console.error("Failed to update combo strategy:",e)}},eb=async e=>{let t=parseInt(e);if(!isNaN(t)&&!(t<1))try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({stickyRoundRobinLimit:t})})).ok&&C(e=>({...e,stickyRoundRobinLimit:t}))}catch(e){console.error("Failed to update sticky limit:",e)}},eg=async e=>{let t=parseInt(e);if(!isNaN(t)&&!(t<1))try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({comboStickyRoundRobinLimit:t})})).ok&&C(e=>({...e,comboStickyRoundRobinLimit:t}))}catch(e){console.error("Failed to update combo sticky limit:",e)}},ey=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({requireLogin:e})})).ok&&C(t=>({...t,requireLogin:e}))}catch(e){console.error("Failed to update require login:",e)}},ef=(e,t)=>{$(s=>({...s,[e]:t}))},ej=async(e=E.authMode||"password")=>{let t=E.oidcIssuerUrl.trim(),s=E.oidcClientId.trim(),a=E.oidcScopes.trim(),r=E.oidcLoginLabel.trim(),o=q.trim();if("password"!==e&&(!t||!s||!o)&&!v.oidcConfigured)return void H({type:"error",message:"Issuer URL, client ID, and client secret are required to enable OIDC."});W(!0),H({type:"",message:""}),K({type:"",message:""});try{let l={authMode:e,oidcIssuerUrl:t,oidcClientId:s,oidcScopes:a||"openid profile email",oidcLoginLabel:r||"Sign in with OIDC"};o&&(l.oidcClientSecret=o);let i=await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)}),n=await i.json();i.ok?(C(e=>({...e,...n})),$({authMode:n?.authMode||e,oidcIssuerUrl:n?.oidcIssuerUrl||t,oidcClientId:n?.oidcClientId||s,oidcScopes:n?.oidcScopes||a||"openid profile email",oidcLoginLabel:n?.oidcLoginLabel||r||"Sign in with OIDC"}),F(""),H({type:"success",message:"oidc"===e?"OIDC login enabled":"both"===e?"Password and OIDC login enabled":"OIDC settings saved"})):H({type:"error",message:n.error||"Failed to save OIDC settings"})}catch(e){H({type:"error",message:"An error occurred"})}finally{W(!1)}},eN=async()=>{let e=E.oidcIssuerUrl.trim(),t=E.oidcClientId.trim(),s=E.oidcScopes.trim(),a=q.trim();if(!e||!t)return void K({type:"error",message:"Issuer URL and client ID are required to test the connection."});B(!0),H({type:"",message:""}),K({type:"",message:""});try{let r=await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({authMode:E.authMode||v.authMode||"password",oidcIssuerUrl:e,oidcClientId:t,oidcScopes:s||"openid profile email",oidcLoginLabel:E.oidcLoginLabel.trim()||"Sign in with OIDC",...a?{oidcClientSecret:a}:{}})}),o=await r.json().catch(()=>({}));if(!r.ok)return void K({type:"error",message:o.error||"Failed to save OIDC settings before testing"});let l=await fetch("/api/auth/oidc/test",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({issuerUrl:o.oidcIssuerUrl||e,clientId:o.oidcClientId||t,scopes:o.oidcScopes||s||"openid profile email"})}),i=await l.json().catch(()=>({}));if(l.ok&&i?.ok){let e=i.clientSecretTested?!0===i.clientSecretValid?`Connection OK. Discovery loaded from ${i.issuerUrl}. Client secret validated too.`:`Connection OK. Discovery loaded from ${i.issuerUrl}. Client secret was not checked.`:`Connection OK. Discovery loaded from ${i.issuerUrl}.`;K({type:"success",message:e})}else K({type:"error",message:i.error||"OIDC connection test failed"})}catch(e){K({type:"error",message:"An error occurred"})}finally{B(!1)}},ew=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({enableObservability:e})})).ok&&C(t=>({...t,enableObservability:e}))}catch(e){console.error("Failed to update enableObservability:",e)}},ev=async()=>{try{let e=await fetch("/api/settings");if(!e.ok)return;let t=await e.json();C(t)}catch(e){console.error("Failed to reload settings:",e)}},eC=async()=>{U(!0),A({type:"",message:""});try{let e=await fetch("/api/settings/database");if(!e.ok){let t=await e.json().catch(()=>({}));throw Error(t.error||"Failed to export database")}let t=await e.json(),s=JSON.stringify(t),a=new Blob([s],{type:"application/json"}),r=URL.createObjectURL(a),o=document.createElement("a"),l=new Date().toISOString().replace(/[.:]/g,"-");o.href=r,o.download=`zevairouter-backup-${l}.json`,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(r);let i=(a.size/1048576).toFixed(2),n=Array.isArray(t?.excludedTables)&&t.excludedTables.length?` (config only — skipped ${t.excludedTables.join(", ")})`:"";A({type:"success",message:`Database backup downloaded (${i} MB)${n}`})}catch(e){A({type:"error",message:e.message||"Failed to export database"})}finally{U(!1)}},ek=async e=>{let t=e.target.files?.[0];if(t){U(!0),A({type:"",message:""});try{let e=await t.text(),s=JSON.parse(e),a=await fetch("/api/settings/database",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)}),r=await a.json().catch(()=>({}));if(!a.ok)throw Error(r.error||"Failed to import database");await ev(),A({type:"success",message:"Database imported successfully"})}catch(e){A({type:"error",message:e.message||"Invalid backup file"})}finally{X.current&&(X.current.value=""),U(!1)}}},eS=!0===v.enableObservability,eP=async()=>{w(!0);try{await fetch("/api/version/shutdown",{method:"POST"})}catch(e){}w(!1),j(!1)},eO=async()=>{try{(await fetch("/api/auth/logout",{method:"POST"})).ok&&(e.push("/login"),e.refresh())}catch(e){console.error("Failed to logout:",e)}};return(0,a.jsxs)("div",{className:"max-w-2xl mx-auto px-4 sm:px-0",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-6",children:[(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-4",children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 sm:gap-4",children:[(0,a.jsx)("div",{className:"size-10 sm:size-12 rounded-lg bg-green-500/10 text-green-500 flex items-center justify-center shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-xl sm:text-2xl",children:"computer"})}),(0,a.jsxs)("div",{children:[(0,a.jsx)("h2",{className:"text-lg sm:text-xl font-semibold",children:"Local Mode"}),(0,a.jsx)("p",{className:"text-sm text-text-muted",children:"Running on your machine"})]})]}),(0,a.jsx)("div",{className:"inline-flex p-1 rounded-lg bg-black/5 dark:bg-white/5 w-full sm:w-auto",children:["light","dark","system"].map(e=>(0,a.jsxs)("button",{type:"button",onClick:()=>s(e),className:(0,c.cn)("flex items-center justify-center gap-1 sm:gap-1.5 px-2 sm:px-3 py-1.5 rounded-md font-medium transition-all flex-1 sm:flex-initial",t===e?"bg-white dark:bg-white/10 text-text-main shadow-sm":"text-text-muted hover:text-text-main"),children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"light"===e?"light_mode":"dark"===e?"dark_mode":"contrast"}),(0,a.jsx)("span",{className:"capitalize text-xs sm:text-sm",children:e})]},e))})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-3 pt-4 border-t border-border",children:[(0,a.jsx)("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between p-3 rounded-lg bg-bg border border-border gap-2",children:(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Database Location"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted font-mono break-all",children:"~/.zevai/db/data.sqlite"})]})}),(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row gap-2",children:[(0,a.jsx)(l.$n,{variant:"secondary",icon:"download",onClick:eC,loading:D,className:"w-full sm:w-auto",children:"Download Backup"}),(0,a.jsx)(l.$n,{variant:"outline",icon:"upload",onClick:()=>X.current?.click(),disabled:D,className:"w-full sm:w-auto",children:"Import Backup"}),(0,a.jsx)("input",{ref:X,type:"file",accept:"application/json,.json",className:"hidden",onChange:ek})]}),M.message&&(0,a.jsx)("p",{className:`text-sm ${"error"===M.type?"text-red-500":"text-green-600 dark:text-green-400"}`,children:M.message})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"size-10 rounded-lg bg-blue-500/10 text-blue-500 flex items-center justify-center shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"language"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Language"})]}),(0,a.jsxs)("button",{onClick:()=>y(!0),className:"flex items-center justify-between w-full p-3 rounded-lg bg-bg border border-border hover:border-primary/50 transition-colors","data-i18n-skip":"true",children:[(0,a.jsx)("span",{className:"text-sm text-text-muted",children:"Display language"}),(0,a.jsx)("span",{className:"text-2xl",children:u.h[h]||"\uD83C\uDF10"})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-primary/10 text-primary shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"shield"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Security"})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Require login"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"When ON, dashboard requires password. When OFF, access without login."})]}),(0,a.jsx)(l.lM,{checked:!0===v.requireLogin,onChange:()=>ey(!v.requireLogin),disabled:k})]}),!0===v.requireLogin&&(0,a.jsxs)("form",{onSubmit:em,className:"flex flex-col gap-4 pt-4 border-t border-border/50",children:[v.hasPassword&&(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"text-xs sm:text-sm font-medium",children:"Current Password"}),(0,a.jsx)(l.pd,{type:"password",placeholder:"Enter current password",value:P.current,onChange:e=>O({...P,current:e.target.value}),required:!0})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"text-xs sm:text-sm font-medium",children:"New Password"}),(0,a.jsx)(l.pd,{type:"password",placeholder:"Enter new password",value:P.new,onChange:e=>O({...P,new:e.target.value}),required:!0})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"text-xs sm:text-sm font-medium",children:"Confirm New Password"}),(0,a.jsx)(l.pd,{type:"password",placeholder:"Confirm new password",value:P.confirm,onChange:e=>O({...P,confirm:e.target.value}),required:!0})]})]}),I.message&&(0,a.jsx)("p",{className:`text-xs sm:text-sm ${"error"===I.type?"text-red-500":"text-green-500"}`,children:I.message}),(0,a.jsx)("div",{className:"pt-2",children:(0,a.jsx)(l.$n,{type:"submit",variant:"primary",loading:T,className:"w-full sm:w-auto",children:v.hasPassword?"Update Password":"Set Password"})})]})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("button",{type:"button",onClick:()=>Y(e=>!e),className:"w-full flex items-center gap-3 text-left",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-indigo-500/10 text-indigo-500 shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"lock_open"})}),(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"OIDC Dashboard Login"}),(0,a.jsx)("p",{className:"text-xs text-text-muted",children:"oidc"===v.authMode?"OIDC active":"both"===v.authMode?"Password + OIDC active":"Optional SSO via Authentik/Keycloak/Google"})]}),(0,a.jsx)("span",{className:"material-symbols-outlined text-text-muted shrink-0",children:G?"expand_less":"expand_more"})]}),G&&(0,a.jsxs)("div",{className:"flex flex-col gap-4 mt-4",children:[(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Use Authentik or any OIDC provider to sign in to the dashboard. You can enable password-only, OIDC-only, or both for the dashboard; model API access still uses API keys."}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Auth Mode"}),(0,a.jsx)("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-2",children:[{value:"password",title:"Password only",desc:"Keep the legacy password login."},{value:"oidc",title:"OIDC only",desc:"Require OIDC for dashboard access."},{value:"both",title:"Both",desc:"Allow either password or OIDC."}].map(e=>{let t=E.authMode===e.value;return(0,a.jsxs)("button",{type:"button",onClick:()=>ef("authMode",e.value),className:(0,c.cn)("text-left rounded-lg border p-3 transition-colors",t?"border-primary bg-primary/5":"border-border bg-bg hover:bg-black/5 dark:hover:bg-white/5"),disabled:k||_,children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:e.title}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted mt-1",children:e.desc})]},e.value)})})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 gap-4",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Issuer URL"}),(0,a.jsx)(l.pd,{placeholder:"https://auth.example.com/application/o/zevairouter/",value:E.oidcIssuerUrl,onChange:e=>ef("oidcIssuerUrl",e.target.value),disabled:k||_})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Client ID"}),(0,a.jsx)(l.pd,{placeholder:"zevairouter-dashboard",value:E.oidcClientId,onChange:e=>ef("oidcClientId",e.target.value),disabled:k||_})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Client Secret"}),(0,a.jsx)(l.pd,{type:"password",placeholder:"Leave blank to keep existing secret",value:q,onChange:e=>F(e.target.value),disabled:k||_}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"This value is write-only after saving."})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Scopes"}),(0,a.jsx)(l.pd,{placeholder:"openid profile email",value:E.oidcScopes,onChange:e=>ef("oidcScopes",e.target.value),disabled:k||_})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Login Button Label"}),(0,a.jsx)(l.pd,{placeholder:"Sign in with OIDC",value:E.oidcLoginLabel,onChange:e=>ef("oidcLoginLabel",e.target.value),disabled:k||_})]})]}),(0,a.jsxs)("div",{className:"rounded-lg border border-border bg-bg p-3 text-xs sm:text-sm text-text-muted",children:[(0,a.jsx)("p",{className:"font-medium text-text-main mb-1",children:"Redirect URI"}),(0,a.jsx)("code",{className:"block break-all font-mono",children:Q})]}),(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row gap-2 pt-2 border-t border-border/50",children:[(0,a.jsx)(l.$n,{type:"button",variant:"primary",loading:_,onClick:()=>ej(),className:"w-full sm:w-auto",children:"Save auth mode"}),(0,a.jsx)(l.$n,{type:"button",variant:"outline",loading:z,onClick:eN,className:"w-full sm:w-auto",children:"Test connection"})]}),Z.message&&(0,a.jsx)("p",{className:`text-xs sm:text-sm ${"error"===Z.type?"text-red-500":"text-green-500"}`,children:Z.message}),J.message&&(0,a.jsx)("p",{className:`text-xs sm:text-sm ${"error"===J.type?"text-red-500":"text-green-500"}`,children:J.message}),"oidc"===v.authMode&&(0,a.jsx)("p",{className:"text-xs sm:text-sm text-amber-600 dark:text-amber-400",children:"OIDC login is currently active. Password login is disabled until you switch back."}),"both"===v.authMode&&(0,a.jsx)("p",{className:"text-xs sm:text-sm text-amber-600 dark:text-amber-400",children:"Password and OIDC login are both active."})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-blue-500/10 text-blue-500 shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"route"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Routing Strategy"})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Round Robin"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Cycle through accounts to distribute load"})]}),(0,a.jsx)(l.lM,{checked:"round-robin"===v.fallbackStrategy,onChange:()=>ex("round-robin"===v.fallbackStrategy?"fill-first":"round-robin"),disabled:k})]}),"round-robin"===v.fallbackStrategy&&(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-2 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Sticky Limit"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Calls per account before switching"})]}),(0,a.jsx)(l.pd,{type:"number",min:"1",max:"10",value:v.stickyRoundRobinLimit||3,onChange:e=>eb(e.target.value),disabled:k,className:"w-16 sm:w-20 text-center shrink-0"})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-4 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Most Quota"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Pick the account with the most remaining quota (uses cached usage)"})]}),(0,a.jsx)(l.lM,{checked:"most-quota"===v.fallbackStrategy,onChange:()=>ex("most-quota"===v.fallbackStrategy?"fill-first":"most-quota"),disabled:k})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-4 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Lowest Latency"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Route to the fastest account by recent avg response time"})]}),(0,a.jsx)(l.lM,{checked:"lowest-latency"===v.fallbackStrategy,onChange:()=>ex("lowest-latency"===v.fallbackStrategy?"fill-first":"lowest-latency"),disabled:k})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-4 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Response Cache"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Serve identical non-streaming requests from memory (saves cost)"})]}),(0,a.jsx)(l.lM,{checked:!1!==v.responseCacheEnabled,onChange:()=>eu(!1===v.responseCacheEnabled),disabled:k})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-4 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Webhook Alerts"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Notify on provider down / quota exhausted (Discord, Telegram, or generic webhook)"})]}),(0,a.jsx)(l.lM,{checked:!0===v.alertEnabled,onChange:()=>ep({alertEnabled:!0!==v.alertEnabled}),disabled:k})]}),!0===v.alertEnabled&&(0,a.jsxs)("div",{className:"flex flex-col gap-3 pt-2 border-t border-border/50",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"text-xs text-text-muted block mb-1",children:"Webhook URL"}),(0,a.jsx)(l.pd,{type:"url",placeholder:"https://discord.com/api/webhooks/… or https://api.telegram.org/bot<token>/sendMessage",defaultValue:v.alertWebhookUrl||"",onBlur:e=>ep({alertWebhookUrl:e.target.value.trim()}),disabled:k})]}),(0,a.jsxs)("div",{className:"flex gap-3",children:[(0,a.jsxs)("div",{className:"flex-1",children:[(0,a.jsx)("label",{className:"text-xs text-text-muted block mb-1",children:"Type"}),(0,a.jsxs)("select",{defaultValue:v.alertWebhookType||"discord",onChange:e=>ep({alertWebhookType:e.target.value}),disabled:k,className:"w-full px-2 py-1.5 text-sm bg-transparent border border-border rounded",children:[(0,a.jsx)("option",{value:"discord",children:"Discord"}),(0,a.jsx)("option",{value:"telegram",children:"Telegram"}),(0,a.jsx)("option",{value:"generic",children:"Generic JSON"})]})]}),"telegram"===v.alertWebhookType&&(0,a.jsxs)("div",{className:"flex-1",children:[(0,a.jsx)("label",{className:"text-xs text-text-muted block mb-1",children:"Telegram Chat ID"}),(0,a.jsx)(l.pd,{type:"text",placeholder:"-1001234567890",defaultValue:v.alertTelegramChatId||"",onBlur:e=>ep({alertTelegramChatId:e.target.value.trim()}),disabled:k})]})]})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-4 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Combo Round Robin"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Cycle through providers in combos instead of always starting with first"})]}),(0,a.jsx)(l.lM,{checked:"round-robin"===v.comboStrategy,onChange:()=>eh("round-robin"===v.comboStrategy?"fallback":"round-robin"),disabled:k})]}),"round-robin"===v.comboStrategy&&(0,a.jsxs)("div",{className:"flex items-center justify-between pt-2 border-t border-border/50",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"font-medium",children:"Combo Sticky Limit"}),(0,a.jsx)("p",{className:"text-sm text-text-muted",children:"Calls per combo model before switching"})]}),(0,a.jsx)(l.pd,{type:"number",min:"1",max:"100",value:v.comboStickyRoundRobinLimit||1,onChange:e=>eg(e.target.value),disabled:k,className:"w-20 text-center"})]}),(0,a.jsxs)("p",{className:"text-xs text-text-muted italic pt-2 border-t border-border/50",children:["round-robin"===v.fallbackStrategy?`Currently distributing requests across all available accounts with ${v.stickyRoundRobinLimit||3} calls per account.`:"most-quota"===v.fallbackStrategy?"Currently routing to the account with the most remaining quota.":"lowest-latency"===v.fallbackStrategy?"Currently routing to the fastest account by recent avg latency.":"Currently using accounts in priority order (Fill First).","round-robin"===v.comboStrategy?` Combos rotate after ${v.comboStickyRoundRobinLimit||1} call${1===(v.comboStickyRoundRobinLimit||1)?"":"s"} per model.`:" Combos always start with their first model."]})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-purple-500/10 text-purple-500 shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"wifi"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Network"})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Outbound Proxy"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Enable proxy for OAuth + provider outbound requests."})]}),(0,a.jsx)(l.lM,{checked:!0===v.outboundProxyEnabled,onChange:()=>ec(!0!==v.outboundProxyEnabled),disabled:k||er})]}),!0===v.outboundProxyEnabled&&(0,a.jsxs)("form",{onSubmit:en,className:"flex flex-col gap-4 pt-2 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Proxy URL"}),(0,a.jsx)(l.pd,{placeholder:"http://127.0.0.1:7897",value:ee.outboundProxyUrl,onChange:e=>et(t=>({...t,outboundProxyUrl:e.target.value})),disabled:k||er}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Leave empty to inherit existing env proxy (if any)."})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2 pt-2 border-t border-border/50",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"No Proxy"}),(0,a.jsx)(l.pd,{placeholder:"localhost,127.0.0.1",value:ee.outboundNoProxy,onChange:e=>et(t=>({...t,outboundNoProxy:e.target.value})),disabled:k||er}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Comma-separated hostnames/domains to bypass the proxy."})]}),(0,a.jsxs)("div",{className:"pt-2 border-t border-border/50 flex flex-col sm:flex-row items-stretch sm:items-center gap-2",children:[(0,a.jsx)(l.$n,{type:"button",variant:"secondary",loading:el,disabled:k||er,onClick:ed,className:"w-full sm:w-auto",children:"Test proxy URL"}),(0,a.jsx)(l.$n,{type:"submit",variant:"primary",loading:er,className:"w-full sm:w-auto",children:"Apply"})]})]}),es.message&&(0,a.jsx)("p",{className:`text-xs sm:text-sm ${"error"===es.type?"text-red-500":"text-green-500"} pt-2 border-t border-border/50`,children:es.message})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-orange-500/10 text-orange-500 shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"monitoring"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Observability"})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Enable Observability"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Record request details for inspection in the logs view"})]}),(0,a.jsx)(l.lM,{checked:eS,onChange:ew,disabled:k})]})]}),(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row gap-2",children:[(0,a.jsx)(l.$n,{variant:"outline",fullWidth:!0,icon:"power_settings_new",onClick:()=>j(!0),className:"text-red-500 border-red-200 hover:bg-red-50 hover:border-red-300",children:"Shutdown"}),(0,a.jsx)(l.$n,{variant:"outline",fullWidth:!0,icon:"logout",onClick:eO,children:"Logout"})]}),(0,a.jsxs)("div",{className:"text-center text-xs sm:text-sm text-text-muted py-4",children:[(0,a.jsxs)("p",{children:[m.vQ.name," v",m.vQ.version]}),(0,a.jsx)("p",{className:"mt-1",children:"Local Mode - All data stored on your machine"})]})]}),(0,a.jsx)(n.default,{hideTrigger:!0,isOpen:g,onClose:e=>{y(!1),b(e)}}),(0,a.jsx)(i.ConfirmModal,{isOpen:f,onClose:()=>j(!1),onConfirm:eP,title:"Close Proxy",message:"Are you sure you want to close the proxy server?",confirmText:"Close",cancelText:"Cancel",variant:"danger",loading:N})]})}}},e=>{e.O(0,[2574,3862,4343,85,5497,8441,3794,7358],()=>e(e.s=52424)),_N_E=e.O()}]);
@@ -1,3 +1,8 @@
1
+ # v1.0.133 (2026-07-26)
2
+
3
+ ## Improvements
4
+ - **CodeBuddy CN per-account Chromium fingerprint**: each bulk-import account now gets a seeded fingerprint (real desktop viewport sizes, deviceScaleFactor, hardwareConcurrency, deviceMemory, and screen metrics) so sticky residential IPs no longer share the same 900×700 + identical navigator.* cluster that Tencent risk scoring can ban after OTP.
5
+
1
6
  # v1.0.128 (2026-07-25)
2
7
 
3
8
  ## Improvements
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zevairouter",
3
- "version": "1.0.131",
3
+ "version": "1.0.133",
4
4
  "description": "Self-hosted AI router: many providers, one OpenAI-compatible /v1 endpoint and dashboard",
5
5
  "bin": {
6
6
  "zevai": "./cli/cli.js"
package/cli/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zevairouter-cli",
3
- "version": "1.0.131",
3
+ "version": "1.0.133",
4
4
  "description": "ZevaiRouter CLI - Start and manage ZevaiRouter server",
5
5
  "bin": {
6
6
  "zevai": "./cli.js"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zevairouter",
3
- "version": "1.0.131",
3
+ "version": "1.0.133",
4
4
  "description": "Self-hosted AI router: many providers, one OpenAI-compatible /v1 endpoint and dashboard",
5
5
  "bin": {
6
6
  "zevai": "./cli/cli.js"
@@ -512,7 +512,8 @@ export default function ProfilePage() {
512
512
  }
513
513
 
514
514
  const payload = await res.json();
515
- const content = JSON.stringify(payload, null, 2);
515
+ // Compact JSON (no pretty-print) — backup is config-only; pretty-print bloats multi‑MB files
516
+ const content = JSON.stringify(payload);
516
517
  const blob = new Blob([content], { type: "application/json" });
517
518
  const url = URL.createObjectURL(blob);
518
519
  const anchor = document.createElement("a");
@@ -524,7 +525,14 @@ export default function ProfilePage() {
524
525
  document.body.removeChild(anchor);
525
526
  URL.revokeObjectURL(url);
526
527
 
527
- setDbStatus({ type: "success", message: "Database backup downloaded" });
528
+ const sizeMb = (blob.size / (1024 * 1024)).toFixed(2);
529
+ const excluded = Array.isArray(payload?.excludedTables) && payload.excludedTables.length
530
+ ? ` (config only — skipped ${payload.excludedTables.join(", ")})`
531
+ : "";
532
+ setDbStatus({
533
+ type: "success",
534
+ message: `Database backup downloaded (${sizeMb} MB)${excluded}`,
535
+ });
528
536
  } catch (err) {
529
537
  setDbStatus({ type: "error", message: err.message || "Failed to export database" });
530
538
  } finally {
@@ -82,12 +82,24 @@ export {
82
82
  saveRequestDetail, getRequestDetails, getRequestDetailById,
83
83
  } from "./repos/requestDetailsRepo.js";
84
84
 
85
+ // Telemetry/history tables — huge and not needed for config restore (settings,
86
+ // connections, API keys, proxies, combos). Including them made "Download backup"
87
+ // multi‑MB JSON after long usage (usageHistory alone often 20MB+).
88
+ const BACKUP_EXCLUDE_TABLES = new Set([
89
+ "usageHistory",
90
+ "requestDetails",
91
+ "quotaCache",
92
+ ]);
93
+
85
94
  // Export/import full DB
86
95
  export async function exportDb() {
87
96
  const db = await getAdapter();
88
97
  const { exportSettings } = await import("./repos/settingsRepo.js");
89
98
 
99
+ const tableNames = Object.keys(TABLES).filter((table) => !BACKUP_EXCLUDE_TABLES.has(table));
100
+
90
101
  const out = {
102
+ // Config-oriented export (legacy top-level fields for older importers)
91
103
  settings: await exportSettings(),
92
104
  providerConnections: db.all(`SELECT * FROM providerConnections`).map((r) => ({ ...parseJson(r.data, {}), id: r.id, provider: r.provider, authType: r.authType, name: r.name, email: r.email, priority: r.priority, isActive: r.isActive === 1, createdAt: r.createdAt, updatedAt: r.updatedAt })),
93
105
  providerNodes: db.all(`SELECT * FROM providerNodes`).map((r) => ({ ...parseJson(r.data, {}), id: r.id, type: r.type, name: r.name, createdAt: r.createdAt, updatedAt: r.updatedAt })),
@@ -98,7 +110,10 @@ export async function exportDb() {
98
110
  customModels: [],
99
111
  mitmAlias: {},
100
112
  pricing: {},
101
- tables: Object.fromEntries(Object.keys(TABLES).map((table) => [table, db.all(`SELECT * FROM "${table}"`)])),
113
+ // Modern path: only config tables (no usage/request dump)
114
+ tables: Object.fromEntries(tableNames.map((table) => [table, db.all(`SELECT * FROM "${table}"`)])),
115
+ // Hint for UI / future full-export option
116
+ excludedTables: [...BACKUP_EXCLUDE_TABLES],
102
117
  };
103
118
 
104
119
  for (const r of db.all(`SELECT key, value FROM kv WHERE scope = 'modelAliases'`)) out.modelAliases[r.key] = parseJson(r.value);
@@ -1,3 +1,4 @@
1
+ import { createHash } from "node:crypto";
1
2
  import { createRequire } from "node:module";
2
3
 
3
4
  const requireFromHere = createRequire(import.meta.url);
@@ -50,11 +51,83 @@ function getStealthPlatformProfile() {
50
51
  };
51
52
  }
52
53
 
54
+ /**
55
+ * Seeded fingerprint so each account/session looks like a different real desktop
56
+ * instead of the same 900x700 + identical navigator.* cluster (Tencent risk signal).
57
+ * WebGL stays OS-native (spoofing Mac GPU on Linux UA is worse).
58
+ *
59
+ * @param {string|number} [seed]
60
+ * @returns {{
61
+ * viewport: { width: number, height: number },
62
+ * deviceScaleFactor: number,
63
+ * hardwareConcurrency: number,
64
+ * deviceMemory: number,
65
+ * maxTouchPoints: number,
66
+ * screen: { width: number, height: number, availWidth: number, availHeight: number, colorDepth: number, pixelDepth: number },
67
+ * seed: string,
68
+ * }}
69
+ */
70
+ export function buildAccountFingerprint(seed) {
71
+ // Deterministic byte stream from seed (stable retry of same account = same fingerprint).
72
+ let buf = createHash("sha256").update(String(seed ?? `${Date.now()}-${Math.random()}`)).digest();
73
+ let i = 0;
74
+ const nextByte = () => {
75
+ if (i >= buf.length) {
76
+ buf = createHash("sha256").update(buf).digest();
77
+ i = 0;
78
+ }
79
+ return buf[i++];
80
+ };
81
+ const next = () => nextByte() / 256;
82
+ const pick = (arr) => arr[Math.floor(next() * arr.length) % arr.length];
83
+
84
+ // Common real desktop resolutions (avoid Playwright default 900x700 bot shape).
85
+ const base = pick([
86
+ { width: 1366, height: 768 },
87
+ { width: 1440, height: 900 },
88
+ { width: 1536, height: 864 },
89
+ { width: 1920, height: 1080 },
90
+ { width: 1280, height: 800 },
91
+ { width: 1600, height: 900 },
92
+ { width: 1280, height: 720 },
93
+ { width: 1680, height: 1050 },
94
+ { width: 2560, height: 1440 },
95
+ ]);
96
+ // Tiny noise so two accounts with same base size still differ slightly.
97
+ const width = base.width - (nextByte() % 17);
98
+ const height = base.height - (nextByte() % 13);
99
+ const taskbar = pick([0, 30, 40, 48]);
100
+ const colorDepth = pick([24, 30, 32]);
101
+ const hardwareConcurrency = pick([4, 6, 8, 8, 12, 16]);
102
+ const deviceMemory = pick([4, 8, 8, 16]);
103
+ const deviceScaleFactor = pick([1, 1, 1.25, 1.5, 2]);
104
+
105
+ return {
106
+ seed: String(seed ?? ""),
107
+ viewport: { width, height },
108
+ deviceScaleFactor,
109
+ hardwareConcurrency,
110
+ deviceMemory,
111
+ maxTouchPoints: 0,
112
+ screen: {
113
+ width,
114
+ height,
115
+ availWidth: width,
116
+ availHeight: Math.max(height - taskbar, Math.floor(height * 0.92)),
117
+ colorDepth,
118
+ pixelDepth: colorDepth,
119
+ },
120
+ };
121
+ }
122
+
53
123
  function buildStealthInitScript(overrides = {}) {
54
124
  const p = getStealthPlatformProfile();
55
125
  const languages = Array.isArray(overrides.languages) && overrides.languages.length
56
126
  ? overrides.languages
57
127
  : p.languages;
128
+ const fp = overrides.fingerprint && typeof overrides.fingerprint === "object"
129
+ ? overrides.fingerprint
130
+ : null;
58
131
  // Inject as JSON so quotes in renderer strings stay safe.
59
132
  return `
60
133
  (() => {
@@ -62,6 +135,10 @@ function buildStealthInitScript(overrides = {}) {
62
135
  languages,
63
136
  webglVendor: p.webglVendor,
64
137
  webglRenderer: p.webglRenderer,
138
+ hardwareConcurrency: fp?.hardwareConcurrency ?? null,
139
+ deviceMemory: fp?.deviceMemory ?? null,
140
+ maxTouchPoints: fp?.maxTouchPoints ?? null,
141
+ screen: fp?.screen ?? null,
65
142
  })};
66
143
  try {
67
144
  Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
@@ -69,6 +146,31 @@ function buildStealthInitScript(overrides = {}) {
69
146
  try {
70
147
  Object.defineProperty(navigator, 'languages', { get: () => profile.languages.slice() });
71
148
  } catch {}
149
+ try {
150
+ if (typeof profile.hardwareConcurrency === 'number') {
151
+ Object.defineProperty(navigator, 'hardwareConcurrency', { get: () => profile.hardwareConcurrency });
152
+ }
153
+ } catch {}
154
+ try {
155
+ if (typeof profile.deviceMemory === 'number') {
156
+ Object.defineProperty(navigator, 'deviceMemory', { get: () => profile.deviceMemory });
157
+ }
158
+ } catch {}
159
+ try {
160
+ if (typeof profile.maxTouchPoints === 'number') {
161
+ Object.defineProperty(navigator, 'maxTouchPoints', { get: () => profile.maxTouchPoints });
162
+ }
163
+ } catch {}
164
+ try {
165
+ if (profile.screen && typeof profile.screen === 'object') {
166
+ const s = profile.screen;
167
+ for (const key of ['width', 'height', 'availWidth', 'availHeight', 'colorDepth', 'pixelDepth']) {
168
+ if (typeof s[key] === 'number') {
169
+ try { Object.defineProperty(screen, key, { get: () => s[key] }); } catch {}
170
+ }
171
+ }
172
+ }
173
+ } catch {}
72
174
  try {
73
175
  Object.defineProperty(navigator, 'plugins', {
74
176
  get: () => {
@@ -150,9 +252,9 @@ function wrapBrowserWithStealth(browser) {
150
252
  languages = ["en-US", "en"];
151
253
  }
152
254
  }
153
- // Playwright accepts locale/timezoneId/geolocation natively; languages is only for init script.
154
- const { languages: _drop, ...pwOptions } = { ...options, languages };
155
- const stealthScript = buildStealthInitScript({ languages });
255
+ // `fingerprint` / `languages` are ours — strip before Playwright newContext.
256
+ const { languages: _drop, fingerprint, ...pwOptions } = { ...options, languages };
257
+ const stealthScript = buildStealthInitScript({ languages, fingerprint });
156
258
  const ctx = await origNewContext(pwOptions);
157
259
  await ctx.addInitScript(stealthScript);
158
260
  return ctx;
@@ -278,6 +278,8 @@ export class CodeBuddyCnBulkImportManager extends KiroBulkImportManager {
278
278
  phone: null,
279
279
  fiveSimOrderId: null,
280
280
  fiveSimActivationId: null,
281
+ // Unique Chromium fingerprint seed per account (viewport/HW/screen noise).
282
+ fingerprintSeed: randomUUID(),
281
283
  proxyUrl: null,
282
284
  abortController: new AbortController(),
283
285
  status: "queued",
@@ -355,9 +357,13 @@ export class CodeBuddyCnBulkImportManager extends KiroBulkImportManager {
355
357
  // Chromium-only stack: use zh-CN locale + HK/CN timezone so Tencent risk
356
358
  // scoring does not see EN-US browser on residential CN/HK egress (common
357
359
  // cause of 账号访问受限 right after OTP). Engine stays Playwright Chromium.
360
+ // Also apply a unique per-account fingerprint seed — sticky residential IP
361
+ // alone still clusters if every session shares the same 900x700 + HW profile.
362
+ if (!account.fingerprintSeed) account.fingerprintSeed = randomUUID();
358
363
  const freshContext = await createFreshContext(job.browser, account.proxyUrl, {
359
364
  profile: "codebuddy-cn",
360
365
  region: job.region || "hongkong",
366
+ fingerprintSeed: account.fingerprintSeed,
361
367
  });
362
368
  context = freshContext.context;
363
369
  const page = freshContext.page;
@@ -380,6 +380,8 @@ export { parsePlaywrightProxy };
380
380
  * @param {object} [opts]
381
381
  * @param {"default"|"codebuddy-cn"} [opts.profile]
382
382
  * @param {"hongkong"|"china"|string} [opts.region] Used by codebuddy-cn profile
383
+ * @param {string|number} [opts.fingerprintSeed] Per-account seed for viewport/HW fingerprint
384
+ * @param {boolean} [opts.randomizeFingerprint] Force fingerprint even outside codebuddy-cn
383
385
  */
384
386
  export async function createFreshContext(browser, proxy, opts = {}) {
385
387
  let effectiveProxy = proxy;
@@ -398,6 +400,32 @@ export async function createFreshContext(browser, proxy, opts = {}) {
398
400
 
399
401
  const parsedProxy = parsePlaywrightProxy(effectiveProxy);
400
402
  const contextOptions = parsedProxy ? { proxy: parsedProxy } : {};
403
+
404
+ // Per-account Chromium fingerprint (viewport + navigator.* + screen).
405
+ // Sticky residential IP alone still clusters if every session is 900x700 + same HW.
406
+ const wantFingerprint =
407
+ opts.profile === "codebuddy-cn" ||
408
+ opts.randomizeFingerprint === true ||
409
+ opts.fingerprintSeed != null;
410
+ let fingerprint = null;
411
+ if (wantFingerprint) {
412
+ try {
413
+ const { buildAccountFingerprint } = await import("./bulkImportBrowserEngine.js");
414
+ fingerprint = buildAccountFingerprint(
415
+ opts.fingerprintSeed ?? randomUUID(),
416
+ );
417
+ contextOptions.viewport = { ...fingerprint.viewport };
418
+ contextOptions.deviceScaleFactor = fingerprint.deviceScaleFactor;
419
+ contextOptions.fingerprint = {
420
+ hardwareConcurrency: fingerprint.hardwareConcurrency,
421
+ deviceMemory: fingerprint.deviceMemory,
422
+ maxTouchPoints: fingerprint.maxTouchPoints,
423
+ screen: fingerprint.screen,
424
+ };
425
+ } catch {
426
+ fingerprint = null;
427
+ }
428
+ }
401
429
  if (!contextOptions.viewport) {
402
430
  contextOptions.viewport = { width: 900, height: 700 };
403
431
  }
@@ -426,6 +454,10 @@ export async function createFreshContext(browser, proxy, opts = {}) {
426
454
  if (opts.timezoneId) contextOptions.timezoneId = opts.timezoneId;
427
455
  if (opts.geolocation) contextOptions.geolocation = opts.geolocation;
428
456
  if (Array.isArray(opts.languages)) contextOptions.languages = opts.languages;
457
+ if (opts.viewport) contextOptions.viewport = opts.viewport;
458
+ if (typeof opts.deviceScaleFactor === "number") {
459
+ contextOptions.deviceScaleFactor = opts.deviceScaleFactor;
460
+ }
429
461
  if (opts.extraHTTPHeaders) {
430
462
  contextOptions.extraHTTPHeaders = {
431
463
  ...(contextOptions.extraHTTPHeaders || {}),
@@ -1 +0,0 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3471],{52424:(e,t,s)=>{Promise.resolve().then(s.bind(s,64561))},64561:(e,t,s)=>{"use strict";s.r(t),s.d(t,{default:()=>p});var a=s(95155),r=s(12115),o=s(73321),l=s(35497),i=s(81127),n=s(21931),d=s(1620),c=s(31474),m=s(90620),x=s(93308),u=s(38202);function p(){let e=(0,o.useRouter)(),{theme:t,setTheme:s,isDark:p}=(0,d.D)(),[h,b]=(0,r.useState)("en"),[g,y]=(0,r.useState)(!1),[f,j]=(0,r.useState)(!1),[N,w]=(0,r.useState)(!1),[v,C]=(0,r.useState)({fallbackStrategy:"fill-first"}),[k,S]=(0,r.useState)(!0),[P,O]=(0,r.useState)({current:"",new:"",confirm:""}),[I,L]=(0,r.useState)({type:"",message:""}),[T,R]=(0,r.useState)(!1),[D,U]=(0,r.useState)(!1),[M,E]=(0,r.useState)({type:"",message:""}),[A,$]=(0,r.useState)({authMode:"password",oidcIssuerUrl:"",oidcClientId:"",oidcScopes:"openid profile email",oidcLoginLabel:"Sign in with OIDC"}),[q,F]=(0,r.useState)(""),[J,H]=(0,r.useState)({type:"",message:""}),[_,W]=(0,r.useState)(!1),[z,B]=(0,r.useState)(!1),[Z,K]=(0,r.useState)({type:"",message:""}),[Q,V]=(0,r.useState)("/api/auth/oidc/callback"),[G,Y]=(0,r.useState)(!1),X=(0,r.useRef)(null),[ee,et]=(0,r.useState)({outboundProxyEnabled:!1,outboundProxyUrl:"",outboundNoProxy:""}),[es,ea]=(0,r.useState)({type:"",message:""}),[er,eo]=(0,r.useState)(!1),[el,ei]=(0,r.useState)(!1);(0,r.useEffect)(()=>{b(function(){if("u"<typeof document)return"en";let e=document.cookie.split(";").find(e=>e.trim().startsWith(`${x.CL}=`)),t=e?decodeURIComponent(e.split("=")[1]):"en";return(0,x.QC)(t)}())},[g]),(0,r.useEffect)(()=>{fetch("/api/settings").then(e=>e.json()).then(e=>{C(e),$({authMode:e?.authMode||"password",oidcIssuerUrl:e?.oidcIssuerUrl||"",oidcClientId:e?.oidcClientId||"",oidcScopes:e?.oidcScopes||"openid profile email",oidcLoginLabel:e?.oidcLoginLabel||"Sign in with OIDC"}),F(""),(e?.authMode==="oidc"||e?.authMode==="both")&&Y(!0),et({outboundProxyEnabled:e?.outboundProxyEnabled===!0,outboundProxyUrl:e?.outboundProxyUrl||"",outboundNoProxy:e?.outboundNoProxy||""}),S(!1)}).catch(e=>{console.error("Failed to fetch settings:",e),S(!1)})},[]),(0,r.useEffect)(()=>{V(`${window.location.origin}/api/auth/oidc/callback`)},[]);let en=async e=>{if(e.preventDefault(),!0===v.outboundProxyEnabled){eo(!0),ea({type:"",message:""});try{let e=await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({outboundProxyUrl:ee.outboundProxyUrl,outboundNoProxy:ee.outboundNoProxy})}),t=await e.json();e.ok?(C(e=>({...e,...t})),ea({type:"success",message:"Proxy settings applied"})):ea({type:"error",message:t.error||"Failed to update proxy settings"})}catch(e){ea({type:"error",message:"An error occurred"})}finally{eo(!1)}}},ed=async()=>{if(!0!==v.outboundProxyEnabled)return;let e=(ee.outboundProxyUrl||"").trim();if(!e)return void ea({type:"error",message:"Please enter a Proxy URL to test"});ei(!0),ea({type:"",message:""});try{let t=await fetch("/api/settings/proxy-test",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({proxyUrl:e})}),s=await t.json();t.ok&&s?.ok?ea({type:"success",message:`Proxy test OK (${s.status}) in ${s.elapsedMs}ms`}):ea({type:"error",message:s?.error||"Proxy test failed"})}catch(e){ea({type:"error",message:"An error occurred"})}finally{ei(!1)}},ec=async e=>{eo(!0),ea({type:"",message:""});try{let t=await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({outboundProxyEnabled:e})}),s=await t.json();t.ok?(C(e=>({...e,...s})),et(e=>({...e,outboundProxyEnabled:s?.outboundProxyEnabled===!0})),ea({type:"success",message:e?"Proxy enabled":"Proxy disabled"})):ea({type:"error",message:s.error||"Failed to update proxy settings"})}catch(e){ea({type:"error",message:"An error occurred"})}finally{eo(!1)}},em=async e=>{if(e.preventDefault(),P.new!==P.confirm)return void L({type:"error",message:"Passwords do not match"});R(!0),L({type:"",message:""});try{let e=await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({currentPassword:P.current,newPassword:P.new})}),t=await e.json();e.ok?(L({type:"success",message:"Password updated successfully"}),O({current:"",new:"",confirm:""})):L({type:"error",message:t.error||"Failed to update password"})}catch(e){L({type:"error",message:"An error occurred"})}finally{R(!1)}},ex=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({fallbackStrategy:e})})).ok&&C(t=>({...t,fallbackStrategy:e}))}catch(e){console.error("Failed to update settings:",e)}},eu=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({responseCacheEnabled:e})})).ok&&C(t=>({...t,responseCacheEnabled:e}))}catch(e){console.error("Failed to update settings:",e)}},ep=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})).ok&&C(t=>({...t,...e}))}catch(e){console.error("Failed to update alert settings:",e)}},eh=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({comboStrategy:e})})).ok&&C(t=>({...t,comboStrategy:e}))}catch(e){console.error("Failed to update combo strategy:",e)}},eb=async e=>{let t=parseInt(e);if(!isNaN(t)&&!(t<1))try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({stickyRoundRobinLimit:t})})).ok&&C(e=>({...e,stickyRoundRobinLimit:t}))}catch(e){console.error("Failed to update sticky limit:",e)}},eg=async e=>{let t=parseInt(e);if(!isNaN(t)&&!(t<1))try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({comboStickyRoundRobinLimit:t})})).ok&&C(e=>({...e,comboStickyRoundRobinLimit:t}))}catch(e){console.error("Failed to update combo sticky limit:",e)}},ey=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({requireLogin:e})})).ok&&C(t=>({...t,requireLogin:e}))}catch(e){console.error("Failed to update require login:",e)}},ef=(e,t)=>{$(s=>({...s,[e]:t}))},ej=async(e=A.authMode||"password")=>{let t=A.oidcIssuerUrl.trim(),s=A.oidcClientId.trim(),a=A.oidcScopes.trim(),r=A.oidcLoginLabel.trim(),o=q.trim();if("password"!==e&&(!t||!s||!o)&&!v.oidcConfigured)return void H({type:"error",message:"Issuer URL, client ID, and client secret are required to enable OIDC."});W(!0),H({type:"",message:""}),K({type:"",message:""});try{let l={authMode:e,oidcIssuerUrl:t,oidcClientId:s,oidcScopes:a||"openid profile email",oidcLoginLabel:r||"Sign in with OIDC"};o&&(l.oidcClientSecret=o);let i=await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)}),n=await i.json();i.ok?(C(e=>({...e,...n})),$({authMode:n?.authMode||e,oidcIssuerUrl:n?.oidcIssuerUrl||t,oidcClientId:n?.oidcClientId||s,oidcScopes:n?.oidcScopes||a||"openid profile email",oidcLoginLabel:n?.oidcLoginLabel||r||"Sign in with OIDC"}),F(""),H({type:"success",message:"oidc"===e?"OIDC login enabled":"both"===e?"Password and OIDC login enabled":"OIDC settings saved"})):H({type:"error",message:n.error||"Failed to save OIDC settings"})}catch(e){H({type:"error",message:"An error occurred"})}finally{W(!1)}},eN=async()=>{let e=A.oidcIssuerUrl.trim(),t=A.oidcClientId.trim(),s=A.oidcScopes.trim(),a=q.trim();if(!e||!t)return void K({type:"error",message:"Issuer URL and client ID are required to test the connection."});B(!0),H({type:"",message:""}),K({type:"",message:""});try{let r=await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({authMode:A.authMode||v.authMode||"password",oidcIssuerUrl:e,oidcClientId:t,oidcScopes:s||"openid profile email",oidcLoginLabel:A.oidcLoginLabel.trim()||"Sign in with OIDC",...a?{oidcClientSecret:a}:{}})}),o=await r.json().catch(()=>({}));if(!r.ok)return void K({type:"error",message:o.error||"Failed to save OIDC settings before testing"});let l=await fetch("/api/auth/oidc/test",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({issuerUrl:o.oidcIssuerUrl||e,clientId:o.oidcClientId||t,scopes:o.oidcScopes||s||"openid profile email"})}),i=await l.json().catch(()=>({}));if(l.ok&&i?.ok){let e=i.clientSecretTested?!0===i.clientSecretValid?`Connection OK. Discovery loaded from ${i.issuerUrl}. Client secret validated too.`:`Connection OK. Discovery loaded from ${i.issuerUrl}. Client secret was not checked.`:`Connection OK. Discovery loaded from ${i.issuerUrl}.`;K({type:"success",message:e})}else K({type:"error",message:i.error||"OIDC connection test failed"})}catch(e){K({type:"error",message:"An error occurred"})}finally{B(!1)}},ew=async e=>{try{(await fetch("/api/settings",{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({enableObservability:e})})).ok&&C(t=>({...t,enableObservability:e}))}catch(e){console.error("Failed to update enableObservability:",e)}},ev=async()=>{try{let e=await fetch("/api/settings");if(!e.ok)return;let t=await e.json();C(t)}catch(e){console.error("Failed to reload settings:",e)}},eC=async()=>{U(!0),E({type:"",message:""});try{let e=await fetch("/api/settings/database");if(!e.ok){let t=await e.json().catch(()=>({}));throw Error(t.error||"Failed to export database")}let t=await e.json(),s=JSON.stringify(t,null,2),a=new Blob([s],{type:"application/json"}),r=URL.createObjectURL(a),o=document.createElement("a"),l=new Date().toISOString().replace(/[.:]/g,"-");o.href=r,o.download=`zevairouter-backup-${l}.json`,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(r),E({type:"success",message:"Database backup downloaded"})}catch(e){E({type:"error",message:e.message||"Failed to export database"})}finally{U(!1)}},ek=async e=>{let t=e.target.files?.[0];if(t){U(!0),E({type:"",message:""});try{let e=await t.text(),s=JSON.parse(e),a=await fetch("/api/settings/database",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)}),r=await a.json().catch(()=>({}));if(!a.ok)throw Error(r.error||"Failed to import database");await ev(),E({type:"success",message:"Database imported successfully"})}catch(e){E({type:"error",message:e.message||"Invalid backup file"})}finally{X.current&&(X.current.value=""),U(!1)}}},eS=!0===v.enableObservability,eP=async()=>{w(!0);try{await fetch("/api/version/shutdown",{method:"POST"})}catch(e){}w(!1),j(!1)},eO=async()=>{try{(await fetch("/api/auth/logout",{method:"POST"})).ok&&(e.push("/login"),e.refresh())}catch(e){console.error("Failed to logout:",e)}};return(0,a.jsxs)("div",{className:"max-w-2xl mx-auto px-4 sm:px-0",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-6",children:[(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-4",children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 sm:gap-4",children:[(0,a.jsx)("div",{className:"size-10 sm:size-12 rounded-lg bg-green-500/10 text-green-500 flex items-center justify-center shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-xl sm:text-2xl",children:"computer"})}),(0,a.jsxs)("div",{children:[(0,a.jsx)("h2",{className:"text-lg sm:text-xl font-semibold",children:"Local Mode"}),(0,a.jsx)("p",{className:"text-sm text-text-muted",children:"Running on your machine"})]})]}),(0,a.jsx)("div",{className:"inline-flex p-1 rounded-lg bg-black/5 dark:bg-white/5 w-full sm:w-auto",children:["light","dark","system"].map(e=>(0,a.jsxs)("button",{type:"button",onClick:()=>s(e),className:(0,c.cn)("flex items-center justify-center gap-1 sm:gap-1.5 px-2 sm:px-3 py-1.5 rounded-md font-medium transition-all flex-1 sm:flex-initial",t===e?"bg-white dark:bg-white/10 text-text-main shadow-sm":"text-text-muted hover:text-text-main"),children:[(0,a.jsx)("span",{className:"material-symbols-outlined text-[18px]",children:"light"===e?"light_mode":"dark"===e?"dark_mode":"contrast"}),(0,a.jsx)("span",{className:"capitalize text-xs sm:text-sm",children:e})]},e))})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-3 pt-4 border-t border-border",children:[(0,a.jsx)("div",{className:"flex flex-col sm:flex-row sm:items-center sm:justify-between p-3 rounded-lg bg-bg border border-border gap-2",children:(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Database Location"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted font-mono break-all",children:"~/.zevai/db/data.sqlite"})]})}),(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row gap-2",children:[(0,a.jsx)(l.$n,{variant:"secondary",icon:"download",onClick:eC,loading:D,className:"w-full sm:w-auto",children:"Download Backup"}),(0,a.jsx)(l.$n,{variant:"outline",icon:"upload",onClick:()=>X.current?.click(),disabled:D,className:"w-full sm:w-auto",children:"Import Backup"}),(0,a.jsx)("input",{ref:X,type:"file",accept:"application/json,.json",className:"hidden",onChange:ek})]}),M.message&&(0,a.jsx)("p",{className:`text-sm ${"error"===M.type?"text-red-500":"text-green-600 dark:text-green-400"}`,children:M.message})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"size-10 rounded-lg bg-blue-500/10 text-blue-500 flex items-center justify-center shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"language"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Language"})]}),(0,a.jsxs)("button",{onClick:()=>y(!0),className:"flex items-center justify-between w-full p-3 rounded-lg bg-bg border border-border hover:border-primary/50 transition-colors","data-i18n-skip":"true",children:[(0,a.jsx)("span",{className:"text-sm text-text-muted",children:"Display language"}),(0,a.jsx)("span",{className:"text-2xl",children:u.h[h]||"\uD83C\uDF10"})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-primary/10 text-primary shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"shield"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Security"})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Require login"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"When ON, dashboard requires password. When OFF, access without login."})]}),(0,a.jsx)(l.lM,{checked:!0===v.requireLogin,onChange:()=>ey(!v.requireLogin),disabled:k})]}),!0===v.requireLogin&&(0,a.jsxs)("form",{onSubmit:em,className:"flex flex-col gap-4 pt-4 border-t border-border/50",children:[v.hasPassword&&(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"text-xs sm:text-sm font-medium",children:"Current Password"}),(0,a.jsx)(l.pd,{type:"password",placeholder:"Enter current password",value:P.current,onChange:e=>O({...P,current:e.target.value}),required:!0})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"text-xs sm:text-sm font-medium",children:"New Password"}),(0,a.jsx)(l.pd,{type:"password",placeholder:"Enter new password",value:P.new,onChange:e=>O({...P,new:e.target.value}),required:!0})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"text-xs sm:text-sm font-medium",children:"Confirm New Password"}),(0,a.jsx)(l.pd,{type:"password",placeholder:"Confirm new password",value:P.confirm,onChange:e=>O({...P,confirm:e.target.value}),required:!0})]})]}),I.message&&(0,a.jsx)("p",{className:`text-xs sm:text-sm ${"error"===I.type?"text-red-500":"text-green-500"}`,children:I.message}),(0,a.jsx)("div",{className:"pt-2",children:(0,a.jsx)(l.$n,{type:"submit",variant:"primary",loading:T,className:"w-full sm:w-auto",children:v.hasPassword?"Update Password":"Set Password"})})]})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("button",{type:"button",onClick:()=>Y(e=>!e),className:"w-full flex items-center gap-3 text-left",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-indigo-500/10 text-indigo-500 shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"lock_open"})}),(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"OIDC Dashboard Login"}),(0,a.jsx)("p",{className:"text-xs text-text-muted",children:"oidc"===v.authMode?"OIDC active":"both"===v.authMode?"Password + OIDC active":"Optional SSO via Authentik/Keycloak/Google"})]}),(0,a.jsx)("span",{className:"material-symbols-outlined text-text-muted shrink-0",children:G?"expand_less":"expand_more"})]}),G&&(0,a.jsxs)("div",{className:"flex flex-col gap-4 mt-4",children:[(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Use Authentik or any OIDC provider to sign in to the dashboard. You can enable password-only, OIDC-only, or both for the dashboard; model API access still uses API keys."}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Auth Mode"}),(0,a.jsx)("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-2",children:[{value:"password",title:"Password only",desc:"Keep the legacy password login."},{value:"oidc",title:"OIDC only",desc:"Require OIDC for dashboard access."},{value:"both",title:"Both",desc:"Allow either password or OIDC."}].map(e=>{let t=A.authMode===e.value;return(0,a.jsxs)("button",{type:"button",onClick:()=>ef("authMode",e.value),className:(0,c.cn)("text-left rounded-lg border p-3 transition-colors",t?"border-primary bg-primary/5":"border-border bg-bg hover:bg-black/5 dark:hover:bg-white/5"),disabled:k||_,children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:e.title}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted mt-1",children:e.desc})]},e.value)})})]}),(0,a.jsxs)("div",{className:"grid grid-cols-1 gap-4",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Issuer URL"}),(0,a.jsx)(l.pd,{placeholder:"https://auth.example.com/application/o/zevairouter/",value:A.oidcIssuerUrl,onChange:e=>ef("oidcIssuerUrl",e.target.value),disabled:k||_})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Client ID"}),(0,a.jsx)(l.pd,{placeholder:"zevairouter-dashboard",value:A.oidcClientId,onChange:e=>ef("oidcClientId",e.target.value),disabled:k||_})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Client Secret"}),(0,a.jsx)(l.pd,{type:"password",placeholder:"Leave blank to keep existing secret",value:q,onChange:e=>F(e.target.value),disabled:k||_}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"This value is write-only after saving."})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Scopes"}),(0,a.jsx)(l.pd,{placeholder:"openid profile email",value:A.oidcScopes,onChange:e=>ef("oidcScopes",e.target.value),disabled:k||_})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Login Button Label"}),(0,a.jsx)(l.pd,{placeholder:"Sign in with OIDC",value:A.oidcLoginLabel,onChange:e=>ef("oidcLoginLabel",e.target.value),disabled:k||_})]})]}),(0,a.jsxs)("div",{className:"rounded-lg border border-border bg-bg p-3 text-xs sm:text-sm text-text-muted",children:[(0,a.jsx)("p",{className:"font-medium text-text-main mb-1",children:"Redirect URI"}),(0,a.jsx)("code",{className:"block break-all font-mono",children:Q})]}),(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row gap-2 pt-2 border-t border-border/50",children:[(0,a.jsx)(l.$n,{type:"button",variant:"primary",loading:_,onClick:()=>ej(),className:"w-full sm:w-auto",children:"Save auth mode"}),(0,a.jsx)(l.$n,{type:"button",variant:"outline",loading:z,onClick:eN,className:"w-full sm:w-auto",children:"Test connection"})]}),Z.message&&(0,a.jsx)("p",{className:`text-xs sm:text-sm ${"error"===Z.type?"text-red-500":"text-green-500"}`,children:Z.message}),J.message&&(0,a.jsx)("p",{className:`text-xs sm:text-sm ${"error"===J.type?"text-red-500":"text-green-500"}`,children:J.message}),"oidc"===v.authMode&&(0,a.jsx)("p",{className:"text-xs sm:text-sm text-amber-600 dark:text-amber-400",children:"OIDC login is currently active. Password login is disabled until you switch back."}),"both"===v.authMode&&(0,a.jsx)("p",{className:"text-xs sm:text-sm text-amber-600 dark:text-amber-400",children:"Password and OIDC login are both active."})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-blue-500/10 text-blue-500 shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"route"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Routing Strategy"})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Round Robin"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Cycle through accounts to distribute load"})]}),(0,a.jsx)(l.lM,{checked:"round-robin"===v.fallbackStrategy,onChange:()=>ex("round-robin"===v.fallbackStrategy?"fill-first":"round-robin"),disabled:k})]}),"round-robin"===v.fallbackStrategy&&(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-2 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Sticky Limit"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Calls per account before switching"})]}),(0,a.jsx)(l.pd,{type:"number",min:"1",max:"10",value:v.stickyRoundRobinLimit||3,onChange:e=>eb(e.target.value),disabled:k,className:"w-16 sm:w-20 text-center shrink-0"})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-4 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Most Quota"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Pick the account with the most remaining quota (uses cached usage)"})]}),(0,a.jsx)(l.lM,{checked:"most-quota"===v.fallbackStrategy,onChange:()=>ex("most-quota"===v.fallbackStrategy?"fill-first":"most-quota"),disabled:k})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-4 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Lowest Latency"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Route to the fastest account by recent avg response time"})]}),(0,a.jsx)(l.lM,{checked:"lowest-latency"===v.fallbackStrategy,onChange:()=>ex("lowest-latency"===v.fallbackStrategy?"fill-first":"lowest-latency"),disabled:k})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-4 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Response Cache"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Serve identical non-streaming requests from memory (saves cost)"})]}),(0,a.jsx)(l.lM,{checked:!1!==v.responseCacheEnabled,onChange:()=>eu(!1===v.responseCacheEnabled),disabled:k})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-4 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Webhook Alerts"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Notify on provider down / quota exhausted (Discord, Telegram, or generic webhook)"})]}),(0,a.jsx)(l.lM,{checked:!0===v.alertEnabled,onChange:()=>ep({alertEnabled:!0!==v.alertEnabled}),disabled:k})]}),!0===v.alertEnabled&&(0,a.jsxs)("div",{className:"flex flex-col gap-3 pt-2 border-t border-border/50",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"text-xs text-text-muted block mb-1",children:"Webhook URL"}),(0,a.jsx)(l.pd,{type:"url",placeholder:"https://discord.com/api/webhooks/… or https://api.telegram.org/bot<token>/sendMessage",defaultValue:v.alertWebhookUrl||"",onBlur:e=>ep({alertWebhookUrl:e.target.value.trim()}),disabled:k})]}),(0,a.jsxs)("div",{className:"flex gap-3",children:[(0,a.jsxs)("div",{className:"flex-1",children:[(0,a.jsx)("label",{className:"text-xs text-text-muted block mb-1",children:"Type"}),(0,a.jsxs)("select",{defaultValue:v.alertWebhookType||"discord",onChange:e=>ep({alertWebhookType:e.target.value}),disabled:k,className:"w-full px-2 py-1.5 text-sm bg-transparent border border-border rounded",children:[(0,a.jsx)("option",{value:"discord",children:"Discord"}),(0,a.jsx)("option",{value:"telegram",children:"Telegram"}),(0,a.jsx)("option",{value:"generic",children:"Generic JSON"})]})]}),"telegram"===v.alertWebhookType&&(0,a.jsxs)("div",{className:"flex-1",children:[(0,a.jsx)("label",{className:"text-xs text-text-muted block mb-1",children:"Telegram Chat ID"}),(0,a.jsx)(l.pd,{type:"text",placeholder:"-1001234567890",defaultValue:v.alertTelegramChatId||"",onBlur:e=>ep({alertTelegramChatId:e.target.value.trim()}),disabled:k})]})]})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4 pt-4 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Combo Round Robin"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Cycle through providers in combos instead of always starting with first"})]}),(0,a.jsx)(l.lM,{checked:"round-robin"===v.comboStrategy,onChange:()=>eh("round-robin"===v.comboStrategy?"fallback":"round-robin"),disabled:k})]}),"round-robin"===v.comboStrategy&&(0,a.jsxs)("div",{className:"flex items-center justify-between pt-2 border-t border-border/50",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"font-medium",children:"Combo Sticky Limit"}),(0,a.jsx)("p",{className:"text-sm text-text-muted",children:"Calls per combo model before switching"})]}),(0,a.jsx)(l.pd,{type:"number",min:"1",max:"100",value:v.comboStickyRoundRobinLimit||1,onChange:e=>eg(e.target.value),disabled:k,className:"w-20 text-center"})]}),(0,a.jsxs)("p",{className:"text-xs text-text-muted italic pt-2 border-t border-border/50",children:["round-robin"===v.fallbackStrategy?`Currently distributing requests across all available accounts with ${v.stickyRoundRobinLimit||3} calls per account.`:"most-quota"===v.fallbackStrategy?"Currently routing to the account with the most remaining quota.":"lowest-latency"===v.fallbackStrategy?"Currently routing to the fastest account by recent avg latency.":"Currently using accounts in priority order (Fill First).","round-robin"===v.comboStrategy?` Combos rotate after ${v.comboStickyRoundRobinLimit||1} call${1===(v.comboStickyRoundRobinLimit||1)?"":"s"} per model.`:" Combos always start with their first model."]})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-purple-500/10 text-purple-500 shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"wifi"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Network"})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Outbound Proxy"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Enable proxy for OAuth + provider outbound requests."})]}),(0,a.jsx)(l.lM,{checked:!0===v.outboundProxyEnabled,onChange:()=>ec(!0!==v.outboundProxyEnabled),disabled:k||er})]}),!0===v.outboundProxyEnabled&&(0,a.jsxs)("form",{onSubmit:en,className:"flex flex-col gap-4 pt-2 border-t border-border/50",children:[(0,a.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"Proxy URL"}),(0,a.jsx)(l.pd,{placeholder:"http://127.0.0.1:7897",value:ee.outboundProxyUrl,onChange:e=>et(t=>({...t,outboundProxyUrl:e.target.value})),disabled:k||er}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Leave empty to inherit existing env proxy (if any)."})]}),(0,a.jsxs)("div",{className:"flex flex-col gap-2 pt-2 border-t border-border/50",children:[(0,a.jsx)("label",{className:"font-medium text-sm sm:text-base",children:"No Proxy"}),(0,a.jsx)(l.pd,{placeholder:"localhost,127.0.0.1",value:ee.outboundNoProxy,onChange:e=>et(t=>({...t,outboundNoProxy:e.target.value})),disabled:k||er}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Comma-separated hostnames/domains to bypass the proxy."})]}),(0,a.jsxs)("div",{className:"pt-2 border-t border-border/50 flex flex-col sm:flex-row items-stretch sm:items-center gap-2",children:[(0,a.jsx)(l.$n,{type:"button",variant:"secondary",loading:el,disabled:k||er,onClick:ed,className:"w-full sm:w-auto",children:"Test proxy URL"}),(0,a.jsx)(l.$n,{type:"submit",variant:"primary",loading:er,className:"w-full sm:w-auto",children:"Apply"})]})]}),es.message&&(0,a.jsx)("p",{className:`text-xs sm:text-sm ${"error"===es.type?"text-red-500":"text-green-500"} pt-2 border-t border-border/50`,children:es.message})]})]}),(0,a.jsxs)(l.Zp,{children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-4",children:[(0,a.jsx)("div",{className:"p-2 rounded-lg bg-orange-500/10 text-orange-500 shrink-0",children:(0,a.jsx)("span",{className:"material-symbols-outlined text-[20px]",children:"monitoring"})}),(0,a.jsx)("h3",{className:"text-base sm:text-lg font-semibold",children:"Observability"})]}),(0,a.jsxs)("div",{className:"flex items-start sm:items-center justify-between gap-4",children:[(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("p",{className:"font-medium text-sm sm:text-base",children:"Enable Observability"}),(0,a.jsx)("p",{className:"text-xs sm:text-sm text-text-muted",children:"Record request details for inspection in the logs view"})]}),(0,a.jsx)(l.lM,{checked:eS,onChange:ew,disabled:k})]})]}),(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row gap-2",children:[(0,a.jsx)(l.$n,{variant:"outline",fullWidth:!0,icon:"power_settings_new",onClick:()=>j(!0),className:"text-red-500 border-red-200 hover:bg-red-50 hover:border-red-300",children:"Shutdown"}),(0,a.jsx)(l.$n,{variant:"outline",fullWidth:!0,icon:"logout",onClick:eO,children:"Logout"})]}),(0,a.jsxs)("div",{className:"text-center text-xs sm:text-sm text-text-muted py-4",children:[(0,a.jsxs)("p",{children:[m.vQ.name," v",m.vQ.version]}),(0,a.jsx)("p",{className:"mt-1",children:"Local Mode - All data stored on your machine"})]})]}),(0,a.jsx)(n.default,{hideTrigger:!0,isOpen:g,onClose:e=>{y(!1),b(e)}}),(0,a.jsx)(i.ConfirmModal,{isOpen:f,onClose:()=>j(!1),onConfirm:eP,title:"Close Proxy",message:"Are you sure you want to close the proxy server?",confirmText:"Close",cancelText:"Cancel",variant:"danger",loading:N})]})}}},e=>{e.O(0,[2574,3862,4343,85,5497,8441,3794,7358],()=>e(e.s=52424)),_N_E=e.O()}]);