ai-zero-token 2.0.4 → 2.0.5
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.
- package/CHANGELOG.md +10 -0
- package/README.md +17 -2
- package/README.zh-CN.md +18 -3
- package/admin-ui/dist/assets/{accounts-CTjk9c4F.js → accounts-ABMyXo4H.js} +1 -1
- package/admin-ui/dist/assets/{docs-oNIugCIL.js → docs-Dh0aFha_.js} +1 -1
- package/admin-ui/dist/assets/{image-bed-CQtIhjg_.js → image-bed-C1M7-0q1.js} +1 -1
- package/admin-ui/dist/assets/{index-rgcJgVAu.js → index--rNjdmzf.js} +2 -2
- package/admin-ui/dist/assets/{index-By4r-wy3.css → index-DjtN30PC.css} +1 -1
- package/admin-ui/dist/assets/{launch-B-2Zdz9m.js → launch-pB7YlWFI.js} +1 -1
- package/admin-ui/dist/assets/{logs-JFuSf56b.js → logs-B7McijSi.js} +1 -1
- package/admin-ui/dist/assets/{network-detect-SfvK6uhx.js → network-detect-Bx3XmXPk.js} +1 -1
- package/admin-ui/dist/assets/{overview-X_WodIqE.js → overview-CV0H2Nsq.js} +1 -1
- package/admin-ui/dist/assets/settings-ynCIdUvZ.js +7 -0
- package/admin-ui/dist/assets/{tester-ocpF053C.js → tester-BG-up8qP.js} +1 -1
- package/admin-ui/dist/index.html +2 -2
- package/dist/core/providers/http-client.js +228 -3
- package/dist/core/providers/openai-codex/chat.js +83 -23
- package/dist/core/services/auth-service.js +14 -5
- package/dist/core/services/config-service.js +15 -5
- package/dist/core/store/codex-auth-store.js +295 -4
- package/dist/core/store/settings-store.js +54 -24
- package/dist/server/app.js +410 -49
- package/docs/API_USAGE.md +18 -1
- package/docs/DESKTOP_RELEASE.md +12 -1
- package/package.json +1 -1
- package/admin-ui/dist/assets/settings-0eXUAvcm.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light;--bg:#f8fafc;--panel:#fff;--panel-soft:#f8fafc;--line:#e2e8f0;--line-strong:#cbd5e1;--text:#0f172a;--text-soft:#334155;--text-muted:#64748b;--brand:#635bff;--brand-strong:#4f46e5;--brand-soft:#635bff1a;--blue:#3b82f6;--blue-soft:#3b82f61f;--green:#22c55e;--green-soft:#22c55e1f;--orange:#f59e0b;--orange-soft:#f59e0b1f;--red:#ef4444;--red-soft:#ef44441f;--plan-color:#94a3b8;--plan-soft:#94a3b81f;--plan-border:var(--line);--shadow:0 2px 10px #0f172a0f;--shadow-sm:var(--shadow);--radius:16px;--radius-sm:12px;--radius-xs:10px}*{box-sizing:border-box}html{background:var(--bg)}body{min-width:0;min-height:100vh;color:var(--text);background:radial-gradient(circle at top left, #635bff14, transparent 28%), radial-gradient(circle at right top, #3b82f60f, transparent 32%), var(--bg);margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,sans-serif}button,input,select,textarea{font:inherit}button,a{-webkit-tap-highlight-color:transparent}button{cursor:pointer}a{color:inherit;text-decoration:none}.app-shell{grid-template-columns:236px minmax(0,1fr);align-items:start;gap:14px;width:min(100vw - 32px,1540px);max-width:none;margin:6px auto 18px;display:grid}.sidebar,.card,.trend-card,.summary-card,.account-card,.log-table-wrap,.tester-tabs,.service-card,.update-panel{border:1px solid var(--line);box-shadow:var(--shadow-sm);background:#fffffff0}.sidebar{border-radius:18px;gap:14px;min-width:0;max-height:calc(100vh - 20px);padding:14px 12px;display:grid;position:sticky;top:10px;overflow:auto}.brand{align-items:center;gap:12px;padding:2px 4px 4px;display:flex}.brand-mark{width:34px;height:34px;color:var(--brand);background:linear-gradient(#635bff24,#635bff0a);border:1px solid #635bff33;border-radius:12px;flex:none;place-items:center;display:grid;overflow:hidden}.brand-mark img{width:100%;height:100%;display:block}.brand strong{font-size:14px;line-height:1.25;display:block}.brand span{color:var(--text-muted);margin-top:5px;font-size:10px;line-height:1.5;display:block}.nav{gap:4px;display:grid}.nav-item{width:100%;min-height:36px;color:var(--text-soft);text-align:left;background:0 0;border:1px solid #0000;border-radius:11px;align-items:center;gap:10px;padding:0 11px;display:flex}.nav-item.is-active,.nav-item:hover{color:var(--brand);background:#635bff14;border-color:#635bff1a;font-weight:650}.sidebar-links{gap:12px;margin-top:auto}.sidebar-status{gap:12px;padding:11px}.sidebar-status-summary{grid-template-columns:16px minmax(0,1fr);align-items:center;gap:9px;min-width:0;display:grid}.sidebar-status-summary strong{font-size:14px;line-height:1.25;display:block}.sidebar-status-summary span:last-child{color:var(--text-muted);text-overflow:ellipsis;white-space:nowrap;margin-top:2px;font-size:11px;line-height:1.3;display:block;overflow:hidden}.sidebar-base-url{border:1px solid var(--line);width:100%;min-width:0;color:var(--text);text-align:left;background:#f8fafc;border-radius:11px;gap:5px;padding:9px;display:grid}.sidebar-base-url span{color:var(--text-muted);font-size:10px;font-weight:800}.sidebar-base-url code{min-width:0;color:var(--text);overflow-wrap:anywhere;font-size:11px;line-height:1.45}.sidebar-kv-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;display:grid}.sidebar-kv{background:#f8fafcd1;border-radius:11px;min-width:0;padding:8px 9px}.sidebar-kv.wide{grid-column:1/-1}.sidebar-kv span{color:var(--text-muted);font-size:10px;font-weight:800;line-height:1.2;display:block}.sidebar-kv strong{color:var(--text);overflow-wrap:anywhere;margin-top:4px;font-size:12px;line-height:1.35;display:block}.sidebar-link-list{gap:7px;display:grid}.sidebar-link{border:1px solid var(--line);width:100%;min-height:34px;color:var(--text-soft);text-align:left;background:#fff;border-radius:11px;justify-content:flex-start;align-items:center;gap:8px;padding:0 12px;font-size:12px;font-weight:700;display:inline-flex}.sidebar-link:hover{border-color:var(--line-strong);background:#f8fafc}.main{gap:16px;min-width:0;display:grid}.page-actions{flex-wrap:wrap;justify-content:flex-end;gap:10px;margin-bottom:2px;display:flex}.topbar{grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:12px;display:grid}.page-title h1{margin:0;font-size:27px;line-height:1.15}.page-kicker{color:var(--brand);letter-spacing:0;margin-bottom:8px;font-size:12px;font-weight:850;display:inline-flex}.page-title p{color:var(--text-muted);margin:8px 0 0;font-size:14px;line-height:1.6}.top-actions,.section-actions,.button-row,.example-row{flex-wrap:wrap;justify-content:flex-end;gap:10px;display:flex}.top-actions .btn-primary,.top-actions .btn-secondary,.top-actions .btn-danger{border-radius:10px;min-height:36px;padding:0 12px;font-size:12px}.route-loading{place-items:center;min-height:56vh;display:grid}.route-loading-card{border:1px solid var(--line);min-width:220px;box-shadow:var(--shadow-sm);text-align:center;background:#ffffffeb;border-radius:14px;grid-template-columns:1fr;justify-items:center;gap:12px;padding:14px 16px;display:grid}.route-loading-card strong{font-size:14px;line-height:1.3;display:block}.route-loading-card p{color:var(--text-muted);margin:4px 0 0;font-size:12px;line-height:1.4}.route-loading-bar{background:linear-gradient(90deg,#635bff3d,#22c55eb8,#f97316e0) 0 0/200% 100%;border-radius:999px;width:92px;height:4px;animation:1.1s ease-in-out infinite route-loading-bar}@keyframes route-loading-bar{0%{background-position:0%}50%{background-position:100%}to{background-position:0%}}.btn-primary,.btn-secondary,.btn-danger{border:1px solid var(--line);white-space:nowrap;min-height:40px;color:var(--text-soft);background:#fff;border-radius:12px;justify-content:center;align-items:center;gap:8px;padding:0 14px;font-size:13px;font-weight:700;display:inline-flex;box-shadow:0 1px #0f172a05}.btn-primary{color:#fff;border-color:var(--brand);background:var(--brand)}.btn-primary:hover{background:var(--brand-strong)}.btn-secondary:hover{border-color:var(--line-strong);background:#f8fafc}.btn-danger{color:#ef4444;background:var(--red-soft);border-color:#ef44442e}.btn-danger:hover{background:#ef444429}.btn-primary:disabled,.btn-secondary:disabled,.btn-danger:disabled{cursor:not-allowed;opacity:.58}.icon-only{width:42px;padding:0}.summary-grid{grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;display:grid}.overview-summary-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.summary-card{background:linear-gradient(145deg, #fffffffa, #f8fbfff5), var(--surface);border-color:#94a3b83d;border-radius:12px;grid-template-columns:24px minmax(0,1fr);align-content:start;gap:9px;min-height:84px;padding:12px 13px;display:grid;position:relative;overflow:hidden;box-shadow:0 14px 28px #0f172a12,inset 0 1px #ffffffe6}.summary-card:before{content:"";background:var(--brand);opacity:.75;width:3px;position:absolute;inset:0 auto 0 0}.summary-card:after{content:"";pointer-events:none;background:radial-gradient(circle at 12% 0,#4053ff14,#0000 34%);position:absolute;inset:0}.summary-card.tone-blue:before{background:var(--blue)}.summary-card.tone-green:before{background:var(--green)}.summary-card.tone-orange:before{background:var(--orange)}.summary-card.tone-red:before{background:var(--red)}.summary-card.tone-slate:before{background:var(--text-muted)}.summary-card>div:last-child{z-index:1;gap:4px;min-width:0;display:grid;position:relative}.summary-card span{color:var(--text-muted);font-size:11px;font-weight:760;line-height:1.2}.summary-card strong{letter-spacing:0;overflow-wrap:break-word;min-width:0;font-size:19px;line-height:1.08;display:block}.summary-card.compact-value strong{overflow-wrap:anywhere;font-size:16px;line-height:1.15}.usage-summary{gap:5px;min-width:0;display:grid}.usage-summary-row{grid-template-columns:42px minmax(0,1fr);align-items:center;gap:7px;min-width:0;display:grid}.usage-summary-row span{min-width:0;height:auto;color:var(--blue);background:0 0;border-radius:0;justify-content:flex-start;align-items:center;font-size:10px;font-weight:850;display:inline-flex}.usage-summary-row span:before{content:"";width:5px;height:5px;box-shadow:0 0 0 3px color-mix(in srgb, currentColor 14%, transparent);background:currentColor;border-radius:999px;margin-right:4px}.usage-summary-row:nth-child(2) span{color:var(--green)}.summary-card.compact-value .usage-summary-row strong{white-space:nowrap;text-overflow:ellipsis;overflow-wrap:normal;min-width:0;font-size:12px;line-height:1.25;overflow:hidden}.summary-card p{color:var(--text-muted);margin:0;font-size:11px;line-height:1.32}.summary-card p:empty{display:none}.summary-icon{z-index:1;width:20px;height:20px;color:var(--brand);background:var(--brand-soft);border-radius:999px;place-items:center;display:grid;position:relative;box-shadow:inset 0 0 0 1px #ffffffb8}.summary-icon.blue{color:var(--blue);background:var(--blue-soft)}.summary-icon.green{color:var(--green);background:var(--green-soft)}.summary-icon.orange{color:var(--orange);background:var(--orange-soft)}.main-grid{grid-template-columns:minmax(0,1.8fr) minmax(360px,.95fr);align-items:start;gap:22px;display:grid}.overview-grid,.tester-route-grid{grid-template-columns:minmax(0,1.18fr) minmax(420px,.82fr);align-items:start;gap:22px;display:grid}.tester-route-grid{grid-template-columns:minmax(0,1fr)}.tester-route-grid .tester-card{width:100%}.card,.trend-card,.log-table-wrap,.update-panel{border-radius:20px;padding:20px}.section-head{justify-content:space-between;align-items:flex-start;gap:16px;margin-bottom:18px;display:flex}.section-head.compact{margin-bottom:14px}.section-head h2,.section-head h3{margin:0;font-size:20px;line-height:1.25}.section-head p{color:var(--text-muted);margin:7px 0 0;font-size:13px;line-height:1.6}.trend-card{gap:14px;display:grid}.chart-wrap{border:1px solid var(--line);background:linear-gradient(#f8fafc99,#fff);border-radius:16px;width:100%;padding:14px;overflow:hidden}.chart-legend{color:var(--text-muted);flex-wrap:wrap;gap:14px;font-size:12px;display:flex}.legend-item{align-items:center;gap:8px;display:inline-flex}.legend-swatch{border-radius:999px;width:10px;height:10px}.legend-swatch.purple{background:#635bff}.legend-swatch.blue{background:#3b82f6}.trend-svg{width:100%;height:210px;margin-top:10px;display:block}.trend-labels{color:var(--text-muted);grid-template-columns:repeat(6,minmax(0,1fr));gap:6px;margin-top:10px;font-size:11px;line-height:1.4;display:grid}.filter-row{flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:18px;display:flex}.search-box{border:1px solid var(--line);min-width:0;min-height:40px;color:var(--text-muted);background:#fff;border-radius:12px;flex:220px;align-items:center;gap:10px;padding:0 12px;display:flex}.search-box input{width:100%;min-width:0;color:var(--text);background:0 0;border:0;outline:none}.input,.control,.textarea{border:1px solid var(--line);width:100%;color:var(--text);background:#fff;border-radius:12px;outline:none}.input,.control{min-height:40px;padding:0 12px}.filter-row .control{flex:0 0 156px;min-width:156px}.textarea{resize:vertical;min-height:180px;padding:14px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:1.55}.field{color:var(--text-soft);gap:8px;font-size:13px;font-weight:700;display:grid}.hint,.status-inline{color:var(--text-muted);margin:9px 0;font-size:13px;line-height:1.6}.account-selected-count{color:var(--text-muted);white-space:nowrap;font-size:12px;font-weight:700}.service-card{border-radius:16px;gap:12px;padding:14px;display:grid}.sidebar-status{border:1px solid var(--line);background:#fff}.sidebar-status.tone-green{border-color:#22c55e2e}.sidebar-status.tone-orange{background:#fffbebf2;border-color:#f59e0b3d}.sidebar-status.tone-red{background:#fef2f2f2;border-color:#ef444433}.sidebar-status .service-head span{color:var(--text-muted);font-size:11px;font-weight:700}.sidebar-meta-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;display:grid}.sidebar-meta{background:#f8fafce0;border-radius:11px;min-width:0;padding:8px 10px}.sidebar-meta span{color:var(--text-muted);font-size:10px;font-weight:800;line-height:1.2;display:block}.sidebar-meta strong{color:var(--text);overflow-wrap:anywhere;margin-top:4px;font-size:12px;line-height:1.35;display:block}.endpoint-card .compact-grid{grid-template-columns:1fr;gap:12px}.service-head{justify-content:space-between;align-items:center;gap:12px;display:flex}.service-list{gap:10px;display:grid}.compact-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.service-row{min-width:0}.service-row label{color:var(--text-muted);margin-bottom:4px;font-size:12px;display:block}.service-row strong,.service-row code{color:var(--text);word-break:break-word;overflow-wrap:anywhere;font-size:13px;line-height:1.5}.meta-grid .service-row label{margin-bottom:0;font-size:10px;line-height:1.4}.meta-grid .service-row strong,.meta-grid .service-row code{color:var(--text-soft);font-size:11px;line-height:1.45}.status-dot{background:var(--green);border-radius:999px;width:8px;height:8px;box-shadow:0 0 0 4px #22c55e24}.status-dot.offline{background:var(--orange);box-shadow:0 0 0 4px #f59e0b24}.update-panel{background:linear-gradient(135deg,#fffbebfa,#fffffff5),#fff;border-color:#f59e0b40;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:12px;padding:12px 14px;display:grid}.strong-update-panel{box-shadow:0 10px 22px #b4530917, var(--shadow-sm);border-color:#f59e0b57}.update-mark{color:#b45309;background:#fff7ed;border:1px solid #f59e0b3d;border-radius:12px;place-items:center;width:36px;height:36px;display:grid;box-shadow:inset 0 1px #ffffffc7}.update-copy{gap:4px;min-width:0;display:grid}.update-title-row{flex-wrap:wrap;align-items:baseline;gap:10px;display:flex}.update-title-row strong{font-size:16px;line-height:1.25}.update-copy p{color:var(--text-muted);flex-wrap:wrap;align-items:center;gap:6px;margin:0;font-size:13px;line-height:1.45;display:flex}.update-title-row span{color:var(--text-muted);font-size:13px;font-weight:700}.update-panel code{color:#92400e;overflow-wrap:anywhere;background:#fff;border:1px solid #f59e0b29;border-radius:8px;max-width:100%;padding:4px 7px;font-size:12px;line-height:1.35}.update-actions{flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:10px;display:flex}.update-panel .btn-primary,.update-panel .btn-secondary{white-space:nowrap;flex:none;align-items:center;gap:7px;min-height:36px;padding-inline:12px;text-decoration:none;display:inline-flex}.modal-backdrop,.drawer-backdrop,.loading-cover{z-index:20;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);background:#0f172a6b;place-items:center;padding:20px;display:grid;position:fixed;inset:0}.loading-cover{z-index:30;color:var(--text);background:#f8fafcc2;gap:12px}.modal-card{border:1px solid var(--line);width:min(760px,100%);max-height:min(760px,100vh - 40px);box-shadow:var(--shadow);background:#fff;border-radius:18px;overflow:auto}.modal-card.wide{width:min(980px,100%)}.modal-head{z-index:1;border-bottom:1px solid var(--line);background:#fffffff5;justify-content:space-between;align-items:center;gap:12px;padding:18px 20px;display:flex;position:sticky;top:0}.modal-head h3{margin:0}.modal-body{padding:20px}.modal-grid{gap:16px;display:grid}.modal-section{border:1px solid var(--line);background:#f8fafc;border-radius:14px;gap:12px;padding:16px;display:grid}.modal-section h4{margin:0}.modal-section p,.contact-notes span{color:var(--text-muted);margin:0;font-size:13px;line-height:1.6}.import-textarea{min-height:220px}.zip-import-box,.zip-import-preview{border:1px solid var(--line);background:#f8fafcd1;border-radius:12px;gap:10px;padding:12px;display:grid}.zip-import-box{grid-template-columns:minmax(0,1fr) auto;align-items:center}.zip-import-box strong,.zip-import-preview strong{color:var(--text);font-size:13px;line-height:1.25}.zip-import-box p,.zip-import-preview p,.zip-import-preview span{color:var(--text-muted);margin:0;font-size:12px;line-height:1.5}.zip-import-trigger{cursor:pointer;position:relative;overflow:hidden}.zip-import-trigger input{opacity:0;pointer-events:none;position:absolute;inset:0}.zip-import-preview.ready{background:#f0fdf4bd;border-color:#22c55e38}.zip-import-preview.error{background:#fef2f2c2;border-color:#ef444438}.zip-import-preview .btn-primary{width:fit-content}.contact-notes{gap:14px;display:grid}.contact-note,.contact-qr{gap:6px;display:grid}.contact-note{border:1px solid var(--line);background:var(--panel-soft);border-radius:16px;padding:14px 16px}.contact-note strong{font-size:14px;line-height:1.4}.contact-note span,.contact-note a,.contact-note code{color:var(--text-soft);word-break:break-word;font-size:13px;line-height:1.6}.contact-qr{border:1px solid var(--line);background:#fff;border-radius:20px;gap:10px;padding:14px}.contact-qr img{border:1px solid var(--line);background:var(--panel-soft);border-radius:16px;width:100%;max-width:420px;height:auto;display:block}.contact-qr span{color:var(--text-muted);font-size:12px;line-height:1.6}.image-preview-stage{background:#0f172a;border-radius:14px;place-items:center;min-height:320px;display:grid;overflow:hidden}.image-preview-stage img{max-width:100%;max-height:min(70vh,680px);display:block}.preview-modal-meta{color:var(--text-soft);word-break:break-word;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;font-size:13px;line-height:1.7;display:flex}.spin{animation:.9s linear infinite spin}@keyframes spin{to{transform:rotate(360deg)}}.launch-page{grid-template-columns:minmax(420px,.82fr) minmax(520px,1.18fr);align-items:stretch;gap:16px;min-height:calc(100vh - 172px);display:grid}.launch-copy,.launch-visual{border:1px solid var(--line);min-width:0;box-shadow:var(--shadow-sm);background:#fffffff0;border-radius:20px}.launch-copy{align-content:center;gap:20px;padding:28px;display:grid}.launch-identity{gap:18px;display:grid}.launch-app-icon{background:linear-gradient(180deg, #ffffffe6, #f8fafcd1), var(--surface);border:1px solid #635bff2e;border-radius:24px;place-items:center;width:96px;height:96px;display:grid;box-shadow:0 22px 44px #0f172a1f,0 0 0 8px #635bff0f}.launch-app-icon img{width:100%;height:100%;display:block}.launch-copy h2{max-width:560px;color:var(--text);letter-spacing:0;margin:0;font-size:44px;line-height:1.02}.launch-copy p{max-width:520px;color:var(--text-soft);margin:0;font-size:15px;line-height:1.8}.launch-metrics{grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;display:grid}.launch-metrics div{border:1px solid var(--line);background:#f8fafcd6;border-radius:14px;gap:8px;min-width:0;padding:14px;display:grid}.launch-metrics svg{color:var(--brand)}.launch-metrics span{color:var(--text-muted);font-size:11px;font-weight:800}.launch-metrics strong{min-width:0;color:var(--text);overflow-wrap:anywhere;font-size:18px;line-height:1.2}.launch-actions{flex-wrap:wrap;gap:10px;display:flex}.launch-actions .btn-secondary,.launch-actions a.btn-secondary{text-decoration:none}.launch-download-note{color:var(--text-muted);margin:-2px 0 0;font-size:12px;line-height:1.6}.launch-pills{flex-wrap:wrap;gap:8px;display:flex}.launch-pills span{min-height:28px;color:var(--text-muted);background:#635bff14;border-radius:999px;align-items:center;padding:0 10px;font-size:12px;font-weight:700;display:inline-flex}.launch-status{border-top:1px solid var(--line);grid-template-columns:repeat(2,minmax(0,1fr));gap:14px 18px;margin-top:8px;padding-top:20px;display:grid}.launch-visual{background:radial-gradient(circle at 24% 22%,#635bff26,#0000 34%),radial-gradient(circle at 82% 78%,#22c55e1f,#0000 32%),linear-gradient(#fffffff5,#f8fafcf0),#fff;place-items:center;padding:18px;display:grid;overflow:hidden}.launch-visual-stage{aspect-ratio:1.2;place-items:center;width:min(760px,100%);display:grid;position:relative}.launch-visual-mark{z-index:2;border-radius:34px;width:min(160px,24%);position:absolute;top:5%;left:4%;box-shadow:0 24px 54px #0f172a2e,0 0 0 10px #ffffffc7}.launch-visual-dashboard{object-fit:contain;filter:drop-shadow(0 28px 50px #0f172a24);width:92%;max-height:min(560px,100vh - 250px);display:block}.left-column,.right-column{gap:18px;min-width:0;display:grid}.account-grid{justify-content:stretch;align-items:start;gap:16px;width:100%;display:grid}.account-grid.profile-count-1{grid-template-columns:minmax(320px,520px)}.account-grid.profile-count-2{grid-template-columns:repeat(2,minmax(320px,1fr))}.account-grid.profile-count-3{grid-template-columns:repeat(3,minmax(300px,1fr))}.account-grid.profile-count-many{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}.account-card{--plan-color:#94a3b8;--plan-soft:#94a3b81f;--plan-border:var(--line);--usage-color:#16a34a;--usage-soft:#16a34a1f;border-color:var(--plan-border);border-radius:16px;grid-template-rows:none;align-content:start;align-self:start;gap:12px;min-width:0;padding:14px;display:grid;position:relative;overflow:hidden}.account-card:before{content:"";background:var(--plan-color);height:3px;position:absolute;inset:0 0 auto}.account-card.plan-free{--plan-color:#94a3b8;--plan-soft:#94a3b81f;--plan-border:var(--line)}.account-card.plan-plus{--plan-color:#635bff;--plan-soft:#635bff1c;--plan-border:#635bff33}.account-card.plan-pro{--plan-color:#4f46e5;--plan-soft:#4f46e51c;--plan-border:#4f46e538}.account-card.plan-team{--plan-color:#0f766e;--plan-soft:#0f766e1c;--plan-border:#0f766e38}.account-card.plan-premium{--plan-color:#d97706;--plan-soft:#d977061f;--plan-border:#d9770657;box-shadow:0 10px 26px #b453091a, var(--shadow)}.account-card.plan-enterprise{--plan-color:#a16207;--plan-soft:#a1620724;--plan-border:#47556947;box-shadow:0 12px 28px #0f172a1a, var(--shadow)}.account-card.is-auth-invalid{--plan-color:#ef4444;--plan-soft:#ef444417;--plan-border:#ef444452;border-color:var(--plan-border);box-shadow:0 12px 28px #b91c1c14, var(--shadow);background:linear-gradient(#fef2f2e6,#fffffffa 46%),#fff}.account-card.is-auth-invalid:before{background:#ef4444;height:3px}.account-card.is-auth-invalid .usage-corner{color:#991b1b;background:linear-gradient(135deg,#fef2f2,#fee2e2);border-color:#ef444447;box-shadow:0 8px 18px #b91c1c1a,inset 0 1px #ffffffd1}.account-card.is-auth-invalid .avatar{color:#dc2626;background:#fff;border-color:#ef444475;box-shadow:0 0 0 3px #ef44441a}.account-card.is-auth-invalid .progress-bar{opacity:.72}.account-card.is-auth-invalid .usage-status-row,.account-card.is-auth-invalid .progress-track{background:#fef2f2ad}.account-card.is-auth-invalid .account-actions .btn-secondary:disabled{opacity:.86;color:#991b1b;background:#fff;border-color:#ef44442e}.account-head{justify-content:space-between;align-items:flex-start;gap:12px;padding-top:8px;display:flex}.account-title{flex:1;gap:6px;min-width:0;display:grid}.account-name{align-items:center;gap:8px;min-width:0;display:flex}.account-name strong{-webkit-line-clamp:2;text-overflow:ellipsis;white-space:normal;overflow-wrap:anywhere;-webkit-box-orient:vertical;min-width:0;font-size:13px;line-height:1.35;display:-webkit-box;overflow:hidden}.account-icon-btn{border:1px solid var(--line);width:24px;height:24px;color:var(--text-muted);background:#fff;border-radius:999px;flex:none;justify-content:center;align-items:center;padding:0;display:flex}.account-icon-btn:hover{color:var(--plan-color);border-color:var(--plan-color);background:var(--plan-soft)}.avatar{background:var(--panel-soft);border:1px solid var(--plan-color);width:24px;height:24px;box-shadow:0 0 0 3px var(--plan-soft);color:var(--plan-color);border-radius:999px;flex:none;place-items:center;font-size:11px;font-weight:700;display:grid}.badge-row{flex-wrap:wrap;gap:6px;display:flex}.account-select{border:1px solid var(--line);min-height:28px;color:var(--text-muted);cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap;background:#fff;border-radius:8px;align-items:center;gap:6px;margin-top:28px;padding:0 8px;font-size:12px;font-weight:600;display:inline-flex}.account-select input{width:14px;height:14px;margin:0}.badge{white-space:nowrap;border-radius:999px;justify-content:center;align-items:center;min-height:22px;padding:0 8px;font-size:11px;font-weight:600;display:inline-flex}.badge.brand{color:var(--plan-color);background:var(--plan-soft)}.usage-corner{color:#047857;letter-spacing:0;pointer-events:none;z-index:1;background:linear-gradient(135deg,#ecfdf5,#d1fae5);border:1px solid #10b98147;border-radius:999px;align-items:center;gap:5px;min-height:24px;padding:0 10px 0 8px;font-size:10px;font-weight:800;line-height:22px;display:inline-flex;position:absolute;top:10px;right:12px;box-shadow:0 8px 18px #10b9811f,inset 0 1px #ffffffd1}.usage-corner:before{content:"";background:currentColor;border-radius:999px;flex:none;width:6px;height:6px;box-shadow:0 0 0 3px #10b9811f}.usage-corner span{line-height:1}.usage-corner.codex-only{color:#1d4ed8;background:linear-gradient(135deg,#eff6ff,#dbeafe);border-color:#2563eb3d;box-shadow:0 8px 18px #2563eb1f,inset 0 1px #ffffffd1}.usage-corner.codex-only:before{box-shadow:0 0 0 3px #2563eb1f}.usage-corner.dual{color:#4f46e5;background:linear-gradient(135deg,#f5f3ff,#ede9fe);border-color:#635bff40;box-shadow:0 8px 18px #635bff21,inset 0 1px #ffffffd1}.usage-corner.dual:before{box-shadow:0 0 0 3px #635bff1f}.badge.green{color:#15803d;background:var(--green-soft)}.badge.orange{color:#b45309;background:var(--orange-soft)}.badge.red{color:#dc2626;background:var(--red-soft)}.badge.muted{color:var(--text-muted);background:#f1f5f9}.account-metrics{gap:10px;display:grid}.quota-row{gap:6px;display:grid}.quota-line{color:var(--text-soft);justify-content:space-between;align-items:center;gap:10px;font-size:11px;line-height:1.45;display:flex}.quota-line span{min-width:0}.quota-line strong{color:var(--text);flex-shrink:0;font-size:12px}.progress-track{background:#eef2f7;border-radius:999px;width:100%;height:5px;overflow:hidden}.progress-bar{border-radius:inherit;background:var(--brand);height:100%}.progress-bar.blue{background:var(--blue)}.progress-bar.orange{background:var(--orange)}.progress-bar.red{background:#f43f5e}.usage-status-row{background:var(--panel-soft);color:var(--text-muted);border-radius:10px;flex-wrap:nowrap;justify-content:space-between;align-items:center;gap:8px;padding:8px 10px;font-size:11px;line-height:1.4;display:flex}.usage-status{white-space:nowrap;align-items:center;gap:5px;min-width:0;font-weight:700;display:inline-flex}.usage-status svg{width:12px;height:12px;color:var(--text-muted);flex:none}.usage-dot{background:#cbd5e1;border-radius:999px;flex:none;width:6px;height:6px}.usage-dot.active{background:#22c55e;box-shadow:0 0 0 3px #22c55e1f}.usage-state-text{color:var(--text-muted);font-weight:700}.usage-status.is-active .usage-state-text{color:#15803d}.compact-meta-row{min-width:0;color:var(--text-muted);gap:8px;font-size:11px;line-height:1.45;display:grid}.compact-reset-list{flex-wrap:nowrap;align-items:center;gap:10px;min-width:0;display:flex}.compact-meta-item{flex:1 1 0;align-items:baseline;gap:5px;min-width:0;display:flex}.compact-meta-item label{color:var(--text-muted);white-space:nowrap;font-size:10px;line-height:1.4}.compact-meta-item strong{color:var(--text-soft);text-align:left;overflow-wrap:anywhere;font-size:11px;line-height:1.4}.compact-meta-actions{justify-content:center;align-items:center;gap:10px;margin-top:2px;display:flex}.compact-meta-actions:before,.compact-meta-actions:after{content:"";background:var(--line);flex:auto;min-width:18px;height:1px}.details-toggle{min-height:24px;color:var(--brand);white-space:nowrap;cursor:pointer;background:0 0;border:0;justify-content:center;align-items:center;gap:5px;padding:0 6px;font-size:11px;font-weight:700;display:inline-flex}.details-toggle:hover{color:#4338ca}.details-toggle svg{width:12px;height:12px;transition:transform .16s}.details-toggle.is-expanded svg{transform:rotate(180deg)}.meta-grid{border-top:1px solid var(--line);grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 12px;padding-top:10px;display:grid}.meta-item{gap:3px;min-width:0;display:grid}.meta-grid .service-row label{color:var(--text-muted);font-size:10px;line-height:1.4}.meta-grid .service-row strong,.meta-grid .service-row span,.meta-grid .service-row code{color:var(--text-soft);word-break:break-word;overflow-wrap:anywhere;font-size:11px;line-height:1.45}.account-actions{flex-wrap:wrap;gap:8px;margin-top:0;display:flex}.account-actions .btn-secondary,.account-actions .btn-danger{border-radius:10px;flex:120px;min-height:36px;padding:0 12px;font-size:12px}.account-actions .btn-secondary.is-current{opacity:1;color:#047857;cursor:default;background:linear-gradient(135deg,#f0fdf4,#dcfce7);border-color:#10b9815c;position:relative;box-shadow:inset 0 1px #fffc,0 6px 14px #10b98114}.account-actions .btn-secondary.is-current:before{content:"";background:#22c55e;border-radius:999px;flex:none;width:7px;height:7px;box-shadow:0 0 0 3px #22c55e1f}.account-actions .btn-secondary.is-current.codex{color:#1d4ed8;background:linear-gradient(135deg,#eff6ff,#dbeafe);border-color:#2563eb52;box-shadow:inset 0 1px #fffc,0 6px 14px #2563eb14}.account-actions .btn-secondary.is-current.codex:before{background:#3b82f6;box-shadow:0 0 0 3px #3b82f61f}.tester-card{gap:16px;display:grid}.tester-tabs,.tester-result-tabs{border-radius:14px;gap:4px;padding:6px;display:flex;overflow-x:auto}.tester-tabs{grid-template-columns:repeat(5,minmax(92px,1fr));gap:6px;display:grid}.tester-result-tabs{box-shadow:none;background:0 0;border:0;padding:0}.tab-btn{min-height:38px;color:var(--text-muted);white-space:nowrap;background:0 0;border:0;border-radius:10px;padding:0 14px;font-weight:800}.tab-btn.is-active{color:var(--brand);background:#fff;box-shadow:0 6px 16px #0f172a0f}.tester-workbench{grid-template-columns:minmax(360px,.92fr) minmax(360px,1.08fr);align-items:stretch;gap:16px;display:grid}.tester-pane{border:1px solid var(--line);background:linear-gradient(#fff,#f8fafc9e);border-radius:16px;align-content:start;gap:12px;min-width:0;padding:14px;display:grid}.tester-request-pane{grid-template-rows:auto auto minmax(180px,1fr) auto auto}.tester-body-field{grid-template-rows:auto minmax(0,1fr);min-height:0;display:grid}.tester-textarea{resize:vertical;height:100%;min-height:180px}.tester-actions-bar{grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:10px;display:grid}.tester-actions-group{gap:10px;min-width:0;display:grid}.tester-actions-bar .example-row{justify-content:flex-start;gap:8px}.tester-copy-row{flex-wrap:wrap;gap:8px;display:flex}.tester-copy-row-top{margin-top:-4px}.tester-actions-bar .btn-secondary{border-radius:10px;min-height:34px;padding:0 10px;font-size:12px}.tester-response-pane{grid-template-rows:auto minmax(0,1fr)}.tester-result-head{grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px;display:grid}.tester-result-head .status-inline{text-align:right;white-space:nowrap;text-overflow:ellipsis;max-width:220px;margin:0;overflow:hidden}.edit-upload-row{grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:10px 12px;margin-top:-2px;display:grid}.edit-upload-mode{gap:6px;min-width:0;display:grid}.edit-upload-mode>span{color:var(--text-muted);font-size:11px;font-weight:800;line-height:1.25}.edit-upload-toggle{flex-wrap:wrap;gap:6px;display:flex}.edit-upload-toggle .tab-btn{min-height:34px;padding:0 12px}.upload-btn{cursor:pointer;white-space:nowrap}.upload-btn input{display:none}.edit-upload-row span{color:var(--text-muted);grid-column:1/-1;font-size:12px;line-height:1.5}.pre{color:#e2e8f0;white-space:pre-wrap;overflow-wrap:anywhere;background:#0f172a;border-radius:12px;width:100%;min-height:312px;max-height:420px;margin:0;padding:16px;font-size:12px;line-height:1.6;overflow:auto}.preview-panel{min-height:312px}.preview-empty,.empty-state{border:1px dashed var(--line-strong);text-align:center;min-height:140px;color:var(--text-muted);background:#f8fafc;border-radius:14px;place-items:center;padding:20px;display:grid}.preview-grid{grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:12px;display:grid}.preview-card{gap:8px;margin:0;display:grid}.preview-card button{border:1px solid var(--line);background:#fff;border-radius:12px;padding:0;overflow:hidden}.preview-card img{aspect-ratio:1;object-fit:cover;width:100%;display:block}.preview-card figcaption{color:var(--text-muted);overflow-wrap:anywhere;font-size:12px}.preview-actions{flex-wrap:wrap;gap:8px;display:flex}.preview-actions a{border:1px solid var(--line);min-height:34px;color:var(--text-soft);border-radius:10px;justify-content:center;align-items:center;padding:0 12px;font-size:12px;font-weight:600;display:inline-flex}.pre.tester-log{min-height:200px}.image-bed-page{gap:16px;display:grid}.image-bed-workbench{grid-template-columns:minmax(0,1.45fr) minmax(320px,.8fr);align-items:start;gap:14px;display:grid}.image-bed-upload-panel,.image-bed-side-card,.image-bed-gallery-section,.image-bed-help-section{border:1px solid var(--line);box-shadow:var(--shadow-sm);background:#fffffff2}.image-bed-upload-panel{background:linear-gradient(135deg,#fffffffa,#f6f8ffeb),#fff;border-radius:18px;grid-template-rows:auto minmax(220px,1fr) auto;gap:16px;min-height:440px;padding:22px;display:grid;overflow:hidden}.image-bed-upload-panel.is-dragging{border-color:#635bff6b;box-shadow:0 18px 45px #635bff1f}.image-bed-upload-copy{gap:7px;max-width:680px;display:grid}.image-bed-upload-copy span{color:var(--brand);font-size:12px;font-weight:850;line-height:1.3}.image-bed-upload-copy h2{color:var(--text);margin:0;font-size:28px;line-height:1.16}.image-bed-upload-copy p{color:var(--text-muted);margin:0;font-size:13px;line-height:1.65}.image-bed-upload-copy strong{color:var(--text);font-weight:800}.upload-dropzone{min-height:220px;color:var(--text-soft);text-align:center;cursor:pointer;background:linear-gradient(#ffffffb8,#f8fafcb8),#f8fafce0;border:1px dashed #635bff52;border-radius:16px;align-content:center;place-items:center;gap:10px;padding:24px;transition:border-color .16s,background .16s,transform .16s;display:grid;position:relative}.upload-dropzone:hover,.upload-dropzone.is-dragging{border-color:var(--brand);background:#635bff12;transform:translateY(-1px)}.upload-dropzone.is-disabled{opacity:.84}.upload-dropzone input{opacity:0;pointer-events:none;width:1px;height:1px;position:absolute}.upload-dropzone-icon{width:52px;height:52px;color:var(--brand);background:#635bff1a;border:1px solid #635bff29;border-radius:16px;place-items:center;display:grid}.upload-dropzone strong{color:var(--text);font-size:18px;line-height:1.3}.upload-dropzone span{max-width:360px;color:var(--text-muted);font-size:13px;line-height:1.5}.upload-progress-block,.image-bed-latest,.image-bed-upload-note{background:#635bff0d;border:1px solid #635bff24;border-radius:15px;min-height:72px}.upload-progress-block{gap:10px;padding:14px 16px;display:grid}.upload-progress-head{justify-content:space-between;align-items:baseline;gap:12px;display:flex}.upload-progress-head strong{color:var(--text);font-size:13px;line-height:1.35}.upload-progress-head span{color:var(--text-muted);overflow-wrap:anywhere;font-size:11px;line-height:1.35}.upload-progress-track{background:#94a3b833;border-radius:999px;height:10px;overflow:hidden}.upload-progress-fill{border-radius:inherit;background:linear-gradient(90deg, var(--brand), #10b981);height:100%;transition:width .18s}.image-bed-latest{grid-template-columns:54px minmax(0,1fr) auto;align-items:center;gap:12px;padding:10px;display:grid}.image-bed-latest-preview{background:#f8fafc;border:0;border-radius:13px;width:54px;height:54px;padding:0;overflow:hidden}.image-bed-latest-preview img{object-fit:cover;width:100%;height:100%;display:block}.image-bed-latest-info{gap:3px;min-width:0;display:grid}.image-bed-latest-info span{color:var(--text-muted);font-size:10px;font-weight:850;line-height:1.2}.image-bed-latest-info strong,.image-bed-latest-info code{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.image-bed-latest-info strong{color:var(--text);font-size:13px}.image-bed-latest-info code{color:var(--text-muted);font-size:11px}.image-bed-upload-note{color:var(--text-muted);align-items:center;padding:14px 16px;font-size:13px;line-height:1.5;display:flex}.image-bed-side-stack{gap:14px;display:grid}.image-bed-side-card{border-radius:16px;align-content:start;gap:13px;padding:18px;display:grid}.image-bed-side-card h4,.image-bed-gallery-section h4{color:var(--text);margin:0;font-size:16px;line-height:1.3}.image-bed-side-card p{color:var(--text-muted);margin:0;font-size:12px;line-height:1.6}.image-bed-section-head{justify-content:space-between;align-items:center;gap:10px;display:flex}.image-bed-section-head p{color:var(--text-muted);margin:4px 0 0;font-size:12px;line-height:1.45}.image-bed-status-dot{background:#cbd5e1;border-radius:999px;width:10px;height:10px;box-shadow:0 0 0 4px #cbd5e138}.image-bed-status-dot.is-ok{background:#10b981;box-shadow:0 0 0 4px #10b98129}.image-bed-status-dot.is-warn{background:#f59e0b;box-shadow:0 0 0 4px #f59e0b29}.image-bed-connection-label{color:var(--text);overflow-wrap:anywhere;font-size:15px;line-height:1.4}.image-bed-link-button{color:var(--brand);background:0 0;border:0;padding:0;font-size:12px;font-weight:800}.image-bed-token-actions{grid-template-columns:1fr auto;gap:10px;display:grid}.image-bed-token-hint{color:var(--text-muted);margin:-2px 0 0;font-size:11px;font-weight:650;line-height:1.5}.image-bed-token-hint code{color:var(--text);font-weight:800}.image-bed-token-summary{border:1px solid var(--line);background:#f8fafccc;border-radius:14px;justify-content:space-between;align-items:center;gap:12px;min-height:58px;padding:12px;display:flex}.image-bed-token-summary span{color:var(--text-muted);font-size:10px;font-weight:850;line-height:1.25;display:block}.image-bed-token-summary strong{color:var(--text);margin-top:4px;font-size:14px;line-height:1.35;display:block}.image-bed-target-list{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;display:grid}.image-bed-target-list div{background:#f8fafcd1;border-radius:12px;min-width:0;padding:10px}.image-bed-target-list span{color:var(--text-muted);font-size:10px;font-weight:850;line-height:1.25;display:block}.image-bed-target-list strong{color:var(--text);overflow-wrap:anywhere;margin-top:5px;font-size:12px;line-height:1.35;display:block}.image-bed-gallery-section{border-radius:18px;gap:14px;padding:18px;display:grid}.image-bed-empty{min-height:136px;color:var(--text-muted);text-align:center;background:#f8fafcd1;border-radius:15px;place-items:center;padding:24px;font-size:13px;line-height:1.6;display:grid}.image-bed-results-grid{grid-template-columns:repeat(auto-fill,minmax(132px,150px));align-items:start;gap:12px;display:grid}.image-bed-result-card{border:1px solid var(--line);background:#fff;border-radius:14px;align-content:start;gap:7px;margin:0;display:grid;position:relative;overflow:hidden;box-shadow:0 8px 18px #0f172a0d}.image-bed-preview-button{aspect-ratio:1/.78;background:#f8fafc;border:0;padding:0;position:relative;overflow:hidden}.image-bed-preview-button img{object-fit:cover;width:100%;height:100%;transition:transform .18s;display:block}.image-bed-preview-button:hover img{transform:scale(1.03)}.image-bed-result-card figcaption{gap:3px;min-width:0;padding:0 10px 10px;display:grid}.image-bed-result-card figcaption strong{color:var(--text);text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:1.4;overflow:hidden}.image-bed-result-card figcaption span,.image-bed-result-card figcaption code{color:var(--text-muted);overflow-wrap:anywhere;font-size:10px;line-height:1.4}.image-bed-result-actions{gap:6px;display:flex;position:absolute;top:7px;right:7px}.image-bed-card-action{width:30px;height:30px;color:var(--text-soft);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);background:#ffffffe0;border:1px solid #ffffffb8;border-radius:10px;justify-content:center;align-items:center;display:inline-flex;box-shadow:0 8px 18px #0f172a1a}.image-bed-card-action:hover{color:var(--brand);background:#fff;border-color:#635bff33}.image-bed-card-action.is-danger{color:#ef4444}.image-bed-card-action.is-danger:hover{color:#dc2626;border-color:#ef444438}.image-bed-card-action:disabled{cursor:not-allowed;opacity:.62}.image-bed-load-more{width:100%}.image-bed-help-section{border-radius:16px;padding:0;overflow:hidden}.image-bed-help-section summary{cursor:pointer;color:var(--text);padding:15px 18px;font-size:14px;font-weight:800}.image-bed-help-intro{color:var(--text-muted);margin:0;padding:0 20px 14px;font-size:13px;line-height:1.6}.image-bed-help-intro code{color:var(--text);font-weight:800}.image-bed-steps{color:var(--text-soft);gap:11px;margin:0;padding:0 20px 16px 36px;font-size:13px;line-height:1.6;display:grid}.image-bed-steps li{min-width:0}.image-bed-steps strong,.image-bed-steps code{color:var(--text);font-weight:750}.image-bed-help-facts{border-top:1px solid var(--line);border-bottom:1px solid var(--line);margin:0 20px 16px;display:grid}.image-bed-help-facts div{border-top:1px solid #94a3b829;grid-template-columns:110px minmax(0,1fr);gap:12px;min-width:0;padding:12px 0;display:grid}.image-bed-help-facts div:first-child{border-top:0}.image-bed-help-facts dt{color:var(--text);font-size:12px;font-weight:850;line-height:1.4}.image-bed-help-facts dd{color:var(--text-muted);margin:0;font-size:12px;line-height:1.55}.image-bed-help-facts code{color:var(--text);font-weight:800}.image-bed-help-section .hint{margin:0;padding:0 20px 18px}@media (width<=1120px){.image-bed-workbench{grid-template-columns:1fr}.image-bed-side-stack{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width<=760px){.image-bed-upload-panel,.image-bed-gallery-section{border-radius:16px;padding:16px}.image-bed-upload-copy h2{font-size:23px}.image-bed-side-stack,.image-bed-target-list,.image-bed-token-actions,.image-bed-help-facts div,.image-bed-latest,.image-bed-result-actions{grid-template-columns:1fr}.image-bed-latest-preview{aspect-ratio:1/.62;width:100%;height:auto}}.network-page{gap:18px;display:grid}.network-command-center{box-shadow:var(--shadow);background:linear-gradient(135deg,#fff 0%,#f8fbff 58%,#f4fbf7 100%);border:1px solid #94a3b838;border-radius:20px;grid-template-columns:minmax(0,1fr) 260px;align-items:stretch;gap:18px;padding:22px;display:grid;overflow:hidden}.network-command-center.green{border-color:#22c55e33}.network-command-center.orange{border-color:#f59e0b38}.network-command-center.red{border-color:#ef444438}.network-command-copy{align-content:center;gap:10px;min-width:0;display:grid}.network-eyebrow{width:fit-content;color:var(--brand);align-items:center;gap:7px;font-size:12px;font-weight:850;line-height:1.2;display:inline-flex}.network-command-copy h2{color:var(--text);letter-spacing:0;margin:0;font-size:31px;line-height:1.12}.network-command-copy p{max-width:760px;color:var(--text-muted);margin:0;font-size:13px;line-height:1.65}.network-command-status{flex-wrap:wrap;align-items:center;gap:8px 12px;margin-top:2px;display:flex}.network-command-status>span:not(.network-chip){color:var(--text-muted);align-items:center;gap:6px;font-size:12px;font-weight:720;display:inline-flex}.network-toolbar-status{color:var(--text-soft)}.access-score-card{background:#ffffffc7;border:1px solid #94a3b82e;border-radius:16px;align-content:center;gap:10px;min-width:0;padding:18px;display:grid;box-shadow:inset 0 1px #ffffffe0}.access-score-card>span{color:var(--text-muted);font-size:11px;font-weight:850;line-height:1.2}.access-score-card strong{color:var(--text);letter-spacing:0;font-size:38px;line-height:1}.access-score-card p{color:var(--text-muted);margin:0;font-size:12px;font-weight:700;line-height:1.45}.access-score-bar{background:#94a3b829;border-radius:999px;width:100%;height:8px;position:relative;overflow:hidden}.access-score-bar i{border-radius:inherit;background:linear-gradient(90deg,#22c55e,#3b82f6);min-width:0;max-width:100%;height:100%;display:block}.access-score-card .btn-secondary{width:100%}.network-error{color:var(--red);background:#ef444412;border:1px solid #ef444429;border-radius:12px;margin:0;padding:10px 12px;font-size:12px;font-weight:750;line-height:1.5}.signal-grid{grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;display:grid}.signal-card{background:#fff;border:1px solid #94a3b833;border-radius:16px;grid-template-columns:34px minmax(0,1fr);align-content:start;gap:12px;min-width:0;min-height:122px;padding:15px;display:grid;box-shadow:0 10px 22px #0f172a0d}.signal-card-icon{width:34px;height:34px;color:var(--blue);background:var(--blue-soft);border-radius:11px;place-items:center;display:grid}.signal-card span,.network-metric span,.network-block span{color:var(--text-muted);font-size:11px;font-weight:820;line-height:1.2;display:block}.signal-card strong,.network-metric strong,.network-block strong{min-width:0;color:var(--text);overflow-wrap:anywhere;margin-top:6px;font-size:15px;line-height:1.25;display:block}.signal-card p,.network-metric p,.network-block p{color:var(--text-muted);overflow-wrap:anywhere;margin:7px 0 0;font-size:12px;line-height:1.45}.signal-card.tone-green,.network-metric.tone-green,.network-block.tone-green{background:linear-gradient(#fff,#f0fdf4c7);border-color:#22c55e2e}.signal-card.tone-green .signal-card-icon{color:var(--green);background:var(--green-soft)}.signal-card.tone-orange,.network-metric.tone-orange,.network-block.tone-orange{background:linear-gradient(#fff,#fffbebd6);border-color:#f59e0b33}.signal-card.tone-orange .signal-card-icon{color:var(--orange);background:var(--orange-soft)}.signal-card.tone-red,.network-metric.tone-red,.network-block.tone-red{background:linear-gradient(#fff,#fef2f2db);border-color:#ef444433}.signal-card.tone-red .signal-card-icon{color:var(--red);background:var(--red-soft)}.signal-card.tone-slate,.network-metric.tone-slate,.network-block.tone-slate{background:linear-gradient(#fff,#f8fafce6)}.network-workspace{grid-template-columns:minmax(560px,1.16fr) minmax(360px,.84fr);align-items:start;gap:18px;display:grid}.network-section{gap:14px;display:grid}.network-platform-panel{padding:20px}.network-side{gap:18px;min-width:0;display:grid}.platform-summary-strip{flex-wrap:wrap;justify-content:flex-end;gap:8px;margin-left:auto;display:inline-flex}.platform-summary-chip{background:#fff;border:1px solid #94a3b82e;border-radius:12px;gap:3px;min-width:66px;padding:9px 11px;display:grid}.platform-summary-chip strong{color:var(--text);font-size:20px;font-weight:900;line-height:1}.platform-summary-chip span{color:var(--text-muted);font-size:10px;font-weight:820;line-height:1.1}.platform-summary-chip.green{background:#f0fdf4cc;border-color:#22c55e33}.platform-summary-chip.orange{background:#fffbebdb;border-color:#f59e0b33}.platform-summary-chip.red{background:#fef2f2db;border-color:#ef444433}.platform-access-header,.platform-access-row{grid-template-columns:minmax(150px,1.05fr) 108px 92px minmax(140px,1fr);align-items:center;column-gap:16px;display:grid}.platform-access-header{color:var(--text-muted);padding:0 16px;font-size:11px;font-weight:830;line-height:1}.platform-access-list{background:#fff;border:1px solid #94a3b82e;border-radius:15px;gap:0;display:grid;overflow:hidden}.platform-access-row{background:#fff;border-top:1px solid #94a3b821;min-width:0;padding:14px 16px 14px 18px;transition:background .14s;position:relative}.platform-access-row:first-child{border-top:0}.platform-access-row:hover{background:#f8fafcd1}.platform-access-row:before{content:"";background:#94a3b861;border-radius:999px;width:3px;position:absolute;inset:12px auto 12px 0}.platform-access-row.green{border-left:0}.platform-access-row.green:before{background:var(--green)}.platform-access-row.orange{border-left:0}.platform-access-row.orange:before{background:var(--orange)}.platform-access-row.red{border-left:0}.platform-access-row.red:before{background:var(--red)}.platform-access-main{align-items:center;gap:12px;min-width:0;display:flex}.platform-access-main>div{gap:3px;min-width:0;display:grid}.platform-access-main strong{color:var(--text);font-size:15px;font-weight:850;line-height:1.2}.platform-access-main span,.platform-access-result>span,.platform-access-latency span{color:var(--text-muted);overflow-wrap:anywhere;font-size:12px;font-weight:700;line-height:1.35}.platform-access-result,.platform-access-latency{justify-items:start;gap:5px;min-width:0;display:grid}.platform-access-latency strong{color:var(--text);font-size:14px;font-weight:850;line-height:1.2}.platform-access-detail{min-width:0}.platform-access-detail span{color:var(--text-muted);overflow-wrap:anywhere;font-size:12px;font-weight:720;line-height:1.45;display:block}.platform-icon{color:#fff;background:linear-gradient(135deg,#64748b,#334155);border-radius:12px;flex:none;place-items:center;width:38px;height:38px;font-size:13px;font-weight:900;display:grid;box-shadow:inset 0 1px #ffffff47}.platform-icon img{filter:brightness(0)invert();width:19px;height:19px;display:block}.platform-icon.green{background:linear-gradient(135deg,#22c55e,#16a34a)}.platform-icon.orange{background:linear-gradient(135deg,#f59e0b,#d97706)}.platform-icon.red{background:linear-gradient(135deg,#ef4444,#dc2626)}.platform-icon.platform-google{background:conic-gradient(from 35deg,#4285f4,#34a853 32%,#fbbc05 58%,#ea4335 78%,#4285f4)}.platform-icon.platform-chatgpt{background:linear-gradient(135deg,#10a37f,#0f766e 62%,#064e3b)}.platform-icon.platform-claude{background:linear-gradient(135deg,#d97706,#b45309 58%,#78350f)}.platform-icon.platform-youtube{background:linear-gradient(135deg,#f03,#dc2626 58%,#991b1b)}.platform-icon.platform-x{background:linear-gradient(135deg,#020617,#111827 58%,#475569)}.access-badge,.network-chip{white-space:nowrap;border:1px solid #0000;border-radius:999px;align-items:center;gap:6px;width:fit-content;min-height:26px;padding:0 10px;font-size:11px;font-weight:830;line-height:1;display:inline-flex}.access-badge.green,.network-chip.green{color:var(--green);background:#22c55e17;border-color:#22c55e2b}.access-badge.orange,.network-chip.orange{color:var(--orange);background:#f59e0b17;border-color:#f59e0b2e}.access-badge.red,.network-chip.red{color:var(--red);background:#ef444417;border-color:#ef44442e}.access-badge.blue,.network-chip.blue{color:var(--blue);background:#3b82f617;border-color:#3b82f62e}.access-badge.slate,.network-chip.slate{color:var(--text-muted);background:#64748b17;border-color:#64748b29}.network-list{gap:10px;display:grid}.network-list.compact-list{margin-top:2px}.network-list-item{background:#ffffffd1;border:1px solid #94a3b829;border-radius:13px;gap:8px;min-width:0;padding:12px;display:grid}.network-list-item p{color:var(--text-soft);overflow-wrap:anywhere;margin:0;font-size:12px;line-height:1.48}.network-dual{grid-template-columns:1fr;gap:10px;display:grid}.network-three-up{grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;display:grid}.network-metric,.network-block{background:#fff;border:1px solid #94a3b82e;border-radius:13px;min-width:0;padding:12px}.network-environment-panel{padding:20px}.dns-chip-row{flex-wrap:wrap;gap:8px;display:flex}.dns-chip{border:1px solid #0000;border-radius:999px;align-items:center;min-height:27px;padding:0 10px;font-size:11px;font-weight:800;display:inline-flex}.dns-chip.green{color:var(--green);background:#22c55e14;border-color:#22c55e29}.dns-chip.orange{color:var(--orange);background:#f59e0b14;border-color:#f59e0b29}.network-empty-state{min-height:132px;color:var(--text-muted);text-align:center;background:#f8fafcb8;border:1px dashed #94a3b847;border-radius:14px;place-items:center;padding:18px;font-size:13px;font-weight:760;display:grid}.network-page .section-head.compact h3{font-size:18px}.network-page .section-head.compact{margin-bottom:0}@media (width<=1180px){.network-command-center,.signal-grid,.network-workspace{grid-template-columns:1fr}.platform-summary-strip{justify-content:flex-start;margin-left:0}}@media (width<=860px){.network-command-center{padding:18px}.network-command-copy h2{font-size:25px}.platform-access-header{display:none}.platform-access-row{grid-template-columns:1fr;align-items:start;row-gap:10px;padding:14px 15px 14px 18px}.network-dual,.network-three-up{grid-template-columns:1fr}}.table-scroller{border:1px solid var(--line);background:#fff;border-radius:14px;overflow-x:auto}table{border-collapse:collapse;width:100%;min-width:720px}th,td{border-bottom:1px solid var(--line);text-align:left;vertical-align:top;color:var(--text-soft);padding:13px 12px;font-size:13px}th{color:var(--text-muted);background:#f8fafc;font-size:12px;font-weight:800}tbody tr:last-child td{border-bottom:0}td code{color:var(--text)}.method-pill,.status-pill{white-space:nowrap;border-radius:999px;justify-content:center;align-items:center;min-height:24px;padding:0 8px;font-size:11px;font-weight:800;display:inline-flex}.method-pill{color:#334155;background:#f1f5f9}.method-post{color:#4f46e5;background:#635bff1a}.method-get,.status-pill.is-ok{color:#047857;background:#22c55e1f}.status-pill.is-error{color:#dc2626;background:#ef44441f}.table-footer{color:var(--text-muted);margin-top:10px;font-size:12px}.log-toolbar{flex-wrap:wrap;gap:10px;margin-bottom:16px;display:flex}.log-search{flex:280px}.filter-chip{border:1px solid var(--line);background:#fff;border-radius:12px;align-items:center;gap:8px;min-height:40px;padding:0 12px;display:inline-flex}.filter-chip select{color:var(--text-soft);background:0 0;border:0;outline:none;font-size:13px;font-weight:700}.table-scroller tbody tr{cursor:pointer}.table-scroller tbody tr.is-selected{background:#635bff0a}.log-detail-panel{border:1px solid var(--line);background:#fffffff0;border-radius:16px;margin-top:16px;padding:18px 20px}.log-detail-head{justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:14px;display:flex}.log-detail-head h3{margin:0}.log-detail-head p{color:var(--text-muted);margin:6px 0 0;font-size:13px}.log-detail-grid{grid-template-columns:minmax(220px,.7fr) minmax(0,1.3fr);gap:14px;display:grid}.log-detail-meta{gap:10px;display:grid}.log-detail-meta div{gap:4px;display:grid}.log-detail-meta span{color:var(--text-muted);font-size:12px}.log-detail-meta strong{color:var(--text-soft);font-size:13px}.log-detail-pre{min-height:220px;max-height:320px}.switch-line{color:var(--text-soft);align-items:flex-start;gap:10px;font-size:13px;font-weight:700;line-height:1.5;display:flex}.settings-page{gap:18px;display:grid}.settings-page-head{justify-content:space-between;align-items:flex-start;gap:16px;display:flex}.settings-page-kicker{color:var(--brand);align-items:center;gap:6px;font-size:12px;font-weight:850;display:inline-flex}.settings-page-head h2{margin:8px 0 0;font-size:28px;line-height:1.15}.settings-page-head p{color:var(--text-muted);margin:8px 0 0;font-size:14px;line-height:1.6}.settings-page-actions{flex-wrap:wrap;justify-content:flex-end;gap:10px;display:flex}.settings-page-footer-actions{justify-content:flex-end;margin-top:2px}.settings-grid{grid-template-columns:repeat(4,minmax(220px,1fr));gap:14px;display:grid}.settings-section{border:1px solid var(--line);box-shadow:var(--shadow-sm);background:#fffffff0;border-radius:16px;gap:13px;padding:18px 20px;display:grid}.settings-section h4{margin:0;font-size:16px}@media (width<=1380px){.main-grid{grid-template-columns:1fr}.right-column{grid-template-columns:minmax(0,1fr)}.tester-card{order:-1}}@media (width<=1120px){.app-shell{grid-template-columns:1fr;width:calc(100vw - 20px);padding:10px}.sidebar{max-height:none;position:relative;top:0}.nav{grid-template-columns:repeat(6,minmax(max-content,1fr));padding-bottom:2px;overflow-x:auto}.nav-item{justify-content:center}.sidebar-status{display:none}.topbar{grid-template-columns:1fr}.top-actions{justify-content:flex-start}}@media (width<=900px){.app-shell{gap:12px;padding:0}.sidebar,.card,.trend-card,.log-table-wrap,.update-panel{border-left:0;border-right:0;border-radius:0}.sidebar{padding:16px 12px}.brand span,.sidebar-status{display:none}.nav{grid-template-columns:none;grid-auto-columns:max-content;grid-auto-flow:column}.nav-item{width:auto}.main{gap:12px}.topbar{padding:0 12px}.page-title h1{font-size:25px}.top-actions{flex-wrap:nowrap;padding-bottom:4px;overflow-x:auto}.summary-grid{grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;padding:0 12px}.summary-card{min-height:82px;padding:14px}.summary-card strong{font-size:19px}.main-grid{gap:12px}.section-head,.update-panel,.settings-drawer-footer{display:grid}.update-panel{grid-template-columns:auto minmax(0,1fr);align-items:start}.update-actions{grid-column:1/-1;grid-template-columns:1fr;justify-content:stretch;display:grid}.update-panel .btn-primary,.update-panel .btn-secondary{justify-content:center;width:100%}.section-actions,.button-row,.example-row{justify-content:flex-start}.filter-row{display:flex}.filter-row .control{flex:100%;min-width:0}.account-grid,.account-grid.profile-count-1,.account-grid.profile-count-2,.account-grid.profile-count-3,.account-grid.profile-count-many,.meta-grid{grid-template-columns:1fr}.account-card{border-radius:14px;padding:16px}.account-head{flex-direction:column;align-items:stretch}.account-select{width:max-content;margin-top:0}.compact-grid{grid-template-columns:1fr}.account-actions{display:flex}.tester-textarea{min-height:150px}.pre{max-height:320px}.modal-backdrop,.drawer-backdrop{padding:0}.modal-card,.settings-drawer{border-radius:0;width:100%;height:100%;max-height:none}.modal-body,.settings-drawer-body,.settings-drawer-head,.settings-drawer-footer{padding:16px}}@media (width<=460px){.summary-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.btn-primary,.btn-secondary,.btn-danger{min-height:40px;padding:0 12px}.card,.trend-card,.log-table-wrap{padding:16px 12px}}@media (width<=1120px){body{min-width:0}.app-shell{grid-template-columns:1fr;gap:14px;width:calc(100vw - 24px);padding:0}.sidebar{border-radius:24px;gap:14px;max-height:none;padding:22px 18px;position:relative;top:0}.brand span,.sidebar-status{display:none}.nav{grid-template-columns:repeat(5,minmax(max-content,1fr));grid-auto-columns:max-content;grid-auto-flow:column;padding-bottom:2px;overflow-x:auto}.nav-item{justify-content:center;width:auto}.topbar{grid-template-columns:1fr;padding:0}.page-title p{max-width:680px}.top-actions{flex-wrap:wrap;justify-content:flex-start;overflow:visible}.summary-grid{grid-template-columns:repeat(2,minmax(0,1fr));padding:0}.overview-grid,.tester-route-grid,.main-grid{grid-template-columns:1fr}.sidebar,.card,.trend-card,.log-table-wrap,.update-panel{border-left:1px solid var(--line);border-right:1px solid var(--line);border-radius:20px}.launch-page{grid-template-columns:1fr}.launch-visual{min-height:420px}.account-grid.profile-count-2{grid-template-columns:repeat(2,minmax(340px,1fr))}.account-grid.profile-count-3{grid-template-columns:repeat(3,minmax(320px,1fr))}.account-grid.profile-count-many{grid-template-columns:repeat(auto-fit,minmax(340px,1fr))}.meta-grid,.compact-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
|
1
|
+
:root{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light;--bg:#f8fafc;--panel:#fff;--panel-soft:#f8fafc;--line:#e2e8f0;--line-strong:#cbd5e1;--text:#0f172a;--text-soft:#334155;--text-muted:#64748b;--brand:#635bff;--brand-strong:#4f46e5;--brand-soft:#635bff1a;--blue:#3b82f6;--blue-soft:#3b82f61f;--green:#22c55e;--green-soft:#22c55e1f;--orange:#f59e0b;--orange-soft:#f59e0b1f;--red:#ef4444;--red-soft:#ef44441f;--plan-color:#94a3b8;--plan-soft:#94a3b81f;--plan-border:var(--line);--shadow:0 2px 10px #0f172a0f;--shadow-sm:var(--shadow);--radius:16px;--radius-sm:12px;--radius-xs:10px}*{box-sizing:border-box}html{background:var(--bg)}body{min-width:0;min-height:100vh;color:var(--text);background:radial-gradient(circle at top left, #635bff14, transparent 28%), radial-gradient(circle at right top, #3b82f60f, transparent 32%), var(--bg);margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,PingFang SC,sans-serif}button,input,select,textarea{font:inherit}button,a{-webkit-tap-highlight-color:transparent}button{cursor:pointer}a{color:inherit;text-decoration:none}.app-shell{grid-template-columns:236px minmax(0,1fr);align-items:start;gap:14px;width:min(100vw - 32px,1540px);max-width:none;margin:6px auto 18px;display:grid}.sidebar,.card,.trend-card,.summary-card,.account-card,.log-table-wrap,.tester-tabs,.service-card,.update-panel{border:1px solid var(--line);box-shadow:var(--shadow-sm);background:#fffffff0}.sidebar{border-radius:18px;gap:14px;min-width:0;max-height:calc(100vh - 20px);padding:14px 12px;display:grid;position:sticky;top:10px;overflow:auto}.brand{align-items:center;gap:12px;padding:2px 4px 4px;display:flex}.brand-mark{width:34px;height:34px;color:var(--brand);background:linear-gradient(#635bff24,#635bff0a);border:1px solid #635bff33;border-radius:12px;flex:none;place-items:center;display:grid;overflow:hidden}.brand-mark img{width:100%;height:100%;display:block}.brand strong{font-size:14px;line-height:1.25;display:block}.brand span{color:var(--text-muted);margin-top:5px;font-size:10px;line-height:1.5;display:block}.nav{gap:4px;display:grid}.nav-item{width:100%;min-height:36px;color:var(--text-soft);text-align:left;background:0 0;border:1px solid #0000;border-radius:11px;align-items:center;gap:10px;padding:0 11px;display:flex}.nav-item.is-active,.nav-item:hover{color:var(--brand);background:#635bff14;border-color:#635bff1a;font-weight:650}.sidebar-links{gap:12px;margin-top:auto}.sidebar-status{gap:12px;padding:11px}.sidebar-status-summary{grid-template-columns:16px minmax(0,1fr);align-items:center;gap:9px;min-width:0;display:grid}.sidebar-status-summary strong{font-size:14px;line-height:1.25;display:block}.sidebar-status-summary span:last-child{color:var(--text-muted);text-overflow:ellipsis;white-space:nowrap;margin-top:2px;font-size:11px;line-height:1.3;display:block;overflow:hidden}.sidebar-base-url{border:1px solid var(--line);width:100%;min-width:0;color:var(--text);text-align:left;background:#f8fafc;border-radius:11px;gap:5px;padding:9px;display:grid}.sidebar-base-url span{color:var(--text-muted);font-size:10px;font-weight:800}.sidebar-base-url code{min-width:0;color:var(--text);overflow-wrap:anywhere;font-size:11px;line-height:1.45}.sidebar-kv-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;display:grid}.sidebar-kv{background:#f8fafcd1;border-radius:11px;min-width:0;padding:8px 9px}.sidebar-kv.wide{grid-column:1/-1}.sidebar-kv span{color:var(--text-muted);font-size:10px;font-weight:800;line-height:1.2;display:block}.sidebar-kv strong{color:var(--text);overflow-wrap:anywhere;margin-top:4px;font-size:12px;line-height:1.35;display:block}.sidebar-link-list{gap:7px;display:grid}.sidebar-link{border:1px solid var(--line);width:100%;min-height:34px;color:var(--text-soft);text-align:left;background:#fff;border-radius:11px;justify-content:flex-start;align-items:center;gap:8px;padding:0 12px;font-size:12px;font-weight:700;display:inline-flex}.sidebar-link:hover{border-color:var(--line-strong);background:#f8fafc}.main{gap:16px;min-width:0;display:grid}.page-actions{flex-wrap:wrap;justify-content:flex-end;gap:10px;margin-bottom:2px;display:flex}.topbar{grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:12px;display:grid}.page-title h1{margin:0;font-size:27px;line-height:1.15}.page-kicker{color:var(--brand);letter-spacing:0;margin-bottom:8px;font-size:12px;font-weight:850;display:inline-flex}.page-title p{color:var(--text-muted);margin:8px 0 0;font-size:14px;line-height:1.6}.top-actions,.section-actions,.button-row,.example-row{flex-wrap:wrap;justify-content:flex-end;gap:10px;display:flex}.top-actions .btn-primary,.top-actions .btn-secondary,.top-actions .btn-danger{border-radius:10px;min-height:36px;padding:0 12px;font-size:12px}.route-loading{place-items:center;min-height:56vh;display:grid}.route-loading-card{border:1px solid var(--line);min-width:220px;box-shadow:var(--shadow-sm);text-align:center;background:#ffffffeb;border-radius:14px;grid-template-columns:1fr;justify-items:center;gap:12px;padding:14px 16px;display:grid}.route-loading-card strong{font-size:14px;line-height:1.3;display:block}.route-loading-card p{color:var(--text-muted);margin:4px 0 0;font-size:12px;line-height:1.4}.route-loading-bar{background:linear-gradient(90deg,#635bff3d,#22c55eb8,#f97316e0) 0 0/200% 100%;border-radius:999px;width:92px;height:4px;animation:1.1s ease-in-out infinite route-loading-bar}@keyframes route-loading-bar{0%{background-position:0%}50%{background-position:100%}to{background-position:0%}}.btn-primary,.btn-secondary,.btn-danger{border:1px solid var(--line);white-space:nowrap;min-height:40px;color:var(--text-soft);background:#fff;border-radius:12px;justify-content:center;align-items:center;gap:8px;padding:0 14px;font-size:13px;font-weight:700;display:inline-flex;box-shadow:0 1px #0f172a05}.btn-primary{color:#fff;border-color:var(--brand);background:var(--brand)}.btn-primary:hover{background:var(--brand-strong)}.btn-secondary:hover{border-color:var(--line-strong);background:#f8fafc}.btn-danger{color:#ef4444;background:var(--red-soft);border-color:#ef44442e}.btn-danger:hover{background:#ef444429}.btn-primary:disabled,.btn-secondary:disabled,.btn-danger:disabled{cursor:not-allowed;opacity:.58}.icon-only{width:42px;padding:0}.summary-grid{grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;display:grid}.overview-summary-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.summary-card{background:linear-gradient(145deg, #fffffffa, #f8fbfff5), var(--surface);border-color:#94a3b83d;border-radius:12px;grid-template-columns:24px minmax(0,1fr);align-content:start;gap:9px;min-height:84px;padding:12px 13px;display:grid;position:relative;overflow:hidden;box-shadow:0 14px 28px #0f172a12,inset 0 1px #ffffffe6}.summary-card:before{content:"";background:var(--brand);opacity:.75;width:3px;position:absolute;inset:0 auto 0 0}.summary-card:after{content:"";pointer-events:none;background:radial-gradient(circle at 12% 0,#4053ff14,#0000 34%);position:absolute;inset:0}.summary-card.tone-blue:before{background:var(--blue)}.summary-card.tone-green:before{background:var(--green)}.summary-card.tone-orange:before{background:var(--orange)}.summary-card.tone-red:before{background:var(--red)}.summary-card.tone-slate:before{background:var(--text-muted)}.summary-card>div:last-child{z-index:1;gap:4px;min-width:0;display:grid;position:relative}.summary-card span{color:var(--text-muted);font-size:11px;font-weight:760;line-height:1.2}.summary-card strong{letter-spacing:0;overflow-wrap:break-word;min-width:0;font-size:19px;line-height:1.08;display:block}.summary-card.compact-value strong{overflow-wrap:anywhere;font-size:16px;line-height:1.15}.usage-summary{gap:5px;min-width:0;display:grid}.usage-summary-row{grid-template-columns:42px minmax(0,1fr);align-items:center;gap:7px;min-width:0;display:grid}.usage-summary-row span{min-width:0;height:auto;color:var(--blue);background:0 0;border-radius:0;justify-content:flex-start;align-items:center;font-size:10px;font-weight:850;display:inline-flex}.usage-summary-row span:before{content:"";width:5px;height:5px;box-shadow:0 0 0 3px color-mix(in srgb, currentColor 14%, transparent);background:currentColor;border-radius:999px;margin-right:4px}.usage-summary-row:nth-child(2) span{color:var(--green)}.summary-card.compact-value .usage-summary-row strong{white-space:nowrap;text-overflow:ellipsis;overflow-wrap:normal;min-width:0;font-size:12px;line-height:1.25;overflow:hidden}.summary-card p{color:var(--text-muted);margin:0;font-size:11px;line-height:1.32}.summary-card p:empty{display:none}.summary-icon{z-index:1;width:20px;height:20px;color:var(--brand);background:var(--brand-soft);border-radius:999px;place-items:center;display:grid;position:relative;box-shadow:inset 0 0 0 1px #ffffffb8}.summary-icon.blue{color:var(--blue);background:var(--blue-soft)}.summary-icon.green{color:var(--green);background:var(--green-soft)}.summary-icon.orange{color:var(--orange);background:var(--orange-soft)}.main-grid{grid-template-columns:minmax(0,1.8fr) minmax(360px,.95fr);align-items:start;gap:22px;display:grid}.overview-grid,.tester-route-grid{grid-template-columns:minmax(0,1.18fr) minmax(420px,.82fr);align-items:start;gap:22px;display:grid}.tester-route-grid{grid-template-columns:minmax(0,1fr)}.tester-route-grid .tester-card{width:100%}.card,.trend-card,.log-table-wrap,.update-panel{border-radius:20px;padding:20px}.section-head{justify-content:space-between;align-items:flex-start;gap:16px;margin-bottom:18px;display:flex}.section-head.compact{margin-bottom:14px}.section-head h2,.section-head h3{margin:0;font-size:20px;line-height:1.25}.section-head p{color:var(--text-muted);margin:7px 0 0;font-size:13px;line-height:1.6}.trend-card{gap:14px;display:grid}.chart-wrap{border:1px solid var(--line);background:linear-gradient(#f8fafc99,#fff);border-radius:16px;width:100%;padding:14px;overflow:hidden}.chart-legend{color:var(--text-muted);flex-wrap:wrap;gap:14px;font-size:12px;display:flex}.legend-item{align-items:center;gap:8px;display:inline-flex}.legend-swatch{border-radius:999px;width:10px;height:10px}.legend-swatch.purple{background:#635bff}.legend-swatch.blue{background:#3b82f6}.trend-svg{width:100%;height:210px;margin-top:10px;display:block}.trend-labels{color:var(--text-muted);grid-template-columns:repeat(6,minmax(0,1fr));gap:6px;margin-top:10px;font-size:11px;line-height:1.4;display:grid}.filter-row{flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:18px;display:flex}.search-box{border:1px solid var(--line);min-width:0;min-height:40px;color:var(--text-muted);background:#fff;border-radius:12px;flex:220px;align-items:center;gap:10px;padding:0 12px;display:flex}.search-box input{width:100%;min-width:0;color:var(--text);background:0 0;border:0;outline:none}.input,.control,.textarea{border:1px solid var(--line);width:100%;color:var(--text);background:#fff;border-radius:12px;outline:none}.input,.control{min-height:40px;padding:0 12px}.filter-row .control{flex:0 0 156px;min-width:156px}.textarea{resize:vertical;min-height:180px;padding:14px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:1.55}.field{color:var(--text-soft);gap:8px;font-size:13px;font-weight:700;display:grid}.hint,.status-inline{color:var(--text-muted);margin:9px 0;font-size:13px;line-height:1.6}.account-selected-count{color:var(--text-muted);white-space:nowrap;font-size:12px;font-weight:700}.service-card{border-radius:16px;gap:12px;padding:14px;display:grid}.sidebar-status{border:1px solid var(--line);background:#fff}.sidebar-status.tone-green{border-color:#22c55e2e}.sidebar-status.tone-orange{background:#fffbebf2;border-color:#f59e0b3d}.sidebar-status.tone-red{background:#fef2f2f2;border-color:#ef444433}.sidebar-status .service-head span{color:var(--text-muted);font-size:11px;font-weight:700}.sidebar-meta-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;display:grid}.sidebar-meta{background:#f8fafce0;border-radius:11px;min-width:0;padding:8px 10px}.sidebar-meta span{color:var(--text-muted);font-size:10px;font-weight:800;line-height:1.2;display:block}.sidebar-meta strong{color:var(--text);overflow-wrap:anywhere;margin-top:4px;font-size:12px;line-height:1.35;display:block}.endpoint-card .compact-grid{grid-template-columns:1fr;gap:12px}.service-head{justify-content:space-between;align-items:center;gap:12px;display:flex}.service-list{gap:10px;display:grid}.compact-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.service-row{min-width:0}.service-row label{color:var(--text-muted);margin-bottom:4px;font-size:12px;display:block}.service-row strong,.service-row code{color:var(--text);word-break:break-word;overflow-wrap:anywhere;font-size:13px;line-height:1.5}.meta-grid .service-row label{margin-bottom:0;font-size:10px;line-height:1.4}.meta-grid .service-row strong,.meta-grid .service-row code{color:var(--text-soft);font-size:11px;line-height:1.45}.status-dot{background:var(--green);border-radius:999px;width:8px;height:8px;box-shadow:0 0 0 4px #22c55e24}.status-dot.offline{background:var(--orange);box-shadow:0 0 0 4px #f59e0b24}.update-panel{background:linear-gradient(135deg,#fffbebfa,#fffffff5),#fff;border-color:#f59e0b40;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:12px;padding:12px 14px;display:grid}.strong-update-panel{box-shadow:0 10px 22px #b4530917, var(--shadow-sm);border-color:#f59e0b57}.update-mark{color:#b45309;background:#fff7ed;border:1px solid #f59e0b3d;border-radius:12px;place-items:center;width:36px;height:36px;display:grid;box-shadow:inset 0 1px #ffffffc7}.update-copy{gap:4px;min-width:0;display:grid}.update-title-row{flex-wrap:wrap;align-items:baseline;gap:10px;display:flex}.update-title-row strong{font-size:16px;line-height:1.25}.update-copy p{color:var(--text-muted);flex-wrap:wrap;align-items:center;gap:6px;margin:0;font-size:13px;line-height:1.45;display:flex}.update-title-row span{color:var(--text-muted);font-size:13px;font-weight:700}.update-panel code{color:#92400e;overflow-wrap:anywhere;background:#fff;border:1px solid #f59e0b29;border-radius:8px;max-width:100%;padding:4px 7px;font-size:12px;line-height:1.35}.update-actions{flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:10px;display:flex}.update-panel .btn-primary,.update-panel .btn-secondary{white-space:nowrap;flex:none;align-items:center;gap:7px;min-height:36px;padding-inline:12px;text-decoration:none;display:inline-flex}.modal-backdrop,.drawer-backdrop,.loading-cover{z-index:20;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);background:#0f172a6b;place-items:center;padding:20px;display:grid;position:fixed;inset:0}.loading-cover{z-index:30;color:var(--text);background:#f8fafcc2;gap:12px}.modal-card{border:1px solid var(--line);width:min(760px,100%);max-height:min(760px,100vh - 40px);box-shadow:var(--shadow);background:#fff;border-radius:18px;overflow:auto}.modal-card.wide{width:min(980px,100%)}.modal-head{z-index:1;border-bottom:1px solid var(--line);background:#fffffff5;justify-content:space-between;align-items:center;gap:12px;padding:18px 20px;display:flex;position:sticky;top:0}.modal-head h3{margin:0}.modal-body{padding:20px}.modal-grid{gap:16px;display:grid}.modal-section{border:1px solid var(--line);background:#f8fafc;border-radius:14px;gap:12px;padding:16px;display:grid}.modal-section h4{margin:0}.modal-section p,.contact-notes span{color:var(--text-muted);margin:0;font-size:13px;line-height:1.6}.import-textarea{min-height:220px}.zip-import-box,.zip-import-preview{border:1px solid var(--line);background:#f8fafcd1;border-radius:12px;gap:10px;padding:12px;display:grid}.zip-import-box{grid-template-columns:minmax(0,1fr) auto;align-items:center}.zip-import-box strong,.zip-import-preview strong{color:var(--text);font-size:13px;line-height:1.25}.zip-import-box p,.zip-import-preview p,.zip-import-preview span{color:var(--text-muted);margin:0;font-size:12px;line-height:1.5}.zip-import-trigger{cursor:pointer;position:relative;overflow:hidden}.zip-import-trigger input{opacity:0;pointer-events:none;position:absolute;inset:0}.zip-import-preview.ready{background:#f0fdf4bd;border-color:#22c55e38}.zip-import-preview.error{background:#fef2f2c2;border-color:#ef444438}.zip-import-preview .btn-primary{width:fit-content}.contact-notes{gap:14px;display:grid}.contact-note,.contact-qr{gap:6px;display:grid}.contact-note{border:1px solid var(--line);background:var(--panel-soft);border-radius:16px;padding:14px 16px}.contact-note strong{font-size:14px;line-height:1.4}.contact-note span,.contact-note a,.contact-note code{color:var(--text-soft);word-break:break-word;font-size:13px;line-height:1.6}.contact-qr{border:1px solid var(--line);background:#fff;border-radius:20px;gap:10px;padding:14px}.contact-qr img{border:1px solid var(--line);background:var(--panel-soft);border-radius:16px;width:100%;max-width:420px;height:auto;display:block}.contact-qr span{color:var(--text-muted);font-size:12px;line-height:1.6}.image-preview-stage{background:#0f172a;border-radius:14px;place-items:center;min-height:320px;display:grid;overflow:hidden}.image-preview-stage img{max-width:100%;max-height:min(70vh,680px);display:block}.preview-modal-meta{color:var(--text-soft);word-break:break-word;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;font-size:13px;line-height:1.7;display:flex}.spin{animation:.9s linear infinite spin}@keyframes spin{to{transform:rotate(360deg)}}.launch-page{grid-template-columns:minmax(420px,.82fr) minmax(520px,1.18fr);align-items:stretch;gap:16px;min-height:calc(100vh - 172px);display:grid}.launch-copy,.launch-visual{border:1px solid var(--line);min-width:0;box-shadow:var(--shadow-sm);background:#fffffff0;border-radius:20px}.launch-copy{align-content:center;gap:20px;padding:28px;display:grid}.launch-identity{gap:18px;display:grid}.launch-app-icon{background:linear-gradient(180deg, #ffffffe6, #f8fafcd1), var(--surface);border:1px solid #635bff2e;border-radius:24px;place-items:center;width:96px;height:96px;display:grid;box-shadow:0 22px 44px #0f172a1f,0 0 0 8px #635bff0f}.launch-app-icon img{width:100%;height:100%;display:block}.launch-copy h2{max-width:560px;color:var(--text);letter-spacing:0;margin:0;font-size:44px;line-height:1.02}.launch-copy p{max-width:520px;color:var(--text-soft);margin:0;font-size:15px;line-height:1.8}.launch-metrics{grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;display:grid}.launch-metrics div{border:1px solid var(--line);background:#f8fafcd6;border-radius:14px;gap:8px;min-width:0;padding:14px;display:grid}.launch-metrics svg{color:var(--brand)}.launch-metrics span{color:var(--text-muted);font-size:11px;font-weight:800}.launch-metrics strong{min-width:0;color:var(--text);overflow-wrap:anywhere;font-size:18px;line-height:1.2}.launch-actions{flex-wrap:wrap;gap:10px;display:flex}.launch-actions .btn-secondary,.launch-actions a.btn-secondary{text-decoration:none}.launch-download-note{color:var(--text-muted);margin:-2px 0 0;font-size:12px;line-height:1.6}.launch-pills{flex-wrap:wrap;gap:8px;display:flex}.launch-pills span{min-height:28px;color:var(--text-muted);background:#635bff14;border-radius:999px;align-items:center;padding:0 10px;font-size:12px;font-weight:700;display:inline-flex}.launch-status{border-top:1px solid var(--line);grid-template-columns:repeat(2,minmax(0,1fr));gap:14px 18px;margin-top:8px;padding-top:20px;display:grid}.launch-visual{background:radial-gradient(circle at 24% 22%,#635bff26,#0000 34%),radial-gradient(circle at 82% 78%,#22c55e1f,#0000 32%),linear-gradient(#fffffff5,#f8fafcf0),#fff;place-items:center;padding:18px;display:grid;overflow:hidden}.launch-visual-stage{aspect-ratio:1.2;place-items:center;width:min(760px,100%);display:grid;position:relative}.launch-visual-mark{z-index:2;border-radius:34px;width:min(160px,24%);position:absolute;top:5%;left:4%;box-shadow:0 24px 54px #0f172a2e,0 0 0 10px #ffffffc7}.launch-visual-dashboard{object-fit:contain;filter:drop-shadow(0 28px 50px #0f172a24);width:92%;max-height:min(560px,100vh - 250px);display:block}.left-column,.right-column{gap:18px;min-width:0;display:grid}.account-grid{justify-content:stretch;align-items:start;gap:16px;width:100%;display:grid}.account-grid.profile-count-1{grid-template-columns:minmax(320px,520px)}.account-grid.profile-count-2{grid-template-columns:repeat(2,minmax(320px,1fr))}.account-grid.profile-count-3{grid-template-columns:repeat(3,minmax(300px,1fr))}.account-grid.profile-count-many{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}.account-card{--plan-color:#94a3b8;--plan-soft:#94a3b81f;--plan-border:var(--line);--usage-color:#16a34a;--usage-soft:#16a34a1f;border-color:var(--plan-border);border-radius:16px;grid-template-rows:none;align-content:start;align-self:start;gap:12px;min-width:0;padding:14px;display:grid;position:relative;overflow:hidden}.account-card:before{content:"";background:var(--plan-color);height:3px;position:absolute;inset:0 0 auto}.account-card.plan-free{--plan-color:#94a3b8;--plan-soft:#94a3b81f;--plan-border:var(--line)}.account-card.plan-plus{--plan-color:#635bff;--plan-soft:#635bff1c;--plan-border:#635bff33}.account-card.plan-pro{--plan-color:#4f46e5;--plan-soft:#4f46e51c;--plan-border:#4f46e538}.account-card.plan-team{--plan-color:#0f766e;--plan-soft:#0f766e1c;--plan-border:#0f766e38}.account-card.plan-premium{--plan-color:#d97706;--plan-soft:#d977061f;--plan-border:#d9770657;box-shadow:0 10px 26px #b453091a, var(--shadow)}.account-card.plan-enterprise{--plan-color:#a16207;--plan-soft:#a1620724;--plan-border:#47556947;box-shadow:0 12px 28px #0f172a1a, var(--shadow)}.account-card.is-auth-invalid{--plan-color:#ef4444;--plan-soft:#ef444417;--plan-border:#ef444452;border-color:var(--plan-border);box-shadow:0 12px 28px #b91c1c14, var(--shadow);background:linear-gradient(#fef2f2e6,#fffffffa 46%),#fff}.account-card.is-auth-invalid:before{background:#ef4444;height:3px}.account-card.is-auth-invalid .usage-corner{color:#991b1b;background:linear-gradient(135deg,#fef2f2,#fee2e2);border-color:#ef444447;box-shadow:0 8px 18px #b91c1c1a,inset 0 1px #ffffffd1}.account-card.is-auth-invalid .avatar{color:#dc2626;background:#fff;border-color:#ef444475;box-shadow:0 0 0 3px #ef44441a}.account-card.is-auth-invalid .progress-bar{opacity:.72}.account-card.is-auth-invalid .usage-status-row,.account-card.is-auth-invalid .progress-track{background:#fef2f2ad}.account-card.is-auth-invalid .account-actions .btn-secondary:disabled{opacity:.86;color:#991b1b;background:#fff;border-color:#ef44442e}.account-head{justify-content:space-between;align-items:flex-start;gap:12px;padding-top:8px;display:flex}.account-title{flex:1;gap:6px;min-width:0;display:grid}.account-name{align-items:center;gap:8px;min-width:0;display:flex}.account-name strong{-webkit-line-clamp:2;text-overflow:ellipsis;white-space:normal;overflow-wrap:anywhere;-webkit-box-orient:vertical;min-width:0;font-size:13px;line-height:1.35;display:-webkit-box;overflow:hidden}.account-icon-btn{border:1px solid var(--line);width:24px;height:24px;color:var(--text-muted);background:#fff;border-radius:999px;flex:none;justify-content:center;align-items:center;padding:0;display:flex}.account-icon-btn:hover{color:var(--plan-color);border-color:var(--plan-color);background:var(--plan-soft)}.avatar{background:var(--panel-soft);border:1px solid var(--plan-color);width:24px;height:24px;box-shadow:0 0 0 3px var(--plan-soft);color:var(--plan-color);border-radius:999px;flex:none;place-items:center;font-size:11px;font-weight:700;display:grid}.badge-row{flex-wrap:wrap;gap:6px;display:flex}.account-select{border:1px solid var(--line);min-height:28px;color:var(--text-muted);cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap;background:#fff;border-radius:8px;align-items:center;gap:6px;margin-top:28px;padding:0 8px;font-size:12px;font-weight:600;display:inline-flex}.account-select input{width:14px;height:14px;margin:0}.badge{white-space:nowrap;border-radius:999px;justify-content:center;align-items:center;min-height:22px;padding:0 8px;font-size:11px;font-weight:600;display:inline-flex}.badge.brand{color:var(--plan-color);background:var(--plan-soft)}.usage-corner{color:#047857;letter-spacing:0;pointer-events:none;z-index:1;background:linear-gradient(135deg,#ecfdf5,#d1fae5);border:1px solid #10b98147;border-radius:999px;align-items:center;gap:5px;min-height:24px;padding:0 10px 0 8px;font-size:10px;font-weight:800;line-height:22px;display:inline-flex;position:absolute;top:10px;right:12px;box-shadow:0 8px 18px #10b9811f,inset 0 1px #ffffffd1}.usage-corner:before{content:"";background:currentColor;border-radius:999px;flex:none;width:6px;height:6px;box-shadow:0 0 0 3px #10b9811f}.usage-corner span{line-height:1}.usage-corner.codex-only{color:#1d4ed8;background:linear-gradient(135deg,#eff6ff,#dbeafe);border-color:#2563eb3d;box-shadow:0 8px 18px #2563eb1f,inset 0 1px #ffffffd1}.usage-corner.codex-only:before{box-shadow:0 0 0 3px #2563eb1f}.usage-corner.dual{color:#4f46e5;background:linear-gradient(135deg,#f5f3ff,#ede9fe);border-color:#635bff40;box-shadow:0 8px 18px #635bff21,inset 0 1px #ffffffd1}.usage-corner.dual:before{box-shadow:0 0 0 3px #635bff1f}.badge.green{color:#15803d;background:var(--green-soft)}.badge.orange{color:#b45309;background:var(--orange-soft)}.badge.red{color:#dc2626;background:var(--red-soft)}.badge.muted{color:var(--text-muted);background:#f1f5f9}.account-metrics{gap:10px;display:grid}.quota-row{gap:6px;display:grid}.quota-line{color:var(--text-soft);justify-content:space-between;align-items:center;gap:10px;font-size:11px;line-height:1.45;display:flex}.quota-line span{min-width:0}.quota-line strong{color:var(--text);flex-shrink:0;font-size:12px}.progress-track{background:#eef2f7;border-radius:999px;width:100%;height:5px;overflow:hidden}.progress-bar{border-radius:inherit;background:var(--brand);height:100%}.progress-bar.blue{background:var(--blue)}.progress-bar.orange{background:var(--orange)}.progress-bar.red{background:#f43f5e}.usage-status-row{background:var(--panel-soft);color:var(--text-muted);border-radius:10px;flex-wrap:nowrap;justify-content:space-between;align-items:center;gap:8px;padding:8px 10px;font-size:11px;line-height:1.4;display:flex}.usage-status{white-space:nowrap;align-items:center;gap:5px;min-width:0;font-weight:700;display:inline-flex}.usage-status svg{width:12px;height:12px;color:var(--text-muted);flex:none}.usage-dot{background:#cbd5e1;border-radius:999px;flex:none;width:6px;height:6px}.usage-dot.active{background:#22c55e;box-shadow:0 0 0 3px #22c55e1f}.usage-state-text{color:var(--text-muted);font-weight:700}.usage-status.is-active .usage-state-text{color:#15803d}.compact-meta-row{min-width:0;color:var(--text-muted);gap:8px;font-size:11px;line-height:1.45;display:grid}.compact-reset-list{flex-wrap:nowrap;align-items:center;gap:10px;min-width:0;display:flex}.compact-meta-item{flex:1 1 0;align-items:baseline;gap:5px;min-width:0;display:flex}.compact-meta-item label{color:var(--text-muted);white-space:nowrap;font-size:10px;line-height:1.4}.compact-meta-item strong{color:var(--text-soft);text-align:left;overflow-wrap:anywhere;font-size:11px;line-height:1.4}.compact-meta-actions{justify-content:center;align-items:center;gap:10px;margin-top:2px;display:flex}.compact-meta-actions:before,.compact-meta-actions:after{content:"";background:var(--line);flex:auto;min-width:18px;height:1px}.details-toggle{min-height:24px;color:var(--brand);white-space:nowrap;cursor:pointer;background:0 0;border:0;justify-content:center;align-items:center;gap:5px;padding:0 6px;font-size:11px;font-weight:700;display:inline-flex}.details-toggle:hover{color:#4338ca}.details-toggle svg{width:12px;height:12px;transition:transform .16s}.details-toggle.is-expanded svg{transform:rotate(180deg)}.meta-grid{border-top:1px solid var(--line);grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 12px;padding-top:10px;display:grid}.meta-item{gap:3px;min-width:0;display:grid}.meta-grid .service-row label{color:var(--text-muted);font-size:10px;line-height:1.4}.meta-grid .service-row strong,.meta-grid .service-row span,.meta-grid .service-row code{color:var(--text-soft);word-break:break-word;overflow-wrap:anywhere;font-size:11px;line-height:1.45}.account-actions{flex-wrap:wrap;gap:8px;margin-top:0;display:flex}.account-actions .btn-secondary,.account-actions .btn-danger{border-radius:10px;flex:120px;min-height:36px;padding:0 12px;font-size:12px}.account-actions .btn-secondary.is-current{opacity:1;color:#047857;cursor:default;background:linear-gradient(135deg,#f0fdf4,#dcfce7);border-color:#10b9815c;position:relative;box-shadow:inset 0 1px #fffc,0 6px 14px #10b98114}.account-actions .btn-secondary.is-current:before{content:"";background:#22c55e;border-radius:999px;flex:none;width:7px;height:7px;box-shadow:0 0 0 3px #22c55e1f}.account-actions .btn-secondary.is-current.codex{color:#1d4ed8;background:linear-gradient(135deg,#eff6ff,#dbeafe);border-color:#2563eb52;box-shadow:inset 0 1px #fffc,0 6px 14px #2563eb14}.account-actions .btn-secondary.is-current.codex:before{background:#3b82f6;box-shadow:0 0 0 3px #3b82f61f}.tester-card{gap:16px;display:grid}.tester-tabs,.tester-result-tabs{border-radius:14px;gap:4px;padding:6px;display:flex;overflow-x:auto}.tester-tabs{grid-template-columns:repeat(5,minmax(92px,1fr));gap:6px;display:grid}.tester-result-tabs{box-shadow:none;background:0 0;border:0;padding:0}.tab-btn{min-height:38px;color:var(--text-muted);white-space:nowrap;background:0 0;border:0;border-radius:10px;padding:0 14px;font-weight:800}.tab-btn.is-active{color:var(--brand);background:#fff;box-shadow:0 6px 16px #0f172a0f}.tester-workbench{grid-template-columns:minmax(360px,.92fr) minmax(360px,1.08fr);align-items:stretch;gap:16px;display:grid}.tester-pane{border:1px solid var(--line);background:linear-gradient(#fff,#f8fafc9e);border-radius:16px;align-content:start;gap:12px;min-width:0;padding:14px;display:grid}.tester-request-pane{grid-template-rows:auto auto minmax(180px,1fr) auto auto}.tester-body-field{grid-template-rows:auto minmax(0,1fr);min-height:0;display:grid}.tester-textarea{resize:vertical;height:100%;min-height:180px}.tester-actions-bar{grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:10px;display:grid}.tester-actions-group{gap:10px;min-width:0;display:grid}.tester-actions-bar .example-row{justify-content:flex-start;gap:8px}.tester-copy-row{flex-wrap:wrap;gap:8px;display:flex}.tester-copy-row-top{margin-top:-4px}.tester-actions-bar .btn-secondary{border-radius:10px;min-height:34px;padding:0 10px;font-size:12px}.tester-response-pane{grid-template-rows:auto minmax(0,1fr)}.tester-result-head{grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px;display:grid}.tester-result-head .status-inline{text-align:right;white-space:nowrap;text-overflow:ellipsis;max-width:220px;margin:0;overflow:hidden}.edit-upload-row{grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:10px 12px;margin-top:-2px;display:grid}.edit-upload-mode{gap:6px;min-width:0;display:grid}.edit-upload-mode>span{color:var(--text-muted);font-size:11px;font-weight:800;line-height:1.25}.edit-upload-toggle{flex-wrap:wrap;gap:6px;display:flex}.edit-upload-toggle .tab-btn{min-height:34px;padding:0 12px}.upload-btn{cursor:pointer;white-space:nowrap}.upload-btn input{display:none}.edit-upload-row span{color:var(--text-muted);grid-column:1/-1;font-size:12px;line-height:1.5}.pre{color:#e2e8f0;white-space:pre-wrap;overflow-wrap:anywhere;background:#0f172a;border-radius:12px;width:100%;min-height:312px;max-height:420px;margin:0;padding:16px;font-size:12px;line-height:1.6;overflow:auto}.preview-panel{min-height:312px}.preview-empty,.empty-state{border:1px dashed var(--line-strong);text-align:center;min-height:140px;color:var(--text-muted);background:#f8fafc;border-radius:14px;place-items:center;padding:20px;display:grid}.preview-grid{grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:12px;display:grid}.preview-card{gap:8px;margin:0;display:grid}.preview-card button{border:1px solid var(--line);background:#fff;border-radius:12px;padding:0;overflow:hidden}.preview-card img{aspect-ratio:1;object-fit:cover;width:100%;display:block}.preview-card figcaption{color:var(--text-muted);overflow-wrap:anywhere;font-size:12px}.preview-actions{flex-wrap:wrap;gap:8px;display:flex}.preview-actions a{border:1px solid var(--line);min-height:34px;color:var(--text-soft);border-radius:10px;justify-content:center;align-items:center;padding:0 12px;font-size:12px;font-weight:600;display:inline-flex}.pre.tester-log{min-height:200px}.image-bed-page{gap:16px;display:grid}.image-bed-workbench{grid-template-columns:minmax(0,1.45fr) minmax(320px,.8fr);align-items:start;gap:14px;display:grid}.image-bed-upload-panel,.image-bed-side-card,.image-bed-gallery-section,.image-bed-help-section{border:1px solid var(--line);box-shadow:var(--shadow-sm);background:#fffffff2}.image-bed-upload-panel{background:linear-gradient(135deg,#fffffffa,#f6f8ffeb),#fff;border-radius:18px;grid-template-rows:auto minmax(220px,1fr) auto;gap:16px;min-height:440px;padding:22px;display:grid;overflow:hidden}.image-bed-upload-panel.is-dragging{border-color:#635bff6b;box-shadow:0 18px 45px #635bff1f}.image-bed-upload-copy{gap:7px;max-width:680px;display:grid}.image-bed-upload-copy span{color:var(--brand);font-size:12px;font-weight:850;line-height:1.3}.image-bed-upload-copy h2{color:var(--text);margin:0;font-size:28px;line-height:1.16}.image-bed-upload-copy p{color:var(--text-muted);margin:0;font-size:13px;line-height:1.65}.image-bed-upload-copy strong{color:var(--text);font-weight:800}.upload-dropzone{min-height:220px;color:var(--text-soft);text-align:center;cursor:pointer;background:linear-gradient(#ffffffb8,#f8fafcb8),#f8fafce0;border:1px dashed #635bff52;border-radius:16px;align-content:center;place-items:center;gap:10px;padding:24px;transition:border-color .16s,background .16s,transform .16s;display:grid;position:relative}.upload-dropzone:hover,.upload-dropzone.is-dragging{border-color:var(--brand);background:#635bff12;transform:translateY(-1px)}.upload-dropzone.is-disabled{opacity:.84}.upload-dropzone input{opacity:0;pointer-events:none;width:1px;height:1px;position:absolute}.upload-dropzone-icon{width:52px;height:52px;color:var(--brand);background:#635bff1a;border:1px solid #635bff29;border-radius:16px;place-items:center;display:grid}.upload-dropzone strong{color:var(--text);font-size:18px;line-height:1.3}.upload-dropzone span{max-width:360px;color:var(--text-muted);font-size:13px;line-height:1.5}.upload-progress-block,.image-bed-latest,.image-bed-upload-note{background:#635bff0d;border:1px solid #635bff24;border-radius:15px;min-height:72px}.upload-progress-block{gap:10px;padding:14px 16px;display:grid}.upload-progress-head{justify-content:space-between;align-items:baseline;gap:12px;display:flex}.upload-progress-head strong{color:var(--text);font-size:13px;line-height:1.35}.upload-progress-head span{color:var(--text-muted);overflow-wrap:anywhere;font-size:11px;line-height:1.35}.upload-progress-track{background:#94a3b833;border-radius:999px;height:10px;overflow:hidden}.upload-progress-fill{border-radius:inherit;background:linear-gradient(90deg, var(--brand), #10b981);height:100%;transition:width .18s}.image-bed-latest{grid-template-columns:54px minmax(0,1fr) auto;align-items:center;gap:12px;padding:10px;display:grid}.image-bed-latest-preview{background:#f8fafc;border:0;border-radius:13px;width:54px;height:54px;padding:0;overflow:hidden}.image-bed-latest-preview img{object-fit:cover;width:100%;height:100%;display:block}.image-bed-latest-info{gap:3px;min-width:0;display:grid}.image-bed-latest-info span{color:var(--text-muted);font-size:10px;font-weight:850;line-height:1.2}.image-bed-latest-info strong,.image-bed-latest-info code{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.image-bed-latest-info strong{color:var(--text);font-size:13px}.image-bed-latest-info code{color:var(--text-muted);font-size:11px}.image-bed-upload-note{color:var(--text-muted);align-items:center;padding:14px 16px;font-size:13px;line-height:1.5;display:flex}.image-bed-side-stack{gap:14px;display:grid}.image-bed-side-card{border-radius:16px;align-content:start;gap:13px;padding:18px;display:grid}.image-bed-side-card h4,.image-bed-gallery-section h4{color:var(--text);margin:0;font-size:16px;line-height:1.3}.image-bed-side-card p{color:var(--text-muted);margin:0;font-size:12px;line-height:1.6}.image-bed-section-head{justify-content:space-between;align-items:center;gap:10px;display:flex}.image-bed-section-head p{color:var(--text-muted);margin:4px 0 0;font-size:12px;line-height:1.45}.image-bed-status-dot{background:#cbd5e1;border-radius:999px;width:10px;height:10px;box-shadow:0 0 0 4px #cbd5e138}.image-bed-status-dot.is-ok{background:#10b981;box-shadow:0 0 0 4px #10b98129}.image-bed-status-dot.is-warn{background:#f59e0b;box-shadow:0 0 0 4px #f59e0b29}.image-bed-connection-label{color:var(--text);overflow-wrap:anywhere;font-size:15px;line-height:1.4}.image-bed-link-button{color:var(--brand);background:0 0;border:0;padding:0;font-size:12px;font-weight:800}.image-bed-token-actions{grid-template-columns:1fr auto;gap:10px;display:grid}.image-bed-token-hint{color:var(--text-muted);margin:-2px 0 0;font-size:11px;font-weight:650;line-height:1.5}.image-bed-token-hint code{color:var(--text);font-weight:800}.image-bed-token-summary{border:1px solid var(--line);background:#f8fafccc;border-radius:14px;justify-content:space-between;align-items:center;gap:12px;min-height:58px;padding:12px;display:flex}.image-bed-token-summary span{color:var(--text-muted);font-size:10px;font-weight:850;line-height:1.25;display:block}.image-bed-token-summary strong{color:var(--text);margin-top:4px;font-size:14px;line-height:1.35;display:block}.image-bed-target-list{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;display:grid}.image-bed-target-list div{background:#f8fafcd1;border-radius:12px;min-width:0;padding:10px}.image-bed-target-list span{color:var(--text-muted);font-size:10px;font-weight:850;line-height:1.25;display:block}.image-bed-target-list strong{color:var(--text);overflow-wrap:anywhere;margin-top:5px;font-size:12px;line-height:1.35;display:block}.image-bed-gallery-section{border-radius:18px;gap:14px;padding:18px;display:grid}.image-bed-empty{min-height:136px;color:var(--text-muted);text-align:center;background:#f8fafcd1;border-radius:15px;place-items:center;padding:24px;font-size:13px;line-height:1.6;display:grid}.image-bed-results-grid{grid-template-columns:repeat(auto-fill,minmax(132px,150px));align-items:start;gap:12px;display:grid}.image-bed-result-card{border:1px solid var(--line);background:#fff;border-radius:14px;align-content:start;gap:7px;margin:0;display:grid;position:relative;overflow:hidden;box-shadow:0 8px 18px #0f172a0d}.image-bed-preview-button{aspect-ratio:1/.78;background:#f8fafc;border:0;padding:0;position:relative;overflow:hidden}.image-bed-preview-button img{object-fit:cover;width:100%;height:100%;transition:transform .18s;display:block}.image-bed-preview-button:hover img{transform:scale(1.03)}.image-bed-result-card figcaption{gap:3px;min-width:0;padding:0 10px 10px;display:grid}.image-bed-result-card figcaption strong{color:var(--text);text-overflow:ellipsis;white-space:nowrap;font-size:12px;line-height:1.4;overflow:hidden}.image-bed-result-card figcaption span,.image-bed-result-card figcaption code{color:var(--text-muted);overflow-wrap:anywhere;font-size:10px;line-height:1.4}.image-bed-result-actions{gap:6px;display:flex;position:absolute;top:7px;right:7px}.image-bed-card-action{width:30px;height:30px;color:var(--text-soft);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);background:#ffffffe0;border:1px solid #ffffffb8;border-radius:10px;justify-content:center;align-items:center;display:inline-flex;box-shadow:0 8px 18px #0f172a1a}.image-bed-card-action:hover{color:var(--brand);background:#fff;border-color:#635bff33}.image-bed-card-action.is-danger{color:#ef4444}.image-bed-card-action.is-danger:hover{color:#dc2626;border-color:#ef444438}.image-bed-card-action:disabled{cursor:not-allowed;opacity:.62}.image-bed-load-more{width:100%}.image-bed-help-section{border-radius:16px;padding:0;overflow:hidden}.image-bed-help-section summary{cursor:pointer;color:var(--text);padding:15px 18px;font-size:14px;font-weight:800}.image-bed-help-intro{color:var(--text-muted);margin:0;padding:0 20px 14px;font-size:13px;line-height:1.6}.image-bed-help-intro code{color:var(--text);font-weight:800}.image-bed-steps{color:var(--text-soft);gap:11px;margin:0;padding:0 20px 16px 36px;font-size:13px;line-height:1.6;display:grid}.image-bed-steps li{min-width:0}.image-bed-steps strong,.image-bed-steps code{color:var(--text);font-weight:750}.image-bed-help-facts{border-top:1px solid var(--line);border-bottom:1px solid var(--line);margin:0 20px 16px;display:grid}.image-bed-help-facts div{border-top:1px solid #94a3b829;grid-template-columns:110px minmax(0,1fr);gap:12px;min-width:0;padding:12px 0;display:grid}.image-bed-help-facts div:first-child{border-top:0}.image-bed-help-facts dt{color:var(--text);font-size:12px;font-weight:850;line-height:1.4}.image-bed-help-facts dd{color:var(--text-muted);margin:0;font-size:12px;line-height:1.55}.image-bed-help-facts code{color:var(--text);font-weight:800}.image-bed-help-section .hint{margin:0;padding:0 20px 18px}@media (width<=1120px){.image-bed-workbench{grid-template-columns:1fr}.image-bed-side-stack{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width<=760px){.image-bed-upload-panel,.image-bed-gallery-section{border-radius:16px;padding:16px}.image-bed-upload-copy h2{font-size:23px}.image-bed-side-stack,.image-bed-target-list,.image-bed-token-actions,.image-bed-help-facts div,.image-bed-latest,.image-bed-result-actions{grid-template-columns:1fr}.image-bed-latest-preview{aspect-ratio:1/.62;width:100%;height:auto}}.network-page{gap:18px;display:grid}.network-command-center{box-shadow:var(--shadow);background:linear-gradient(135deg,#fff 0%,#f8fbff 58%,#f4fbf7 100%);border:1px solid #94a3b838;border-radius:20px;grid-template-columns:minmax(0,1fr) 260px;align-items:stretch;gap:18px;padding:22px;display:grid;overflow:hidden}.network-command-center.green{border-color:#22c55e33}.network-command-center.orange{border-color:#f59e0b38}.network-command-center.red{border-color:#ef444438}.network-command-copy{align-content:center;gap:10px;min-width:0;display:grid}.network-eyebrow{width:fit-content;color:var(--brand);align-items:center;gap:7px;font-size:12px;font-weight:850;line-height:1.2;display:inline-flex}.network-command-copy h2{color:var(--text);letter-spacing:0;margin:0;font-size:31px;line-height:1.12}.network-command-copy p{max-width:760px;color:var(--text-muted);margin:0;font-size:13px;line-height:1.65}.network-command-status{flex-wrap:wrap;align-items:center;gap:8px 12px;margin-top:2px;display:flex}.network-command-status>span:not(.network-chip){color:var(--text-muted);align-items:center;gap:6px;font-size:12px;font-weight:720;display:inline-flex}.network-toolbar-status{color:var(--text-soft)}.access-score-card{background:#ffffffc7;border:1px solid #94a3b82e;border-radius:16px;align-content:center;gap:10px;min-width:0;padding:18px;display:grid;box-shadow:inset 0 1px #ffffffe0}.access-score-card>span{color:var(--text-muted);font-size:11px;font-weight:850;line-height:1.2}.access-score-card strong{color:var(--text);letter-spacing:0;font-size:38px;line-height:1}.access-score-card p{color:var(--text-muted);margin:0;font-size:12px;font-weight:700;line-height:1.45}.access-score-bar{background:#94a3b829;border-radius:999px;width:100%;height:8px;position:relative;overflow:hidden}.access-score-bar i{border-radius:inherit;background:linear-gradient(90deg,#22c55e,#3b82f6);min-width:0;max-width:100%;height:100%;display:block}.access-score-card .btn-secondary{width:100%}.network-error{color:var(--red);background:#ef444412;border:1px solid #ef444429;border-radius:12px;margin:0;padding:10px 12px;font-size:12px;font-weight:750;line-height:1.5}.signal-grid{grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;display:grid}.signal-card{background:#fff;border:1px solid #94a3b833;border-radius:16px;grid-template-columns:34px minmax(0,1fr);align-content:start;gap:12px;min-width:0;min-height:122px;padding:15px;display:grid;box-shadow:0 10px 22px #0f172a0d}.signal-card-icon{width:34px;height:34px;color:var(--blue);background:var(--blue-soft);border-radius:11px;place-items:center;display:grid}.signal-card span,.network-metric span,.network-block span{color:var(--text-muted);font-size:11px;font-weight:820;line-height:1.2;display:block}.signal-card strong,.network-metric strong,.network-block strong{min-width:0;color:var(--text);overflow-wrap:anywhere;margin-top:6px;font-size:15px;line-height:1.25;display:block}.signal-card p,.network-metric p,.network-block p{color:var(--text-muted);overflow-wrap:anywhere;margin:7px 0 0;font-size:12px;line-height:1.45}.signal-card.tone-green,.network-metric.tone-green,.network-block.tone-green{background:linear-gradient(#fff,#f0fdf4c7);border-color:#22c55e2e}.signal-card.tone-green .signal-card-icon{color:var(--green);background:var(--green-soft)}.signal-card.tone-orange,.network-metric.tone-orange,.network-block.tone-orange{background:linear-gradient(#fff,#fffbebd6);border-color:#f59e0b33}.signal-card.tone-orange .signal-card-icon{color:var(--orange);background:var(--orange-soft)}.signal-card.tone-red,.network-metric.tone-red,.network-block.tone-red{background:linear-gradient(#fff,#fef2f2db);border-color:#ef444433}.signal-card.tone-red .signal-card-icon{color:var(--red);background:var(--red-soft)}.signal-card.tone-slate,.network-metric.tone-slate,.network-block.tone-slate{background:linear-gradient(#fff,#f8fafce6)}.network-workspace{grid-template-columns:minmax(560px,1.16fr) minmax(360px,.84fr);align-items:start;gap:18px;display:grid}.network-section{gap:14px;display:grid}.network-platform-panel{padding:20px}.network-side{gap:18px;min-width:0;display:grid}.platform-summary-strip{flex-wrap:wrap;justify-content:flex-end;gap:8px;margin-left:auto;display:inline-flex}.platform-summary-chip{background:#fff;border:1px solid #94a3b82e;border-radius:12px;gap:3px;min-width:66px;padding:9px 11px;display:grid}.platform-summary-chip strong{color:var(--text);font-size:20px;font-weight:900;line-height:1}.platform-summary-chip span{color:var(--text-muted);font-size:10px;font-weight:820;line-height:1.1}.platform-summary-chip.green{background:#f0fdf4cc;border-color:#22c55e33}.platform-summary-chip.orange{background:#fffbebdb;border-color:#f59e0b33}.platform-summary-chip.red{background:#fef2f2db;border-color:#ef444433}.platform-access-header,.platform-access-row{grid-template-columns:minmax(150px,1.05fr) 108px 92px minmax(140px,1fr);align-items:center;column-gap:16px;display:grid}.platform-access-header{color:var(--text-muted);padding:0 16px;font-size:11px;font-weight:830;line-height:1}.platform-access-list{background:#fff;border:1px solid #94a3b82e;border-radius:15px;gap:0;display:grid;overflow:hidden}.platform-access-row{background:#fff;border-top:1px solid #94a3b821;min-width:0;padding:14px 16px 14px 18px;transition:background .14s;position:relative}.platform-access-row:first-child{border-top:0}.platform-access-row:hover{background:#f8fafcd1}.platform-access-row:before{content:"";background:#94a3b861;border-radius:999px;width:3px;position:absolute;inset:12px auto 12px 0}.platform-access-row.green{border-left:0}.platform-access-row.green:before{background:var(--green)}.platform-access-row.orange{border-left:0}.platform-access-row.orange:before{background:var(--orange)}.platform-access-row.red{border-left:0}.platform-access-row.red:before{background:var(--red)}.platform-access-main{align-items:center;gap:12px;min-width:0;display:flex}.platform-access-main>div{gap:3px;min-width:0;display:grid}.platform-access-main strong{color:var(--text);font-size:15px;font-weight:850;line-height:1.2}.platform-access-main span,.platform-access-result>span,.platform-access-latency span{color:var(--text-muted);overflow-wrap:anywhere;font-size:12px;font-weight:700;line-height:1.35}.platform-access-result,.platform-access-latency{justify-items:start;gap:5px;min-width:0;display:grid}.platform-access-latency strong{color:var(--text);font-size:14px;font-weight:850;line-height:1.2}.platform-access-detail{min-width:0}.platform-access-detail span{color:var(--text-muted);overflow-wrap:anywhere;font-size:12px;font-weight:720;line-height:1.45;display:block}.platform-icon{color:#fff;background:linear-gradient(135deg,#64748b,#334155);border-radius:12px;flex:none;place-items:center;width:38px;height:38px;font-size:13px;font-weight:900;display:grid;box-shadow:inset 0 1px #ffffff47}.platform-icon img{filter:brightness(0)invert();width:19px;height:19px;display:block}.platform-icon.green{background:linear-gradient(135deg,#22c55e,#16a34a)}.platform-icon.orange{background:linear-gradient(135deg,#f59e0b,#d97706)}.platform-icon.red{background:linear-gradient(135deg,#ef4444,#dc2626)}.platform-icon.platform-google{background:conic-gradient(from 35deg,#4285f4,#34a853 32%,#fbbc05 58%,#ea4335 78%,#4285f4)}.platform-icon.platform-chatgpt{background:linear-gradient(135deg,#10a37f,#0f766e 62%,#064e3b)}.platform-icon.platform-claude{background:linear-gradient(135deg,#d97706,#b45309 58%,#78350f)}.platform-icon.platform-youtube{background:linear-gradient(135deg,#f03,#dc2626 58%,#991b1b)}.platform-icon.platform-x{background:linear-gradient(135deg,#020617,#111827 58%,#475569)}.access-badge,.network-chip{white-space:nowrap;border:1px solid #0000;border-radius:999px;align-items:center;gap:6px;width:fit-content;min-height:26px;padding:0 10px;font-size:11px;font-weight:830;line-height:1;display:inline-flex}.access-badge.green,.network-chip.green{color:var(--green);background:#22c55e17;border-color:#22c55e2b}.access-badge.orange,.network-chip.orange{color:var(--orange);background:#f59e0b17;border-color:#f59e0b2e}.access-badge.red,.network-chip.red{color:var(--red);background:#ef444417;border-color:#ef44442e}.access-badge.blue,.network-chip.blue{color:var(--blue);background:#3b82f617;border-color:#3b82f62e}.access-badge.slate,.network-chip.slate{color:var(--text-muted);background:#64748b17;border-color:#64748b29}.network-list{gap:10px;display:grid}.network-list.compact-list{margin-top:2px}.network-list-item{background:#ffffffd1;border:1px solid #94a3b829;border-radius:13px;gap:8px;min-width:0;padding:12px;display:grid}.network-list-item p{color:var(--text-soft);overflow-wrap:anywhere;margin:0;font-size:12px;line-height:1.48}.network-dual{grid-template-columns:1fr;gap:10px;display:grid}.network-three-up{grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;display:grid}.network-metric,.network-block{background:#fff;border:1px solid #94a3b82e;border-radius:13px;min-width:0;padding:12px}.network-environment-panel{padding:20px}.dns-chip-row{flex-wrap:wrap;gap:8px;display:flex}.dns-chip{border:1px solid #0000;border-radius:999px;align-items:center;min-height:27px;padding:0 10px;font-size:11px;font-weight:800;display:inline-flex}.dns-chip.green{color:var(--green);background:#22c55e14;border-color:#22c55e29}.dns-chip.orange{color:var(--orange);background:#f59e0b14;border-color:#f59e0b29}.network-empty-state{min-height:132px;color:var(--text-muted);text-align:center;background:#f8fafcb8;border:1px dashed #94a3b847;border-radius:14px;place-items:center;padding:18px;font-size:13px;font-weight:760;display:grid}.network-page .section-head.compact h3{font-size:18px}.network-page .section-head.compact{margin-bottom:0}@media (width<=1180px){.network-command-center,.signal-grid,.network-workspace{grid-template-columns:1fr}.platform-summary-strip{justify-content:flex-start;margin-left:0}}@media (width<=860px){.network-command-center{padding:18px}.network-command-copy h2{font-size:25px}.platform-access-header{display:none}.platform-access-row{grid-template-columns:1fr;align-items:start;row-gap:10px;padding:14px 15px 14px 18px}.network-dual,.network-three-up{grid-template-columns:1fr}}.table-scroller{border:1px solid var(--line);background:#fff;border-radius:14px;overflow-x:auto}table{border-collapse:collapse;width:100%;min-width:720px}th,td{border-bottom:1px solid var(--line);text-align:left;vertical-align:top;color:var(--text-soft);padding:13px 12px;font-size:13px}th{color:var(--text-muted);background:#f8fafc;font-size:12px;font-weight:800}tbody tr:last-child td{border-bottom:0}td code{color:var(--text)}.method-pill,.status-pill{white-space:nowrap;border-radius:999px;justify-content:center;align-items:center;min-height:24px;padding:0 8px;font-size:11px;font-weight:800;display:inline-flex}.method-pill{color:#334155;background:#f1f5f9}.method-post{color:#4f46e5;background:#635bff1a}.method-get,.status-pill.is-ok{color:#047857;background:#22c55e1f}.status-pill.is-error{color:#dc2626;background:#ef44441f}.table-footer{color:var(--text-muted);margin-top:10px;font-size:12px}.log-toolbar{flex-wrap:wrap;gap:10px;margin-bottom:16px;display:flex}.log-search{flex:280px}.filter-chip{border:1px solid var(--line);background:#fff;border-radius:12px;align-items:center;gap:8px;min-height:40px;padding:0 12px;display:inline-flex}.filter-chip select{color:var(--text-soft);background:0 0;border:0;outline:none;font-size:13px;font-weight:700}.table-scroller tbody tr{cursor:pointer}.table-scroller tbody tr.is-selected{background:#635bff0a}.log-detail-panel{border:1px solid var(--line);background:#fffffff0;border-radius:16px;margin-top:16px;padding:18px 20px}.log-detail-head{justify-content:space-between;align-items:flex-start;gap:12px;margin-bottom:14px;display:flex}.log-detail-head h3{margin:0}.log-detail-head p{color:var(--text-muted);margin:6px 0 0;font-size:13px}.log-detail-grid{grid-template-columns:minmax(220px,.7fr) minmax(0,1.3fr);gap:14px;display:grid}.log-detail-meta{gap:10px;display:grid}.log-detail-meta div{gap:4px;display:grid}.log-detail-meta span{color:var(--text-muted);font-size:12px}.log-detail-meta strong{color:var(--text-soft);font-size:13px}.log-detail-pre{min-height:220px;max-height:320px}.switch-line{color:var(--text-soft);align-items:flex-start;gap:10px;font-size:13px;font-weight:700;line-height:1.5;display:flex}.settings-page{gap:18px;display:grid}.settings-page-head{justify-content:space-between;align-items:flex-start;gap:16px;display:flex}.settings-page-kicker{color:var(--brand);align-items:center;gap:6px;font-size:12px;font-weight:850;display:inline-flex}.settings-page-head h2{margin:8px 0 0;font-size:28px;line-height:1.15}.settings-page-head p{color:var(--text-muted);margin:8px 0 0;font-size:14px;line-height:1.6}.settings-page-actions{flex-wrap:wrap;justify-content:flex-end;gap:10px;display:flex}.codex-provider-button{border-color:#2563eb3d;transition:background .16s,border-color .16s,color .16s,box-shadow .16s}.codex-provider-button.is-inactive{color:#1d4ed8;background:linear-gradient(135deg,#eff6ff,#dbeafe);border-color:#2563eb52;box-shadow:inset 0 1px #fffc,0 6px 14px #2563eb14}.codex-provider-button.is-inactive:hover{background:linear-gradient(135deg,#dbeafe,#bfdbfe);border-color:#2563eb6b}.codex-provider-button.is-active{color:#b91c1c;background:linear-gradient(135deg,#fff1f2,#fee2e2);border-color:#ef444447;box-shadow:inset 0 1px #fffc,0 6px 14px #ef444414}.codex-provider-button.is-active:hover{background:linear-gradient(135deg,#ffe4e6,#fecaca);border-color:#ef444461}.codex-provider-button.is-busy{color:var(--text-muted);border-color:var(--line);background:#f8fafc}.settings-page-footer-actions{justify-content:flex-end;margin-top:2px}.settings-grid{grid-template-columns:repeat(4,minmax(220px,1fr));gap:14px;display:grid}.settings-section{border:1px solid var(--line);box-shadow:var(--shadow-sm);background:#fffffff0;border-radius:16px;gap:13px;padding:18px 20px;display:grid}.settings-section h4{margin:0;font-size:16px}.codex-provider-section{grid-column:1/-1;gap:16px}.codex-provider-head{justify-content:space-between;align-items:flex-start;gap:16px;display:flex}.codex-provider-head .hint{max-width:720px;margin:8px 0 0}.codex-provider-controls{grid-template-columns:284px minmax(320px,1fr) auto;align-items:end;gap:14px;display:grid}.codex-mode-toggle{border:1px solid var(--line);background:#f1f5f9;border-radius:12px;grid-template-columns:1fr 1fr;gap:6px;min-height:42px;padding:5px;display:grid}.codex-mode-option{min-width:0;color:var(--text-soft);font:inherit;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:9px;justify-content:center;align-items:center;gap:7px;font-size:13px;font-weight:850;display:inline-flex}.codex-mode-option.is-active{color:#1d4ed8;box-shadow:var(--shadow-sm);background:#fff;border-color:#bfdbfe}.codex-url-field{min-width:0}.codex-url-input{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:13px}.codex-url-input[readonly]{color:var(--text-soft);background:#f8fafc}.codex-provider-actions{flex-wrap:wrap;justify-content:flex-end;gap:10px;display:flex}.codex-provider-meta-strip{border:1px solid var(--line);background:#f8fafc;border-radius:12px;grid-template-columns:minmax(220px,.8fr) minmax(280px,1.1fr) minmax(260px,1fr);display:grid;overflow:hidden}.codex-provider-meta-strip>div{border-right:1px solid var(--line);gap:8px;min-width:0;padding:14px 16px;display:grid}.codex-provider-meta-strip>div:last-child{border-right:0}.codex-provider-meta-strip span{color:var(--text-muted);font-size:12px;font-weight:850}.codex-provider-meta-strip code,.codex-provider-section .hint code{color:var(--text);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.codex-provider-meta-strip strong{color:#9a3412;font-size:12px;line-height:1.45}.codex-provider-meta-strip .is-warning{background:#fff7ed}.auto-switch-exclusion-section{grid-column:1/-1}.auto-switch-exclusion-head{justify-content:space-between;align-items:flex-start;gap:16px;display:flex}.auto-switch-exclusion-head .hint{max-width:720px;margin:8px 0 0}.auto-switch-counts{flex-wrap:wrap;justify-content:flex-end;gap:8px;display:flex}.count-pill,.auto-switch-state-pill{border:1px solid var(--line);white-space:nowrap;border-radius:999px;justify-content:center;align-items:center;min-height:28px;padding:0 12px;font-size:12px;font-weight:800;display:inline-flex}.count-pill.is-included,.auto-switch-state-pill.is-included{color:#047857;background:#ecfdf5;border-color:#bbf7d0}.count-pill.is-excluded,.auto-switch-state-pill.is-excluded{color:#c2410c;background:#fff7ed;border-color:#fed7aa}.auto-switch-search{border:1px solid var(--line);height:42px;color:var(--text-muted);background:#f8fafc;border-radius:10px;align-items:center;gap:10px;padding:0 13px;display:flex}.auto-switch-search input{width:100%;min-width:0;color:var(--text);font:inherit;background:0 0;border:0;outline:0}.auto-switch-profile-list{gap:10px;max-height:342px;padding-right:4px;display:grid;overflow:auto}.auto-switch-profile-row{border:1px solid var(--line);cursor:pointer;background:#fbfcff;border-radius:12px;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:14px;min-height:70px;padding:14px 16px;display:grid}.auto-switch-profile-row.is-excluded{background:#fff7ed;border-color:#fed7aa}.auto-switch-profile-main{gap:5px;min-width:0;display:grid}.auto-switch-profile-main strong,.auto-switch-profile-main span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.auto-switch-profile-main strong{color:var(--text);font-size:14px}.auto-switch-profile-main span{color:var(--text-muted);font-size:12px;line-height:1.4}.auto-switch-empty{border:1px dashed var(--line-strong);min-height:90px;color:var(--text-muted);background:#f8fafc;border-radius:12px;place-items:center;font-size:13px;display:grid}@media (width<=860px){.codex-provider-head,.auto-switch-exclusion-head,.auto-switch-profile-row{grid-template-columns:1fr}.codex-provider-head,.auto-switch-exclusion-head{display:grid}.codex-provider-controls,.codex-provider-meta-strip{grid-template-columns:1fr}.codex-provider-actions{justify-content:flex-start}.codex-provider-meta-strip>div{border-right:0;border-bottom:1px solid var(--line)}.codex-provider-meta-strip>div:last-child{border-bottom:0}.auto-switch-counts{justify-content:flex-start}.auto-switch-profile-row{align-items:start}.auto-switch-state-pill{justify-self:flex-start}}@media (width<=1380px){.main-grid{grid-template-columns:1fr}.right-column{grid-template-columns:minmax(0,1fr)}.tester-card{order:-1}}@media (width<=1120px){.app-shell{grid-template-columns:1fr;width:calc(100vw - 20px);padding:10px}.sidebar{max-height:none;position:relative;top:0}.nav{grid-template-columns:repeat(6,minmax(max-content,1fr));padding-bottom:2px;overflow-x:auto}.nav-item{justify-content:center}.sidebar-status{display:none}.topbar{grid-template-columns:1fr}.top-actions{justify-content:flex-start}}@media (width<=900px){.app-shell{gap:12px;padding:0}.sidebar,.card,.trend-card,.log-table-wrap,.update-panel{border-left:0;border-right:0;border-radius:0}.sidebar{padding:16px 12px}.brand span,.sidebar-status{display:none}.nav{grid-template-columns:none;grid-auto-columns:max-content;grid-auto-flow:column}.nav-item{width:auto}.main{gap:12px}.topbar{padding:0 12px}.page-title h1{font-size:25px}.top-actions{flex-wrap:nowrap;padding-bottom:4px;overflow-x:auto}.summary-grid{grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;padding:0 12px}.summary-card{min-height:82px;padding:14px}.summary-card strong{font-size:19px}.main-grid{gap:12px}.section-head,.update-panel,.settings-drawer-footer{display:grid}.update-panel{grid-template-columns:auto minmax(0,1fr);align-items:start}.update-actions{grid-column:1/-1;grid-template-columns:1fr;justify-content:stretch;display:grid}.update-panel .btn-primary,.update-panel .btn-secondary{justify-content:center;width:100%}.section-actions,.button-row,.example-row{justify-content:flex-start}.filter-row{display:flex}.filter-row .control{flex:100%;min-width:0}.account-grid,.account-grid.profile-count-1,.account-grid.profile-count-2,.account-grid.profile-count-3,.account-grid.profile-count-many,.meta-grid{grid-template-columns:1fr}.account-card{border-radius:14px;padding:16px}.account-head{flex-direction:column;align-items:stretch}.account-select{width:max-content;margin-top:0}.compact-grid{grid-template-columns:1fr}.account-actions{display:flex}.tester-textarea{min-height:150px}.pre{max-height:320px}.modal-backdrop,.drawer-backdrop{padding:0}.modal-card,.settings-drawer{border-radius:0;width:100%;height:100%;max-height:none}.modal-body,.settings-drawer-body,.settings-drawer-head,.settings-drawer-footer{padding:16px}}@media (width<=460px){.summary-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.btn-primary,.btn-secondary,.btn-danger{min-height:40px;padding:0 12px}.card,.trend-card,.log-table-wrap{padding:16px 12px}}@media (width<=1120px){body{min-width:0}.app-shell{grid-template-columns:1fr;gap:14px;width:calc(100vw - 24px);padding:0}.sidebar{border-radius:24px;gap:14px;max-height:none;padding:22px 18px;position:relative;top:0}.brand span,.sidebar-status{display:none}.nav{grid-template-columns:repeat(5,minmax(max-content,1fr));grid-auto-columns:max-content;grid-auto-flow:column;padding-bottom:2px;overflow-x:auto}.nav-item{justify-content:center;width:auto}.topbar{grid-template-columns:1fr;padding:0}.page-title p{max-width:680px}.top-actions{flex-wrap:wrap;justify-content:flex-start;overflow:visible}.summary-grid{grid-template-columns:repeat(2,minmax(0,1fr));padding:0}.overview-grid,.tester-route-grid,.main-grid{grid-template-columns:1fr}.sidebar,.card,.trend-card,.log-table-wrap,.update-panel{border-left:1px solid var(--line);border-right:1px solid var(--line);border-radius:20px}.launch-page{grid-template-columns:1fr}.launch-visual{min-height:420px}.account-grid.profile-count-2{grid-template-columns:repeat(2,minmax(340px,1fr))}.account-grid.profile-count-3{grid-template-columns:repeat(3,minmax(320px,1fr))}.account-grid.profile-count-many{grid-template-columns:repeat(auto-fit,minmax(340px,1fr))}.meta-grid,.compact-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./jsx-runtime-DqpGtLhh.js";import{t}from"./activity-D21-Xrc4.js";import{t as n}from"./server-BrjJPb9D.js";import{t as r}from"./zap-B4_oDbCp.js";import{m as i}from"./profiles-DMOjJORP.js";import{S as a,h as o,v as s,y as c}from"./index
|
|
1
|
+
import{t as e}from"./jsx-runtime-DqpGtLhh.js";import{t}from"./activity-D21-Xrc4.js";import{t as n}from"./server-BrjJPb9D.js";import{t as r}from"./zap-B4_oDbCp.js";import{m as i}from"./profiles-DMOjJORP.js";import{S as a,h as o,v as s,y as c}from"./index--rNjdmzf.js";import{t as l}from"./InfoRow-0ULI9iI3.js";var u=e(),d=`https://github.com/fchangjun/AI-Zero-Token/releases`;function f(e){return(0,u.jsxs)(`section`,{className:`launch-page`,children:[(0,u.jsxs)(`div`,{className:`launch-copy`,children:[(0,u.jsxs)(`div`,{className:`launch-identity`,children:[(0,u.jsx)(`div`,{className:`launch-app-icon`,children:(0,u.jsx)(`img`,{src:a,alt:``})}),(0,u.jsxs)(`div`,{children:[(0,u.jsx)(`span`,{className:`badge brand`,children:`Desktop Gateway`}),(0,u.jsx)(`h2`,{children:`AI Zero Token`}),(0,u.jsx)(`p`,{children:`本地 OpenAI 兼容网关、账号池和接口测试工作台。`})]})]}),(0,u.jsxs)(`div`,{className:`launch-metrics`,children:[(0,u.jsxs)(`div`,{children:[(0,u.jsx)(o,{size:18}),(0,u.jsx)(`span`,{children:`账号池`}),(0,u.jsx)(`strong`,{children:e.config?.status.profileCount||0})]}),(0,u.jsxs)(`div`,{children:[(0,u.jsx)(n,{size:18}),(0,u.jsx)(`span`,{children:`网关`}),(0,u.jsx)(`strong`,{children:e.config?.status.loggedIn?`运行中`:`待登录`})]}),(0,u.jsxs)(`div`,{children:[(0,u.jsx)(t,{size:18}),(0,u.jsx)(`span`,{children:`模型`}),(0,u.jsx)(`strong`,{children:e.config?.settings.defaultModel||`-`})]})]}),(0,u.jsxs)(`div`,{className:`launch-actions`,children:[(0,u.jsxs)(`button`,{className:`btn-secondary`,type:`button`,onClick:()=>e.onRoute(`accounts`),children:[(0,u.jsx)(o,{size:16}),`管理账号`]}),(0,u.jsxs)(`button`,{className:`btn-secondary`,type:`button`,onClick:()=>e.onRoute(`tester`),children:[(0,u.jsx)(r,{size:16}),`测试接口`]}),(0,u.jsxs)(`a`,{className:`btn-secondary`,href:d,target:`_blank`,rel:`noreferrer`,children:[(0,u.jsx)(c,{size:16}),`桌面版下载`]}),(0,u.jsxs)(`a`,{className:`btn-secondary`,href:d,target:`_blank`,rel:`noreferrer`,title:`桌面版安装包发布后会放在这里`,children:[(0,u.jsx)(s,{size:16}),`发布页`]})]}),(0,u.jsx)(`p`,{className:`launch-download-note`,children:`当前还没有公开安装包时,这里会先打开 GitHub Releases 发布页。`}),(0,u.jsxs)(`div`,{className:`launch-status`,children:[(0,u.jsx)(l,{label:`当前账号`,value:i(e.activeProfile,e.showEmails)}),(0,u.jsx)(l,{label:`服务状态`,value:e.config?.status.loggedIn?`已登录并运行`:`等待登录`}),(0,u.jsx)(l,{label:`Base URL`,value:e.config?.baseUrl||`http://127.0.0.1:8787/v1`,code:!0}),(0,u.jsx)(l,{label:`同步消息`,value:e.status})]})]}),(0,u.jsx)(`div`,{className:`launch-visual`,children:(0,u.jsxs)(`div`,{className:`launch-visual-stage`,children:[(0,u.jsx)(`img`,{className:`launch-visual-mark`,src:a,alt:`AI Zero Token 图标`}),(0,u.jsx)(`img`,{className:`launch-visual-dashboard`,src:e.visualSrc||`data:image/svg+xml,%3csvg%20width='920'%20height='600'%20viewBox='0%200%20920%20600'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3crect%20width='920'%20height='600'%20rx='36'%20fill='%23F8FAFC'/%3e%3crect%20x='56'%20y='54'%20width='808'%20height='492'%20rx='24'%20fill='%23FFFFFF'%20stroke='%23D8E0EA'/%3e%3crect%20x='56'%20y='54'%20width='190'%20height='492'%20rx='24'%20fill='%23111827'/%3e%3cpath%20d='M246%2054h594c13.255%200%2024%2010.745%2024%2024v40H246V54Z'%20fill='%23F8FAFC'/%3e%3ccircle%20cx='88'%20cy='86'%20r='7'%20fill='%23EF4444'/%3e%3ccircle%20cx='112'%20cy='86'%20r='7'%20fill='%23F59E0B'/%3e%3ccircle%20cx='136'%20cy='86'%20r='7'%20fill='%2322C55E'/%3e%3crect%20x='86'%20y='148'%20width='108'%20height='14'%20rx='7'%20fill='%23E5E7EB'%20fill-opacity='.75'/%3e%3crect%20x='86'%20y='194'%20width='128'%20height='34'%20rx='10'%20fill='%232563EB'/%3e%3crect%20x='86'%20y='244'%20width='112'%20height='34'%20rx='10'%20fill='%231F2937'/%3e%3crect%20x='86'%20y='294'%20width='124'%20height='34'%20rx='10'%20fill='%231F2937'/%3e%3crect%20x='86'%20y='344'%20width='98'%20height='34'%20rx='10'%20fill='%231F2937'/%3e%3crect%20x='278'%20y='150'%20width='250'%20height='96'%20rx='18'%20fill='%23EFF6FF'%20stroke='%23BFDBFE'/%3e%3crect%20x='558'%20y='150'%20width='250'%20height='96'%20rx='18'%20fill='%23F0FDF4'%20stroke='%23BBF7D0'/%3e%3crect%20x='278'%20y='280'%20width='530'%20height='210'%20rx='18'%20fill='%23FFFFFF'%20stroke='%23D8E0EA'/%3e%3cpath%20d='M318%20430c43-68%2089-70%20137-8%2039%2049%2081%2037%20126-36%2038-62%2081-79%20129-21'%20stroke='%232563EB'%20stroke-width='8'%20stroke-linecap='round'/%3e%3cpath%20d='M318%20386c42-35%2083-33%20123%206%2045%2045%2092%2040%20141-16%2038-43%2080-49%20126-18'%20stroke='%2322C55E'%20stroke-width='8'%20stroke-linecap='round'/%3e%3crect%20x='318'%20y='316'%20width='118'%20height='13'%20rx='6.5'%20fill='%23111827'/%3e%3crect%20x='318'%20y='342'%20width='194'%20height='10'%20rx='5'%20fill='%23CBD5E1'/%3e%3crect%20x='596'%20y='182'%20width='80'%20height='12'%20rx='6'%20fill='%23111827'/%3e%3crect%20x='596'%20y='207'%20width='150'%20height='10'%20rx='5'%20fill='%2386EFAC'/%3e%3crect%20x='316'%20y='182'%20width='80'%20height='12'%20rx='6'%20fill='%23111827'/%3e%3crect%20x='316'%20y='207'%20width='150'%20height='10'%20rx='5'%20fill='%2393C5FD'/%3e%3ccircle%20cx='776'%20cy='198'%20r='16'%20fill='%2322C55E'/%3e%3cpath%20d='M768%20198l6%206%2011-13'%20stroke='%23FFFFFF'%20stroke-width='5'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M478%20186l15%2020-15%2020-15-20%2015-20Z'%20fill='%232563EB'/%3e%3c/svg%3e`,alt:`AI Zero Token 桌面端启动页配图`})]})})]})}export{f as LaunchPage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,n as t,r as n,t as r}from"./jsx-runtime-DqpGtLhh.js";import{t as i}from"./search-B2hz41D3.js";import{T as a,w as o,x as s}from"./profiles-DMOjJORP.js";import{b as c,n as l}from"./index
|
|
1
|
+
import{a as e,n as t,r as n,t as r}from"./jsx-runtime-DqpGtLhh.js";import{t as i}from"./search-B2hz41D3.js";import{T as a,w as o,x as s}from"./profiles-DMOjJORP.js";import{b as c,n as l}from"./index--rNjdmzf.js";var u=t(`funnel`,[[`path`,{d:`M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z`,key:`sc7q7i`}]]),d=e(n(),1),f=r();function p(e){let[t,n]=(0,d.useState)(``),[r,p]=(0,d.useState)(`all`),[m,h]=(0,d.useState)(`all`),[g,_]=(0,d.useState)(`all`),[v,y]=(0,d.useState)(null);(0,d.useEffect)(()=>{if(e.logs.length===0){y(null);return}(!v||!e.logs.some(e=>e.id===v))&&y(e.logs[0].id)},[e.logs,v]);let b=(0,d.useMemo)(()=>Array.from(new Set(e.logs.map(e=>e.source||`管理页`))),[e.logs]),x=(0,d.useMemo)(()=>Array.from(new Set(e.logs.map(e=>e.method))),[e.logs]),S=(0,d.useMemo)(()=>{let n=t.trim().toLowerCase();return e.logs.filter(e=>{let t=[e.time,e.method,e.endpoint,e.account,e.model,e.statusCode,e.durationMs,e.source].join(` `).toLowerCase();return!(n&&!t.includes(n)||r!==`all`&&e.method!==r||m!==`all`&&(e.source||`管理页`)!==m||g===`ok`&&e.statusCode>=400||g===`error`&&e.statusCode<400)})},[r,e.logs,t,m,g]),C=S.find(e=>e.id===v)||S[0]||null;function w(){C&&l(o(C)).then(e=>{}).catch(()=>void 0)}return(0,f.jsxs)(`section`,{className:`log-table-wrap`,id:`logs`,children:[(0,f.jsx)(`div`,{className:`section-head compact`,children:(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`h2`,{children:`请求日志`}),(0,f.jsx)(`p`,{children:`记录网关最近收到的 API 请求,详情为安全摘要。`})]})}),(0,f.jsxs)(`div`,{className:`log-toolbar`,children:[(0,f.jsxs)(`label`,{className:`search-box log-search`,children:[(0,f.jsx)(i,{size:16}),(0,f.jsx)(`input`,{value:t,onChange:e=>n(e.target.value),placeholder:`搜索时间、接口、账号、模型或状态`})]}),(0,f.jsxs)(`label`,{className:`filter-chip`,children:[(0,f.jsx)(u,{size:14}),(0,f.jsxs)(`select`,{value:r,onChange:e=>p(e.target.value),children:[(0,f.jsx)(`option`,{value:`all`,children:`全部方法`}),x.map(e=>(0,f.jsx)(`option`,{value:e,children:e},e))]})]}),(0,f.jsx)(`label`,{className:`filter-chip`,children:(0,f.jsxs)(`select`,{value:m,onChange:e=>h(e.target.value),children:[(0,f.jsx)(`option`,{value:`all`,children:`全部来源`}),b.map(e=>(0,f.jsx)(`option`,{value:e,children:e},e))]})}),(0,f.jsx)(`label`,{className:`filter-chip`,children:(0,f.jsxs)(`select`,{value:g,onChange:e=>_(e.target.value),children:[(0,f.jsx)(`option`,{value:`all`,children:`全部状态`}),(0,f.jsx)(`option`,{value:`ok`,children:`成功`}),(0,f.jsx)(`option`,{value:`error`,children:`失败`})]})})]}),(0,f.jsx)(`div`,{className:`table-scroller`,children:(0,f.jsxs)(`table`,{children:[(0,f.jsx)(`thead`,{children:(0,f.jsxs)(`tr`,{children:[(0,f.jsx)(`th`,{children:`时间`}),(0,f.jsx)(`th`,{children:`方法`}),(0,f.jsx)(`th`,{children:`接口`}),(0,f.jsx)(`th`,{children:`账号`}),(0,f.jsx)(`th`,{children:`模型`}),(0,f.jsx)(`th`,{children:`状态`}),(0,f.jsx)(`th`,{children:`耗时`}),(0,f.jsx)(`th`,{children:`来源`})]})}),(0,f.jsx)(`tbody`,{children:S.length===0?(0,f.jsx)(`tr`,{children:(0,f.jsx)(`td`,{colSpan:8,children:`最近 API 请求会在这里显示。`})}):S.map(e=>(0,f.jsxs)(`tr`,{className:e.id===C?.id?`is-selected`:``,onClick:()=>y(e.id),children:[(0,f.jsx)(`td`,{children:a(e.time)}),(0,f.jsx)(`td`,{children:(0,f.jsx)(`span`,{className:`method-pill method-${e.method.toLowerCase()}`,children:e.method})}),(0,f.jsx)(`td`,{children:(0,f.jsx)(`code`,{children:e.endpoint})}),(0,f.jsx)(`td`,{children:e.account}),(0,f.jsx)(`td`,{children:e.model}),(0,f.jsx)(`td`,{children:(0,f.jsx)(`span`,{className:`status-pill ${e.statusCode>=400?`is-error`:`is-ok`}`,children:e.statusCode})}),(0,f.jsx)(`td`,{children:s(e.durationMs)}),(0,f.jsx)(`td`,{children:e.source||`管理页`})]},e.id))})]})}),(0,f.jsxs)(`div`,{className:`table-footer`,children:[`当前展示 `,S.length,` 条请求记录,最近总计 `,e.logs.length,` 条。`]}),C&&(0,f.jsxs)(`div`,{className:`log-detail-panel`,children:[(0,f.jsxs)(`div`,{className:`log-detail-head`,children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`h3`,{children:`日志详情`}),(0,f.jsxs)(`p`,{children:[a(C.time),` · `,C.method,` `,C.endpoint]})]}),(0,f.jsxs)(`button`,{className:`btn-secondary`,type:`button`,onClick:w,children:[(0,f.jsx)(c,{size:16}),`复制详情`]})]}),(0,f.jsxs)(`div`,{className:`log-detail-grid`,children:[(0,f.jsxs)(`div`,{className:`log-detail-meta`,children:[(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`span`,{children:`账号`}),(0,f.jsx)(`strong`,{children:C.account})]}),(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`span`,{children:`模型`}),(0,f.jsx)(`strong`,{children:C.model})]}),(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`span`,{children:`状态`}),(0,f.jsx)(`strong`,{children:C.statusCode})]}),(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`span`,{children:`耗时`}),(0,f.jsx)(`strong`,{children:s(C.durationMs)})]}),(0,f.jsxs)(`div`,{children:[(0,f.jsx)(`span`,{children:`来源`}),(0,f.jsx)(`strong`,{children:C.source||`管理页`})]})]}),(0,f.jsx)(`pre`,{className:`pre log-detail-pre`,children:o(C)})]})]})]})}function m(e){return(0,f.jsx)(p,{logs:e.logs})}export{m as LogsPage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,n as t,r as n,t as r}from"./jsx-runtime-DqpGtLhh.js";import{t as i}from"./activity-D21-Xrc4.js";import{t as a}from"./circle-check-ZYtn9GqY.js";import{t as o}from"./clock-3-BzDANsVk.js";import{t as s}from"./refresh-cw-CAAH2rqe.js";import{t as c}from"./server-BrjJPb9D.js";import{g as l,m as u,p as ee}from"./index-rgcJgVAu.js";var d=t(`circle-x`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m15 9-6 6`,key:`1uzhvr`}],[`path`,{d:`m9 9 6 6`,key:`z0biqf`}]]),f=t(`map-pin`,[[`path`,{d:`M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0`,key:`1r0f0z`}],[`circle`,{cx:`12`,cy:`10`,r:`3`,key:`ilqhr7`}]]),p=t(`triangle-alert`,[[`path`,{d:`m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3`,key:`wmoenq`}],[`path`,{d:`M12 9v4`,key:`juzpu7`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}]]),m=e(n(),1),h=`data:image/svg+xml,%3csvg%20role='img'%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3e%3ctitle%3eClaude%3c/title%3e%3cpath%20d='m4.7144%2015.9555%204.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608%201.5179.1032%202.2767.1578%201.6514.0972%202.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973%209.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686%201.9064%201.4754%202.4893%201.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335%206.6997%200l.9957.1336.419.3642.6192%201.4147%201.0018%202.2282%201.5543%203.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853%201.8517-.5586%202.9021-.3643%201.9429h.2125l.2429-.2429.9835-1.3053%201.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759%201.1293-.34%201.1657-1.0625%201.3478-.8804%201.1414-1.2628%201.7-.7893%201.36.0729.1093.1882-.0183%202.8535-.607%201.5421-.2794%201.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607%201.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929%201.0686%202.0035%201.8092%202.5075%202.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496%202.3436%203.5214.1214%201.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38%2017.959l-1.1414-1.9428-.1397.079-.674%207.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328%201.9672-2.1796%202.9446-1.7243%201.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889%202.386-3.0357%201.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385%204.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429%201.9064-1.3114Z'/%3e%3c/svg%3e`,g=`data:image/svg+xml,%3csvg%20role='img'%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3e%3ctitle%3eOpenAI%3c/title%3e%3cpath%20d='M22.2819%209.8211a5.9847%205.9847%200%200%200-.5157-4.9108%206.0462%206.0462%200%200%200-6.5098-2.9A6.0651%206.0651%200%200%200%204.9807%204.1818a5.9847%205.9847%200%200%200-3.9977%202.9%206.0462%206.0462%200%200%200%20.7427%207.0966%205.98%205.98%200%200%200%20.511%204.9107%206.051%206.051%200%200%200%206.5146%202.9001A5.9847%205.9847%200%200%200%2013.2599%2024a6.0557%206.0557%200%200%200%205.7718-4.2058%205.9894%205.9894%200%200%200%203.9977-2.9001%206.0557%206.0557%200%200%200-.7475-7.0729zm-9.022%2012.6081a4.4755%204.4755%200%200%201-2.8764-1.0408l.1419-.0804%204.7783-2.7582a.7948.7948%200%200%200%20.3927-.6813v-6.7369l2.02%201.1686a.071.071%200%200%201%20.038.052v5.5826a4.504%204.504%200%200%201-4.4945%204.4944zm-9.6607-4.1254a4.4708%204.4708%200%200%201-.5346-3.0137l.142.0852%204.783%202.7582a.7712.7712%200%200%200%20.7806%200l5.8428-3.3685v2.3324a.0804.0804%200%200%201-.0332.0615L9.74%2019.9502a4.4992%204.4992%200%200%201-6.1408-1.6464zM2.3408%207.8956a4.485%204.485%200%200%201%202.3655-1.9728V11.6a.7664.7664%200%200%200%20.3879.6765l5.8144%203.3543-2.0201%201.1685a.0757.0757%200%200%201-.071%200l-4.8303-2.7865A4.504%204.504%200%200%201%202.3408%207.872zm16.5963%203.8558L13.1038%208.364%2015.1192%207.2a.0757.0757%200%200%201%20.071%200l4.8303%202.7913a4.4944%204.4944%200%200%201-.6765%208.1042v-5.6772a.79.79%200%200%200-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759%200%200%200-.7854%200L9.409%209.2297V6.8974a.0662.0662%200%200%201%20.0284-.0615l4.8303-2.7866a4.4992%204.4992%200%200%201%206.6802%204.66zM8.3065%2012.863l-2.02-1.1638a.0804.0804%200%200%201-.038-.0567V6.0742a4.4992%204.4992%200%200%201%207.3757-3.4537l-.142.0805L8.704%205.459a.7948.7948%200%200%200-.3927.6813zm1.0976-2.3654l2.602-1.4998%202.6069%201.4998v2.9994l-2.5974%201.4997-2.6067-1.4997Z'/%3e%3c/svg%3e`,_=`data:image/svg+xml,%3csvg%20role='img'%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3e%3ctitle%3eGoogle%3c/title%3e%3cpath%20d='M12.48%2010.92v3.28h7.84c-.24%201.84-.853%203.187-1.787%204.133-1.147%201.147-2.933%202.4-6.053%202.4-4.827%200-8.6-3.893-8.6-8.72s3.773-8.72%208.6-8.72c2.6%200%204.507%201.027%205.907%202.347l2.307-2.307C18.747%201.44%2016.133%200%2012.48%200%205.867%200%20.307%205.387.307%2012s5.56%2012%2012.173%2012c3.573%200%206.267-1.173%208.373-3.36%202.16-2.16%202.84-5.213%202.84-7.667%200-.76-.053-1.467-.173-2.053H12.48z'/%3e%3c/svg%3e`,v=`data:image/svg+xml,%3csvg%20role='img'%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3e%3ctitle%3eX%3c/title%3e%3cpath%20d='M14.234%2010.162%2022.977%200h-2.072l-7.591%208.824L7.251%200H.258l9.168%2013.343L.258%2024H2.33l8.016-9.318L16.749%2024h6.993zm-2.837%203.299-.929-1.329L3.076%201.56h3.182l5.965%208.532.929%201.329%207.754%2011.09h-3.182z'/%3e%3c/svg%3e`,y=`data:image/svg+xml,%3csvg%20role='img'%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3e%3ctitle%3eYouTube%3c/title%3e%3cpath%20d='M23.498%206.186a3.016%203.016%200%200%200-2.122-2.136C19.505%203.545%2012%203.545%2012%203.545s-7.505%200-9.377.505A3.017%203.017%200%200%200%20.502%206.186C0%208.07%200%2012%200%2012s0%203.93.502%205.814a3.016%203.016%200%200%200%202.122%202.136c1.871.505%209.376.505%209.376.505s7.505%200%209.377-.505a3.015%203.015%200%200%200%202.122-2.136C24%2015.93%2024%2012%2024%2012s0-3.93-.502-5.814zM9.545%2015.568V8.432L15.818%2012l-6.273%203.568z'/%3e%3c/svg%3e`,b=r(),x={claude:h,chatgpt:g,google:_,x:v,youtube:y};function S(e){return`tone-${e}`}function C(e){try{return new URL(e).hostname.replace(/^www\./i,``)}catch{return e}}function w(e){return/^(10|127|169\.254|172\.(1[6-9]|2\d|3[0-1])|192\.168)\./.test(e)||/^100\.(6[4-9]|[7-9]\d|1\d\d|2[0-3]\d|24[0-7])\./.test(e)||/^198\.(18|19)\./.test(e)||/^192\.0\.2\./.test(e)||/^198\.51\.100\./.test(e)||/^203\.0\.113\./.test(e)||/^fc00:/i.test(e)||/^fd00:/i.test(e)||/^fe80:/i.test(e)||/^::1$/.test(e)}function T(e){let t=e.match(/Electron\/([\d.]+)/i);if(t)return`Electron ${t[1]}`;let n=e.match(/Chrome\/([\d.]+)/i);if(n&&/Safari\//i.test(e))return`Chrome ${n[1].split(`.`)[0]}`;let r=e.match(/Version\/([\d.]+).*Safari\//i);if(r&&!/Chrome\//i.test(e))return`Safari ${r[1].split(`.`)[0]}`;let i=e.match(/Firefox\/([\d.]+)/i);return i?`Firefox ${i[1].split(`.`)[0]}`:e.slice(0,40)}async function E(){if(typeof RTCPeerConnection>`u`)return{status:`不支持`,detail:`当前环境不支持 WebRTC。`,tone:`orange`,candidates:[]};let e=new Set,t=new RTCPeerConnection({iceServers:[]}),n=!1,r=new Promise(r=>{t.onicecandidate=t=>{t.candidate?.candidate&&e.add(t.candidate.candidate),t.candidate||(n=!0,r())}});try{t.createDataChannel(`probe`);let e=await t.createOffer();await t.setLocalDescription(e),await Promise.race([r,new Promise(e=>window.setTimeout(e,2400))])}catch{}finally{t.close()}let i=[...e],a=i.some(e=>/\btyp srflx\b/.test(e)||/\btyp relay\b/.test(e)),o=i.some(e=>/\btyp host\b/.test(e));return a?{status:`需要留意`,detail:`收集到 ${i.length} 个候选地址,其中包含公网回显特征。`,tone:`red`,candidates:i}:o||n?{status:`本地候选为主`,detail:`收集到 ${i.length} 个候选地址,主要来自本地网段。`,tone:`orange`,candidates:i}:{status:`暂未发现异常`,detail:`未收集到可识别的候选地址。`,tone:`green`,candidates:i}}async function D(){let[e]=await Promise.all([E()]);return{timezone:Intl.DateTimeFormat().resolvedOptions().timeZone||`-`,language:navigator.language||`-`,browser:T(navigator.userAgent||``),webrtc:e}}function O(e){return e.length===0?`slate`:e.some(e=>w(e))?`orange`:`green`}function k(e){return e.length===0?`未读取`:e.some(e=>w(e))?`内网 / 企业 DNS`:`公网 DNS`}function A(e){return{total:e.length,reachable:e.filter(e=>e.status===`可达`).length,limited:e.filter(e=>e.status===`受限`).length,unavailable:e.filter(e=>e.status===`不可用`).length}}function j(e,t){return!e||t.total===0?{label:`正在判断海外访问`,detail:`正在检查 ChatGPT、Claude、Google、YouTube 和 X 的连通性。`,tone:`blue`}:t.unavailable>0?{label:`海外访问受阻`,detail:`${t.unavailable} 个海外应用不可用,优先检查代理出口、DNS 或上游链路。`,tone:`red`}:t.limited>0?{label:`部分应用受限`,detail:`${t.reachable}/${t.total} 个海外应用可达,其余应用返回限制状态。`,tone:`orange`}:{label:`海外应用可访问`,detail:`${t.total} 个目标应用均已连通,当前出口可用于海外反向代理场景。`,tone:`green`}}function te(e,t){if(!e&&!t)return{label:`检测中`,detail:`正在采集公网出口、DNS、WebRTC、代理和平台可达性。`,tone:`blue`};if(!e||!t)return{label:`部分结果`,detail:`已有项目返回,剩余项目会保留失败原因,方便继续排查。`,tone:`orange`};let n=e.publicIpv4.available&&!!e.publicIpv4.ip,r=e.publicIpv6.available&&!!e.publicIpv6.ip,i=[e.platforms.some(e=>e.tone===`red`),t.webrtc.tone===`red`,!n&&!r],a=[e.platforms.some(e=>e.tone===`orange`),t.webrtc.tone===`orange`,O(e.dns.servers)!==`green`,!n,!e.publicIpv6.available];return i.some(Boolean)?{label:`建议先处理`,detail:`有明显阻塞项,先把出口或浏览器回显风险排掉。`,tone:`red`}:a.some(Boolean)?{label:`需要留意`,detail:`结果可用,但有几项信息值得再看一眼。`,tone:`orange`}:{label:`状态正常`,detail:`出口、DNS、WebRTC 和常用平台状态都比较稳定。`,tone:`green`}}function M(e){return(0,b.jsx)(`span`,{className:`network-chip ${e.tone}`,children:e.children})}function N(e){return(0,b.jsxs)(`span`,{className:`access-badge ${e.tone}`,children:[e.tone===`green`?(0,b.jsx)(a,{size:13}):e.tone===`red`?(0,b.jsx)(d,{size:13}):(0,b.jsx)(p,{size:13}),e.children]})}function P(e){let t=e.platformKey.toLowerCase(),n=x[t];return(0,b.jsx)(`span`,{className:`platform-icon ${e.tone} platform-${t}`,children:n?(0,b.jsx)(`img`,{alt:``,src:n}):e.icon})}function F(e){return(0,b.jsxs)(`div`,{className:`network-metric ${S(e.tone)}`,children:[(0,b.jsx)(`span`,{children:e.label}),(0,b.jsx)(`strong`,{children:e.value}),e.detail?(0,b.jsx)(`p`,{children:e.detail}):null]})}function I(e){let t=e.icon;return(0,b.jsxs)(`div`,{className:`signal-card ${S(e.tone)}`,children:[(0,b.jsx)(`div`,{className:`signal-card-icon`,children:(0,b.jsx)(t,{size:17})}),(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`span`,{children:e.label}),(0,b.jsx)(`strong`,{children:e.value}),(0,b.jsx)(`p`,{children:e.detail})]})]})}function L(e){return(0,b.jsxs)(`div`,{className:`network-block ${S(e.tone)}`,children:[(0,b.jsx)(`span`,{children:e.label}),(0,b.jsx)(`strong`,{children:e.value}),(0,b.jsx)(`p`,{children:e.detail})]})}function R(e){let{item:t}=e;return(0,b.jsxs)(`div`,{className:`platform-access-row ${t.tone}`,children:[(0,b.jsxs)(`div`,{className:`platform-access-main`,children:[(0,b.jsx)(P,{icon:t.label.slice(0,1),tone:t.tone,platformKey:t.key}),(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`strong`,{children:t.label}),(0,b.jsx)(`span`,{children:C(t.url)})]})]}),(0,b.jsxs)(`div`,{className:`platform-access-result`,children:[(0,b.jsx)(N,{tone:t.tone,children:t.status}),(0,b.jsx)(`span`,{children:t.httpStatus?`HTTP ${t.httpStatus}`:`连接结果`})]}),(0,b.jsxs)(`div`,{className:`platform-access-latency`,children:[(0,b.jsx)(`strong`,{children:z(t.elapsedMs)}),(0,b.jsx)(`span`,{children:t.httpStatus?`${t.httpStatus} 响应`:`等待结果`})]}),(0,b.jsx)(`div`,{className:`platform-access-detail`,children:(0,b.jsx)(`span`,{children:t.detail})})]})}function z(e){return typeof e==`number`?`${e} ms`:`-`}function B(e){return e instanceof DOMException&&e.name===`AbortError`?`网络探测超过 18 秒,已停止等待。`:e instanceof Error?e.message:String(e)}function V(){let[e,t]=(0,m.useState)(null),[n,r]=(0,m.useState)(null),[a,d]=(0,m.useState)(!0),[p,h]=(0,m.useState)(`正在采集真实网络状态...`),[g,_]=(0,m.useState)(null);async function v(){d(!0),_(null),h(`正在采集真实网络状态...`);let e=new AbortController,n=window.setTimeout(()=>e.abort(),18e3);try{let[n,i]=await Promise.allSettled([ee(`/_gateway/admin/network-detect`,{signal:e.signal}),D()]);n.status===`fulfilled`&&t(n.value),i.status===`fulfilled`&&r(i.value);let a=[];n.status===`rejected`&&a.push(`网络探测: ${B(n.reason)}`),i.status===`rejected`&&a.push(`本地环境: ${B(i.reason)}`);let o=n.status===`fulfilled`&&i.status===`fulfilled`?`检测完成。`:n.status===`fulfilled`||i.status===`fulfilled`?`部分结果已更新。`:`检测失败。`;_(a.length>0?a.join(` · `):null),h(o)}catch(e){_(B(e)),h(`检测失败。`)}finally{window.clearTimeout(n),d(!1)}}(0,m.useEffect)(()=>{v().catch(()=>void 0)},[]);let y=(0,m.useMemo)(()=>e?new Intl.DateTimeFormat(`zh-CN`,{hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1}).format(new Date(e.checkedAt)):`--:--:--`,[e]),x=te(e,n),S=O(e?.dns.servers||[]),C=k(e?.dns.servers||[]),T=e?.dns.servers?.length?e.dns.servers.slice(0,2).join(` / `):`-`,E=e?.dns.detail||`尚未检测到系统 DNS。`,N=A(e?.platforms||[]),P=e?e.publicIpv4.available&&e.publicIpv4.ip?`green`:`orange`:`blue`,V=e?e.publicIpv6.available?`green`:`orange`:`blue`,H=e?e.publicIpv4.available&&e.publicIpv4.ip?e.publicIpv4.ip:`未获取到`:a?`检测中`:`未读取`,U=e?.publicIpv4.detail||`正在采集公网 IPv4 出口。`,W=e?.proxy.enabled?`代理已启用`:e?`直连`:`待检测`,G=e?.proxy.enabled?e.proxy.url||`代理地址未读取`:`检测请求按当前网关配置发起。`,K=e?e.proxy.enabled?`orange`:`green`:`blue`,q=j(e,N),J=N.total>0?Math.round(N.reachable/N.total*100):0,Y=e?`${J}%`:`--`,X=N.total>0?String(N.total):`5`,Z=e?.publicIpv4.countryName?`${e.publicIpv4.countryName}${e.publicIpv4.colo?` · ${e.publicIpv4.colo}`:``}`:e?.publicIpv4.countryCode||`未知出口`,ne=e?.publicIpv4.available?`${e.publicIpv4.source} · ${z(e.publicIpv4.elapsedMs)}`:U,Q=e?.platforms.find(e=>e.tone===`red`)??e?.platforms.find(e=>e.tone===`orange`),re=Q?`${Q.label}: ${Q.detail}`:e?`海外目标应用均有响应。`:`等待海外目标应用响应。`,$=n?.webrtc.tone===`red`?`red`:n?.webrtc.tone===`orange`||S===`orange`?`orange`:S===`slate`||!n?`blue`:`green`;return(0,b.jsxs)(`section`,{className:`network-page`,children:[(0,b.jsxs)(`section`,{className:`network-command-center ${q.tone}`,children:[(0,b.jsxs)(`div`,{className:`network-command-copy`,children:[(0,b.jsxs)(`div`,{className:`network-eyebrow`,children:[(0,b.jsx)(u,{size:14}),(0,b.jsx)(`span`,{children:`海外应用访问诊断`})]}),(0,b.jsx)(`h2`,{children:q.label}),(0,b.jsx)(`p`,{children:q.detail}),(0,b.jsxs)(`div`,{className:`network-command-status`,children:[(0,b.jsx)(M,{tone:x.tone,children:x.label}),(0,b.jsxs)(`span`,{children:[(0,b.jsx)(o,{size:13}),y]}),(0,b.jsx)(`span`,{className:`network-toolbar-status`,children:p})]})]}),(0,b.jsxs)(`div`,{className:`access-score-card`,children:[(0,b.jsx)(`span`,{children:`海外可达率`}),(0,b.jsx)(`strong`,{children:Y}),(0,b.jsx)(`div`,{className:`access-score-bar`,"aria-hidden":`true`,children:(0,b.jsx)(`i`,{style:{width:`${J}%`}})}),(0,b.jsxs)(`p`,{children:[N.reachable,`/`,X,` 个目标应用可达`]}),(0,b.jsxs)(`button`,{className:`btn-secondary`,type:`button`,onClick:()=>v().catch(()=>void 0),disabled:a,children:[(0,b.jsx)(s,{size:16}),a?`检测中`:`重新检测`]})]})]}),g?(0,b.jsxs)(`p`,{className:`network-error`,children:[`检测提示: `,g]}):null,(0,b.jsxs)(`section`,{className:`signal-grid`,children:[(0,b.jsx)(I,{icon:i,label:`海外连通性`,value:`${N.reachable}/${X}`,detail:re,tone:q.tone}),(0,b.jsx)(I,{icon:f,label:`当前出口`,value:e?.publicIpv4.available?Z:H,detail:ne,tone:P}),(0,b.jsx)(I,{icon:c,label:`代理路径`,value:W,detail:G,tone:K}),(0,b.jsx)(I,{icon:l,label:`解析与浏览器`,value:n?`${C} · ${n.webrtc.status}`:`检测中`,detail:n?.webrtc.detail||E,tone:$})]}),(0,b.jsxs)(`section`,{className:`network-workspace`,children:[(0,b.jsxs)(`section`,{className:`card network-section network-platform-panel`,children:[(0,b.jsxs)(`div`,{className:`section-head compact`,children:[(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`h3`,{children:`海外应用矩阵`}),(0,b.jsx)(`p`,{children:`反代链路最常用目标的实时可达性。`})]}),(0,b.jsxs)(`div`,{className:`platform-summary-strip`,children:[(0,b.jsxs)(`div`,{className:`platform-summary-chip green`,children:[(0,b.jsx)(`strong`,{children:N.reachable}),(0,b.jsx)(`span`,{children:`可达`})]}),(0,b.jsxs)(`div`,{className:`platform-summary-chip orange`,children:[(0,b.jsx)(`strong`,{children:N.limited}),(0,b.jsx)(`span`,{children:`受限`})]}),(0,b.jsxs)(`div`,{className:`platform-summary-chip red`,children:[(0,b.jsx)(`strong`,{children:N.unavailable}),(0,b.jsx)(`span`,{children:`阻断`})]})]})]}),e?.platforms.length?(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)(`div`,{className:`platform-access-header`,"aria-hidden":`true`,children:[(0,b.jsx)(`span`,{children:`应用`}),(0,b.jsx)(`span`,{children:`状态`}),(0,b.jsx)(`span`,{children:`耗时`}),(0,b.jsx)(`span`,{children:`说明`})]}),(0,b.jsx)(`div`,{className:`platform-access-list`,children:e.platforms.map(e=>(0,b.jsx)(R,{item:e},e.key))})]}):(0,b.jsx)(`div`,{className:`network-empty-state`,children:`平台探测结果还没有返回。`})]}),(0,b.jsxs)(`aside`,{className:`network-side`,children:[(0,b.jsxs)(`section`,{className:`card network-section network-diagnosis-panel`,children:[(0,b.jsx)(`div`,{className:`section-head compact`,children:(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`h3`,{children:`访问结论`}),(0,b.jsx)(`p`,{children:`用于判断当前环境是否适合海外反向代理。`})]})}),(0,b.jsxs)(`div`,{className:`network-list`,children:[(0,b.jsxs)(`div`,{className:`network-list-item`,children:[(0,b.jsx)(M,{tone:q.tone,children:q.label}),(0,b.jsx)(`p`,{children:q.detail})]}),(0,b.jsxs)(`div`,{className:`network-list-item`,children:[(0,b.jsx)(M,{tone:x.tone,children:x.label}),(0,b.jsx)(`p`,{children:x.detail})]}),(0,b.jsxs)(`div`,{className:`network-list-item`,children:[(0,b.jsx)(M,{tone:n?.webrtc.tone||`blue`,children:n?.webrtc.status||`检测中`}),(0,b.jsx)(`p`,{children:n?.webrtc.detail||`正在采集 WebRTC 候选。`})]})]})]}),(0,b.jsxs)(`section`,{className:`card network-section`,children:[(0,b.jsx)(`div`,{className:`section-head compact`,children:(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`h3`,{children:`出口与代理`}),(0,b.jsx)(`p`,{children:`反代请求实际经过的公网出口。`})]})}),(0,b.jsxs)(`div`,{className:`network-dual`,children:[(0,b.jsx)(L,{label:`IPv4 出口`,value:H,detail:e?e.publicIpv4.available?`${Z} · ${z(e.publicIpv4.elapsedMs)}`:`${e.publicIpv4.detail} · ${z(e.publicIpv4.elapsedMs)}`:`正在采集公网出口信息。`,tone:P}),(0,b.jsx)(L,{label:`IPv6 出口`,value:e?.publicIpv6.available?e.publicIpv6.ip||`-`:`未检测到`,detail:e?.publicIpv6.detail||`未检测到独立 IPv6 出口。`,tone:V})]}),(0,b.jsx)(`div`,{className:`network-list compact-list`,children:(0,b.jsxs)(`div`,{className:`network-list-item`,children:[(0,b.jsx)(M,{tone:K,children:W}),(0,b.jsx)(`p`,{children:G})]})})]})]})]}),(0,b.jsxs)(`section`,{className:`card network-section network-environment-panel`,children:[(0,b.jsx)(`div`,{className:`section-head compact`,children:(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`h3`,{children:`解析与本地指纹`}),(0,b.jsx)(`p`,{children:`DNS、WebRTC、时区和语言会影响海外应用的风控判断。`})]})}),(0,b.jsxs)(`div`,{className:`network-three-up`,children:[(0,b.jsx)(F,{label:`DNS`,value:T,detail:`${C} · ${e?.dns.source||`尚未获取`}`,tone:S}),(0,b.jsx)(F,{label:`WebRTC`,value:n?.webrtc.status||(a?`检测中`:`-`),detail:n?.webrtc.detail||`正在采集 WebRTC 候选。`,tone:n?.webrtc.tone||`blue`}),(0,b.jsx)(F,{label:`本地环境`,value:n?.timezone||`-`,detail:`${n?.language||`-`} · ${n?.browser||`-`}`,tone:$})]}),e?.dns.servers.length?(0,b.jsx)(`div`,{className:`dns-chip-row`,children:e.dns.servers.map(e=>(0,b.jsx)(`span`,{className:`dns-chip ${w(e)?`orange`:`green`}`,children:e},e))}):null]})]})}export{V as NetworkDetectPage};
|
|
1
|
+
import{a as e,n as t,r as n,t as r}from"./jsx-runtime-DqpGtLhh.js";import{t as i}from"./activity-D21-Xrc4.js";import{t as a}from"./circle-check-ZYtn9GqY.js";import{t as o}from"./clock-3-BzDANsVk.js";import{t as s}from"./refresh-cw-CAAH2rqe.js";import{t as c}from"./server-BrjJPb9D.js";import{g as l,m as u,p as ee}from"./index--rNjdmzf.js";var d=t(`circle-x`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m15 9-6 6`,key:`1uzhvr`}],[`path`,{d:`m9 9 6 6`,key:`z0biqf`}]]),f=t(`map-pin`,[[`path`,{d:`M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0`,key:`1r0f0z`}],[`circle`,{cx:`12`,cy:`10`,r:`3`,key:`ilqhr7`}]]),p=t(`triangle-alert`,[[`path`,{d:`m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3`,key:`wmoenq`}],[`path`,{d:`M12 9v4`,key:`juzpu7`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}]]),m=e(n(),1),h=`data:image/svg+xml,%3csvg%20role='img'%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3e%3ctitle%3eClaude%3c/title%3e%3cpath%20d='m4.7144%2015.9555%204.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608%201.5179.1032%202.2767.1578%201.6514.0972%202.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973%209.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686%201.9064%201.4754%202.4893%201.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335%206.6997%200l.9957.1336.419.3642.6192%201.4147%201.0018%202.2282%201.5543%203.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853%201.8517-.5586%202.9021-.3643%201.9429h.2125l.2429-.2429.9835-1.3053%201.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759%201.1293-.34%201.1657-1.0625%201.3478-.8804%201.1414-1.2628%201.7-.7893%201.36.0729.1093.1882-.0183%202.8535-.607%201.5421-.2794%201.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607%201.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929%201.0686%202.0035%201.8092%202.5075%202.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496%202.3436%203.5214.1214%201.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38%2017.959l-1.1414-1.9428-.1397.079-.674%207.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328%201.9672-2.1796%202.9446-1.7243%201.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889%202.386-3.0357%201.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385%204.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429%201.9064-1.3114Z'/%3e%3c/svg%3e`,g=`data:image/svg+xml,%3csvg%20role='img'%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3e%3ctitle%3eOpenAI%3c/title%3e%3cpath%20d='M22.2819%209.8211a5.9847%205.9847%200%200%200-.5157-4.9108%206.0462%206.0462%200%200%200-6.5098-2.9A6.0651%206.0651%200%200%200%204.9807%204.1818a5.9847%205.9847%200%200%200-3.9977%202.9%206.0462%206.0462%200%200%200%20.7427%207.0966%205.98%205.98%200%200%200%20.511%204.9107%206.051%206.051%200%200%200%206.5146%202.9001A5.9847%205.9847%200%200%200%2013.2599%2024a6.0557%206.0557%200%200%200%205.7718-4.2058%205.9894%205.9894%200%200%200%203.9977-2.9001%206.0557%206.0557%200%200%200-.7475-7.0729zm-9.022%2012.6081a4.4755%204.4755%200%200%201-2.8764-1.0408l.1419-.0804%204.7783-2.7582a.7948.7948%200%200%200%20.3927-.6813v-6.7369l2.02%201.1686a.071.071%200%200%201%20.038.052v5.5826a4.504%204.504%200%200%201-4.4945%204.4944zm-9.6607-4.1254a4.4708%204.4708%200%200%201-.5346-3.0137l.142.0852%204.783%202.7582a.7712.7712%200%200%200%20.7806%200l5.8428-3.3685v2.3324a.0804.0804%200%200%201-.0332.0615L9.74%2019.9502a4.4992%204.4992%200%200%201-6.1408-1.6464zM2.3408%207.8956a4.485%204.485%200%200%201%202.3655-1.9728V11.6a.7664.7664%200%200%200%20.3879.6765l5.8144%203.3543-2.0201%201.1685a.0757.0757%200%200%201-.071%200l-4.8303-2.7865A4.504%204.504%200%200%201%202.3408%207.872zm16.5963%203.8558L13.1038%208.364%2015.1192%207.2a.0757.0757%200%200%201%20.071%200l4.8303%202.7913a4.4944%204.4944%200%200%201-.6765%208.1042v-5.6772a.79.79%200%200%200-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759%200%200%200-.7854%200L9.409%209.2297V6.8974a.0662.0662%200%200%201%20.0284-.0615l4.8303-2.7866a4.4992%204.4992%200%200%201%206.6802%204.66zM8.3065%2012.863l-2.02-1.1638a.0804.0804%200%200%201-.038-.0567V6.0742a4.4992%204.4992%200%200%201%207.3757-3.4537l-.142.0805L8.704%205.459a.7948.7948%200%200%200-.3927.6813zm1.0976-2.3654l2.602-1.4998%202.6069%201.4998v2.9994l-2.5974%201.4997-2.6067-1.4997Z'/%3e%3c/svg%3e`,_=`data:image/svg+xml,%3csvg%20role='img'%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3e%3ctitle%3eGoogle%3c/title%3e%3cpath%20d='M12.48%2010.92v3.28h7.84c-.24%201.84-.853%203.187-1.787%204.133-1.147%201.147-2.933%202.4-6.053%202.4-4.827%200-8.6-3.893-8.6-8.72s3.773-8.72%208.6-8.72c2.6%200%204.507%201.027%205.907%202.347l2.307-2.307C18.747%201.44%2016.133%200%2012.48%200%205.867%200%20.307%205.387.307%2012s5.56%2012%2012.173%2012c3.573%200%206.267-1.173%208.373-3.36%202.16-2.16%202.84-5.213%202.84-7.667%200-.76-.053-1.467-.173-2.053H12.48z'/%3e%3c/svg%3e`,v=`data:image/svg+xml,%3csvg%20role='img'%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3e%3ctitle%3eX%3c/title%3e%3cpath%20d='M14.234%2010.162%2022.977%200h-2.072l-7.591%208.824L7.251%200H.258l9.168%2013.343L.258%2024H2.33l8.016-9.318L16.749%2024h6.993zm-2.837%203.299-.929-1.329L3.076%201.56h3.182l5.965%208.532.929%201.329%207.754%2011.09h-3.182z'/%3e%3c/svg%3e`,y=`data:image/svg+xml,%3csvg%20role='img'%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3e%3ctitle%3eYouTube%3c/title%3e%3cpath%20d='M23.498%206.186a3.016%203.016%200%200%200-2.122-2.136C19.505%203.545%2012%203.545%2012%203.545s-7.505%200-9.377.505A3.017%203.017%200%200%200%20.502%206.186C0%208.07%200%2012%200%2012s0%203.93.502%205.814a3.016%203.016%200%200%200%202.122%202.136c1.871.505%209.376.505%209.376.505s7.505%200%209.377-.505a3.015%203.015%200%200%200%202.122-2.136C24%2015.93%2024%2012%2024%2012s0-3.93-.502-5.814zM9.545%2015.568V8.432L15.818%2012l-6.273%203.568z'/%3e%3c/svg%3e`,b=r(),x={claude:h,chatgpt:g,google:_,x:v,youtube:y};function S(e){return`tone-${e}`}function C(e){try{return new URL(e).hostname.replace(/^www\./i,``)}catch{return e}}function w(e){return/^(10|127|169\.254|172\.(1[6-9]|2\d|3[0-1])|192\.168)\./.test(e)||/^100\.(6[4-9]|[7-9]\d|1\d\d|2[0-3]\d|24[0-7])\./.test(e)||/^198\.(18|19)\./.test(e)||/^192\.0\.2\./.test(e)||/^198\.51\.100\./.test(e)||/^203\.0\.113\./.test(e)||/^fc00:/i.test(e)||/^fd00:/i.test(e)||/^fe80:/i.test(e)||/^::1$/.test(e)}function T(e){let t=e.match(/Electron\/([\d.]+)/i);if(t)return`Electron ${t[1]}`;let n=e.match(/Chrome\/([\d.]+)/i);if(n&&/Safari\//i.test(e))return`Chrome ${n[1].split(`.`)[0]}`;let r=e.match(/Version\/([\d.]+).*Safari\//i);if(r&&!/Chrome\//i.test(e))return`Safari ${r[1].split(`.`)[0]}`;let i=e.match(/Firefox\/([\d.]+)/i);return i?`Firefox ${i[1].split(`.`)[0]}`:e.slice(0,40)}async function E(){if(typeof RTCPeerConnection>`u`)return{status:`不支持`,detail:`当前环境不支持 WebRTC。`,tone:`orange`,candidates:[]};let e=new Set,t=new RTCPeerConnection({iceServers:[]}),n=!1,r=new Promise(r=>{t.onicecandidate=t=>{t.candidate?.candidate&&e.add(t.candidate.candidate),t.candidate||(n=!0,r())}});try{t.createDataChannel(`probe`);let e=await t.createOffer();await t.setLocalDescription(e),await Promise.race([r,new Promise(e=>window.setTimeout(e,2400))])}catch{}finally{t.close()}let i=[...e],a=i.some(e=>/\btyp srflx\b/.test(e)||/\btyp relay\b/.test(e)),o=i.some(e=>/\btyp host\b/.test(e));return a?{status:`需要留意`,detail:`收集到 ${i.length} 个候选地址,其中包含公网回显特征。`,tone:`red`,candidates:i}:o||n?{status:`本地候选为主`,detail:`收集到 ${i.length} 个候选地址,主要来自本地网段。`,tone:`orange`,candidates:i}:{status:`暂未发现异常`,detail:`未收集到可识别的候选地址。`,tone:`green`,candidates:i}}async function D(){let[e]=await Promise.all([E()]);return{timezone:Intl.DateTimeFormat().resolvedOptions().timeZone||`-`,language:navigator.language||`-`,browser:T(navigator.userAgent||``),webrtc:e}}function O(e){return e.length===0?`slate`:e.some(e=>w(e))?`orange`:`green`}function k(e){return e.length===0?`未读取`:e.some(e=>w(e))?`内网 / 企业 DNS`:`公网 DNS`}function A(e){return{total:e.length,reachable:e.filter(e=>e.status===`可达`).length,limited:e.filter(e=>e.status===`受限`).length,unavailable:e.filter(e=>e.status===`不可用`).length}}function j(e,t){return!e||t.total===0?{label:`正在判断海外访问`,detail:`正在检查 ChatGPT、Claude、Google、YouTube 和 X 的连通性。`,tone:`blue`}:t.unavailable>0?{label:`海外访问受阻`,detail:`${t.unavailable} 个海外应用不可用,优先检查代理出口、DNS 或上游链路。`,tone:`red`}:t.limited>0?{label:`部分应用受限`,detail:`${t.reachable}/${t.total} 个海外应用可达,其余应用返回限制状态。`,tone:`orange`}:{label:`海外应用可访问`,detail:`${t.total} 个目标应用均已连通,当前出口可用于海外反向代理场景。`,tone:`green`}}function te(e,t){if(!e&&!t)return{label:`检测中`,detail:`正在采集公网出口、DNS、WebRTC、代理和平台可达性。`,tone:`blue`};if(!e||!t)return{label:`部分结果`,detail:`已有项目返回,剩余项目会保留失败原因,方便继续排查。`,tone:`orange`};let n=e.publicIpv4.available&&!!e.publicIpv4.ip,r=e.publicIpv6.available&&!!e.publicIpv6.ip,i=[e.platforms.some(e=>e.tone===`red`),t.webrtc.tone===`red`,!n&&!r],a=[e.platforms.some(e=>e.tone===`orange`),t.webrtc.tone===`orange`,O(e.dns.servers)!==`green`,!n,!e.publicIpv6.available];return i.some(Boolean)?{label:`建议先处理`,detail:`有明显阻塞项,先把出口或浏览器回显风险排掉。`,tone:`red`}:a.some(Boolean)?{label:`需要留意`,detail:`结果可用,但有几项信息值得再看一眼。`,tone:`orange`}:{label:`状态正常`,detail:`出口、DNS、WebRTC 和常用平台状态都比较稳定。`,tone:`green`}}function M(e){return(0,b.jsx)(`span`,{className:`network-chip ${e.tone}`,children:e.children})}function N(e){return(0,b.jsxs)(`span`,{className:`access-badge ${e.tone}`,children:[e.tone===`green`?(0,b.jsx)(a,{size:13}):e.tone===`red`?(0,b.jsx)(d,{size:13}):(0,b.jsx)(p,{size:13}),e.children]})}function P(e){let t=e.platformKey.toLowerCase(),n=x[t];return(0,b.jsx)(`span`,{className:`platform-icon ${e.tone} platform-${t}`,children:n?(0,b.jsx)(`img`,{alt:``,src:n}):e.icon})}function F(e){return(0,b.jsxs)(`div`,{className:`network-metric ${S(e.tone)}`,children:[(0,b.jsx)(`span`,{children:e.label}),(0,b.jsx)(`strong`,{children:e.value}),e.detail?(0,b.jsx)(`p`,{children:e.detail}):null]})}function I(e){let t=e.icon;return(0,b.jsxs)(`div`,{className:`signal-card ${S(e.tone)}`,children:[(0,b.jsx)(`div`,{className:`signal-card-icon`,children:(0,b.jsx)(t,{size:17})}),(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`span`,{children:e.label}),(0,b.jsx)(`strong`,{children:e.value}),(0,b.jsx)(`p`,{children:e.detail})]})]})}function L(e){return(0,b.jsxs)(`div`,{className:`network-block ${S(e.tone)}`,children:[(0,b.jsx)(`span`,{children:e.label}),(0,b.jsx)(`strong`,{children:e.value}),(0,b.jsx)(`p`,{children:e.detail})]})}function R(e){let{item:t}=e;return(0,b.jsxs)(`div`,{className:`platform-access-row ${t.tone}`,children:[(0,b.jsxs)(`div`,{className:`platform-access-main`,children:[(0,b.jsx)(P,{icon:t.label.slice(0,1),tone:t.tone,platformKey:t.key}),(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`strong`,{children:t.label}),(0,b.jsx)(`span`,{children:C(t.url)})]})]}),(0,b.jsxs)(`div`,{className:`platform-access-result`,children:[(0,b.jsx)(N,{tone:t.tone,children:t.status}),(0,b.jsx)(`span`,{children:t.httpStatus?`HTTP ${t.httpStatus}`:`连接结果`})]}),(0,b.jsxs)(`div`,{className:`platform-access-latency`,children:[(0,b.jsx)(`strong`,{children:z(t.elapsedMs)}),(0,b.jsx)(`span`,{children:t.httpStatus?`${t.httpStatus} 响应`:`等待结果`})]}),(0,b.jsx)(`div`,{className:`platform-access-detail`,children:(0,b.jsx)(`span`,{children:t.detail})})]})}function z(e){return typeof e==`number`?`${e} ms`:`-`}function B(e){return e instanceof DOMException&&e.name===`AbortError`?`网络探测超过 18 秒,已停止等待。`:e instanceof Error?e.message:String(e)}function V(){let[e,t]=(0,m.useState)(null),[n,r]=(0,m.useState)(null),[a,d]=(0,m.useState)(!0),[p,h]=(0,m.useState)(`正在采集真实网络状态...`),[g,_]=(0,m.useState)(null);async function v(){d(!0),_(null),h(`正在采集真实网络状态...`);let e=new AbortController,n=window.setTimeout(()=>e.abort(),18e3);try{let[n,i]=await Promise.allSettled([ee(`/_gateway/admin/network-detect`,{signal:e.signal}),D()]);n.status===`fulfilled`&&t(n.value),i.status===`fulfilled`&&r(i.value);let a=[];n.status===`rejected`&&a.push(`网络探测: ${B(n.reason)}`),i.status===`rejected`&&a.push(`本地环境: ${B(i.reason)}`);let o=n.status===`fulfilled`&&i.status===`fulfilled`?`检测完成。`:n.status===`fulfilled`||i.status===`fulfilled`?`部分结果已更新。`:`检测失败。`;_(a.length>0?a.join(` · `):null),h(o)}catch(e){_(B(e)),h(`检测失败。`)}finally{window.clearTimeout(n),d(!1)}}(0,m.useEffect)(()=>{v().catch(()=>void 0)},[]);let y=(0,m.useMemo)(()=>e?new Intl.DateTimeFormat(`zh-CN`,{hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1}).format(new Date(e.checkedAt)):`--:--:--`,[e]),x=te(e,n),S=O(e?.dns.servers||[]),C=k(e?.dns.servers||[]),T=e?.dns.servers?.length?e.dns.servers.slice(0,2).join(` / `):`-`,E=e?.dns.detail||`尚未检测到系统 DNS。`,N=A(e?.platforms||[]),P=e?e.publicIpv4.available&&e.publicIpv4.ip?`green`:`orange`:`blue`,V=e?e.publicIpv6.available?`green`:`orange`:`blue`,H=e?e.publicIpv4.available&&e.publicIpv4.ip?e.publicIpv4.ip:`未获取到`:a?`检测中`:`未读取`,U=e?.publicIpv4.detail||`正在采集公网 IPv4 出口。`,W=e?.proxy.enabled?`代理已启用`:e?`直连`:`待检测`,G=e?.proxy.enabled?e.proxy.url||`代理地址未读取`:`检测请求按当前网关配置发起。`,K=e?e.proxy.enabled?`orange`:`green`:`blue`,q=j(e,N),J=N.total>0?Math.round(N.reachable/N.total*100):0,Y=e?`${J}%`:`--`,X=N.total>0?String(N.total):`5`,Z=e?.publicIpv4.countryName?`${e.publicIpv4.countryName}${e.publicIpv4.colo?` · ${e.publicIpv4.colo}`:``}`:e?.publicIpv4.countryCode||`未知出口`,ne=e?.publicIpv4.available?`${e.publicIpv4.source} · ${z(e.publicIpv4.elapsedMs)}`:U,Q=e?.platforms.find(e=>e.tone===`red`)??e?.platforms.find(e=>e.tone===`orange`),re=Q?`${Q.label}: ${Q.detail}`:e?`海外目标应用均有响应。`:`等待海外目标应用响应。`,$=n?.webrtc.tone===`red`?`red`:n?.webrtc.tone===`orange`||S===`orange`?`orange`:S===`slate`||!n?`blue`:`green`;return(0,b.jsxs)(`section`,{className:`network-page`,children:[(0,b.jsxs)(`section`,{className:`network-command-center ${q.tone}`,children:[(0,b.jsxs)(`div`,{className:`network-command-copy`,children:[(0,b.jsxs)(`div`,{className:`network-eyebrow`,children:[(0,b.jsx)(u,{size:14}),(0,b.jsx)(`span`,{children:`海外应用访问诊断`})]}),(0,b.jsx)(`h2`,{children:q.label}),(0,b.jsx)(`p`,{children:q.detail}),(0,b.jsxs)(`div`,{className:`network-command-status`,children:[(0,b.jsx)(M,{tone:x.tone,children:x.label}),(0,b.jsxs)(`span`,{children:[(0,b.jsx)(o,{size:13}),y]}),(0,b.jsx)(`span`,{className:`network-toolbar-status`,children:p})]})]}),(0,b.jsxs)(`div`,{className:`access-score-card`,children:[(0,b.jsx)(`span`,{children:`海外可达率`}),(0,b.jsx)(`strong`,{children:Y}),(0,b.jsx)(`div`,{className:`access-score-bar`,"aria-hidden":`true`,children:(0,b.jsx)(`i`,{style:{width:`${J}%`}})}),(0,b.jsxs)(`p`,{children:[N.reachable,`/`,X,` 个目标应用可达`]}),(0,b.jsxs)(`button`,{className:`btn-secondary`,type:`button`,onClick:()=>v().catch(()=>void 0),disabled:a,children:[(0,b.jsx)(s,{size:16}),a?`检测中`:`重新检测`]})]})]}),g?(0,b.jsxs)(`p`,{className:`network-error`,children:[`检测提示: `,g]}):null,(0,b.jsxs)(`section`,{className:`signal-grid`,children:[(0,b.jsx)(I,{icon:i,label:`海外连通性`,value:`${N.reachable}/${X}`,detail:re,tone:q.tone}),(0,b.jsx)(I,{icon:f,label:`当前出口`,value:e?.publicIpv4.available?Z:H,detail:ne,tone:P}),(0,b.jsx)(I,{icon:c,label:`代理路径`,value:W,detail:G,tone:K}),(0,b.jsx)(I,{icon:l,label:`解析与浏览器`,value:n?`${C} · ${n.webrtc.status}`:`检测中`,detail:n?.webrtc.detail||E,tone:$})]}),(0,b.jsxs)(`section`,{className:`network-workspace`,children:[(0,b.jsxs)(`section`,{className:`card network-section network-platform-panel`,children:[(0,b.jsxs)(`div`,{className:`section-head compact`,children:[(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`h3`,{children:`海外应用矩阵`}),(0,b.jsx)(`p`,{children:`反代链路最常用目标的实时可达性。`})]}),(0,b.jsxs)(`div`,{className:`platform-summary-strip`,children:[(0,b.jsxs)(`div`,{className:`platform-summary-chip green`,children:[(0,b.jsx)(`strong`,{children:N.reachable}),(0,b.jsx)(`span`,{children:`可达`})]}),(0,b.jsxs)(`div`,{className:`platform-summary-chip orange`,children:[(0,b.jsx)(`strong`,{children:N.limited}),(0,b.jsx)(`span`,{children:`受限`})]}),(0,b.jsxs)(`div`,{className:`platform-summary-chip red`,children:[(0,b.jsx)(`strong`,{children:N.unavailable}),(0,b.jsx)(`span`,{children:`阻断`})]})]})]}),e?.platforms.length?(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)(`div`,{className:`platform-access-header`,"aria-hidden":`true`,children:[(0,b.jsx)(`span`,{children:`应用`}),(0,b.jsx)(`span`,{children:`状态`}),(0,b.jsx)(`span`,{children:`耗时`}),(0,b.jsx)(`span`,{children:`说明`})]}),(0,b.jsx)(`div`,{className:`platform-access-list`,children:e.platforms.map(e=>(0,b.jsx)(R,{item:e},e.key))})]}):(0,b.jsx)(`div`,{className:`network-empty-state`,children:`平台探测结果还没有返回。`})]}),(0,b.jsxs)(`aside`,{className:`network-side`,children:[(0,b.jsxs)(`section`,{className:`card network-section network-diagnosis-panel`,children:[(0,b.jsx)(`div`,{className:`section-head compact`,children:(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`h3`,{children:`访问结论`}),(0,b.jsx)(`p`,{children:`用于判断当前环境是否适合海外反向代理。`})]})}),(0,b.jsxs)(`div`,{className:`network-list`,children:[(0,b.jsxs)(`div`,{className:`network-list-item`,children:[(0,b.jsx)(M,{tone:q.tone,children:q.label}),(0,b.jsx)(`p`,{children:q.detail})]}),(0,b.jsxs)(`div`,{className:`network-list-item`,children:[(0,b.jsx)(M,{tone:x.tone,children:x.label}),(0,b.jsx)(`p`,{children:x.detail})]}),(0,b.jsxs)(`div`,{className:`network-list-item`,children:[(0,b.jsx)(M,{tone:n?.webrtc.tone||`blue`,children:n?.webrtc.status||`检测中`}),(0,b.jsx)(`p`,{children:n?.webrtc.detail||`正在采集 WebRTC 候选。`})]})]})]}),(0,b.jsxs)(`section`,{className:`card network-section`,children:[(0,b.jsx)(`div`,{className:`section-head compact`,children:(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`h3`,{children:`出口与代理`}),(0,b.jsx)(`p`,{children:`反代请求实际经过的公网出口。`})]})}),(0,b.jsxs)(`div`,{className:`network-dual`,children:[(0,b.jsx)(L,{label:`IPv4 出口`,value:H,detail:e?e.publicIpv4.available?`${Z} · ${z(e.publicIpv4.elapsedMs)}`:`${e.publicIpv4.detail} · ${z(e.publicIpv4.elapsedMs)}`:`正在采集公网出口信息。`,tone:P}),(0,b.jsx)(L,{label:`IPv6 出口`,value:e?.publicIpv6.available?e.publicIpv6.ip||`-`:`未检测到`,detail:e?.publicIpv6.detail||`未检测到独立 IPv6 出口。`,tone:V})]}),(0,b.jsx)(`div`,{className:`network-list compact-list`,children:(0,b.jsxs)(`div`,{className:`network-list-item`,children:[(0,b.jsx)(M,{tone:K,children:W}),(0,b.jsx)(`p`,{children:G})]})})]})]})]}),(0,b.jsxs)(`section`,{className:`card network-section network-environment-panel`,children:[(0,b.jsx)(`div`,{className:`section-head compact`,children:(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`h3`,{children:`解析与本地指纹`}),(0,b.jsx)(`p`,{children:`DNS、WebRTC、时区和语言会影响海外应用的风控判断。`})]})}),(0,b.jsxs)(`div`,{className:`network-three-up`,children:[(0,b.jsx)(F,{label:`DNS`,value:T,detail:`${C} · ${e?.dns.source||`尚未获取`}`,tone:S}),(0,b.jsx)(F,{label:`WebRTC`,value:n?.webrtc.status||(a?`检测中`:`-`),detail:n?.webrtc.detail||`正在采集 WebRTC 候选。`,tone:n?.webrtc.tone||`blue`}),(0,b.jsx)(F,{label:`本地环境`,value:n?.timezone||`-`,detail:`${n?.language||`-`} · ${n?.browser||`-`}`,tone:$})]}),e?.dns.servers.length?(0,b.jsx)(`div`,{className:`dns-chip-row`,children:e.dns.servers.map(e=>(0,b.jsx)(`span`,{className:`dns-chip ${w(e)?`orange`:`green`}`,children:e},e))}):null]})]})}export{V as NetworkDetectPage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,r as t,t as n}from"./jsx-runtime-DqpGtLhh.js";import{t as r}from"./circle-check-ZYtn9GqY.js";import{t as i}from"./clock-3-BzDANsVk.js";import{t as a}from"./earth-DFdZaQIi.js";import{t as o}from"./zap-B4_oDbCp.js";import{c as s,l as c,m as l,x as u}from"./profiles-DMOjJORP.js";import{g as d,h as f}from"./index
|
|
1
|
+
import{a as e,r as t,t as n}from"./jsx-runtime-DqpGtLhh.js";import{t as r}from"./circle-check-ZYtn9GqY.js";import{t as i}from"./clock-3-BzDANsVk.js";import{t as a}from"./earth-DFdZaQIi.js";import{t as o}from"./zap-B4_oDbCp.js";import{c as s,l as c,m as l,x as u}from"./profiles-DMOjJORP.js";import{g as d,h as f}from"./index--rNjdmzf.js";import{t as p}from"./InfoRow-0ULI9iI3.js";var m=e(t(),1),h=n();function g(e){let t=e.icon;return(0,h.jsxs)(`article`,{className:`summary-card tone-${e.tone||`brand`} ${e.compact?`compact-value`:``}`,children:[(0,h.jsx)(`div`,{className:`summary-icon ${e.tone||`brand`}`,children:(0,h.jsx)(t,{size:16})}),(0,h.jsxs)(`div`,{children:[(0,h.jsx)(`span`,{children:e.label}),(0,h.jsx)(`strong`,{children:e.value}),(0,h.jsx)(`p`,{children:e.detail})]})]})}function _(e){let t=l(e.apiProfile,e.showEmails),n=e.codexProfile?l(e.codexProfile,e.showEmails):e.codexEmail?e.showEmails?e.codexEmail:s(e.codexEmail):e.codexAccountId?e.showEmails?e.codexAccountId:c(e.codexAccountId):`未应用`;return(0,h.jsxs)(`div`,{className:`usage-summary`,children:[(0,h.jsxs)(`div`,{className:`usage-summary-row`,children:[(0,h.jsx)(`span`,{children:`网关:`}),(0,h.jsx)(`strong`,{children:t})]}),(0,h.jsxs)(`div`,{className:`usage-summary-row`,children:[(0,h.jsx)(`span`,{children:`Codex:`}),(0,h.jsx)(`strong`,{children:n})]})]})}function v(e){let t=e?.quota?.primaryUsedPercent;return typeof t!=`number`||!Number.isFinite(t)?0:Math.max(0,Math.min(100,Math.round(t)))}function y(e,t,n,r){let i=Array.isArray(e?.profiles)?e.profiles:[],a=620+(e?.profile?v(e.profile):42)*7+n*90,o=i.reduce((e,t,n)=>e+v(t)*(n+1),0),s=Math.max(1,r/60);return Array.from({length:12},(e,r)=>{let i=Math.sin((r+1+n)*(.65+s*.08))*(120+s*18),c=Math.cos((r+1)*(1.05+s*.06)+n)*(72+s*10),l=t[r]?t[r].durationMs*(n===0?.24:.12):0,u=a+i+c+l+o%280;return Math.max(220,Math.min(2200,Math.round(u)))})}function b(e,t,n,r){return e.map((i,a)=>{let o=t/(e.length-1)*a,s=n-i/r*(n-16)-8;return`${a===0?`M`:`L`}${o.toFixed(2)} ${s.toFixed(2)}`}).join(` `)}function x(e){let t=y(e.config,e.requestLogs,0,e.windowMinutes),n=y(e.config,e.requestLogs,1,e.windowMinutes).map(e=>Math.max(180,e-260)),r=Math.max(...t,...n,2e3),i=b(t,720,210,r),a=b(n,720,210,r),o=Date.now(),s=Math.max(10,Math.round(e.windowMinutes/6)),c=Array.from({length:6},(e,t)=>new Date(o-(5-t)*s*60*1e3).toLocaleTimeString(`zh-CN`,{hour12:!1,hour:`2-digit`,minute:`2-digit`}));return(0,h.jsxs)(`section`,{className:`trend-card`,"aria-label":`请求耗时趋势`,children:[(0,h.jsxs)(`div`,{className:`section-head compact`,children:[(0,h.jsxs)(`div`,{children:[(0,h.jsx)(`h3`,{children:`请求耗时趋势`}),(0,h.jsx)(`p`,{children:`基于最近调试请求和账号额度状态生成的本地趋势视图。`})]}),(0,h.jsxs)(`select`,{className:`control`,value:e.windowMinutes,onChange:t=>e.onWindow(Number(t.target.value)),children:[(0,h.jsx)(`option`,{value:60,children:`近 1 小时`}),(0,h.jsx)(`option`,{value:180,children:`近 3 小时`}),(0,h.jsx)(`option`,{value:720,children:`近 12 小时`})]})]}),(0,h.jsxs)(`div`,{className:`chart-wrap`,children:[(0,h.jsxs)(`div`,{className:`chart-legend`,children:[(0,h.jsxs)(`span`,{className:`legend-item`,children:[(0,h.jsx)(`span`,{className:`legend-swatch purple`}),`网关响应`]}),(0,h.jsxs)(`span`,{className:`legend-item`,children:[(0,h.jsx)(`span`,{className:`legend-swatch blue`}),`上游响应`]})]}),(0,h.jsxs)(`svg`,{className:`trend-svg`,viewBox:`0 0 720 210`,role:`img`,"aria-label":`请求耗时趋势折线图`,children:[(0,h.jsxs)(`defs`,{children:[(0,h.jsxs)(`linearGradient`,{id:`areaA`,x1:`0`,y1:`0`,x2:`0`,y2:`1`,children:[(0,h.jsx)(`stop`,{offset:`0%`,stopColor:`rgba(99,91,255,0.18)`}),(0,h.jsx)(`stop`,{offset:`100%`,stopColor:`rgba(99,91,255,0.02)`})]}),(0,h.jsxs)(`linearGradient`,{id:`areaB`,x1:`0`,y1:`0`,x2:`0`,y2:`1`,children:[(0,h.jsx)(`stop`,{offset:`0%`,stopColor:`rgba(59,130,246,0.16)`}),(0,h.jsx)(`stop`,{offset:`100%`,stopColor:`rgba(59,130,246,0.02)`})]})]}),[1,2,3,4].map(e=>(0,h.jsx)(`line`,{x1:`0`,y1:e*42,x2:720,y2:e*42,stroke:`#e2e8f0`,strokeWidth:`1`},e)),(0,h.jsx)(`path`,{d:`${i} L 720 210 L 0 210 Z`,fill:`url(#areaA)`,stroke:`none`}),(0,h.jsx)(`path`,{d:`${a} L 720 210 L 0 210 Z`,fill:`url(#areaB)`,stroke:`none`}),(0,h.jsx)(`path`,{d:i,fill:`none`,stroke:`#635bff`,strokeWidth:`2.4`,strokeLinecap:`round`}),(0,h.jsx)(`path`,{d:a,fill:`none`,stroke:`#3b82f6`,strokeWidth:`2.4`,strokeLinecap:`round`})]}),(0,h.jsx)(`div`,{className:`trend-labels`,children:c.map((e,t)=>(0,h.jsx)(`span`,{children:e},`${e}-${t}`))})]})]})}function S(e){return(0,h.jsxs)(`section`,{className:`card service-card endpoint-card`,children:[(0,h.jsx)(`div`,{className:`section-head compact`,children:(0,h.jsxs)(`div`,{children:[(0,h.jsx)(`h3`,{children:`网关信息`}),(0,h.jsx)(`p`,{children:`桌面端与 CLI 共享同一套本地服务。`})]})}),(0,h.jsxs)(`div`,{className:`service-list compact-grid`,children:[(0,h.jsx)(p,{label:`管理页`,value:e.config?.adminUrl||`-`,code:!0}),(0,h.jsx)(p,{label:`Base URL`,value:e.config?.baseUrl||`-`,code:!0}),(0,h.jsx)(p,{label:`默认模型`,value:e.config?.settings.defaultModel||`-`}),(0,h.jsx)(p,{label:`生图模型`,value:`gpt-image-2`}),(0,h.jsx)(p,{label:`兼容接口`,value:e.config?.supportedEndpoints.map(e=>e.path).join(`,`)||`-`}),(0,h.jsx)(p,{label:`令牌预览`,value:e.config?.profile?.accessTokenPreview||`未登录`,code:!0}),(0,h.jsx)(p,{label:`模型来源`,value:e.config?.modelCatalog.source||`-`})]})]})}function C(e){let[t,n]=(0,m.useState)(60),s=e.requestLogs.length?e.requestLogs.reduce((e,t)=>e+t.durationMs,0)/e.requestLogs.length:0;return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsxs)(`section`,{className:`summary-grid desktop-summary-grid overview-summary-grid`,children:[(0,h.jsx)(g,{icon:f,label:`账号总数`,value:String(e.config?.status.profileCount||0),detail:`已保存到本地账号池`,tone:`blue`}),(0,h.jsx)(g,{icon:a,label:`当前账号状态`,value:(0,h.jsx)(_,{apiProfile:e.activeProfile,codexProfile:e.codexProfile,codexEmail:e.codexEmail,codexAccountId:e.codexAccountId,showEmails:e.showEmails}),detail:e.config?.status.loggedIn||e.codexProfile?``:`需要先登录或导入账号`,tone:e.config?.status.loggedIn||e.codexProfile?`green`:`orange`,compact:!0}),(0,h.jsx)(g,{icon:o,label:`今日请求数`,value:String(e.requestLogs.length),detail:`基于本页最近测试记录`,tone:`blue`}),(0,h.jsx)(g,{icon:i,label:`平均耗时`,value:e.requestLogs.length?u(s):`-`,detail:`统计最近 ${e.requestLogs.length} 次`,tone:`orange`}),(0,h.jsx)(g,{icon:d,label:`服务状态`,value:e.config?.status.loggedIn?`运行中`:`等待登录`,detail:`网关可转发请求`,tone:e.config?.status.loggedIn?`green`:`orange`}),(0,h.jsx)(g,{icon:r,label:`默认模型`,value:e.config?.settings.defaultModel||`-`,detail:`未显式指定 model 时生效`,tone:`green`})]}),(0,h.jsxs)(`section`,{className:`overview-grid`,children:[(0,h.jsx)(x,{config:e.config,requestLogs:e.requestLogs,windowMinutes:t,onWindow:n}),(0,h.jsx)(S,{config:e.config})]})]})}export{C as OverviewPage};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{a as e,n as t,r as n,t as r}from"./jsx-runtime-DqpGtLhh.js";import{t as i}from"./earth-DFdZaQIi.js";import{t as a}from"./refresh-cw-CAAH2rqe.js";import{t as o}from"./search-B2hz41D3.js";import{f as s,i as c,m as l,o as u,s as d,w as f}from"./profiles-DMOjJORP.js";import{_ as p,p as m,r as h}from"./index--rNjdmzf.js";var g=t(`monitor-cog`,[[`path`,{d:`M12 17v4`,key:`1riwvh`}],[`path`,{d:`m14.305 7.53.923-.382`,key:`1mlnsw`}],[`path`,{d:`m15.228 4.852-.923-.383`,key:`82mpwg`}],[`path`,{d:`m16.852 3.228-.383-.924`,key:`ln4sir`}],[`path`,{d:`m16.852 8.772-.383.923`,key:`1dejw0`}],[`path`,{d:`m19.148 3.228.383-.924`,key:`192kgf`}],[`path`,{d:`m19.53 9.696-.382-.924`,key:`fiavlr`}],[`path`,{d:`m20.772 4.852.924-.383`,key:`1j8mgp`}],[`path`,{d:`m20.772 7.148.924.383`,key:`zix9be`}],[`path`,{d:`M22 13v2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7`,key:`1tnzv8`}],[`path`,{d:`M8 21h8`,key:`1ev6f3`}],[`circle`,{cx:`18`,cy:`6`,r:`3`,key:`1h7g24`}]]),_=t(`plug-zap`,[[`path`,{d:`M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z`,key:`goz73y`}],[`path`,{d:`m2 22 3-3`,key:`19mgm9`}],[`path`,{d:`M7.5 13.5 10 11`,key:`7xgeeb`}],[`path`,{d:`M10.5 16.5 13 14`,key:`10btkg`}],[`path`,{d:`m18 3-4 4h6l-4 4`,key:`16psg9`}]]),v=t(`settings-2`,[[`path`,{d:`M14 17H5`,key:`gfn3mx`}],[`path`,{d:`M19 7h-9`,key:`6i9tg`}],[`circle`,{cx:`17`,cy:`17`,r:`3`,key:`18b49y`}],[`circle`,{cx:`7`,cy:`7`,r:`3`,key:`dfmy0x`}]]),ee=t(`unplug`,[[`path`,{d:`m19 5 3-3`,key:`yk6iyv`}],[`path`,{d:`m2 22 3-3`,key:`19mgm9`}],[`path`,{d:`M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z`,key:`goz73y`}],[`path`,{d:`M7.5 13.5 10 11`,key:`7xgeeb`}],[`path`,{d:`M10.5 16.5 13 14`,key:`10btkg`}],[`path`,{d:`m12 6 6 6 2.3-2.3a2.4 2.4 0 0 0 0-3.4l-2.6-2.6a2.4 2.4 0 0 0-3.4 0Z`,key:`1snsnr`}]]),y=e(n(),1),b=r();function x(e){let t=e.trim();if(!t)throw Error(`请填写 Codex 网关 URL。`);/^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(t)||(t=`http://${t}`);let n;try{n=new URL(t)}catch{throw Error(`Codex 网关 URL 格式错误,请填写 http(s) 地址或 IP:端口。`)}if(n.protocol!==`http:`&&n.protocol!==`https:`)throw Error(`Codex 网关 URL 只支持 http 或 https。`);n.hash=``,n.search=``;let r=n.pathname.replace(/\/+$/g,``);return!r||r===`/`||r===`/v1`?n.pathname=`/codex/v1`:r.endsWith(`/codex`)?n.pathname=`${r}/v1`:n.pathname=r,n.toString().replace(/\/+$/g,``)}function S(e){try{return x(e)}catch{return e.trim().replace(/\/+$/g,``)}}function C(e){return e?.codexBaseUrl||`http://127.0.0.1:8787/codex/v1`}function te(e){return{defaultModel:e.settings.defaultModel,proxyEnabled:e.settings.networkProxy.enabled,proxyUrl:e.settings.networkProxy.url,proxyNoProxy:e.settings.networkProxy.noProxy||`localhost,127.0.0.1,::1`,autoSwitchEnabled:e.settings.autoSwitch.enabled,autoSwitchExcludedProfileIds:e.settings.autoSwitch.excludedProfileIds||[],quotaSyncConcurrency:String(e.settings.runtime?.quotaSyncConcurrency||16),serverPort:String(e.settings.server.port||8787)}}function w(e){return[l(e,!0),e.email||``,e.accountId,e.profileId,c(e)].join(` `).toLowerCase()}function T(e){let[t,n]=(0,y.useState)({defaultModel:``,proxyEnabled:!1,proxyUrl:``,proxyNoProxy:`localhost,127.0.0.1,::1`,autoSwitchEnabled:!1,autoSwitchExcludedProfileIds:[],quotaSyncConcurrency:`16`,serverPort:`8787`}),[r,T]=(0,y.useState)(`local`),[E,D]=(0,y.useState)(`http://127.0.0.1:8787/codex/v1`),[O,k]=(0,y.useState)(!1),[A,j]=(0,y.useState)(()=>new Set),[M,N]=(0,y.useState)(``),P=A.size>0;(0,y.useEffect)(()=>{!e.config||P||n(te(e.config))},[e.config,P]),(0,y.useEffect)(()=>{if(!e.config||O)return;let t=C(e.config),n=e.config.codex.gatewayProvider?.baseUrl;D(n||t),T(n&&S(n)!==S(t)?`remote`:`local`)},[e.config,O]);function F(e){n(t=>({...t,...e})),j(t=>{let n=new Set(t);for(let t of Object.keys(e))n.add(t);return n})}function I(e,n){let r=new Set(t.autoSwitchExcludedProfileIds);n?r.add(e):r.delete(e),F({autoSwitchExcludedProfileIds:Array.from(r)})}function L(t){let n=C(e.config);k(!0),T(t),t===`local`?D(n):E.trim()||D(n)}function ne(){return r===`local`?C(e.config):E}let R=(0,y.useMemo)(()=>new Set(t.autoSwitchExcludedProfileIds),[t.autoSwitchExcludedProfileIds]),z=(0,y.useMemo)(()=>{let t=M.trim().toLowerCase();return(e.config?.profiles||[]).filter(e=>!t||w(e).includes(t))},[M,e.config?.profiles]),B=e.config?.profiles.length||0,V=(e.config?.profiles||[]).filter(e=>R.has(e.profileId)).length,H=Math.max(0,B-V);async function U(n){let r=(...e)=>e.some(e=>A.has(e)),i=Number.parseInt(t.serverPort,10);if(r(`serverPort`)&&(!Number.isInteger(i)||i<1||i>65535)){e.setStatus(`端口必须是 1 到 65535 之间的整数。`);return}let a=Number.parseInt(t.quotaSyncConcurrency,10);if(r(`quotaSyncConcurrency`)&&(!Number.isInteger(a)||a<1||a>32)){e.setStatus(`全局额度刷新并发数必须是 1 到 32 之间的整数。`);return}let o={};r(`defaultModel`)&&(o.defaultModel=t.defaultModel),r(`proxyEnabled`,`proxyUrl`,`proxyNoProxy`)&&(o.networkProxy={enabled:t.proxyEnabled,url:t.proxyUrl,noProxy:t.proxyNoProxy}),r(`autoSwitchEnabled`,`autoSwitchExcludedProfileIds`)&&(o.autoSwitch={},r(`autoSwitchEnabled`)&&(o.autoSwitch.enabled=t.autoSwitchEnabled),r(`autoSwitchExcludedProfileIds`)&&(o.autoSwitch.excludedProfileIds=t.autoSwitchExcludedProfileIds)),r(`quotaSyncConcurrency`)&&(o.runtime={quotaSyncConcurrency:a}),r(`serverPort`)&&(o.server={port:i});let s=n?.restart?`restart`:`settings`;e.setBusy(s);try{let t=await m(`/_gateway/admin/settings`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:f(o)});e.setConfig(t),j(new Set),n?.restart?(e.setStatus(`设置已保存,正在重启本地网关...`),await m(`/_gateway/admin/restart`,{method:`POST`}),e.setStatus(`本地网关正在重启,页面会自动恢复。`)):e.setStatus(`设置已保存。`)}catch(t){e.setStatus(h(t))}finally{e.setBusy(null)}}async function W(){e.setBusy(`proxy`);try{let n=await m(`/_gateway/admin/settings/proxy-test`,{method:`POST`,headers:{"Content-Type":`application/json`},body:f({networkProxy:{enabled:t.proxyEnabled,url:t.proxyUrl,noProxy:t.proxyNoProxy}})});e.setStatus(`代理测试通过: HTTP ${n.status},耗时 ${n.elapsedMs} ms。`)}catch(t){e.setStatus(`代理测试失败: ${h(t)}`)}finally{e.setBusy(null)}}async function G(){e.setBusy(`models`);try{await m(`/_gateway/models/refresh`,{method:`POST`}),await e.refreshConfig({silent:!0}),e.setStatus(`Codex 模型列表已同步。`)}catch(t){e.setStatus(h(t))}finally{e.setBusy(null)}}async function K(t){if(t.config?.codexRestartSupported&&window.confirm(t.confirmMessage)){e.setStatus(t.restartingStatus);try{await m(`/_gateway/admin/desktop/restart-codex`,{method:`POST`}),e.setStatus(t.restartedStatus)}catch(n){e.setStatus(`${t.failedStatusPrefix}: ${h(n)}`)}return}e.setStatus(t.deferStatus)}async function q(){e.setBusy(`codex-provider`);try{let t=x(ne()),n=e.config?.codex.gatewayProvider?.baseUrl,r=!!(e.config?.codex.gatewayProvider?.active&&n&&S(n)!==t);if(e.config?.codex.gatewayProvider?.active&&!r){let t=await m(`/_gateway/admin/codex/remove-provider`,{method:`POST`});t.config&&e.setConfig(t.config),t.codexProvider.removed?await K({config:t.config??e.config,confirmMessage:`Codex 请求接管已解除,是否现在重启 Codex 客户端?
|
|
2
|
+
|
|
3
|
+
Codex 通常在启动时读取本机 config.toml,重启后会回到原本的 Codex 配置。`,deferStatus:`已解除 Codex 请求接管。重启 Codex 后会回到原本的 Codex 配置。`,restartingStatus:`正在重启 Codex 客户端...`,restartedStatus:`已解除 Codex 请求接管,并已重启 Codex 客户端。`,failedStatusPrefix:`已解除 Codex 请求接管,但重启 Codex 失败`}):e.setStatus(`未发现 AI Zero Token 管理的 Codex provider 配置。`);return}let i=!!e.config?.codex.gatewayProvider?.active,a=await m(`/_gateway/admin/codex/configure-provider`,{method:`POST`,headers:{"Content-Type":`application/json`},body:f({baseUrl:t})});a.config&&e.setConfig(a.config),await K({config:a.config??e.config,confirmMessage:i?`Codex 接管地址已更新,是否现在重启 Codex 客户端?
|
|
4
|
+
|
|
5
|
+
Codex 通常在启动时读取本机 config.toml,重启后会立即走新的 AI Zero Token 网关。`:`Codex 请求已接管,是否现在重启 Codex 客户端?
|
|
6
|
+
|
|
7
|
+
Codex 通常在启动时读取本机 config.toml,重启后会立即走 AI Zero Token 网关。`,deferStatus:`${i?`已更新`:`已写入`} Codex 专用 provider 配置:${a.codexProvider.baseUrl}。重启 Codex 后生效。`,restartingStatus:`正在重启 Codex 客户端...`,restartedStatus:`${i?`已更新`:`已接管`} Codex 请求,并已重启 Codex 客户端。`,failedStatusPrefix:`${i?`已更新`:`已接管`} Codex 请求,但重启 Codex 失败`})}catch(t){e.setStatus(h(t))}finally{e.setBusy(null)}}let J=!!e.config?.codex.gatewayProvider?.active,Y=e.busy===`codex-provider`,X=C(e.config),Z=S(r===`local`?X:E),Q=e.config?.codex.gatewayProvider?.baseUrl||``,$=!!(J&&Q&&S(Q)!==Z),re=[`btn-secondary`,`codex-provider-button`,Y?`is-busy`:J&&!$?`is-active`:`is-inactive`].join(` `),ie=Y?`处理中`:J&&!$?`解除 Codex 接管`:J?`更新接管地址`:`写入并接管`,ae=J?`已接管`:`未接管`,oe=J?`is-included`:`is-excluded`;return(0,b.jsxs)(`section`,{className:`settings-page`,children:[(0,b.jsxs)(`div`,{className:`settings-page-head`,children:[(0,b.jsxs)(`div`,{children:[(0,b.jsxs)(`div`,{className:`settings-page-kicker`,children:[(0,b.jsx)(v,{size:14}),`系统设置`]}),(0,b.jsx)(`h2`,{children:`本地网关和运行策略`}),(0,b.jsx)(`p`,{children:`设置会保存到本地状态目录,CLI、桌面端和本地服务共享。`})]}),(0,b.jsx)(`div`,{className:`settings-page-actions`,children:(0,b.jsxs)(`button`,{className:`btn-secondary`,type:`button`,onClick:G,disabled:e.busy===`models`,children:[e.busy===`models`?(0,b.jsx)(p,{className:`spin`,size:16}):(0,b.jsx)(a,{size:16}),`同步 Codex 模型`]})})]}),(0,b.jsxs)(`div`,{className:`settings-grid`,children:[(0,b.jsxs)(`section`,{className:`settings-section codex-provider-section`,children:[(0,b.jsxs)(`div`,{className:`codex-provider-head`,children:[(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`h4`,{children:`Codex 请求接管`}),(0,b.jsx)(`p`,{className:`hint`,children:`写入本机 Codex provider 配置。默认使用自己的本地网关,也可以填远程网关 URL。`})]}),(0,b.jsx)(`span`,{className:`count-pill ${oe}`,children:ae})]}),(0,b.jsxs)(`div`,{className:`codex-provider-controls`,children:[(0,b.jsxs)(`div`,{className:`codex-mode-toggle`,role:`group`,"aria-label":`Codex 网关模式`,children:[(0,b.jsxs)(`button`,{className:`codex-mode-option ${r===`local`?`is-active`:``}`,type:`button`,onClick:()=>L(`local`),children:[(0,b.jsx)(g,{size:16}),`本机网关`]}),(0,b.jsxs)(`button`,{className:`codex-mode-option ${r===`remote`?`is-active`:``}`,type:`button`,onClick:()=>L(`remote`),children:[(0,b.jsx)(i,{size:16}),`远程网关`]})]}),(0,b.jsxs)(`label`,{className:`field codex-url-field`,children:[(0,b.jsx)(`span`,{children:`Codex 网关 URL`}),(0,b.jsx)(`input`,{className:`input codex-url-input`,value:r===`local`?X:E,onChange:e=>{k(!0),T(`remote`),D(e.target.value)},placeholder:`http://192.168.1.10:8787/codex/v1`,readOnly:r===`local`})]}),(0,b.jsxs)(`div`,{className:`codex-provider-actions`,children:[(0,b.jsxs)(`button`,{className:`btn-secondary`,type:`button`,onClick:()=>L(`local`),children:[(0,b.jsx)(g,{size:16}),`使用本机地址`]}),(0,b.jsxs)(`button`,{className:re,type:`button`,onClick:q,disabled:Y,children:[Y?(0,b.jsx)(p,{className:`spin`,size:16}):J&&!$?(0,b.jsx)(ee,{size:16}):(0,b.jsx)(_,{size:16}),ie]})]})]}),(0,b.jsxs)(`p`,{className:`hint`,children:[`可直接输入 IP:端口,系统会自动补全为 http://IP:端口/codex/v1。当前将写入:`,(0,b.jsx)(`code`,{children:Z||`-`})]}),(0,b.jsxs)(`div`,{className:`codex-provider-meta-strip`,children:[(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`span`,{children:`配置文件`}),(0,b.jsx)(`code`,{children:e.config?.codex.gatewayProvider.path||`~/.codex/config.toml`})]}),(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`span`,{children:`当前 provider`}),(0,b.jsx)(`code`,{children:Q||`未写入 AI Zero Token provider`})]}),(0,b.jsxs)(`div`,{className:`is-warning`,children:[(0,b.jsx)(`span`,{children:`远程网关提示`}),(0,b.jsx)(`strong`,{children:`远程请求会消耗对方网关机器上保存的账号额度。`})]})]})]}),(0,b.jsxs)(`section`,{className:`settings-section`,children:[(0,b.jsx)(`h4`,{children:`模型`}),(0,b.jsxs)(`label`,{className:`field`,children:[(0,b.jsx)(`span`,{children:`默认文本模型`}),(0,b.jsx)(`select`,{className:`control`,value:t.defaultModel,onChange:e=>F({defaultModel:e.target.value}),children:(e.config?.models||[]).map(e=>(0,b.jsx)(`option`,{value:e.id,children:e.id},e.id))})]}),(0,b.jsxs)(`p`,{className:`hint`,children:[`模型列表来源:`,e.config?.modelCatalog.source||`-`,`,共 `,e.config?.modelCatalog.modelCount||0,` 个。`]})]}),(0,b.jsxs)(`section`,{className:`settings-section`,children:[(0,b.jsx)(`h4`,{children:`上游代理`}),(0,b.jsxs)(`label`,{className:`switch-line`,children:[(0,b.jsx)(`input`,{type:`checkbox`,checked:t.proxyEnabled,onChange:e=>F({proxyEnabled:e.target.checked})}),(0,b.jsx)(`span`,{children:`启用 OAuth、模型刷新和接口转发代理`})]}),(0,b.jsxs)(`label`,{className:`field`,children:[(0,b.jsx)(`span`,{children:`代理地址`}),(0,b.jsx)(`input`,{className:`input`,value:t.proxyUrl,onChange:e=>F({proxyUrl:e.target.value}),placeholder:`http://127.0.0.1:7890`})]}),(0,b.jsxs)(`label`,{className:`field`,children:[(0,b.jsx)(`span`,{children:`No Proxy`}),(0,b.jsx)(`input`,{className:`input`,value:t.proxyNoProxy,onChange:e=>F({proxyNoProxy:e.target.value})})]}),(0,b.jsx)(`button`,{className:`btn-secondary`,type:`button`,onClick:W,disabled:e.busy===`proxy`,children:`测试代理`})]}),(0,b.jsxs)(`section`,{className:`settings-section`,children:[(0,b.jsx)(`h4`,{children:`端口`}),(0,b.jsxs)(`label`,{className:`field`,children:[(0,b.jsx)(`span`,{children:`网关端口`}),(0,b.jsx)(`input`,{className:`input`,inputMode:`numeric`,type:`number`,min:1,max:65535,value:t.serverPort,onChange:e=>F({serverPort:e.target.value})})]}),(0,b.jsx)(`p`,{className:`hint`,children:`修改后重启本地网关生效,桌面窗口不会退出。若端口被占用,启动时会自动顺延到下一个可用端口。`})]}),(0,b.jsxs)(`section`,{className:`settings-section`,children:[(0,b.jsx)(`h4`,{children:`账号运行策略`}),(0,b.jsxs)(`label`,{className:`switch-line`,children:[(0,b.jsx)(`input`,{type:`checkbox`,checked:t.autoSwitchEnabled,onChange:e=>F({autoSwitchEnabled:e.target.checked})}),(0,b.jsx)(`span`,{children:`当前 API 账号额度耗尽后自动切换到下一个仍有额度的账号`})]}),(0,b.jsxs)(`label`,{className:`field`,children:[(0,b.jsx)(`span`,{children:`全局额度刷新并发数`}),(0,b.jsx)(`input`,{className:`input`,inputMode:`numeric`,max:32,min:1,type:`number`,value:t.quotaSyncConcurrency,onChange:e=>F({quotaSyncConcurrency:e.target.value})})]}),(0,b.jsx)(`p`,{className:`hint`,children:`手动刷新全部账号额度时使用,默认 16。账号很多可以调高,遇到限流或失败增多时调低。`}),(0,b.jsx)(`p`,{className:`hint`,children:e.status})]}),(0,b.jsxs)(`section`,{className:`settings-section auto-switch-exclusion-section`,children:[(0,b.jsxs)(`div`,{className:`auto-switch-exclusion-head`,children:[(0,b.jsxs)(`div`,{children:[(0,b.jsx)(`h4`,{children:`不参与自动轮换名单`}),(0,b.jsx)(`p`,{className:`hint`,children:`这些账号不会被自动切换选中,也不会在自己额度耗尽时触发自动切走;仍可在账号页手动应用到网关或 Codex。`})]}),(0,b.jsxs)(`div`,{className:`auto-switch-counts`,"aria-label":`自动轮换账号统计`,children:[(0,b.jsxs)(`span`,{className:`count-pill is-included`,children:[`参与 `,H,` 个`]}),(0,b.jsxs)(`span`,{className:`count-pill is-excluded`,children:[`不参与 `,V,` 个`]})]})]}),(0,b.jsxs)(`label`,{className:`auto-switch-search`,children:[(0,b.jsx)(o,{size:16}),(0,b.jsx)(`input`,{value:M,onChange:e=>N(e.target.value),placeholder:`搜索邮箱、账号 ID 或 Profile ID`})]}),(0,b.jsx)(`div`,{className:`auto-switch-profile-list`,children:z.length===0?(0,b.jsx)(`div`,{className:`auto-switch-empty`,children:`还没有匹配的账号。`}):z.map(t=>{let n=R.has(t.profileId),r=s(t),i=!!(e.config?.codex.accountId&&e.config.codex.accountId===t.accountId),a=u(t)?`登录不可用`:d(t)?`额度耗尽`:``;return(0,b.jsxs)(`label`,{className:`auto-switch-profile-row ${n?`is-excluded`:``}`,children:[(0,b.jsx)(`input`,{type:`checkbox`,checked:n,onChange:e=>I(t.profileId,e.target.checked)}),(0,b.jsxs)(`span`,{className:`auto-switch-profile-main`,children:[(0,b.jsx)(`strong`,{children:l(t,e.showEmails)}),(0,b.jsxs)(`span`,{children:[c(t),` · `,r.label,t.isActive?` · 当前 API 使用中`:``,i?` · Codex 使用中`:``,a?` · ${a}`:``]})]}),(0,b.jsx)(`span`,{className:`auto-switch-state-pill ${n?`is-excluded`:`is-included`}`,children:n?`不参与轮换`:`参与轮换`})]},t.profileId)})})]}),(0,b.jsxs)(`section`,{className:`settings-section`,children:[(0,b.jsx)(`h4`,{children:`显示`}),(0,b.jsxs)(`label`,{className:`switch-line`,children:[(0,b.jsx)(`input`,{type:`checkbox`,checked:e.showEmails,onChange:t=>e.setShowEmails(t.target.checked)}),(0,b.jsx)(`span`,{children:`脱敏模式`})]}),(0,b.jsx)(`p`,{className:`hint`,children:`开启后账号邮箱将以脱敏形式展示。`})]})]}),(0,b.jsxs)(`div`,{className:`settings-page-actions settings-page-footer-actions`,children:[(0,b.jsx)(`button`,{className:`btn-secondary`,type:`button`,onClick:()=>void U(),disabled:e.busy===`settings`||e.busy===`restart`||!P,children:`保存设置`}),(0,b.jsx)(`button`,{className:`btn-primary`,type:`button`,onClick:()=>void U({restart:!0}),disabled:e.busy===`settings`||e.busy===`restart`||!P||!e.config?.restartSupported,children:`保存并重启网关`})]})]})}export{T as SettingsPage};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{a as e,n as t,r as n,t as r}from"./jsx-runtime-DqpGtLhh.js";import{t as i}from"./upload-CwXb7Q1b.js";import{t as a}from"./zap-B4_oDbCp.js";import{S as o,m as s,w as c,x as l}from"./profiles-DMOjJORP.js";import{_ as u,a as d,b as f,c as p,i as m,l as h,n as g,o as _,p as v,r as y,s as b,t as x,u as S}from"./index
|
|
1
|
+
import{a as e,n as t,r as n,t as r}from"./jsx-runtime-DqpGtLhh.js";import{t as i}from"./upload-CwXb7Q1b.js";import{t as a}from"./zap-B4_oDbCp.js";import{S as o,m as s,w as c,x as l}from"./profiles-DMOjJORP.js";import{_ as u,a as d,b as f,c as p,i as m,l as h,n as g,o as _,p as v,r as y,s as b,t as x,u as S}from"./index--rNjdmzf.js";var C=t(`rotate-ccw`,[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`,key:`1357e3`}],[`path`,{d:`M3 3v5h5`,key:`1xhq8a`}]]),w=e(n(),1),T=r();function E(e){let t=e.endpoint.startsWith(`/v1/images/`);function n(t){let n=t.currentTarget.files?.[0];t.currentTarget.value=``,n&&e.onImageUpload(n,e.imageUploadMode).catch(()=>void 0)}return(0,T.jsxs)(`section`,{className:`card tester-card`,id:`tester`,children:[(0,T.jsxs)(`div`,{className:`section-head compact`,children:[(0,T.jsxs)(`div`,{children:[(0,T.jsx)(`h2`,{children:`快速测试`}),(0,T.jsx)(`p`,{children:`页面直接调用当前网关暴露的 OpenAI 风格接口。`})]}),(0,T.jsx)(`span`,{className:`badge brand`,children:e.busy===`test`?`请求中`:`准备就绪`})]}),(0,T.jsx)(`div`,{className:`tester-tabs`,children:e.endpoints.map(t=>(0,T.jsx)(`button`,{className:`tab-btn ${e.endpoint===t.path?`is-active`:``}`,type:`button`,onClick:()=>e.onEndpoint(t.path),children:S[t.path]||t.path},t.path))}),(0,T.jsxs)(`div`,{className:`tester-workbench`,children:[(0,T.jsxs)(`div`,{className:`tester-pane tester-request-pane`,children:[(0,T.jsxs)(`label`,{className:`field`,children:[(0,T.jsx)(`span`,{children:`接口`}),(0,T.jsx)(`select`,{className:`control`,value:e.endpoint,onChange:t=>e.onEndpoint(t.target.value),children:e.endpoints.map(e=>(0,T.jsxs)(`option`,{value:e.path,children:[e.method,` `,e.path]},e.path))})]}),(0,T.jsxs)(`div`,{className:`tester-copy-row tester-copy-row-top`,children:[(0,T.jsxs)(`button`,{className:`btn-secondary`,type:`button`,onClick:e.onCopyRequest,children:[(0,T.jsx)(f,{size:16}),`复制请求`]}),(0,T.jsxs)(`button`,{className:`btn-secondary`,type:`button`,onClick:e.onCopyResponse,children:[(0,T.jsx)(f,{size:16}),`复制响应`]}),(0,T.jsxs)(`button`,{className:`btn-secondary`,type:`button`,onClick:e.onCopyTiming,children:[(0,T.jsx)(f,{size:16}),`复制日志`]}),(0,T.jsxs)(`button`,{className:`btn-secondary`,type:`button`,onClick:e.onResetExample,children:[(0,T.jsx)(C,{size:16}),`重置示例`]})]}),(0,T.jsxs)(`label`,{className:`field tester-body-field`,children:[(0,T.jsx)(`span`,{children:`请求体 JSON`}),(0,T.jsx)(`textarea`,{className:`textarea tester-textarea`,value:e.requestBody,onChange:t=>e.onRequestBody(t.target.value),disabled:e.activeEndpoint.method===`GET`,spellCheck:!1})]}),e.endpoint===`/v1/images/edits`&&(0,T.jsxs)(`div`,{className:`edit-upload-row`,children:[(0,T.jsxs)(`div`,{className:`edit-upload-mode`,role:`group`,"aria-label":`图片写入方式`,children:[(0,T.jsx)(`span`,{children:`写入方式`}),(0,T.jsxs)(`div`,{className:`edit-upload-toggle`,children:[(0,T.jsx)(`button`,{className:`tab-btn ${e.imageUploadMode===`base64`?`is-active`:``}`,type:`button`,onClick:()=>e.onImageUploadMode(`base64`),children:`Base64`}),(0,T.jsx)(`button`,{className:`tab-btn ${e.imageUploadMode===`image-bed`?`is-active`:``}`,type:`button`,onClick:()=>e.onImageUploadMode(`image-bed`),children:`图床`})]})]}),(0,T.jsxs)(`label`,{className:`btn-secondary upload-btn`,title:e.imageUploadMode===`base64`?`上传图片并写入 base64 data URL`:`上传图片到图床并写入公网链接`,children:[e.imageUploadMode===`image-bed`&&e.busy===`image-bed-upload`?(0,T.jsx)(u,{className:`spin`,size:16}):(0,T.jsx)(i,{size:16}),e.imageUploadMode===`base64`?`上传并写入 Base64`:`上传并写入图床链接`,(0,T.jsx)(`input`,{type:`file`,accept:`image/*`,onChange:n})]}),(0,T.jsxs)(`span`,{children:[`目标字段:images[0].image_url · `,e.imageUploadMode===`base64`?`直接写入 data URL`:`先上传图床再写入公网链接`]})]}),(0,T.jsx)(`p`,{className:`hint`,children:t?e.capability.detail:e.activeEndpoint.description||`GET /v1/models 无需请求体。`}),(0,T.jsxs)(`div`,{className:`tester-actions-bar`,children:[(0,T.jsx)(`div`,{className:`tester-actions-group`,children:(0,T.jsx)(`div`,{className:`example-row`,children:p.map(t=>(0,T.jsxs)(`button`,{className:`btn-secondary`,type:`button`,onClick:()=>e.onEndpoint(t),disabled:!e.endpoints.some(e=>e.path===t),children:[`示例 `,S[t]||t]},t))})}),(0,T.jsxs)(`button`,{className:`btn-primary`,type:`button`,onClick:e.onRun,disabled:e.busy===`test`||t&&!e.config?.profile,children:[e.busy===`test`?(0,T.jsx)(u,{className:`spin`,size:16}):(0,T.jsx)(a,{size:16}),`发送请求`]})]})]}),(0,T.jsxs)(`div`,{className:`tester-pane tester-response-pane`,children:[(0,T.jsxs)(`div`,{className:`tester-result-head`,children:[(0,T.jsxs)(`div`,{className:`tester-result-tabs`,children:[(0,T.jsx)(`button`,{className:`tab-btn ${e.resultTab===`response`?`is-active`:``}`,type:`button`,onClick:()=>e.onResultTab(`response`),children:`响应 JSON`}),(0,T.jsx)(`button`,{className:`tab-btn ${e.resultTab===`timing`?`is-active`:``}`,type:`button`,onClick:()=>e.onResultTab(`timing`),children:`耗时日志`}),(0,T.jsx)(`button`,{className:`tab-btn ${e.resultTab===`preview`?`is-active`:``}`,type:`button`,onClick:()=>e.onResultTab(`preview`),children:`图片预览`})]}),(0,T.jsx)(`p`,{className:`status-inline`,children:e.status})]}),e.resultTab===`response`&&(0,T.jsx)(`pre`,{className:`pre`,children:e.responseBody}),e.resultTab===`timing`&&(0,T.jsx)(`pre`,{className:`pre`,children:e.timingBody}),e.resultTab===`preview`&&(0,T.jsx)(`div`,{className:`preview-panel`,children:e.previewImages.length===0?(0,T.jsx)(`div`,{className:`preview-empty`,children:`图片结果会显示在这里。点击缩略图可查看大图。`}):(0,T.jsx)(`div`,{className:`preview-grid`,children:e.previewImages.map(t=>(0,T.jsxs)(`figure`,{className:`preview-card`,children:[(0,T.jsx)(`button`,{type:`button`,onClick:()=>e.onPreview({src:t.src,meta:t.meta,filename:t.filename}),children:(0,T.jsx)(`img`,{src:t.src,alt:t.meta})}),(0,T.jsx)(`figcaption`,{children:t.meta}),(0,T.jsx)(`div`,{className:`preview-actions`,children:(0,T.jsx)(`a`,{href:t.src,download:t.filename,children:`下载`})})]},t.filename))})})]})]})]})}function D(e){let[t,n]=(0,w.useState)(`/v1/models`),[r,i]=(0,w.useState)(``),[a,u]=(0,w.useState)(`等待请求...`),[f,S]=(0,w.useState)(`等待请求...`),[C,D]=(0,w.useState)(`response`),[O,k]=(0,w.useState)([]),[A,j]=(0,w.useState)(`base64`),M=(0,w.useMemo)(()=>[...e.config?.supportedEndpoints||[]].sort(h),[e.config?.supportedEndpoints]),N=(0,w.useMemo)(()=>M.find(e=>e.path===t)||M[0]||{method:`GET`,path:`/v1/models`,description:``},[t,M]);(0,w.useEffect)(()=>{if(!e.config)return;let r=p.find(t=>e.config?.supportedEndpoints.some(e=>e.path===t)),a=e.config.supportedEndpoints.some(e=>e.path===t)?t:r||`/v1/models`;n(a),i(x(a,e.config.settings.defaultModel))},[e.config]);function P(t){n(t),i(x(t,e.config?.settings.defaultModel||`gpt-5.4`)),k([])}function F(){P(t)}function I(){g(r||x(t,e.config?.settings.defaultModel||`gpt-5.4`)).then(t=>e.setStatus(t?`请求体已复制。`:`请求体复制失败。`)).catch(()=>e.setStatus(`请求体复制失败。`))}function L(){g(a).then(t=>e.setStatus(t?`响应内容已复制。`:`响应内容复制失败。`)).catch(()=>e.setStatus(`响应内容复制失败。`))}function R(){g(f).then(t=>e.setStatus(t?`耗时日志已复制。`:`耗时日志复制失败。`)).catch(()=>e.setStatus(`耗时日志复制失败。`))}async function z(){let t=N,n=performance.now(),i=[];e.setBusy(`test`),D(`response`),u(`请求发送中...`),S(`请求发送中...`),k([]);try{let a=null,o={method:t.method,headers:{}};if(t.method!==`GET`){let e=performance.now();a=r.trim()?JSON.parse(r):{},i.push(`解析请求体: ${l(performance.now()-e)}`),o.headers[`Content-Type`]=`application/json`,o.body=c(a)}let d=performance.now(),f=await fetch(t.path,o);i.push(`等待响应头: ${l(performance.now()-d)}`);let p=performance.now(),h=await f.text();i.push(`读取响应体: ${l(performance.now()-p)}`);let g=performance.now(),_=h;try{_=h?JSON.parse(h):null}catch{_=h}i.push(`解析响应体: ${l(performance.now()-g)}`);let v=m(_);k(v),v.length>0&&D(`preview`),u(typeof _==`string`?_:c(b(_))),S([`${t.method} ${t.path}`,`HTTP 状态: ${f.status} ${f.statusText}`,...i].join(`
|
|
2
2
|
`)),e.setStatus(`${f.ok?`成功`:`失败`}: HTTP ${f.status} ${t.method} ${t.path}`),e.setRequestLogs(r=>[{id:crypto.randomUUID(),time:Date.now(),method:t.method,endpoint:t.path,account:s(e.config?.profile,e.showEmails),model:typeof a==`object`&&a&&`model`in a?String(a.model||e.config?.settings.defaultModel||`-`):e.config?.settings.defaultModel||`-`,statusCode:f.status,durationMs:performance.now()-n,source:`管理台`},...r].slice(0,20)),e.config?.profile&&e.refreshConfig({silent:!0}).catch(()=>void 0)}catch(n){let r=y(n);u(r),S([`${t.method} ${t.path}(失败)`,...i,`错误: ${r}`].join(`
|
|
3
3
|
`)),e.setStatus(`请求失败。`)}finally{e.setBusy(null)}}async function B(t,n){if(!t.type.startsWith(`image/`)){e.setStatus(`请选择图片文件。`);return}try{if(n===`image-bed`){e.setBusy(`image-bed-upload`);let n=await _(t);i(d(r,(await v(`/_gateway/image-bed/upload`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({filename:t.name,dataUrl:n})})).url,e.config?.settings.defaultModel||`gpt-image-2`)),e.setStatus(`已上传到图床并写入公网链接(${t.name},${o(t.size)})。`);return}i(d(r,await _(t),e.config?.settings.defaultModel||`gpt-image-2`)),e.setStatus(`已将 ${t.name} 转成 base64 data URL,并写入请求体 images[0].image_url(${o(t.size)})。`)}catch(t){e.setStatus(`图片写入失败: ${y(t)}`)}finally{n===`image-bed`&&e.setBusy(null)}}return(0,T.jsx)(E,{config:e.config,endpoints:M,activeEndpoint:N,endpoint:t,requestBody:r,responseBody:a,timingBody:f,resultTab:C,status:e.status,busy:e.busy,previewImages:O,capability:e.capability,imageUploadMode:A,onEndpoint:P,onRequestBody:i,onResultTab:D,onRun:z,onResetExample:F,onCopyRequest:I,onCopyResponse:L,onCopyTiming:R,onImageUploadMode:j,onPreview:e.setPreviewImage,onImageUpload:B})}export{D as TesterPage};
|