@lynn123411/dsh-a6api 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js ADDED
@@ -0,0 +1,2462 @@
1
+ window.__ModuleLoader__.load({ id: "@lynn123411/dsh-a6api", factory: (require) => { var module = { exports: {} }; var exports = module.exports;
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name2 in all)
9
+ __defProp(target, name2, { get: all[name2], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/client/index.ts
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ apply: () => apply,
25
+ inject: () => inject,
26
+ name: () => name
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+
30
+ // src/client/components/A6ApiSettings.tsx
31
+ var import_react4 = require("react");
32
+
33
+ // src/client/store.ts
34
+ var A6ApiStore = class {
35
+ state = {
36
+ loading: true,
37
+ config: {
38
+ baseURL: "https://api.a6api.com",
39
+ apiKey: "",
40
+ userId: "",
41
+ activeModels: []
42
+ },
43
+ balance: null,
44
+ models: [],
45
+ dshConfiguredModels: [],
46
+ recentLogs: [],
47
+ probingModelNames: /* @__PURE__ */ new Set(),
48
+ error: null
49
+ };
50
+ listeners = /* @__PURE__ */ new Set();
51
+ autoRefreshTimer = null;
52
+ constructor() {
53
+ this.startAutoRefresh();
54
+ }
55
+ subscribe(listener) {
56
+ this.listeners.add(listener);
57
+ return () => this.listeners.delete(listener);
58
+ }
59
+ notify() {
60
+ for (const l of this.listeners) {
61
+ try {
62
+ l();
63
+ } catch (err) {
64
+ console.error("[dsh-a6api] listener error:", err);
65
+ }
66
+ }
67
+ }
68
+ getState() {
69
+ return this.state;
70
+ }
71
+ async fetchState() {
72
+ this.state.loading = true;
73
+ this.notify();
74
+ try {
75
+ const res = await fetch("/api/dsh-a6api/state");
76
+ if (res.ok) {
77
+ const json = await res.json();
78
+ if (json?.data) {
79
+ const data = json.data;
80
+ this.state.config = data.config;
81
+ this.state.balance = data.balance;
82
+ this.state.models = data.models;
83
+ this.state.dshConfiguredModels = data.dshConfiguredModels;
84
+ if (data.recentLogs) {
85
+ this.state.recentLogs = data.recentLogs;
86
+ }
87
+ this.state.error = null;
88
+ }
89
+ }
90
+ } catch (err) {
91
+ this.state.error = err?.message || String(err);
92
+ } finally {
93
+ this.state.loading = false;
94
+ this.notify();
95
+ }
96
+ }
97
+ async saveConfig(config) {
98
+ try {
99
+ const res = await fetch("/api/dsh-a6api/config", {
100
+ method: "POST",
101
+ headers: { "Content-Type": "application/json" },
102
+ body: JSON.stringify(config)
103
+ });
104
+ if (res.ok) {
105
+ await this.fetchState();
106
+ return true;
107
+ }
108
+ } catch (err) {
109
+ this.state.error = err?.message || String(err);
110
+ this.notify();
111
+ }
112
+ return false;
113
+ }
114
+ async refreshBalance() {
115
+ try {
116
+ const res = await fetch("/api/dsh-a6api/balance");
117
+ if (res.ok) {
118
+ const json = await res.json();
119
+ if (json?.balance) {
120
+ this.state.balance = json.balance;
121
+ }
122
+ if (json?.recentLogs) {
123
+ this.state.recentLogs = json.recentLogs;
124
+ }
125
+ this.notify();
126
+ }
127
+ } catch {
128
+ }
129
+ }
130
+ async probeModel(modelName) {
131
+ this.state.probingModelNames.add(modelName);
132
+ this.state.models = this.state.models.map(
133
+ (m) => m.model_name === modelName ? { ...m, probeStatus: "probing" } : m
134
+ );
135
+ this.notify();
136
+ try {
137
+ const res = await fetch("/api/dsh-a6api/probe", {
138
+ method: "POST",
139
+ headers: { "Content-Type": "application/json" },
140
+ body: JSON.stringify({ modelName })
141
+ });
142
+ if (res.ok) {
143
+ const json = await res.json();
144
+ if (json?.result?.merchant) {
145
+ this.state.models = this.state.models.map(
146
+ (m) => m.model_name === modelName ? {
147
+ ...m,
148
+ merchant: json.result.merchant,
149
+ probeStatus: "success",
150
+ probeLatencyMs: json.result.durationMs,
151
+ probeError: void 0,
152
+ lastProbedAt: Date.now()
153
+ } : m
154
+ );
155
+ } else if (json?.result?.error) {
156
+ this.state.models = this.state.models.map(
157
+ (m) => m.model_name === modelName ? {
158
+ ...m,
159
+ probeStatus: "error",
160
+ probeError: json.result.error,
161
+ lastProbedAt: Date.now()
162
+ } : m
163
+ );
164
+ } else {
165
+ this.state.models = this.state.models.map(
166
+ (m) => m.model_name === modelName ? {
167
+ ...m,
168
+ probeStatus: json?.result?.success ? "success" : "idle",
169
+ probeLatencyMs: json?.result?.durationMs,
170
+ probeError: void 0,
171
+ lastProbedAt: Date.now()
172
+ } : m
173
+ );
174
+ }
175
+ } else {
176
+ this.state.models = this.state.models.map(
177
+ (m) => m.model_name === modelName ? {
178
+ ...m,
179
+ probeStatus: "error",
180
+ probeError: `HTTP ${res.status}`,
181
+ lastProbedAt: Date.now()
182
+ } : m
183
+ );
184
+ }
185
+ } catch (err) {
186
+ this.state.models = this.state.models.map(
187
+ (m) => m.model_name === modelName ? {
188
+ ...m,
189
+ probeStatus: "error",
190
+ probeError: err?.message || String(err),
191
+ lastProbedAt: Date.now()
192
+ } : m
193
+ );
194
+ } finally {
195
+ this.state.probingModelNames.delete(modelName);
196
+ this.notify();
197
+ this.refreshBalance().catch(() => {
198
+ });
199
+ }
200
+ }
201
+ async probeAll() {
202
+ const allNames = this.state.models.map((m) => m.model_name);
203
+ for (const name2 of allNames) {
204
+ await this.probeModel(name2);
205
+ }
206
+ }
207
+ async toggleDshModel(modelName) {
208
+ const currentSet = new Set(this.state.dshConfiguredModels);
209
+ if (currentSet.has(modelName)) {
210
+ currentSet.delete(modelName);
211
+ } else {
212
+ currentSet.add(modelName);
213
+ }
214
+ const newModels = [...currentSet];
215
+ try {
216
+ const res = await fetch("/api/dsh-a6api/sync-models", {
217
+ method: "POST",
218
+ headers: { "Content-Type": "application/json" },
219
+ body: JSON.stringify({ modelIds: newModels })
220
+ });
221
+ if (res.ok) {
222
+ const json = await res.json();
223
+ this.state.dshConfiguredModels = json.dshConfiguredModels || newModels;
224
+ const dshSet = new Set(this.state.dshConfiguredModels);
225
+ this.state.models = this.state.models.map((m) => ({
226
+ ...m,
227
+ inDsh: dshSet.has(m.model_name)
228
+ }));
229
+ this.notify();
230
+ }
231
+ } catch (err) {
232
+ this.state.error = err?.message || String(err);
233
+ this.notify();
234
+ }
235
+ }
236
+ startAutoRefresh() {
237
+ if (this.autoRefreshTimer) clearInterval(this.autoRefreshTimer);
238
+ this.autoRefreshTimer = setInterval(() => {
239
+ this.refreshBalance().catch(() => {
240
+ });
241
+ }, 6e4);
242
+ }
243
+ };
244
+ var store = new A6ApiStore();
245
+
246
+ // src/client/components/MerchantCard.tsx
247
+ var import_react = require("react");
248
+ var import_jsx_runtime = require("react/jsx-runtime");
249
+ var MerchantCard = ({ model }) => {
250
+ const [expanded, setExpanded] = (0, import_react.useState)(false);
251
+ const isProbing = model.probeStatus === "probing";
252
+ const merchant = model.merchant;
253
+ const handleProbe = (e) => {
254
+ e.stopPropagation();
255
+ store.probeModel(model.model_name);
256
+ };
257
+ const handleToggleDsh = (e) => {
258
+ e.stopPropagation();
259
+ store.toggleDshModel(model.model_name);
260
+ };
261
+ const renderRealtimeDots = () => {
262
+ if (merchant?.success_buckets && merchant.success_buckets.length > 0) {
263
+ return merchant.success_buckets.slice(0, 10).map((b, i) => {
264
+ const rate = b.success_rate;
265
+ let colorClass = "green";
266
+ if (rate < 8e3) colorClass = "red";
267
+ else if (rate < 9500) colorClass = "yellow";
268
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `dsh-a6-rate-dot ${colorClass}` }, i);
269
+ });
270
+ }
271
+ const count = 10;
272
+ const greenCount = merchant ? Math.round(merchant.recent_success_rate_pct / 100 * count) : 10;
273
+ return Array.from({ length: count }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `dsh-a6-rate-dot ${i < greenCount ? "green" : "empty"}` }, i));
274
+ };
275
+ const render24hDots = () => {
276
+ if (merchant?.b24 && merchant.b24.length > 0) {
277
+ return merchant.b24.slice(0, 12).map((b, i) => {
278
+ if (!b.s || b.s === 0) {
279
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-rate-dot empty" }, i);
280
+ }
281
+ let colorClass = "green";
282
+ if (b.r < 8e3) colorClass = "red";
283
+ else if (b.r < 9500) colorClass = "yellow";
284
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `dsh-a6-rate-dot ${colorClass}` }, i);
285
+ });
286
+ }
287
+ const count = 12;
288
+ const greenCount = merchant ? Math.round(merchant.success_rate_24h_pct / 100 * count) : 12;
289
+ return Array.from({ length: count }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `dsh-a6-rate-dot ${i < greenCount ? "green" : "empty"}` }, i));
290
+ };
291
+ const render7dDots = () => {
292
+ if (merchant?.b7d && merchant.b7d.length > 0) {
293
+ return merchant.b7d.slice(0, 7).map((b, i) => {
294
+ if (!b.s || b.s === 0) {
295
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-rate-dot empty" }, i);
296
+ }
297
+ let colorClass = "green";
298
+ if (b.r && b.r < 8e3) colorClass = "red";
299
+ else if (b.r && b.r < 9500) colorClass = "yellow";
300
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `dsh-a6-rate-dot ${colorClass}` }, i);
301
+ });
302
+ }
303
+ return Array.from({ length: 7 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `dsh-a6-rate-dot ${i >= 4 ? "green" : "empty"}` }, i));
304
+ };
305
+ const getTagClass = (tag) => {
306
+ if (tag.includes("\u4FDD\u771F")) return "tag-guarantee";
307
+ if (tag.includes("\u7A33\u5B9A")) return "tag-stable";
308
+ if (tag.includes("\u4F4E\u4EF7")) return "tag-cheap";
309
+ if (tag.includes("\u9AD8\u901F")) return "tag-fast";
310
+ if (tag.includes("\u9AD8\u8D28")) return "tag-quality";
311
+ return "";
312
+ };
313
+ const ratioText = merchant?.realtime_ratio_formatted || "0.0341";
314
+ const latencySec = merchant ? ((merchant.p50_ttft_ms || merchant.recent_p50_ms || 2340) / 1e3).toFixed(2) + "s" : model.probeLatencyMs ? (model.probeLatencyMs / 1e3).toFixed(2) + "s" : "2.34s";
315
+ const cacheHitPct = merchant ? merchant.cache_hit_rate_pct : 72;
316
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `dsh-a6-official-card ${model.inDsh ? "in-dsh" : ""}`, children: [
317
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-card-main-bar", onClick: () => setExpanded(!expanded), children: [
318
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-identity", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-title-col", children: [
319
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-title-line", children: [
320
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-name-text", children: model.model_name }),
321
+ merchant?.channel_id && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
322
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-dot-sep", children: "\xB7" }),
323
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dsh-a6-merchant-id-text", children: [
324
+ "\u5546\u6237ID ",
325
+ merchant.channel_id
326
+ ] })
327
+ ] })
328
+ ] }),
329
+ merchant?.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-sub-desc", children: merchant.description })
330
+ ] }) }),
331
+ merchant ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-bar-pricing", children: [
332
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-price-col", children: [
333
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-price-top", title: "\u8F93\u5165\u4EF7 (1M)", children: merchant.input_price_cny }),
334
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-price-btm", title: "\u7F13\u5B58\u8BFB (1M)", children: merchant.cache_read_price_cny })
335
+ ] }),
336
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-price-col", children: [
337
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-price-top", title: "\u8F93\u51FA\u4EF7 (1M)", children: merchant.output_price_cny }),
338
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-price-btm", title: "\u7F13\u5B58\u5199 (1M)", children: merchant.cache_write_price_cny })
339
+ ] }),
340
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-ratio-pill", title: "\u5B9E\u65F6\u500D\u7387\u6BD4\u5B98\u65B9\u4EF7", children: ratioText })
341
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-pricing unprobed", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-unprobed-hint", children: isProbing ? "\u5546\u5BB6\u63A2\u6D4B\u4E2D..." : "\u5C1A\u672A\u63A2\u6D4B\u5546\u5BB6" }) }),
342
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-bar-uptime", children: [
343
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-uptime-row", children: [
344
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-label", children: "\u5B9E\u65F6" }),
345
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-dots-track", children: renderRealtimeDots() }),
346
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-val", children: merchant ? `${merchant.recent_success_rate_pct.toFixed(1)}%` : "100.0%" })
347
+ ] }),
348
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-uptime-row", children: [
349
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-label", children: "24h" }),
350
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-dots-track", children: render24hDots() }),
351
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-val", children: merchant ? `${merchant.success_rate_24h_pct.toFixed(1)}%` : "99.3%" })
352
+ ] }),
353
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-uptime-row", children: [
354
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-label", children: "7d" }),
355
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-dots-track", children: render7dDots() }),
356
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-uptime-val", children: merchant?.sr_7d_state === "no_data" ? "-" : merchant?.success_rate_7d_pct ? `${merchant.success_rate_7d_pct.toFixed(1)}%` : "-" })
357
+ ] })
358
+ ] }),
359
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-perf", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-perf-row", children: [
360
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-latency-text", children: latencySec }),
361
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dsh-a6-cache-hit-text", children: [
362
+ cacheHitPct.toFixed(1),
363
+ "%"
364
+ ] }),
365
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-hit-track", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
366
+ "div",
367
+ {
368
+ className: "dsh-a6-hit-fill",
369
+ style: { width: `${Math.min(100, Math.max(0, cacheHitPct))}%` }
370
+ }
371
+ ) })
372
+ ] }) }),
373
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-bar-tags", children: (merchant?.labels || ["\u7A33\u5B9A", "\u4F4E\u4EF7", "\u9AD8\u901F", "\u9AD8\u8D28"]).map((lbl, idx) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: `dsh-a6-smart-pill ${getTagClass(lbl)}`, children: lbl }, idx)) }),
374
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-bar-actions", onClick: (e) => e.stopPropagation(), children: [
375
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
376
+ "span",
377
+ {
378
+ className: "dsh-a6-time-ago",
379
+ "data-tooltip": "\u8BE5\u5546\u6237\u8DEF\u7EBF\u5168\u7F51\u6700\u8FD1\u4E00\u6B21\u6210\u529F\u54CD\u5E94\u65F6\u95F4",
380
+ children: merchant?.last_success_text || "\u521A\u521A"
381
+ }
382
+ ),
383
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
384
+ "button",
385
+ {
386
+ type: "button",
387
+ className: "dsh-a6-btn dsh-a6-btn-secondary dsh-a6-btn-sm",
388
+ onClick: handleProbe,
389
+ disabled: isProbing,
390
+ "data-tooltip": "\u5411\u8BE5\u6A21\u578B\u53D1\u9001\u4E00\u6B21\u8BF7\u6C42\u4EE5\u63A2\u6D4B\u5E76\u6355\u83B7\u5176\u5B9E\u9645\u547D\u4E2D\u7684\u5546\u6237 ID\u3001\u4EF7\u683C\u53CA\u5065\u5EB7\u5EA6\u6307\u6807\uFF08\u6D88\u8017\u5C11\u91CFToken\uFF09",
391
+ children: isProbing ? "\u63A2\u6D4B\u4E2D..." : "\u63A2\u6D4B\u5546\u5BB6"
392
+ }
393
+ ),
394
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
395
+ "button",
396
+ {
397
+ type: "button",
398
+ className: `dsh-a6-btn dsh-a6-btn-sm ${model.inDsh ? "dsh-a6-btn-in-dsh" : "dsh-a6-btn-primary"}`,
399
+ onClick: handleToggleDsh,
400
+ "data-tooltip": model.inDsh ? "\u5DF2\u52A0\u5165 DSH \u6A21\u578B\u9009\u62E9\u5668 (\u70B9\u51FB\u79FB\u9664)" : "\u6DFB\u52A0\u81F3 DSH \u6A21\u578B\u9009\u62E9\u5668",
401
+ children: model.inDsh ? "\u5DF2\u5728 DSH" : "\u6DFB\u52A0\u5230 DSH"
402
+ }
403
+ ),
404
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
405
+ "button",
406
+ {
407
+ type: "button",
408
+ className: `dsh-a6-expand-toggle-btn ${expanded ? "open" : ""}`,
409
+ onClick: () => setExpanded(!expanded),
410
+ "data-tooltip": expanded ? "\u6536\u8D77\u4EF7\u683C\u8BE6\u60C5" : "\u5C55\u5F00\u5B98\u65B9\u57FA\u51C6\u4EF7\u4E0E\u5546\u6237\u5B9E\u65F6\u4EF7\u5BF9\u6BD4\u8868",
411
+ "data-tooltip-pos": "left",
412
+ children: expanded ? "\u6536\u8D77" : "\u8BE6\u60C5"
413
+ }
414
+ )
415
+ ] })
416
+ ] }),
417
+ expanded && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-detail-container", children: [
418
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-detail-top-row", children: [
419
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-dt-left", children: [
420
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-dt-label", children: "\u6E20\u9053\u8BF4\u660E" }),
421
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-dt-desc", children: merchant?.description || "\u9AD8\u5E76\u53D1 \u4E3B\u6253\u4FBF\u5B9C \u7A33\u5B9A" })
422
+ ] }),
423
+ merchant?.channel_name && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-a6-dt-right", children: [
424
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-a6-dt-label", children: "\u547D\u4E2D\u7EBF\u8DEF" }),
425
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dsh-a6-dt-channel-name", children: [
426
+ merchant.channel_name,
427
+ " (ID: ",
428
+ merchant.channel_id,
429
+ ")"
430
+ ] })
431
+ ] })
432
+ ] }),
433
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-dt-divider" }),
434
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-a6-dt-table-col", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: "dsh-a6-price-table", children: [
435
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
436
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "dsh-a6-th-blank" }),
437
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u8F93\u5165\u4EF7 (1M)" }),
438
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u8F93\u51FA\u4EF7 (1M)" }),
439
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u7F13\u5B58\u8BFB (1M)" }),
440
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { children: "\u7F13\u5B58\u5199 (1M)" })
441
+ ] }) }),
442
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tbody", { children: [
443
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: "dsh-a6-tr-official", children: [
444
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-label", children: "\u5B98\u65B9\u4EF7" }),
445
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: merchant?.official_price?.input_cny || "\xA526.884" }),
446
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: merchant?.official_price?.output_cny || "\xA5134.418" }),
447
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: merchant?.official_price?.cache_read_cny || "\xA52.688" }),
448
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: merchant?.official_price?.cache_write_cny || "\xA533.605" })
449
+ ] }),
450
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { className: "dsh-a6-tr-merchant", children: [
451
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-label", children: "\u5546\u6237\u4EF7" }),
452
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-bold", children: merchant?.input_price_cny || "\xA50.1364" }),
453
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-bold", children: merchant?.output_price_cny || "\xA50.6822" }),
454
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-bold", children: merchant?.cache_read_price_cny || "\xA50.0136" }),
455
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "dsh-a6-td-bold", children: merchant?.cache_write_price_cny || "\xA50.1705" })
456
+ ] })
457
+ ] })
458
+ ] }) })
459
+ ] })
460
+ ] });
461
+ };
462
+
463
+ // src/client/components/BalanceCard.tsx
464
+ var import_react2 = require("react");
465
+ var import_jsx_runtime2 = require("react/jsx-runtime");
466
+ var AccountPanel = ({ balance, config, recentLogs = [], onNavigateToConfig }) => {
467
+ const [refreshing, setRefreshing] = (0, import_react2.useState)(false);
468
+ const handleRefreshBalance = async () => {
469
+ setRefreshing(true);
470
+ await store.refreshBalance();
471
+ setRefreshing(false);
472
+ };
473
+ const hasAuth = balance?.hasAccountAuth ?? false;
474
+ const isLow = balance ? balance.isLow : false;
475
+ const formatLogTime = (ts) => {
476
+ if (!ts) return "\u521A\u521A";
477
+ const d = new Date(ts * 1e3);
478
+ return `${d.getHours().toString().padStart(2, "0")}:${d.getMinutes().toString().padStart(2, "0")}:${d.getSeconds().toString().padStart(2, "0")}`;
479
+ };
480
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dsh-a6-account-page", children: [
481
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `dsh-a6-balance-banner ${isLow ? "low-balance" : ""}`, children: [
482
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dsh-a6-balance-header", children: [
483
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dsh-a6-balance-left", children: [
484
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dsh-a6-balance-main-title", children: [
485
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dsh-a6-balance-label", children: "\u8D26\u6237\u771F\u5B9E\u4F59\u989D (\u5B9E\u65F6\u540C\u6B65)" }),
486
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dsh-a6-balance-num-row", children: [
487
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `dsh-a6-balance-amount ${!hasAuth ? "unauthed" : ""}`, children: hasAuth ? balance?.accountBalanceFormatted ?? "$0.00" : "\u672A\u8FDE\u63A5" }),
488
+ hasAuth && balance?.accountBalanceCnyFormatted && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dsh-a6-balance-cny", children: balance.accountBalanceCnyFormatted }),
489
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `dsh-a6-status-pill ${hasAuth ? "success" : "warn"}`, children: hasAuth ? "\u8D26\u6237\u5DF2\u540C\u6B65" : "\u672A\u8FDE\u63A5\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C" })
490
+ ] })
491
+ ] }),
492
+ isLow && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dsh-a6-low-alert", children: "\u4F59\u989D\u8F83\u4F4E (< $0.50)\uFF0C\u5EFA\u8BAE\u53CA\u65F6\u5145\u503C\u4EE5\u4FDD\u969C\u6B63\u5E38\u8C03\u7528" })
493
+ ] }),
494
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dsh-a6-balance-actions", children: [
495
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
496
+ "button",
497
+ {
498
+ type: "button",
499
+ className: "dsh-a6-btn dsh-a6-btn-secondary dsh-a6-btn-sm",
500
+ onClick: handleRefreshBalance,
501
+ disabled: refreshing,
502
+ "data-tooltip": "\u4ECE A6API \u63A7\u5236\u53F0\u540C\u6B65\u83B7\u53D6\u6700\u65B0\u8D26\u6237\u771F\u5B9E\u53EF\u7528\u4F59\u989D\u4E0E\u6D88\u8017\u7EDF\u8BA1\uFF08\u4E0D\u6D88\u8017 Token\uFF09",
503
+ "data-tooltip-pos": "down",
504
+ children: refreshing ? "\u5237\u65B0\u4E2D..." : "\u5237\u65B0\u4F59\u989D"
505
+ }
506
+ ),
507
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
508
+ "a",
509
+ {
510
+ href: "https://a6api.com/console",
511
+ target: "_blank",
512
+ rel: "noreferrer",
513
+ className: "dsh-a6-btn dsh-a6-btn-primary dsh-a6-btn-sm",
514
+ style: { textDecoration: "none" },
515
+ "data-tooltip": "\u5728\u65B0\u6807\u7B7E\u9875\u4E2D\u6253\u5F00 A6API \u63A7\u5236\u53F0\u8FDB\u884C\u5728\u7EBF\u5145\u503C\u6216\u7BA1\u7406\u51ED\u636E",
516
+ "data-tooltip-pos": "down-left",
517
+ children: "\u524D\u5F80\u5145\u503C / \u63A7\u5236\u53F0"
518
+ }
519
+ )
520
+ ] })
521
+ ] }),
522
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dsh-a6-stat-cards-grid", children: [
523
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dsh-a6-kpi-card", children: [
524
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dsh-a6-kpi-label", children: "\u5173\u8054\u8D26\u6237" }),
525
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dsh-a6-kpi-val", children: hasAuth ? `${balance?.username || "\u5DF2\u8BA4\u8BC1\u7528\u6237"} (#${balance?.userId || "\u2014"})` : "\u672A\u7ED1\u5B9A" })
526
+ ] }),
527
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dsh-a6-kpi-card", children: [
528
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dsh-a6-kpi-label", children: "\u5386\u53F2\u603B\u6D88\u8017" }),
529
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dsh-a6-kpi-val", children: hasAuth ? `$${balance?.usedUsd?.toFixed(2) ?? "0.00"}` : "\u2014" })
530
+ ] }),
531
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dsh-a6-kpi-card", children: [
532
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dsh-a6-kpi-label", children: "\u7D2F\u8BA1\u8BF7\u6C42\u6B21\u6570" }),
533
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dsh-a6-kpi-val", children: hasAuth ? `${balance?.requestCount ?? 0} \u6B21` : "\u2014" })
534
+ ] }),
535
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dsh-a6-kpi-card", children: [
536
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dsh-a6-kpi-label", children: "\u5B9E\u65F6\u6C47\u7387\u53C2\u8003" }),
537
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dsh-a6-kpi-val", children: "1 USD \u2248 6.7209 CNY" })
538
+ ] })
539
+ ] })
540
+ ] }),
541
+ !hasAuth && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dsh-a6-auth-banner-box", children: [
542
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dsh-a6-auth-banner-content", children: [
543
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dsh-a6-auth-banner-title", children: "\u8FDE\u63A5\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C\u4EE5\u89E3\u9501\u5B8C\u6574\u8D44\u4EA7\u76D1\u63A7" }),
544
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dsh-a6-auth-banner-desc", children: [
545
+ "\u586B\u5165\u60A8\u7684 ",
546
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "A6API \u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C" }),
547
+ " \u540E\uFF0C\u5373\u53EF\u5728\u6B64\u5B9E\u65F6\u67E5\u770B\u8D26\u6237\u771F\u5B9E\u53EF\u7528\u4F59\u989D\u3001\u5386\u53F2\u6D88\u8017\u3001\u7D2F\u8BA1\u8BF7\u6C42\u4EE5\u53CA\u5546\u6237\u8DEF\u7531\u4EF7\u683C\u6307\u6807\u3002"
548
+ ] })
549
+ ] }),
550
+ onNavigateToConfig && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
551
+ "button",
552
+ {
553
+ type: "button",
554
+ className: "dsh-a6-btn dsh-a6-btn-primary dsh-a6-btn-sm",
555
+ onClick: onNavigateToConfig,
556
+ children: "\u586B\u5199\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C"
557
+ }
558
+ )
559
+ ] }),
560
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dsh-a6-logs-section", children: [
561
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "dsh-a6-logs-header", children: [
562
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dsh-a6-logs-title", children: "\u6700\u8FD1\u8DEF\u7531\u8C03\u7528\u660E\u7EC6 (\u5B9E\u65F6\u5FEB\u7167)" }),
563
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dsh-a6-logs-subtitle", children: "\u5C55\u793A\u901A\u8FC7\u5F53\u524D A6API \u63A5\u5165\u7684\u8FD1\u671F\u8BF7\u6C42\u4E0E\u5546\u6237\u8DEF\u7531\u8017\u65F6" })
564
+ ] }),
565
+ recentLogs && recentLogs.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dsh-a6-logs-table-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("table", { className: "dsh-a6-logs-table", children: [
566
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("tr", { children: [
567
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { children: "\u8C03\u7528\u65F6\u95F4" }),
568
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { children: "\u72B6\u6001" }),
569
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { children: "\u5546\u6237id" }),
570
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { children: "\u8BF7\u6C42\u6A21\u578B" }),
571
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { children: "\u8F93\u5165/\u8F93\u51FA" }),
572
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { children: "\u82B1\u8D39" }),
573
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { children: "\u8017\u65F6" })
574
+ ] }) }),
575
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tbody", { children: recentLogs.map((log, idx) => {
576
+ const isErr = log.status === "error" || log.status === "failed" || log.raw && (log.raw.type !== 2 || log.raw.other && (log.raw.other.includes('"request_final_status":"failed"') || log.raw.other.includes('"request_final_status":"error"') || log.raw.other.includes('"request_final_status":"upstream_error"')) || Boolean(log.raw.content && log.raw.content.startsWith("status_code=")));
577
+ const channelNum = Number(log.channel || log.raw?.channel || 0);
578
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("tr", { children: [
579
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { className: "dsh-a6-log-time", children: formatLogTime(log.created_at) }),
580
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `dsh-a6-log-status ${isErr ? "err" : "ok"}`, children: isErr ? "\u5931\u8D25" : "\u6210\u529F" }) }),
581
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { className: "dsh-a6-log-channel", children: channelNum > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "dsh-a6-log-channel-badge", children: [
582
+ "#",
583
+ channelNum
584
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "dsh-a6-log-channel-empty", children: "\u65E0" }) }),
585
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { className: "dsh-a6-log-model", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { children: log.model_name }) }),
586
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("td", { className: "dsh-a6-log-tokens", children: [
587
+ log.prompt_tokens || 0,
588
+ " / ",
589
+ log.completion_tokens || 0
590
+ ] }),
591
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { className: "dsh-a6-log-cost", children: log.cost_formatted || "$0.00" }),
592
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { className: "dsh-a6-log-time-use", children: log.use_time ? `${log.use_time}s` : "\u2014" })
593
+ ] }, log.id || idx);
594
+ }) })
595
+ ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "dsh-a6-empty-logs", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u6682\u65E0\u8FD1\u671F\u8C03\u7528\u8BB0\u5F55\u3002\u5728 DSH \u4E2D\u53D1\u8D77\u6A21\u578B\u5BF9\u8BDD\u6216\u70B9\u51FB\u300C\u63A2\u6D4B\u5546\u5BB6\u300D\u540E\uFF0C\u8C03\u7528\u660E\u7EC6\u5C06\u5728\u6B64\u5B9E\u65F6\u5C55\u793A\u3002" }) })
596
+ ] })
597
+ ] });
598
+ };
599
+
600
+ // src/client/components/ConfigPanel.tsx
601
+ var import_react3 = require("react");
602
+ var import_jsx_runtime3 = require("react/jsx-runtime");
603
+ var ConfigPanel = ({ config, dshConfiguredModels }) => {
604
+ const [apiKey, setApiKey] = (0, import_react3.useState)(config.apiKey || "");
605
+ const [accessToken, setAccessToken] = (0, import_react3.useState)(
606
+ config.accessToken || config.sessionCookie || ""
607
+ );
608
+ const [selectedNode, setSelectedNode] = (0, import_react3.useState)(
609
+ config.baseURL || "https://api.a6api.com"
610
+ );
611
+ const [customNode, setCustomNode] = (0, import_react3.useState)(config.customBaseURL || "");
612
+ const [isCustom, setIsCustom] = (0, import_react3.useState)(
613
+ config.baseURL !== "https://api.a6api.com" && config.baseURL !== "https://a6.a6api.com"
614
+ );
615
+ const [showKey, setShowKey] = (0, import_react3.useState)(false);
616
+ const [showToken, setShowToken] = (0, import_react3.useState)(false);
617
+ const [showHelp, setShowHelp] = (0, import_react3.useState)(false);
618
+ const [saving, setSaving] = (0, import_react3.useState)(false);
619
+ const [saveSuccess, setSaveSuccess] = (0, import_react3.useState)(false);
620
+ (0, import_react3.useEffect)(() => {
621
+ setApiKey(config.apiKey || "");
622
+ setAccessToken(config.accessToken || config.sessionCookie || "");
623
+ setSelectedNode(config.baseURL || "https://api.a6api.com");
624
+ setCustomNode(config.customBaseURL || "");
625
+ setIsCustom(
626
+ config.baseURL !== "https://api.a6api.com" && config.baseURL !== "https://a6.a6api.com"
627
+ );
628
+ }, [config]);
629
+ const handleSave = async () => {
630
+ setSaving(true);
631
+ const finalBaseUrl = isCustom ? customNode.trim() || "https://api.a6api.com" : selectedNode;
632
+ const ok = await store.saveConfig({
633
+ apiKey: apiKey.trim(),
634
+ accessToken: accessToken.trim(),
635
+ sessionCookie: accessToken.trim(),
636
+ baseURL: finalBaseUrl,
637
+ customBaseURL: customNode.trim()
638
+ });
639
+ setSaving(false);
640
+ if (ok) {
641
+ setSaveSuccess(true);
642
+ setTimeout(() => setSaveSuccess(false), 3500);
643
+ }
644
+ };
645
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-config-page", children: [
646
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-config-section", children: [
647
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-section-heading", children: [
648
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-a6-heading-title", children: "API \u63A5\u5165\u8282\u70B9 (Base URL)" }),
649
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-a6-heading-desc", children: "\u9009\u62E9\u79BB\u60A8\u6700\u8FD1\u7684 A6API \u805A\u5408\u7F51\u5173\u63A5\u5165\u70B9\uFF0C\u652F\u6301 CDN \u8282\u70B9\u4E0E\u76F4\u8FDE\u5907\u7528\u8282\u70B9\u3002" })
650
+ ] }),
651
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-node-picker", children: [
652
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
653
+ "button",
654
+ {
655
+ type: "button",
656
+ className: `dsh-a6-node-pill ${!isCustom && selectedNode === "https://api.a6api.com" ? "active" : ""}`,
657
+ onClick: () => {
658
+ setIsCustom(false);
659
+ setSelectedNode("https://api.a6api.com");
660
+ },
661
+ children: "https://api.a6api.com (CDN \u63A8\u8350)"
662
+ }
663
+ ),
664
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
665
+ "button",
666
+ {
667
+ type: "button",
668
+ className: `dsh-a6-node-pill ${!isCustom && selectedNode === "https://a6.a6api.com" ? "active" : ""}`,
669
+ onClick: () => {
670
+ setIsCustom(false);
671
+ setSelectedNode("https://a6.a6api.com");
672
+ },
673
+ children: "https://a6.a6api.com (\u76F4\u8FDE\u5907\u7528)"
674
+ }
675
+ ),
676
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
677
+ "button",
678
+ {
679
+ type: "button",
680
+ className: `dsh-a6-node-pill ${isCustom ? "active" : ""}`,
681
+ onClick: () => setIsCustom(true),
682
+ children: "\u81EA\u5B9A\u4E49\u8282\u70B9"
683
+ }
684
+ )
685
+ ] }),
686
+ isCustom && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
687
+ "input",
688
+ {
689
+ type: "text",
690
+ className: "dsh-a6-input",
691
+ placeholder: "https://your-custom-gateway.com",
692
+ value: customNode,
693
+ onChange: (e) => setCustomNode(e.target.value),
694
+ style: { marginTop: "8px" }
695
+ }
696
+ )
697
+ ] }),
698
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-config-section", children: [
699
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-section-heading", children: [
700
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-a6-heading-title", children: "\u8BBF\u95EE\u9274\u6743\u4E0E\u4EE4\u724C\u51ED\u636E" }),
701
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-a6-heading-desc", children: "\u914D\u7F6E\u6A21\u578B\u8C03\u7528 API Key \u4EE5\u53CA\u7528\u4E8E\u540C\u6B65\u8D26\u6237\u4F59\u989D\u4E0E\u5546\u6237\u884C\u60C5\u7684\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C\u3002" })
702
+ ] }),
703
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-config-fields-grid", children: [
704
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-field", children: [
705
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-field-header", children: [
706
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { className: "dsh-a6-label", children: "A6API \u4EE4\u724C (API Key)" }),
707
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
708
+ "button",
709
+ {
710
+ type: "button",
711
+ className: "dsh-a6-btn-text",
712
+ onClick: () => setShowKey(!showKey),
713
+ children: showKey ? "\u9690\u85CF" : "\u663E\u793A"
714
+ }
715
+ )
716
+ ] }),
717
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-a6-input-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
718
+ "input",
719
+ {
720
+ type: showKey ? "text" : "password",
721
+ className: "dsh-a6-input",
722
+ placeholder: "sk-xxxxxxxxxxxxxxxxxxxxxxxx",
723
+ value: apiKey,
724
+ onChange: (e) => setApiKey(e.target.value)
725
+ }
726
+ ) }),
727
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-a6-field-hint", children: "\u7528\u4E8E\u5411 A6API \u53D1\u8D77\u6A21\u578B\u5BF9\u8BDD\u8BF7\u6C42\u4E0E\u62C9\u53D6\u767D\u540D\u5355\u6A21\u578B\u3002" })
728
+ ] }),
729
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-field", children: [
730
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-field-header", children: [
731
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { className: "dsh-a6-label", children: "\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C (Access Token)" }),
732
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
733
+ "button",
734
+ {
735
+ type: "button",
736
+ className: "dsh-a6-btn-text",
737
+ onClick: () => setShowToken(!showToken),
738
+ children: showToken ? "\u9690\u85CF" : "\u663E\u793A"
739
+ }
740
+ )
741
+ ] }),
742
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-a6-input-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
743
+ "input",
744
+ {
745
+ type: showToken ? "text" : "password",
746
+ className: "dsh-a6-input",
747
+ placeholder: "\u5728\u63A7\u5236\u53F0\u5B89\u5168\u8BBE\u7F6E\u4E2D\u590D\u5236\uFF0C\u4F8B\u5982 eyJhbGciOi...",
748
+ value: accessToken,
749
+ onChange: (e) => setAccessToken(e.target.value)
750
+ }
751
+ ) }),
752
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-field-footer", children: [
753
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-a6-field-hint", children: "\u7528\u4E8E\u514D\u5931\u6548\u540C\u6B65\u8D26\u6237\u771F\u5B9E\u4F59\u989D\u4E0E\u5546\u6237\u6307\u6807\u3002" }),
754
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
755
+ "button",
756
+ {
757
+ type: "button",
758
+ className: "dsh-a6-btn-text",
759
+ onClick: () => setShowHelp(!showHelp),
760
+ style: { fontSize: "11px", whiteSpace: "nowrap" },
761
+ children: showHelp ? "\u6536\u8D77\u6559\u7A0B" : "\u83B7\u53D6\u6559\u7A0B"
762
+ }
763
+ )
764
+ ] })
765
+ ] })
766
+ ] }),
767
+ showHelp && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-help-drawer", children: [
768
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-a6-help-title", children: "\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C\u83B7\u53D6\u6B65\u9AA4\uFF08\u6C38\u4E45\u6709\u6548\uFF09\uFF1A" }),
769
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("ol", { className: "dsh-a6-help-list", children: [
770
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { children: [
771
+ "\u5728\u6D4F\u89C8\u5668\u6253\u5F00\u5E76\u767B\u5F55",
772
+ " ",
773
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { href: "https://a6api.com/console/personal", target: "_blank", rel: "noreferrer", children: "a6api.com/console/personal" }),
774
+ " ",
775
+ "\uFF08\u4E2A\u4EBA\u8BBE\u7F6E - \u5B89\u5168\u8BBE\u7F6E\uFF09"
776
+ ] }),
777
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { children: [
778
+ "\u5728\u300C\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C\u300D\u680F\u76EE\u76F4\u63A5\u70B9\u51FB\u590D\u5236\u4EE4\u724C\u5B57\u7B26\u4E32\uFF08\u4F8B\u5982 ",
779
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("code", { children: "eyJhbGciOi..." }),
780
+ "\uFF09"
781
+ ] }),
782
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("li", { children: "\u7C98\u8D34\u5230\u4E0A\u65B9\u7684\u300C\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C\u300D\u8F93\u5165\u6846\u4E2D\u5E76\u70B9\u51FB\u4E0B\u65B9\u300C\u4FDD\u5B58\u914D\u7F6E\u300D\u5373\u53EF\u81EA\u52A8\u540C\u6B65\u4F59\u989D\uFF01" })
783
+ ] })
784
+ ] })
785
+ ] }),
786
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-config-section", children: [
787
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-section-heading", children: [
788
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-a6-heading-title", children: "DSH \u539F\u751F LLM \u63D0\u4F9B\u5546\u96C6\u6210\u72B6\u6001" }),
789
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dsh-a6-heading-desc", children: [
790
+ "\u63D2\u4EF6\u5DF2\u5C06 A6API \u6CE8\u518C\u4E3A DSH \u539F\u751F\u6A21\u578B\u63D0\u4F9B\u5546 (",
791
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("code", { children: "a6api" }),
792
+ ")\u3002\u5728\u300C\u53EF\u7528\u6A21\u578B\u300D\u4E2D\u542F\u7528\u7684\u6A21\u578B\u5C06\u81EA\u52A8\u5199\u5165 DSH \u914D\u7F6E\u6587\u4EF6\u3002"
793
+ ] })
794
+ ] }),
795
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-integration-card", children: [
796
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-int-row", children: [
797
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-a6-int-key", children: "\u63D0\u4F9B\u5546\u6807\u8BC6" }),
798
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "dsh-a6-int-val", children: [
799
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("code", { children: "a6api" }),
800
+ " (OpenAI-compatible)"
801
+ ] })
802
+ ] }),
803
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-int-row", children: [
804
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-a6-int-key", children: "\u5F53\u524D\u5DF2\u542F\u7528\u6A21\u578B" }),
805
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-a6-int-tags", children: dshConfiguredModels.length > 0 ? dshConfiguredModels.map((m) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-a6-model-chip", children: m }, m)) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-a6-empty-hint", children: "\u6682\u672A\u542F\u7528\u4EFB\u4F55\u6A21\u578B\uFF0C\u8BF7\u524D\u5F80\u300C\u53EF\u7528\u6A21\u578B\u300D\u9875\u9762\u70B9\u51FB\u300C\u6DFB\u52A0\u5230 DSH\u300D" }) })
806
+ ] })
807
+ ] })
808
+ ] }),
809
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "dsh-a6-save-bar", children: [
810
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "dsh-a6-save-status", children: saveSuccess && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "dsh-a6-success-msg", children: "\u914D\u7F6E\u5DF2\u6210\u529F\u4FDD\u5B58\u5E76\u540C\u6B65" }) }),
811
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
812
+ "button",
813
+ {
814
+ type: "button",
815
+ className: "dsh-a6-btn dsh-a6-btn-primary",
816
+ onClick: handleSave,
817
+ disabled: saving,
818
+ style: { minWidth: "100px" },
819
+ children: saving ? "\u6B63\u5728\u4FDD\u5B58..." : "\u4FDD\u5B58\u914D\u7F6E"
820
+ }
821
+ )
822
+ ] })
823
+ ] });
824
+ };
825
+
826
+ // src/client/components/A6ApiSettings.tsx
827
+ var import_jsx_runtime4 = require("react/jsx-runtime");
828
+ var A6ApiSettingsPanel = () => {
829
+ const [state, setState] = (0, import_react4.useState)(store.getState());
830
+ const [activeTab, setActiveTab] = (0, import_react4.useState)("models");
831
+ const [filterMode, setFilterMode] = (0, import_react4.useState)("all");
832
+ const [searchQuery, setSearchQuery] = (0, import_react4.useState)("");
833
+ const [probingAll, setProbingAll] = (0, import_react4.useState)(false);
834
+ const [refreshing, setRefreshing] = (0, import_react4.useState)(false);
835
+ const [refreshSuccess, setRefreshSuccess] = (0, import_react4.useState)(false);
836
+ (0, import_react4.useEffect)(() => {
837
+ const unsub = store.subscribe(() => {
838
+ setState({ ...store.getState() });
839
+ });
840
+ store.fetchState();
841
+ return unsub;
842
+ }, []);
843
+ const handleProbeAll = async () => {
844
+ setProbingAll(true);
845
+ await store.probeAll();
846
+ setProbingAll(false);
847
+ };
848
+ const handleRefreshState = async () => {
849
+ setRefreshing(true);
850
+ await store.fetchState();
851
+ setRefreshing(false);
852
+ setRefreshSuccess(true);
853
+ setTimeout(() => setRefreshSuccess(false), 2e3);
854
+ };
855
+ const inDshCount = state.models.filter((m) => m.inDsh).length;
856
+ const probedCount = state.models.filter((m) => Boolean(m.merchant)).length;
857
+ const filteredModels = state.models.filter((m) => {
858
+ if (filterMode === "enabled" && !m.inDsh) return false;
859
+ if (filterMode === "probed" && !m.merchant) return false;
860
+ if (searchQuery.trim()) {
861
+ const q = searchQuery.toLowerCase().trim();
862
+ return m.model_name.toLowerCase().includes(q) || m.brand.toLowerCase().includes(q) || m.merchant?.supplier_name && m.merchant.supplier_name.toLowerCase().includes(q) || m.merchant?.channel_name && m.merchant.channel_name.toLowerCase().includes(q) || m.merchant?.description && m.merchant.description.toLowerCase().includes(q);
863
+ }
864
+ return true;
865
+ });
866
+ const sortedModels = [...filteredModels].sort((a, b) => {
867
+ if (a.inDsh !== b.inDsh) {
868
+ return a.inDsh ? -1 : 1;
869
+ }
870
+ return a.model_name.localeCompare(b.model_name);
871
+ });
872
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-a6-container", children: [
873
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-a6-main-header", children: [
874
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-a6-header-text", children: [
875
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "dsh-a6-main-title", children: "A6API \u805A\u5408\u7AD9" }),
876
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "dsh-a6-main-subtitle", children: "\u805A\u5408\u5168\u7403\u4E3B\u6D41\u4E0E\u9AD8\u6027\u4EF7\u6BD4\u6A21\u578B\uFF0C\u5B9E\u65F6\u76D1\u63A7\u5546\u6237\u6307\u6807\u3001\u4EF7\u683C\u500D\u7387\u4E0E\u8D26\u6237\u8D44\u4EA7\u3002" })
877
+ ] }),
878
+ state.balance?.hasAccountAuth && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
879
+ "div",
880
+ {
881
+ className: "dsh-a6-header-balance-badge",
882
+ onClick: () => setActiveTab("account"),
883
+ title: "\u70B9\u51FB\u5207\u6362\u81F3\u300C\u8D26\u6237\u8D44\u4EA7\u300D\u9875\u9762",
884
+ children: [
885
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dsh-a6-hb-label", children: "\u8D26\u6237\u4F59\u989D:" }),
886
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dsh-a6-hb-amount", children: state.balance.accountBalanceFormatted })
887
+ ]
888
+ }
889
+ )
890
+ ] }),
891
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-a6-nav-tabs", children: [
892
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
893
+ "button",
894
+ {
895
+ type: "button",
896
+ className: `dsh-a6-nav-tab ${activeTab === "models" ? "active" : ""}`,
897
+ onClick: () => setActiveTab("models"),
898
+ children: [
899
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u53EF\u7528\u6A21\u578B" }),
900
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dsh-a6-tab-badge", children: state.models.length })
901
+ ]
902
+ }
903
+ ),
904
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
905
+ "button",
906
+ {
907
+ type: "button",
908
+ className: `dsh-a6-nav-tab ${activeTab === "account" ? "active" : ""}`,
909
+ onClick: () => setActiveTab("account"),
910
+ children: [
911
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u8D26\u6237\u8D44\u4EA7" }),
912
+ state.balance?.hasAccountAuth && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "dsh-a6-tab-badge success", children: state.balance.accountBalanceFormatted })
913
+ ]
914
+ }
915
+ ),
916
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
917
+ "button",
918
+ {
919
+ type: "button",
920
+ className: `dsh-a6-nav-tab ${activeTab === "config" ? "active" : ""}`,
921
+ onClick: () => setActiveTab("config"),
922
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u57FA\u7840\u914D\u7F6E" })
923
+ }
924
+ )
925
+ ] }),
926
+ activeTab === "models" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-a6-tab-page models-page", children: [
927
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-a6-section-header", children: [
928
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-a6-filter-group", children: [
929
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
930
+ "button",
931
+ {
932
+ type: "button",
933
+ className: `dsh-a6-filter-btn ${filterMode === "all" ? "active" : ""}`,
934
+ onClick: () => setFilterMode("all"),
935
+ children: [
936
+ "\u5168\u90E8 (",
937
+ state.models.length,
938
+ ")"
939
+ ]
940
+ }
941
+ ),
942
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
943
+ "button",
944
+ {
945
+ type: "button",
946
+ className: `dsh-a6-filter-btn ${filterMode === "enabled" ? "active" : ""}`,
947
+ onClick: () => setFilterMode("enabled"),
948
+ children: [
949
+ "\u5DF2\u542F\u7528 (",
950
+ inDshCount,
951
+ ")"
952
+ ]
953
+ }
954
+ ),
955
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
956
+ "button",
957
+ {
958
+ type: "button",
959
+ className: `dsh-a6-filter-btn ${filterMode === "probed" ? "active" : ""}`,
960
+ onClick: () => setFilterMode("probed"),
961
+ children: [
962
+ "\u5DF2\u63A2\u6D4B (",
963
+ probedCount,
964
+ ")"
965
+ ]
966
+ }
967
+ )
968
+ ] }),
969
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-a6-toolbar-right", children: [
970
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-a6-search-wrapper", children: [
971
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
972
+ "input",
973
+ {
974
+ type: "text",
975
+ className: "dsh-a6-input dsh-a6-search-input",
976
+ placeholder: "\u641C\u7D22\u6A21\u578B / \u4F9B\u5E94\u5546 / \u6E20\u9053...",
977
+ value: searchQuery,
978
+ onChange: (e) => setSearchQuery(e.target.value)
979
+ }
980
+ ),
981
+ searchQuery && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
982
+ "button",
983
+ {
984
+ type: "button",
985
+ className: "dsh-a6-clear-btn",
986
+ onClick: () => setSearchQuery(""),
987
+ title: "\u6E05\u7A7A\u641C\u7D22",
988
+ children: "\xD7"
989
+ }
990
+ )
991
+ ] }),
992
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
993
+ "button",
994
+ {
995
+ type: "button",
996
+ className: `dsh-a6-btn dsh-a6-btn-secondary dsh-a6-btn-sm ${refreshSuccess ? "dsh-a6-btn-refresh-ok" : ""}`,
997
+ onClick: handleRefreshState,
998
+ disabled: refreshing,
999
+ "data-tooltip": "\u91CD\u65B0\u5411 A6API \u63A5\u53E3\u62C9\u53D6\u5F53\u524D\u4EE4\u724C\u7684\u53EF\u7528\u6A21\u578B\u5217\u8868\u53CA\u5DF2\u7F13\u5B58\u5546\u6237\u6307\u6807\uFF08\u4E0D\u6D88\u8017 Token\uFF09",
1000
+ "data-tooltip-pos": "down",
1001
+ children: refreshing ? "\u5237\u65B0\u4E2D..." : refreshSuccess ? "\u5DF2\u5237\u65B0 \u2713" : "\u5237\u65B0\u5217\u8868"
1002
+ }
1003
+ ),
1004
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1005
+ "button",
1006
+ {
1007
+ type: "button",
1008
+ className: "dsh-a6-btn dsh-a6-btn-primary dsh-a6-btn-sm",
1009
+ onClick: handleProbeAll,
1010
+ disabled: probingAll || state.models.length === 0,
1011
+ "data-tooltip": "\u5BF9\u5F53\u524D\u4EE4\u724C\u652F\u6301\u7684\u6240\u6709\u6A21\u578B\u9010\u4E2A\u53D1\u9001\u4E00\u6B21\u8BF7\u6C42\uFF0C\u6279\u91CF\u6355\u83B7\u5546\u6237\u8DEF\u7531\u4E0E\u6700\u65B0\u884C\u60C5\uFF08\u6BCF\u4E2A\u6A21\u578B\u6D88\u8017\u5C11\u91CFToken\uFF09",
1012
+ "data-tooltip-pos": "down-left",
1013
+ children: probingAll ? "\u5168\u91CF\u63A2\u6D4B\u4E2D..." : "\u4E00\u952E\u5168\u91CF\u63A2\u6D4B"
1014
+ }
1015
+ )
1016
+ ] })
1017
+ ] }),
1018
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dsh-a6-cards-list", children: state.loading && state.models.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "dsh-a6-empty-state", children: [
1019
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dsh-a6-spinner" }),
1020
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u6B63\u5728\u8FDE\u63A5 A6API \u805A\u5408\u7AD9\u5E76\u52A0\u8F7D\u6A21\u578B\u884C\u60C5..." })
1021
+ ] }) : sortedModels.length > 0 ? sortedModels.map((m) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MerchantCard, { model: m }, m.model_name)) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dsh-a6-empty-state", children: searchQuery ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
1022
+ "\u672A\u641C\u7D22\u5230\u5339\u914D\u300C",
1023
+ searchQuery,
1024
+ "\u300D\u7684\u6A21\u578B"
1025
+ ] }) : filterMode === "enabled" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u5F53\u524D\u5C1A\u672A\u5728 DSH \u4E2D\u542F\u7528\u4EFB\u4F55 A6API \u6A21\u578B\uFF0C\u70B9\u51FB\u6A21\u578B\u5361\u7247\u53F3\u4FA7\u300C\u6DFB\u52A0\u5230 DSH\u300D\u5373\u53EF\u542F\u7528\u3002" }) : filterMode === "probed" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u5C1A\u672A\u63A2\u6D4B\u4EFB\u4F55\u6A21\u578B\u5546\u6237\u7EBF\u8DEF\uFF0C\u70B9\u51FB\u6A21\u578B\u5361\u7247\u4E0A\u7684\u300C\u63A2\u6D4B\u5546\u5BB6\u300D\u6216\u4E0A\u65B9\u300C\u4E00\u952E\u5168\u91CF\u63A2\u6D4B\u300D\u5373\u53EF\u5F00\u59CB\u3002" }) : !state.config.apiKey ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u8BF7\u524D\u5F80\u300C\u57FA\u7840\u914D\u7F6E\u300D\u9875\u9762\u586B\u5165\u60A8\u7684 A6API \u4EE4\u724C (API Key) \u5E76\u4FDD\u5B58\uFF0C\u5373\u53EF\u81EA\u52A8\u52A0\u8F7D\u53EF\u7528\u6A21\u578B\u5217\u8868\u3002" }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u5F53\u524D\u4EE4\u724C\u6682\u65E0\u53EF\u7528\u6A21\u578B\uFF0C\u8BF7\u68C0\u67E5 A6API \u63A7\u5236\u53F0\u4E2D\u7684\u4EE4\u724C\u9650\u5236\u8BBE\u7F6E\u3002" }) }) })
1026
+ ] }),
1027
+ activeTab === "account" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dsh-a6-tab-page account-page", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1028
+ AccountPanel,
1029
+ {
1030
+ balance: state.balance,
1031
+ config: state.config,
1032
+ recentLogs: state.recentLogs,
1033
+ onNavigateToConfig: () => setActiveTab("config")
1034
+ }
1035
+ ) }),
1036
+ activeTab === "config" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "dsh-a6-tab-page config-page", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1037
+ ConfigPanel,
1038
+ {
1039
+ config: state.config,
1040
+ dshConfiguredModels: state.dshConfiguredModels
1041
+ }
1042
+ ) })
1043
+ ] });
1044
+ };
1045
+
1046
+ // src/client/styles/main.css
1047
+ var main_default = `/* A6API Plugin Styles - Clean Professional DSH Native Theme Integration */
1048
+
1049
+ .dsh-a6-container {
1050
+ display: flex;
1051
+ flex-direction: column;
1052
+ color: var(--dsw-alias-label-primary, var(--ds-text-primary, #1e293b));
1053
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
1054
+ padding-bottom: 28px;
1055
+ }
1056
+
1057
+ /* ==========================================================================
1058
+ 1. Master Header & Navigation Tabs (Image 2 Style)
1059
+ ========================================================================== */
1060
+ .dsh-a6-main-header {
1061
+ display: flex;
1062
+ justify-content: space-between;
1063
+ align-items: flex-start;
1064
+ gap: 16px;
1065
+ margin-bottom: 12px;
1066
+ flex-wrap: wrap;
1067
+ }
1068
+
1069
+ .dsh-a6-header-text {
1070
+ display: flex;
1071
+ flex-direction: column;
1072
+ gap: 4px;
1073
+ }
1074
+
1075
+ .dsh-a6-main-title {
1076
+ font-size: 20px;
1077
+ font-weight: 700;
1078
+ color: var(--dsw-alias-label-primary, #0f172a);
1079
+ margin: 0;
1080
+ line-height: 1.2;
1081
+ }
1082
+
1083
+ .dsh-a6-main-subtitle {
1084
+ font-size: 13px;
1085
+ color: var(--dsw-alias-label-secondary, #64748b);
1086
+ margin: 0;
1087
+ line-height: 1.5;
1088
+ }
1089
+
1090
+ .dsh-a6-header-balance-badge {
1091
+ display: inline-flex;
1092
+ align-items: center;
1093
+ gap: 6px;
1094
+ padding: 5px 12px;
1095
+ background: var(--dsw-alias-bg-layer-2, #ffffff);
1096
+ border: 1px solid var(--dsw-alias-border-l2, #e2e8f0);
1097
+ border-radius: 16px;
1098
+ cursor: pointer;
1099
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
1100
+ transition: all 0.15s;
1101
+ }
1102
+
1103
+ .dsh-a6-header-balance-badge:hover {
1104
+ border-color: #10b981;
1105
+ background: rgba(16, 185, 129, 0.04);
1106
+ }
1107
+
1108
+ .dsh-a6-hb-label {
1109
+ font-size: 12px;
1110
+ color: var(--dsw-alias-label-secondary, #64748b);
1111
+ }
1112
+
1113
+ .dsh-a6-hb-amount {
1114
+ font-size: 13px;
1115
+ font-weight: 700;
1116
+ color: #10b981;
1117
+ }
1118
+
1119
+ /* Nav Tabs */
1120
+ .dsh-a6-nav-tabs {
1121
+ display: flex;
1122
+ gap: 28px;
1123
+ border-bottom: 1px solid var(--dsw-alias-border-l2, #e2e8f0);
1124
+ margin-bottom: 18px;
1125
+ margin-top: 4px;
1126
+ }
1127
+
1128
+ .dsh-a6-nav-tab {
1129
+ background: transparent;
1130
+ border: none;
1131
+ padding: 10px 2px 12px 2px;
1132
+ font-size: 14px;
1133
+ font-weight: 500;
1134
+ color: var(--dsw-alias-label-secondary, #64748b);
1135
+ cursor: pointer;
1136
+ position: relative;
1137
+ display: inline-flex;
1138
+ align-items: center;
1139
+ gap: 6px;
1140
+ transition: color 0.15s;
1141
+ margin-bottom: -1px;
1142
+ }
1143
+
1144
+ .dsh-a6-nav-tab:hover {
1145
+ color: var(--dsw-alias-label-primary, #0f172a);
1146
+ }
1147
+
1148
+ .dsh-a6-nav-tab.active {
1149
+ color: var(--dsw-alias-label-primary, #0f172a);
1150
+ font-weight: 600;
1151
+ border-bottom: 2px solid var(--dsw-alias-label-primary, #0f172a);
1152
+ }
1153
+
1154
+ .dsh-a6-tab-badge {
1155
+ font-size: 11px;
1156
+ font-weight: 500;
1157
+ padding: 1px 6px;
1158
+ border-radius: 10px;
1159
+ background: var(--dsw-alias-bg-layer-1, rgba(0, 0, 0, 0.06));
1160
+ color: var(--dsw-alias-label-secondary, #64748b);
1161
+ }
1162
+
1163
+ .dsh-a6-tab-badge.success {
1164
+ background: rgba(16, 185, 129, 0.12);
1165
+ color: #10b981;
1166
+ }
1167
+
1168
+ /* Tab Page Wrapper */
1169
+ .dsh-a6-tab-page {
1170
+ display: flex;
1171
+ flex-direction: column;
1172
+ gap: 16px;
1173
+ animation: dsh-a6-fadein 0.15s ease-out;
1174
+ }
1175
+
1176
+ @keyframes dsh-a6-fadein {
1177
+ from {
1178
+ opacity: 0.8;
1179
+ transform: translateY(2px);
1180
+ }
1181
+ to {
1182
+ opacity: 1;
1183
+ transform: translateY(0);
1184
+ }
1185
+ }
1186
+
1187
+ /* ==========================================================================
1188
+ 2. Models Tab Toolbar & Filters
1189
+ ========================================================================== */
1190
+ .dsh-a6-section-header {
1191
+ display: flex;
1192
+ justify-content: space-between;
1193
+ align-items: center;
1194
+ gap: 12px;
1195
+ flex-wrap: wrap;
1196
+ position: relative;
1197
+ z-index: 100;
1198
+ }
1199
+
1200
+ .dsh-a6-filter-group {
1201
+ display: flex;
1202
+ background: var(--dsw-alias-bg-layer-1, rgba(0, 0, 0, 0.04));
1203
+ border: 1px solid var(--dsw-alias-border-l3, #cbd5e1);
1204
+ border-radius: 6px;
1205
+ padding: 2px;
1206
+ }
1207
+
1208
+ .dsh-a6-filter-btn {
1209
+ background: transparent;
1210
+ border: none;
1211
+ padding: 4px 10px;
1212
+ font-size: 12px;
1213
+ font-weight: 500;
1214
+ border-radius: 4px;
1215
+ color: var(--dsw-alias-label-secondary, #64748b);
1216
+ cursor: pointer;
1217
+ transition: all 0.15s;
1218
+ }
1219
+
1220
+ .dsh-a6-filter-btn:hover {
1221
+ color: var(--dsw-alias-label-primary, #0f172a);
1222
+ }
1223
+
1224
+ .dsh-a6-filter-btn.active {
1225
+ background: var(--dsw-alias-bg-layer-2, #ffffff);
1226
+ color: var(--dsw-alias-label-primary, #0f172a);
1227
+ font-weight: 600;
1228
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
1229
+ }
1230
+
1231
+ .dsh-a6-toolbar-right {
1232
+ display: flex;
1233
+ gap: 8px;
1234
+ align-items: center;
1235
+ flex-wrap: wrap;
1236
+ }
1237
+
1238
+ .dsh-a6-search-wrapper {
1239
+ position: relative;
1240
+ display: flex;
1241
+ align-items: center;
1242
+ }
1243
+
1244
+ .dsh-a6-search-input {
1245
+ width: 200px;
1246
+ height: 30px;
1247
+ padding-right: 22px;
1248
+ font-size: 12px;
1249
+ }
1250
+
1251
+ .dsh-a6-clear-btn {
1252
+ position: absolute;
1253
+ right: 6px;
1254
+ background: transparent;
1255
+ border: none;
1256
+ color: #94a3b8;
1257
+ cursor: pointer;
1258
+ font-size: 14px;
1259
+ padding: 2px;
1260
+ line-height: 1;
1261
+ }
1262
+
1263
+ /* ==========================================================================
1264
+ 3. Clean Model Card
1265
+ ========================================================================== */
1266
+ .dsh-a6-cards-list {
1267
+ display: flex;
1268
+ flex-direction: column;
1269
+ gap: 12px;
1270
+ }
1271
+
1272
+ .dsh-a6-official-card {
1273
+ background: var(--dsw-alias-bg-layer-2, #ffffff);
1274
+ border: 1px solid var(--dsw-alias-border-l2, #e2e8f0);
1275
+ border-radius: 10px;
1276
+ padding: 12px 16px;
1277
+ display: flex;
1278
+ flex-direction: column;
1279
+ gap: 8px;
1280
+ transition: border-color 0.15s, box-shadow 0.15s;
1281
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.02);
1282
+ }
1283
+
1284
+ .dsh-a6-official-card:hover {
1285
+ border-color: var(--dsw-alias-border-l1, #cbd5e1);
1286
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
1287
+ }
1288
+
1289
+ .dsh-a6-official-card.in-dsh {
1290
+ border-left: 3px solid #10b981;
1291
+ }
1292
+
1293
+ /* Main Top Bar */
1294
+ .dsh-a6-card-main-bar {
1295
+ display: flex;
1296
+ align-items: center;
1297
+ justify-content: space-between;
1298
+ gap: 14px;
1299
+ cursor: pointer;
1300
+ user-select: none;
1301
+ flex-wrap: wrap;
1302
+ }
1303
+
1304
+ /* Identity Col (Clean text without Brand Logos) */
1305
+ .dsh-a6-bar-identity {
1306
+ display: flex;
1307
+ align-items: center;
1308
+ min-width: 180px;
1309
+ flex: 1.2;
1310
+ }
1311
+
1312
+ .dsh-a6-title-col {
1313
+ display: flex;
1314
+ flex-direction: column;
1315
+ gap: 2px;
1316
+ }
1317
+
1318
+ .dsh-a6-title-line {
1319
+ display: flex;
1320
+ align-items: center;
1321
+ gap: 6px;
1322
+ flex-wrap: wrap;
1323
+ }
1324
+
1325
+ .dsh-a6-name-text {
1326
+ font-size: 14px;
1327
+ font-weight: 700;
1328
+ color: var(--dsw-alias-label-primary, #0f172a);
1329
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, monospace;
1330
+ }
1331
+
1332
+ .dsh-a6-dot-sep {
1333
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
1334
+ }
1335
+
1336
+ .dsh-a6-merchant-id-text {
1337
+ font-size: 12px;
1338
+ font-weight: 500;
1339
+ color: var(--dsw-alias-label-secondary, #475569);
1340
+ }
1341
+
1342
+ .dsh-a6-sub-desc {
1343
+ font-size: 11px;
1344
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
1345
+ }
1346
+
1347
+ /* Pricing Col */
1348
+ .dsh-a6-bar-pricing {
1349
+ display: flex;
1350
+ align-items: center;
1351
+ gap: 10px;
1352
+ flex: 1;
1353
+ }
1354
+
1355
+ .dsh-a6-bar-pricing.unprobed {
1356
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
1357
+ font-size: 12px;
1358
+ }
1359
+
1360
+ .dsh-a6-price-col {
1361
+ display: flex;
1362
+ flex-direction: column;
1363
+ gap: 1px;
1364
+ }
1365
+
1366
+ .dsh-a6-price-top {
1367
+ font-size: 13px;
1368
+ font-weight: 700;
1369
+ color: var(--dsw-alias-label-primary, #0f172a);
1370
+ }
1371
+
1372
+ .dsh-a6-price-btm {
1373
+ font-size: 11px;
1374
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
1375
+ }
1376
+
1377
+ .dsh-a6-ratio-pill {
1378
+ font-size: 11px;
1379
+ font-weight: 600;
1380
+ padding: 2px 7px;
1381
+ border-radius: 10px;
1382
+ background: #f0fdfa;
1383
+ color: #0d9488;
1384
+ border: 1px solid #99f6e4;
1385
+ white-space: nowrap;
1386
+ }
1387
+
1388
+ /* Uptime / Health Col (\u5B9E\u65F6 / 24h / 7d) */
1389
+ .dsh-a6-bar-uptime {
1390
+ display: flex;
1391
+ flex-direction: column;
1392
+ gap: 2px;
1393
+ min-width: 130px;
1394
+ }
1395
+
1396
+ .dsh-a6-uptime-row {
1397
+ display: flex;
1398
+ align-items: center;
1399
+ gap: 5px;
1400
+ font-size: 11px;
1401
+ }
1402
+
1403
+ .dsh-a6-uptime-label {
1404
+ width: 24px;
1405
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
1406
+ font-size: 10px;
1407
+ }
1408
+
1409
+ .dsh-a6-dots-track {
1410
+ display: flex;
1411
+ gap: 2px;
1412
+ align-items: center;
1413
+ }
1414
+
1415
+ .dsh-a6-rate-dot {
1416
+ width: 4px;
1417
+ height: 8px;
1418
+ border-radius: 2px;
1419
+ background: #10b981;
1420
+ }
1421
+
1422
+ .dsh-a6-rate-dot.green {
1423
+ background: #10b981;
1424
+ }
1425
+
1426
+ .dsh-a6-rate-dot.yellow {
1427
+ background: #f59e0b;
1428
+ }
1429
+
1430
+ .dsh-a6-rate-dot.red {
1431
+ background: #ef4444;
1432
+ }
1433
+
1434
+ .dsh-a6-rate-dot.empty {
1435
+ background: var(--dsw-alias-border-l3, rgba(0, 0, 0, 0.1));
1436
+ }
1437
+
1438
+ .dsh-a6-uptime-val {
1439
+ font-weight: 600;
1440
+ font-size: 10px;
1441
+ color: var(--dsw-alias-label-secondary, #475569);
1442
+ min-width: 38px;
1443
+ text-align: right;
1444
+ }
1445
+
1446
+ /* Performance Col (Speed / Cache Hit Bar) */
1447
+ .dsh-a6-bar-perf {
1448
+ display: flex;
1449
+ align-items: center;
1450
+ gap: 6px;
1451
+ }
1452
+
1453
+ .dsh-a6-perf-row {
1454
+ display: flex;
1455
+ align-items: center;
1456
+ gap: 6px;
1457
+ }
1458
+
1459
+ .dsh-a6-latency-text {
1460
+ font-size: 12px;
1461
+ font-weight: 600;
1462
+ color: var(--dsw-alias-label-primary, #0f172a);
1463
+ }
1464
+
1465
+ .dsh-a6-cache-hit-text {
1466
+ font-size: 11px;
1467
+ font-weight: 600;
1468
+ color: #d97706;
1469
+ }
1470
+
1471
+ .dsh-a6-hit-track {
1472
+ width: 38px;
1473
+ height: 4px;
1474
+ border-radius: 2px;
1475
+ background: var(--dsw-alias-border-l3, rgba(0, 0, 0, 0.08));
1476
+ overflow: hidden;
1477
+ }
1478
+
1479
+ .dsh-a6-hit-fill {
1480
+ height: 100%;
1481
+ border-radius: 2px;
1482
+ background: linear-gradient(90deg, #f59e0b, #eab308);
1483
+ }
1484
+
1485
+ /* Smart Tags */
1486
+ .dsh-a6-bar-tags {
1487
+ display: flex;
1488
+ gap: 5px;
1489
+ align-items: center;
1490
+ flex-wrap: wrap;
1491
+ }
1492
+
1493
+ .dsh-a6-smart-pill {
1494
+ font-size: 11px;
1495
+ font-weight: 500;
1496
+ padding: 1px 6px;
1497
+ border-radius: 10px;
1498
+ background: var(--dsw-alias-bg-layer-1, rgba(0, 0, 0, 0.04));
1499
+ border: 1px solid var(--dsw-alias-border-l3, rgba(0, 0, 0, 0.08));
1500
+ color: var(--dsw-alias-label-secondary, #475569);
1501
+ }
1502
+
1503
+ .dsh-a6-smart-pill.tag-stable {
1504
+ background: rgba(16, 185, 129, 0.08);
1505
+ border-color: rgba(16, 185, 129, 0.25);
1506
+ color: #10b981;
1507
+ }
1508
+
1509
+ .dsh-a6-smart-pill.tag-cheap {
1510
+ background: rgba(59, 130, 246, 0.08);
1511
+ border-color: rgba(59, 130, 246, 0.25);
1512
+ color: #3b82f6;
1513
+ }
1514
+
1515
+ .dsh-a6-smart-pill.tag-fast {
1516
+ background: rgba(249, 115, 22, 0.08);
1517
+ border-color: rgba(249, 115, 22, 0.25);
1518
+ color: #ea580c;
1519
+ }
1520
+
1521
+ .dsh-a6-smart-pill.tag-quality {
1522
+ background: rgba(234, 179, 8, 0.08);
1523
+ border-color: rgba(234, 179, 8, 0.25);
1524
+ color: #ca8a04;
1525
+ }
1526
+
1527
+ .dsh-a6-smart-pill.tag-guarantee {
1528
+ background: rgba(16, 185, 129, 0.12);
1529
+ border-color: rgba(16, 185, 129, 0.35);
1530
+ color: #059669;
1531
+ }
1532
+
1533
+ /* Right Actions Group */
1534
+ .dsh-a6-bar-actions {
1535
+ display: flex;
1536
+ align-items: center;
1537
+ gap: 8px;
1538
+ flex-shrink: 0;
1539
+ }
1540
+
1541
+ .dsh-a6-time-ago {
1542
+ font-size: 11px;
1543
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
1544
+ }
1545
+
1546
+ .dsh-a6-btn-in-dsh {
1547
+ background: rgba(16, 185, 129, 0.12);
1548
+ border: 1px solid rgba(16, 185, 129, 0.35);
1549
+ color: #059669;
1550
+ }
1551
+
1552
+ .dsh-a6-btn-in-dsh:hover {
1553
+ background: rgba(16, 185, 129, 0.2);
1554
+ }
1555
+
1556
+ .dsh-a6-expand-toggle-btn {
1557
+ background: transparent;
1558
+ border: 1px solid var(--dsw-alias-border-l3, #cbd5e1);
1559
+ border-radius: 6px;
1560
+ color: var(--dsw-alias-label-secondary, #64748b);
1561
+ cursor: pointer;
1562
+ font-size: 11px;
1563
+ padding: 4px 8px;
1564
+ height: 28px;
1565
+ transition: all 0.15s;
1566
+ }
1567
+
1568
+ .dsh-a6-expand-toggle-btn:hover {
1569
+ background: var(--dsw-alias-bg-layer-1, rgba(0, 0, 0, 0.04));
1570
+ color: var(--dsw-alias-label-primary, #0f172a);
1571
+ }
1572
+
1573
+ /* ==========================================================================
1574
+ 4. Bottom Detailed Comparison Box
1575
+ ========================================================================== */
1576
+ .dsh-a6-detail-container {
1577
+ background: var(--dsw-alias-bg-layer-1, rgba(0, 0, 0, 0.02));
1578
+ border: 1px solid var(--dsw-alias-border-l3, rgba(226, 232, 240, 0.8));
1579
+ border-radius: 8px;
1580
+ padding: 10px 14px;
1581
+ display: flex;
1582
+ flex-direction: column;
1583
+ gap: 8px;
1584
+ }
1585
+
1586
+ .dsh-a6-detail-top-row {
1587
+ display: flex;
1588
+ justify-content: space-between;
1589
+ align-items: center;
1590
+ gap: 12px;
1591
+ flex-wrap: wrap;
1592
+ }
1593
+
1594
+ .dsh-a6-dt-left,
1595
+ .dsh-a6-dt-right {
1596
+ display: flex;
1597
+ align-items: center;
1598
+ gap: 8px;
1599
+ }
1600
+
1601
+ .dsh-a6-dt-label {
1602
+ font-size: 11px;
1603
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
1604
+ }
1605
+
1606
+ .dsh-a6-dt-desc {
1607
+ font-size: 12px;
1608
+ font-weight: 500;
1609
+ color: var(--dsw-alias-label-primary, #1e293b);
1610
+ }
1611
+
1612
+ .dsh-a6-dt-channel-name {
1613
+ font-size: 12px;
1614
+ font-weight: 500;
1615
+ color: #3b82f6;
1616
+ }
1617
+
1618
+ .dsh-a6-dt-divider {
1619
+ height: 1px;
1620
+ background: var(--dsw-alias-border-l3, rgba(226, 232, 240, 0.6));
1621
+ margin: 1px 0;
1622
+ }
1623
+
1624
+ /* Price Comparison Table */
1625
+ .dsh-a6-dt-table-col {
1626
+ overflow-x: auto;
1627
+ }
1628
+
1629
+ .dsh-a6-price-table {
1630
+ width: 100%;
1631
+ border-collapse: collapse;
1632
+ font-size: 12px;
1633
+ text-align: left;
1634
+ }
1635
+
1636
+ .dsh-a6-price-table th {
1637
+ padding: 4px 8px;
1638
+ font-size: 11px;
1639
+ font-weight: 500;
1640
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
1641
+ border-bottom: 1px solid var(--dsw-alias-border-l3, rgba(226, 232, 240, 0.6));
1642
+ }
1643
+
1644
+ .dsh-a6-th-blank {
1645
+ width: 50px;
1646
+ }
1647
+
1648
+ .dsh-a6-price-table td {
1649
+ padding: 5px 8px;
1650
+ }
1651
+
1652
+ .dsh-a6-td-label {
1653
+ color: var(--dsw-alias-label-secondary, #64748b);
1654
+ font-weight: 500;
1655
+ }
1656
+
1657
+ .dsh-a6-tr-official td {
1658
+ color: var(--dsw-alias-label-secondary, #64748b);
1659
+ }
1660
+
1661
+ .dsh-a6-tr-merchant td {
1662
+ color: var(--dsw-alias-label-primary, #0f172a);
1663
+ }
1664
+
1665
+ .dsh-a6-td-bold {
1666
+ font-weight: 700;
1667
+ }
1668
+
1669
+ /* ==========================================================================
1670
+ 5. Account Tab & Asset Panel Styles
1671
+ ========================================================================== */
1672
+ .dsh-a6-account-page {
1673
+ display: flex;
1674
+ flex-direction: column;
1675
+ gap: 14px;
1676
+ }
1677
+
1678
+ .dsh-a6-balance-banner {
1679
+ background: var(--dsw-alias-bg-layer-2, #ffffff);
1680
+ border: 1px solid var(--dsw-alias-border-l2, rgba(226, 232, 240, 0.8));
1681
+ border-radius: 10px;
1682
+ padding: 16px 20px;
1683
+ display: flex;
1684
+ flex-direction: column;
1685
+ gap: 14px;
1686
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.03);
1687
+ position: relative;
1688
+ }
1689
+
1690
+ .dsh-a6-balance-banner::before {
1691
+ content: '';
1692
+ position: absolute;
1693
+ top: 0;
1694
+ left: 0;
1695
+ right: 0;
1696
+ height: 3px;
1697
+ border-top-left-radius: 9px;
1698
+ border-top-right-radius: 9px;
1699
+ background: linear-gradient(90deg, #3b82f6 0%, #10b981 50%, #6366f1 100%);
1700
+ }
1701
+
1702
+ .dsh-a6-balance-banner.low-balance::before {
1703
+ background: linear-gradient(90deg, #ef4444 0%, #f59e0b 100%);
1704
+ }
1705
+
1706
+ .dsh-a6-balance-header {
1707
+ display: flex;
1708
+ justify-content: space-between;
1709
+ align-items: flex-start;
1710
+ gap: 16px;
1711
+ flex-wrap: wrap;
1712
+ }
1713
+
1714
+ .dsh-a6-balance-left {
1715
+ display: flex;
1716
+ flex-direction: column;
1717
+ gap: 6px;
1718
+ }
1719
+
1720
+ .dsh-a6-balance-main-title {
1721
+ display: flex;
1722
+ flex-direction: column;
1723
+ gap: 4px;
1724
+ }
1725
+
1726
+ .dsh-a6-balance-label {
1727
+ font-size: 12px;
1728
+ font-weight: 500;
1729
+ color: var(--dsw-alias-label-secondary, #64748b);
1730
+ }
1731
+
1732
+ .dsh-a6-balance-num-row {
1733
+ display: flex;
1734
+ align-items: baseline;
1735
+ gap: 10px;
1736
+ flex-wrap: wrap;
1737
+ }
1738
+
1739
+ .dsh-a6-balance-amount {
1740
+ font-size: 26px;
1741
+ font-weight: 700;
1742
+ color: #10b981;
1743
+ letter-spacing: -0.5px;
1744
+ line-height: 1.1;
1745
+ }
1746
+
1747
+ .dsh-a6-balance-amount.unauthed {
1748
+ font-size: 22px;
1749
+ color: var(--dsw-alias-label-secondary, #64748b);
1750
+ }
1751
+
1752
+ .dsh-a6-balance-banner.low-balance .dsh-a6-balance-amount {
1753
+ color: #ef4444;
1754
+ }
1755
+
1756
+ .dsh-a6-balance-cny {
1757
+ font-size: 14px;
1758
+ font-weight: 500;
1759
+ color: var(--dsw-alias-label-secondary, #64748b);
1760
+ }
1761
+
1762
+ .dsh-a6-status-pill {
1763
+ font-size: 11px;
1764
+ font-weight: 500;
1765
+ padding: 2px 8px;
1766
+ border-radius: 12px;
1767
+ display: inline-flex;
1768
+ align-items: center;
1769
+ }
1770
+
1771
+ .dsh-a6-status-pill.success {
1772
+ background: rgba(16, 185, 129, 0.12);
1773
+ color: #10b981;
1774
+ border: 1px solid rgba(16, 185, 129, 0.25);
1775
+ }
1776
+
1777
+ .dsh-a6-status-pill.warn {
1778
+ background: rgba(245, 158, 11, 0.12);
1779
+ color: #f59e0b;
1780
+ border: 1px solid rgba(245, 158, 11, 0.25);
1781
+ }
1782
+
1783
+ .dsh-a6-low-alert {
1784
+ display: inline-flex;
1785
+ align-items: center;
1786
+ background: rgba(239, 68, 68, 0.12);
1787
+ color: #ef4444;
1788
+ padding: 4px 10px;
1789
+ border-radius: 6px;
1790
+ font-size: 12px;
1791
+ font-weight: 500;
1792
+ width: fit-content;
1793
+ }
1794
+
1795
+ .dsh-a6-balance-actions {
1796
+ display: flex;
1797
+ align-items: center;
1798
+ gap: 8px;
1799
+ flex-wrap: wrap;
1800
+ }
1801
+
1802
+ /* Stat KPI Cards Grid */
1803
+ .dsh-a6-stat-cards-grid {
1804
+ display: grid;
1805
+ grid-template-columns: repeat(4, 1fr);
1806
+ gap: 10px;
1807
+ }
1808
+
1809
+ @media (max-width: 768px) {
1810
+ .dsh-a6-stat-cards-grid {
1811
+ grid-template-columns: repeat(2, 1fr);
1812
+ }
1813
+ }
1814
+
1815
+ .dsh-a6-kpi-card {
1816
+ background: var(--dsw-alias-bg-layer-1, rgba(0, 0, 0, 0.02));
1817
+ border: 1px solid var(--dsw-alias-border-l3, rgba(226, 232, 240, 0.6));
1818
+ border-radius: 8px;
1819
+ padding: 10px 12px;
1820
+ display: flex;
1821
+ flex-direction: column;
1822
+ gap: 4px;
1823
+ }
1824
+
1825
+ .dsh-a6-kpi-label {
1826
+ font-size: 11px;
1827
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
1828
+ }
1829
+
1830
+ .dsh-a6-kpi-val {
1831
+ font-size: 13px;
1832
+ font-weight: 600;
1833
+ color: var(--dsw-alias-label-primary, #0f172a);
1834
+ }
1835
+
1836
+ /* Auth Banner Box */
1837
+ .dsh-a6-auth-banner-box {
1838
+ display: flex;
1839
+ justify-content: space-between;
1840
+ align-items: center;
1841
+ gap: 14px;
1842
+ padding: 12px 16px;
1843
+ background: rgba(59, 130, 246, 0.06);
1844
+ border: 1px solid rgba(59, 130, 246, 0.2);
1845
+ border-radius: 8px;
1846
+ flex-wrap: wrap;
1847
+ }
1848
+
1849
+ .dsh-a6-auth-banner-title {
1850
+ font-size: 13px;
1851
+ font-weight: 600;
1852
+ color: #2563eb;
1853
+ margin-bottom: 2px;
1854
+ }
1855
+
1856
+ .dsh-a6-auth-banner-desc {
1857
+ font-size: 12px;
1858
+ color: var(--dsw-alias-label-secondary, #475569);
1859
+ line-height: 1.4;
1860
+ }
1861
+
1862
+ /* Recent Logs Section */
1863
+ .dsh-a6-logs-section {
1864
+ background: var(--dsw-alias-bg-layer-2, #ffffff);
1865
+ border: 1px solid var(--dsw-alias-border-l2, #e2e8f0);
1866
+ border-radius: 10px;
1867
+ padding: 14px 18px;
1868
+ display: flex;
1869
+ flex-direction: column;
1870
+ gap: 10px;
1871
+ }
1872
+
1873
+ .dsh-a6-logs-header {
1874
+ display: flex;
1875
+ flex-direction: column;
1876
+ gap: 2px;
1877
+ }
1878
+
1879
+ .dsh-a6-logs-title {
1880
+ font-size: 13px;
1881
+ font-weight: 600;
1882
+ color: var(--dsw-alias-label-primary, #0f172a);
1883
+ }
1884
+
1885
+ .dsh-a6-logs-subtitle {
1886
+ font-size: 11px;
1887
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
1888
+ }
1889
+
1890
+ .dsh-a6-logs-table-wrapper {
1891
+ overflow-x: auto;
1892
+ }
1893
+
1894
+ .dsh-a6-logs-table {
1895
+ width: 100%;
1896
+ border-collapse: collapse;
1897
+ font-size: 12px;
1898
+ text-align: left;
1899
+ }
1900
+
1901
+ .dsh-a6-logs-table th {
1902
+ padding: 6px 8px;
1903
+ font-size: 11px;
1904
+ font-weight: 600;
1905
+ color: var(--dsw-alias-label-secondary, #64748b);
1906
+ border-bottom: 1px solid var(--dsw-alias-border-l2, #e2e8f0);
1907
+ }
1908
+
1909
+ .dsh-a6-logs-table td {
1910
+ padding: 6px 8px;
1911
+ border-bottom: 1px solid var(--dsw-alias-border-l3, rgba(226, 232, 240, 0.5));
1912
+ }
1913
+
1914
+ .dsh-a6-log-time {
1915
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
1916
+ font-size: 11px;
1917
+ }
1918
+
1919
+ .dsh-a6-log-channel-badge {
1920
+ font-size: 11px;
1921
+ padding: 2px 6px;
1922
+ background: rgba(59, 130, 246, 0.08);
1923
+ color: #3b82f6;
1924
+ border-radius: 4px;
1925
+ }
1926
+
1927
+ .dsh-a6-log-status {
1928
+ font-size: 11px;
1929
+ font-weight: 500;
1930
+ padding: 1px 6px;
1931
+ border-radius: 10px;
1932
+ }
1933
+
1934
+ .dsh-a6-log-status.ok {
1935
+ background: rgba(16, 185, 129, 0.12);
1936
+ color: #10b981;
1937
+ }
1938
+
1939
+ .dsh-a6-log-status.err {
1940
+ background: rgba(239, 68, 68, 0.12);
1941
+ color: #ef4444;
1942
+ }
1943
+
1944
+ .dsh-a6-log-cost {
1945
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, monospace;
1946
+ font-size: 11px;
1947
+ color: var(--dsw-alias-label-secondary, #475569);
1948
+ font-weight: 500;
1949
+ }
1950
+
1951
+ .dsh-a6-btn-refresh-ok {
1952
+ color: #10b981 !important;
1953
+ border-color: rgba(16, 185, 129, 0.4) !important;
1954
+ background: rgba(16, 185, 129, 0.08) !important;
1955
+ }
1956
+
1957
+ .dsh-a6-empty-logs {
1958
+ padding: 20px;
1959
+ text-align: center;
1960
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
1961
+ font-size: 12px;
1962
+ }
1963
+
1964
+ /* ==========================================================================
1965
+ 6. Configuration Tab Styles
1966
+ ========================================================================== */
1967
+ .dsh-a6-config-page {
1968
+ display: flex;
1969
+ flex-direction: column;
1970
+ gap: 14px;
1971
+ }
1972
+
1973
+ .dsh-a6-config-section {
1974
+ background: var(--dsw-alias-bg-layer-2, #ffffff);
1975
+ border: 1px solid var(--dsw-alias-border-l2, #e2e8f0);
1976
+ border-radius: 10px;
1977
+ padding: 16px 18px;
1978
+ display: flex;
1979
+ flex-direction: column;
1980
+ gap: 10px;
1981
+ }
1982
+
1983
+ .dsh-a6-section-heading {
1984
+ display: flex;
1985
+ flex-direction: column;
1986
+ gap: 2px;
1987
+ }
1988
+
1989
+ .dsh-a6-heading-title {
1990
+ font-size: 13px;
1991
+ font-weight: 600;
1992
+ color: var(--dsw-alias-label-primary, #0f172a);
1993
+ }
1994
+
1995
+ .dsh-a6-heading-desc {
1996
+ font-size: 11px;
1997
+ color: var(--dsw-alias-label-secondary, #64748b);
1998
+ line-height: 1.4;
1999
+ }
2000
+
2001
+ .dsh-a6-node-picker {
2002
+ display: flex;
2003
+ gap: 8px;
2004
+ flex-wrap: wrap;
2005
+ }
2006
+
2007
+ .dsh-a6-node-pill {
2008
+ padding: 5px 12px;
2009
+ border-radius: 6px;
2010
+ border: 1px solid var(--dsw-alias-border-l3, #cbd5e1);
2011
+ background: var(--dsw-alias-bg-layer-1, #ffffff);
2012
+ font-size: 12px;
2013
+ color: var(--dsw-alias-label-secondary, #475569);
2014
+ cursor: pointer;
2015
+ transition: all 0.15s;
2016
+ }
2017
+
2018
+ .dsh-a6-node-pill:hover {
2019
+ background: var(--dsw-alias-bg-layer-2, #f8fafc);
2020
+ border-color: #94a3b8;
2021
+ }
2022
+
2023
+ .dsh-a6-node-pill.active {
2024
+ background: #3b82f6;
2025
+ color: #ffffff;
2026
+ border-color: #3b82f6;
2027
+ font-weight: 500;
2028
+ }
2029
+
2030
+ .dsh-a6-config-fields-grid {
2031
+ display: flex;
2032
+ gap: 14px;
2033
+ }
2034
+
2035
+ @media (max-width: 768px) {
2036
+ .dsh-a6-config-fields-grid {
2037
+ flex-direction: column;
2038
+ }
2039
+ }
2040
+
2041
+ .dsh-a6-field {
2042
+ display: flex;
2043
+ flex-direction: column;
2044
+ gap: 5px;
2045
+ flex: 1;
2046
+ }
2047
+
2048
+ .dsh-a6-field-header {
2049
+ display: flex;
2050
+ justify-content: space-between;
2051
+ align-items: center;
2052
+ }
2053
+
2054
+ .dsh-a6-label {
2055
+ font-size: 12px;
2056
+ font-weight: 600;
2057
+ color: var(--dsw-alias-label-secondary, #475569);
2058
+ }
2059
+
2060
+ .dsh-a6-field-hint {
2061
+ font-size: 11px;
2062
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
2063
+ line-height: 1.4;
2064
+ }
2065
+
2066
+ .dsh-a6-field-footer {
2067
+ display: flex;
2068
+ justify-content: space-between;
2069
+ align-items: center;
2070
+ gap: 8px;
2071
+ margin-top: 1px;
2072
+ }
2073
+
2074
+ .dsh-a6-input-wrapper {
2075
+ position: relative;
2076
+ display: flex;
2077
+ align-items: center;
2078
+ }
2079
+
2080
+ .dsh-a6-input {
2081
+ width: 100%;
2082
+ height: 32px;
2083
+ padding: 0 10px;
2084
+ border-radius: 6px;
2085
+ border: 1px solid var(--dsw-alias-border-l3, #cbd5e1);
2086
+ background: var(--dsw-alias-bg-layer-1, #ffffff);
2087
+ color: var(--dsw-alias-label-primary, #1e293b);
2088
+ font-size: 12px;
2089
+ outline: none;
2090
+ box-sizing: border-box;
2091
+ transition: border-color 0.15s, box-shadow 0.15s;
2092
+ }
2093
+
2094
+ .dsh-a6-input:focus {
2095
+ border-color: #3b82f6;
2096
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
2097
+ }
2098
+
2099
+ .dsh-a6-help-drawer {
2100
+ background: var(--dsw-alias-bg-layer-1, #f8fafc);
2101
+ border: 1px dashed var(--dsw-alias-border-l2, #cbd5e1);
2102
+ border-radius: 8px;
2103
+ padding: 10px 14px;
2104
+ font-size: 11px;
2105
+ color: var(--dsw-alias-label-secondary, #475569);
2106
+ }
2107
+
2108
+ .dsh-a6-help-title {
2109
+ font-weight: 600;
2110
+ color: var(--dsw-alias-label-primary, #0f172a);
2111
+ margin-bottom: 4px;
2112
+ }
2113
+
2114
+ .dsh-a6-help-list {
2115
+ margin: 0;
2116
+ padding-left: 18px;
2117
+ display: flex;
2118
+ flex-direction: column;
2119
+ gap: 3px;
2120
+ }
2121
+
2122
+ .dsh-a6-help-list code {
2123
+ background: rgba(0, 0, 0, 0.06);
2124
+ padding: 1px 4px;
2125
+ border-radius: 3px;
2126
+ font-size: 10px;
2127
+ }
2128
+
2129
+ .dsh-a6-integration-card {
2130
+ background: var(--dsw-alias-bg-layer-1, rgba(0, 0, 0, 0.02));
2131
+ border: 1px solid var(--dsw-alias-border-l3, rgba(226, 232, 240, 0.6));
2132
+ border-radius: 8px;
2133
+ padding: 10px 14px;
2134
+ display: flex;
2135
+ flex-direction: column;
2136
+ gap: 6px;
2137
+ }
2138
+
2139
+ .dsh-a6-int-row {
2140
+ display: flex;
2141
+ align-items: center;
2142
+ gap: 10px;
2143
+ font-size: 12px;
2144
+ }
2145
+
2146
+ .dsh-a6-int-key {
2147
+ width: 100px;
2148
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
2149
+ }
2150
+
2151
+ .dsh-a6-int-val {
2152
+ font-weight: 600;
2153
+ color: var(--dsw-alias-label-primary, #0f172a);
2154
+ }
2155
+
2156
+ .dsh-a6-int-tags {
2157
+ display: flex;
2158
+ gap: 6px;
2159
+ flex-wrap: wrap;
2160
+ }
2161
+
2162
+ .dsh-a6-model-chip {
2163
+ font-size: 11px;
2164
+ font-weight: 500;
2165
+ padding: 2px 7px;
2166
+ border-radius: 4px;
2167
+ background: rgba(16, 185, 129, 0.12);
2168
+ color: #059669;
2169
+ border: 1px solid rgba(16, 185, 129, 0.25);
2170
+ }
2171
+
2172
+ .dsh-a6-empty-hint {
2173
+ color: var(--dsw-alias-label-tertiary, #94a3b8);
2174
+ font-size: 12px;
2175
+ }
2176
+
2177
+ .dsh-a6-save-bar {
2178
+ display: flex;
2179
+ justify-content: space-between;
2180
+ align-items: center;
2181
+ gap: 12px;
2182
+ }
2183
+
2184
+ .dsh-a6-success-msg {
2185
+ color: #10b981;
2186
+ font-size: 12px;
2187
+ font-weight: 500;
2188
+ }
2189
+
2190
+ /* ==========================================================================
2191
+ 7. Buttons & Common State Styles
2192
+ ========================================================================== */
2193
+ .dsh-a6-btn {
2194
+ display: inline-flex;
2195
+ align-items: center;
2196
+ justify-content: center;
2197
+ gap: 6px;
2198
+ height: 30px;
2199
+ padding: 0 10px;
2200
+ border-radius: 6px;
2201
+ font-size: 12px;
2202
+ font-weight: 500;
2203
+ cursor: pointer;
2204
+ border: 1px solid transparent;
2205
+ transition: all 0.15s;
2206
+ white-space: nowrap;
2207
+ }
2208
+
2209
+ .dsh-a6-btn-primary {
2210
+ background: #3b82f6;
2211
+ color: #ffffff;
2212
+ }
2213
+
2214
+ .dsh-a6-btn-primary:hover {
2215
+ background: #2563eb;
2216
+ }
2217
+
2218
+ .dsh-a6-btn-secondary {
2219
+ background: var(--dsw-alias-bg-layer-1, #ffffff);
2220
+ border-color: var(--dsw-alias-border-l3, #cbd5e1);
2221
+ color: var(--dsw-alias-label-primary, #334155);
2222
+ }
2223
+
2224
+ .dsh-a6-btn-secondary:hover {
2225
+ background: var(--dsw-alias-bg-layer-2, #f8fafc);
2226
+ border-color: #94a3b8;
2227
+ }
2228
+
2229
+ .dsh-a6-btn-sm {
2230
+ height: 28px;
2231
+ padding: 0 9px;
2232
+ font-size: 12px;
2233
+ }
2234
+
2235
+ .dsh-a6-btn-xs {
2236
+ height: 26px;
2237
+ padding: 0 8px;
2238
+ font-size: 11px;
2239
+ }
2240
+
2241
+ .dsh-a6-btn-text {
2242
+ background: transparent;
2243
+ border: none;
2244
+ color: #3b82f6;
2245
+ font-size: 11px;
2246
+ font-weight: 500;
2247
+ cursor: pointer;
2248
+ padding: 1px 3px;
2249
+ }
2250
+
2251
+ .dsh-a6-btn-text:hover {
2252
+ text-decoration: underline;
2253
+ }
2254
+
2255
+ .dsh-a6-empty-state {
2256
+ text-align: center;
2257
+ padding: 36px 20px;
2258
+ background: var(--dsw-alias-bg-layer-2, #ffffff);
2259
+ border: 1px dashed var(--dsw-alias-border-l2, #e2e8f0);
2260
+ border-radius: 10px;
2261
+ color: var(--dsw-alias-label-secondary, #64748b);
2262
+ font-size: 13px;
2263
+ display: flex;
2264
+ flex-direction: column;
2265
+ align-items: center;
2266
+ gap: 10px;
2267
+ }
2268
+
2269
+ .dsh-a6-spinner {
2270
+ width: 20px;
2271
+ height: 20px;
2272
+ border: 2px solid rgba(59, 130, 246, 0.2);
2273
+ border-top-color: #3b82f6;
2274
+ border-radius: 50%;
2275
+ animation: dsh-a6-spin 0.8s linear infinite;
2276
+ }
2277
+
2278
+ @keyframes dsh-a6-spin {
2279
+ to {
2280
+ transform: rotate(360deg);
2281
+ }
2282
+ }
2283
+
2284
+ /* ==========================================================================
2285
+ 8. Instant Custom Tooltip (Zero-Delay, High Contrast)
2286
+ ========================================================================== */
2287
+ [data-tooltip] {
2288
+ position: relative;
2289
+ }
2290
+
2291
+ [data-tooltip]::after {
2292
+ content: attr(data-tooltip);
2293
+ position: absolute;
2294
+ bottom: calc(100% + 7px);
2295
+ left: 50%;
2296
+ transform: translateX(-50%);
2297
+ padding: 5px 9px;
2298
+ background: rgba(15, 23, 42, 0.94);
2299
+ color: #f8fafc;
2300
+ font-size: 11px;
2301
+ font-weight: 400;
2302
+ line-height: 1.35;
2303
+ white-space: nowrap;
2304
+ border-radius: 5px;
2305
+ box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
2306
+ pointer-events: none;
2307
+ opacity: 0;
2308
+ visibility: hidden;
2309
+ transition: opacity 0.04s ease-out, visibility 0.04s ease-out;
2310
+ z-index: 99999;
2311
+ border: 1px solid rgba(255, 255, 255, 0.12);
2312
+ }
2313
+
2314
+ [data-tooltip]::before {
2315
+ content: '';
2316
+ position: absolute;
2317
+ bottom: calc(100% + 2px);
2318
+ left: 50%;
2319
+ transform: translateX(-50%);
2320
+ border-width: 5px 5px 0 5px;
2321
+ border-style: solid;
2322
+ border-color: rgba(15, 23, 42, 0.94) transparent transparent transparent;
2323
+ pointer-events: none;
2324
+ opacity: 0;
2325
+ visibility: hidden;
2326
+ transition: opacity 0.04s ease-out, visibility 0.04s ease-out;
2327
+ z-index: 99999;
2328
+ }
2329
+
2330
+ [data-tooltip]:hover::after,
2331
+ [data-tooltip]:hover::before {
2332
+ opacity: 1;
2333
+ visibility: visible;
2334
+ }
2335
+
2336
+ [data-tooltip-pos="left"]::after {
2337
+ left: auto;
2338
+ right: 0;
2339
+ transform: none;
2340
+ }
2341
+
2342
+ [data-tooltip-pos="left"]::before {
2343
+ left: auto;
2344
+ right: 14px;
2345
+ transform: none;
2346
+ }
2347
+
2348
+ [data-tooltip-pos="right"]::after {
2349
+ left: 0;
2350
+ right: auto;
2351
+ transform: none;
2352
+ }
2353
+
2354
+ [data-tooltip-pos="right"]::before {
2355
+ left: 14px;
2356
+ right: auto;
2357
+ transform: none;
2358
+ }
2359
+
2360
+ /* Down positions (for top toolbar and header buttons) */
2361
+ [data-tooltip-pos="down"]::after {
2362
+ top: calc(100% + 7px);
2363
+ bottom: auto;
2364
+ left: 50%;
2365
+ right: auto;
2366
+ transform: translateX(-50%);
2367
+ }
2368
+
2369
+ [data-tooltip-pos="down"]::before {
2370
+ top: calc(100% + 2px);
2371
+ bottom: auto;
2372
+ left: 50%;
2373
+ right: auto;
2374
+ transform: translateX(-50%);
2375
+ border-width: 0 5px 5px 5px;
2376
+ border-color: transparent transparent rgba(15, 23, 42, 0.94) transparent;
2377
+ }
2378
+
2379
+ [data-tooltip-pos="down-left"]::after {
2380
+ top: calc(100% + 7px);
2381
+ bottom: auto;
2382
+ left: auto;
2383
+ right: 0;
2384
+ transform: none;
2385
+ }
2386
+
2387
+ [data-tooltip-pos="down-left"]::before {
2388
+ top: calc(100% + 2px);
2389
+ bottom: auto;
2390
+ left: auto;
2391
+ right: 14px;
2392
+ transform: none;
2393
+ border-width: 0 5px 5px 5px;
2394
+ border-color: transparent transparent rgba(15, 23, 42, 0.94) transparent;
2395
+ }
2396
+
2397
+ [data-tooltip-pos="down-right"]::after {
2398
+ top: calc(100% + 7px);
2399
+ bottom: auto;
2400
+ left: 0;
2401
+ right: auto;
2402
+ transform: none;
2403
+ }
2404
+
2405
+ [data-tooltip-pos="down-right"]::before {
2406
+ top: calc(100% + 2px);
2407
+ bottom: auto;
2408
+ left: 14px;
2409
+ right: auto;
2410
+ transform: none;
2411
+ border-width: 0 5px 5px 5px;
2412
+ border-color: transparent transparent rgba(15, 23, 42, 0.94) transparent;
2413
+ }
2414
+
2415
+ /* Card actions tooltip default alignment */
2416
+ .dsh-a6-bar-actions [data-tooltip]:not([data-tooltip-pos])::after {
2417
+ left: 0;
2418
+ transform: none;
2419
+ }
2420
+
2421
+ .dsh-a6-bar-actions [data-tooltip]:not([data-tooltip-pos])::before {
2422
+ left: 16px;
2423
+ transform: none;
2424
+ }
2425
+ `;
2426
+
2427
+ // src/client/index.ts
2428
+ var name = "@lynn123411/dsh-a6api";
2429
+ var inject = ["slots"];
2430
+ function injectStyles() {
2431
+ if (typeof document === "undefined") return;
2432
+ const styleId = "dsh-a6api-styles";
2433
+ if (!document.getElementById(styleId)) {
2434
+ const style = document.createElement("style");
2435
+ style.id = styleId;
2436
+ style.textContent = main_default;
2437
+ document.head.appendChild(style);
2438
+ }
2439
+ }
2440
+ function apply(ctx) {
2441
+ injectStyles();
2442
+ if (typeof window === "undefined") return;
2443
+ try {
2444
+ const slots = ctx?.slots || (ctx?.get ? ctx.get("slots") : null);
2445
+ if (!slots || typeof slots.inject !== "function") return;
2446
+ slots.inject("settings.section", () => {
2447
+ return slots.register(
2448
+ {
2449
+ name: "settings.section",
2450
+ id: "dsh-a6api",
2451
+ order: 4,
2452
+ label: () => "A6API \u805A\u5408\u7AD9"
2453
+ },
2454
+ A6ApiSettingsPanel
2455
+ );
2456
+ });
2457
+ } catch (err) {
2458
+ console.warn("[dsh-a6api] Failed to inject settings section:", err);
2459
+ }
2460
+ }
2461
+ return module.exports; } });
2462
+ //# sourceMappingURL=client.js.map