cartethyia 2.6.7 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/.env.example +106 -113
  2. package/dist/dashboard/assets/{BannedPage-Dskhyp0l.js → BannedPage-P76QLGJA.js} +1 -1
  3. package/dist/dashboard/assets/BannedPage-P76QLGJA.js.gz +0 -0
  4. package/dist/dashboard/assets/{CliToolDetailPage--SJhk7qQ.js → CliToolDetailPage-DdBggJS9.js} +1 -1
  5. package/dist/dashboard/assets/CliToolDetailPage-DdBggJS9.js.gz +0 -0
  6. package/dist/dashboard/assets/{CliToolsPage-C203VT-c.js → CliToolsPage-aN1iXhhP.js} +1 -1
  7. package/dist/dashboard/assets/CliToolsPage-aN1iXhhP.js.gz +0 -0
  8. package/dist/dashboard/assets/{CombosPage-BcS7kGG1.js → CombosPage-DE-F1nxZ.js} +1 -1
  9. package/dist/dashboard/assets/CombosPage-DE-F1nxZ.js.gz +0 -0
  10. package/dist/dashboard/assets/{ConsoleLogPage-ChmiSLwO.js → ConsoleLogPage-5SpmfLyw.js} +1 -1
  11. package/dist/dashboard/assets/ConsoleLogPage-5SpmfLyw.js.gz +0 -0
  12. package/dist/dashboard/assets/{CustomizationPage-uujbBYwC.js → CustomizationPage-3CUxMy2X.js} +1 -1
  13. package/dist/dashboard/assets/CustomizationPage-3CUxMy2X.js.gz +0 -0
  14. package/dist/dashboard/assets/{HealthEventsModal-fKAWd-OQ.js → HealthEventsModal-BkmJQKC0.js} +1 -1
  15. package/dist/dashboard/assets/HealthEventsModal-BkmJQKC0.js.gz +0 -0
  16. package/dist/dashboard/assets/{LoginPage-DoOUthbG.js → LoginPage-B_0FUKWc.js} +1 -1
  17. package/dist/dashboard/assets/LoginPage-B_0FUKWc.js.gz +0 -0
  18. package/dist/dashboard/assets/{ModelPicker-CA1kLs45.js → ModelPicker-DKVslqG3.js} +1 -1
  19. package/dist/dashboard/assets/ModelPicker-DKVslqG3.js.gz +0 -0
  20. package/dist/dashboard/assets/OverviewPage-D-H4MEiT.js +1 -0
  21. package/dist/dashboard/assets/OverviewPage-D-H4MEiT.js.gz +0 -0
  22. package/dist/dashboard/assets/{ProviderDetailPage-CFu1qGcT.js → ProviderDetailPage-CEJw6Guo.js} +3 -3
  23. package/dist/dashboard/assets/ProviderDetailPage-CEJw6Guo.js.gz +0 -0
  24. package/dist/dashboard/assets/{ProvidersPage-CnlJZbxF.js → ProvidersPage-CEplAR-i.js} +1 -1
  25. package/dist/dashboard/assets/ProvidersPage-CEplAR-i.js.gz +0 -0
  26. package/dist/dashboard/assets/{ProxyPage-B9mBTweh.js → ProxyPage-CAN7hy0f.js} +1 -1
  27. package/dist/dashboard/assets/ProxyPage-CAN7hy0f.js.gz +0 -0
  28. package/dist/dashboard/assets/{QuotaPage-BueSWX5D.js → QuotaPage-BjldQwIU.js} +1 -1
  29. package/dist/dashboard/assets/QuotaPage-BjldQwIU.js.gz +0 -0
  30. package/dist/dashboard/assets/SettingsPage-DUIoLRxk.js +1 -0
  31. package/dist/dashboard/assets/SettingsPage-DUIoLRxk.js.gz +0 -0
  32. package/dist/dashboard/assets/{SetupPage-DQ9oDRpi.js → SetupPage-_bCaTM0v.js} +1 -1
  33. package/dist/dashboard/assets/SetupPage-_bCaTM0v.js.gz +0 -0
  34. package/dist/dashboard/assets/{SortableList-DrKeMcGN.js → SortableList-fI7JkdIB.js} +1 -1
  35. package/dist/dashboard/assets/SortableList-fI7JkdIB.js.gz +0 -0
  36. package/dist/dashboard/assets/{StudioPage-qjuYtccc.js → StudioPage-CHVZqskZ.js} +1 -1
  37. package/dist/dashboard/assets/StudioPage-CHVZqskZ.js.gz +0 -0
  38. package/dist/dashboard/assets/UsagePage-DiFBymHj.js +56 -0
  39. package/dist/dashboard/assets/UsagePage-DiFBymHj.js.gz +0 -0
  40. package/dist/dashboard/assets/{api-keys-C23S9sgp.js → api-keys-DFY_fZU4.js} +1 -1
  41. package/dist/dashboard/assets/api-keys-DFY_fZU4.js.gz +0 -0
  42. package/dist/dashboard/assets/app-BOJ1_xUB.css +2 -0
  43. package/dist/dashboard/assets/app-BOJ1_xUB.css.gz +0 -0
  44. package/dist/dashboard/assets/{assert-DU6qrMA_.js → assert-CwdnZARt.js} +1 -1
  45. package/dist/dashboard/assets/assert-CwdnZARt.js.gz +0 -0
  46. package/dist/dashboard/assets/{badge-Bkz_-RrM.js → badge-Dr-uf0Au.js} +1 -1
  47. package/dist/dashboard/assets/badge-Dr-uf0Au.js.gz +0 -0
  48. package/dist/dashboard/assets/{banner-C-7y3VKV.js → banner-BddmMdoS.js} +1 -1
  49. package/dist/dashboard/assets/banner-BddmMdoS.js.gz +0 -0
  50. package/dist/dashboard/assets/{card-BOPBuBzD.js → card-CK0PXWlX.js} +1 -1
  51. package/dist/dashboard/assets/card-CK0PXWlX.js.gz +0 -0
  52. package/dist/dashboard/assets/{cli-tools-BaFUuFFF.js → cli-tools-CcB6mGh2.js} +1 -1
  53. package/dist/dashboard/assets/cli-tools-CcB6mGh2.js.gz +0 -0
  54. package/dist/dashboard/assets/{clipboard-button-e-Mlk0FH.js → clipboard-button-DGb2P9Yx.js} +1 -1
  55. package/dist/dashboard/assets/clipboard-button-DGb2P9Yx.js.gz +0 -0
  56. package/dist/dashboard/assets/{dialog-Iec_ywbD.js → dialog-LkfuL50u.js} +1 -1
  57. package/dist/dashboard/assets/dialog-LkfuL50u.js.gz +0 -0
  58. package/dist/dashboard/assets/{drawer-Bs8MIIHc.js → drawer-ZbEZ_84c.js} +1 -1
  59. package/dist/dashboard/assets/drawer-ZbEZ_84c.js.gz +0 -0
  60. package/dist/dashboard/assets/{entry-DcobaKFu.js → entry-BJfsVMvA.js} +1 -1
  61. package/dist/dashboard/assets/entry-BJfsVMvA.js.gz +0 -0
  62. package/dist/dashboard/assets/{entry-DOddwoc0.js → entry-CWBY5A0f.js} +3 -3
  63. package/dist/dashboard/assets/entry-CWBY5A0f.js.gz +0 -0
  64. package/dist/dashboard/assets/{entry-BRszm4_Z.js → entry-CvC1-Zqx.js} +1 -1
  65. package/dist/dashboard/assets/entry-CvC1-Zqx.js.gz +0 -0
  66. package/dist/dashboard/assets/{github-badge-BuDsrsPn.js → github-badge-BxpznFLt.js} +1 -1
  67. package/dist/dashboard/assets/github-badge-BxpznFLt.js.gz +0 -0
  68. package/dist/dashboard/assets/{index-BeLRhsmt.js → index-CDzP3ovJ.js} +2 -2
  69. package/dist/dashboard/assets/index-CDzP3ovJ.js.gz +0 -0
  70. package/dist/dashboard/assets/{inline-DToMICwl.js → inline-Ae13MQ5w.js} +1 -1
  71. package/dist/dashboard/assets/inline-Ae13MQ5w.js.gz +0 -0
  72. package/dist/dashboard/assets/{input-WlyHWeG2.js → input-D23fo7cp.js} +1 -1
  73. package/dist/dashboard/assets/input-D23fo7cp.js.gz +0 -0
  74. package/dist/dashboard/assets/{layout-DaJ5baJr.js → layout-CSsxjj5P.js} +1 -1
  75. package/dist/dashboard/assets/layout-CSsxjj5P.js.gz +0 -0
  76. package/dist/dashboard/assets/{list-row-B3oSK13z.js → list-row-dmbwZMDY.js} +1 -1
  77. package/dist/dashboard/assets/list-row-dmbwZMDY.js.gz +0 -0
  78. package/dist/dashboard/assets/{live-ta6GMb-8.js → live-BG1oUsZZ.js} +1 -1
  79. package/dist/dashboard/assets/live-BG1oUsZZ.js.gz +0 -0
  80. package/dist/dashboard/assets/minimize-2-D-MN8W8a.js +1 -0
  81. package/dist/dashboard/assets/minimize-2-D-MN8W8a.js.gz +0 -0
  82. package/dist/dashboard/assets/{mutation-g_fduiNw.js → mutation-DSF-e4ho.js} +1 -1
  83. package/dist/dashboard/assets/mutation-DSF-e4ho.js.gz +0 -0
  84. package/dist/dashboard/assets/{numbers-Dulqgys5.js → numbers-Bm_aECY7.js} +1 -1
  85. package/dist/dashboard/assets/{numbers-Dulqgys5.js.gz → numbers-Bm_aECY7.js.gz} +0 -0
  86. package/dist/dashboard/assets/{query-keys-UETqfytp.js → query-keys-CF56nYIV.js} +1 -1
  87. package/dist/dashboard/assets/query-keys-CF56nYIV.js.gz +0 -0
  88. package/dist/dashboard/assets/{routing-BPUo-W8d.js → routing-CeA71n7G.js} +1 -1
  89. package/dist/dashboard/assets/routing-CeA71n7G.js.gz +0 -0
  90. package/dist/dashboard/assets/{select-BfZ3SCTM.js → select-KIT0rC6G.js} +1 -1
  91. package/dist/dashboard/assets/select-KIT0rC6G.js.gz +0 -0
  92. package/dist/dashboard/assets/settings-B_2gkePf.js +1 -0
  93. package/dist/dashboard/assets/settings-B_2gkePf.js.gz +0 -0
  94. package/dist/dashboard/assets/{stack-B1w5BM0u.js → stack-D7WOSzcX.js} +1 -1
  95. package/dist/dashboard/assets/stack-D7WOSzcX.js.gz +0 -0
  96. package/dist/dashboard/assets/{state-DhZBfWgx.js → state-BBxtKZOQ.js} +1 -1
  97. package/dist/dashboard/assets/state-BBxtKZOQ.js.gz +0 -0
  98. package/dist/dashboard/assets/{switch-yD7D99Lg.js → switch-DNS_D5Ea.js} +1 -1
  99. package/dist/dashboard/assets/switch-DNS_D5Ea.js.gz +0 -0
  100. package/dist/dashboard/assets/{useMutation-EDFRkn1i.js → useMutation-BgoxdoMk.js} +1 -1
  101. package/dist/dashboard/assets/useMutation-BgoxdoMk.js.gz +0 -0
  102. package/dist/dashboard/index.html +1 -1
  103. package/dist/dashboard/index.html.gz +0 -0
  104. package/dist/dashboard/precompressed-assets.json +51 -51
  105. package/package.json +96 -96
  106. package/src/boot/app.ts +714 -722
  107. package/src/boot/dependencies.ts +729 -750
  108. package/src/config/resources.ts +70 -137
  109. package/src/config/security.ts +37 -73
  110. package/src/config/spec.ts +358 -378
  111. package/src/console/console-router.ts +225 -233
  112. package/src/console/domain-registration.ts +381 -391
  113. package/src/console/remote-support/contracts.ts +3 -1
  114. package/src/console/remote-support/service.ts +115 -6
  115. package/src/main.ts +167 -169
  116. package/src/observability/metrics.ts +467 -457
  117. package/src/observability/runtime-metrics.ts +269 -254
  118. package/src/protocol/gateway-error.ts +232 -233
  119. package/src/providers/integrations/commandcode/commandcode.ts +134 -104
  120. package/src/providers/integrations/commandcode/discovery.ts +6 -5
  121. package/src/providers/integrations/qoder/qoder.ts +597 -23
  122. package/src/security/abuse.ts +17 -0
  123. package/src/transport/guards/auth-guard.ts +109 -127
  124. package/src/transport/guards/pipeline.ts +220 -226
  125. package/src/transport/guards/request-context.ts +238 -318
  126. package/src/transport/request/inflight.ts +21 -2
  127. package/dist/dashboard/assets/BannedPage-Dskhyp0l.js.gz +0 -0
  128. package/dist/dashboard/assets/CliToolDetailPage--SJhk7qQ.js.gz +0 -0
  129. package/dist/dashboard/assets/CliToolsPage-C203VT-c.js.gz +0 -0
  130. package/dist/dashboard/assets/CombosPage-BcS7kGG1.js.gz +0 -0
  131. package/dist/dashboard/assets/ConsoleLogPage-ChmiSLwO.js.gz +0 -0
  132. package/dist/dashboard/assets/CustomizationPage-uujbBYwC.js.gz +0 -0
  133. package/dist/dashboard/assets/HealthEventsModal-fKAWd-OQ.js.gz +0 -0
  134. package/dist/dashboard/assets/LoginPage-DoOUthbG.js.gz +0 -0
  135. package/dist/dashboard/assets/ModelPicker-CA1kLs45.js.gz +0 -0
  136. package/dist/dashboard/assets/OverviewPage-C5Z-UBz1.js +0 -1
  137. package/dist/dashboard/assets/OverviewPage-C5Z-UBz1.js.gz +0 -0
  138. package/dist/dashboard/assets/ProviderDetailPage-CFu1qGcT.js.gz +0 -0
  139. package/dist/dashboard/assets/ProvidersPage-CnlJZbxF.js.gz +0 -0
  140. package/dist/dashboard/assets/ProxyPage-B9mBTweh.js.gz +0 -0
  141. package/dist/dashboard/assets/QuotaPage-BueSWX5D.js.gz +0 -0
  142. package/dist/dashboard/assets/SettingsPage-B0x00MVY.js +0 -1
  143. package/dist/dashboard/assets/SettingsPage-B0x00MVY.js.gz +0 -0
  144. package/dist/dashboard/assets/SetupPage-DQ9oDRpi.js.gz +0 -0
  145. package/dist/dashboard/assets/SortableList-DrKeMcGN.js.gz +0 -0
  146. package/dist/dashboard/assets/StudioPage-qjuYtccc.js.gz +0 -0
  147. package/dist/dashboard/assets/UsagePage-Be7aNviQ.js +0 -56
  148. package/dist/dashboard/assets/UsagePage-Be7aNviQ.js.gz +0 -0
  149. package/dist/dashboard/assets/api-keys-C23S9sgp.js.gz +0 -0
  150. package/dist/dashboard/assets/app-BUSiYL6F.css +0 -2
  151. package/dist/dashboard/assets/app-BUSiYL6F.css.gz +0 -0
  152. package/dist/dashboard/assets/assert-DU6qrMA_.js.gz +0 -0
  153. package/dist/dashboard/assets/badge-Bkz_-RrM.js.gz +0 -0
  154. package/dist/dashboard/assets/banner-C-7y3VKV.js.gz +0 -0
  155. package/dist/dashboard/assets/card-BOPBuBzD.js.gz +0 -0
  156. package/dist/dashboard/assets/cli-tools-BaFUuFFF.js.gz +0 -0
  157. package/dist/dashboard/assets/clipboard-button-e-Mlk0FH.js.gz +0 -0
  158. package/dist/dashboard/assets/dialog-Iec_ywbD.js.gz +0 -0
  159. package/dist/dashboard/assets/drawer-Bs8MIIHc.js.gz +0 -0
  160. package/dist/dashboard/assets/entry-BRszm4_Z.js.gz +0 -0
  161. package/dist/dashboard/assets/entry-DOddwoc0.js.gz +0 -0
  162. package/dist/dashboard/assets/entry-DcobaKFu.js.gz +0 -0
  163. package/dist/dashboard/assets/github-badge-BuDsrsPn.js.gz +0 -0
  164. package/dist/dashboard/assets/index-BeLRhsmt.js.gz +0 -0
  165. package/dist/dashboard/assets/inline-DToMICwl.js.gz +0 -0
  166. package/dist/dashboard/assets/input-WlyHWeG2.js.gz +0 -0
  167. package/dist/dashboard/assets/layout-DaJ5baJr.js.gz +0 -0
  168. package/dist/dashboard/assets/list-row-B3oSK13z.js.gz +0 -0
  169. package/dist/dashboard/assets/live-ta6GMb-8.js.gz +0 -0
  170. package/dist/dashboard/assets/model-bans-BmYTmbAk.js +0 -1
  171. package/dist/dashboard/assets/model-bans-BmYTmbAk.js.gz +0 -0
  172. package/dist/dashboard/assets/mutation-g_fduiNw.js.gz +0 -0
  173. package/dist/dashboard/assets/query-keys-UETqfytp.js.gz +0 -0
  174. package/dist/dashboard/assets/routing-BPUo-W8d.js.gz +0 -0
  175. package/dist/dashboard/assets/select-BfZ3SCTM.js.gz +0 -0
  176. package/dist/dashboard/assets/settings--3hxSyry.js +0 -1
  177. package/dist/dashboard/assets/settings--3hxSyry.js.gz +0 -0
  178. package/dist/dashboard/assets/stack-B1w5BM0u.js.gz +0 -0
  179. package/dist/dashboard/assets/state-DhZBfWgx.js.gz +0 -0
  180. package/dist/dashboard/assets/switch-yD7D99Lg.js.gz +0 -0
  181. package/dist/dashboard/assets/useMutation-EDFRkn1i.js.gz +0 -0
  182. package/src/console/admin/model-abuse/contracts.ts +0 -38
  183. package/src/console/admin/model-abuse/routes.ts +0 -97
  184. package/src/security/model-abuse.ts +0 -704
  185. package/src/transport/guards/concurrency-guard.ts +0 -125
  186. /package/dist/dashboard/assets/{app-MdVfwraB.js → app-CaXZ9SCn.js} +0 -0
  187. /package/dist/dashboard/assets/{app-MdVfwraB.js.gz → app-CaXZ9SCn.js.gz} +0 -0
