dsh-ds-balance 2.1.1 → 2.1.2
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/README.md +4 -0
- package/README_en.md +4 -0
- package/lib/adapters/console-logger.js +12 -4
- package/lib/adapters/domain-core-store.js +9 -3
- package/lib/adapters/http-deepseek-client.js +14 -4
- package/lib/adapters/salt-file.js +6 -2
- package/lib/client.js +339 -153
- package/lib/config.js +7 -1
- package/lib/domain/errors.js +10 -5
- package/lib/domain/select.js +5 -5
- package/lib/http/handlers.js +55 -13
- package/lib/index.js +34 -9
- package/lib/services/balance-service.js +13 -5
- package/lib/services/scheduler.js +6 -2
- package/lib/types/client/settings/fields.d.ts +3 -3
- package/lib/types/client/sidebar/PercentRing.d.ts +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +10 -1
package/lib/client.js
CHANGED
|
@@ -198,7 +198,10 @@ var en = {
|
|
|
198
198
|
"dev.hint": "UI development only; does not affect real configuration."
|
|
199
199
|
};
|
|
200
200
|
function interpolate(template, params) {
|
|
201
|
-
return template.replace(
|
|
201
|
+
return template.replace(
|
|
202
|
+
/\{(\w+)\}/g,
|
|
203
|
+
(whole, name) => Object.prototype.hasOwnProperty.call(params, name) ? params[name] : whole
|
|
204
|
+
);
|
|
202
205
|
}
|
|
203
206
|
|
|
204
207
|
// src/client/settings/fields.tsx
|
|
@@ -230,7 +233,6 @@ var fields_default = {
|
|
|
230
233
|
groupNote: "fields_groupNote",
|
|
231
234
|
fields: "fields_fields",
|
|
232
235
|
details: "fields_details",
|
|
233
|
-
detailsSummary: "fields_detailsSummary",
|
|
234
236
|
detailsBody: "fields_detailsBody",
|
|
235
237
|
field: "fields_field",
|
|
236
238
|
row: "fields_row",
|
|
@@ -241,10 +243,10 @@ var fields_default = {
|
|
|
241
243
|
label: "fields_label",
|
|
242
244
|
badges: "fields_badges",
|
|
243
245
|
reset: "fields_reset",
|
|
244
|
-
input: "fields_input",
|
|
245
246
|
inputStatic: "fields_inputStatic",
|
|
246
247
|
inputInvalid: "fields_inputInvalid",
|
|
247
248
|
inputWithAction: "fields_inputWithAction",
|
|
249
|
+
input: "fields_input",
|
|
248
250
|
reveal: "fields_reveal",
|
|
249
251
|
revealOn: "fields_revealOn",
|
|
250
252
|
selectorAnchor: "fields_selectorAnchor",
|
|
@@ -254,7 +256,6 @@ var fields_default = {
|
|
|
254
256
|
pairNote: "fields_pairNote",
|
|
255
257
|
invalid: "fields_invalid",
|
|
256
258
|
actions: "fields_actions",
|
|
257
|
-
actionButton: "fields_actionButton",
|
|
258
259
|
resultOk: "fields_resultOk",
|
|
259
260
|
resultFail: "fields_resultFail"
|
|
260
261
|
};
|
|
@@ -322,10 +323,10 @@ function FieldFrame(props) {
|
|
|
322
323
|
}
|
|
323
324
|
function TextControl(props) {
|
|
324
325
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
325
|
-
|
|
326
|
+
import_dsh_client_ui_primitives.Input,
|
|
326
327
|
{
|
|
327
328
|
id: props.id,
|
|
328
|
-
className: props.invalid ? fields_default.inputInvalid :
|
|
329
|
+
className: props.invalid ? fields_default.inputInvalid : void 0,
|
|
329
330
|
type: "text",
|
|
330
331
|
...props.numeric ? { inputMode: "numeric" } : {},
|
|
331
332
|
...props.invalid ? { "aria-invalid": true } : {},
|
|
@@ -340,10 +341,10 @@ function TextControl(props) {
|
|
|
340
341
|
}
|
|
341
342
|
function ReadOnlyControl(props) {
|
|
342
343
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
343
|
-
|
|
344
|
+
import_dsh_client_ui_primitives.Input,
|
|
344
345
|
{
|
|
345
346
|
id: props.id,
|
|
346
|
-
className:
|
|
347
|
+
className: fields_default.inputStatic,
|
|
347
348
|
type: "text",
|
|
348
349
|
value: "",
|
|
349
350
|
readOnly: true
|
|
@@ -352,20 +353,20 @@ function ReadOnlyControl(props) {
|
|
|
352
353
|
}
|
|
353
354
|
function DetailsGroup(props) {
|
|
354
355
|
const [open, setOpen] = (0, import_react.useState)(props.defaultOpen === true);
|
|
355
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.
|
|
356
|
-
|
|
356
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: fields_default.details, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
357
|
+
import_dsh_client_ui_primitives.DisclosureRow,
|
|
357
358
|
{
|
|
358
|
-
|
|
359
|
+
icon: null,
|
|
360
|
+
title: props.title,
|
|
359
361
|
open,
|
|
360
|
-
|
|
361
|
-
|
|
362
|
+
expandable: true,
|
|
363
|
+
expandOnRowClick: true,
|
|
364
|
+
onToggle: () => {
|
|
365
|
+
setOpen((value) => !value);
|
|
362
366
|
},
|
|
363
|
-
children:
|
|
364
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { className: fields_default.detailsSummary, children: props.title }),
|
|
365
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: fields_default.detailsBody, children: props.children })
|
|
366
|
-
]
|
|
367
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: fields_default.detailsBody, children: props.children })
|
|
367
368
|
}
|
|
368
|
-
);
|
|
369
|
+
) });
|
|
369
370
|
}
|
|
370
371
|
function SelectorControl(props) {
|
|
371
372
|
const [open, setOpen] = (0, import_react.useState)(false);
|
|
@@ -411,10 +412,10 @@ function SelectorControl(props) {
|
|
|
411
412
|
function ActionRow(props) {
|
|
412
413
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
413
414
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: fields_default.actions, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
414
|
-
|
|
415
|
+
import_dsh_client_ui_primitives.Button,
|
|
415
416
|
{
|
|
416
417
|
type: "button",
|
|
417
|
-
|
|
418
|
+
variant: "outline",
|
|
418
419
|
disabled: props.disabled,
|
|
419
420
|
onClick: props.onClick,
|
|
420
421
|
children: props.label
|
|
@@ -469,7 +470,13 @@ function selectField(field) {
|
|
|
469
470
|
var AUTO_CURRENCY = "auto";
|
|
470
471
|
var KNOWN_CURRENCIES = ["CNY", "USD"];
|
|
471
472
|
var THRESHOLD_PAIRS = [
|
|
472
|
-
{
|
|
473
|
+
{
|
|
474
|
+
currency: "CNY",
|
|
475
|
+
warn: "cnyWarn",
|
|
476
|
+
critical: "cnyCritical",
|
|
477
|
+
defaultWarn: 10,
|
|
478
|
+
defaultCritical: 5
|
|
479
|
+
},
|
|
473
480
|
{ currency: "USD", warn: "usdWarn", critical: "usdCritical", defaultWarn: 2, defaultCritical: 1 }
|
|
474
481
|
];
|
|
475
482
|
function pairNumber(state, fallback) {
|
|
@@ -512,8 +519,10 @@ var SPEC_BY_FIELD = new Map(
|
|
|
512
519
|
var TEST_LATENCY_MS = 800;
|
|
513
520
|
function probeFailure(baseUrl, apiKey, apiKeyRef) {
|
|
514
521
|
const url = baseUrl.trim();
|
|
515
|
-
if (url !== "" && !/^https?:\/\//i.test(url))
|
|
516
|
-
|
|
522
|
+
if (url !== "" && !/^https?:\/\//i.test(url))
|
|
523
|
+
return "base URL must start with http:// or https://";
|
|
524
|
+
if (apiKey.trim() === "" && apiKeyRef.trim() === "")
|
|
525
|
+
return "no API key or credential reference configured";
|
|
517
526
|
return null;
|
|
518
527
|
}
|
|
519
528
|
function isRecord(input) {
|
|
@@ -564,16 +573,72 @@ function fieldStateOf(snapshot, spec, edit) {
|
|
|
564
573
|
const effective = snapshot.value[spec.field];
|
|
565
574
|
const stored = Object.hasOwn(snapshot.user, spec.field);
|
|
566
575
|
if (edit === void 0) {
|
|
567
|
-
return isTextSpec(spec) ? {
|
|
576
|
+
return isTextSpec(spec) ? {
|
|
577
|
+
text: spec.format(effective),
|
|
578
|
+
value: void 0,
|
|
579
|
+
effective,
|
|
580
|
+
stored,
|
|
581
|
+
overridden: stored,
|
|
582
|
+
dirty: false,
|
|
583
|
+
invalid: false
|
|
584
|
+
} : {
|
|
585
|
+
text: "",
|
|
586
|
+
value: effective,
|
|
587
|
+
effective,
|
|
588
|
+
stored,
|
|
589
|
+
overridden: stored,
|
|
590
|
+
dirty: false,
|
|
591
|
+
invalid: false
|
|
592
|
+
};
|
|
568
593
|
}
|
|
569
594
|
if (edit.kind === "clear") {
|
|
570
|
-
return isTextSpec(spec) ? {
|
|
595
|
+
return isTextSpec(spec) ? {
|
|
596
|
+
text: "",
|
|
597
|
+
value: void 0,
|
|
598
|
+
effective,
|
|
599
|
+
stored,
|
|
600
|
+
overridden: false,
|
|
601
|
+
dirty: stored,
|
|
602
|
+
invalid: false
|
|
603
|
+
} : {
|
|
604
|
+
text: "",
|
|
605
|
+
value: effective,
|
|
606
|
+
effective,
|
|
607
|
+
stored,
|
|
608
|
+
overridden: false,
|
|
609
|
+
dirty: stored,
|
|
610
|
+
invalid: false
|
|
611
|
+
};
|
|
571
612
|
}
|
|
572
613
|
if (!isTextSpec(spec)) {
|
|
573
|
-
return edit.kind === "value" ? {
|
|
614
|
+
return edit.kind === "value" ? {
|
|
615
|
+
text: "",
|
|
616
|
+
value: edit.value,
|
|
617
|
+
effective,
|
|
618
|
+
stored,
|
|
619
|
+
overridden: true,
|
|
620
|
+
dirty: edit.value !== effective,
|
|
621
|
+
invalid: false
|
|
622
|
+
} : {
|
|
623
|
+
text: "",
|
|
624
|
+
value: effective,
|
|
625
|
+
effective,
|
|
626
|
+
stored,
|
|
627
|
+
overridden: stored,
|
|
628
|
+
dirty: false,
|
|
629
|
+
invalid: false
|
|
630
|
+
};
|
|
574
631
|
}
|
|
575
632
|
if (edit.kind !== "text") {
|
|
576
|
-
return {
|
|
633
|
+
return {
|
|
634
|
+
text: "",
|
|
635
|
+
value: void 0,
|
|
636
|
+
effective,
|
|
637
|
+
stored,
|
|
638
|
+
overridden: stored,
|
|
639
|
+
dirty: false,
|
|
640
|
+
invalid: false
|
|
641
|
+
};
|
|
577
642
|
}
|
|
578
643
|
const write = spec.parse(edit.text);
|
|
579
644
|
const dirty = write === void 0 ? true : write.kind === "clear" ? stored : edit.text !== spec.format(effective);
|
|
@@ -618,10 +683,7 @@ function useConfigForm(form) {
|
|
|
618
683
|
cacheRef.current = { value, user, writable, available, snapshot: snapshot2 };
|
|
619
684
|
return snapshot2;
|
|
620
685
|
}, [form]);
|
|
621
|
-
const subscribe = (0, import_react2.useCallback)(
|
|
622
|
-
(listener) => form.subscribe(listener),
|
|
623
|
-
[form]
|
|
624
|
-
);
|
|
686
|
+
const subscribe = (0, import_react2.useCallback)((listener) => form.subscribe(listener), [form]);
|
|
625
687
|
const snapshot = (0, import_react2.useSyncExternalStore)(subscribe, readSnapshot);
|
|
626
688
|
const [staged, setStaged] = (0, import_react2.useState)(() => /* @__PURE__ */ new Map());
|
|
627
689
|
const [saving, setSaving] = (0, import_react2.useState)(false);
|
|
@@ -631,18 +693,23 @@ function useConfigForm(form) {
|
|
|
631
693
|
const [test, setTest] = (0, import_react2.useState)({ running: false, ok: null, message: "" });
|
|
632
694
|
const testTimerRef = (0, import_react2.useRef)(null);
|
|
633
695
|
const testRunningRef = (0, import_react2.useRef)(false);
|
|
634
|
-
(0, import_react2.useEffect)(
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
696
|
+
(0, import_react2.useEffect)(
|
|
697
|
+
() => () => {
|
|
698
|
+
if (testTimerRef.current !== null) clearTimeout(testTimerRef.current);
|
|
699
|
+
testTimerRef.current = null;
|
|
700
|
+
testRunningRef.current = false;
|
|
701
|
+
},
|
|
702
|
+
[]
|
|
703
|
+
);
|
|
639
704
|
const plan = (0, import_react2.useMemo)(() => planWrites(snapshot, staged), [snapshot, staged]);
|
|
640
705
|
const pairsInvalid = (0, import_react2.useMemo)(
|
|
641
|
-
() => THRESHOLD_PAIRS.some(
|
|
642
|
-
pair
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
706
|
+
() => THRESHOLD_PAIRS.some(
|
|
707
|
+
(pair) => !thresholdsOk(
|
|
708
|
+
pair,
|
|
709
|
+
fieldOf(snapshot, pair.warn, staged.get(pair.warn)),
|
|
710
|
+
fieldOf(snapshot, pair.critical, staged.get(pair.critical))
|
|
711
|
+
)
|
|
712
|
+
),
|
|
646
713
|
[snapshot, staged]
|
|
647
714
|
);
|
|
648
715
|
const invalid = plan.some((item) => item.write === void 0) || pairsInvalid;
|
|
@@ -659,17 +726,28 @@ function useConfigForm(form) {
|
|
|
659
726
|
testTimerRef.current = null;
|
|
660
727
|
}
|
|
661
728
|
testRunningRef.current = false;
|
|
662
|
-
setTest(
|
|
729
|
+
setTest(
|
|
730
|
+
(current) => current.running || current.ok !== null ? { running: false, ok: null, message: "" } : current
|
|
731
|
+
);
|
|
663
732
|
}, []);
|
|
664
|
-
const edit = (0, import_react2.useCallback)(
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
stage
|
|
669
|
-
|
|
670
|
-
const
|
|
671
|
-
|
|
672
|
-
|
|
733
|
+
const edit = (0, import_react2.useCallback)(
|
|
734
|
+
(field2, text) => {
|
|
735
|
+
stage(field2, { kind: "text", text });
|
|
736
|
+
},
|
|
737
|
+
[stage]
|
|
738
|
+
);
|
|
739
|
+
const setValue = (0, import_react2.useCallback)(
|
|
740
|
+
(field2, value) => {
|
|
741
|
+
stage(field2, { kind: "value", value });
|
|
742
|
+
},
|
|
743
|
+
[stage]
|
|
744
|
+
);
|
|
745
|
+
const resetField = (0, import_react2.useCallback)(
|
|
746
|
+
(field2) => {
|
|
747
|
+
stage(field2, { kind: "clear" });
|
|
748
|
+
},
|
|
749
|
+
[stage]
|
|
750
|
+
);
|
|
673
751
|
const discard = (0, import_react2.useCallback)(() => {
|
|
674
752
|
setStaged((current) => current.size === 0 ? current : /* @__PURE__ */ new Map());
|
|
675
753
|
setFailed(false);
|
|
@@ -678,7 +756,9 @@ function useConfigForm(form) {
|
|
|
678
756
|
testTimerRef.current = null;
|
|
679
757
|
}
|
|
680
758
|
testRunningRef.current = false;
|
|
681
|
-
setTest(
|
|
759
|
+
setTest(
|
|
760
|
+
(current) => current.running || current.ok !== null ? { running: false, ok: null, message: "" } : current
|
|
761
|
+
);
|
|
682
762
|
}, []);
|
|
683
763
|
const save = (0, import_react2.useCallback)(async () => {
|
|
684
764
|
if (savingRef.current) return;
|
|
@@ -692,9 +772,11 @@ function useConfigForm(form) {
|
|
|
692
772
|
for (const item of writes) {
|
|
693
773
|
const write = item.write;
|
|
694
774
|
if (write === void 0) continue;
|
|
695
|
-
ops.push(
|
|
775
|
+
ops.push(
|
|
776
|
+
write.kind === "clear" ? { op: "unset", path: [item.field] } : { op: "set", path: [item.field], value: write.value }
|
|
777
|
+
);
|
|
696
778
|
}
|
|
697
|
-
let landed
|
|
779
|
+
let landed;
|
|
698
780
|
try {
|
|
699
781
|
landed = await form.mutate(ops, form.getSnapshot().revision);
|
|
700
782
|
} catch {
|
|
@@ -720,7 +802,9 @@ function useConfigForm(form) {
|
|
|
720
802
|
testTimerRef.current = setTimeout(() => {
|
|
721
803
|
testTimerRef.current = null;
|
|
722
804
|
testRunningRef.current = false;
|
|
723
|
-
setTest(
|
|
805
|
+
setTest(
|
|
806
|
+
failure === null ? { running: false, ok: true, message: "" } : { running: false, ok: false, message: failure }
|
|
807
|
+
);
|
|
724
808
|
}, TEST_LATENCY_MS);
|
|
725
809
|
}, [readSnapshot, staged]);
|
|
726
810
|
const field = (0, import_react2.useCallback)(
|
|
@@ -871,8 +955,7 @@ var BalanceSettingsCard_default = {
|
|
|
871
955
|
readOnly: "BalanceSettingsCard_readOnly",
|
|
872
956
|
footer: "BalanceSettingsCard_footer",
|
|
873
957
|
failed: "BalanceSettingsCard_failed",
|
|
874
|
-
notice: "BalanceSettingsCard_notice"
|
|
875
|
-
save: "BalanceSettingsCard_save"
|
|
958
|
+
notice: "BalanceSettingsCard_notice"
|
|
876
959
|
};
|
|
877
960
|
|
|
878
961
|
// src/client/settings/BalanceSettingsCard.tsx
|
|
@@ -922,7 +1005,8 @@ function BalanceSettingsCard({ t, form: scopedForm }) {
|
|
|
922
1005
|
const toggleGroup = (key) => {
|
|
923
1006
|
setGroupOpen((current) => ({ ...current, [key]: !current[key] }));
|
|
924
1007
|
};
|
|
925
|
-
const groupOpenNow = (key) => groupOpen[key] || GROUP_FIELDS[key].some((name) => form.field(name).invalid) ||
|
|
1008
|
+
const groupOpenNow = (key) => groupOpen[key] || GROUP_FIELDS[key].some((name) => form.field(name).invalid) || // 成对校验不是字段级 invalid,得单独问一次:否则收起的阈值组会挡住「保存为什么是灰的」。
|
|
1009
|
+
key === "thresholds" && THRESHOLD_PAIRS.some((pair) => !form.thresholdPairOk(pair.currency));
|
|
926
1010
|
const { available, writable, dirty, invalid, saving, failed } = form.state;
|
|
927
1011
|
const disabled = !writable || saving;
|
|
928
1012
|
const credentialStatus = (name) => {
|
|
@@ -1079,7 +1163,10 @@ function BalanceSettingsCard({ t, form: scopedForm }) {
|
|
|
1079
1163
|
{
|
|
1080
1164
|
id: FIELD_IDS.apiKeyState ?? "apiKeyState",
|
|
1081
1165
|
label: t("settings.field.apiKey"),
|
|
1082
|
-
status: {
|
|
1166
|
+
status: {
|
|
1167
|
+
label: t(CREDENTIAL_BADGE[credentialView]),
|
|
1168
|
+
tone: credentialView === "notConfigured" ? "quiet" : "neutral"
|
|
1169
|
+
},
|
|
1083
1170
|
pending: false,
|
|
1084
1171
|
resettable: false,
|
|
1085
1172
|
pendingLabel: t("settings.unsaved"),
|
|
@@ -1089,12 +1176,7 @@ function BalanceSettingsCard({ t, form: scopedForm }) {
|
|
|
1089
1176
|
disabled: true,
|
|
1090
1177
|
onReset: () => {
|
|
1091
1178
|
},
|
|
1092
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1093
|
-
ReadOnlyControl,
|
|
1094
|
-
{
|
|
1095
|
-
id: FIELD_IDS.apiKeyState ?? "apiKeyState"
|
|
1096
|
-
}
|
|
1097
|
-
)
|
|
1179
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ReadOnlyControl, { id: FIELD_IDS.apiKeyState ?? "apiKeyState" })
|
|
1098
1180
|
}
|
|
1099
1181
|
),
|
|
1100
1182
|
textRow("baseUrl", "settings.field.baseUrl", "settings.hint.baseUrl", false),
|
|
@@ -1153,19 +1235,31 @@ function BalanceSettingsCard({ t, form: scopedForm }) {
|
|
|
1153
1235
|
},
|
|
1154
1236
|
last: true,
|
|
1155
1237
|
children: [
|
|
1156
|
-
numberRow(
|
|
1157
|
-
|
|
1158
|
-
|
|
1238
|
+
numberRow(
|
|
1239
|
+
"serverRefreshSeconds",
|
|
1240
|
+
"settings.field.serverRefreshSeconds",
|
|
1241
|
+
"settings.hint.serverRefreshSeconds"
|
|
1242
|
+
),
|
|
1243
|
+
numberRow(
|
|
1244
|
+
"clientPollSeconds",
|
|
1245
|
+
"settings.field.clientPollSeconds",
|
|
1246
|
+
"settings.hint.clientPollSeconds"
|
|
1247
|
+
),
|
|
1248
|
+
numberRow(
|
|
1249
|
+
"manualRefreshCooldownSeconds",
|
|
1250
|
+
"settings.field.manualRefreshCooldownSeconds",
|
|
1251
|
+
"settings.hint.manualRefreshCooldownSeconds"
|
|
1252
|
+
)
|
|
1159
1253
|
]
|
|
1160
1254
|
}
|
|
1161
1255
|
),
|
|
1162
1256
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: BalanceSettingsCard_default.footer, children: [
|
|
1163
1257
|
footerNote === null ? null : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: footerNote.className, role: "status", children: footerNote.text }),
|
|
1164
1258
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1165
|
-
|
|
1259
|
+
import_dsh_client_ui_primitives2.Button,
|
|
1166
1260
|
{
|
|
1167
1261
|
type: "button",
|
|
1168
|
-
|
|
1262
|
+
variant: "primary",
|
|
1169
1263
|
disabled: !dirty || invalid || saving || !writable,
|
|
1170
1264
|
onClick: () => {
|
|
1171
1265
|
void form.save();
|
|
@@ -1315,9 +1409,17 @@ var scenarios = {
|
|
|
1315
1409
|
/** 正常。 */
|
|
1316
1410
|
ok: make({}),
|
|
1317
1411
|
/** 余额偏低但可用。 */
|
|
1318
|
-
warn: make({
|
|
1412
|
+
warn: make({
|
|
1413
|
+
severity: "warn",
|
|
1414
|
+
balances: [cny("8.00000000", "0.00000000", "8.00000000")],
|
|
1415
|
+
selected: { currency: "CNY", total: "8.00000000" }
|
|
1416
|
+
}),
|
|
1319
1417
|
/** 余额告急。 */
|
|
1320
|
-
critical: make({
|
|
1418
|
+
critical: make({
|
|
1419
|
+
severity: "critical",
|
|
1420
|
+
balances: [cny("3.00000000", "0.00000000", "3.00000000")],
|
|
1421
|
+
selected: { currency: "CNY", total: "3.00000000" }
|
|
1422
|
+
}),
|
|
1321
1423
|
/** 账户不可用(余额耗尽 / 欠费)。 */
|
|
1322
1424
|
unavailable: make({
|
|
1323
1425
|
severity: "unavailable",
|
|
@@ -1326,7 +1428,14 @@ var scenarios = {
|
|
|
1326
1428
|
selected: { currency: "CNY", total: "0.00000000" }
|
|
1327
1429
|
}),
|
|
1328
1430
|
/** 有旧值但本次刷新失败。 */
|
|
1329
|
-
stale: make({
|
|
1431
|
+
stale: make({
|
|
1432
|
+
state: "stale",
|
|
1433
|
+
stale: true,
|
|
1434
|
+
severity: "unknown",
|
|
1435
|
+
ageMs: 36e5,
|
|
1436
|
+
fetchedAt: T0 - 36e5,
|
|
1437
|
+
error: { code: "NO_NETWORK", message: "fetch failed" }
|
|
1438
|
+
}),
|
|
1330
1439
|
/** 无值失败。 */
|
|
1331
1440
|
error: make({
|
|
1332
1441
|
state: "error",
|
|
@@ -1339,14 +1448,35 @@ var scenarios = {
|
|
|
1339
1448
|
error: { code: "UPSTREAM_5XX", message: "upstream returned 500" }
|
|
1340
1449
|
}),
|
|
1341
1450
|
/** 未配置。 */
|
|
1342
|
-
empty: make({
|
|
1451
|
+
empty: make({
|
|
1452
|
+
state: "empty",
|
|
1453
|
+
severity: "unknown",
|
|
1454
|
+
isAvailable: false,
|
|
1455
|
+
balances: [],
|
|
1456
|
+
selected: null,
|
|
1457
|
+
ageMs: 0
|
|
1458
|
+
}),
|
|
1343
1459
|
/** 未配置且带 NO_KEY 错误。 */
|
|
1344
|
-
noKey: make({
|
|
1460
|
+
noKey: make({
|
|
1461
|
+
state: "empty",
|
|
1462
|
+
severity: "unknown",
|
|
1463
|
+
isAvailable: false,
|
|
1464
|
+
balances: [],
|
|
1465
|
+
selected: null,
|
|
1466
|
+
ageMs: 0,
|
|
1467
|
+
error: { code: "NO_KEY", message: "no API key configured" }
|
|
1468
|
+
}),
|
|
1345
1469
|
/** 多币种。`selected` 显式写出,不靠 `make()` 的默认值兜。 */
|
|
1346
1470
|
multiCurrency: make({
|
|
1347
|
-
balances: [
|
|
1471
|
+
balances: [
|
|
1472
|
+
cny("110.00000000", "10.00000000", "100.00000000"),
|
|
1473
|
+
{ currency: "USD", total: "20.00000000", granted: "0.00000000", toppedUp: "20.00000000" }
|
|
1474
|
+
],
|
|
1348
1475
|
selected: { currency: "CNY", total: "110.00000000" },
|
|
1349
|
-
thresholds: {
|
|
1476
|
+
thresholds: {
|
|
1477
|
+
CNY: { warn: "10.00000000", critical: "5.00000000" },
|
|
1478
|
+
USD: { warn: "2.00000000", critical: "1.00000000" }
|
|
1479
|
+
}
|
|
1350
1480
|
}),
|
|
1351
1481
|
/**
|
|
1352
1482
|
* 选定了账户里没有的币种(USD),账户只有 CNY。
|
|
@@ -1561,9 +1691,12 @@ function BalancePopover(props) {
|
|
|
1561
1691
|
const cooling = cooldownSeconds > 0;
|
|
1562
1692
|
let statusText = "";
|
|
1563
1693
|
if (refreshing) statusText = t("popover.refreshing");
|
|
1564
|
-
else if (cooling)
|
|
1694
|
+
else if (cooling)
|
|
1695
|
+
statusText = interpolate(t("popover.cooldown"), { value: String(cooldownSeconds) });
|
|
1565
1696
|
const refreshLabel = t("sidebar.aria.refresh");
|
|
1566
|
-
const pluginsLabel = t(
|
|
1697
|
+
const pluginsLabel = t(
|
|
1698
|
+
pluginsAction?.reachesConfig === true ? "popover.action.openPluginConfig" : "popover.action.openPlugins"
|
|
1699
|
+
);
|
|
1567
1700
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1568
1701
|
"section",
|
|
1569
1702
|
{
|
|
@@ -1609,7 +1742,16 @@ function BalancePopover(props) {
|
|
|
1609
1742
|
] }),
|
|
1610
1743
|
shown !== null && !selection.matchesPreference ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: BalancePopover_default.notice, children: [
|
|
1611
1744
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: BalancePopover_default.noticeText, children: interpolate(t("popover.mismatch"), { wanted: displayCurrency, shown: shown.currency }) }),
|
|
1612
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: BalancePopover_default.noticeActions, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1745
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: BalancePopover_default.noticeActions, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1746
|
+
import_dsh_client_ui_primitives3.Button,
|
|
1747
|
+
{
|
|
1748
|
+
size: "sm",
|
|
1749
|
+
variant: "outline",
|
|
1750
|
+
disabled: useShownDisabled === true,
|
|
1751
|
+
onClick: onUseShown,
|
|
1752
|
+
children: interpolate(t("popover.action.useShown"), { shown: shown.currency })
|
|
1753
|
+
}
|
|
1754
|
+
) })
|
|
1613
1755
|
] }) : null,
|
|
1614
1756
|
configSlotWarning === null ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: BalancePopover_default.notice, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: BalancePopover_default.noticeText, children: configSlotWarning }) }),
|
|
1615
1757
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: BalancePopover_default.footer, children: [
|
|
@@ -1654,7 +1796,13 @@ var CROSS_ARM = (2 * RADIUS - STROKE) / 2 / Math.SQRT2;
|
|
|
1654
1796
|
function round3(value) {
|
|
1655
1797
|
return Math.round(value * 1e3) / 1e3;
|
|
1656
1798
|
}
|
|
1657
|
-
function PercentRing({
|
|
1799
|
+
function PercentRing({
|
|
1800
|
+
state,
|
|
1801
|
+
marker = null,
|
|
1802
|
+
ratio = 1,
|
|
1803
|
+
size = 18,
|
|
1804
|
+
title
|
|
1805
|
+
}) {
|
|
1658
1806
|
const clamped = Number.isFinite(ratio) ? Math.min(1, Math.max(0, ratio)) : 1;
|
|
1659
1807
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1660
1808
|
"svg",
|
|
@@ -1747,8 +1895,10 @@ function usePluginsNavigation(navigation) {
|
|
|
1747
1895
|
return action;
|
|
1748
1896
|
}
|
|
1749
1897
|
function stateLabelKey(response, selection) {
|
|
1750
|
-
if (response.state === "error")
|
|
1751
|
-
|
|
1898
|
+
if (response.state === "error")
|
|
1899
|
+
return response.error?.code === "NO_KEY" ? "state.noKey" : "state.error";
|
|
1900
|
+
if (response.state === "empty")
|
|
1901
|
+
return response.error?.code === "NO_KEY" ? "state.noKey" : "state.empty";
|
|
1752
1902
|
if (response.state === "stale") return "state.stale";
|
|
1753
1903
|
if (!response.isAvailable) return "state.unavailable";
|
|
1754
1904
|
if (selection.shown === null) return "state.noBalance";
|
|
@@ -1793,16 +1943,19 @@ function SidebarBalance({
|
|
|
1793
1943
|
}, []);
|
|
1794
1944
|
const preference = config.displayCurrency;
|
|
1795
1945
|
const selection = (0, import_react5.useMemo)(() => selectionOf(response, preference), [response, preference]);
|
|
1796
|
-
(0, import_react5.useEffect)(
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1946
|
+
(0, import_react5.useEffect)(
|
|
1947
|
+
() => subscribeScenario((key) => {
|
|
1948
|
+
const active = resolveScenario() !== null;
|
|
1949
|
+
setMock(active);
|
|
1950
|
+
if (!active || lastScenario.current === key) return;
|
|
1951
|
+
lastScenario.current = key;
|
|
1952
|
+
acceptBalance(currentBalance());
|
|
1953
|
+
setRefreshing(false);
|
|
1954
|
+
setCooldownUntil(0);
|
|
1955
|
+
setOpen(false);
|
|
1956
|
+
}),
|
|
1957
|
+
[acceptBalance]
|
|
1958
|
+
);
|
|
1806
1959
|
(0, import_react5.useEffect)(() => {
|
|
1807
1960
|
if (mock) return;
|
|
1808
1961
|
let cancelled = false;
|
|
@@ -1818,17 +1971,30 @@ function SidebarBalance({
|
|
|
1818
1971
|
}
|
|
1819
1972
|
};
|
|
1820
1973
|
void load();
|
|
1821
|
-
const id = window.setInterval(
|
|
1822
|
-
|
|
1823
|
-
|
|
1974
|
+
const id = window.setInterval(
|
|
1975
|
+
() => {
|
|
1976
|
+
void load();
|
|
1977
|
+
},
|
|
1978
|
+
Math.max(5, config.clientPollSeconds) * MS_PER_SECOND
|
|
1979
|
+
);
|
|
1824
1980
|
return () => {
|
|
1825
1981
|
cancelled = true;
|
|
1826
1982
|
window.clearInterval(id);
|
|
1827
1983
|
};
|
|
1828
|
-
}, [
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1984
|
+
}, [
|
|
1985
|
+
mock,
|
|
1986
|
+
preference,
|
|
1987
|
+
config.clientPollSeconds,
|
|
1988
|
+
config.configSignature,
|
|
1989
|
+
acceptBalance,
|
|
1990
|
+
showUnreachable
|
|
1991
|
+
]);
|
|
1992
|
+
(0, import_react5.useEffect)(
|
|
1993
|
+
() => () => {
|
|
1994
|
+
if (refreshTimer.current !== void 0) window.clearTimeout(refreshTimer.current);
|
|
1995
|
+
},
|
|
1996
|
+
[]
|
|
1997
|
+
);
|
|
1832
1998
|
const closeNow = (0, import_react5.useCallback)(() => {
|
|
1833
1999
|
setOpen(false);
|
|
1834
2000
|
}, []);
|
|
@@ -1870,7 +2036,9 @@ function SidebarBalance({
|
|
|
1870
2036
|
setRefreshing(true);
|
|
1871
2037
|
const finish = () => {
|
|
1872
2038
|
setRefreshing(false);
|
|
1873
|
-
setCooldownUntil(
|
|
2039
|
+
setCooldownUntil(
|
|
2040
|
+
Date.now() + Math.max(0, config.manualRefreshCooldownSeconds) * MS_PER_SECOND
|
|
2041
|
+
);
|
|
1874
2042
|
};
|
|
1875
2043
|
if (mock) {
|
|
1876
2044
|
refreshTimer.current = window.setTimeout(() => {
|
|
@@ -1892,7 +2060,16 @@ function SidebarBalance({
|
|
|
1892
2060
|
finish();
|
|
1893
2061
|
}
|
|
1894
2062
|
})();
|
|
1895
|
-
}, [
|
|
2063
|
+
}, [
|
|
2064
|
+
cooldownUntil,
|
|
2065
|
+
config.manualRefreshCooldownSeconds,
|
|
2066
|
+
mock,
|
|
2067
|
+
preference,
|
|
2068
|
+
refreshing,
|
|
2069
|
+
acceptBalance,
|
|
2070
|
+
showUnreachable,
|
|
2071
|
+
markFresh
|
|
2072
|
+
]);
|
|
1896
2073
|
const handleUseShown = (0, import_react5.useCallback)(() => {
|
|
1897
2074
|
const current = selection.shown;
|
|
1898
2075
|
if (current === null) return;
|
|
@@ -1949,42 +2126,42 @@ function SidebarBalance({
|
|
|
1949
2126
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: SidebarBalance_default.icon, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PercentRing, { state: ring.state, marker: ring.marker, ratio: ringRatio, size: 16 }) }),
|
|
1950
2127
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: SidebarBalance_default.label, children: t("sidebar.label") }),
|
|
1951
2128
|
markerLabel === null ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_dsh_client_ui_primitives4.Tooltip, { label: markerHint, side: "bottom", delayMs: 500, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: SidebarBalance_default.marker, role: "img", "aria-label": markerLabel, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_dsh_client_ui_primitives4.IconWarningOutlineRegular, { size: 12 }) }) })
|
|
1952
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
children: [
|
|
1963
|
-
wide && hoverLabel !== null ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_dsh_client_ui_primitives4.Tooltip, { label: hoverLabel, side: "right", delayMs: 500, disabled: open, children: trigger }) : trigger,
|
|
1964
|
-
open ? (0, import_react_dom.createPortal)(
|
|
1965
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1966
|
-
BalancePopover,
|
|
1967
|
-
{
|
|
1968
|
-
t,
|
|
1969
|
-
selection,
|
|
1970
|
-
displayCurrency: preference,
|
|
1971
|
-
ageMs,
|
|
1972
|
-
refreshing,
|
|
1973
|
-
cooldownSeconds,
|
|
1974
|
-
configSlotWarning: configSlotState === "missing" ? CONFIG_SLOT_WARNING : null,
|
|
1975
|
-
panelRef,
|
|
1976
|
-
style: pos ?? MEASURE_STYLE,
|
|
1977
|
-
onRefresh: handleRefresh,
|
|
1978
|
-
onUseShown: handleUseShown,
|
|
1979
|
-
useShownDisabled: !config.writable,
|
|
1980
|
-
pluginsAction: popoverPluginsAction
|
|
1981
|
-
}
|
|
1982
|
-
),
|
|
1983
|
-
document.body
|
|
1984
|
-
) : null
|
|
1985
|
-
]
|
|
2129
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2130
|
+
PercentRing,
|
|
2131
|
+
{
|
|
2132
|
+
state: ring.state,
|
|
2133
|
+
marker: ring.marker,
|
|
2134
|
+
ratio: ringRatio,
|
|
2135
|
+
size: 18,
|
|
2136
|
+
title: ringTitle
|
|
2137
|
+
}
|
|
2138
|
+
)
|
|
1986
2139
|
}
|
|
1987
2140
|
);
|
|
2141
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: rootRef, className: SidebarBalance_default.root, "data-mode": wide ? "wide" : "rail", tabIndex: -1, children: [
|
|
2142
|
+
wide && hoverLabel !== null ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_dsh_client_ui_primitives4.Tooltip, { label: hoverLabel, side: "right", delayMs: 500, disabled: open, children: trigger }) : trigger,
|
|
2143
|
+
open ? (0, import_react_dom.createPortal)(
|
|
2144
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2145
|
+
BalancePopover,
|
|
2146
|
+
{
|
|
2147
|
+
t,
|
|
2148
|
+
selection,
|
|
2149
|
+
displayCurrency: preference,
|
|
2150
|
+
ageMs,
|
|
2151
|
+
refreshing,
|
|
2152
|
+
cooldownSeconds,
|
|
2153
|
+
configSlotWarning: configSlotState === "missing" ? CONFIG_SLOT_WARNING : null,
|
|
2154
|
+
panelRef,
|
|
2155
|
+
style: pos ?? MEASURE_STYLE,
|
|
2156
|
+
onRefresh: handleRefresh,
|
|
2157
|
+
onUseShown: handleUseShown,
|
|
2158
|
+
useShownDisabled: !config.writable,
|
|
2159
|
+
pluginsAction: popoverPluginsAction
|
|
2160
|
+
}
|
|
2161
|
+
),
|
|
2162
|
+
document.body
|
|
2163
|
+
) : null
|
|
2164
|
+
] });
|
|
1988
2165
|
}
|
|
1989
2166
|
|
|
1990
2167
|
// src/client/index.tsx
|
|
@@ -2142,7 +2319,10 @@ function apply(ctx) {
|
|
|
2142
2319
|
const candidate = face["openBundle"];
|
|
2143
2320
|
if (typeof candidate !== "function") return;
|
|
2144
2321
|
const openBundle = candidate.bind(face);
|
|
2145
|
-
navCtx.effect(
|
|
2322
|
+
navCtx.effect(
|
|
2323
|
+
() => pluginsNavigation.attachDeepLink(openBundle),
|
|
2324
|
+
"ds-balance: bundle config deep link"
|
|
2325
|
+
);
|
|
2146
2326
|
});
|
|
2147
2327
|
ctx.inject(["layout"], (layoutCtx) => {
|
|
2148
2328
|
if (!("layout" in layoutCtx)) return;
|
|
@@ -2160,25 +2340,31 @@ function apply(ctx) {
|
|
|
2160
2340
|
ctx.inject(["configForms"], (configCtx) => {
|
|
2161
2341
|
configSlotProbe.markDeclared();
|
|
2162
2342
|
const form = configCtx.configForms.get(ENTRY_ID);
|
|
2163
|
-
ctx.slots.inject(
|
|
2164
|
-
|
|
2165
|
-
(
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
{ name: "sidebar.footer.action", id: SIDEBAR_ENTRY_ID, order: 0, locale: NS },
|
|
2169
|
-
(seat) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2170
|
-
SidebarSeatComponent,
|
|
2171
|
-
{
|
|
2172
|
-
seat,
|
|
2173
|
-
form,
|
|
2174
|
-
configSlotProbe,
|
|
2175
|
-
pluginsNavigation
|
|
2176
|
-
}
|
|
2343
|
+
ctx.slots.inject(
|
|
2344
|
+
CONFIG_SLOT,
|
|
2345
|
+
() => ctx.slots.register(
|
|
2346
|
+
{ name: CONFIG_SLOT, key: BUNDLE_CONFIG_KEY, locale: NS },
|
|
2347
|
+
(seat) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SettingsSeatComponent, { seat, form })
|
|
2177
2348
|
)
|
|
2178
|
-
)
|
|
2349
|
+
);
|
|
2350
|
+
ctx.slots.inject(
|
|
2351
|
+
"sidebar.footer.action",
|
|
2352
|
+
() => ctx.slots.register(
|
|
2353
|
+
{ name: "sidebar.footer.action", id: SIDEBAR_ENTRY_ID, order: 0, locale: NS },
|
|
2354
|
+
(seat) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2355
|
+
SidebarSeatComponent,
|
|
2356
|
+
{
|
|
2357
|
+
seat,
|
|
2358
|
+
form,
|
|
2359
|
+
configSlotProbe,
|
|
2360
|
+
pluginsNavigation
|
|
2361
|
+
}
|
|
2362
|
+
)
|
|
2363
|
+
)
|
|
2364
|
+
);
|
|
2179
2365
|
});
|
|
2180
2366
|
}
|
|
2181
|
-
var __dsbCss = "/* src/client/settings/fields.module.css */\n.fields_group {\n padding: 12px 0 0;\n}\n.fields_groupLast {\n padding-bottom: 12px;\n}\n.fields_groupNote {\n margin: 4px 0 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n.fields_fields {\n display: flex;\n flex-direction: column;\n}\n.fields_fields > * + * {\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n.fields_details {\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n margin-top: 12px;\n padding-top: 12px;\n}\n.fields_detailsSummary {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n line-height: 18px;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n list-style: none;\n}\n.fields_detailsSummary::-webkit-details-marker {\n display: none;\n}\n.fields_detailsSummary::before {\n content: \"\";\n flex: none;\n width: 5px;\n height: 5px;\n border-right: 1.5px solid currentColor;\n border-bottom: 1.5px solid currentColor;\n transform: translate(-0.5px, -1px) rotate(-45deg);\n transition: transform 120ms ease;\n}\n.fields_details[open] > .fields_detailsSummary::before {\n transform: translate(-0.5px, -1px) rotate(45deg);\n}\n.fields_detailsBody {\n padding-top: 10px;\n}\n.fields_field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px 0;\n}\n.fields_row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 0;\n}\n.fields_rowText {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding-right: 48px;\n}\n.fields_rowTitleLine {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.fields_rowTitle {\n flex: 1;\n min-width: 0;\n font-size: 13px;\n font-weight: 500;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n}\n.fields_head {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.fields_label {\n flex: 1;\n min-width: 0;\n font-size: 13px;\n font-weight: 500;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n}\n.fields_badges {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n.fields_reset {\n border: none;\n background: none;\n padding: 0;\n font: inherit;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n.fields_reset:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n.fields_reset:disabled {\n cursor: default;\n}\n.fields_input {\n box-sizing: border-box;\n width: 100%;\n height: 34px;\n padding: 0 12px;\n border: 0.5px solid var(--dsw-alias-border-l4);\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-3);\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n}\n.fields_input:focus-visible {\n outline: none;\n border-color: var(--dsw-alias-brand-primary);\n}\n.fields_input:disabled {\n color: var(--dsw-alias-label-tertiary);\n opacity: 0.6;\n cursor: default;\n}\ninput.fields_inputStatic,\ninput.fields_inputStatic:hover,\ninput.fields_inputStatic:focus,\ninput.fields_inputStatic:focus-visible,\ninput.fields_inputStatic:active {\n border-color: var(--dsw-alias-border-l4);\n background: var(--dsw-alias-bg-layer-3);\n outline: none;\n box-shadow: none;\n cursor: default;\n pointer-events: none;\n}\n.fields_inputInvalid {\n box-sizing: border-box;\n width: 100%;\n height: 34px;\n padding: 0 12px;\n border: 1px solid var(--dsw-alias-state-error-primary);\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-3);\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n}\n.fields_inputInvalid:focus-visible {\n outline: none;\n border-color: var(--dsw-alias-brand-primary);\n}\n.fields_inputInvalid:disabled {\n color: var(--dsw-alias-label-tertiary);\n cursor: default;\n}\n.fields_inputWithAction {\n position: relative;\n display: flex;\n align-items: center;\n}\n.fields_inputWithAction .fields_input,\n.fields_inputWithAction .fields_inputInvalid {\n padding-right: 38px;\n}\n.fields_reveal {\n position: absolute;\n right: 4px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n padding: 0;\n border: none;\n border-radius: 999px;\n corner-shape: round;\n background: transparent;\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n.fields_reveal:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-secondary);\n}\n.fields_revealOn {\n color: var(--dsw-alias-label-primary);\n}\n.fields_reveal:disabled {\n cursor: default;\n opacity: 0.4;\n}\n.fields_selectorAnchor {\n flex: none;\n}\n.fields_selector {\n display: inline-flex;\n align-items: center;\n gap: 12px;\n flex: none;\n max-width: 100%;\n height: 36px;\n padding: 0 14px;\n border: none;\n border-radius: 18px;\n background: var(--dsw-alias-bg-module-platform);\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n color: var(--dsw-alias-label-primary);\n text-align: left;\n cursor: pointer;\n}\n.fields_selector:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.fields_selector:disabled {\n color: var(--dsw-alias-label-tertiary);\n cursor: default;\n}\n.fields_selectorChevron {\n flex: none;\n}\n.fields_hint {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n.fields_pairNote {\n display: flex;\n align-items: center;\n gap: 6px;\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-state-warn-primary);\n}\n.fields_pairNote::before {\n content: \"\";\n flex: none;\n width: 5px;\n height: 5px;\n border-radius: 999px;\n corner-shape: round;\n background: currentColor;\n}\n.fields_invalid {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-state-error-primary);\n}\n.fields_actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.fields_actionButton {\n appearance: none;\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: 8px;\n padding: 5px 14px;\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n cursor: pointer;\n background: none;\n color: var(--dsw-alias-label-secondary);\n}\n.fields_actionButton:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n border-color: var(--dsw-alias-label-dimmed);\n}\n.fields_actionButton:disabled {\n opacity: 0.4;\n cursor: default;\n}\n.fields_actionButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n.fields_resultOk {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-state-success-primary);\n}\n.fields_resultFail {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-state-error-primary);\n}\n\n/* src/client/settings/BalanceSettingsCard.module.css */\n.BalanceSettingsCard_form {\n display: flex;\n flex-direction: column;\n}\n.BalanceSettingsCard_readOnly {\n margin: 0 0 12px;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n.BalanceSettingsCard_footer {\n display: flex;\n align-items: center;\n gap: 8px;\n padding-top: 16px;\n}\n.BalanceSettingsCard_failed {\n flex: 1;\n min-width: 0;\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-state-error-primary);\n}\n.BalanceSettingsCard_notice {\n flex: 1;\n min-width: 0;\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n.BalanceSettingsCard_save {\n appearance: none;\n border: 0.5px solid transparent;\n border-radius: 8px;\n padding: 5px 14px;\n font: inherit;\n font-size: 13px;\n line-height: 1.5;\n cursor: pointer;\n background: var(--dsw-alias-label-primary);\n color: var(--dsw-alias-bg-layer-3);\n}\n.BalanceSettingsCard_save:disabled {\n opacity: 0.4;\n cursor: default;\n}\n.BalanceSettingsCard_save:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n\n/* src/client/sidebar/BalancePopover.module.css */\n.BalancePopover_panel {\n position: fixed;\n isolation: isolate;\n z-index: 1100;\n box-sizing: border-box;\n width: max-content;\n min-width: min(300px, calc(100vw - 24px));\n max-width: min(440px, calc(100vw - 24px));\n padding: 16px;\n border: 0;\n border-radius: 12px;\n --dsw-elevation-stroke-color: var(--dsw-alias-border-l1);\n box-shadow: var(--dsw-elevation-prominent);\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-secondary);\n cursor: default;\n}\n.BalancePopover_panel::before {\n position: absolute;\n z-index: -1;\n inset: 0;\n border-radius: inherit;\n background: var(--dsw-specific-menu);\n backdrop-filter: var(--dsw-menu-backdrop-filter);\n content: \"\";\n pointer-events: none;\n}\n.BalancePopover_title {\n display: flex;\n justify-content: space-between;\n gap: 16px;\n margin-bottom: 8px;\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n.BalancePopover_titleLabel {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n cursor: pointer;\n color: inherit;\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n.BalancePopover_titleLabel:hover,\n.BalancePopover_titleLabel:visited {\n color: inherit;\n}\n.BalancePopover_titleLabel svg {\n flex: none;\n width: 14px;\n height: auto;\n}\n.BalancePopover_iconButton {\n position: relative;\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 50%;\n corner-shape: round;\n padding: 0;\n background: transparent;\n cursor: pointer;\n color: var(--dsw-alias-label-secondary);\n}\n.BalancePopover_iconButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.BalancePopover_iconButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n.BalancePopover_titleRule {\n margin-bottom: 10px;\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n.BalancePopover_details {\n display: grid;\n grid-template-columns: minmax(76px, auto) minmax(0, 1fr);\n gap: 6px 16px;\n margin: 0;\n color: var(--dsw-alias-label-tertiary);\n}\n.BalancePopover_details dt,\n.BalancePopover_details dd {\n min-width: 0;\n margin: 0;\n}\n.BalancePopover_details dd {\n color: var(--dsw-alias-label-secondary);\n font-variant-numeric: tabular-nums;\n text-align: right;\n}\n.BalancePopover_notice {\n margin-top: 12px;\n}\n.BalancePopover_noticeText {\n margin: 0 0 8px;\n color: var(--dsw-alias-label-tertiary);\n}\n.BalancePopover_noticeActions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n}\n.BalancePopover_footer {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 12px;\n}\n.BalancePopover_updated {\n flex: none;\n color: var(--dsw-alias-label-tertiary);\n}\n.BalancePopover_status {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n text-align: right;\n color: var(--dsw-alias-label-tertiary);\n}\n.BalancePopover_refresh {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: none;\n border-radius: 999px;\n corner-shape: round;\n background: transparent;\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n.BalancePopover_refresh:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-secondary);\n}\n.BalancePopover_refresh:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n.BalancePopover_refresh:disabled {\n opacity: 0.4;\n cursor: default;\n}\n.BalancePopover_refresh[data-cooling] {\n color: var(--dsw-alias-label-caption);\n}\n.BalancePopover_refresh[data-refreshing] svg {\n animation: BalancePopover_balance-refresh-spin 900ms linear infinite;\n}\n@keyframes BalancePopover_balance-refresh-spin {\n to {\n transform: rotate(360deg);\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .BalancePopover_refresh[data-refreshing] svg {\n animation-duration: 2400ms;\n }\n}\n\n/* src/client/sidebar/PercentRing.module.css */\n.PercentRing_ring {\n display: block;\n flex: none;\n color: var(--dsw-alias-label-tertiary);\n}\n.PercentRing_ring[data-state=done] {\n color: var(--dsw-alias-state-success-primary);\n}\n.PercentRing_ring[data-state=warning] {\n color: var(--dsw-alias-state-warn-primary);\n}\n.PercentRing_ring[data-state=error] {\n color: var(--dsw-alias-state-error-primary);\n}\n.PercentRing_ring[data-state=idle] {\n color: var(--dsw-alias-state-idle-primary);\n}\n.PercentRing_track {\n fill: none;\n stroke: var(--dsw-alias-border-l3);\n stroke-width: 1;\n}\n.PercentRing_fill {\n fill: none;\n stroke: currentColor;\n stroke-width: 1;\n stroke-linecap: round;\n}\n.PercentRing_cross {\n fill: none;\n stroke: currentColor;\n stroke-width: 1;\n stroke-linecap: round;\n}\n\n/* src/client/sidebar/SidebarBalance.module.css */\n.SidebarBalance_root {\n position: relative;\n display: flex;\n min-width: 0;\n}\n.SidebarBalance_root[data-mode=wide] {\n flex: none;\n width: calc(100% + 4px);\n margin: 4px -2px 0;\n}\n.SidebarBalance_root[data-mode=rail] {\n flex: none;\n margin: 8px 0 0;\n}\n.SidebarBalance_trigger {\n display: flex;\n align-items: center;\n box-sizing: border-box;\n border: none;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font-family: inherit;\n font-size: 14px;\n line-height: 22px;\n cursor: pointer;\n overflow: hidden;\n}\n.SidebarBalance_trigger:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.SidebarBalance_trigger:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n.SidebarBalance_root[data-mode=wide] .SidebarBalance_trigger {\n flex: none;\n gap: 8px;\n width: 100%;\n height: 42px;\n padding: 0 10px 0 8px;\n border-radius: 12px;\n}\n.SidebarBalance_root[data-mode=rail] .SidebarBalance_trigger {\n flex: none;\n justify-content: center;\n width: 36px;\n height: 36px;\n padding: 0;\n border-radius: 12px;\n}\n.SidebarBalance_icon {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n}\n.SidebarBalance_label {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.SidebarBalance_marker {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n color: var(--dsw-alias-label-tertiary);\n position: relative;\n top: 1.63px;\n}\n\n/* src/client/sidebar/footer-stack.module.css */\ndiv:has(> [data-slot=\"sidebar.footer.action\"]) {\n flex-direction: column;\n}\n";
|
|
2367
|
+
var __dsbCss = "/* src/client/settings/fields.module.css */\n.fields_group {\n padding: 12px 0 0;\n}\n.fields_groupLast {\n padding-bottom: 12px;\n}\n.fields_groupNote {\n margin: 4px 0 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n.fields_fields {\n display: flex;\n flex-direction: column;\n}\n.fields_fields > * + * {\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n.fields_details {\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n margin-top: 12px;\n padding-top: 12px;\n}\n.fields_detailsBody {\n padding-top: 10px;\n}\n.fields_field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px 0;\n}\n.fields_row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 0;\n}\n.fields_rowText {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding-right: 48px;\n}\n.fields_rowTitleLine {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.fields_rowTitle {\n flex: 1;\n min-width: 0;\n font-size: 13px;\n font-weight: 500;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n}\n.fields_head {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.fields_label {\n flex: 1;\n min-width: 0;\n font-size: 13px;\n font-weight: 500;\n line-height: 1.5;\n color: var(--dsw-alias-label-primary);\n}\n.fields_badges {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n.fields_reset {\n border: none;\n background: none;\n padding: 0;\n font: inherit;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n}\n.fields_reset:hover:not(:disabled) {\n color: var(--dsw-alias-label-primary);\n}\n.fields_reset:disabled {\n cursor: default;\n}\n.fields_inputStatic,\n.fields_inputStatic:hover {\n pointer-events: none;\n}\n.fields_inputStatic input,\n.fields_inputStatic input:hover,\n.fields_inputStatic input:focus,\n.fields_inputStatic input:focus-visible,\n.fields_inputStatic input:active {\n border-color: var(--dsw-alias-border-l4);\n background: var(--dsw-alias-bg-layer-3);\n outline: none;\n box-shadow: none;\n cursor: default;\n}\n.fields_inputInvalid input {\n border: 1px solid var(--dsw-alias-state-error-primary);\n}\n.fields_inputInvalid input:focus-visible {\n border-color: var(--dsw-alias-brand-primary);\n}\n.fields_inputWithAction {\n position: relative;\n display: flex;\n align-items: center;\n}\n.fields_inputWithAction .fields_input,\n.fields_inputWithAction .fields_inputInvalid {\n padding-right: 38px;\n}\n.fields_reveal {\n position: absolute;\n right: 4px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n padding: 0;\n border: none;\n border-radius: 999px;\n corner-shape: round;\n background: transparent;\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n.fields_reveal:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-secondary);\n}\n.fields_revealOn {\n color: var(--dsw-alias-label-primary);\n}\n.fields_reveal:disabled {\n cursor: default;\n opacity: 0.4;\n}\n.fields_selectorAnchor {\n flex: none;\n}\n.fields_selector {\n display: inline-flex;\n align-items: center;\n gap: 12px;\n flex: none;\n max-width: 100%;\n height: 36px;\n padding: 0 14px;\n border: none;\n border-radius: 18px;\n background: var(--dsw-alias-bg-module-platform);\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n color: var(--dsw-alias-label-primary);\n text-align: left;\n cursor: pointer;\n}\n.fields_selector:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.fields_selector:disabled {\n color: var(--dsw-alias-label-tertiary);\n cursor: default;\n}\n.fields_selectorChevron {\n flex: none;\n}\n.fields_hint {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n.fields_pairNote {\n display: flex;\n align-items: center;\n gap: 6px;\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-state-warn-primary);\n}\n.fields_pairNote::before {\n content: \"\";\n flex: none;\n width: 5px;\n height: 5px;\n border-radius: 999px;\n corner-shape: round;\n background: currentColor;\n}\n.fields_invalid {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-state-error-primary);\n}\n.fields_actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.fields_resultOk {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-state-success-primary);\n}\n.fields_resultFail {\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-state-error-primary);\n}\n\n/* src/client/settings/BalanceSettingsCard.module.css */\n.BalanceSettingsCard_form {\n display: flex;\n flex-direction: column;\n}\n.BalanceSettingsCard_readOnly {\n margin: 0 0 12px;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n.BalanceSettingsCard_footer {\n display: flex;\n align-items: center;\n gap: 8px;\n padding-top: 16px;\n}\n.BalanceSettingsCard_failed {\n flex: 1;\n min-width: 0;\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-state-error-primary);\n}\n.BalanceSettingsCard_notice {\n flex: 1;\n min-width: 0;\n margin: 0;\n font-size: 12px;\n line-height: 1.5;\n color: var(--dsw-alias-label-tertiary);\n}\n\n/* src/client/sidebar/BalancePopover.module.css */\n.BalancePopover_panel {\n position: fixed;\n isolation: isolate;\n z-index: 1100;\n box-sizing: border-box;\n width: max-content;\n min-width: min(300px, calc(100vw - 24px));\n max-width: min(440px, calc(100vw - 24px));\n padding: 16px;\n border: 0;\n border-radius: 12px;\n --dsw-elevation-stroke-color: var(--dsw-alias-border-l1);\n box-shadow: var(--dsw-elevation-prominent);\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-secondary);\n cursor: default;\n}\n.BalancePopover_panel::before {\n position: absolute;\n z-index: -1;\n inset: 0;\n border-radius: inherit;\n background: var(--dsw-specific-menu);\n backdrop-filter: var(--dsw-menu-backdrop-filter);\n content: \"\";\n pointer-events: none;\n}\n.BalancePopover_title {\n display: flex;\n justify-content: space-between;\n gap: 16px;\n margin-bottom: 8px;\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n.BalancePopover_titleLabel {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n cursor: pointer;\n color: inherit;\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n.BalancePopover_titleLabel:hover,\n.BalancePopover_titleLabel:visited {\n color: inherit;\n}\n.BalancePopover_titleLabel svg {\n flex: none;\n width: 14px;\n height: auto;\n}\n.BalancePopover_iconButton {\n position: relative;\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n border-radius: 50%;\n corner-shape: round;\n padding: 0;\n background: transparent;\n cursor: pointer;\n color: var(--dsw-alias-label-secondary);\n}\n.BalancePopover_iconButton:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.BalancePopover_iconButton:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n.BalancePopover_titleRule {\n margin-bottom: 10px;\n border-top: 0.5px solid var(--dsw-alias-border-l2);\n}\n.BalancePopover_details {\n display: grid;\n grid-template-columns: minmax(76px, auto) minmax(0, 1fr);\n gap: 6px 16px;\n margin: 0;\n color: var(--dsw-alias-label-tertiary);\n}\n.BalancePopover_details dt,\n.BalancePopover_details dd {\n min-width: 0;\n margin: 0;\n}\n.BalancePopover_details dd {\n color: var(--dsw-alias-label-secondary);\n font-variant-numeric: tabular-nums;\n text-align: right;\n}\n.BalancePopover_notice {\n margin-top: 12px;\n}\n.BalancePopover_noticeText {\n margin: 0 0 8px;\n color: var(--dsw-alias-label-tertiary);\n}\n.BalancePopover_noticeActions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n}\n.BalancePopover_footer {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 12px;\n}\n.BalancePopover_updated {\n flex: none;\n color: var(--dsw-alias-label-tertiary);\n}\n.BalancePopover_status {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n text-align: right;\n color: var(--dsw-alias-label-tertiary);\n}\n.BalancePopover_refresh {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: none;\n border-radius: 999px;\n corner-shape: round;\n background: transparent;\n color: var(--dsw-alias-label-tertiary);\n cursor: pointer;\n}\n.BalancePopover_refresh:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-secondary);\n}\n.BalancePopover_refresh:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: 1px;\n}\n.BalancePopover_refresh:disabled {\n opacity: 0.4;\n cursor: default;\n}\n.BalancePopover_refresh[data-cooling] {\n color: var(--dsw-alias-label-caption);\n}\n.BalancePopover_refresh[data-refreshing] svg {\n animation: BalancePopover_balance-refresh-spin 900ms linear infinite;\n}\n@keyframes BalancePopover_balance-refresh-spin {\n to {\n transform: rotate(360deg);\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .BalancePopover_refresh[data-refreshing] svg {\n animation-duration: 2400ms;\n }\n}\n\n/* src/client/sidebar/PercentRing.module.css */\n.PercentRing_ring {\n display: block;\n flex: none;\n color: var(--dsw-alias-label-tertiary);\n}\n.PercentRing_ring[data-state=done] {\n color: var(--dsw-alias-state-success-primary);\n}\n.PercentRing_ring[data-state=warning] {\n color: var(--dsw-alias-state-warn-primary);\n}\n.PercentRing_ring[data-state=error] {\n color: var(--dsw-alias-state-error-primary);\n}\n.PercentRing_ring[data-state=idle] {\n color: var(--dsw-alias-state-idle-primary);\n}\n.PercentRing_track {\n fill: none;\n stroke: var(--dsw-alias-border-l3);\n stroke-width: 1;\n}\n.PercentRing_fill {\n fill: none;\n stroke: currentColor;\n stroke-width: 1;\n stroke-linecap: round;\n}\n.PercentRing_cross {\n fill: none;\n stroke: currentColor;\n stroke-width: 1;\n stroke-linecap: round;\n}\n\n/* src/client/sidebar/SidebarBalance.module.css */\n.SidebarBalance_root {\n position: relative;\n display: flex;\n min-width: 0;\n}\n.SidebarBalance_root[data-mode=wide] {\n flex: none;\n width: calc(100% + 4px);\n margin: 4px -2px 0;\n}\n.SidebarBalance_root[data-mode=rail] {\n flex: none;\n margin: 8px 0 0;\n}\n.SidebarBalance_trigger {\n display: flex;\n align-items: center;\n box-sizing: border-box;\n border: none;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n font-family: inherit;\n font-size: 14px;\n line-height: 22px;\n cursor: pointer;\n overflow: hidden;\n}\n.SidebarBalance_trigger:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n.SidebarBalance_trigger:focus-visible {\n outline: 2px solid var(--dsw-alias-brand-primary);\n outline-offset: -2px;\n}\n.SidebarBalance_root[data-mode=wide] .SidebarBalance_trigger {\n flex: none;\n gap: 8px;\n width: 100%;\n height: 42px;\n padding: 0 10px 0 8px;\n border-radius: 12px;\n}\n.SidebarBalance_root[data-mode=rail] .SidebarBalance_trigger {\n flex: none;\n justify-content: center;\n width: 36px;\n height: 36px;\n padding: 0;\n border-radius: 12px;\n}\n.SidebarBalance_icon {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n}\n.SidebarBalance_label {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.SidebarBalance_marker {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n color: var(--dsw-alias-label-tertiary);\n position: relative;\n top: 1.63px;\n}\n\n/* src/client/sidebar/footer-stack.module.css */\ndiv:has(> [data-slot=\"sidebar.footer.action\"]) {\n flex-direction: column;\n}\n";
|
|
2182
2368
|
var __dsbTagId = "dsh-ds-balance/client.css";
|
|
2183
2369
|
if (typeof document !== 'undefined' && document.querySelector('style[data-plugin-css="' + __dsbTagId + '"]') === null) {
|
|
2184
2370
|
var __dsbTag = document.createElement('style');
|