@eddyskywalker/dsh-chatgpt-subscription 0.42.0 → 0.43.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -0
- package/README.md +1 -0
- package/lib/client.js +256 -182
- package/lib/client.js.map +1 -1
- package/lib/index.js +813 -237
- package/lib/types/client/command-code/CommandCodeComposerQuota.d.ts.map +1 -1
- package/lib/types/client/common/format.d.ts +16 -0
- package/lib/types/client/common/format.d.ts.map +1 -1
- package/lib/types/client/kimi-code/KimiCodeComposerQuota.d.ts.map +1 -1
- package/lib/types/client/kimi-code/KimiCodeSection.d.ts.map +1 -1
- package/lib/types/client/kimi-code/KimiQuotaCard.d.ts.map +1 -1
- package/lib/types/client/kimi-code/styles.d.ts.map +1 -1
- package/lib/types/client/locales-ru/opendesign.d.ts.map +1 -1
- package/lib/types/client/locales-ru/qoder.d.ts.map +1 -1
- package/lib/types/client/opendesign/OpenDesignSection.d.ts.map +1 -1
- package/lib/types/client/opendesign/locales.d.ts +12 -0
- package/lib/types/client/opendesign/locales.d.ts.map +1 -1
- package/lib/types/client/qoder/QoderSection.d.ts.map +1 -1
- package/lib/types/client/qoder/locales.d.ts +9 -1
- package/lib/types/client/qoder/locales.d.ts.map +1 -1
- package/lib/types/client/qoder/styles.d.ts.map +1 -1
- package/lib/types/compat.d.ts +1 -1
- package/lib/types/host/claude/types.d.ts +7 -1
- package/lib/types/host/claude/types.d.ts.map +1 -1
- package/lib/types/host/glm-coding-plan/types.d.ts +5 -1
- package/lib/types/host/glm-coding-plan/types.d.ts.map +1 -1
- package/lib/types/host/kimi-code/account-pool.d.ts +26 -1
- package/lib/types/host/kimi-code/account-pool.d.ts.map +1 -1
- package/lib/types/host/kimi-code/client.d.ts +24 -0
- package/lib/types/host/kimi-code/client.d.ts.map +1 -1
- package/lib/types/host/kimi-code/oauth.d.ts +16 -0
- package/lib/types/host/kimi-code/oauth.d.ts.map +1 -1
- package/lib/types/host/kimi-code/routes.d.ts.map +1 -1
- package/lib/types/host/opendesign/adapter.d.ts +11 -13
- package/lib/types/host/opendesign/adapter.d.ts.map +1 -1
- package/lib/types/host/opendesign/catalog.d.ts +14 -0
- package/lib/types/host/opendesign/catalog.d.ts.map +1 -1
- package/lib/types/host/opendesign/line.d.ts +17 -6
- package/lib/types/host/opendesign/line.d.ts.map +1 -1
- package/lib/types/host/opendesign/routes.d.ts.map +1 -1
- package/lib/types/host/opendesign/token-store.d.ts +91 -4
- package/lib/types/host/opendesign/token-store.d.ts.map +1 -1
- package/lib/types/host/opendesign/types.d.ts.map +1 -1
- package/lib/types/host/qoder/client.d.ts.map +1 -1
- package/lib/types/host/qoder/mapper.d.ts +74 -2
- package/lib/types/host/qoder/mapper.d.ts.map +1 -1
- package/lib/types/host/qoder/types.d.ts +6 -1
- package/lib/types/host/qoder/types.d.ts.map +1 -1
- package/lib/types/host/step-code/types.d.ts +5 -1
- package/lib/types/host/step-code/types.d.ts.map +1 -1
- package/lib/types/shared/opendesign-contracts.d.ts +24 -1
- package/lib/types/shared/opendesign-contracts.d.ts.map +1 -1
- package/lib/types/shared/qoder-contracts.d.ts +10 -0
- package/lib/types/shared/qoder-contracts.d.ts.map +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -146,11 +146,11 @@ window.__ModuleLoader__.load({
|
|
|
146
146
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
147
147
|
className: "dsh-codex-composer-quota",
|
|
148
148
|
"data-level": quota === null ? "normal" : quota.remainingPercent <= 5 ? "danger" : quota.remainingPercent <= 20 ? "warning" : "normal",
|
|
149
|
-
"aria-label": quota === null ? t("quickQuotaLoading") : `${t("quickQuotaLabel")}: ${formatPercent$
|
|
150
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("quickQuotaLabel") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: quota === null ? loading ? t("quickQuotaLoading") : "—" : formatPercent$
|
|
149
|
+
"aria-label": quota === null ? t("quickQuotaLoading") : `${t("quickQuotaLabel")}: ${formatPercent$2(quota.remainingPercent)}`,
|
|
150
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("quickQuotaLabel") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: quota === null ? loading ? t("quickQuotaLoading") : "—" : formatPercent$2(quota.remainingPercent) })]
|
|
151
151
|
});
|
|
152
152
|
}
|
|
153
|
-
function formatPercent$
|
|
153
|
+
function formatPercent$2(value) {
|
|
154
154
|
return `${new Intl.NumberFormat(void 0, { maximumFractionDigits: 0 }).format(value)}%`;
|
|
155
155
|
}
|
|
156
156
|
//#endregion
|
|
@@ -1147,6 +1147,26 @@ window.__ModuleLoader__.load({
|
|
|
1147
1147
|
if (value >= 1e3) return Math.round(value / 1e3) + "k";
|
|
1148
1148
|
return String(value);
|
|
1149
1149
|
}
|
|
1150
|
+
/**
|
|
1151
|
+
* A share as a person reads it: at most `digits` decimals, no trailing zeros.
|
|
1152
|
+
*
|
|
1153
|
+
* The formatting has to happen on the RESULT rather than on its inputs. Most
|
|
1154
|
+
* percentages on these cards are a remainder — `100 - used` — and that
|
|
1155
|
+
* subtraction is exactly where binary floating point shows up: `100 - 8.04` is
|
|
1156
|
+
* `91.96000000000001`, `100 - 0.0007 * 100` is `99.93` but `100 - 0.0014 * 100`
|
|
1157
|
+
* is `99.86` only because it happens to land on a friendly neighbour. String
|
|
1158
|
+
* interpolation of the difference therefore prints a long tail for roughly a
|
|
1159
|
+
* third of all two-decimal inputs, which reads as "sometimes" — and no amount of
|
|
1160
|
+
* rounding the used share beforehand fixes a subtraction done afterwards.
|
|
1161
|
+
*
|
|
1162
|
+
* Anything non-finite renders as `0`, because every caller has already decided
|
|
1163
|
+
* the window is measured; this is the last line of defence, not a claim.
|
|
1164
|
+
*/
|
|
1165
|
+
function formatPercent$1(value, digits = 2) {
|
|
1166
|
+
if (!Number.isFinite(value)) return "0";
|
|
1167
|
+
const factor = 10 ** Math.min(6, Math.max(0, Math.trunc(digits)));
|
|
1168
|
+
return String(Math.round(value * factor) / factor);
|
|
1169
|
+
}
|
|
1150
1170
|
/** A stamp in the reader's own locale, or an em dash when there is none. */
|
|
1151
1171
|
function formatDate$1(ms) {
|
|
1152
1172
|
if (ms === void 0 || ms === null || !Number.isFinite(ms) || ms <= 0) return "—";
|
|
@@ -5420,10 +5440,12 @@ window.__ModuleLoader__.load({
|
|
|
5420
5440
|
const SHORT_PER_WEEK = 5;
|
|
5421
5441
|
/** 5 小时窗口在月额度里的份数。 */
|
|
5422
5442
|
const SHORT_PER_MONTH = 25;
|
|
5423
|
-
/**
|
|
5443
|
+
/** 提示条箭头离气泡两端的最小距离,免得圆角把三角切掉。 */
|
|
5444
|
+
const ARROW_INSET = 12;
|
|
5445
|
+
/** 百分比,最多两位小数;非有限数不画。舍入规则放在共享的 `formatPercent`。 */
|
|
5424
5446
|
function percentText$2(value) {
|
|
5425
5447
|
if (!Number.isFinite(value)) return "0%";
|
|
5426
|
-
return `${
|
|
5448
|
+
return `${formatPercent$1(value)}%`;
|
|
5427
5449
|
}
|
|
5428
5450
|
/** `YYYY-MM-DD HH:mm`,本地时区;令牌到期用它,年份不能省。 */
|
|
5429
5451
|
function dateText(ms) {
|
|
@@ -5513,6 +5535,43 @@ window.__ModuleLoader__.load({
|
|
|
5513
5535
|
const timer = window.setInterval(() => setClock(Date.now()), 3e4);
|
|
5514
5536
|
return () => window.clearInterval(timer);
|
|
5515
5537
|
}, [shortReset]);
|
|
5538
|
+
const tipPercent = Math.max(0, Math.min(100, totalPercent));
|
|
5539
|
+
const barRef = (0, react.useRef)(null);
|
|
5540
|
+
const tipRef = (0, react.useRef)(null);
|
|
5541
|
+
const [tipPlacement, setTipPlacement] = (0, react.useState)({
|
|
5542
|
+
shift: 0,
|
|
5543
|
+
arrowPx: null
|
|
5544
|
+
});
|
|
5545
|
+
(0, react.useEffect)(() => {
|
|
5546
|
+
const wrap = barRef.current;
|
|
5547
|
+
const tip = tipRef.current;
|
|
5548
|
+
if (wrap === null || tip === null) return void 0;
|
|
5549
|
+
const place = () => {
|
|
5550
|
+
const width = wrap.clientWidth;
|
|
5551
|
+
const bubble = tip.offsetWidth;
|
|
5552
|
+
if (width <= 0 || bubble <= 0) {
|
|
5553
|
+
setTipPlacement({
|
|
5554
|
+
shift: 0,
|
|
5555
|
+
arrowPx: null
|
|
5556
|
+
});
|
|
5557
|
+
return;
|
|
5558
|
+
}
|
|
5559
|
+
const half = bubble / 2;
|
|
5560
|
+
const anchor = width * tipPercent / 100;
|
|
5561
|
+
const clamped = Math.min(Math.max(anchor, half), Math.max(half, width - half));
|
|
5562
|
+
const arrow = Math.min(Math.max(anchor - (clamped - half), ARROW_INSET), bubble - ARROW_INSET);
|
|
5563
|
+
setTipPlacement({
|
|
5564
|
+
shift: Math.round((clamped - anchor) * 10) / 10,
|
|
5565
|
+
arrowPx: Math.round(arrow * 10) / 10
|
|
5566
|
+
});
|
|
5567
|
+
};
|
|
5568
|
+
place();
|
|
5569
|
+
if (typeof ResizeObserver === "undefined") return void 0;
|
|
5570
|
+
const observer = new ResizeObserver(place);
|
|
5571
|
+
observer.observe(wrap);
|
|
5572
|
+
observer.observe(tip);
|
|
5573
|
+
return () => observer.disconnect();
|
|
5574
|
+
}, [tipPercent]);
|
|
5516
5575
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5517
5576
|
className: "dsha-kq",
|
|
5518
5577
|
children: [
|
|
@@ -5564,6 +5623,8 @@ window.__ModuleLoader__.load({
|
|
|
5564
5623
|
}),
|
|
5565
5624
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5566
5625
|
className: "dsha-kq-barwrap",
|
|
5626
|
+
ref: barRef,
|
|
5627
|
+
style: { "--kq-tip-x": `${tipPercent}%` },
|
|
5567
5628
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5568
5629
|
className: "dsha-kq-meter dsha-kq-meter--total",
|
|
5569
5630
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -5578,6 +5639,11 @@ window.__ModuleLoader__.load({
|
|
|
5578
5639
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5579
5640
|
className: "dsha-kq-tip",
|
|
5580
5641
|
role: "tooltip",
|
|
5642
|
+
ref: tipRef,
|
|
5643
|
+
style: {
|
|
5644
|
+
"--kq-tip-shift": `${tipPlacement.shift}px`,
|
|
5645
|
+
...tipPlacement.arrowPx === null ? {} : { "--kq-tip-arrow": `${tipPlacement.arrowPx}px` }
|
|
5646
|
+
},
|
|
5581
5647
|
children: t.kqTip.replace("{pct}", percentText$2(totalPercent))
|
|
5582
5648
|
})]
|
|
5583
5649
|
}),
|
|
@@ -5623,19 +5689,6 @@ window.__ModuleLoader__.load({
|
|
|
5623
5689
|
//#endregion
|
|
5624
5690
|
//#region src/client/kimi-code/KimiCodeSection.tsx
|
|
5625
5691
|
const api$12 = createLineApi("/kimi-code/api", "Kimi Code");
|
|
5626
|
-
/** Money the service reports in minor units, rendered in its own currency. */
|
|
5627
|
-
function formatMoney(cents, currency) {
|
|
5628
|
-
if (cents === null) return "—";
|
|
5629
|
-
const code = currency ?? "USD";
|
|
5630
|
-
try {
|
|
5631
|
-
return new Intl.NumberFormat(void 0, {
|
|
5632
|
-
style: "currency",
|
|
5633
|
-
currency: code
|
|
5634
|
-
}).format(cents / 100);
|
|
5635
|
-
} catch {
|
|
5636
|
-
return `${(cents / 100).toFixed(2)} ${code}`;
|
|
5637
|
-
}
|
|
5638
|
-
}
|
|
5639
5692
|
/**
|
|
5640
5693
|
* One token count as the card prints it.
|
|
5641
5694
|
*
|
|
@@ -6001,7 +6054,7 @@ window.__ModuleLoader__.load({
|
|
|
6001
6054
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6002
6055
|
className: "dsha-page",
|
|
6003
6056
|
children: [
|
|
6004
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
6057
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AccountPoolSection, {
|
|
6005
6058
|
accounts: status?.accounts ?? [],
|
|
6006
6059
|
activeAccountId: status?.activeAccountId,
|
|
6007
6060
|
rotationStrategy: status?.rotationStrategy ?? "sequential",
|
|
@@ -6025,59 +6078,74 @@ window.__ModuleLoader__.load({
|
|
|
6025
6078
|
now,
|
|
6026
6079
|
labels: t
|
|
6027
6080
|
}),
|
|
6028
|
-
children:
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
target: "_blank",
|
|
6051
|
-
rel: "noreferrer noopener",
|
|
6052
|
-
children: flow.verificationUriComplete
|
|
6053
|
-
}),
|
|
6054
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6055
|
-
className: "dsha-row",
|
|
6056
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6057
|
-
className: "dsha-label",
|
|
6058
|
-
children: t.codeExpires
|
|
6059
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6060
|
-
className: "dsha-value",
|
|
6061
|
-
children: formatDate$1(flow?.expiresAt)
|
|
6062
|
-
})]
|
|
6063
|
-
}),
|
|
6064
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6065
|
-
className: "dsha-actions",
|
|
6066
|
-
children: [flow?.verificationUriComplete && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
6067
|
-
className: "dsha-btn",
|
|
6081
|
+
children: [
|
|
6082
|
+
loginPending && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6083
|
+
className: "dsha-device-box",
|
|
6084
|
+
children: [
|
|
6085
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t.deviceCodeSection }),
|
|
6086
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6087
|
+
className: "dsha-muted",
|
|
6088
|
+
children: t.deviceCodeHint
|
|
6089
|
+
}),
|
|
6090
|
+
flow?.userCode && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6091
|
+
className: "dsha-code-row",
|
|
6092
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6093
|
+
className: "dsha-code",
|
|
6094
|
+
children: flow.userCode
|
|
6095
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6096
|
+
className: "dsha-btn",
|
|
6097
|
+
onClick: () => void handleCopyCode(),
|
|
6098
|
+
children: copied ? t.copied : t.copyCode
|
|
6099
|
+
})]
|
|
6100
|
+
}),
|
|
6101
|
+
flow?.verificationUriComplete && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
6102
|
+
className: "dsha-link",
|
|
6068
6103
|
href: flow.verificationUriComplete,
|
|
6069
6104
|
target: "_blank",
|
|
6070
6105
|
rel: "noreferrer noopener",
|
|
6071
|
-
children:
|
|
6072
|
-
}),
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6106
|
+
children: flow.verificationUriComplete
|
|
6107
|
+
}),
|
|
6108
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6109
|
+
className: "dsha-row",
|
|
6110
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6111
|
+
className: "dsha-label",
|
|
6112
|
+
children: t.codeExpires
|
|
6113
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6114
|
+
className: "dsha-value",
|
|
6115
|
+
children: formatDate$1(flow?.expiresAt)
|
|
6116
|
+
})]
|
|
6117
|
+
}),
|
|
6118
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6119
|
+
className: "dsha-actions",
|
|
6120
|
+
children: [flow?.verificationUriComplete && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
6121
|
+
className: "dsha-btn",
|
|
6122
|
+
href: flow.verificationUriComplete,
|
|
6123
|
+
target: "_blank",
|
|
6124
|
+
rel: "noreferrer noopener",
|
|
6125
|
+
children: t.openSignInPage
|
|
6126
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6127
|
+
className: "dsha-btn",
|
|
6128
|
+
disabled: busy !== null,
|
|
6129
|
+
onClick: () => void handleCancelLogin(),
|
|
6130
|
+
children: t.cancelSignIn
|
|
6131
|
+
})]
|
|
6132
|
+
})
|
|
6133
|
+
]
|
|
6134
|
+
}),
|
|
6135
|
+
status?.quotaError != null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6136
|
+
className: "dsha-notice",
|
|
6137
|
+
children: status.quotaError
|
|
6138
|
+
}),
|
|
6139
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6140
|
+
className: "dsha-actions",
|
|
6141
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6142
|
+
className: "dsha-btn",
|
|
6143
|
+
disabled: busy !== null || !status?.authenticated,
|
|
6144
|
+
onClick: () => void handleRefreshQuota(),
|
|
6145
|
+
children: busy === "quota" ? t.refreshingQuota : t.refreshQuota
|
|
6078
6146
|
})
|
|
6079
|
-
|
|
6080
|
-
|
|
6147
|
+
})
|
|
6148
|
+
]
|
|
6081
6149
|
}),
|
|
6082
6150
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
6083
6151
|
className: "dsha-group",
|
|
@@ -6365,69 +6433,6 @@ window.__ModuleLoader__.load({
|
|
|
6365
6433
|
})
|
|
6366
6434
|
]
|
|
6367
6435
|
}),
|
|
6368
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
6369
|
-
className: "dsha-group",
|
|
6370
|
-
children: [
|
|
6371
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6372
|
-
className: "dsha-grouphead",
|
|
6373
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.quotaSection }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6374
|
-
className: "dsha-btn",
|
|
6375
|
-
disabled: busy !== null || !status?.authenticated,
|
|
6376
|
-
onClick: () => void handleRefreshQuota(),
|
|
6377
|
-
children: busy === "quota" ? t.refreshingQuota : t.refreshQuota
|
|
6378
|
-
})]
|
|
6379
|
-
}),
|
|
6380
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6381
|
-
className: "dsha-muted",
|
|
6382
|
-
children: t.quotaDesc
|
|
6383
|
-
}),
|
|
6384
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6385
|
-
className: "dsha-muted",
|
|
6386
|
-
children: t.quotaFactsScope
|
|
6387
|
-
}),
|
|
6388
|
-
status?.quotaError && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
6389
|
-
className: "dsha-notice",
|
|
6390
|
-
children: status.quotaError
|
|
6391
|
-
}),
|
|
6392
|
-
!status?.authenticated ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6393
|
-
className: "dsha-empty",
|
|
6394
|
-
children: t.signedOut
|
|
6395
|
-
}) : quota === null || quota === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6396
|
-
className: "dsha-empty",
|
|
6397
|
-
children: busy === "quota" ? t.refreshingQuota : t.quotaEmpty
|
|
6398
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6399
|
-
className: "dsha-quota-card",
|
|
6400
|
-
children: [
|
|
6401
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6402
|
-
className: "dsha-quota-title",
|
|
6403
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t.quotaPlan }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: quota.planName || t.planUnknown })]
|
|
6404
|
-
}),
|
|
6405
|
-
quota.extraUsage !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6406
|
-
className: "dsha-meter-wrap",
|
|
6407
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6408
|
-
className: "dsha-meter-label",
|
|
6409
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.quotaWallet }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: formatMoney(quota.extraUsage.balanceCents, quota.extraUsage.currency) })]
|
|
6410
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6411
|
-
className: "dsha-meter-meta",
|
|
6412
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: formatMoney(quota.extraUsage.totalCents, quota.extraUsage.currency) }), quota.extraUsage.monthlyChargeLimitEnabled && quota.extraUsage.monthlyChargeLimitCents !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
6413
|
-
t.quotaWalletLimit,
|
|
6414
|
-
": ",
|
|
6415
|
-
formatMoney(quota.extraUsage.monthlyChargeLimitCents, quota.extraUsage.currency)
|
|
6416
|
-
] })]
|
|
6417
|
-
})]
|
|
6418
|
-
}),
|
|
6419
|
-
quota.windows.length === 0 && quota.extraUsage === null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6420
|
-
className: "dsha-empty",
|
|
6421
|
-
children: t.quotaEmpty
|
|
6422
|
-
}),
|
|
6423
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6424
|
-
className: "dsha-timestamp",
|
|
6425
|
-
children: t.updatedAt.replace("{time}", new Date(quota.fetchedAt).toLocaleString())
|
|
6426
|
-
})
|
|
6427
|
-
]
|
|
6428
|
-
})
|
|
6429
|
-
]
|
|
6430
|
-
}),
|
|
6431
6436
|
error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6432
6437
|
className: "dsha-error",
|
|
6433
6438
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: error })
|
|
@@ -15960,6 +15965,10 @@ window.__ModuleLoader__.load({
|
|
|
15960
15965
|
quotaSignedOut: "登录后这里显示账号的额度。",
|
|
15961
15966
|
quotaErrorLabel: "额度读取失败",
|
|
15962
15967
|
quotaNoUnit: "",
|
|
15968
|
+
/** 上游明说额度用尽:它是账号层面的事实,三只桶全是 0 时只有它能说清为什么被拒。 */
|
|
15969
|
+
quotaExceeded: "额度已用尽",
|
|
15970
|
+
quotaExceededHint: "上游说这个账号的额度已经用尽,请求会被拒。额度恢复之前发消息会失败:可以等周期重置,或在额度页升级套餐。",
|
|
15971
|
+
quotaUpgradeLink: "打开升级页面",
|
|
15963
15972
|
cacheSection: "缓存用量",
|
|
15964
15973
|
cacheStatScope: "本机统计(token 维度,自本进程启动累计):它回答「缓存帮了多少忙」,不是上游账单。",
|
|
15965
15974
|
cacheDesc: "Qoder 服务端自动做前缀缓存;命中量从响应的 usage.prompt_tokens_details.cached_tokens 读出(缺失时读顶层 cached_tokens)。本线路订阅没有公开的 token 单价,整页只显示 token 数字,不显示金额。",
|
|
@@ -16080,6 +16089,9 @@ window.__ModuleLoader__.load({
|
|
|
16080
16089
|
quotaSignedOut: "Sign in to see the account's quota here.",
|
|
16081
16090
|
quotaErrorLabel: "Quota read failed",
|
|
16082
16091
|
quotaNoUnit: "",
|
|
16092
|
+
quotaExceeded: "Quota exhausted",
|
|
16093
|
+
quotaExceededHint: "Upstream says this account's quota is exhausted, so requests get rejected. Sending a message fails until the quota resets: wait for the period to reset, or upgrade the plan on the quota page.",
|
|
16094
|
+
quotaUpgradeLink: "Open the upgrade page",
|
|
16083
16095
|
cacheSection: "Cache usage",
|
|
16084
16096
|
cacheStatScope: "Local statistics (tokens, accumulated since this process started): it answers \"how much the cache helped\", not the upstream bill.",
|
|
16085
16097
|
cacheDesc: "Qoder caches prefixes automatically server-side; hits are read from usage.prompt_tokens_details.cached_tokens (falling back to a top-level cached_tokens). There is no public per-token price for the subscription, so this page shows token counts only, never money.",
|
|
@@ -17193,49 +17205,71 @@ window.__ModuleLoader__.load({
|
|
|
17193
17205
|
children: busy === "quota" ? t.quotaRefreshing : t.quotaEmpty
|
|
17194
17206
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17195
17207
|
className: "dsha-quota-card",
|
|
17196
|
-
children: [
|
|
17197
|
-
|
|
17198
|
-
|
|
17199
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17200
|
-
className: "dshq-fact",
|
|
17201
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.quotaExpiresAt }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: quota.expiresAt !== null ? formatDate$1(quota.expiresAt) : "—" })]
|
|
17202
|
-
}),
|
|
17203
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17204
|
-
className: "dshq-fact",
|
|
17205
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.quotaReadAt }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: formatDate$1(quota.fetchedAt) })]
|
|
17206
|
-
}),
|
|
17207
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17208
|
-
className: "dshq-fact",
|
|
17209
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.quotaRegion }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: regionText(quota.region, t) })]
|
|
17210
|
-
})
|
|
17211
|
-
]
|
|
17212
|
-
}), quota.buckets.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17213
|
-
className: "dsha-empty",
|
|
17214
|
-
children: t.quotaEmpty
|
|
17215
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17216
|
-
className: "dshq-quota-list",
|
|
17217
|
-
children: quota.buckets.map((bucket, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17218
|
-
className: "dshq-quota-row",
|
|
17208
|
+
children: [
|
|
17209
|
+
quota.quotaExceeded && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17210
|
+
className: "dshq-quota-exhausted",
|
|
17219
17211
|
children: [
|
|
17220
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
17221
|
-
className: "dshq-quota-
|
|
17222
|
-
children:
|
|
17212
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17213
|
+
className: "dshq-quota-exhausted-title",
|
|
17214
|
+
children: t.quotaExceeded
|
|
17223
17215
|
}),
|
|
17224
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
17225
|
-
className: "dshq-quota-
|
|
17226
|
-
children:
|
|
17216
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17217
|
+
className: "dshq-quota-exhausted-hint",
|
|
17218
|
+
children: t.quotaExceededHint
|
|
17227
17219
|
}),
|
|
17228
|
-
|
|
17229
|
-
|
|
17230
|
-
|
|
17231
|
-
|
|
17232
|
-
|
|
17233
|
-
percentText(bucket.used / bucket.total)
|
|
17234
|
-
]
|
|
17220
|
+
quota.upgradeUrl !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
17221
|
+
href: quota.upgradeUrl,
|
|
17222
|
+
target: "_blank",
|
|
17223
|
+
rel: "noreferrer noopener",
|
|
17224
|
+
children: t.quotaUpgradeLink
|
|
17235
17225
|
})
|
|
17236
17226
|
]
|
|
17237
|
-
},
|
|
17238
|
-
|
|
17227
|
+
}),
|
|
17228
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17229
|
+
className: "dshq-fact-grid",
|
|
17230
|
+
children: [
|
|
17231
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17232
|
+
className: "dshq-fact",
|
|
17233
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.quotaExpiresAt }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: quota.expiresAt !== null ? formatDate$1(quota.expiresAt) : "—" })]
|
|
17234
|
+
}),
|
|
17235
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17236
|
+
className: "dshq-fact",
|
|
17237
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.quotaReadAt }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: formatDate$1(quota.fetchedAt) })]
|
|
17238
|
+
}),
|
|
17239
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17240
|
+
className: "dshq-fact",
|
|
17241
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.quotaRegion }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: regionText(quota.region, t) })]
|
|
17242
|
+
})
|
|
17243
|
+
]
|
|
17244
|
+
}),
|
|
17245
|
+
quota.buckets.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17246
|
+
className: "dsha-empty",
|
|
17247
|
+
children: t.quotaEmpty
|
|
17248
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17249
|
+
className: "dshq-quota-list",
|
|
17250
|
+
children: quota.buckets.map((bucket, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17251
|
+
className: "dshq-quota-row",
|
|
17252
|
+
children: [
|
|
17253
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
17254
|
+
className: "dshq-quota-name",
|
|
17255
|
+
children: quotaBucketText(bucket.kind, t)
|
|
17256
|
+
}),
|
|
17257
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
17258
|
+
className: "dshq-quota-value",
|
|
17259
|
+
children: bucketAmountText(bucket, t)
|
|
17260
|
+
}),
|
|
17261
|
+
bucket.used !== null && bucket.total !== null && bucket.total > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
17262
|
+
className: "dshq-quota-meta",
|
|
17263
|
+
children: [
|
|
17264
|
+
t.quotaUsed,
|
|
17265
|
+
" ",
|
|
17266
|
+
percentText(bucket.used / bucket.total)
|
|
17267
|
+
]
|
|
17268
|
+
})
|
|
17269
|
+
]
|
|
17270
|
+
}, bucket.kind + ":" + index))
|
|
17271
|
+
})
|
|
17272
|
+
]
|
|
17239
17273
|
}),
|
|
17240
17274
|
moreNotes(t.moreNotes, [t.quotaDesc])
|
|
17241
17275
|
]
|
|
@@ -17375,6 +17409,8 @@ window.__ModuleLoader__.load({
|
|
|
17375
17409
|
catalogSyncedNote: "实时目录已同步 {count} 个模型。",
|
|
17376
17410
|
noModels: "暂无可用模型。",
|
|
17377
17411
|
pricingNote: "价格为官方公开价目(美元 / 每百万 token,输入 / 输出)。",
|
|
17412
|
+
unservedBadge: "套餐不支持",
|
|
17413
|
+
unservedHint: "当前套餐不提供的模型默认隐藏,勾选后会强制显示。",
|
|
17378
17414
|
contextSection: "上下文窗口",
|
|
17379
17415
|
contextHint: "官方未公布各模型的上下文窗口:默认按 128k 处理,可在这里按模型修正。留空或保存无效值会提示错误;恢复默认会清掉覆盖值。",
|
|
17380
17416
|
tokens: "tokens",
|
|
@@ -17481,6 +17517,8 @@ window.__ModuleLoader__.load({
|
|
|
17481
17517
|
catalogSyncedNote: "Live catalog synced: {count} model(s).",
|
|
17482
17518
|
noModels: "No models available.",
|
|
17483
17519
|
pricingNote: "Prices are the official public list (USD per 1M tokens, input / output).",
|
|
17520
|
+
unservedBadge: "Not in plan",
|
|
17521
|
+
unservedHint: "Models the current plan does not serve stay hidden by default; checking one here forces it to show.",
|
|
17484
17522
|
contextSection: "Context windows",
|
|
17485
17523
|
contextHint: "The vendor publishes no per-model context windows, so models default to 128k; correct any model here. An invalid value is reported rather than saved; restoring clears the override.",
|
|
17486
17524
|
tokens: "tokens",
|
|
@@ -17583,6 +17621,19 @@ window.__ModuleLoader__.load({
|
|
|
17583
17621
|
return Math.min(100, Math.max(0, value));
|
|
17584
17622
|
}
|
|
17585
17623
|
/**
|
|
17624
|
+
* Whether the plan the gateway bills for withholds this model.
|
|
17625
|
+
*
|
|
17626
|
+
* The host adds `served: false` to a catalog entry the current plan does not
|
|
17627
|
+
* provide. Such a row stays listed — unchecking it is what hides it, and
|
|
17628
|
+
* checking it is how a user forces it visible — so the card labels it rather
|
|
17629
|
+
* than dropping it. The field is optional: `true` and an absent field both mean
|
|
17630
|
+
* served, so the badge and the note never appear for them and every row renders
|
|
17631
|
+
* exactly as it did before this marker existed.
|
|
17632
|
+
*/
|
|
17633
|
+
function unserved(model) {
|
|
17634
|
+
return model.served === false;
|
|
17635
|
+
}
|
|
17636
|
+
/**
|
|
17586
17637
|
* A window's length in the words the service sold it in.
|
|
17587
17638
|
*
|
|
17588
17639
|
* A policy states seconds, and the tier's windows are round days and hours:
|
|
@@ -18325,6 +18376,11 @@ window.__ModuleLoader__.load({
|
|
|
18325
18376
|
style: { fontSize: 12 },
|
|
18326
18377
|
children: t.modelsHint
|
|
18327
18378
|
}),
|
|
18379
|
+
models.some(unserved) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
18380
|
+
className: "dsha-muted",
|
|
18381
|
+
style: { fontSize: 12 },
|
|
18382
|
+
children: t.unservedHint
|
|
18383
|
+
}),
|
|
18328
18384
|
status !== null && models.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
18329
18385
|
className: "dsha-empty",
|
|
18330
18386
|
children: t.noModels
|
|
@@ -18336,12 +18392,15 @@ window.__ModuleLoader__.load({
|
|
|
18336
18392
|
children: t.catalogNeverSynced
|
|
18337
18393
|
}),
|
|
18338
18394
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelChecklist, {
|
|
18339
|
-
items: models.map((model) =>
|
|
18340
|
-
|
|
18341
|
-
|
|
18342
|
-
|
|
18343
|
-
|
|
18344
|
-
|
|
18395
|
+
items: models.map((model) => {
|
|
18396
|
+
const hint = model.hint ?? `${formatCapacity$1(model.contextWindow)} · ${model.input.join("+")}${model.reasoning ? " · reasoning" : ""}`;
|
|
18397
|
+
return {
|
|
18398
|
+
id: model.id,
|
|
18399
|
+
name: model.name,
|
|
18400
|
+
hint: unserved(model) ? `${hint} · ${t.unservedBadge}` : hint,
|
|
18401
|
+
enabled: model.enabled
|
|
18402
|
+
};
|
|
18403
|
+
}),
|
|
18345
18404
|
busy: busyAny,
|
|
18346
18405
|
onToggle: (id, enabled) => toggleModel(id, enabled),
|
|
18347
18406
|
onToggleAll: (enabled) => setAllModels(enabled),
|
|
@@ -20872,6 +20931,8 @@ window.__ModuleLoader__.load({
|
|
|
20872
20931
|
catalogSyncedNote: "Живой каталог синхронизирован: моделей {count}.",
|
|
20873
20932
|
noModels: "Доступных моделей нет.",
|
|
20874
20933
|
pricingNote: "Цены — официальный публичный прайс (доллары США за 1 млн токенов, вход / выход).",
|
|
20934
|
+
unservedBadge: "Нет в тарифе",
|
|
20935
|
+
unservedHint: "Модели, которых нет в текущем тарифе, по умолчанию скрыты; отметьте их здесь, чтобы показать принудительно.",
|
|
20875
20936
|
contextSection: "Контекстные окна",
|
|
20876
20937
|
contextHint: "Производитель не публикует контекстные окна по моделям, поэтому по умолчанию берётся 128k; здесь любую модель можно поправить. Неверное значение не сохраняется, а показывается ошибкой; восстановление сбрасывает переопределение.",
|
|
20877
20938
|
tokens: "токены",
|
|
@@ -21066,6 +21127,9 @@ window.__ModuleLoader__.load({
|
|
|
21066
21127
|
quotaSignedOut: "Войдите, чтобы увидеть здесь квоту аккаунта.",
|
|
21067
21128
|
quotaErrorLabel: "Не удалось прочитать квоту",
|
|
21068
21129
|
quotaNoUnit: "",
|
|
21130
|
+
quotaExceeded: "Квота исчерпана",
|
|
21131
|
+
quotaExceededHint: "Апстрим сообщает, что квота этого аккаунта исчерпана, поэтому запросы отклоняются. Отправка сообщения не удастся, пока квота не восстановится: дождитесь сброса периода или смените тариф на странице квоты.",
|
|
21132
|
+
quotaUpgradeLink: "Открыть страницу тарифа",
|
|
21069
21133
|
cacheSection: "Расход кеша",
|
|
21070
21134
|
cacheStatScope: "Локальная статистика (в токенах, с начала работы процесса): она отвечает, насколько помог кеш, и не является счётом апстрима.",
|
|
21071
21135
|
cacheDesc: "Qoder кеширует префиксы на сервере автоматически; попадания читаются из usage.prompt_tokens_details.cached_tokens (при отсутствии — из верхнеуровневого cached_tokens). У подписки нет публичной цены за токен, поэтому страница показывает только токены, без денег.",
|
|
@@ -21977,9 +22041,10 @@ window.__ModuleLoader__.load({
|
|
|
21977
22041
|
const window = [...quota.windows ?? []].sort((a, b) => (a.windowDurationMins ?? Infinity) - (b.windowDurationMins ?? Infinity))[0];
|
|
21978
22042
|
if (window !== void 0) {
|
|
21979
22043
|
const remaining = Math.max(0, 100 - window.usedPercent);
|
|
22044
|
+
const remainingText = formatPercent$1(remaining);
|
|
21980
22045
|
return {
|
|
21981
|
-
text: `${
|
|
21982
|
-
tooltip: `[Command Code] ${window.label}: ${
|
|
22046
|
+
text: `${remainingText}%`,
|
|
22047
|
+
tooltip: `[Command Code] ${window.label}: ${remainingText}% left`,
|
|
21983
22048
|
level: quotaLevel(remaining)
|
|
21984
22049
|
};
|
|
21985
22050
|
}
|
|
@@ -22038,9 +22103,10 @@ window.__ModuleLoader__.load({
|
|
|
22038
22103
|
const window = [...quota.windows ?? []].filter((candidate) => candidate.windowDurationMins !== null).sort((a, b) => (a.windowDurationMins ?? Infinity) - (b.windowDurationMins ?? Infinity))[0] ?? quota.windows[0];
|
|
22039
22104
|
if (window !== void 0) {
|
|
22040
22105
|
const remaining = Math.max(0, 100 - window.usedPercent);
|
|
22106
|
+
const remainingText = formatPercent$1(remaining);
|
|
22041
22107
|
return {
|
|
22042
|
-
text: `${
|
|
22043
|
-
tooltip: `[Kimi Code] ${window.label}: ${
|
|
22108
|
+
text: `${remainingText}%`,
|
|
22109
|
+
tooltip: `[Kimi Code] ${window.label}: ${remainingText}% left`,
|
|
22044
22110
|
level: quotaLevel(remaining)
|
|
22045
22111
|
};
|
|
22046
22112
|
}
|
|
@@ -22182,9 +22248,11 @@ window.__ModuleLoader__.load({
|
|
|
22182
22248
|
.dsha-kq-seg{border-radius:999px;display:block;height:100%;transition:width .9s cubic-bezier(.22,.61,.36,1)}
|
|
22183
22249
|
.dsha-kq-seg--recent{background:var(--kq-code)}
|
|
22184
22250
|
.dsha-kq-seg--rest{background:var(--kq-rest)}
|
|
22185
|
-
.dsha-kq-tip{background:var(--kq-tip-bg);border-radius:10px;bottom:calc(100% + 10px);color:var(--dsw-alias-bg-base,#fff);font-size:13px;line-height:1;opacity:0;padding:9px 14px;pointer-events:none;position:absolute;
|
|
22186
|
-
|
|
22187
|
-
|
|
22251
|
+
.dsha-kq-tip{background:var(--kq-tip-bg);border-radius:10px;bottom:calc(100% + 10px);color:var(--dsw-alias-bg-base,#fff);font-size:13px;line-height:1;left:var(--kq-tip-x,50%);opacity:0;padding:9px 14px;pointer-events:none;position:absolute;transform:translate(calc(-50% + var(--kq-tip-shift,0px)),4px);transition:opacity .16s ease-out,transform .16s ease-out;white-space:nowrap}
|
|
22252
|
+
/* 箭头不跟气泡的位移走:气泡被 --kq-tip-shift 收回卡片内时,箭头按
|
|
22253
|
+
--kq-tip-arrow 单独挪回「已用段末端」在气泡里的位置,所以它指的一直是那个数字。 */
|
|
22254
|
+
.dsha-kq-tip::after{border:6px solid transparent;border-top-color:var(--kq-tip-bg);content:"";left:var(--kq-tip-arrow,50%);margin-left:-6px;position:absolute;top:100%}
|
|
22255
|
+
.dsha-kq-barwrap:hover .dsha-kq-tip{opacity:1;transform:translate(calc(-50% + var(--kq-tip-shift,0px)),0)}
|
|
22188
22256
|
.dsha-kq-legend{align-items:center;color:var(--kq-fg-2);column-gap:16px;display:flex;flex-wrap:wrap;font-size:13px;margin-top:11px;row-gap:6px}
|
|
22189
22257
|
.dsha-kq-legend-item{align-items:center;display:inline-flex;gap:6px;white-space:nowrap}
|
|
22190
22258
|
.dsha-kq-legend-note{color:var(--kq-fg-3);white-space:nowrap}
|
|
@@ -23347,6 +23415,12 @@ window.__ModuleLoader__.load({
|
|
|
23347
23415
|
.dshq-quota-name{color:var(--dsw-alias-label-primary);font-size:12px;min-width:104px}
|
|
23348
23416
|
.dshq-quota-value{color:var(--dsw-alias-label-secondary);font-size:12px}
|
|
23349
23417
|
.dshq-quota-meta{color:var(--dsw-alias-label-tertiary);font-size:11px}
|
|
23418
|
+
/* 额度用尽:账号层面的一条事实(上游明说),与三只桶的数字并排给出。 */
|
|
23419
|
+
.dshq-quota-exhausted{margin-top:11px}
|
|
23420
|
+
.dshq-quota-exhausted-title{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:600}
|
|
23421
|
+
.dshq-quota-exhausted-hint{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.5;margin-top:4px}
|
|
23422
|
+
.dshq-quota-exhausted a{color:var(--dsw-alias-label-link,#397ee8);font-size:12px;text-decoration:none}
|
|
23423
|
+
.dshq-quota-exhausted a:hover{text-decoration:underline}
|
|
23350
23424
|
/* 快照卡里的几行事实:紧凑网格,一格一件事,行高一致。 */
|
|
23351
23425
|
.dshq-fact-grid{display:grid;gap:9px 20px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));margin-top:11px}
|
|
23352
23426
|
.dshq-fact{display:flex;flex-direction:column;gap:3px;min-width:0}
|