@@ -1 +0,0 @@
1
- import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{n as i}from"./terminal-0_IjPWTk.js";import{a,i as o,n as s,r as c}from"./model-bans-BmYTmbAk.js";import{n as l,r as u,t as d}from"./concurrency-BDF0ok7y.js";import{C as f,E as p,O as m,T as h,c as g,s as _,v,x as y}from"./numbers-Dulqgys5.js";import{t as ee}from"./chevron-right-BXIy5l3h.js";import{t as b}from"./SortableList-DrKeMcGN.js";import{t as x}from"./database-Dz9N3zGd.js";import{t as S}from"./eye-off-Bk5g2luF.js";import{t as C}from"./eye-C_hawfH4.js";import{t as te}from"./gauge-BbIMy7MB.js";import{n as w,r as T,t as E}from"./state-DhZBfWgx.js";import{t as D}from"./key-round-UkavsGxp.js";import{n as ne,r as re,t as O}from"./clipboard-button-e-Mlk0FH.js";import{t as k}from"./dialog-Iec_ywbD.js";import{t as A}from"./pencil-768ysRAr.js";import{t as j}from"./plus-DIdX_g-x.js";import{t as M}from"./power-off-Yjw9GMJh.js";import{t as ie}from"./refresh-cw-BqJFk4sU.js";import{t as N}from"./route-CNSNj9Zm.js";import{t as ae}from"./search-JOKus9rb.js";import{t as oe}from"./shield-check-DVS0Foqh.js";import{n as P,r as se,t as F}from"./settings--3hxSyry.js";import{t as ce}from"./trash-Cppn5c3R.js";import{C as le,T as ue,b as de,x as fe}from"./assert-DU6qrMA_.js";import{l as I,o as pe,t as L}from"./query-keys-UETqfytp.js";import{t as me}from"./useMutation-EDFRkn1i.js";import{it as he,j as ge,lt as _e,ot as ve,z as ye}from"./entry-DOddwoc0.js";import{n as R,r as z,t as B}from"./card-BOPBuBzD.js";import{t as V}from"./use-clipboard-B0Sy03fE.js";import{n as be}from"./download-dRFo5_Wu.js";import{c as H,d as U}from"./tokens-COzario9.js";import{t as W}from"./badge-Bkz_-RrM.js";import{n as G,t as xe}from"./input-WlyHWeG2.js";import{t as Se}from"./select-BfZ3SCTM.js";import{t as Ce}from"./ModelPicker-CA1kLs45.js";import{t as K}from"./switch-yD7D99Lg.js";import{t as q}from"./stack-B1w5BM0u.js";import{n as J}from"./inline-DToMICwl.js";import{a as we,c as Y,d as Te,f as Ee,i as X,l as Z,n as De,o as Oe,r as ke,s as Ae,t as je,u as Me}from"./api-keys-C23S9sgp.js";import{a as Ne,i as Pe,n as Fe,r as Ie}from"./cli-tools-BaFUuFFF.js";import{t as Le}from"./layout-DaJ5baJr.js";import{s as Re}from"./quota-DZGyp0N5.js";var ze=e(`lock-keyhole`,[[`circle`,{cx:`12`,cy:`16`,r:`1`,key:`1au0dj`}],[`rect`,{x:`3`,y:`10`,width:`18`,height:`12`,rx:`2`,key:`6s8ecr`}],[`path`,{d:`M7 10V7a5 5 0 0 1 10 0v3`,key:`1pqi11`}]]),Be=e(`radio-tower`,[[`path`,{d:`M4.9 16.1C1 12.2 1 5.8 4.9 1.9`,key:`s0qx1y`}],[`path`,{d:`M7.8 4.7a6.14 6.14 0 0 0-.8 7.5`,key:`1idnkw`}],[`circle`,{cx:`12`,cy:`9`,r:`2`,key:`1092wv`}],[`path`,{d:`M16.2 4.8c2 2 2.26 5.11.8 7.47`,key:`ojru2q`}],[`path`,{d:`M19.1 1.9a9.96 9.96 0 0 1 0 14.1`,key:`rhi7fg`}],[`path`,{d:`M9.5 18h5`,key:`mfy3pd`}],[`path`,{d:`m8 22 4-11 4 11`,key:`25yftu`}]]),Ve=e(`repeat-2`,[[`path`,{d:`m2 9 3-3 3 3`,key:`1ltn5i`}],[`path`,{d:`M13 18H7a2 2 0 0 1-2-2V6`,key:`1r6tfw`}],[`path`,{d:`m22 15-3 3-3-3`,key:`4rnwn2`}],[`path`,{d:`M11 6h6a2 2 0 0 1 2 2v10`,key:`2f72bc`}]]),He=e(`rotate-cw`,[[`path`,{d:`M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8`,key:`1p45f6`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}]]),Ue=e(`scissors`,[[`circle`,{cx:`6`,cy:`6`,r:`3`,key:`1lh9wr`}],[`path`,{d:`M8.12 8.12 12 12`,key:`1alkpv`}],[`path`,{d:`M20 4 8.12 15.88`,key:`xgtan2`}],[`circle`,{cx:`6`,cy:`18`,r:`3`,key:`fqmcym`}],[`path`,{d:`M14.8 14.8 20 20`,key:`ptml3r`}]]),We=e(`share-2`,[[`circle`,{cx:`18`,cy:`5`,r:`3`,key:`gq8acd`}],[`circle`,{cx:`6`,cy:`12`,r:`3`,key:`w7nqdw`}],[`circle`,{cx:`18`,cy:`19`,r:`3`,key:`1xt0gg`}],[`line`,{x1:`8.59`,x2:`15.42`,y1:`13.51`,y2:`17.49`,key:`47mynk`}],[`line`,{x1:`15.41`,x2:`8.59`,y1:`6.51`,y2:`10.49`,key:`1n3mei`}]]),Ge=e(`shield-off`,[[`path`,{d:`m2 2 20 20`,key:`1ooewy`}],[`path`,{d:`M5 5a1 1 0 0 0-1 1v7c0 5 3.5 7.5 7.67 8.94a1 1 0 0 0 .67.01c2.35-.82 4.48-1.97 5.9-3.71`,key:`1jlk70`}],[`path`,{d:`M9.309 3.652A12.252 12.252 0 0 0 11.24 2.28a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1v7a9.784 9.784 0 0 1-.08 1.264`,key:`18rp1v`}]]),Ke=e(`shield-x`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}],[`path`,{d:`m14.5 9.5-5 5`,key:`17q4r4`}],[`path`,{d:`m9.5 9.5 5 5`,key:`18nt4w`}]]),qe=e(`undo-2`,[[`path`,{d:`M9 14 4 9l5-5`,key:`102s5s`}],[`path`,{d:`M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11`,key:`f3b9sd`}]]),Je=e(`user-round`,[[`circle`,{cx:`12`,cy:`8`,r:`5`,key:`1hypcn`}],[`path`,{d:`M20 21a8 8 0 0 0-16 0`,key:`rfgkzh`}]]),Ye=e(`users-round`,[[`path`,{d:`M18 21a8 8 0 0 0-16 0`,key:`3ypg7q`}],[`circle`,{cx:`10`,cy:`8`,r:`5`,key:`o932ke`}],[`path`,{d:`M22 20c0-3.37-2-6.5-4-8a5 5 0 0 0-.45-8.3`,key:`10s06x`}]]),Xe=[`routing:invoke`,`routing:cli_mapping`,`search:invoke`,`dashboard:read`,`dashboard:write`,`providers:read`,`providers:write`,`models:read`,`models:write`],Ze=[`image/png`,`image/jpeg`,`image/webp`,`image/gif`],Q=t(n(),1),$=r(),Qe={"routing:invoke":`Call /v1/* gateway routes within this tenant.`,"routing:cli_mapping":`Resolve persisted CLI source→target model mappings.`,"search:invoke":`Call POST /v1/search with exa.`,"dashboard:read":`Read this tenant's configuration and usage.`,"dashboard:write":`Modify this tenant's configuration.`,"providers:read":`Read provider rows, including accounts.`,"providers:write":`Add, modify, or delete provider rows and their credentials.`,"models:read":`Read catalog model rows.`,"models:write":`Add, modify, or delete catalog model rows.`},$e={"routing:invoke":N,"routing:cli_mapping":N,"search:invoke":ae,"dashboard:read":C,"dashboard:write":A,"providers:read":he,"providers:write":ze,"models:read":u,"models:write":x},et={k:1e3,m:1e6,b:1e9,t:0xe8d4a51000},tt=[{label:`1M`,amount:1e6,description:`1 million`},{label:`100M`,amount:1e8,description:`100 million`},{label:`1B`,amount:1e9,description:`1 billion`},{label:`1T`,amount:0xe8d4a51000,description:`1 trillion`}];function nt(e){let t=e.trim().toLowerCase();if(!t)return;let n=t.match(/^([\d.]+)\s*([kmbt])?$/);if(!n)return;let r=Number(n[1]);if(!Number.isFinite(r)||r<=0)return;let i=n[2]?et[n[2]]??1:1;return Math.round(r*i)}function rt(e){if(e==null)return``;let t=tt.find(t=>t.amount===e);return t?t.label:e>=1e9?`${(e/1e9).toFixed(1).replace(/\.0$/,``)}B`:e>=1e6?`${(e/1e6).toFixed(1).replace(/\.0$/,``)}M`:e>=1e3?`${(e/1e3).toFixed(1).replace(/\.0$/,``)}K`:String(e)}function it(e){let t=Number(e.trim());return Number.isFinite(t)&&t>0?Math.round(t):void 0}function at(e){let t=it(e);return e.trim()===``?null:t}function ot({label:e,value:t,onChange:n,disabled:r}){let i=nt(t),a=tt.find(e=>e.amount===i)?.label;return(0,$.jsxs)(`div`,{children:[(0,$.jsx)(G,{label:e,value:t,onChange:e=>n(e.target.value),placeholder:`e.g. 1M, 500K`,disabled:r}),(0,$.jsx)(`div`,{className:`flex flex-wrap gap-2 mt-2`,role:`group`,"aria-label":`${e} presets`,children:tt.map(e=>(0,$.jsx)(`button`,{type:`button`,"aria-pressed":a===e.label,"aria-label":`${e.label}, ${e.description} tokens`,onClick:()=>n(e.label),disabled:r,className:`py-0.5 px-3 rounded-chip text-micro font-semibold`,style:{cursor:r?`not-allowed`:`pointer`,border:`1px solid ${a===e.label?`var(--accent)`:`var(--inner-border)`}`,background:a===e.label?`var(--accent-soft)`:`transparent`,color:a===e.label?`var(--accent)`:`var(--text-tertiary)`},children:e.label},e.label))})]})}function st({tool:e,keyId:t,busy:n,scopeGranted:r,onScopeChange:i}){let a=Pe(e.id,t),o=Ie(),s=Fe(),c=a.data?.enabled??!1,l=r&&c,u=a.data?.mappings.length??0,d=o.isPending||s.isPending;return(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-4 py-1.5 px-4 rounded-inset`,style:{minHeight:`38px`,border:`1px solid var(--inner-border)`,background:l?`var(--accent-soft)`:`var(--surface-1)`},children:[(0,$.jsxs)(`div`,{className:`flex min-w-0 items-start gap-3`,children:[(0,$.jsx)(N,{size:16,className:`mt-1 shrink-0 text-accent`,"aria-hidden":`true`}),(0,$.jsxs)(`div`,{className:`min-w-0`,children:[(0,$.jsx)(`div`,{className:`text-caption font-semibold text-text-primary`,children:e.name}),(0,$.jsx)(`p`,{className:`mt-1 text-badge text-text-tertiary`,children:l?`Remote routing on — ${u} route${u===1?``:`s`} active, routing:cli_mapping granted.`:`Remote routing off — this key's requests go straight to the provider.`})]})]}),(0,$.jsxs)(`div`,{className:`flex items-center gap-4`,children:[(0,$.jsx)(K,{checked:l,disabled:n||d||a.isLoading,"aria-label":`Enable remote routing for ${e.name}`,onChange:n=>{n!==r&&i(n),o.mutate({toolId:e.id,keyId:t,input:{enabled:n,mappings:a.data?.mappings??[]}},{onSuccess:()=>_.success(`Saved remote routing for ${e.name}.`),onError:e=>_.error(I(e,`Could not save remote routing.`))})}}),(0,$.jsx)(g,{variant:`secondary`,size:`sm`,disabled:n||d||!c&&u===0,onClick:()=>s.mutate({toolId:e.id,keyId:t},{onSuccess:()=>_.success(`Cleared remote routes for ${e.name}.`),onError:e=>_.error(I(e,`Could not reset remote routes.`))}),children:s.isPending?`Resetting…`:`Reset`})]})]})}function ct({keyId:e,busy:t,scopeGranted:n,onScopeChange:r,persistScope:i}){let a=(Ne().data??[]).filter(e=>e.mappingSupported);return(0,$.jsxs)(`section`,{"aria-labelledby":`remote-routing-heading`,className:`flex flex-col gap-3`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsxs)(`h4`,{id:`remote-routing-heading`,className:`inline-flex items-center gap-2 text-caption font-bold text-text-primary`,children:[(0,$.jsx)(N,{size:15,className:`text-accent`,"aria-hidden":`true`}),`Remote routing`]}),(0,$.jsx)(`p`,{className:`mt-1 text-badge text-text-tertiary`,children:`Route this key's CLI model calls through persisted mappings and grant routing:cli_mapping. Applies immediately — no save needed.`})]}),e.length===0?(0,$.jsx)(`p`,{className:`text-badge text-text-tertiary m-0`,children:`Save the key first to configure per-tool remote routing mappings.`}):a.length===0?(0,$.jsx)(`p`,{className:`text-badge text-text-tertiary m-0`,children:`No CLI tools with mapping support are currently registered.`}):(0,$.jsx)(`div`,{className:`flex flex-col gap-3`,children:a.map(a=>(0,$.jsx)(st,{tool:a,keyId:e,busy:t,scopeGranted:n,onScopeChange:e=>{r(e),i(e)}},a.id))})]})}function lt(e,t,n){let r=e===`personal`?t.trim():``;return{keyMode:e,keyPrefix:n.trim()||void 0,...r?{key:r}:{}}}function ut(e,t){return e===`personal`?t??null:null}function dt(e){let t=e?.scopes;return e?.isDefault?t&&t.length>0?[...t]:[...Xe]:t&&t.length>0?[...t]:[`routing:invoke`,`search:invoke`]}function ft({mode:e,record:t,busy:n,onDone:r,onClose:i,actionsRef:o}){let[s,c]=(0,Q.useState)(t?.label??``),[d,f]=(0,Q.useState)(t?.keyPrefix??``),[p,m]=(0,Q.useState)(``),[h,v]=(0,Q.useState)(t?.requestsPerMinute?.toString()??``),[y,ee]=(0,Q.useState)(rt(t?.dailyTokenLimit??null)),[b,x]=(0,Q.useState)(rt(t?.monthlyTokenLimit??null)),[S,C]=(0,Q.useState)(rt(t?.lifetimeTokenBudget??null)),[w,T]=(0,Q.useState)(t?.lifetimeTokenBudget==null?`recurring`:`one-time`),[E,re]=(0,Q.useState)(t?.maxConcurrentRequests?.toString()??``),[O,k]=(0,Q.useState)(()=>dt(t)),[A,j]=(0,Q.useState)(t?.modelAccessMode??`whitelist`),[M,ie]=(0,Q.useState)(()=>{let e=t?.modelList;return e?[...e]:[]}),[ae,P]=(0,Q.useState)(!1),[F,ce]=(0,Q.useState)(()=>{let e=t?.clientRouterDenylist;return e?[...new Set(e.map(fe).filter(e=>e!==void 0))]:[]}),[le,ue]=(0,Q.useState)(()=>t?.notesTitle??``),[pe,L]=(0,Q.useState)(()=>t?.notesSubtitle??``),[me,he]=(0,Q.useState)(()=>t?.notesBody??``),[ge,ye]=(0,Q.useState)(t?.sharePopupEnabled??!0),[R,z]=(0,Q.useState)(null),[B,V]=(0,Q.useState)(!1),[be,H]=(0,Q.useState)(null),U=t?.sharePopupImageMime!==void 0,W=R??(U&&!B&&t!==null?`/console/api/api-keys/${t.id}/share-popup-image`:null);(0,Q.useEffect)(()=>{U||R!==null||B||fetch(`/donation/qris-risun-marke.png`).then(e=>e.ok?e.blob():Promise.reject(e.status)).then(e=>{let{promise:t,resolve:n,reject:r}=Promise.withResolvers(),i=new FileReader;return i.onload=()=>n(i.result),i.onerror=r,i.readAsDataURL(e),t}).then(e=>z(e)).catch(()=>{})},[]);let[Se,q]=(0,Q.useState)(t?.sharePopupTitle??`Support via QRIS`),[J,we]=(0,Q.useState)(t?.sharePopupBody??`Scan the QR code above with any QRIS-compatible banking or e-wallet app to support this gateway's upkeep. Every contribution helps keep the service running — thank you! 🙏`),[Y,Te]=(0,Q.useState)(t?.keyMode??`personal`),X=w===`one-time`,Z=e===`edit`,De=Ee(),Oe=e=>k(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e]),ke=()=>{r({label:s.trim(),...lt(Y,p,d),scopes:O,modelAccessMode:A,modelList:M,clientRouterDenylist:F,requestsPerMinute:at(h),maxConcurrentRequests:at(E),dailyTokenLimit:X?null:nt(y)??null,monthlyTokenLimit:X?null:nt(b)??null,lifetimeTokenBudget:X?nt(S)??null:null,notesTitle:le.trim(),notesSubtitle:pe.trim(),notesBody:me.trim(),sharePopupEnabled:ge,...R===null?B?{sharePopupImage:null}:{}:{sharePopupImage:R},sharePopupTitle:Se.trim(),sharePopupBody:J.trim()})};return(0,Q.useEffect)(()=>{o?.((0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:i,disabled:n,children:`Cancel`}),(0,$.jsx)(g,{variant:`primary`,size:`sm`,disabled:n||e===`create`&&!s.trim(),onClick:ke,children:n?`Saving…`:e===`create`?`Create API key`:`Save changes`})]}))}),(0,$.jsxs)(`div`,{className:`flex flex-col gap-3 min-w-0 pb-2`,children:[(0,$.jsxs)(`section`,{className:`flex flex-col gap-3 min-w-0 p-4 border border-inner-border rounded-card bg-surface-2 col-span-full`,children:[(0,$.jsxs)(`h3`,{className:`inline-flex items-center gap-2 text-caption font-bold text-text-primary`,children:[(0,$.jsx)(D,{size:16,className:`text-accent`,"aria-hidden":`true`}),`Credential mode`]}),(0,$.jsx)(`div`,{role:`group`,"aria-label":`Credential mode`,className:`flex gap-4`,children:[`personal`,`share`].map(e=>(0,$.jsx)(`button`,{type:`button`,"aria-pressed":Y===e,disabled:n||Z,onClick:()=>Te(e),title:Z?`Credential mode cannot change after creation`:void 0,className:`rounded-inset py-1.5 px-5`,style:{border:`1px solid var(--inner-border)`,color:Y===e?`var(--accent)`:`var(--text-secondary)`,background:Y===e?`var(--accent-soft)`:`var(--surface-2)`,cursor:Z?`not-allowed`:`pointer`,opacity:Z&&Y!==e?.5:1},children:(0,$.jsxs)(`span`,{className:`inline-flex items-center gap-2`,children:[e===`personal`?(0,$.jsx)(Je,{size:14,"aria-hidden":`true`}):(0,$.jsx)(Ye,{size:14,"aria-hidden":`true`}),e===`personal`?`Personal`:`Share template`]})},e))}),(0,$.jsx)(`p`,{className:`mt-1 text-badge text-text-tertiary`,children:Y===`share`?`A share template does not authenticate requests. Recipients generate their own child key from its public enrollment page.`:`A personal key authenticates requests directly; its secret is shown once when created or rotated.`})]}),(0,$.jsxs)(`div`,{className:`grid grid-cols-2 gap-3 min-w-0 max-medium:grid-cols-1`,children:[e===`create`&&(0,$.jsxs)(`section`,{className:`flex flex-col gap-3 min-w-0 p-4 border border-inner-border rounded-card bg-surface-2`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsxs)(`h3`,{className:`inline-flex items-center gap-2 text-caption font-bold text-text-primary`,children:[(0,$.jsx)(l,{size:16,className:`text-accent`,"aria-hidden":`true`}),`Identity`]}),(0,$.jsx)(`p`,{className:`mt-1 text-badge text-text-tertiary`,children:`Give this credential a recognizable name.`})]}),(0,$.jsxs)(`div`,{className:`grid grid-cols-2 gap-4 items-start min-w-0 max-medium:grid-cols-1`,children:[(0,$.jsx)(G,{label:`Name`,value:s,onChange:e=>c(e.target.value),placeholder:`ci-key…`,disabled:n,autoFocus:!0}),(0,$.jsx)(G,{label:`Key prefix`,value:d,onChange:e=>f(e.target.value),placeholder:`pn-carte- (default)…`,disabled:n||p.trim().length>0})]}),Y===`personal`&&(0,$.jsx)(G,{label:`Custom API key value (optional)`,value:p,onChange:e=>m(e.target.value),placeholder:`Leave blank to generate…`,disabled:n})]}),e===`edit`&&(0,$.jsxs)(`section`,{className:`flex flex-col gap-3 min-w-0 p-4 border border-inner-border rounded-card bg-surface-2`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsxs)(`h3`,{className:`text-caption font-bold text-text-primary`,children:[(0,$.jsx)(l,{size:16,className:`mr-2 inline text-accent`,"aria-hidden":`true`}),`Identity`]}),(0,$.jsx)(`p`,{className:`mt-1 text-badge text-text-tertiary`,children:t?.isDefault?`The default key's name is fixed. Limits, access, and everything else can still change.`:`Update the label for this credential.`})]}),(0,$.jsx)(`div`,{className:`grid grid-cols-2 gap-4 items-start min-w-0 max-medium:grid-cols-1`,children:(0,$.jsx)(G,{label:`Name`,value:s,onChange:e=>c(e.target.value),placeholder:`ci-key…`,disabled:n||t?.isDefault===!0,title:t?.isDefault?`The default gateway key keeps its name`:void 0,autoFocus:!0})})]}),(0,$.jsxs)(`section`,{className:`flex flex-col gap-3 min-w-0 p-4 border border-inner-border rounded-card bg-surface-2`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsxs)(`h3`,{className:`text-caption font-bold text-text-primary`,children:[(0,$.jsx)(ne,{size:16,className:`mr-2 inline text-accent`,"aria-hidden":`true`}),`Share notes`]}),(0,$.jsx)(`p`,{className:`mt-1 text-badge text-text-tertiary`,children:`Optional copy shown on the public share page.`})]}),(0,$.jsxs)(`div`,{className:`grid grid-cols-2 gap-4 items-start min-w-0 max-medium:grid-cols-1`,children:[(0,$.jsx)(G,{label:`Title`,value:le,onChange:e=>ue(e.target.value),placeholder:`e.g. Bansos Token`,disabled:n}),(0,$.jsx)(G,{label:`Subtitle`,value:pe,onChange:e=>L(e.target.value),placeholder:`e.g. Come and save your tokens`,disabled:n}),(0,$.jsx)(`div`,{className:`col-span-full`,children:(0,$.jsx)(G,{label:`Body`,value:me,onChange:e=>he(e.target.value),placeholder:`Free-form notes for the recipient`,disabled:n})})]})]}),(0,$.jsxs)(`section`,{className:`flex flex-col gap-3 min-w-0 p-4 border border-inner-border rounded-card bg-surface-2 col-span-full`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsxs)(`h3`,{className:`text-caption font-bold text-text-primary`,children:[(0,$.jsx)(te,{size:16,className:`mr-2 inline text-accent`,"aria-hidden":`true`}),`Limits`]}),(0,$.jsx)(`p`,{className:`mt-1 text-badge text-text-tertiary`,children:`Keep this credential predictable under load.`})]}),(0,$.jsxs)(`div`,{className:`grid grid-cols-2 gap-4 items-start min-w-0 max-medium:grid-cols-1`,children:[(0,$.jsx)(G,{label:`Requests per minute`,type:`number`,min:`0`,value:h,onChange:e=>v(e.target.value),placeholder:`Unlimited…`,disabled:n}),(0,$.jsx)(G,{label:`Max concurrent requests`,type:`number`,min:`0`,value:E,onChange:e=>re(e.target.value),placeholder:`Unlimited…`,disabled:n})]}),(0,$.jsx)(`p`,{className:`text-micro leading-normal text-text-tertiary`,children:E===``?`No concurrency limit, so the tenant allowance does nothing.`:`Limit ${E} concurrent. Refusals name this number; the allowance above it is tenant-wide and set in Settings.`}),(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-4 rounded-panel border border-inner-border px-4 py-3 bg-surface-2`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsxs)(`div`,{className:`text-caption font-bold text-text-primary`,children:[(0,$.jsx)(te,{size:14,className:`mr-2 inline text-accent`,"aria-hidden":`true`}),`Token budget`]}),(0,$.jsx)(`p`,{className:`mt-1 text-text-tertiary text-micro`,children:X?`One-time cap; it does not reset.`:`Daily and monthly limits reset automatically.`})]}),(0,$.jsxs)(`div`,{className:`flex gap-2 rounded-inset border border-inner-border bg-surface-1 p-1`,children:[(0,$.jsx)(`button`,{type:`button`,onClick:()=>T(`recurring`),disabled:n,className:`py-1.5 px-4 rounded-chip font-semibold border-0 cursor-pointer`,style:{fontSize:`10px`,background:X?`transparent`:`var(--accent-soft)`,color:X?`var(--text-tertiary)`:`var(--accent)`},children:(0,$.jsxs)(`span`,{className:`inline-flex items-center gap-2`,children:[(0,$.jsx)(Ve,{size:13,"aria-hidden":`true`}),`Recurring`]})}),(0,$.jsx)(`button`,{type:`button`,onClick:()=>T(`one-time`),disabled:n,className:`py-1.5 px-4 rounded-chip font-semibold border-0 cursor-pointer`,style:{fontSize:`10px`,background:X?`var(--accent-soft)`:`transparent`,color:X?`var(--accent)`:`var(--text-tertiary)`},children:(0,$.jsxs)(`span`,{className:`inline-flex items-center gap-2`,children:[(0,$.jsx)(ze,{size:13,"aria-hidden":`true`}),`One-time`]})})]})]}),X?(0,$.jsx)(ot,{label:`One-time token limit`,value:S,onChange:C,disabled:n}):(0,$.jsxs)(`div`,{className:`grid grid-cols-2 gap-4 items-start min-w-0 max-medium:grid-cols-1`,children:[(0,$.jsx)(ot,{label:`Daily token limit`,value:y,onChange:ee,disabled:n}),(0,$.jsx)(ot,{label:`Monthly token limit`,value:b,onChange:x,disabled:n})]})]})]}),(0,$.jsxs)(`section`,{className:`flex flex-col gap-3 min-w-0 p-4 border border-inner-border rounded-card bg-surface-2 col-span-full`,"aria-labelledby":`share-popup-heading`,children:[(0,$.jsxs)(`div`,{className:`flex items-start justify-between gap-6`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsxs)(`h3`,{id:`share-popup-heading`,className:`text-caption font-bold text-text-primary`,children:[(0,$.jsx)(We,{size:16,className:`mr-2 inline text-accent`,"aria-hidden":`true`}),`Share page popup`]}),(0,$.jsx)(`p`,{className:`mt-1 text-badge text-text-tertiary`,children:`Optional card visitors open from the Base URL card on your share page.`})]}),(0,$.jsx)(K,{checked:ge,onChange:e=>ye(e),disabled:n,label:`Enable popup`})]}),ge?(0,$.jsxs)(`div`,{className:`flex gap-7 items-start mt-2 min-w-0 max-medium:flex-col max-medium:items-stretch`,children:[(0,$.jsxs)(`div`,{className:`flex flex-col gap-4 min-w-0 w-100 shrink-0 max-medium:w-auto`,children:[W?(0,$.jsx)(`img`,{className:`block w-full h-66 object-cover border border-inner-border rounded-control bg-surface-1 max-medium:h-80`,src:W,alt:`Popup image preview`}):(0,$.jsx)(`div`,{className:`flex items-center justify-center w-full h-66 object-cover border border-dashed border-inner-border rounded-control bg-surface-1 text-text-tertiary text-badge max-medium:h-80`,"aria-hidden":`true`,children:(0,$.jsx)(`span`,{children:`No image`})}),(0,$.jsx)(xe,{id:`share-popup-image`,accept:Ze.join(`,`),"aria-label":`Popup image`,disabled:n,onChange:e=>{let t=e.target.files?.[0];if(e.target.value=``,!t)return;if(H(null),t.size>2097152){z(null),H(`Image must be 2 MB or smaller.`);return}let n=new FileReader;n.onload=()=>{z(String(n.result)),V(!1)},n.onerror=()=>H(`Could not read that file.`),n.readAsDataURL(t)}}),W?(0,$.jsx)(g,{variant:`secondary`,size:`sm`,type:`button`,disabled:n,className:`h-14 px-5 text-badge self-start`,onClick:()=>{z(null),V(!0),H(null)},children:`Remove image`}):null,be?(0,$.jsx)(`p`,{className:`form-error`,children:be}):null,(0,$.jsx)(`p`,{className:`m-0 text-text-tertiary text-badge leading-normal`,children:`PNG, JPEG, WebP, or GIF up to 2 MB.`})]}),(0,$.jsxs)(`div`,{className:`flex flex-col gap-4 min-w-0 flex-1 [&_.form-group]:gap-2`,children:[(0,$.jsx)(G,{label:`Popup title`,value:Se,onChange:e=>q(e.target.value),maxLength:120,placeholder:`Support this gateway`,disabled:n}),(0,$.jsxs)(`div`,{className:`form-group`,children:[(0,$.jsx)(`label`,{className:`form-label`,htmlFor:`share-popup-copy`,children:`Message`}),(0,$.jsx)(`textarea`,{className:`form-textarea`,id:`share-popup-copy`,value:J,onChange:e=>we(e.target.value),maxLength:1200,rows:3,placeholder:`If this service helps you, consider supporting its upkeep…`,disabled:n})]})]})]}):null]}),(0,$.jsxs)(`details`,{className:`group min-w-0 col-span-full rounded-card border border-inner-border bg-surface-2`,children:[(0,$.jsxs)(`summary`,{className:`flex cursor-pointer list-none items-center justify-between gap-3 p-4 [&::-webkit-details-marker]:hidden`,children:[(0,$.jsxs)(`span`,{className:`flex min-w-0 items-start gap-3`,children:[(0,$.jsx)(`span`,{className:`grid size-8 shrink-0 place-items-center rounded-inset bg-accent-soft text-accent`,children:(0,$.jsx)(se,{size:18,"aria-hidden":`true`})}),(0,$.jsxs)(`span`,{className:`min-w-0`,children:[(0,$.jsx)(`span`,{className:`block text-body font-bold text-text-primary`,children:`Access`}),(0,$.jsx)(`span`,{className:`mt-1 block text-badge text-text-tertiary`,children:t?.isDefault?`Default gateway key · all tenant permissions, including gateway routing and remote debugging.`:`Choose model, router, and dashboard permissions for this key.`})]})]}),(0,$.jsxs)(`span`,{className:`inline-flex shrink-0 items-center gap-2 rounded-control border border-inner-border bg-surface-1 px-3 py-2 text-micro font-semibold text-text-secondary`,children:[O.length,`/`,Xe.length,` grants`,(0,$.jsx)(_e,{size:14,className:`transition-transform group-open:rotate-180`,"aria-hidden":`true`})]})]}),(0,$.jsxs)(`div`,{className:`flex flex-col gap-4 border-t border-inner-border p-4`,children:[t?.isDefault?(0,$.jsxs)(`div`,{className:`flex items-start gap-3 rounded-control border border-accent/30 bg-accent-soft p-4 text-badge text-text-secondary`,children:[(0,$.jsx)(oe,{size:16,className:`mt-0.5 shrink-0 text-accent`,"aria-hidden":`true`}),(0,$.jsxs)(`p`,{className:`m-0`,children:[`This default API key is provisioned with every tenant permission, including `,(0,$.jsx)(`code`,{children:`routing:invoke`}),` and`,` `,(0,$.jsx)(`code`,{children:`routing:cli_mapping`}),`. Those grant gateway access and authorization to use remote CLI mappings; each client's mapping toggle below still controls whether those routes are active. You can remove individual grants here.`]})]}):null,(0,$.jsxs)(`div`,{className:`grid grid-cols-access gap-5 min-w-0 max-medium:grid-cols-1`,children:[(0,$.jsxs)(`section`,{"aria-labelledby":`model-access-heading`,className:`flex flex-col gap-3 min-w-0 rounded-card border border-inner-border bg-surface-1 p-4`,children:[(0,$.jsxs)(`h4`,{id:`model-access-heading`,className:`inline-flex items-center gap-2 text-caption font-bold text-text-primary`,children:[(0,$.jsx)(u,{size:15,className:`text-accent`,"aria-hidden":`true`}),`Model access`]}),(0,$.jsx)(`div`,{role:`group`,"aria-label":`Model access mode`,className:`flex gap-2`,children:[`whitelist`,`blacklist`].map(e=>(0,$.jsxs)(`button`,{type:`button`,"aria-pressed":A===e,disabled:n,onClick:()=>j(e),title:e===`whitelist`?`Only the listed models may be used. An empty list allows every model.`:`The listed models are refused. Everything else is allowed.`,className:`flex-1 py-2 px-3 text-badge font-semibold`,style:{borderRadius:`7px`,border:`1px solid ${A===e?`var(--accent)`:`var(--inner-border)`}`,background:A===e?`var(--accent-soft)`:`var(--surface-2)`,color:A===e?`var(--accent)`:`var(--text-secondary)`,cursor:n?`not-allowed`:`pointer`,opacity:n?.6:1},children:[e===`whitelist`?`Whitelist`:`Blacklist`,e===`whitelist`?(0,$.jsx)(oe,{size:13,className:`ml-1.5 inline`,"aria-hidden":`true`}):(0,$.jsx)(Ke,{size:13,className:`ml-1.5 inline`,"aria-hidden":`true`})]},e))}),(0,$.jsx)(`p`,{className:`text-badge text-text-tertiary m-0`,children:A===`whitelist`?`Only these models may be called. Empty = all allowed.`:`These models are refused. Everything else is allowed.`}),(0,$.jsx)(`div`,{className:`flex gap-1.5 flex-wrap min-h-6`,children:M.length===0?(0,$.jsx)(`span`,{className:`text-badge text-text-tertiary`,children:A===`whitelist`?`All models allowed`:`No models blocked`}):M.map(e=>(0,$.jsxs)(`span`,{className:`font-mono tabular-nums inline-flex items-center gap-1.5 text-badge bg-accent-soft text-accent py-1 px-3 rounded-chip border border-accent`,children:[e,(0,$.jsx)(`button`,{type:`button`,"aria-label":`Remove ${e} from the model list`,onClick:()=>ie(t=>t.filter(t=>t!==e)),disabled:n,className:`bg-transparent border-0 cursor-pointer p-0 flex`,children:`×`})]},e))}),(0,$.jsx)(g,{variant:`secondary`,size:`sm`,type:`button`,onClick:()=>P(!0),disabled:n,children:`Browse models`}),(0,$.jsx)(Ce,{open:ae,onClose:()=>P(!1),selected:M,onToggle:e=>ie(t=>t.includes(e)?t.filter(t=>t!==e):[...t,e]),title:A===`whitelist`?`Select allowed models`:`Select blocked models`,multi:!0})]}),(0,$.jsxs)(`div`,{className:`flex flex-col gap-4 min-w-0`,children:[(0,$.jsxs)(`section`,{"aria-labelledby":`routing-blocking-heading`,className:`flex flex-col gap-0 min-w-0 rounded-card border border-inner-border bg-surface-1 overflow-hidden`,children:[(0,$.jsxs)(`div`,{className:`px-4 pt-4 pb-3 border-b border-inner-border`,children:[(0,$.jsxs)(`h4`,{id:`routing-blocking-heading`,className:`inline-flex items-center gap-2 text-caption font-bold text-text-primary`,children:[(0,$.jsx)(N,{size:15,className:`text-accent`,"aria-hidden":`true`}),`Routing & Client Blocking`]}),(0,$.jsx)(`p`,{className:`mt-1 mb-0 text-badge text-text-tertiary`,children:`Control which gateway routes this key can call and which client apps are blocked before routing.`})]}),(0,$.jsxs)(`div`,{className:`flex flex-col divide-y divide-inner-border`,children:[(0,$.jsxs)(`div`,{className:`flex flex-col gap-2 px-4 py-3`,children:[(0,$.jsx)(`p`,{className:`text-badge font-semibold text-text-secondary m-0`,children:`Gateway routing`}),Xe.filter(e=>e===`routing:invoke`).map(e=>(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-4 py-1.5 px-4 rounded-inset`,style:{minHeight:`38px`,border:`1px solid var(--inner-border)`,background:O.includes(e)?`var(--accent-soft)`:`var(--surface-2)`},children:[(0,$.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,$.jsx)(N,{size:14,className:`mt-0.5 shrink-0 text-accent`,"aria-hidden":`true`}),(0,$.jsxs)(`div`,{className:`min-w-0`,children:[(0,$.jsx)(`div`,{className:`text-caption font-semibold text-text-primary`,children:e}),(0,$.jsx)(`p`,{className:`mt-0.5 mb-0 text-badge text-text-tertiary`,children:Qe[e]})]})]}),(0,$.jsx)(K,{checked:O.includes(e),onChange:()=>Oe(e),disabled:n,"aria-label":`Grant ${e}`})]},e))]}),(0,$.jsxs)(`div`,{className:`flex flex-col gap-2 px-4 py-3`,children:[(0,$.jsx)(`p`,{className:`text-badge font-semibold text-text-secondary m-0`,children:`Blocked client apps`}),(0,$.jsx)(`div`,{className:`flex flex-col gap-2`,children:de.map(e=>(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-4 py-1.5 px-4 rounded-inset`,style:{minHeight:`38px`,border:`1px solid var(--inner-border)`,background:F.includes(e.id)?`var(--accent-soft)`:`var(--surface-2)`},children:[(0,$.jsxs)(`div`,{className:`flex min-w-0 items-center gap-3`,children:[(0,$.jsx)(a,{size:14,className:`shrink-0 text-orange`,"aria-hidden":`true`}),(0,$.jsxs)(`div`,{className:`min-w-0`,children:[(0,$.jsxs)(`div`,{className:`text-caption font-semibold text-text-primary`,children:[`Block `,e.label,` Client`]}),(0,$.jsx)(`p`,{className:`mt-0.5 mb-0 text-badge text-text-tertiary`,children:e.id===`9router`?`9router, Omniroute, and Baazar Probes`:`Fingerprint-based detection — best-effort; unrecognised clients are never matched`})]})]}),(0,$.jsx)(K,{checked:F.includes(e.id),onChange:t=>ce(n=>t?[...n,e.id]:n.filter(t=>t!==e.id)),disabled:n,"aria-label":`Block ${e.label} client`})]},e.id))})]})]}),(0,$.jsx)(`div`,{className:`px-4 py-3`,children:(0,$.jsx)(ct,{keyId:e===`edit`&&t?t.id:``,busy:n,scopeGranted:O.includes(`routing:cli_mapping`),onScopeChange:e=>{e!==O.includes(`routing:cli_mapping`)&&Oe(`routing:cli_mapping`)},persistScope:n=>{if(e!==`edit`||!t)return;let r=n?[...new Set([...O,`routing:cli_mapping`])]:O.filter(e=>e!==`routing:cli_mapping`);De.mutate({keyId:t.id,request:{scopes:r}},{onError:e=>_.error(I(e,`Could not update the key's routing scope.`))})}})})]}),(0,$.jsxs)(`section`,{"aria-labelledby":`dashboard-scopes-heading`,className:`flex flex-col gap-0 min-w-0 rounded-card border border-inner-border bg-surface-1 overflow-hidden`,children:[(0,$.jsxs)(`div`,{className:`px-4 pt-4 pb-3 border-b border-inner-border`,children:[(0,$.jsxs)(`h4`,{id:`dashboard-scopes-heading`,className:`inline-flex items-center gap-2 text-caption font-bold text-text-primary`,children:[(0,$.jsx)(ve,{size:15,className:`text-accent`,"aria-hidden":`true`}),`Dashboard / Resources`]}),(0,$.jsx)(`p`,{className:`mt-1 mb-0 text-badge text-text-tertiary`,children:`Grants read or write access to console data — providers, models, configuration, and usage stats. No routing is implied by these scopes.`})]}),(0,$.jsx)(`div`,{className:`flex flex-col gap-2 p-4`,children:Xe.filter(e=>!e.startsWith(`routing:`)).map(e=>(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-4 py-1.5 px-4 rounded-inset`,style:{minHeight:`38px`,border:`1px solid var(--inner-border)`,background:O.includes(e)?`var(--accent-soft)`:`var(--surface-2)`},children:[(0,$.jsxs)(`div`,{className:`flex items-start gap-3 min-w-0`,children:[(()=>{let t=$e[e];return(0,$.jsx)(t,{size:14,className:`mt-0.5 shrink-0 text-accent`,"aria-hidden":`true`})})(),(0,$.jsxs)(`div`,{className:`min-w-0`,children:[(0,$.jsx)(`div`,{className:`text-caption font-semibold text-text-primary`,children:e}),(0,$.jsx)(`p`,{className:`mt-0.5 mb-0 text-badge text-text-tertiary`,children:Qe[e]})]})]}),(0,$.jsx)(K,{checked:O.includes(e),onChange:()=>Oe(e),disabled:n,"aria-label":`Grant ${e}`})]},e))})]})]})]})]})]})]})}function pt({secret:e,onClose:t}){return(0,$.jsx)(k,{open:e!==null,onClose:t,title:`New API key`,description:`Copy it now, or reveal it again later from the key's Share button.`,size:`md`,children:(0,$.jsxs)(`div`,{className:`flex flex-col gap-7`,children:[(0,$.jsx)(`p`,{className:`text-body text-text-secondary m-0 leading-normal`,children:`A personal key stays recoverable. Open the key's Share button and choose Reveal to see it again and copy it. Rotating the key replaces this secret, and any client still using it starts getting 401s.`}),(0,$.jsx)(`code`,{className:`block rounded-inset border border-inner-border bg-surface-1 py-5 px-6 text-caption text-text-primary break-all`,children:e}),(0,$.jsxs)(`div`,{className:`flex gap-4 flex-wrap`,children:[(0,$.jsx)(O,{value:e??``,size:`sm`,variant:`primary`,label:`Copy key`,copiedLabel:`Copied`}),(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,$.jsx)(h,{size:13}),onClick:()=>{e!==null&&(be(`cartethyia-api-key.txt`,`Cartethyia API key\n\n${e}\n\nKeep this secret. Reveal it again from the key's Share button.\n`,`text/plain;charset=utf-8`),_.success(`Key saved to your downloads.`))},children:`Save this key`})]})]})})}function mt(e,t){if(t)return`Permanent — lift manually`;let n=new Date(e);if(!Number.isFinite(n.getTime()))return`—`;let r=e-Date.now(),i=n.toLocaleString();if(r<=0)return`${i} (lapsed)`;let a=Math.ceil(r/6e4);if(a<60)return`${i} (in ${a}m)`;let o=Math.floor(a/60);return o<24?`${i} (in ${o}h)`:`${i} (in ${Math.floor(o/24)}d)`}function ht({onClose:e}){let t=s(!0),n=c(),[r,i]=(0,Q.useState)(null),a=t.data??[];return(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(k,{open:!0,onClose:e,title:`Banned Users`,description:`A caller is banned after repeated invalid-model requests. A ban is scoped to the API key that made them, so other keys used from the same address keep working — unless an operator banned the address outright.`,size:`lg`,children:(0,$.jsxs)(`div`,{className:`flex flex-col gap-7 min-w-0`,children:[(0,$.jsxs)(`div`,{className:`min-w-0`,children:[(0,$.jsxs)(`h4`,{className:`text-caption font-semibold text-text-secondary mb-4`,children:[`Active bans (`,a.length,`)`]}),t.isPending?(0,$.jsx)(T,{compact:!0,label:`Loading banned users…`}):t.isError?(0,$.jsx)(w,{compact:!0,message:I(t.error,`Could not load banned users.`),onRetry:()=>void t.refetch()}):a.length===0?(0,$.jsx)(E,{compact:!0,title:`No banned users`,message:`No client address is currently banned for model abuse.`,icon:(0,$.jsx)(Ge,{size:20})}):(0,$.jsx)(`div`,{className:`rounded-inset border border-inner-border`,children:(0,$.jsx)(Le,{maxHeight:480,scrollRegion:!0,headers:[`Client IP`,`API key`,`Reason`,`Applies to`,`Lapses`,``],children:a.map(e=>(0,$.jsxs)(`tr`,{children:[(0,$.jsx)(`td`,{className:`font-mono tabular-nums text-badge text-text-primary whitespace-nowrap`,children:e.ip}),(0,$.jsx)(`td`,{className:`font-mono tabular-nums text-badge text-text-secondary whitespace-nowrap`,children:e.apiKeyId?`${e.apiKeyId.slice(0,8)}…`:`—`}),(0,$.jsx)(`td`,{className:`text-badge text-text-secondary`,children:e.reason===`repeated_invalid_model_requests`?`Repeated invalid-model requests`:e.reason}),(0,$.jsx)(`td`,{className:`text-badge text-text-secondary whitespace-nowrap`,children:e.apiKeyId?`This key only`:`All keys from this IP`}),(0,$.jsx)(`td`,{className:`text-badge text-text-secondary whitespace-nowrap`,children:mt(e.expiresAt,e.permanent===!0)}),(0,$.jsx)(`td`,{className:`text-right whitespace-nowrap`,children:(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,$.jsx)(qe,{size:13}),disabled:n.isPending,onClick:()=>i(e),children:`Unban`})})]},e.identity))})})]}),(0,$.jsx)(J,{justify:`flex-end`,gap:`0px`,children:(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:e,children:`Close`})})]})}),(0,$.jsx)(ye,{open:r!==null,onClose:()=>i(null),onConfirm:async()=>{r&&(await n.mutateAsync(r.identity),_.success(`Unbanned ${r.ip}.`),i(null))},title:`Lift this ban?`,message:r?`Lift the ban on ${r.ip}${r.apiKeyId?` for this API key`:``}? The caller can reach the gateway again immediately.`:`Lift this ban?`,confirmLabel:`Unban`,danger:!0})]})}var gt=e=>(e??0).toLocaleString(),_t=e=>e?new Date(e).toLocaleString():`—`;function vt({keyId:e}){let t=we(),[n,r]=(0,Q.useState)(null),[i,a]=(0,Q.useState)(!1);return(0,$.jsxs)(`div`,{className:`flex min-w-0 items-center gap-4 rounded-control border border-inner-border bg-surface-2 px-5 py-4 text-text-tertiary`,children:[(0,$.jsx)(`code`,{title:i&&n?n:void 0,className:`min-w-0 flex-auto overflow-hidden font-mono text-caption text-text-primary text-ellipsis whitespace-nowrap`,children:i&&n?n:`••••••••••••••••`}),(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:i?(0,$.jsx)(S,{size:13}):(0,$.jsx)(C,{size:13}),loading:t.isPending,disabled:t.isPending,onClick:()=>{if(n!==null){a(e=>!e);return}t.mutate({keyId:e},{onSuccess:e=>{r(e.secret),a(!0)},onError:e=>_.error(I(e,`Could not reveal the key.`))})},children:i?`Hide`:`Reveal`}),i&&n?(0,$.jsx)(O,{value:n,size:`sm`,variant:`secondary`,label:`Copy`,copiedLabel:`Copied`}):null]})}function yt({label:e,value:t}){return(0,$.jsxs)(`div`,{className:`min-w-0 flex-1 basis-60 rounded-control border border-inner-border bg-surface-2 px-5 py-3`,children:[(0,$.jsx)(`dt`,{className:`text-badge font-normal tracking-label text-text-tertiary uppercase`,children:e}),(0,$.jsx)(`dd`,{className:`mt-1 text-caption font-normal text-text-primary tabular-nums`,children:t==null?`Unlimited`:gt(t)})]})}function bt(e){return e?{title:`Regenerate this key?`,message:`This rotates the key credential. Any client still using the current secret starts getting 401s immediately, and the old secret cannot be recovered. The handoff link is re-pointed to reveal the new key.`,confirmLabel:`Regenerate key`}:{title:`Regenerate this link?`,message:`This replaces the link URL; the current URL stops resolving immediately. Recipients keep the keys they already generated and keep working — but no one can enroll through the old link again.`,confirmLabel:`Regenerate link`}}function xt({consumed:e,budget:t}){let n=t==null||t<=0,r=n?100:Math.min(100,e/t*100),i=!n&&e>=t;return(0,$.jsxs)(`div`,{className:`grid flex-auto basis-full gap-2.5 rounded-control border border-inner-border bg-surface-2 px-5 py-3.5`,children:[(0,$.jsxs)(`div`,{className:`flex items-baseline justify-between gap-4 text-badge tracking-label text-text-tertiary uppercase`,children:[(0,$.jsx)(`span`,{children:`Lifetime budget`}),(0,$.jsx)(`span`,{className:`text-caption font-normal text-text-primary tabular-nums normal-case tracking-normal`,children:n?`${H(e)} · Unlimited`:`${H(e)} / ${H(t)}`})]}),(0,$.jsx)(`div`,{className:`h-3 overflow-hidden rounded bg-inner-border`,role:`progressbar`,"aria-label":`Lifetime token budget consumed`,"aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":Math.round(r),"aria-valuetext":n?`${H(e)} tokens consumed, no lifetime budget set`:`${H(e)} of ${H(t)} tokens consumed`,children:(0,$.jsx)(`div`,{className:i?`h-full rounded bg-status-danger`:`h-full rounded bg-status-success`,style:{width:`${r}%`}})})]})}var St=6;function Ct(e){return e.filter(e=>e.revokedAt===null).length}function wt(e){return e.reduce((e,t)=>e+t.allTime.totalTokens,0)}function Tt({consumed:e,budget:t}){if(t==null)return(0,$.jsx)(`div`,{className:`grid flex-auto basis-full gap-2.5 rounded-control border border-inner-border bg-surface-2 px-5 py-3.5`,children:(0,$.jsxs)(`div`,{className:`flex items-baseline justify-between gap-4 text-badge tracking-label text-text-tertiary uppercase`,children:[(0,$.jsx)(`span`,{children:`Total quota used`}),(0,$.jsx)(`span`,{className:`text-caption font-normal text-text-primary tabular-nums normal-case tracking-normal`,children:H(e)})]})});let n=t>0?Math.min(100,e/t*100):0,r=t>0?Math.max(0,100-e/t*100):100,i=Math.max(0,t-e),a=Re(e>=t?0:r),o=e>=t;return(0,$.jsxs)(`div`,{className:`grid flex-auto basis-full gap-2.5 rounded-control border border-inner-border bg-surface-2 px-5 py-3.5`,children:[(0,$.jsxs)(`div`,{className:`flex items-baseline justify-between gap-4 text-badge tracking-label text-text-tertiary uppercase`,children:[(0,$.jsx)(`span`,{children:`Total quota`}),(0,$.jsxs)(`span`,{className:`text-caption font-normal text-text-primary tabular-nums normal-case tracking-normal`,children:[H(e),` / `,H(t)]}),(0,$.jsx)(`span`,{className:`border rounded-chip px-4 py-0.5 text-caption font-bold whitespace-nowrap tabular-nums`,style:{color:a.text,borderColor:a.text},children:o?`Exhausted`:`${H(i)} left`})]}),(0,$.jsx)(`div`,{className:`h-3 overflow-hidden rounded bg-inner-border`,role:`progressbar`,"aria-label":`Total quota consumed`,"aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":Math.round(n),"aria-valuetext":`${H(e)} of ${H(t)} tokens consumed`,children:(0,$.jsx)(`div`,{className:o?`h-full rounded bg-status-danger`:`h-full rounded`,style:{width:`${n}%`,background:o?void 0:a.bar}})})]})}function Et({parentId:e,childId:t}){let n=Me(e,t);if(n.isPending)return(0,$.jsx)(T,{label:`Loading activity…`,compact:!0});if(n.isError)return(0,$.jsx)(w,{compact:!0,message:I(n.error,`Could not load activity.`),onRetry:()=>void n.refetch()});let r=n.data;return r?(0,$.jsxs)(`div`,{className:`grid min-w-0 gap-6 border-t border-inner-border bg-surface-1 px-6 py-5`,children:[(0,$.jsxs)(`section`,{children:[(0,$.jsx)(`h4`,{className:`mb-3 text-caption font-bold text-text-primary`,children:`Top models`}),r.models.length?(0,$.jsx)(`div`,{className:`data-table-container`,children:(0,$.jsxs)(`table`,{className:`data-table text-caption`,children:[(0,$.jsx)(`thead`,{children:(0,$.jsxs)(`tr`,{children:[(0,$.jsx)(`th`,{scope:`col`,children:`Model`}),(0,$.jsx)(`th`,{scope:`col`,children:`Today`}),(0,$.jsx)(`th`,{scope:`col`,children:`Errors`}),(0,$.jsx)(`th`,{scope:`col`,children:`Tokens`})]})}),(0,$.jsx)(`tbody`,{children:r.models.map((e,t)=>(0,$.jsxs)(`tr`,{children:[(0,$.jsx)(`td`,{children:e.modelId}),(0,$.jsx)(`td`,{children:gt(e.todayRequests)}),(0,$.jsx)(`td`,{children:gt(e.todayErrors)}),(0,$.jsx)(`td`,{children:H(e.todayTokens)})]},`${e.providerId??``}-${e.modelId}-${t}`))})]})}):(0,$.jsx)(`p`,{className:`py-3 text-caption text-text-tertiary`,children:`No model activity yet.`})]}),(0,$.jsxs)(`section`,{children:[(0,$.jsx)(`h4`,{className:`mb-3 text-caption font-bold text-text-primary`,children:`Recent requests`}),r.requests.length?(0,$.jsx)(`div`,{className:`data-table-container`,children:(0,$.jsxs)(`table`,{className:`data-table text-caption`,children:[(0,$.jsx)(`thead`,{children:(0,$.jsxs)(`tr`,{children:[(0,$.jsx)(`th`,{scope:`col`,children:`Model`}),(0,$.jsx)(`th`,{scope:`col`,children:`Status`}),(0,$.jsx)(`th`,{scope:`col`,children:`Tokens`}),(0,$.jsx)(`th`,{scope:`col`,children:`Time`})]})}),(0,$.jsx)(`tbody`,{children:r.requests.map(e=>(0,$.jsxs)(`tr`,{children:[(0,$.jsxs)(`td`,{children:[e.providerId??`Provider`,`/`,e.modelId??`Model`]}),(0,$.jsxs)(`td`,{children:[e.status,e.httpStatus?` · ${e.httpStatus}`:``]}),(0,$.jsx)(`td`,{children:H(e.totalTokens)}),(0,$.jsx)(`td`,{children:_t(e.startedAt)})]},e.requestId))})]})}):(0,$.jsx)(`p`,{className:`py-3 text-caption text-text-tertiary`,children:`No recent requests.`})]})]}):null}function Dt({parent:e,onSecretRevealed:t}){let[n,r]=(0,Q.useState)(null),[i,o]=(0,Q.useState)(`active`),[s,c]=(0,Q.useState)(null),l=ue(),u=Y(),f=ke(),p=Ae(),m=Z(e.id),h=e.keyMode!==`share`,v=Te(h?null:e.id),y=v.data??[],b=i===`active`?y.filter(e=>e.revokedAt===null):y.filter(e=>e.revokedAt!==null),x=y.filter(e=>e.revokedAt===null&&e.allTime.totalTokens===0);(0,Q.useEffect)(()=>{r(null)},[e.id]);let S=async(t,n)=>{let r=(await d(t,St,t=>p.mutateAsync({parentKeyId:e.id,childKeyId:t.id,deferInvalidation:!0}))).filter(e=>e.status===`fulfilled`).length;await l.invalidateQueries({queryKey:L.apiKeys.sharedKeys(e.id)}),await l.invalidateQueries({queryKey:L.apiKeys.all}),await v.refetch();let i=t.length-r;i>0?_.error(`Revoked ${r} of ${t.length} ${n}; ${i} failed.`):_.success(`Revoked ${r} ${n}.`)},C=u.isPending||f.isPending,[te,D]=(0,Q.useState)(!1),ne=async()=>{if(h){let n=await f.mutateAsync({keyId:e.id});t?.(n.secret);return}await u.mutateAsync({keyId:e.id,regenerate:!0}),_.success(`Link regenerated; the previous URL no longer works.`)},k=()=>{u.mutate({keyId:e.id},{onError:e=>_.error(I(e,`Could not create link.`))})},A=m.data?.url??null,j=bt(h);return(0,$.jsxs)(`div`,{className:`grid min-w-0 gap-6`,children:[(0,$.jsx)(`section`,{"aria-label":`Link`,children:m.isPending?(0,$.jsx)(T,{label:`Loading link…`,compact:!0}):m.isError?(0,$.jsx)(w,{compact:!0,message:I(m.error,`Could not load the link.`),onRetry:()=>void m.refetch()}):A?(0,$.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-4 rounded-control border border-inner-border bg-surface-2 px-5 py-4 text-text-tertiary`,children:[(0,$.jsx)(re,{size:14,"aria-hidden":`true`,className:`shrink-0`}),(0,$.jsx)(`code`,{title:A,className:`min-w-0 flex-auto overflow-hidden font-mono text-caption text-text-primary text-ellipsis whitespace-nowrap`,children:A}),(0,$.jsx)(O,{value:A,size:`sm`,variant:`secondary`,label:`Copy`,copiedLabel:`Copied`}),(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,$.jsx)(He,{size:13}),loading:C,disabled:C,onClick:()=>D(!0),children:`Regenerate`})]}):(0,$.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-4 rounded-control border border-inner-border bg-surface-2 px-5 py-4 text-text-tertiary`,children:[(0,$.jsx)(re,{size:14,"aria-hidden":`true`,className:`shrink-0`}),(0,$.jsx)(`span`,{className:`flex-auto text-caption text-text-tertiary`,children:`No link yet.`}),(0,$.jsx)(g,{variant:`primary`,size:`sm`,loading:C,disabled:C,onClick:k,children:`Create link`})]})}),h?(0,$.jsxs)(`section`,{"aria-label":`API key`,className:`grid gap-3`,children:[(0,$.jsx)(`div`,{className:`flex items-center justify-between gap-4`,children:(0,$.jsx)(`strong`,{className:`text-caption`,children:`API key`})}),(0,$.jsx)(vt,{keyId:e.id})]}):null,h?(0,$.jsxs)(`section`,{"aria-label":`Usage`,className:`grid gap-3`,children:[(0,$.jsx)(`div`,{className:`flex items-center justify-between gap-4`,children:(0,$.jsx)(`strong`,{className:`text-caption`,children:`Usage`})}),(0,$.jsxs)(`dl`,{className:`m-0 flex flex-wrap gap-3`,children:[(0,$.jsxs)(`div`,{className:`min-w-0 flex-1 basis-60 rounded-control border border-inner-border bg-surface-2 px-5 py-3`,children:[(0,$.jsx)(`dt`,{className:`text-badge font-normal tracking-label text-text-tertiary uppercase`,children:`Lifetime tokens`}),(0,$.jsx)(`dd`,{className:`mt-1 text-caption font-normal text-text-primary tabular-nums`,children:H(e.tokensConsumed)})]}),(0,$.jsx)(yt,{label:`Requests / min`,value:e.requestsPerMinute}),(0,$.jsx)(yt,{label:`Daily tokens`,value:e.dailyTokenLimit}),(0,$.jsx)(yt,{label:`Monthly tokens`,value:e.monthlyTokenLimit}),(0,$.jsx)(xt,{consumed:e.tokensConsumed,budget:e.lifetimeTokenBudget})]})]}):(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(`section`,{"aria-label":`Total quota`,className:`grid gap-3`,children:[(0,$.jsx)(`div`,{className:`flex items-center justify-between gap-4`,children:(0,$.jsx)(`strong`,{className:`text-caption`,children:`Total quota`})}),(0,$.jsx)(Tt,{consumed:wt(y),budget:e.lifetimeTokenBudget})]}),(0,$.jsxs)(`section`,{"aria-label":`Recipients`,className:`grid gap-3`,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,$.jsx)(`strong`,{className:`text-caption`,children:`Recipients`}),(0,$.jsxs)(`span`,{className:`mr-2 ml-auto text-caption text-text-tertiary tabular-nums`,children:[`Active users: `,Ct(y)]}),(0,$.jsx)(`div`,{className:`inline-flex items-center gap-1 rounded-chip border border-inner-border p-0.5`,role:`group`,"aria-label":`Filter recipients by status`,children:[`active`,`revoked`].map(e=>(0,$.jsx)(`button`,{type:`button`,"aria-pressed":i===e,onClick:()=>o(e),className:`rounded-chip border-0 px-3 py-1 text-badge font-semibold capitalize cursor-pointer ${i===e?`bg-surface-1 text-text-primary`:`bg-transparent text-text-secondary hover:text-text-primary`}`,children:e},e))}),s===null?null:(0,$.jsxs)(`span`,{className:`inline-flex items-center gap-2 rounded-chip border border-danger-border bg-surface-2 px-3 py-1`,children:[(0,$.jsx)(`span`,{className:`text-badge text-text-secondary`,children:s===`all`?`Revoke ${b.length}?`:`Revoke ${x.length} unused?`}),(0,$.jsx)(g,{variant:`danger`,size:`sm`,loading:p.isPending,onClick:()=>{let e=s===`all`?b:x,t=s===`all`?`recipients`:`unused recipients`;c(null),S(e,t)},children:`Confirm`}),(0,$.jsx)(g,{variant:`ghost`,size:`sm`,onClick:()=>c(null),children:`Cancel`})]}),(0,$.jsx)(g,{variant:`ghost`,size:`sm`,disabled:x.length===0||p.isPending,title:x.length===0?`No active recipient has spent zero tokens`:`Revoke ${x.length} recipient${x.length===1?``:`s`} that never spent a token`,onClick:()=>c(`unused`),icon:(0,$.jsx)(a,{size:13}),children:`Revoke no-usage`}),(0,$.jsx)(g,{variant:`ghost`,size:`sm`,disabled:b.length===0||p.isPending,title:b.length===0?`Nothing to revoke in this view`:`Revoke all ${b.length} listed recipient${b.length===1?``:`s`}`,onClick:()=>c(`all`),icon:(0,$.jsx)(a,{size:13}),children:`Revoke all`}),(0,$.jsx)(g,{variant:`ghost`,size:`sm`,onClick:()=>void v.refetch(),icon:(0,$.jsx)(ie,{size:13,className:v.isFetching?`animate-spin`:void 0}),children:`Refresh`})]}),v.isPending&&!v.data?(0,$.jsx)(T,{label:`Loading recipients…`,compact:!0}):v.isError?(0,$.jsx)(w,{compact:!0,message:I(v.error,`Could not load recipients.`),onRetry:()=>void v.refetch()}):b.length===0?(0,$.jsx)(E,{compact:!0,title:i===`revoked`?`No revoked recipients`:`No active recipients`,message:i===`revoked`?`Revoked keys appear here once a recipient's key is revoked.`:`Keys generated through this link appear here with their masked client IP and token usage.`}):(0,$.jsx)(`div`,{className:`data-table-container max-h-[46vh]`,children:(0,$.jsxs)(`table`,{className:`data-table text-caption`,children:[(0,$.jsx)(`thead`,{children:(0,$.jsxs)(`tr`,{children:[(0,$.jsx)(`th`,{scope:`col`,className:`w-12`,"aria-label":`Expand`}),(0,$.jsx)(`th`,{scope:`col`,children:`Key`}),(0,$.jsx)(`th`,{scope:`col`,children:`Status`}),(0,$.jsx)(`th`,{scope:`col`,children:`Today`}),(0,$.jsx)(`th`,{scope:`col`,children:`Lifetime`}),(0,$.jsx)(`th`,{scope:`col`,children:`Last activity`}),(0,$.jsx)(`th`,{scope:`col`,className:`text-right whitespace-nowrap`,children:`Actions`})]})}),(0,$.jsx)(`tbody`,{children:b.map(t=>{let i=n===t.id;return(0,$.jsxs)(Q.Fragment,{children:[(0,$.jsxs)(`tr`,{children:[(0,$.jsx)(`td`,{children:(0,$.jsx)(`button`,{type:`button`,className:`grid h-11 w-11 place-items-center rounded-chip border-0 bg-transparent p-0 text-text-secondary hover:bg-hover hover:text-text-primary`,"aria-expanded":i,"aria-label":i?`Collapse recipient`:`Expand recipient`,onClick:()=>r(i?null:t.id),children:i?(0,$.jsx)(_e,{size:14}):(0,$.jsx)(ee,{size:14})})}),(0,$.jsxs)(`td`,{children:[(0,$.jsxs)(`code`,{children:[t.label||t.keyPrefix||`key`,`…`]}),(0,$.jsx)(`div`,{className:`mt-1 text-badge text-text-tertiary wrap-anywhere`,children:t.issuedClientIp??`IP hidden`})]}),(0,$.jsx)(`td`,{children:t.revokedAt?`revoked`:`active`}),(0,$.jsx)(`td`,{children:H(t.today.totalTokens)}),(0,$.jsx)(`td`,{children:H(t.allTime.totalTokens)}),(0,$.jsx)(`td`,{children:_t(t.lastUsedAt)}),(0,$.jsx)(`td`,{className:`text-right whitespace-nowrap`,children:(0,$.jsx)(g,{variant:`danger`,size:`sm`,disabled:p.isPending||!!t.revokedAt,onClick:()=>p.mutate({parentKeyId:e.id,childKeyId:t.id},{onError:e=>_.error(I(e,`Could not revoke key.`))}),children:`Revoke`})})]}),i?(0,$.jsx)(`tr`,{children:(0,$.jsx)(`td`,{colSpan:7,className:`p-0`,children:(0,$.jsx)(Et,{parentId:e.id,childId:t.id})})}):null]},t.id)})})]})})]})]}),(0,$.jsx)(ye,{open:te,onClose:()=>D(!1),onConfirm:ne,title:j.title,message:j.message,confirmLabel:j.confirmLabel,danger:!0})]})}function Ot({parent:e,onClose:t,onSecretRevealed:n}){let r=e.keyMode!==`share`;return(0,$.jsx)(k,{open:!0,onClose:t,title:`Sharing — ${e.label||`API key`}`,description:r?`One stable handoff link for this key. Regenerating rotates the key itself.`:`One stable enrollment link. Regenerating replaces the URL; recipients keep the keys they already generated.`,size:`lg`,children:(0,$.jsx)(Dt,{parent:e,onSecretRevealed:n})})}function kt(){let e=je(),t=ge(),n=De(),r=Ee(),i=Oe(),a=ke(),o=we(),s=X(),{copy:c}=V(),[l,u]=(0,Q.useState)(!1),[d,f]=(0,Q.useState)(null),[m,h]=(0,Q.useState)(null),[v,y]=(0,Q.useState)(null),[ee,x]=(0,Q.useState)(null),[S,C]=(0,Q.useState)(null),[te,ne]=(0,Q.useState)(!1),[re,O]=(0,Q.useState)(null),[M,ie]=(0,Q.useState)(null),N=e.data??[],ae=t.data?.isPlatformAdmin??!1,oe=e=>{x(null),C(e)},P=async e=>{try{let{secret:t}=await o.mutateAsync({keyId:e.id});await c(t)?_.success(`API key copied`):_.error(`Clipboard unavailable on this origin`)}catch(e){_.error(I(e,`Could not reveal API key.`))}},se=bt(!0);return(0,$.jsxs)(B,{children:[(0,$.jsx)(z,{title:`API Credentials`,subtitle:`Manage tenant API keys, model access, budgets, and sharing.`,icon:(0,$.jsx)(D,{size:16}),action:(0,$.jsxs)(`div`,{className:`flex items-center gap-4`,children:[ae?(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:()=>ne(!0),icon:(0,$.jsx)(Ge,{size:13}),children:`Banned Users`}):null,(0,$.jsx)(g,{variant:`primary`,size:`sm`,onClick:()=>{x(null),u(!0)},icon:(0,$.jsx)(j,{size:13}),children:`Create Key`})]})}),(0,$.jsx)(R,{children:e.isPending&&!e.data?(0,$.jsx)(T,{label:`Loading API keys…`}):e.isError&&!e.data?(0,$.jsx)(w,{message:I(e.error,`Could not load credentials.`),onRetry:()=>void e.refetch()}):N.length===0?(0,$.jsx)(E,{title:`No API keys issued`,message:`Generate a secret key to authenticate your SDK or CLI client against the gateway.`,icon:(0,$.jsx)(D,{size:20})}):(0,$.jsx)(`div`,{className:`scroll-region max-h-280 pr-1`,children:(0,$.jsx)(b,{items:N,label:`API credentials`,disabled:s.isPending,onReorder:e=>s.mutate(e,{onError:e=>_.error(I(e,`Could not save the new order.`))}),renderItem:e=>(0,$.jsxs)(`div`,{className:`api-key-card flex items-start justify-between gap-6 px-6 py-4 rounded-chip border border-inner-border bg-surface-2 max-medium:flex-col max-medium:items-stretch max-medium:gap-4 max-medium:p-5 [&>div:last-child]:flex-wrap`,children:[(0,$.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-4 flex-wrap`,children:[(0,$.jsx)(`strong`,{className:`text-body`,children:e.label||`Unnamed credential`}),(0,$.jsx)(W,{tone:e.revokedAt?`err`:e.enabled?`ok`:`warn`,children:e.revokedAt?`revoked`:e.enabled?`enabled`:`disabled`}),(0,$.jsx)(W,{tone:e.keyMode===`share`?`accent`:`default`,children:e.keyMode===`share`?`share template`:`personal`}),e.isDefault?(0,$.jsx)(W,{tone:`warn`,title:`Required by the gateway. Rotate it; it cannot be deleted.`,children:`default · rotate only`}):null]}),(0,$.jsxs)(`div`,{className:`api-key-facts flex items-center flex-wrap gap-2 mt-3 min-w-0 max-medium:grid max-medium:grid-cols-3 max-medium:gap-2 max-medium:mt-0`,children:[(0,$.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap max-medium:justify-between`,children:[(0,$.jsx)(`span`,{className:`text-text-tertiary text-micro font-semibold uppercase tracking-label`,children:`Created`}),new Date(e.createdAt).toLocaleDateString()]}),(0,$.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap max-medium:justify-between`,children:[(0,$.jsx)(`span`,{className:`text-text-tertiary text-micro font-semibold uppercase tracking-label`,children:e.keyMode===`share`?`Total usage`:`Usage`}),H(e.tokensConsumed)]}),(0,$.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap max-medium:justify-between`,children:[(0,$.jsx)(`span`,{className:`text-text-tertiary text-micro font-semibold uppercase tracking-label`,children:`RPM`}),U(e.requestsPerMinute)]})]}),(0,$.jsxs)(`div`,{className:`api-key-facts flex items-center flex-wrap gap-2 mt-3 min-w-0 max-medium:grid max-medium:grid-cols-3 max-medium:gap-2 max-medium:mt-0`,children:[(0,$.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap max-medium:justify-between`,children:[(0,$.jsx)(`span`,{className:`text-text-tertiary text-micro font-semibold uppercase tracking-label`,children:`Daily`}),U(e.dailyTokenLimit)]}),(0,$.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap max-medium:justify-between`,children:[(0,$.jsx)(`span`,{className:`text-text-tertiary text-micro font-semibold uppercase tracking-label`,children:`Monthly`}),U(e.monthlyTokenLimit)]}),(0,$.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap max-medium:justify-between`,children:[(0,$.jsx)(`span`,{className:`text-text-tertiary text-micro font-semibold uppercase tracking-label`,children:`One-time`}),U(e.lifetimeTokenBudget)]}),(0,$.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap max-medium:justify-between`,children:[(0,$.jsx)(`span`,{className:`text-text-tertiary text-micro font-semibold uppercase tracking-label`,children:`Concurrent`}),U(e.maxConcurrentRequests)]}),(0,$.jsxs)(`span`,{className:`inline-flex items-center gap-2.5 px-3.5 py-1 border border-inner-border rounded-chip bg-surface-1 text-text-secondary text-badge leading-normal whitespace-nowrap max-medium:justify-between`,children:[(0,$.jsx)(`span`,{className:`text-text-tertiary text-micro font-semibold uppercase tracking-label`,children:e.modelAccessMode===`blacklist`?`Blocked`:`Models`}),e.modelAccessMode===`blacklist`?e.modelList?.length??0:e.modelList?.length?e.modelList.length:`All`]})]})]}),(0,$.jsxs)(`div`,{className:`flex gap-3 shrink-0 flex-wrap`,children:[e.revokedAt?null:(0,$.jsx)(K,{checked:e.enabled,disabled:r.isPending,id:`api-key-enabled-${e.id}`,label:``,"aria-label":`${e.enabled?`Disable`:`Enable`} ${e.label||`API credential`}`,onChange:t=>r.mutate({keyId:e.id,request:{enabled:t}},{onSuccess:()=>_.success(`${e.label||`API credential`} ${t?`enabled`:`disabled`}`),onError:e=>_.error(I(e,`Could not update credential state.`))})}),(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,$.jsx)(A,{size:13}),onClick:()=>{x(null),f(e)},children:`Edit`}),!e.revokedAt&&e.keyMode!==`share`?(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,$.jsx)(p,{size:13}),onClick:()=>void P(e),disabled:o.isPending,children:`Copy`}):null,!e.revokedAt&&(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,$.jsx)(We,{size:13}),onClick:()=>oe(e),children:e.keyMode===`share`?`Recipients`:`Share`}),!e.revokedAt&&e.keyMode!==`share`&&(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:(0,$.jsx)(He,{size:13}),onClick:()=>{x(null),y(e)},disabled:a.isPending,children:`Rotate`}),!e.revokedAt&&!e.isDefault&&(0,$.jsx)(g,{variant:`danger`,size:`sm`,icon:(0,$.jsx)(ce,{size:13}),onClick:()=>h(e),disabled:i.isPending,children:`Revoke`})]})]})})})}),(0,$.jsx)(k,{open:l,onClose:()=>u(!1),title:`Create API Key`,description:`Create a tenant-scoped credential. Choose model access, permissions, limits, and optional blocked client routers.`,size:`lg`,footer:re,children:(0,$.jsx)(ft,{mode:`create`,record:null,busy:n.isPending,onClose:()=>u(!1),actionsRef:O,onDone:e=>{n.mutate(e,{onSuccess:t=>{u(!1),x(ut(e.keyMode,t.secret)),_.success(`API key created`)},onError:e=>_.error(I(e,`Could not create API key.`))})}})}),(0,$.jsx)(k,{open:d!==null,onClose:()=>f(null),title:`Edit API Key`,description:`Update the key's model access, permissions, limits, share notes, and optional public popup.`,size:`lg`,footer:M,children:(0,$.jsx)(ft,{mode:`edit`,record:d,busy:r.isPending,onClose:()=>f(null),actionsRef:ie,onDone:e=>{d&&r.mutate({keyId:d.id,request:e},{onSuccess:t=>{f(null),x(ut(e.keyMode,t.secret)),_.success(`API key updated`)},onError:e=>_.error(I(e,`Could not update API key.`))})}})}),S?(0,$.jsx)(Ot,{parent:S,onClose:()=>C(null),onSecretRevealed:e=>{C(null),x(e)}}):null,(0,$.jsx)(ye,{open:v!==null,onClose:()=>y(null),onConfirm:async()=>{if(!v)return;let e=await a.mutateAsync({keyId:v.id});x(e.secret),_.success(`Rotated ${v.label||v.id}.`),y(null)},title:se.title,message:se.message,confirmLabel:se.confirmLabel,danger:!0}),(0,$.jsx)(ye,{open:m!==null,onClose:()=>h(null),onConfirm:async()=>{m&&(await i.mutateAsync(m.id),_.success(`Revoked ${m.label||m.id}.`),h(null))},title:`Revoke API key?`,message:m?`Revoke ${m.label||m.id}? Clients using it will be rejected.${m.keyMode===`share`?` All child keys and enrollment links will also be revoked.`:``}`:`Revoke this API key?`,confirmLabel:`Revoke`,danger:!0}),te?(0,$.jsx)(ht,{onClose:()=>ne(!1)}):null,(0,$.jsx)(pt,{secret:ee,onClose:()=>x(null)})]})}function At(){let e=F(),t=P(),n=e.data;if(e.isPending)return(0,$.jsx)(T,{label:`Loading compression settings…`});if(e.isError||!n)return(0,$.jsx)(w,{message:I(e.error,`Failed to load compression settings`),onRetry:()=>void e.refetch()});let r=n.rtkPruneEnabled,a=n.ponyTailEnabled;return(0,$.jsxs)(B,{children:[(0,$.jsx)(z,{title:`Compression`,subtitle:`Shrink requests before they reach the provider`,icon:(0,$.jsx)(o,{size:16})}),(0,$.jsx)(R,{children:(0,$.jsxs)(q,{gap:`14px`,children:[(0,$.jsxs)(`div`,{className:`flex items-start gap-x-8 gap-y-5`,children:[(0,$.jsxs)(`div`,{className:`flex gap-5 min-w-0 flex-auto`,children:[(0,$.jsx)(Ue,{size:16,className:`shrink-0 mt-1 text-text-secondary`}),(0,$.jsxs)(`div`,{className:`min-w-0`,children:[(0,$.jsx)(`label`,{htmlFor:`compression-rtk`,children:(0,$.jsx)(J,{gap:`6px`,className:`text-body font-semibold`,children:`Prune tool output (RTK)`})}),(0,$.jsx)(`div`,{className:`text-badge text-text-tertiary wrap-anywhere max-w-full`,children:`Compact bulky tool results (diffs, grep dumps, listings) in the message history so a long conversation stops re-sending megabytes of raw output. Higher strength compresses more aggressively.`})]})]}),(0,$.jsxs)(J,{gap:`8px`,className:`shrink-0 items-center ml-auto`,children:[(0,$.jsx)(Se,{id:`compression-rtk-level`,"aria-label":`RTK strength`,value:n.rtkPruneLevel,onValueChange:e=>t.mutate({rtkPruneLevel:e===`lite`||e===`full`||e===`ultra`?e:`full`},{onError:e=>_.error(I(e,`Could not update RTK strength.`))}),options:[{value:`lite`,label:`Lite`},{value:`full`,label:`Full`},{value:`ultra`,label:`Ultra`}]}),(0,$.jsx)(K,{id:`compression-rtk`,"aria-label":`Enable RTK prune`,checked:r,onChange:e=>t.mutate({rtkPruneEnabled:e},{onError:e=>_.error(I(e,`Could not update RTK prune.`))})})]})]}),(0,$.jsxs)(`div`,{className:`flex items-start gap-x-8 gap-y-5`,children:[(0,$.jsxs)(`div`,{className:`flex gap-5 min-w-0 flex-auto`,children:[(0,$.jsx)(i,{size:16,className:`shrink-0 mt-1 text-text-secondary`}),(0,$.jsxs)(`div`,{className:`min-w-0`,children:[(0,$.jsx)(`label`,{htmlFor:`compression-ponytail`,children:(0,$.jsx)(J,{gap:`6px`,className:`text-body font-semibold`,children:`PonyTail (system directive)`})}),(0,$.jsx)(`div`,{className:`text-badge text-text-tertiary wrap-anywhere max-w-full`,children:`Appends a minimal-code directive to the system content, biasing the model toward the smallest working change. Higher strength pushes harder toward deletion over addition.`})]})]}),(0,$.jsxs)(J,{gap:`8px`,className:`shrink-0 items-center ml-auto`,children:[(0,$.jsx)(Se,{id:`compression-ponytail-level`,"aria-label":`PonyTail strength`,value:n.ponyTailLevel,onValueChange:e=>t.mutate({ponyTailLevel:e===`lite`||e===`full`||e===`ultra`?e:`full`},{onError:e=>_.error(I(e,`Could not update PonyTail strength.`))}),options:[{value:`lite`,label:`Lite`},{value:`full`,label:`Full`},{value:`ultra`,label:`Ultra`}]}),(0,$.jsx)(K,{id:`compression-ponytail`,"aria-label":`Enable PonyTail`,checked:a,onChange:e=>t.mutate({ponyTailEnabled:e},{onError:e=>_.error(I(e,`Could not update PonyTail.`))})})]})]}),r||a?(0,$.jsxs)(`p`,{role:`note`,className:`flex gap-4 items-start m-0 py-4 px-5 rounded-inset border border-orange bg-orange-soft text-text-secondary text-badge`,children:[(0,$.jsx)(v,{size:14,className:`shrink-0 mt-0.5 text-orange`}),(0,$.jsx)(`span`,{children:`Your AI may produce degraded quality while compression is active: it sees a shortened history and a minimal-code directive, so fewer tokens but a chance of missing detail. Turn it off if answers get worse.`})]}):null]})})]})}function jt(){return le({queryKey:L.remoteSupport.status,queryFn:()=>pe(`/remote-support/status`)})}function Mt(){let e=ue();return me({mutationFn:e=>pe(`/remote-support/start`,{method:`POST`,body:JSON.stringify({tool:e})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:L.remoteSupport.status})}})}function Nt(){let e=ue();return me({mutationFn:e=>pe(`/remote-support/stop`,{method:`POST`,body:JSON.stringify(e===void 0?{}:{tool:e})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:L.remoteSupport.status})}})}var Pt={cloudflared:`cloudflared`,tailscale:`Tailscale`},Ft={cloudflared:`Publish a temporary public URL without opening a port.`,tailscale:`Give a helper a private address on your own tailnet.`};function It({tool:e}){return e===`cloudflared`?(0,$.jsxs)(`svg`,{viewBox:`0 0 24 24`,className:`size-8 shrink-0`,"aria-hidden":`true`,fill:`currentColor`,children:[(0,$.jsx)(`path`,{d:`M16.5 18.4a4.6 4.6 0 0 1-3.2-1.3l-6-5.9a2.4 2.4 0 0 0-3.3 0 2.3 2.3 0 0 0 0 3.3l5.4 5.3a.9.9 0 0 1-1.3 1.3L2.7 15.8a4.1 4.1 0 0 1 0-5.8 4.2 4.2 0 0 1 5.8 0l6 5.9a2.4 2.4 0 0 0 3.3 0 2.3 2.3 0 0 0 0-3.3l-4.2-4.1a.9.9 0 0 1 1.3-1.3l4.2 4.1a4.1 4.1 0 0 1 0 5.8 4.2 4.2 0 0 1-2.6 1.3Z`}),(0,$.jsx)(`path`,{d:`M7.6 18.4a4.5 4.5 0 0 1-3-1.1 5.4 5.4 0 0 1-1.5-3.5 6 6 0 0 1 .4-2 .9.9 0 0 1 1.7.6 4.2 4.2 0 0 0-.3 1.4 3.6 3.6 0 0 0 1 2.3 2.7 2.7 0 0 0 1.8.7.9.9 0 0 1 0 1.8Z`})]}):(0,$.jsxs)(`svg`,{viewBox:`0 0 24 24`,className:`size-8 shrink-0`,"aria-hidden":`true`,fill:`currentColor`,children:[(0,$.jsx)(`path`,{d:`M12 3.2a4.4 4.4 0 0 0-4.4 4.4v2.2H4.6a2.2 2.2 0 0 0 0 4.4h3v2.2a4.4 4.4 0 0 0 8.8 0v-2.2h1.1a3.3 3.3 0 0 0 0-6.6h-1.1V7.6A4.4 4.4 0 0 0 12 3.2Zm0 2.2a2.2 2.2 0 0 1 2.2 2.2v6.6a2.2 2.2 0 0 1-4.4 0V7.6A2.2 2.2 0 0 1 12 5.4Z`}),(0,$.jsx)(`path`,{d:`M6.6 11h4.2v2.2H6.6zM13.2 11h4.2v2.2h-4.2z`})]})}function Lt({tool:e}){let t=jt(),n=Mt(),r=Nt(),{copied:i,copy:a}=V(2e3),o=t.data?.active===e,s=n.isPending||r.isPending,c=o?t.data?.url??null:null,[l,u]=(0,Q.useState)(null),[d,f]=(0,Q.useState)(o);(0,Q.useEffect)(()=>{!n.isPending&&!r.isPending&&f(o)},[o,n.isPending,r.isPending]);let h=async t=>{f(t);try{let i=t?await n.mutateAsync(e):await r.mutateAsync(e);if(i.blocker!==null&&i.message!==null){u(i.message),_.error(i.message),f(!t);return}u(null),_.success(t?`${Pt[e]} started`:`${Pt[e]} stopped`)}catch{_.error(`Could not ${t?`start`:`stop`} ${Pt[e]}`),f(!t)}},v=async()=>{if(c!==null){if(await a(c)){_.success(`Remote URL copied`,c);return}_.error(`Clipboard unavailable on this origin`)}};return(0,$.jsxs)(`div`,{className:`rounded-control border border-inner-border bg-surface-2 p-5`,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,$.jsxs)(`div`,{className:`flex min-w-0 items-center gap-3`,children:[(0,$.jsx)(It,{tool:e}),(0,$.jsx)(`h3`,{className:`text-caption font-semibold`,children:Pt[e]})]}),(0,$.jsx)(K,{checked:d,disabled:s,onChange:e=>void h(e),"aria-label":`Toggle ${Pt[e]} remote support`})]}),n.isPending?(0,$.jsxs)(`div`,{className:`mt-3 flex items-center justify-between gap-3`,children:[(0,$.jsxs)(`div`,{className:`flex items-center gap-2 text-badge text-text-secondary`,children:[(0,$.jsx)(y,{size:14,className:`animate-spin`,"aria-hidden":`true`}),(0,$.jsx)(`span`,{className:`animate-pulse`,children:`Waiting for address…`})]}),(0,$.jsx)(g,{variant:`secondary`,size:`sm`,onClick:()=>void h(!1),children:`Cancel`})]}):c===null?l===null?(0,$.jsx)(`p`,{className:`mt-2 text-badge leading-normal text-text-tertiary`,children:Ft[e]}):(0,$.jsxs)(`div`,{className:`mt-2 rounded-control border border-warning/30 bg-warning/10 p-3 text-badge leading-normal text-text-secondary`,children:[(0,$.jsx)(`p`,{className:`font-medium text-warning`,children:`Setup needed`}),(0,$.jsx)(`p`,{className:`mt-1 whitespace-pre-wrap break-words`,children:l}),(()=>{let e=l.match(/https:\/\/login\.tailscale\.com\/f\/serve\?[^\s]+/);return e?(0,$.jsx)(`a`,{href:e[0],target:`_blank`,rel:`noreferrer`,className:`mt-2 inline-block font-medium text-accent underline`,children:`Enable Tailscale Serve →`}):null})()]}):(0,$.jsxs)(`div`,{className:`mt-3 flex items-center gap-3`,children:[(0,$.jsx)(`code`,{className:`min-w-0 flex-1 truncate font-mono text-badge text-text-primary`,title:c,children:c}),(0,$.jsxs)(g,{variant:`secondary`,size:`sm`,onClick:()=>void v(),children:[i?(0,$.jsx)(m,{size:14}):(0,$.jsx)(p,{size:14}),i?`Copied`:`Copy`]})]})]})}function Rt(){let{copied:e,copy:t}=V(2e3),n=`${window.location.origin}/v1`,r=async()=>{if(await t(n)){_.success(`Gateway endpoint copied`,n);return}_.error(`Clipboard unavailable on this origin`)};return(0,$.jsxs)(B,{children:[(0,$.jsx)(z,{title:`Gateway Endpoint`,subtitle:`Universal OpenAI & Anthropic Wire API Endpoint Compatible`,icon:(0,$.jsx)(f,{size:16})}),(0,$.jsx)(R,{children:(0,$.jsxs)(q,{gap:`10px`,children:[(0,$.jsxs)(`div`,{className:`nested-panel flex items-center gap-4 rounded-control border border-inner-border bg-code-surface px-7 py-5 font-mono text-body font-semibold tabular-nums`,children:[(0,$.jsx)(`code`,{className:`min-w-0 flex-1 truncate`,title:n,children:n}),(0,$.jsx)(g,{variant:`secondary`,size:`sm`,icon:e?(0,$.jsx)(m,{size:13}):(0,$.jsx)(p,{size:13}),"aria-label":`Copy endpoint`,title:`Copy endpoint`,onClick:()=>void r(),className:`shrink-0`,children:e?`Copied`:`Copy`})]}),(0,$.jsxs)(`p`,{className:`text-caption leading-normal text-text-secondary`,children:[`Point any SDK, CLI, or agent (e.g. OpenCode, Pi, OMP, Kilo, Cline, Droid and more clients) to this same-origin base URL.`,(0,$.jsxs)(`span`,{className:`mt-1 block text-text-tertiary`,children:[`You may not put `,(0,$.jsx)(`code`,{className:`font-mono`,children:`/v1`}),` on Claude Code — the CLI appends it itself.`]})]})]})})]})}function zt(){let e=F(),t=P(),n=e.data?.invokeDisabled===!0,r=e=>{t.mutate({invokeDisabled:!e},{onSuccess:()=>_.success(e?`Invoke enabled — routing has resumed.`:`Invoke disabled — every request now returns 503 and nothing upstream is dialed.`),onError:e=>_.error(e instanceof Error?e.message:`Could not save the setting`)})};return(0,$.jsxs)(B,{children:[(0,$.jsx)(z,{title:`Invoke Switch`,subtitle:`Stop every request without deleting anything`,icon:(0,$.jsx)(M,{size:16})}),(0,$.jsx)(R,{children:(0,$.jsxs)(q,{gap:`10px`,children:[(0,$.jsxs)(`div`,{className:`flex items-center justify-between gap-4`,children:[(0,$.jsxs)(`p`,{className:`min-w-0 text-caption leading-normal text-text-secondary`,children:[`Off refuses every `,(0,$.jsx)(`code`,{className:`font-mono`,children:`/v1/*`}),` request with 503. Nothing is dispatched upstream, and no account, key, or model is changed — the dashboard stays reachable so you can turn it back on.`]}),(0,$.jsx)(K,{checked:!n,disabled:e.isLoading||t.isPending,onChange:e=>r(e),"aria-label":`Toggle invoke for every request`})]}),n?(0,$.jsxs)(`p`,{className:`flex items-start gap-2 text-caption leading-normal text-warning`,children:[(0,$.jsx)(v,{size:14,className:`mt-0.5 shrink-0`,"aria-hidden":`true`}),(0,$.jsx)(`span`,{children:`Invoke is off. Every API request is being refused, and any client pointed at this gateway will keep failing until you switch it back on.`})]}):null]})})]})}function Bt(){let e=jt();return(0,$.jsxs)(B,{children:[(0,$.jsx)(z,{title:`Remote Support`,subtitle:`Reach this gateway from outside the local network`,icon:(0,$.jsx)(Be,{size:16})}),(0,$.jsx)(R,{children:(0,$.jsxs)(q,{gap:`10px`,children:[(0,$.jsxs)(`div`,{className:`grid grid-cols-2 gap-4 max-medium:grid-cols-1`,children:[(0,$.jsx)(Lt,{tool:`cloudflared`}),(0,$.jsx)(Lt,{tool:`tailscale`})]}),e.data?.blocker!==null&&e.data?.message!==null?(0,$.jsx)(`p`,{className:`text-badge leading-normal text-red-primary`,children:e.data?.message}):null,(0,$.jsxs)(`p`,{className:`text-caption leading-normal text-text-secondary`,children:[`Either way the gateway still sees the tunnel's address as the client, so set`,` `,(0,$.jsx)(`code`,{className:`font-mono`,children:`TRUSTED_PROXY_CIDRS`}),` to the edge that forwards to it — otherwise every remote caller is recorded as the loopback address.`]}),(0,$.jsx)(`p`,{className:`text-badge leading-normal text-text-tertiary`,children:`cloudflared and Tailscale are not installed by Cartethyia — install either one yourself first. The tunnel is launched detached from this process, so it survives a gateway restart.`})]})})]})}function Vt(){return(0,$.jsxs)(q,{gap:`16px`,children:[(0,$.jsx)(Rt,{}),(0,$.jsx)(zt,{}),(0,$.jsx)(Bt,{}),(0,$.jsx)(At,{}),(0,$.jsx)(kt,{})]})}export{Vt as default};
@@ -1 +0,0 @@
1
- import{n as e,o as t,r as n,t as r}from"./jsx-runtime-CXUMngI_.js";import{i,r as a}from"./terminal-0_IjPWTk.js";import{T as o,c as s,i as c,s as l,t as u}from"./numbers-Dulqgys5.js";import{t as d}from"./database-Dz9N3zGd.js";import{t as f}from"./eye-C_hawfH4.js";import{n as p,r as m}from"./state-DhZBfWgx.js";import{t as h}from"./layers-2-glBbjl.js";import{t as ee}from"./dialog-Iec_ywbD.js";import{n as g,r as te,t as _}from"./settings--3hxSyry.js";import{t as v}from"./trash-Cppn5c3R.js";import{t as y}from"./zap-C4EeVW4q.js";import{C as b,T as x,v as S}from"./assert-DU6qrMA_.js";import{a as C,i as w,l as T,o as E,s as D,t as O}from"./query-keys-UETqfytp.js";import{t as k}from"./useMutation-EDFRkn1i.js";import{it as A}from"./entry-DOddwoc0.js";import{n as j,r as M,t as N}from"./card-BOPBuBzD.js";import{n as ne,t as re}from"./download-dRFo5_Wu.js";import{n as P}from"./input-WlyHWeG2.js";import{t as F}from"./select-BfZ3SCTM.js";import{t as ie}from"./switch-yD7D99Lg.js";import{t as I}from"./stack-B1w5BM0u.js";import{t as L}from"./banner-C-7y3VKV.js";import{t as ae}from"./backup-file-gdKIlg8U.js";var oe=e(`archive`,[[`rect`,{width:`20`,height:`5`,x:`2`,y:`3`,rx:`1`,key:`1wp1u1`}],[`path`,{d:`M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8`,key:`1s80jp`}],[`path`,{d:`M10 12h4`,key:`a56b0p`}]]),se=e(`file-braces`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1`,key:`1oajmo`}],[`path`,{d:`M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1`,key:`mpwhp6`}]]),ce=e(`file-clock`,[[`path`,{d:`M16 22h2a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v2.85`,key:`ryk6xj`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}],[`path`,{d:`M8 14v2.2l1.6 1`,key:`6m4bie`}],[`circle`,{cx:`8`,cy:`16`,r:`6`,key:`10v15b`}]]),R=e(`hard-drive-download`,[[`path`,{d:`M12 2v8`,key:`1q4o3n`}],[`path`,{d:`m16 6-4 4-4-4`,key:`6wukr`}],[`rect`,{width:`20`,height:`8`,x:`2`,y:`14`,rx:`2`,key:`w68u3i`}],[`path`,{d:`M6 18h.01`,key:`uhywen`}],[`path`,{d:`M10 18h.01`,key:`h775k`}]]),z=e(`hard-drive`,[[`path`,{d:`M10 16h.01`,key:`1bzywj`}],[`path`,{d:`M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z`,key:`18tbho`}],[`path`,{d:`M21.946 12.013H2.054`,key:`zqlbp7`}],[`path`,{d:`M6 16h.01`,key:`1pmjb7`}]]),le=e(`upload`,[[`path`,{d:`M12 3v12`,key:`1x0j5s`}],[`path`,{d:`m17 8-5-5-5 5`,key:`7q97r8`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}]]),B=t(n(),1);function ue(){return k({mutationFn:async({password:e,sections:t,compressed:n,onProgress:r})=>{let i=new URLSearchParams({password:e});t!==void 0&&t.length>0&&i.set(`sections`,t),n===!0&&i.set(`compressed`,`1`);let a=`/backup/export?${i.toString()}`;if(n!==!0)return E(a);let o=await E(a),s=atob(o.bytes),c=Uint8Array.from(s,e=>e.charCodeAt(0));return r?.({loaded:c.byteLength,total:c.byteLength}),c}})}function de(){let e=x();return k({mutationFn:({password:e,scopes:t})=>E(`/backup/delete-all`,{method:`POST`,body:JSON.stringify({password:e,scopes:t})}),onSuccess:async()=>{await e.invalidateQueries()}})}function fe(){let e=x();return k({mutationFn:({password:e,backup:t,tables:n,onProgress:r})=>D(`/backup/import`,JSON.stringify({password:e,backup:t,...n===void 0||n.length===0?{}:{tables:[...n]}}),r),onSuccess:async()=>{await e.invalidateQueries()}})}function pe(){return k({mutationFn:({backup:e})=>E(`/backup/inspect`,{method:`POST`,body:JSON.stringify({backup:e})})})}var V=r();function me({title:e,description:t}){return(0,V.jsxs)(`div`,{className:`mb-6 min-w-0`,children:[(0,V.jsx)(`h3`,{className:`text-body-lg font-bold text-text-primary`,children:e}),(0,V.jsx)(`p`,{className:`mt-1 text-caption text-text-secondary`,children:t})]})}function H({icon:e,label:t,description:n,checked:r,onChange:i}){return(0,V.jsxs)(`label`,{className:`flex items-start gap-5 min-h-21 px-6 py-5 border border-inner-border rounded-control bg-surface-2 text-text-primary text-caption leading-snug cursor-pointer hover:border-border-strong hover:bg-hover has-checked:border-accent has-checked:bg-accent-soft`,children:[(0,V.jsx)(`input`,{type:`checkbox`,checked:r,onChange:i}),(0,V.jsx)(`span`,{className:`grid size-9 shrink-0 place-items-center rounded-control bg-surface-1 text-text-secondary`,children:(0,V.jsx)(e,{size:15,"aria-hidden":`true`})}),(0,V.jsxs)(`span`,{className:`flex flex-col gap-1 min-w-0`,children:[(0,V.jsx)(`strong`,{children:t}),(0,V.jsx)(`small`,{className:`text-text-tertiary text-badge`,children:n})]})]})}function he(e){return e===`providers`?A:e===`proxies`?a:h}function ge({report:e}){let t=Object.entries(e.imported).filter(([,e])=>e>0);return(0,V.jsxs)(I,{gap:`8px`,children:[t.length>0?(0,V.jsxs)(`p`,{className:`text-caption`,children:[`Imported:`,` `,t.map(([e,t])=>`${t} ${e}`).join(`, `)]}):null,e.remapped.length>0?(0,V.jsxs)(`p`,{className:`text-caption text-text-secondary`,children:[`Remapped provider ids: `,e.remapped.join(`, `)]}):null,e.skipped.length>0?(0,V.jsxs)(`div`,{children:[(0,V.jsxs)(`p`,{className:`text-caption text-yellow`,children:[`Skipped (`,e.skipped.length,`) — nothing was guessed:`]}),(0,V.jsx)(`ul`,{className:`text-caption text-text-tertiary mt-2 ml-8`,children:e.skipped.map(e=>(0,V.jsx)(`li`,{children:e},e))})]}):null,e.warnings.length>0?(0,V.jsxs)(`div`,{children:[(0,V.jsx)(`p`,{className:`text-caption text-text-secondary`,children:`Warnings:`}),(0,V.jsx)(`ul`,{className:`text-caption text-text-tertiary mt-2 ml-8`,children:e.warnings.map(e=>(0,V.jsx)(`li`,{children:e},e))})]}):null]})}function _e({warnings:e}){return e.length===0?null:(0,V.jsxs)(L,{tone:`warning`,surface:`raised`,live:`status`,children:[(0,V.jsxs)(`strong`,{children:[`Restore completed with `,e.length,` warning`,e.length===1?``:`s`]}),(0,V.jsx)(`ul`,{className:`mt-2 ml-8`,children:e.map((e,t)=>(0,V.jsxs)(`li`,{children:[e.table?`${e.table}${e.column?`.${e.column}`:``}: `:``,e.reason]},`${e.table??`backup`}:${e.column??`general`}:${t}`))})]})}function U(e){return e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(1)} KB`:`${(e/1048576).toFixed(1)} MB`}function ve(e,t){if(e===null)return t;let n=Math.max((Date.now()-e.startedAt)/1e3,.1),r=U(e.loaded/n);return`${e.total===null?U(e.loaded):`${U(e.loaded)} / ${U(e.total)}`} · ${r}/s`}function W(){let[e,t]=(0,B.useState)(``),[n,r]=(0,B.useState)(null),[i,a]=(0,B.useState)(!0),[c,u]=(0,B.useState)(!1),[f,p]=(0,B.useState)(!0),[m,h]=(0,B.useState)(null),[g,te]=(0,B.useState)(null),[_,y]=(0,B.useState)(null),[b,x]=(0,B.useState)(null),[S,C]=(0,B.useState)(null),[w,E]=(0,B.useState)(null),[D,O]=(0,B.useState)(new Set),[k,A]=(0,B.useState)(null),[j,M]=(0,B.useState)(null),[N,F]=(0,B.useState)(new Set),[oe,se]=(0,B.useState)(null),R=(0,B.useRef)(null),z=ue(),U=fe(),W=de(),ye=pe(),be=e=>{O(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},G=()=>{r(null),t(``)},xe=()=>{D.size!==0&&(t(``),r(`delete`))},Se=async()=>{if(e.length===0)return;let t=await W.mutateAsync({password:e,scopes:[...D]});O(new Set),G(),l.success(`Selected configuration deleted.`,Object.entries(t.deleted).map(([e,t])=>`${e}: ${t}`).join(` · `))},K=()=>{let t=[...i?[`config`]:[],...c?[`telemetry`]:[]].join(`,`);if(t.length===0){l.error(`Select at least one backup section.`);return}z.mutate({password:e,sections:t,compressed:f,onProgress:e=>h(t=>({...e,startedAt:t?.startedAt??Date.now()}))},{onSuccess:e=>{let t=new Date().toISOString().slice(0,19).replace(/[:T]/g,`-`);e instanceof Uint8Array?re(`cartethyia_backup_${t}.json.gz`,e,`application/gzip`):ne(`cartethyia_backup_${t}.json`,JSON.stringify(e,null,2),`application/json`),G(),l.success(`Backup downloaded.`)},onError:e=>l.error(T(e,`Backup export failed.`))})},q=async e=>{te(null),y(null),x(null),C(null),E(null),se(null),M(null),F(new Set),A(e);try{let t=await ae(e),n=await ye.mutateAsync({backup:t});M(n),F(new Set(n.rows.filter(e=>e.supported).map(e=>e.table)))}catch(e){A(null),l.error(`Could not read that backup`,T(e,`The file is not a readable backup.`))}},Ce=e=>{F(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},J=()=>{M(null),A(null),se(null)},we=()=>{k!==null&&N.size!==0&&(t(``),x(null),r(`restore`))},Te=async()=>{let t=k;if(t!==null){x(null);try{let n=await ae(t),r=await U.mutateAsync({password:e,backup:n,tables:[...N],onProgress:e=>h(t=>({...e,startedAt:t?.startedAt??Date.now()}))});te(r.restored),y(r.warnings),C(r.report??null),E(r.format),G(),A(null),M(null),l.success(r.warnings.length===0?`Restore complete.`:`Restore completed with warnings.`,r.warnings.length===0?null:`${r.warnings.length} item(s) need attention. See the restore report below.`)}catch(e){let t=T(e,`Backup restore failed.`);x(t),l.error(`Backup restore failed`,t)}}},Ee=g===null?[]:Object.entries(g);return(0,V.jsxs)(V.Fragment,{children:[(0,V.jsxs)(`div`,{className:`grid grid-cols-2 gap-8 w-full min-w-0 max-medium:grid-cols-1`,children:[(0,V.jsxs)(`section`,{"aria-label":`Backup`,className:`min-w-0`,children:[(0,V.jsx)(me,{title:`Export and restore`,description:`Download a JSON snapshot, or restore one you already trust.`}),(0,V.jsxs)(I,{gap:`14px`,children:[(0,V.jsxs)(`fieldset`,{className:`grid grid-cols-2 gap-5 min-w-0 border-0 m-0 p-0 max-medium:grid-cols-1`,children:[(0,V.jsx)(`legend`,{className:`mb-4 text-text-secondary text-caption font-semibold`,children:`Include in the download`}),(0,V.jsx)(H,{icon:d,label:`Account, proxy & settings`,description:`Credentials, API-key hashes, routing, and settings`,checked:i,onChange:()=>a(!i)}),(0,V.jsx)(H,{icon:ce,label:`Telemetry history`,description:`Status, tokens, cost, latency — never prompt bodies`,checked:c,onChange:()=>u(!c)})]}),(0,V.jsxs)(`div`,{className:`flex items-center justify-between gap-6 rounded-control border border-inner-border px-6 py-5`,children:[(0,V.jsxs)(`span`,{children:[(0,V.jsx)(`strong`,{className:`block text-body`,children:`Highly Compress Backup`}),(0,V.jsx)(`small`,{className:`text-caption text-text-tertiary`,children:`Makes the download smaller.`})]}),(0,V.jsx)(ie,{checked:f,onChange:p,"aria-label":`Highly Compress Backup`})]}),(0,V.jsx)(`p`,{className:`mt-1 text-caption text-text-tertiary`,children:`The file contains provider credentials. Treat it like the database. Prompt and response bodies, health-event history, and console sessions are left out.`}),(0,V.jsxs)(`div`,{className:`mt-auto flex justify-end gap-4`,children:[(0,V.jsx)(s,{variant:`primary`,size:`sm`,onClick:()=>{t(``),r(`download`)},disabled:!i&&!c,icon:(0,V.jsx)(o,{size:13}),children:`Download backup`}),(0,V.jsx)(s,{variant:`secondary`,size:`sm`,onClick:()=>R.current?.click(),icon:(0,V.jsx)(le,{size:13}),children:`Restore from file`}),(0,V.jsx)(`input`,{ref:R,type:`file`,accept:`application/json,.json,.gz,application/gzip`,className:`sr-only`,onChange:e=>{let t=e.target.files?.[0];t&&q(t),e.target.value=``}})]}),w===null?null:(0,V.jsxs)(`p`,{className:`mt-1 text-caption text-text-tertiary`,children:[`Detected format:`,` `,w===`nine_router`?`router export`:`Cartethyia backup`]}),g===null?null:(0,V.jsxs)(L,{tone:`success`,surface:`raised`,live:`status`,children:[(0,V.jsx)(`strong`,{children:`Restore complete`}),Ee.length>0?(0,V.jsx)(`ul`,{children:Ee.map(([e,t])=>(0,V.jsxs)(`li`,{children:[e,`: `,t]},e))}):(0,V.jsx)(`p`,{children:`No rows were imported.`})]}),_===null?null:(0,V.jsx)(_e,{warnings:_}),S===null?null:(0,V.jsx)(ge,{report:S})]})]}),(0,V.jsxs)(`section`,{"aria-label":`Delete data`,className:`min-w-0`,children:[(0,V.jsx)(me,{title:`Delete data`,description:`Removes the scopes you check. Console users, sessions, and audit history stay.`}),(0,V.jsxs)(I,{gap:`12px`,children:[(0,V.jsxs)(`fieldset`,{className:`grid grid-cols-1 gap-5 min-w-0 border-0 m-0 p-0`,children:[(0,V.jsx)(`legend`,{className:`mb-4 text-text-secondary text-caption font-semibold`,children:`Delete`}),[[`providers`,`Providers`,`Accounts, credentials, tenant models, routing, and account health`],[`proxies`,`Proxies`,`Network pools, pool settings, and pool health`],[`configuration`,`All configuration`,`Providers, proxies, aliases, combos, API keys, CLI tools, and settings`]].map(([e,t,n])=>(0,V.jsx)(H,{icon:he(e),label:t,description:n,checked:D.has(e),onChange:()=>be(e)},e))]}),(0,V.jsx)(`div`,{className:`mt-auto flex justify-end gap-4 flex-wrap`,children:(0,V.jsx)(s,{variant:`danger`,size:`sm`,icon:(0,V.jsx)(v,{size:14}),disabled:D.size===0,onClick:xe,children:`Delete selected`})})]})]})]}),(0,V.jsx)(ee,{open:j!==null,onClose:J,title:`Restore from backup`,description:`Choose which parts of this file to restore, then confirm with your console password.`,size:`md`,footer:(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(s,{variant:`secondary`,size:`sm`,onClick:J,children:`Cancel`}),(0,V.jsx)(s,{variant:`primary`,size:`sm`,disabled:N.size===0,onClick:we,children:`Restore now`})]}),children:(0,V.jsx)(I,{gap:`12px`,children:j===null?null:(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(`p`,{className:`text-caption text-text-tertiary`,children:j.format===`nine_router`?`Router export — it is converted at restore time, so every table it produces is restored.`:`${j.total} rows · exported ${j.exportedAt||`unknown date`}`}),j.rows.length>0?(0,V.jsxs)(`fieldset`,{className:`grid grid-cols-1 gap-4 min-w-0 border-0 m-0 p-0`,children:[(0,V.jsx)(`legend`,{className:`mb-3 text-text-secondary text-caption font-semibold`,children:`Restore these tables`}),(0,V.jsxs)(`div`,{className:`flex justify-end gap-4`,children:[(0,V.jsx)(`button`,{type:`button`,className:`text-badge text-accent hover:underline`,onClick:()=>F(new Set(j.rows.filter(e=>e.supported).map(e=>e.table))),children:`Select all`}),(0,V.jsx)(`button`,{type:`button`,className:`text-badge text-text-secondary hover:underline`,onClick:()=>F(new Set),children:`Select none`})]}),j.rows.map(e=>(0,V.jsxs)(`label`,{className:`flex items-start gap-4 px-5 py-4 border border-inner-border rounded-control bg-surface-2 text-caption leading-snug cursor-pointer hover:border-border-strong hover:bg-hover has-checked:border-accent has-checked:bg-accent-soft`,children:[(0,V.jsx)(`input`,{type:`checkbox`,checked:N.has(e.table),disabled:!e.supported,onChange:()=>Ce(e.table)}),(0,V.jsxs)(`span`,{className:`flex flex-col gap-1 min-w-0`,children:[(0,V.jsx)(`strong`,{className:`text-text-primary`,children:e.table}),(0,V.jsxs)(`small`,{className:`text-text-tertiary text-badge`,children:[e.count,` rows · `,e.section,e.supported?``:` · not in the current schema, will be skipped`]})]})]},`${e.section}:${e.table}`))]}):null,oe===null?null:(0,V.jsx)(`p`,{role:`alert`,className:`text-caption text-red`,children:oe})]})})}),(0,V.jsx)(ee,{open:n!==null,onClose:G,title:n===`delete`?`Confirm deletion`:n===`restore`?`Restore backup`:`Download backup`,description:`The console password is checked again before this runs.`,size:`sm`,footer:(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(s,{variant:`secondary`,size:`sm`,onClick:G,children:`Cancel`}),(0,V.jsx)(s,{variant:n===`delete`?`danger`:`primary`,size:`sm`,loading:z.isPending||U.isPending||W.isPending,disabled:e.length===0||z.isPending||U.isPending||W.isPending,onClick:()=>{h(null),n===`download`?K():n===`restore`?Te():Se()},children:z.isPending?ve(m,`Downloading…`):U.isPending?ve(m,`Uploading…`):W.isPending?`Working…`:n===`delete`?`Delete permanently`:n===`restore`?`Restore`:`Download`})]}),children:(0,V.jsxs)(I,{gap:`10px`,children:[n===`restore`&&b!==null?(0,V.jsx)(`p`,{role:`alert`,className:`text-caption text-red`,children:b}):null,(0,V.jsx)(`p`,{className:`mt-1 text-caption text-text-tertiary`,children:n===`delete`?`This cannot be undone. The password is verified again before anything is removed.`:n===`restore`?`Restore replaces the tenant configuration in this file. Continue only if the file is trusted.`:`The export is plain JSON and contains provider credentials.`}),(0,V.jsx)(P,{label:`Console password`,type:`password`,value:e,onChange:e=>t(e.target.value),autoComplete:`current-password`,"data-autofocus":!0})]})})]})}function ye(){return b({queryKey:O.settings.diskUsage,queryFn:e=>E(`/data-management/usage`,{signal:S(e)}),...w,staleTime:C.status})}function be(){let e=x();return k({mutationFn:e=>E(`/data-management/reclaim`,{method:`POST`,body:JSON.stringify({action:e})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:O.settings.diskUsage})}})}function G(){return k({mutationFn:()=>E(`/data-management/flush`,{method:`POST`})})}function xe(){let e=x();return k({mutationFn:()=>E(`/data-management/purge`,{method:`POST`,body:JSON.stringify({target:`health_events`})}),onSuccess:async()=>{await e.invalidateQueries({queryKey:O.settings.diskUsage})}})}function Se(){let e=ye(),t=be(),n=G(),r=xe(),[a,o]=(0,B.useState)(null),[d,f]=(0,B.useState)(!1);if(e.isPending)return(0,V.jsx)(m,{label:`Measuring disk usage…`});if(e.isError||!e.data)return(0,V.jsx)(p,{message:T(e.error,`Failed to measure disk usage`),onRetry:()=>void e.refetch()});let h=e.data,ee=e=>{e!==null&&(o(null),t.mutate(e,{onSuccess:e=>{if(e.deletedFiles===0){l.success(`Nothing to reclaim.`);return}l.success(`Reclaimed ${u(e.reclaimedBytes)} across ${c(e.deletedFiles)} file${e.deletedFiles===1?``:`s`}.`)},onError:e=>l.error(T(e,`Reclaim failed.`))}))},g=h.healthEventCount;return(0,V.jsxs)(I,{gap:`14px`,children:[(0,V.jsxs)(`div`,{className:`flex items-center justify-between gap-4 flex-wrap`,children:[(0,V.jsxs)(`span`,{className:`text-caption text-text-tertiary`,children:[u(h.totalBytes),` on disk across`,` `,c(h.buckets.reduce((e,t)=>e+t.files,0)),` files`]}),(0,V.jsx)(s,{variant:`secondary`,size:`sm`,icon:(0,V.jsx)(z,{size:14}),onClick:()=>void e.refetch(),disabled:e.isFetching,children:e.isFetching?`Measuring…`:`Refresh`})]}),(0,V.jsxs)(`div`,{className:`settings-bucket-grid`,children:[h.buckets.map(e=>{let n=q(e);return(0,V.jsx)(J,{bucket:e,busy:t.isPending,confirming:n!==null&&a===n,onAsk:()=>o(n),onCancel:()=>o(null),onConfirm:()=>ee(n)},e.id)}),(0,V.jsx)(K,{icon:i,title:`Health & Error Log`,note:g===void 0?`Purging is not offered in this deployment's console composition.`:`${c(g)} recorded transition${g===1?``:`s`} across accounts and pools. Purge clears only this audit trail — account statuses and cooldowns stay as they are, and this cannot be undone.`,testId:`health_events`,children:g===void 0?null:d?(0,V.jsx)(`span`,{className:`flex flex-col gap-3`,children:(0,V.jsxs)(`span`,{className:`flex items-center gap-3`,children:[(0,V.jsx)(s,{variant:`secondary`,size:`sm`,onClick:()=>f(!1),disabled:r.isPending,children:`Cancel`}),(0,V.jsx)(s,{variant:`danger`,size:`sm`,icon:(0,V.jsx)(v,{size:14}),disabled:r.isPending,onClick:()=>r.mutate(void 0,{onSuccess:e=>{f(!1),l.success(e.deleted===0?`Health & error log was already empty.`:`Purged ${c(e.deleted)} health event${e.deleted===1?``:`s`}.`)},onError:e=>l.error(T(e,`Purge failed.`))}),children:`Delete`})]})}):(0,V.jsx)(s,{variant:`secondary`,size:`sm`,icon:(0,V.jsx)(v,{size:14}),disabled:r.isPending||g===0,onClick:()=>f(!0),children:`Purge`})}),(0,V.jsx)(K,{icon:R,title:`Flush pending writes`,note:`Write queued telemetry, usage, and health events now instead of waiting for the interval. Nothing is deleted.`,testId:`flush`,children:(0,V.jsx)(s,{variant:`secondary`,size:`sm`,icon:(0,V.jsx)(y,{size:14}),disabled:n.isPending,onClick:()=>n.mutate(void 0,{onSuccess:()=>l.success(`Buffers flushed.`),onError:e=>l.error(T(e,`Flush failed.`))}),children:n.isPending?`Flushing…`:`Flush`})})]}),t.isError?(0,V.jsx)(L,{tone:`danger`,surface:`raised`,live:`status`,children:T(t.error,`Reclaim failed.`)}):null]})}function K({icon:e,title:t,note:n,children:r,testId:i}){return(0,V.jsxs)(`div`,{"data-panel":i,className:`flex flex-col rounded-control border border-inner-border px-6 py-5 min-w-0`,children:[(0,V.jsxs)(`span`,{className:`flex items-start gap-4`,children:[(0,V.jsx)(`span`,{className:`grid size-9 shrink-0 place-items-center rounded-control bg-surface-1 text-text-secondary`,children:(0,V.jsx)(e,{size:15,"aria-hidden":`true`})}),(0,V.jsxs)(`span`,{className:`min-w-0`,children:[(0,V.jsx)(`span`,{className:`block text-caption text-text-tertiary`,children:t}),(0,V.jsx)(`span`,{className:`mt-1 block text-caption text-text-tertiary`,children:n})]})]}),(0,V.jsx)(`div`,{className:`mt-auto flex justify-end pt-5`,children:r})]})}function q(e){return e.id===`payload_frames`?`payload_frames`:e.id===`telemetry_events`?`telemetry_retention`:null}function Ce(e){return e.id===`payload_frames`?se:ce}function J({bucket:e,busy:t,confirming:n,onAsk:r,onCancel:i,onConfirm:a}){let o=q(e),l=e.reclaimableBytes!==null,d=e.reclaimableBytes??0,f=e.reclaimableFiles??0,p=l&&d===0,m=Ce(e);return(0,V.jsxs)(`div`,{"data-bucket":e.id,className:`flex flex-col rounded-control border border-inner-border px-6 py-5 min-w-0`,children:[(0,V.jsxs)(`span`,{className:`flex items-start gap-4`,children:[(0,V.jsx)(`span`,{className:`grid size-9 shrink-0 place-items-center rounded-control bg-surface-1 text-text-secondary`,children:(0,V.jsx)(m,{size:15,"aria-hidden":`true`})}),(0,V.jsxs)(`span`,{className:`min-w-0`,children:[(0,V.jsx)(`span`,{className:`block text-caption text-text-tertiary`,children:e.label}),(0,V.jsx)(`span`,{className:`mt-1 block text-lead font-semibold text-text-primary`,children:u(e.bytes)}),(0,V.jsxs)(`span`,{className:`block text-caption text-text-tertiary`,children:[c(e.files),` file`,e.files===1?``:`s`,` · `,e.note]})]})]}),(0,V.jsx)(`div`,{className:`mt-auto flex justify-end pt-5`,children:o===null?(0,V.jsx)(`p`,{className:`text-caption text-text-tertiary`,children:`Kept — no other copy.`}):n?(0,V.jsxs)(`span`,{className:`flex flex-col gap-3`,children:[(0,V.jsx)(`span`,{className:`text-caption text-text-secondary`,children:l?`Delete ${c(f)} file${f===1?``:`s`}, ${u(d)}?`:`Delete raw event files past the retention window?`}),(0,V.jsxs)(`span`,{className:`flex items-center gap-3`,children:[(0,V.jsx)(s,{variant:`secondary`,size:`sm`,onClick:i,disabled:t,children:`Cancel`}),(0,V.jsx)(s,{variant:`danger`,size:`sm`,icon:(0,V.jsx)(v,{size:14}),onClick:a,disabled:t,children:`Delete`})]})]}):(0,V.jsxs)(`span`,{className:`flex items-center justify-between gap-3 flex-wrap`,children:[(0,V.jsx)(`span`,{className:`text-caption text-text-tertiary`,children:l?p?`Clean`:`${u(d)} free`:`Expired events only`}),(0,V.jsx)(s,{variant:`secondary`,size:`sm`,icon:(0,V.jsx)(v,{size:14}),onClick:r,disabled:t||p,children:`Reclaim`})]})})]})}function we(){return k({mutationFn:e=>E(`/auth/change-password`,{method:`POST`,body:JSON.stringify(e)})})}var Te=[5,15,30,60,120,300,600],Ee=[5,15,30,60,180,720,1440],De=[1,5,10,25,50,100];function Oe({name:e}){let t={size:16};return e===`privacy`?(0,V.jsx)(f,{...t}):e===`operations`?(0,V.jsx)(y,{...t}):e===`data`?(0,V.jsx)(oe,{...t}):e===`data-management`?(0,V.jsx)(d,{...t}):(0,V.jsx)(te,{...t})}function Y(e,t,n){return(t===null||e.includes(t)?[...e]:[...e,t].sort((e,t)=>e-t)).map(e=>({value:String(e),label:n(e)}))}var ke=[{id:`security`,title:`Security`,description:`Change the password used to sign in to this console.`},{id:`privacy`,title:`Privacy`,description:`What request telemetry stores, and how client addresses are shown.`},{id:`backup`,title:`Backup`,description:`Export or restore this tenant's configuration and history.`},{id:`operations`,title:`Operations`,description:`Routing, admission, request handling, and response shaping for this tenant.`},{id:`data-management`,title:`Data Management`,description:`See what the gateway keeps on disk, reclaim space, and flush queued writes.`}];function X(e){if(e%1440==0){let t=e/1440;return`${t} day${t===1?``:`s`}`}if(e%60==0){let t=e/60;return`${t} hour${t===1?``:`s`}`}return`${e} min`}function Z(e){return`Deployment default (${e})`}function Ae(e){return`${Math.round(e/1048576)} MB`}function Q({label:e,hint:t,labelFor:n,control:r}){return(0,V.jsxs)(`div`,{className:`settings-row`,children:[(0,V.jsxs)(`div`,{className:`settings-row-text`,children:[n?(0,V.jsx)(`label`,{className:`settings-row-label`,htmlFor:n,children:e}):(0,V.jsx)(`span`,{className:`settings-row-label`,children:e}),t?(0,V.jsx)(`p`,{className:`settings-row-hint`,children:t}):null]}),(0,V.jsx)(`div`,{className:`settings-row-control`,children:r})]})}function $({title:e}){return(0,V.jsx)(`p`,{className:`settings-group-head`,children:e})}function je({id:e,title:t,description:n,children:r}){return(0,V.jsxs)(N,{id:e,"aria-label":t,className:`min-w-0`,children:[(0,V.jsx)(M,{title:t,subtitle:n,icon:(0,V.jsx)(Oe,{name:e})}),(0,V.jsx)(j,{className:`flex flex-col gap-0`,children:r})]})}function Me(){let e=_(),t=g(),n=e.data;return e.isPending?(0,V.jsx)(m,{label:`Loading privacy settings…`}):e.isError||!n?(0,V.jsx)(p,{message:T(e.error,`Failed to load runtime settings`),onRetry:()=>void e.refetch()}):(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Q,{label:`Telemetry payloads`,labelFor:`privacy-payloads`,hint:`Request metadata is always kept. Bodies stay off until you turn them on, and anything captured is redacted and deleted when the Request detail window in Operations runs out.`,control:(0,V.jsx)(F,{"aria-label":`Telemetry payloads`,id:`privacy-payloads`,value:n.telemetryPayloads,onValueChange:e=>t.mutate({telemetryPayloads:e===`full`||e===`metadata`?e:`none`},{onSuccess:()=>l.success(`Payload capture updated`),onError:e=>l.error(T(e,`Could not update payload capture.`))}),options:[{value:`none`,label:`Off — no payload capture`},{value:`metadata`,label:`Metadata — method and headers only`},{value:`full`,label:`Full — redacted bodies`}]})}),n.telemetryPayloads===`full`?(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Q,{label:`Capture depth`,labelFor:`privacy-payload-depth`,hint:`Size cap for each captured body.`,control:(0,V.jsx)(F,{"aria-label":`Capture depth`,id:`privacy-payload-depth`,value:n.telemetryPayloadDepth,onValueChange:e=>t.mutate({telemetryPayloadDepth:e===`moderate`||e===`maximum`?e:`minimum`},{onSuccess:()=>l.success(`Capture depth updated`),onError:e=>l.error(T(e,`Could not update capture depth.`))}),options:[{value:`minimum`,label:`Minimum — 1 MiB cap`},{value:`moderate`,label:`Moderate — 8 MiB cap`},{value:`maximum`,label:`Maximum — 16 MiB cap`}]})}),n.telemetryPayloadDepth===`minimum`?null:(0,V.jsx)(`div`,{className:`settings-row-banner`,children:(0,V.jsxs)(L,{tone:`warning`,surface:`raised`,className:`text-text-secondary`,children:[(0,V.jsx)(`strong`,{children:`High CPU and memory while this is on.`}),` Use it to debug, then switch back to Metadata or Minimum.`]})})]}):null,(0,V.jsx)(Q,{label:`Client IP display`,labelFor:`privacy-ip`,hint:`Raw addresses stay stored and are still written to telemetry. This only changes how they are shown in the console.`,control:(0,V.jsx)(F,{"aria-label":`Client IP display`,id:`privacy-ip`,value:n.privacyMode,onValueChange:e=>t.mutate({privacyMode:e===`full`?`full`:`masked`},{onSuccess:()=>l.success(`IP display updated`),onError:e=>l.error(T(e,`Could not update IP display.`))}),options:[{value:`masked`,label:`Masked — recommended`},{value:`full`,label:`Show full IP`}]})})]})}function Ne(){let e=_(),t=g(),n=e.data;if(e.isPending)return(0,V.jsx)(m,{label:`Loading operational settings…`});if(e.isError||!n)return(0,V.jsx)(p,{message:T(e.error,`Failed to load runtime settings`),onRetry:()=>void e.refetch()});let r=(e,n)=>{t.mutate(e,{onSuccess:()=>l.success(n),onError:e=>l.error(T(e,`Could not update settings.`))})};return(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)($,{title:`Routing`}),(0,V.jsx)(Q,{label:`Ignore cooldowns`,labelFor:`ignore-cooldowns`,hint:`Route to accounts that are cooling down, including ones already parked. Off by default: a cooling account stays out of the rotation until it resets. On dials it anyway, which is what the warning below is about.`,control:(0,V.jsx)(F,{"aria-label":`Ignore cooldowns`,id:`ignore-cooldowns`,value:n.forceDisableCooldown?`on`:`off`,onValueChange:e=>{let t=e===`on`;r({forceDisableCooldown:t},t?`Cooldowns are ignored.`:`Cooldowns are enforced again.`)},options:[{value:`off`,label:`Off — default`},{value:`on`,label:`On`}]})}),n.forceDisableCooldown?(0,V.jsx)(`div`,{className:`settings-row-banner`,children:(0,V.jsxs)(L,{tone:`warning`,surface:`raised`,live:`status`,children:[(0,V.jsx)(`strong`,{children:`This may cause admission failure.`}),` A cooled-down account was parked because the upstream refused it, so dialing it anyway reproduces that refusal on every attempt — and if every candidate is cooling, the request fails instead of waiting for a reset. The cooldown is still recorded and still recovered by the sweep, so turning this back off needs no cleanup. Per-model cooldowns are still enforced.`]})}):null,(0,V.jsx)($,{title:`Admission`}),(0,V.jsx)(Q,{label:`Tenant concurrency limit`,labelFor:`tenant-concurrency-limit`,hint:`Ceiling on requests in flight across every key in this tenant at once. Empty means no tenant-wide ceiling — each key is then bounded only by its own limit.`,control:(0,V.jsx)(P,{id:`tenant-concurrency-limit`,"aria-label":`Tenant concurrency limit`,type:`number`,min:`1`,step:`1`,inputMode:`numeric`,placeholder:`No ceiling`,value:n.tenantConcurrencyLimit?.toString()??``,onChange:e=>{let t=e.target.value.trim();if(t===``){r({tenantConcurrencyLimit:null},`Tenant ceiling removed.`);return}let n=Number(t);!Number.isInteger(n)||n<1||r({tenantConcurrencyLimit:n},`Tenant concurrency limit updated.`)}})}),(0,V.jsx)(Q,{label:`Concurrency tolerance`,labelFor:`concurrency-tolerance`,hint:`Slack added above a key's own concurrency limit. The effective ceiling is the key's limit plus this, so a run landing a few over is not refused at the number it was told.`,control:(0,V.jsx)(P,{id:`concurrency-tolerance`,"aria-label":`Concurrency tolerance`,type:`number`,min:`0`,max:`1024`,step:`1`,inputMode:`numeric`,placeholder:`None`,value:n.concurrencyTolerance?.toString()??``,onChange:e=>{let t=e.target.value.trim();if(t===``){r({concurrencyTolerance:null},`Tolerance removed.`);return}let n=Number(t);!Number.isInteger(n)||n<0||n>1024||r({concurrencyTolerance:n},`Concurrency tolerance updated.`)}})}),(0,V.jsx)($,{title:`Request handling`}),(0,V.jsx)(Q,{label:`Upstream timeout`,labelFor:`upstream-timeout`,hint:`5–600 seconds, ${n.defaults.upstreamTimeoutSeconds}s when unset. Applied when the request is dispatched, so it can only shorten a deadline that has already started.`,control:(0,V.jsx)(F,{"aria-label":`Upstream timeout`,id:`upstream-timeout`,value:n.upstreamTimeoutSeconds?.toString()??``,placeholder:Z(`${n.defaults.upstreamTimeoutSeconds} seconds`),onValueChange:e=>r({upstreamTimeoutSeconds:e===``?null:Number(e)},`Upstream timeout updated.`),options:[...Y(Te,n.upstreamTimeoutSeconds,e=>`${e} seconds`),{value:``,label:Z(`${n.defaults.upstreamTimeoutSeconds} seconds`)}]})}),(0,V.jsx)(Q,{label:`Request detail window`,labelFor:`telemetry-window-minutes`,hint:`1–1440 minutes, ${X(n.defaults.telemetryWindowMinutes)} when unset. Controls how long captured payload frames are kept — the same number Data Management reports as what payload frames expire after. Raw request events follow the ${n.defaults.telemetryRetentionDays}-day server retention instead.`,control:(0,V.jsx)(F,{"aria-label":`Request detail window`,id:`telemetry-window-minutes`,value:n.telemetryWindowMinutes?.toString()??``,placeholder:Z(X(n.defaults.telemetryWindowMinutes)),onValueChange:e=>r({telemetryWindowMinutes:e===``?null:Number(e)},`Detail window updated.`),options:[...Y(Ee,n.telemetryWindowMinutes,X),{value:``,label:Z(X(n.defaults.telemetryWindowMinutes))}]})}),(0,V.jsx)(Q,{label:`Max attachment size`,labelFor:`image-clamp-max-bytes`,hint:`Per image, ${Ae(n.defaults.imageClampMaxBytes)} when unset. An oversized attachment is refused before send rather than after the upstream rejects it — a block too large poisons every retry and every replayed turn. Raising this asserts your upstreams accept more; lowering it is the safer direction. Applies to the Messages and Gemini wires.`,control:(0,V.jsx)(F,{"aria-label":`Max attachment size`,id:`image-clamp-max-bytes`,value:n.imageClampMaxBytes===null?``:String(Math.round(n.imageClampMaxBytes/1048576)),placeholder:Z(Ae(n.defaults.imageClampMaxBytes)),onValueChange:e=>r({imageClampMaxBytes:e===``?null:Number(e)*1024*1024},`Attachment size limit updated.`),options:[...Y(De,n.imageClampMaxBytes===null?null:Math.round(n.imageClampMaxBytes/1048576),e=>`${e} MB`),{value:``,label:Z(Ae(n.defaults.imageClampMaxBytes))}]})}),(0,V.jsx)($,{title:`Response shaping`}),(0,V.jsx)(Q,{label:`Thinking normalization`,labelFor:`thinking-normalization`,hint:`Rewrite a provider's native thinking config into the canonical shape on turns where the user is not the final reader. Off by default: the upstream's own config is passed through untouched.`,control:(0,V.jsx)(F,{"aria-label":`Thinking normalization`,id:`thinking-normalization`,value:n.thinkingNormalizationEnabled?`on`:`off`,onValueChange:e=>{let t=e===`on`;r({thinkingNormalizationEnabled:t},t?`Thinking config will be normalized.`:`Upstream thinking config is left as sent.`)},options:[{value:`off`,label:`Off — default`},{value:`on`,label:`On`}]})}),(0,V.jsx)(Q,{label:`Reasoning summary`,labelFor:`responses-reasoning-summary`,hint:`Verbosity of the reasoning summary on the Responses wire, forced even when a request carries no reasoning block. Applies when the routed model is Responses and the client called a Chat surface.`,control:(0,V.jsx)(F,{"aria-label":`Reasoning summary`,id:`responses-reasoning-summary`,value:n.responsesReasoningSummary,onValueChange:e=>r({responsesReasoningSummary:e===`concise`||e===`detailed`?e:`auto`},`Reasoning summary updated.`),options:[{value:`auto`,label:`Auto — follow the request`},{value:`concise`,label:`Concise`},{value:`detailed`,label:`Detailed — default`}]})})]})}function Pe(){let e=we(),[t,n]=(0,B.useState)(``),[r,i]=(0,B.useState)(``),[a,o]=(0,B.useState)(``),[c,l]=(0,B.useState)(null),[u,d]=(0,B.useState)(!1);return(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Q,{label:`Current password`,labelFor:`current-password`,hint:`This is the password for this console, not for any upstream provider. Provider credentials live on each provider in Providers.`,control:(0,V.jsx)(P,{id:`current-password`,"aria-label":`Current password`,type:`password`,value:t,onChange:e=>n(e.target.value),autoComplete:`current-password`})}),(0,V.jsx)(Q,{label:`New password`,labelFor:`new-password`,hint:`Minimum 8 characters. A passphrase is easier to remember and harder to guess.`,control:(0,V.jsx)(P,{id:`new-password`,"aria-label":`New password`,type:`password`,value:r,onChange:e=>i(e.target.value),autoComplete:`new-password`})}),(0,V.jsx)(Q,{label:`Confirm new password`,labelFor:`confirm-password`,control:(0,V.jsx)(P,{id:`confirm-password`,"aria-label":`Confirm new password`,type:`password`,value:a,onChange:e=>o(e.target.value),autoComplete:`new-password`})}),c?(0,V.jsx)(`p`,{role:`alert`,className:`settings-feedback`,"data-tone":`err`,children:c}):null,u?(0,V.jsx)(`p`,{role:`status`,className:`settings-feedback`,"data-tone":`ok`,children:`Password updated.`}):null,(0,V.jsx)(`div`,{className:`settings-actions`,children:(0,V.jsx)(s,{variant:`primary`,size:`sm`,onClick:()=>{if(d(!1),r.length<8){l(`New password must be at least 8 characters.`);return}if(r!==a){l(`New password and confirmation do not match.`);return}l(null),e.mutate({currentPassword:t,newPassword:r},{onSuccess:()=>{d(!0),n(``),i(``),o(``)},onError:e=>l(T(e,`Password change failed.`))})},disabled:e.isPending||!t||!r||!a,children:e.isPending?`Updating…`:`Update password`})})]})}var Fe={security:(0,V.jsx)(Pe,{}),privacy:(0,V.jsx)(Me,{}),operations:(0,V.jsx)(Ne,{}),backup:(0,V.jsx)(W,{}),"data-management":(0,V.jsx)(Se,{})},Ie=[`security`,`privacy`];function Le(){return(0,V.jsxs)(`div`,{className:`settings-page`,children:[(0,V.jsx)(`div`,{className:`settings-grid`,children:Ie.map(e=>{let t=ke.find(t=>t.id===e);return t?(0,V.jsx)(je,{id:t.id,title:t.title,description:t.description,children:Fe[t.id]},e):null})}),ke.filter(e=>!Ie.includes(e.id)).map(e=>(0,V.jsx)(je,{id:e.id,title:e.title,description:e.description,children:Fe[e.id]},e.id))]})}export{Y as boundedOptions,Le as default};