@jxgame2020/dsh-token-quota 0.1.42 → 0.1.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +293 -148
- package/lib/index.js +1 -1
- package/lib/types/client/TokenQuotaPanel.d.ts +8 -1
- package/lib/types/client/TokenQuotaPanel.js +61 -2
- package/lib/types/client/index.js +54 -24
- package/lib/types/client/locales.d.ts +20 -0
- package/lib/types/client/locales.js +24 -4
- package/package.json +4 -3
package/lib/client.js
CHANGED
|
@@ -132,7 +132,7 @@ window.__ModuleLoader__.load({
|
|
|
132
132
|
d.transcribe = settings;
|
|
133
133
|
},
|
|
134
134
|
setUpgrade: (d, upgrade) => {
|
|
135
|
-
const normalized = upgrade !== null && upgrade.latestVersion !== "" && upgrade.latestVersion !== "0.1.
|
|
135
|
+
const normalized = upgrade !== null && upgrade.latestVersion !== "" && upgrade.latestVersion !== "0.1.44" ? upgrade : null;
|
|
136
136
|
if (d.upgrade === null || d.upgrade.latestVersion !== normalized?.latestVersion) d.upgradeDismissed = false;
|
|
137
137
|
d.upgrade = normalized;
|
|
138
138
|
},
|
|
@@ -252,7 +252,7 @@ window.__ModuleLoader__.load({
|
|
|
252
252
|
}
|
|
253
253
|
//#endregion
|
|
254
254
|
//#region \0dsh-css:/Users/jxgame/Desktop/works/deepseek-harness-package/dsh-token-quota/packages/token-quota/src/client/TokenQuotaPanel.module.css.mjs
|
|
255
|
-
const css$1 = ".NPLLIq_panel{box-sizing:border-box;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);pointer-events:auto;z-index:40;opacity:1;border-radius:12px;flex-direction:column;width:320px;max-height:min(72vh,560px);transition:opacity .18s;display:flex;position:fixed;top:56px;right:12px;overflow:hidden;box-shadow:0 8px 28px #0000002e}.NPLLIq_panelDim{opacity:.55}.NPLLIq_panelDimStrong{opacity:.3}.NPLLIq_header{border-bottom:1px solid var(--dsw-alias-border-l1);cursor:grab;user-select:none;touch-action:none;flex-wrap:wrap;justify-content:space-between;align-items:flex-start;gap:8px;padding:10px 12px;display:flex}.NPLLIq_header:active{cursor:grabbing}.NPLLIq_headerText{flex-direction:column;gap:2px;min-width:0;display:flex}.NPLLIq_title{color:var(--dsw-alias-label-primary);align-items:baseline;gap:6px;font-size:13px;font-weight:600;display:flex}.NPLLIq_version{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:10px;font-weight:500}.NPLLIq_versionNew{color:var(--dsw-alias-status-warning-foreground,#b56900);background:var(--dsw-alias-status-warning-background,#fff6d7);cursor:default;border-radius:4px;padding:1px 6px}.NPLLIq_subtitle{color:var(--dsw-alias-label-secondary);font-size:11px}.NPLLIq_notesBar{flex-wrap:wrap;flex:100%;align-items:center;gap:4px;padding:2px 0 0;display:flex}.NPLLIq_noteChip{width:20px;height:20px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);cursor:pointer;border-radius:5px;flex:none;justify-content:center;align-items:center;padding:0;font-size:11px;line-height:1;transition:color .12s,border-color .12s;display:inline-flex}.NPLLIq_noteChip:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l2)}.NPLLIq_noteChipOpen{color:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}.NPLLIq_noteNew{width:22px;height:20px;color:var(--dsw-alias-label-secondary);border:1px dashed var(--dsw-alias-border-l2);cursor:pointer;background:0 0;border-radius:5px;flex:none;justify-content:center;align-items:center;padding:0;transition:color .12s,border-color .12s;display:inline-flex;position:relative}.NPLLIq_noteNew:hover:not(:disabled){color:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}.NPLLIq_noteNew:disabled{opacity:.4;cursor:not-allowed}.NPLLIq_noteNewPlus{color:inherit;font-size:10px;font-weight:700;line-height:1;position:absolute;bottom:-2px;right:-1px}.NPLLIq_noteWin{z-index:60;pointer-events:auto;box-sizing:border-box;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;flex-direction:column;display:flex;position:fixed;overflow:hidden;box-shadow:0 8px 24px #00000038}.NPLLIq_noteWinCollapsed{height:auto!important}.NPLLIq_noteWinBar{background:var(--dsw-alias-bg-layer-1);border-bottom:1px solid var(--dsw-alias-border-l1);cursor:grab;user-select:none;flex:none;align-items:center;gap:4px;padding:4px 6px;display:flex}.NPLLIq_noteWinBar:active{cursor:grabbing}.NPLLIq_noteWinGripBar{color:var(--dsw-alias-label-secondary);opacity:.7;flex:none;font-size:10px}.NPLLIq_noteWinTitleText{min-width:0;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;padding:1px 2px;font-size:11px;font-weight:600;overflow:hidden}.NPLLIq_noteWinTitle{min-width:0;color:var(--dsw-alias-label-primary);background:0 0;border:1px solid #0000;border-radius:4px;outline:none;flex:1;padding:1px 2px;font-size:11px;font-weight:600}.NPLLIq_noteWinTitle:hover{border-color:var(--dsw-alias-border-l1)}.NPLLIq_noteWinTitle:focus{background:var(--dsw-alias-bg-overlay);border-color:var(--dsw-alias-brand-primary)}.NPLLIq_noteWinBtn{width:18px;height:18px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;flex:none;justify-content:center;align-items:center;padding:0;font-size:12px;line-height:1;display:inline-flex}.NPLLIq_noteWinBtn:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.NPLLIq_noteWinText{box-sizing:border-box;width:100%;min-height:0;color:var(--dsw-alias-label-primary);resize:none;background:0 0;border:none;outline:none;flex:1;padding:6px 8px;font-family:inherit;font-size:11px;line-height:1.5}.NPLLIq_noteWinResize{cursor:nwse-resize;background:linear-gradient(135deg, transparent 0 45%, var(--dsw-alias-border-l2) 45% 55%, transparent 55% 70%, var(--dsw-alias-border-l2) 70% 80%, transparent 80%);width:14px;height:14px;position:absolute;bottom:0;right:0}.NPLLIq_noteMenuBackdrop{z-index:100;pointer-events:auto;position:fixed;inset:0}.NPLLIq_noteMenu{z-index:101;pointer-events:auto;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;flex-direction:column;min-width:96px;padding:4px;display:flex;position:fixed;box-shadow:0 8px 24px #0000003d}.NPLLIq_noteMenuItem{text-align:left;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:none;border-radius:5px;padding:5px 8px;font-size:11px}.NPLLIq_noteMenuItem:hover{background:var(--dsw-alias-bg-layer-2)}.NPLLIq_collapse{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;padding:2px 6px;font-size:11px}.NPLLIq_collapse:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_body{padding:4px 0;overflow-y:auto}.NPLLIq_row{border-bottom:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:6px;padding:8px 12px;display:flex}.NPLLIq_rowHeader{justify-content:space-between;align-items:center;gap:8px;display:flex}.NPLLIq_rowDrag{cursor:grab;color:var(--dsw-alias-label-secondary);user-select:none;border-radius:4px;flex:none;margin-right:2px;padding:2px 3px;font-size:11px;line-height:1}.NPLLIq_rowDrag:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_rowDrag:active{cursor:grabbing}.NPLLIq_rowDragging{opacity:.45}.NPLLIq_rowDropTarget{box-shadow:inset 0 2px 0 var(--dsw-alias-brand-primary)}.NPLLIq_rowName{min-width:0;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;align-items:center;gap:6px;font-size:12px;font-weight:500;display:inline-flex;overflow:hidden}.NPLLIq_currentBadge{color:var(--dsw-alias-state-success-primary);border:1px solid var(--dsw-alias-state-success-primary);border-radius:8px;flex:none;padding:1px 6px;font-size:10px}.NPLLIq_rowMeta{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;font-size:11px}.NPLLIq_bar{background:var(--dsw-alias-bg-layer-1);border-radius:3px;height:6px;overflow:hidden}.NPLLIq_fillIdle{background:var(--dsw-alias-brand-primary);height:100%;transition:width .2s}.NPLLIq_fillWarn{background:var(--dsw-alias-state-warn-primary);height:100%;transition:width .2s}.NPLLIq_fillOver{background:var(--dsw-alias-state-error-primary);height:100%;transition:width .2s}.NPLLIq_controls{align-items:center;gap:6px;display:flex}.NPLLIq_input{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);min-width:0;color:var(--dsw-alias-label-primary);border-radius:6px;flex:1;padding:4px 8px;font-size:11px}.NPLLIq_input::placeholder{color:var(--dsw-alias-label-secondary)}.NPLLIq_save,.NPLLIq_switch{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;flex:none;padding:4px 10px;font-size:11px}.NPLLIq_save:hover,.NPLLIq_switch:hover:not(:disabled){background:var(--dsw-alias-bg-layer-2)}.NPLLIq_switch:disabled{opacity:.5;cursor:default}.NPLLIq_balanceToggle{margin-left:auto}.NPLLIq_balanceToggleOpen{color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_balanceWin{z-index:1199;background:var(--dsw-alias-bg-layer-2);width:280px;color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l1);pointer-events:auto;border-radius:12px;flex-direction:column;display:flex;position:fixed;overflow:hidden;box-shadow:0 8px 24px #00000029}.NPLLIq_balanceWinHeader{border-bottom:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-3);user-select:none;align-items:center;gap:6px;padding:6px 8px 6px 12px;display:flex}.NPLLIq_balanceWinTitle{flex:1;font-size:12px;font-weight:600;line-height:1}.NPLLIq_balanceWinBody{font-variant-numeric:tabular-nums;padding:6px 10px 10px;font-size:11px}.NPLLIq_balanceRowHeader{border-bottom:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);grid-template-columns:1fr auto 20px;align-items:center;gap:6px;padding:3px 2px;font-weight:600;display:grid}.NPLLIq_balanceSortBtn{all:unset;cursor:pointer;color:inherit;border-radius:4px;padding:1px 2px;font-size:10px;font-weight:600}.NPLLIq_balanceSortBtn:hover{color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_balanceRefreshAll{width:18px;height:18px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;justify-content:center;align-items:center;padding:0;font-size:12px;line-height:1;display:inline-flex}.NPLLIq_balanceRefreshAll:hover:not(:disabled){color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_balanceRefreshAll:disabled{opacity:.4;cursor:not-allowed}.NPLLIq_balanceRow{grid-template-columns:1fr auto 20px;align-items:center;gap:6px;padding:3px 2px;display:grid}.NPLLIq_balanceRow+.NPLLIq_balanceRow{border-top:1px dashed var(--dsw-alias-border-l1)}.NPLLIq_balanceRowName{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-weight:500;overflow:hidden}.NPLLIq_balanceRowValue{text-align:right;font-weight:600}.NPLLIq_balanceRowRefresh{width:18px;height:18px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;justify-content:center;align-items:center;padding:0;font-size:12px;line-height:1;display:inline-flex}.NPLLIq_balanceRowRefresh:hover:not(:disabled){color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_balanceRowRefresh:disabled{opacity:.4;cursor:not-allowed}.NPLLIq_balanceValueOk{color:var(--dsw-alias-label-primary)}.NPLLIq_balanceValueLow{color:var(--dsw-alias-state-warn-primary)}.NPLLIq_balanceValueError{color:var(--dsw-alias-state-error-primary)}.NPLLIq_balanceStateHint{color:var(--dsw-alias-label-secondary);font-style:italic;font-weight:500}.NPLLIq_balanceStateError{color:var(--dsw-alias-state-error-primary);font-weight:500}.NPLLIq_balanceLastLine{border-top:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-tertiary);margin-top:6px;padding-top:5px;font-size:10px}.NPLLIq_balanceBar{color:var(--dsw-alias-label-primary);border-bottom:1px solid var(--dsw-alias-border-l1);font-variant-numeric:tabular-nums;justify-content:space-between;align-items:center;gap:6px;padding:5px 12px;font-size:11px;display:flex}.NPLLIq_balanceBarText{text-overflow:ellipsis;white-space:nowrap;align-items:center;gap:6px;min-width:0;font-weight:600;display:inline-flex;overflow:hidden}.NPLLIq_balanceBarBadge{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-1);border-radius:4px;flex:none;padding:0 4px;font-size:10px;font-weight:600}.NPLLIq_balanceBarDim{color:var(--dsw-alias-label-secondary);font-weight:500}.NPLLIq_balanceBarLow{color:var(--dsw-alias-state-warn-primary)}.NPLLIq_balanceBarError{color:var(--dsw-alias-state-error-primary)}.NPLLIq_balanceBarRefresh{width:18px;height:18px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;flex:none;justify-content:center;align-items:center;padding:0;font-size:12px;line-height:1;display:inline-flex}.NPLLIq_balanceBarRefresh:hover:not(:disabled){color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_balanceBarRefresh:disabled{opacity:.4;cursor:not-allowed}.NPLLIq_notice,.NPLLIq_noticeError{color:var(--dsw-alias-label-secondary);padding:10px 12px;font-size:12px}.NPLLIq_noticeError{color:var(--dsw-alias-state-error-primary)}.NPLLIq_tab{background:var(--dsw-alias-brand-primary);border:1px solid var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-overlay);pointer-events:auto;cursor:pointer;z-index:90;border-radius:10px;align-items:center;gap:6px;padding:9px 14px;font-size:12px;font-weight:600;display:inline-flex;position:fixed;top:56px;right:12px;box-shadow:0 6px 20px #00000040}.NPLLIq_tab:hover{filter:brightness(1.08)}.NPLLIq_tabIcon{font-size:12px;line-height:1}.NPLLIq_tabLabel{white-space:nowrap}.NPLLIq_headerActions{flex:none;align-items:center;gap:4px;display:flex}.NPLLIq_settingsBtn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;padding:2px 6px;font-size:11px}.NPLLIq_settingsBtn:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_settingsBtnActive{color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-2,#0000000f);box-shadow:inset 0 0 0 1px var(--dsw-alias-brand-primary);font-weight:700}.NPLLIq_selectBtn{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-brand-primary);cursor:pointer;background:0 0;border-radius:6px;flex:none;padding:1px 6px;font-size:10px}.NPLLIq_selectBtn:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_gearBtn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;flex:none;margin-left:6px;padding:0 2px;font-size:12px;line-height:1}.NPLLIq_gearBtn:hover{color:var(--dsw-alias-label-primary)}.NPLLIq_fullNotice{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-state-error-primary);border-radius:8px;margin:6px 12px;padding:8px 10px;font-size:12px}.NPLLIq_upgradeBanner{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-divider-1,#0000001a);border-radius:8px;margin:6px 12px;padding:10px 30px 10px 10px;font-size:12px;position:relative}@keyframes NPLLIq_upgradeBannerFlash{0%,to{border-color:var(--dsw-alias-divider-1,#0000001a);box-shadow:0 0 #f0a02000}50%{border-color:var(--dsw-alias-status-warning-foreground,#b56900);box-shadow:0 0 0 5px #f0a02073}}.NPLLIq_upgradeBannerFlash{border-color:var(--dsw-alias-status-warning-foreground,#b56900);animation:.6s ease-in-out 4 NPLLIq_upgradeBannerFlash}.NPLLIq_upgradeBannerText{margin-bottom:6px;font-weight:600}.NPLLIq_upgradeCommands{flex-direction:column;gap:4px;display:flex}.NPLLIq_upgradeCommandRow{align-items:center;gap:6px;display:flex}.NPLLIq_upgradeCommand{background:var(--dsw-alias-bg-layer-2,#0000000a);white-space:nowrap;border-radius:4px;flex:1;min-width:0;padding:4px 6px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;overflow-x:auto}.NPLLIq_copyBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;flex:none;padding:3px 8px;font-size:11px;transition:transform 80ms,background .12s,color .12s}.NPLLIq_copyBtn:hover{background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_copyBtn:active{transform:scale(.92)}.NPLLIq_copyBtnDone{background:var(--dsw-alias-status-success-background,#14963c1f);border-color:var(--dsw-alias-status-success-foreground,#0a7d32);color:var(--dsw-alias-status-success-foreground,#0a7d32);font-weight:600}.NPLLIq_upgradeHint{color:var(--dsw-alias-label-secondary);margin-top:6px;font-size:11px}.NPLLIq_upgradeClose{width:20px;height:20px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;font-size:16px;line-height:1;position:absolute;top:4px;right:6px}.NPLLIq_upgradeClose:hover{background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary)}.NPLLIq_checkUpdatesRow{justify-content:space-between;align-items:center;gap:12px;display:flex}.NPLLIq_checkUpdatesLabel{color:var(--dsw-alias-label-primary);cursor:pointer;align-items:center;gap:6px;font-size:12px;display:flex}.NPLLIq_checkUpdatesLabel input{margin:0}.NPLLIq_checkUpdatesLabel input[type=range]{min-width:90px;accent-color:var(--dsw-alias-brand-primary);flex:1}.NPLLIq_checkUpdatesLabel select{background:var(--dsw-alias-bg-layer-2,#0000000a);min-width:90px;color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-divider-1,#00000026);border-radius:4px;flex:1;padding:2px 4px;font-size:12px}.NPLLIq_checkBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;white-space:nowrap;text-align:center;border-radius:4px;flex:none;min-width:72px;padding:4px 10px;font-size:12px}.NPLLIq_checkBtn:hover:not(:disabled){background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_checkBtn:disabled{opacity:.6;cursor:default}.NPLLIq_checkErrorHint{color:var(--dsw-alias-state-error-primary,#c00);background:var(--dsw-alias-state-error-background,#ff00000f);border:1px solid var(--dsw-alias-state-error-border,#b4000040);word-break:break-all;border-radius:6px;margin-top:8px;padding:6px 8px;font-size:11px;line-height:1.4}.NPLLIq_dialog{z-index:100;pointer-events:auto;box-sizing:border-box;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);border-radius:12px;flex-direction:column;gap:12px;width:430px;max-width:94vw;max-height:80vh;padding:14px;display:flex;position:fixed;top:50%;left:50%;overflow-y:auto;transform:translate(-50%,-50%);box-shadow:0 8px 28px #00000040}.NPLLIq_dialogTabs{border-bottom:1px solid var(--dsw-alias-divider-1,#00000014);gap:2px;margin:-6px -14px 0;padding:0 14px;display:flex}.NPLLIq_dialogTab{appearance:none;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-bottom:2px solid #0000;padding:6px 12px 8px;font-size:12px}.NPLLIq_dialogTab:hover{color:var(--dsw-alias-label-primary)}.NPLLIq_dialogTabActive{color:var(--dsw-alias-brand-primary);border-bottom-color:var(--dsw-alias-brand-primary);font-weight:600}.NPLLIq_settingsDialog{height:min(560px,80vh)}.NPLLIq_dialogTitle{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.NPLLIq_dialogSection{flex-direction:column;gap:6px;display:flex}.NPLLIq_dialogLabel{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:500}.NPLLIq_monitorHint{color:var(--dsw-alias-label-secondary);font-size:11px}.NPLLIq_dialogHint{color:var(--dsw-alias-label-secondary);margin-top:4px;font-size:11px;line-height:1.4}.NPLLIq_monitorList{flex-direction:column;gap:2px;max-height:180px;display:flex;overflow-y:auto}.NPLLIq_monitorRow{color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:6px;padding:2px 4px;font-size:12px;display:flex}.NPLLIq_monitorRow:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_monitorName{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.NPLLIq_radioRow{color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:6px;padding:3px 4px;font-size:12px;display:flex}.NPLLIq_radioRow:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_dialogActions{justify-content:flex-end;gap:6px;display:flex}.NPLLIq_dialogBtn,.NPLLIq_dialogBtnPrimary{border:1px solid var(--dsw-alias-border-l1);cursor:pointer;border-radius:6px;padding:4px 12px;font-size:11px}.NPLLIq_dialogBtn{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)}.NPLLIq_dialogBtnPrimary{background:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-overlay)}.NPLLIq_dialogHeader{z-index:2;background:var(--dsw-alias-bg-overlay);cursor:grab;user-select:none;touch-action:none;justify-content:space-between;align-items:center;gap:8px;margin:-14px -14px 0;padding:14px 14px 8px;display:flex;position:sticky;top:-14px}.NPLLIq_dialogHeader:active{cursor:grabbing}.NPLLIq_dialogClose{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:8px;flex:none;justify-content:center;align-items:center;font-size:18px;line-height:1;display:flex}.NPLLIq_dialogClose:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_resetRow{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.NPLLIq_resetSelect{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:6px;padding:3px 6px;font-size:12px}.NPLLIq_logTable{border-collapse:collapse;width:100%;font-size:11px}.NPLLIq_logTable th{text-align:left;color:var(--dsw-alias-label-secondary);border-bottom:1px solid var(--dsw-alias-border-l1);padding:4px 6px;font-weight:500}.NPLLIq_logTable td{color:var(--dsw-alias-label-primary);border-bottom:1px solid var(--dsw-alias-border-l1);font-variant-numeric:tabular-nums;padding:4px 6px}.NPLLIq_logDayCol{white-space:nowrap;color:var(--dsw-alias-label-secondary)}.NPLLIq_logModelCol{text-overflow:ellipsis;white-space:nowrap;max-width:160px;overflow:hidden}.NPLLIq_logUsedCol{text-align:right}.NPLLIq_logDialog{gap:0;width:380px;max-height:min(72vh,480px);padding:0}.NPLLIq_logHeader{background:var(--dsw-alias-bg-overlay);cursor:grab;user-select:none;touch-action:none;flex:none;justify-content:space-between;align-items:center;gap:8px;padding:14px 14px 8px;display:flex}.NPLLIq_logHeader:active{cursor:grabbing}.NPLLIq_logScroll{flex:1;min-height:0;padding:0 14px 14px;overflow:auto}.NPLLIq_logToolbar{flex:1;align-items:center;gap:6px;display:flex}.NPLLIq_logSearch{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);min-width:0;color:var(--dsw-alias-label-primary);border-radius:4px;flex:1;padding:3px 6px;font-size:11px}.NPLLIq_logSearch:focus{border-color:var(--dsw-alias-accent-1,#4a9eff);outline:none}.NPLLIq_logClearBtn{border:1px solid var(--dsw-alias-state-error-border,#b400004d);color:var(--dsw-alias-state-error-primary,#c00);cursor:pointer;white-space:nowrap;background:0 0;border-radius:4px;flex:none;padding:3px 8px;font-size:11px}.NPLLIq_logClearBtn:hover{background:var(--dsw-alias-state-error-background,#ff00000f)}.NPLLIq_logPager{border-top:1px solid var(--dsw-alias-divider-1,#00000014);background:var(--dsw-alias-bg-overlay);color:var(--dsw-alias-label-secondary);flex:none;justify-content:space-between;align-items:center;gap:8px;padding:6px 14px;font-size:11px;display:flex}.NPLLIq_logPagerInfo{white-space:nowrap}.NPLLIq_logPagerControls{align-items:center;gap:4px;display:flex}.NPLLIq_logPagerBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);width:24px;height:24px;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;font-size:13px;line-height:1}.NPLLIq_logPagerBtn:disabled{opacity:.4;cursor:default}.NPLLIq_logPagerPages{text-align:center;min-width:50px;color:var(--dsw-alias-label-secondary)}.NPLLIq_logPageSizeSelect{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;padding:2px 4px;font-size:11px}.NPLLIq_dialogOverlay{z-index:100001;pointer-events:auto;background:#0000004d;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.NPLLIq_logClearDialog{gap:0;width:320px;padding:16px}.NPLLIq_dialogBody{color:var(--dsw-alias-label-secondary);margin:6px 0 10px;font-size:12px;line-height:1.5}.NPLLIq_logClearDate{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);width:100%;color:var(--dsw-alias-label-primary);border-radius:6px;margin-bottom:12px;padding:6px 8px;font-size:13px}.NPLLIq_logClearDate:focus{border-color:var(--dsw-alias-accent-1,#4a9eff);outline:none}";
|
|
255
|
+
const css$1 = ".NPLLIq_panel{box-sizing:border-box;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);pointer-events:auto;z-index:40;opacity:1;border-radius:12px;flex-direction:column;width:320px;max-height:min(72vh,560px);transition:opacity .18s;display:flex;position:fixed;top:56px;right:12px;overflow:hidden;box-shadow:0 8px 28px #0000002e}.NPLLIq_panelDim{opacity:.55}.NPLLIq_panelDimStrong{opacity:.3}.NPLLIq_header{border-bottom:1px solid var(--dsw-alias-border-l1);cursor:grab;user-select:none;touch-action:none;flex-wrap:wrap;justify-content:space-between;align-items:flex-start;gap:8px;padding:10px 12px;display:flex}.NPLLIq_header:active{cursor:grabbing}.NPLLIq_headerText{flex-direction:column;gap:2px;min-width:0;display:flex}.NPLLIq_title{color:var(--dsw-alias-label-primary);align-items:baseline;gap:6px;font-size:13px;font-weight:600;display:flex}.NPLLIq_version{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:10px;font-weight:500}.NPLLIq_versionNew{color:var(--dsw-alias-status-warning-foreground,#b56900);background:var(--dsw-alias-status-warning-background,#fff6d7);cursor:default;border-radius:4px;padding:1px 6px}.NPLLIq_subtitle{color:var(--dsw-alias-label-secondary);font-size:11px}.NPLLIq_notesBar{flex-wrap:wrap;flex:100%;align-items:center;gap:4px;padding:2px 0 0;display:flex}.NPLLIq_noteChip{width:20px;height:20px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);cursor:pointer;border-radius:5px;flex:none;justify-content:center;align-items:center;padding:0;font-size:11px;line-height:1;transition:color .12s,border-color .12s;display:inline-flex}.NPLLIq_noteChip:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l2)}.NPLLIq_noteChipOpen{color:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}.NPLLIq_noteNew{width:22px;height:20px;color:var(--dsw-alias-label-secondary);border:1px dashed var(--dsw-alias-border-l2);cursor:pointer;background:0 0;border-radius:5px;flex:none;justify-content:center;align-items:center;padding:0;transition:color .12s,border-color .12s;display:inline-flex;position:relative}.NPLLIq_noteNew:hover:not(:disabled){color:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}.NPLLIq_noteNew:disabled{opacity:.4;cursor:not-allowed}.NPLLIq_noteNewPlus{color:inherit;font-size:10px;font-weight:700;line-height:1;position:absolute;bottom:-2px;right:-1px}.NPLLIq_noteWin{z-index:60;pointer-events:auto;box-sizing:border-box;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;flex-direction:column;display:flex;position:fixed;overflow:hidden;box-shadow:0 8px 24px #00000038}.NPLLIq_noteWinCollapsed{height:auto!important}.NPLLIq_noteWinBar{background:var(--dsw-alias-bg-layer-1);border-bottom:1px solid var(--dsw-alias-border-l1);cursor:grab;user-select:none;flex:none;align-items:center;gap:4px;padding:4px 6px;display:flex}.NPLLIq_noteWinBar:active{cursor:grabbing}.NPLLIq_noteWinGripBar{color:var(--dsw-alias-label-secondary);opacity:.7;flex:none;font-size:10px}.NPLLIq_noteWinTitleText{min-width:0;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;padding:1px 2px;font-size:11px;font-weight:600;overflow:hidden}.NPLLIq_noteWinTitle{min-width:0;color:var(--dsw-alias-label-primary);background:0 0;border:1px solid #0000;border-radius:4px;outline:none;flex:1;padding:1px 2px;font-size:11px;font-weight:600}.NPLLIq_noteWinTitle:hover{border-color:var(--dsw-alias-border-l1)}.NPLLIq_noteWinTitle:focus{background:var(--dsw-alias-bg-overlay);border-color:var(--dsw-alias-brand-primary)}.NPLLIq_noteWinBtn{width:18px;height:18px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;flex:none;justify-content:center;align-items:center;padding:0;font-size:12px;line-height:1;display:inline-flex}.NPLLIq_noteWinBtn:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.NPLLIq_noteWinText{box-sizing:border-box;width:100%;min-height:0;color:var(--dsw-alias-label-primary);resize:none;background:0 0;border:none;outline:none;flex:1;padding:6px 8px;font-family:inherit;font-size:11px;line-height:1.5}.NPLLIq_noteWinResize{cursor:nwse-resize;background:linear-gradient(135deg, transparent 0 45%, var(--dsw-alias-border-l2) 45% 55%, transparent 55% 70%, var(--dsw-alias-border-l2) 70% 80%, transparent 80%);width:14px;height:14px;position:absolute;bottom:0;right:0}.NPLLIq_noteMenuBackdrop{z-index:100;pointer-events:auto;position:fixed;inset:0}.NPLLIq_noteMenu{z-index:101;pointer-events:auto;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;flex-direction:column;min-width:96px;padding:4px;display:flex;position:fixed;box-shadow:0 8px 24px #0000003d}.NPLLIq_noteMenuItem{text-align:left;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:none;border-radius:5px;padding:5px 8px;font-size:11px}.NPLLIq_noteMenuItem:hover{background:var(--dsw-alias-bg-layer-2)}.NPLLIq_collapse{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;padding:2px 6px;font-size:11px}.NPLLIq_collapse:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_body{padding:4px 0;overflow-y:auto}.NPLLIq_row{border-bottom:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:6px;padding:8px 12px;display:flex}.NPLLIq_rowHeader{justify-content:space-between;align-items:center;gap:8px;display:flex}.NPLLIq_rowDrag{cursor:grab;color:var(--dsw-alias-label-secondary);user-select:none;border-radius:4px;flex:none;margin-right:2px;padding:2px 3px;font-size:11px;line-height:1}.NPLLIq_rowDrag:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_rowDrag:active{cursor:grabbing}.NPLLIq_rowDragging{opacity:.45}.NPLLIq_rowDropTarget{box-shadow:inset 0 2px 0 var(--dsw-alias-brand-primary)}.NPLLIq_rowName{min-width:0;color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;align-items:center;gap:6px;font-size:12px;font-weight:500;display:inline-flex;overflow:hidden}.NPLLIq_currentBadge{color:var(--dsw-alias-state-success-primary);border:1px solid var(--dsw-alias-state-success-primary);border-radius:8px;flex:none;padding:1px 6px;font-size:10px}.NPLLIq_rowMeta{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;font-size:11px}.NPLLIq_bar{background:var(--dsw-alias-bg-layer-1);border-radius:3px;height:6px;overflow:hidden}.NPLLIq_fillIdle{background:var(--dsw-alias-brand-primary);height:100%;transition:width .2s}.NPLLIq_fillWarn{background:var(--dsw-alias-state-warn-primary);height:100%;transition:width .2s}.NPLLIq_fillOver{background:var(--dsw-alias-state-error-primary);height:100%;transition:width .2s}.NPLLIq_controls{align-items:center;gap:6px;display:flex}.NPLLIq_input{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);min-width:0;color:var(--dsw-alias-label-primary);border-radius:6px;flex:1;padding:4px 8px;font-size:11px}.NPLLIq_input::placeholder{color:var(--dsw-alias-label-secondary)}.NPLLIq_save,.NPLLIq_switch{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;flex:none;padding:4px 10px;font-size:11px}.NPLLIq_save:hover,.NPLLIq_switch:hover:not(:disabled){background:var(--dsw-alias-bg-layer-2)}.NPLLIq_switch:disabled{opacity:.5;cursor:default}.NPLLIq_balanceToggle{margin-left:auto}.NPLLIq_balanceToggleOpen{color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_balanceWin{z-index:1199;background:var(--dsw-alias-bg-layer-2);width:280px;color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l1);pointer-events:auto;border-radius:12px;flex-direction:column;display:flex;position:fixed;overflow:hidden;box-shadow:0 8px 24px #00000029}.NPLLIq_balanceWinHeader{border-bottom:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-3);user-select:none;align-items:center;gap:6px;padding:6px 8px 6px 12px;display:flex}.NPLLIq_balanceWinTitle{flex:1;font-size:12px;font-weight:600;line-height:1}.NPLLIq_balanceWinBody{font-variant-numeric:tabular-nums;padding:6px 10px 10px;font-size:11px}.NPLLIq_balanceRowHeader{border-bottom:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);grid-template-columns:1fr auto 20px;align-items:center;gap:6px;padding:3px 2px;font-weight:600;display:grid}.NPLLIq_balanceSortBtn{all:unset;cursor:pointer;color:inherit;border-radius:4px;padding:1px 2px;font-size:10px;font-weight:600}.NPLLIq_balanceSortBtn:hover{color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_balanceRefreshAll{width:18px;height:18px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;justify-content:center;align-items:center;padding:0;font-size:12px;line-height:1;display:inline-flex}.NPLLIq_balanceRefreshAll:hover:not(:disabled){color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_balanceRefreshAll:disabled{opacity:.4;cursor:not-allowed}.NPLLIq_balanceRow{grid-template-columns:1fr auto 20px;align-items:center;gap:6px;padding:3px 2px;display:grid}.NPLLIq_balanceRow+.NPLLIq_balanceRow{border-top:1px dashed var(--dsw-alias-border-l1)}.NPLLIq_balanceRowName{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-weight:500;overflow:hidden}.NPLLIq_balanceRowValue{text-align:right;font-weight:600}.NPLLIq_balanceRowRefresh{width:18px;height:18px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;justify-content:center;align-items:center;padding:0;font-size:12px;line-height:1;display:inline-flex}.NPLLIq_balanceRowRefresh:hover:not(:disabled){color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_balanceRowRefresh:disabled{opacity:.4;cursor:not-allowed}.NPLLIq_balanceValueOk{color:var(--dsw-alias-label-primary)}.NPLLIq_balanceValueLow{color:var(--dsw-alias-state-warn-primary)}.NPLLIq_balanceValueError{color:var(--dsw-alias-state-error-primary)}.NPLLIq_balanceStateHint{color:var(--dsw-alias-label-secondary);font-style:italic;font-weight:500}.NPLLIq_balanceStateError{color:var(--dsw-alias-state-error-primary);font-weight:500}.NPLLIq_balanceLastLine{border-top:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-tertiary);margin-top:6px;padding-top:5px;font-size:10px}.NPLLIq_balanceBar{color:var(--dsw-alias-label-primary);border-bottom:1px solid var(--dsw-alias-border-l1);font-variant-numeric:tabular-nums;justify-content:space-between;align-items:center;gap:6px;padding:5px 12px;font-size:11px;display:flex}.NPLLIq_balanceBarText{text-overflow:ellipsis;white-space:nowrap;align-items:center;gap:6px;min-width:0;font-weight:600;display:inline-flex;overflow:hidden}.NPLLIq_balanceBarBadge{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-1);border-radius:4px;flex:none;padding:0 4px;font-size:10px;font-weight:600}.NPLLIq_balanceBarDim{color:var(--dsw-alias-label-secondary);font-weight:500}.NPLLIq_balanceBarLow{color:var(--dsw-alias-state-warn-primary)}.NPLLIq_balanceBarError{color:var(--dsw-alias-state-error-primary)}.NPLLIq_balanceBarRefresh{width:18px;height:18px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;flex:none;justify-content:center;align-items:center;padding:0;font-size:12px;line-height:1;display:inline-flex}.NPLLIq_balanceBarRefresh:hover:not(:disabled){color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_balanceBarRefresh:disabled{opacity:.4;cursor:not-allowed}.NPLLIq_notice,.NPLLIq_noticeError{color:var(--dsw-alias-label-secondary);padding:10px 12px;font-size:12px}.NPLLIq_noticeError{color:var(--dsw-alias-state-error-primary)}.NPLLIq_tab{background:var(--dsw-alias-brand-primary);border:1px solid var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-overlay);pointer-events:auto;cursor:pointer;z-index:90;border-radius:10px;align-items:center;gap:6px;padding:9px 14px;font-size:12px;font-weight:600;display:inline-flex;position:fixed;top:56px;right:12px;box-shadow:0 6px 20px #00000040}.NPLLIq_tab:hover{filter:brightness(1.08)}.NPLLIq_tabIcon{font-size:12px;line-height:1}.NPLLIq_tabLabel{white-space:nowrap}.NPLLIq_headerActions{flex:none;align-items:center;gap:4px;display:flex}.NPLLIq_settingsBtn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;padding:2px 6px;font-size:11px}.NPLLIq_settingsBtn:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_settingsBtnActive{color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-bg-layer-2,#0000000f);box-shadow:inset 0 0 0 1px var(--dsw-alias-brand-primary);font-weight:700}.NPLLIq_selectBtn{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-brand-primary);cursor:pointer;background:0 0;border-radius:6px;flex:none;padding:1px 6px;font-size:10px}.NPLLIq_selectBtn:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_gearBtn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;flex:none;margin-left:6px;padding:0 2px;font-size:12px;line-height:1}.NPLLIq_gearBtn:hover{color:var(--dsw-alias-label-primary)}.NPLLIq_fullNotice{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-state-error-primary);border-radius:8px;margin:6px 12px;padding:8px 10px;font-size:12px}.NPLLIq_upgradeBanner{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-divider-1,#0000001a);border-radius:8px;margin:6px 12px;padding:10px 30px 10px 10px;font-size:12px;position:relative}@keyframes NPLLIq_upgradeBannerFlash{0%,to{border-color:var(--dsw-alias-divider-1,#0000001a);box-shadow:0 0 #f0a02000}50%{border-color:var(--dsw-alias-status-warning-foreground,#b56900);box-shadow:0 0 0 5px #f0a02073}}.NPLLIq_upgradeBannerFlash{border-color:var(--dsw-alias-status-warning-foreground,#b56900);animation:.6s ease-in-out 4 NPLLIq_upgradeBannerFlash}.NPLLIq_upgradeBannerText{margin-bottom:6px;font-weight:600}.NPLLIq_upgradeCommands{flex-direction:column;gap:4px;display:flex}.NPLLIq_upgradeCommandRow{align-items:center;gap:6px;display:flex}.NPLLIq_upgradeCommand{background:var(--dsw-alias-bg-layer-2,#0000000a);white-space:nowrap;border-radius:4px;flex:1;min-width:0;padding:4px 6px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;overflow-x:auto}.NPLLIq_copyBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;flex:none;padding:3px 8px;font-size:11px;transition:transform 80ms,background .12s,color .12s}.NPLLIq_copyBtn:hover{background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_copyBtn:active{transform:scale(.92)}.NPLLIq_copyBtnDone{background:var(--dsw-alias-status-success-background,#14963c1f);border-color:var(--dsw-alias-status-success-foreground,#0a7d32);color:var(--dsw-alias-status-success-foreground,#0a7d32);font-weight:600}.NPLLIq_upgradeHint{color:var(--dsw-alias-label-secondary);margin-top:6px;font-size:11px}.NPLLIq_upgradeClose{width:20px;height:20px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;font-size:16px;line-height:1;position:absolute;top:4px;right:6px}.NPLLIq_upgradeClose:hover{background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary)}.NPLLIq_checkUpdatesRow{justify-content:space-between;align-items:center;gap:12px;display:flex}.NPLLIq_checkUpdatesLabel{color:var(--dsw-alias-label-primary);cursor:pointer;align-items:center;gap:6px;font-size:12px;display:flex}.NPLLIq_checkUpdatesLabel input{margin:0}.NPLLIq_checkUpdatesLabel input[type=range]{min-width:90px;accent-color:var(--dsw-alias-brand-primary);flex:1}.NPLLIq_checkUpdatesLabel select{background:var(--dsw-alias-bg-layer-2,#0000000a);min-width:90px;color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-divider-1,#00000026);border-radius:4px;flex:1;padding:2px 4px;font-size:12px}.NPLLIq_checkBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;white-space:nowrap;text-align:center;border-radius:4px;flex:none;min-width:72px;padding:4px 10px;font-size:12px}.NPLLIq_checkBtn:hover:not(:disabled){background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_checkBtn:disabled{opacity:.6;cursor:default}.NPLLIq_checkErrorHint{color:var(--dsw-alias-state-error-primary,#c00);background:var(--dsw-alias-state-error-background,#ff00000f);border:1px solid var(--dsw-alias-state-error-border,#b4000040);word-break:break-all;border-radius:6px;margin-top:8px;padding:6px 8px;font-size:11px;line-height:1.4}.NPLLIq_dialog{z-index:100;pointer-events:auto;box-sizing:border-box;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);border-radius:12px;flex-direction:column;gap:12px;width:430px;max-width:94vw;max-height:80vh;padding:14px;display:flex;position:fixed;top:50%;left:50%;overflow-y:auto;transform:translate(-50%,-50%);box-shadow:0 8px 28px #00000040}.NPLLIq_dialogTabs{border-bottom:1px solid var(--dsw-alias-divider-1,#00000014);gap:2px;margin:-6px -14px 0;padding:0 14px;display:flex}.NPLLIq_dialogTab{appearance:none;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-bottom:2px solid #0000;padding:6px 12px 8px;font-size:12px}.NPLLIq_dialogTab:hover{color:var(--dsw-alias-label-primary)}.NPLLIq_dialogTabActive{color:var(--dsw-alias-brand-primary);border-bottom-color:var(--dsw-alias-brand-primary);font-weight:600}.NPLLIq_settingsDialog{height:min(560px,80vh)}.NPLLIq_dialogTitle{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.NPLLIq_dialogSection{flex-direction:column;gap:6px;display:flex}.NPLLIq_dialogLabel{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:500}.NPLLIq_monitorHint{color:var(--dsw-alias-label-secondary);font-size:11px}.NPLLIq_dialogHint{color:var(--dsw-alias-label-secondary);margin-top:4px;font-size:11px;line-height:1.4}.NPLLIq_monitorList{flex-direction:column;gap:2px;max-height:180px;display:flex;overflow-y:auto}.NPLLIq_monitorRow{color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:6px;padding:2px 4px;font-size:12px;display:flex}.NPLLIq_monitorRow:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_monitorName{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.NPLLIq_radioRow{color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:6px;padding:3px 4px;font-size:12px;display:flex}.NPLLIq_radioRow:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_dialogActions{justify-content:flex-end;gap:6px;display:flex}.NPLLIq_dialogBtn,.NPLLIq_dialogBtnPrimary{border:1px solid var(--dsw-alias-border-l1);cursor:pointer;border-radius:6px;padding:4px 12px;font-size:11px}.NPLLIq_dialogBtn{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)}.NPLLIq_dialogBtnPrimary{background:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-overlay)}.NPLLIq_dialogHeader{z-index:2;background:var(--dsw-alias-bg-overlay);cursor:grab;user-select:none;touch-action:none;justify-content:space-between;align-items:center;gap:8px;margin:-14px -14px 0;padding:14px 14px 8px;display:flex;position:sticky;top:-14px}.NPLLIq_dialogHeader:active{cursor:grabbing}.NPLLIq_dialogClose{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:8px;flex:none;justify-content:center;align-items:center;font-size:18px;line-height:1;display:flex}.NPLLIq_dialogClose:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_resetRow{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.NPLLIq_resetSelect{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:6px;padding:3px 6px;font-size:12px}.NPLLIq_logTable{border-collapse:collapse;width:100%;font-size:11px}.NPLLIq_logTable th{text-align:left;color:var(--dsw-alias-label-secondary);border-bottom:1px solid var(--dsw-alias-border-l1);padding:4px 6px;font-weight:500}.NPLLIq_logTable td{color:var(--dsw-alias-label-primary);border-bottom:1px solid var(--dsw-alias-border-l1);font-variant-numeric:tabular-nums;padding:4px 6px}.NPLLIq_logDayCol{white-space:nowrap;color:var(--dsw-alias-label-secondary)}.NPLLIq_logModelCol{text-overflow:ellipsis;white-space:nowrap;max-width:160px;overflow:hidden}.NPLLIq_logUsedCol{text-align:right}.NPLLIq_logDialog{gap:0;width:380px;max-height:min(72vh,480px);padding:0}.NPLLIq_logHeader{background:var(--dsw-alias-bg-overlay);cursor:grab;user-select:none;touch-action:none;flex:none;justify-content:space-between;align-items:center;gap:8px;padding:14px 14px 8px;display:flex}.NPLLIq_logHeader:active{cursor:grabbing}.NPLLIq_logScroll{flex:1;min-height:0;padding:0 14px 14px;overflow:auto}.NPLLIq_logToolbar{flex:1;align-items:center;gap:6px;display:flex}.NPLLIq_logSearch{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);min-width:0;color:var(--dsw-alias-label-primary);border-radius:4px;flex:1;padding:3px 6px;font-size:11px}.NPLLIq_logSearch:focus{border-color:var(--dsw-alias-accent-1,#4a9eff);outline:none}.NPLLIq_logClearBtn{border:1px solid var(--dsw-alias-state-error-border,#b400004d);color:var(--dsw-alias-state-error-primary,#c00);cursor:pointer;white-space:nowrap;background:0 0;border-radius:4px;flex:none;padding:3px 8px;font-size:11px}.NPLLIq_logClearBtn:hover{background:var(--dsw-alias-state-error-background,#ff00000f)}.NPLLIq_logPager{border-top:1px solid var(--dsw-alias-divider-1,#00000014);background:var(--dsw-alias-bg-overlay);color:var(--dsw-alias-label-secondary);flex:none;justify-content:space-between;align-items:center;gap:8px;padding:6px 14px;font-size:11px;display:flex}.NPLLIq_logPagerInfo{white-space:nowrap}.NPLLIq_logPagerControls{align-items:center;gap:4px;display:flex}.NPLLIq_logPagerBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);width:24px;height:24px;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;font-size:13px;line-height:1}.NPLLIq_logPagerBtn:disabled{opacity:.4;cursor:default}.NPLLIq_logPagerPages{text-align:center;min-width:50px;color:var(--dsw-alias-label-secondary)}.NPLLIq_logPageSizeSelect{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;padding:2px 4px;font-size:11px}.NPLLIq_dialogOverlay{z-index:100001;pointer-events:auto;background:#0000004d;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.NPLLIq_logClearDialog{gap:0;width:320px;padding:16px}.NPLLIq_dialogBody{color:var(--dsw-alias-label-secondary);margin:6px 0 10px;font-size:12px;line-height:1.5}.NPLLIq_logClearDate{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);width:100%;color:var(--dsw-alias-label-primary);border-radius:6px;margin-bottom:12px;padding:6px 8px;font-size:13px}.NPLLIq_logClearDate:focus{border-color:var(--dsw-alias-accent-1,#4a9eff);outline:none}.NPLLIq_keyRow{align-items:center;gap:8px;margin-top:6px;display:flex}.NPLLIq_keySaveBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;white-space:nowrap;border-radius:4px;flex:none;padding:4px 10px;font-size:12px}.NPLLIq_keySaveBtn:hover:not(:disabled){background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_keySaveBtn:disabled{opacity:.5;cursor:not-allowed}.NPLLIq_keyBadgeOk,.NPLLIq_keyBadgeOff{white-space:nowrap;border-radius:999px;padding:3px 7px;font-size:11px;line-height:1}.NPLLIq_keyBadgeOk{color:var(--dsw-alias-state-success-primary,#2f9e44);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#2f9e44) 14%, transparent)}.NPLLIq_keyBadgeOff{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2,#0000000f)}.NPLLIq_keyError{word-break:break-word;color:var(--dsw-alias-state-error-primary,#e03131);margin-top:4px;font-size:11px;line-height:1.4}";
|
|
256
256
|
const tagId$1 = "@jxgame2020/dsh-token-quota/TokenQuotaPanel.module.css";
|
|
257
257
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
258
258
|
const tag = document.createElement("style");
|
|
@@ -262,142 +262,147 @@ window.__ModuleLoader__.load({
|
|
|
262
262
|
document.head.appendChild(tag);
|
|
263
263
|
}
|
|
264
264
|
var TokenQuotaPanel_module_css_default = {
|
|
265
|
-
"
|
|
266
|
-
"
|
|
267
|
-
"
|
|
268
|
-
"noteWin": "NPLLIq_noteWin",
|
|
265
|
+
"tabIcon": "NPLLIq_tabIcon",
|
|
266
|
+
"copyBtn": "NPLLIq_copyBtn",
|
|
267
|
+
"balanceBarDim": "NPLLIq_balanceBarDim",
|
|
269
268
|
"selectBtn": "NPLLIq_selectBtn",
|
|
270
|
-
"
|
|
271
|
-
"
|
|
272
|
-
"
|
|
273
|
-
"
|
|
274
|
-
"
|
|
275
|
-
"
|
|
276
|
-
"
|
|
277
|
-
"upgradeBannerText": "NPLLIq_upgradeBannerText",
|
|
278
|
-
"checkUpdatesLabel": "NPLLIq_checkUpdatesLabel",
|
|
279
|
-
"logTable": "NPLLIq_logTable",
|
|
280
|
-
"logClearDate": "NPLLIq_logClearDate",
|
|
269
|
+
"radioRow": "NPLLIq_radioRow",
|
|
270
|
+
"tab": "NPLLIq_tab",
|
|
271
|
+
"rowHeader": "NPLLIq_rowHeader",
|
|
272
|
+
"logModelCol": "NPLLIq_logModelCol",
|
|
273
|
+
"balanceRowName": "NPLLIq_balanceRowName",
|
|
274
|
+
"dialogSection": "NPLLIq_dialogSection",
|
|
275
|
+
"dialogOverlay": "NPLLIq_dialogOverlay",
|
|
281
276
|
"headerText": "NPLLIq_headerText",
|
|
282
|
-
"currentBadge": "NPLLIq_currentBadge",
|
|
283
277
|
"balanceStateHint": "NPLLIq_balanceStateHint",
|
|
284
|
-
"
|
|
285
|
-
"
|
|
286
|
-
"
|
|
287
|
-
"
|
|
288
|
-
"
|
|
278
|
+
"noteMenuBackdrop": "NPLLIq_noteMenuBackdrop",
|
|
279
|
+
"balanceWinHeader": "NPLLIq_balanceWinHeader",
|
|
280
|
+
"balanceRowHeader": "NPLLIq_balanceRowHeader",
|
|
281
|
+
"noteWinResize": "NPLLIq_noteWinResize",
|
|
282
|
+
"notice": "NPLLIq_notice",
|
|
283
|
+
"panel": "NPLLIq_panel",
|
|
284
|
+
"logPagerPages": "NPLLIq_logPagerPages",
|
|
285
|
+
"keyBadgeOff": "NPLLIq_keyBadgeOff",
|
|
286
|
+
"noteWinGripBar": "NPLLIq_noteWinGripBar",
|
|
287
|
+
"checkErrorHint": "NPLLIq_checkErrorHint",
|
|
288
|
+
"logTable": "NPLLIq_logTable",
|
|
289
|
+
"dialogLabel": "NPLLIq_dialogLabel",
|
|
290
|
+
"noteChipOpen": "NPLLIq_noteChipOpen",
|
|
291
|
+
"balanceLastLine": "NPLLIq_balanceLastLine",
|
|
292
|
+
"monitorList": "NPLLIq_monitorList",
|
|
293
|
+
"logSearch": "NPLLIq_logSearch",
|
|
294
|
+
"bar": "NPLLIq_bar",
|
|
295
|
+
"balanceRefreshAll": "NPLLIq_balanceRefreshAll",
|
|
296
|
+
"save": "NPLLIq_save",
|
|
297
|
+
"balanceBar": "NPLLIq_balanceBar",
|
|
289
298
|
"balanceSortBtn": "NPLLIq_balanceSortBtn",
|
|
290
|
-
"
|
|
291
|
-
"
|
|
292
|
-
"
|
|
299
|
+
"balanceWinTitle": "NPLLIq_balanceWinTitle",
|
|
300
|
+
"logClearBtn": "NPLLIq_logClearBtn",
|
|
301
|
+
"noteWinBar": "NPLLIq_noteWinBar",
|
|
302
|
+
"logClearDialog": "NPLLIq_logClearDialog",
|
|
303
|
+
"noteMenu": "NPLLIq_noteMenu",
|
|
293
304
|
"upgradeCommandRow": "NPLLIq_upgradeCommandRow",
|
|
305
|
+
"monitorHint": "NPLLIq_monitorHint",
|
|
306
|
+
"resetSelect": "NPLLIq_resetSelect",
|
|
307
|
+
"subtitle": "NPLLIq_subtitle",
|
|
308
|
+
"rowDropTarget": "NPLLIq_rowDropTarget",
|
|
309
|
+
"settingsBtnActive": "NPLLIq_settingsBtnActive",
|
|
310
|
+
"notesBar": "NPLLIq_notesBar",
|
|
311
|
+
"upgradeCommands": "NPLLIq_upgradeCommands",
|
|
312
|
+
"logDayCol": "NPLLIq_logDayCol",
|
|
313
|
+
"balanceStateError": "NPLLIq_balanceStateError",
|
|
314
|
+
"upgradeHint": "NPLLIq_upgradeHint",
|
|
315
|
+
"controls": "NPLLIq_controls",
|
|
316
|
+
"input": "NPLLIq_input",
|
|
294
317
|
"noteChip": "NPLLIq_noteChip",
|
|
295
|
-
"balanceRowRefresh": "NPLLIq_balanceRowRefresh",
|
|
296
|
-
"noticeError": "NPLLIq_noticeError",
|
|
297
|
-
"copyBtnDone": "NPLLIq_copyBtnDone",
|
|
298
|
-
"logDialog": "NPLLIq_logDialog",
|
|
299
318
|
"logPagerBtn": "NPLLIq_logPagerBtn",
|
|
300
|
-
"
|
|
301
|
-
"
|
|
302
|
-
"
|
|
303
|
-
"rowName": "NPLLIq_rowName",
|
|
304
|
-
"upgradeCommand": "NPLLIq_upgradeCommand",
|
|
305
|
-
"noteMenuItem": "NPLLIq_noteMenuItem",
|
|
306
|
-
"collapse": "NPLLIq_collapse",
|
|
307
|
-
"fillWarn": "NPLLIq_fillWarn",
|
|
308
|
-
"headerActions": "NPLLIq_headerActions",
|
|
309
|
-
"balanceBar": "NPLLIq_balanceBar",
|
|
319
|
+
"logDialog": "NPLLIq_logDialog",
|
|
320
|
+
"dialogHeader": "NPLLIq_dialogHeader",
|
|
321
|
+
"monitorName": "NPLLIq_monitorName",
|
|
310
322
|
"noteWinCollapsed": "NPLLIq_noteWinCollapsed",
|
|
311
|
-
"
|
|
312
|
-
"
|
|
313
|
-
"
|
|
314
|
-
"
|
|
315
|
-
"
|
|
316
|
-
"
|
|
317
|
-
"
|
|
318
|
-
"
|
|
319
|
-
"
|
|
320
|
-
"
|
|
321
|
-
"dialogClose": "NPLLIq_dialogClose",
|
|
322
|
-
"upgradeBanner": "NPLLIq_upgradeBanner",
|
|
323
|
-
"upgradeCommands": "NPLLIq_upgradeCommands",
|
|
324
|
-
"balanceRowName": "NPLLIq_balanceRowName",
|
|
325
|
-
"version": "NPLLIq_version",
|
|
326
|
-
"dialogTab": "NPLLIq_dialogTab",
|
|
327
|
-
"panelDim": "NPLLIq_panelDim",
|
|
323
|
+
"panelDimStrong": "NPLLIq_panelDimStrong",
|
|
324
|
+
"header": "NPLLIq_header",
|
|
325
|
+
"switch": "NPLLIq_switch",
|
|
326
|
+
"balanceBarBadge": "NPLLIq_balanceBarBadge",
|
|
327
|
+
"fillIdle": "NPLLIq_fillIdle",
|
|
328
|
+
"balanceBarLow": "NPLLIq_balanceBarLow",
|
|
329
|
+
"gearBtn": "NPLLIq_gearBtn",
|
|
330
|
+
"dialogBtn": "NPLLIq_dialogBtn",
|
|
331
|
+
"dialogTabs": "NPLLIq_dialogTabs",
|
|
332
|
+
"currentBadge": "NPLLIq_currentBadge",
|
|
328
333
|
"rowDragging": "NPLLIq_rowDragging",
|
|
329
|
-
"
|
|
330
|
-
"
|
|
331
|
-
"row": "NPLLIq_row",
|
|
332
|
-
"logUsedCol": "NPLLIq_logUsedCol",
|
|
334
|
+
"fillWarn": "NPLLIq_fillWarn",
|
|
335
|
+
"balanceRowRefresh": "NPLLIq_balanceRowRefresh",
|
|
333
336
|
"body": "NPLLIq_body",
|
|
334
|
-
"
|
|
335
|
-
"
|
|
336
|
-
"
|
|
337
|
-
"
|
|
338
|
-
"
|
|
339
|
-
"balanceWinBody": "NPLLIq_balanceWinBody",
|
|
340
|
-
"bar": "NPLLIq_bar",
|
|
341
|
-
"balanceWinHeader": "NPLLIq_balanceWinHeader",
|
|
342
|
-
"noteMenuBackdrop": "NPLLIq_noteMenuBackdrop",
|
|
343
|
-
"dialogSection": "NPLLIq_dialogSection",
|
|
337
|
+
"title": "NPLLIq_title",
|
|
338
|
+
"keyRow": "NPLLIq_keyRow",
|
|
339
|
+
"versionNew": "NPLLIq_versionNew",
|
|
340
|
+
"noteWinText": "NPLLIq_noteWinText",
|
|
341
|
+
"dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
|
|
344
342
|
"balanceToggleOpen": "NPLLIq_balanceToggleOpen",
|
|
345
|
-
"
|
|
346
|
-
"
|
|
347
|
-
"
|
|
348
|
-
"
|
|
343
|
+
"upgradeBannerText": "NPLLIq_upgradeBannerText",
|
|
344
|
+
"logPagerControls": "NPLLIq_logPagerControls",
|
|
345
|
+
"balanceWin": "NPLLIq_balanceWin",
|
|
346
|
+
"noteWin": "NPLLIq_noteWin",
|
|
347
|
+
"noteNewPlus": "NPLLIq_noteNewPlus",
|
|
349
348
|
"rowDrag": "NPLLIq_rowDrag",
|
|
350
|
-
"
|
|
351
|
-
"
|
|
352
|
-
"
|
|
349
|
+
"logPager": "NPLLIq_logPager",
|
|
350
|
+
"balanceValueError": "NPLLIq_balanceValueError",
|
|
351
|
+
"upgradeBanner": "NPLLIq_upgradeBanner",
|
|
352
|
+
"collapse": "NPLLIq_collapse",
|
|
353
|
+
"copyBtnDone": "NPLLIq_copyBtnDone",
|
|
354
|
+
"checkUpdatesLabel": "NPLLIq_checkUpdatesLabel",
|
|
355
|
+
"checkBtn": "NPLLIq_checkBtn",
|
|
356
|
+
"dialogTabActive": "NPLLIq_dialogTabActive",
|
|
357
|
+
"noteWinTitleText": "NPLLIq_noteWinTitleText",
|
|
358
|
+
"keyBadgeOk": "NPLLIq_keyBadgeOk",
|
|
359
|
+
"keyError": "NPLLIq_keyError",
|
|
353
360
|
"settingsBtn": "NPLLIq_settingsBtn",
|
|
361
|
+
"dialog": "NPLLIq_dialog",
|
|
362
|
+
"noteMenuItem": "NPLLIq_noteMenuItem",
|
|
354
363
|
"balanceRow": "NPLLIq_balanceRow",
|
|
355
|
-
"
|
|
356
|
-
"
|
|
357
|
-
"noteWinGripBar": "NPLLIq_noteWinGripBar",
|
|
358
|
-
"gearBtn": "NPLLIq_gearBtn",
|
|
359
|
-
"dialogActions": "NPLLIq_dialogActions",
|
|
360
|
-
"logPagerPages": "NPLLIq_logPagerPages",
|
|
364
|
+
"balanceValueLow": "NPLLIq_balanceValueLow",
|
|
365
|
+
"balanceBarError": "NPLLIq_balanceBarError",
|
|
361
366
|
"rowMeta": "NPLLIq_rowMeta",
|
|
367
|
+
"checkUpdatesRow": "NPLLIq_checkUpdatesRow",
|
|
368
|
+
"balanceToggle": "NPLLIq_balanceToggle",
|
|
369
|
+
"balanceBarText": "NPLLIq_balanceBarText",
|
|
370
|
+
"balanceWinBody": "NPLLIq_balanceWinBody",
|
|
371
|
+
"noteNew": "NPLLIq_noteNew",
|
|
372
|
+
"logUsedCol": "NPLLIq_logUsedCol",
|
|
373
|
+
"logPagerInfo": "NPLLIq_logPagerInfo",
|
|
374
|
+
"rowName": "NPLLIq_rowName",
|
|
375
|
+
"dialogActions": "NPLLIq_dialogActions",
|
|
376
|
+
"balanceValueOk": "NPLLIq_balanceValueOk",
|
|
377
|
+
"settingsDialog": "NPLLIq_settingsDialog",
|
|
378
|
+
"version": "NPLLIq_version",
|
|
379
|
+
"upgradeClose": "NPLLIq_upgradeClose",
|
|
380
|
+
"balanceRowValue": "NPLLIq_balanceRowValue",
|
|
381
|
+
"fillOver": "NPLLIq_fillOver",
|
|
382
|
+
"panelDim": "NPLLIq_panelDim",
|
|
383
|
+
"logPageSizeSelect": "NPLLIq_logPageSizeSelect",
|
|
362
384
|
"upgradeBannerFlash": "NPLLIq_upgradeBannerFlash",
|
|
363
|
-
"
|
|
364
|
-
"
|
|
385
|
+
"row": "NPLLIq_row",
|
|
386
|
+
"tabLabel": "NPLLIq_tabLabel",
|
|
387
|
+
"dialogHint": "NPLLIq_dialogHint",
|
|
388
|
+
"dialogClose": "NPLLIq_dialogClose",
|
|
365
389
|
"logHeader": "NPLLIq_logHeader",
|
|
366
|
-
"dialogTabs": "NPLLIq_dialogTabs",
|
|
367
|
-
"dialogOverlay": "NPLLIq_dialogOverlay",
|
|
368
|
-
"checkBtn": "NPLLIq_checkBtn",
|
|
369
|
-
"settingsBtnActive": "NPLLIq_settingsBtnActive",
|
|
370
|
-
"balanceValueOk": "NPLLIq_balanceValueOk",
|
|
371
|
-
"dialogBody": "NPLLIq_dialogBody",
|
|
372
390
|
"logScroll": "NPLLIq_logScroll",
|
|
373
|
-
"balanceBarRefresh": "NPLLIq_balanceBarRefresh",
|
|
374
|
-
"fillOver": "NPLLIq_fillOver",
|
|
375
391
|
"monitorRow": "NPLLIq_monitorRow",
|
|
376
|
-
"
|
|
377
|
-
"
|
|
378
|
-
"
|
|
379
|
-
"dialogTabActive": "NPLLIq_dialogTabActive",
|
|
380
|
-
"balanceToggle": "NPLLIq_balanceToggle",
|
|
381
|
-
"logClearBtn": "NPLLIq_logClearBtn",
|
|
382
|
-
"dialogBtn": "NPLLIq_dialogBtn",
|
|
383
|
-
"monitorName": "NPLLIq_monitorName",
|
|
384
|
-
"monitorHint": "NPLLIq_monitorHint",
|
|
385
|
-
"noteNew": "NPLLIq_noteNew",
|
|
386
|
-
"dialogHeader": "NPLLIq_dialogHeader",
|
|
387
|
-
"balanceBarLow": "NPLLIq_balanceBarLow",
|
|
388
|
-
"noteWinBar": "NPLLIq_noteWinBar",
|
|
389
|
-
"logModelCol": "NPLLIq_logModelCol",
|
|
390
|
-
"logClearDialog": "NPLLIq_logClearDialog",
|
|
391
|
-
"dialogLabel": "NPLLIq_dialogLabel",
|
|
392
|
-
"balanceLastLine": "NPLLIq_balanceLastLine",
|
|
393
|
-
"copyBtn": "NPLLIq_copyBtn",
|
|
394
|
-
"controls": "NPLLIq_controls",
|
|
395
|
-
"radioRow": "NPLLIq_radioRow",
|
|
396
|
-
"tab": "NPLLIq_tab",
|
|
397
|
-
"balanceRowHeader": "NPLLIq_balanceRowHeader",
|
|
398
|
-
"balanceRowValue": "NPLLIq_balanceRowValue",
|
|
392
|
+
"dialogTitle": "NPLLIq_dialogTitle",
|
|
393
|
+
"balanceBarRefresh": "NPLLIq_balanceBarRefresh",
|
|
394
|
+
"noteWinBtn": "NPLLIq_noteWinBtn",
|
|
399
395
|
"logToolbar": "NPLLIq_logToolbar",
|
|
400
|
-
"
|
|
396
|
+
"keySaveBtn": "NPLLIq_keySaveBtn",
|
|
397
|
+
"upgradeCommand": "NPLLIq_upgradeCommand",
|
|
398
|
+
"resetRow": "NPLLIq_resetRow",
|
|
399
|
+
"headerActions": "NPLLIq_headerActions",
|
|
400
|
+
"dialogTab": "NPLLIq_dialogTab",
|
|
401
|
+
"dialogBody": "NPLLIq_dialogBody",
|
|
402
|
+
"fullNotice": "NPLLIq_fullNotice",
|
|
403
|
+
"noticeError": "NPLLIq_noticeError",
|
|
404
|
+
"logClearDate": "NPLLIq_logClearDate",
|
|
405
|
+
"noteWinTitle": "NPLLIq_noteWinTitle"
|
|
401
406
|
};
|
|
402
407
|
//#endregion
|
|
403
408
|
//#region lib/types/client/TokenQuotaPanel.js
|
|
@@ -535,13 +540,18 @@ window.__ModuleLoader__.load({
|
|
|
535
540
|
* @param props - composed slot props.
|
|
536
541
|
* @returns the panel element tree.
|
|
537
542
|
*/
|
|
538
|
-
function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle, setModelOrder, saveNotes, setBalanceSettings, refreshBalance, setMusicEnabled, setMusicVolume, setMusicStyle, setMusicOnlyCurrentSession, setTranscribeSettings, useStore, actions, useSessions }) {
|
|
543
|
+
function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle, setModelOrder, saveNotes, setBalanceSettings, refreshBalance, setMusicEnabled, setMusicVolume, setMusicStyle, setMusicOnlyCurrentSession, setTranscribeSettings, checkTranscribeKey, saveTranscribeKey, useStore, actions, useSessions }) {
|
|
539
544
|
const [collapsed, setCollapsed] = (0, react.useState)(false);
|
|
540
545
|
const [drafts, setDrafts] = (0, react.useState)({});
|
|
541
546
|
const [editingKey, setEditingKey] = (0, react.useState)(null);
|
|
542
547
|
const [hovered, setHovered] = (0, react.useState)(false);
|
|
543
548
|
const [inputActive, setInputActive] = (0, react.useState)(false);
|
|
544
549
|
const [settingsTab, setSettingsTab] = (0, react.useState)("quota");
|
|
550
|
+
const [keyDraft, setKeyDraft] = (0, react.useState)("");
|
|
551
|
+
const [keyConfigured, setKeyConfigured] = (0, react.useState)(null);
|
|
552
|
+
const [keySaving, setKeySaving] = (0, react.useState)(false);
|
|
553
|
+
const [keySaved, setKeySaved] = (0, react.useState)(false);
|
|
554
|
+
const [keyError, setKeyError] = (0, react.useState)(null);
|
|
545
555
|
const [dragKey, setDragKey] = (0, react.useState)(null);
|
|
546
556
|
const [dropKey, setDropKey] = (0, react.useState)(null);
|
|
547
557
|
const storedNotes = useStore((s) => s.notes);
|
|
@@ -729,6 +739,44 @@ window.__ModuleLoader__.load({
|
|
|
729
739
|
(0, react.useEffect)(() => {
|
|
730
740
|
if (sessionId !== void 0) load(sessionId);
|
|
731
741
|
}, [sessionId, load]);
|
|
742
|
+
(0, react.useEffect)(() => {
|
|
743
|
+
if (settingsTab !== "transcribe") return;
|
|
744
|
+
const ref = transcribe.apiKeyEnv;
|
|
745
|
+
if (ref === "") return;
|
|
746
|
+
let cancelled = false;
|
|
747
|
+
checkTranscribeKey(ref).then((configured) => {
|
|
748
|
+
if (!cancelled) {
|
|
749
|
+
setKeyConfigured(configured);
|
|
750
|
+
setKeySaved(false);
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
return () => {
|
|
754
|
+
cancelled = true;
|
|
755
|
+
};
|
|
756
|
+
}, [
|
|
757
|
+
settingsTab,
|
|
758
|
+
transcribe.apiKeyEnv,
|
|
759
|
+
checkTranscribeKey
|
|
760
|
+
]);
|
|
761
|
+
/**
|
|
762
|
+
* Write the staged transcription key through the credential seam, then
|
|
763
|
+
* re-read presence. The secret is never read back, so the badge reflects
|
|
764
|
+
* what the Host reports rather than what was typed.
|
|
765
|
+
*/
|
|
766
|
+
const saveKey = () => {
|
|
767
|
+
const ref = transcribe.apiKeyEnv;
|
|
768
|
+
if (ref === "" || keyDraft === "") return;
|
|
769
|
+
setKeySaving(true);
|
|
770
|
+
setKeyError(null);
|
|
771
|
+
saveTranscribeKey(ref, keyDraft).then((result) => {
|
|
772
|
+
setKeySaving(false);
|
|
773
|
+
if (result.ok) {
|
|
774
|
+
setKeyDraft("");
|
|
775
|
+
setKeyConfigured(true);
|
|
776
|
+
setKeySaved(true);
|
|
777
|
+
} else setKeyError(result.error ?? t("transcribeKeyFailed"));
|
|
778
|
+
});
|
|
779
|
+
};
|
|
732
780
|
(0, react.useEffect)(() => {
|
|
733
781
|
const onFocusIn = (event) => {
|
|
734
782
|
const target = event.target;
|
|
@@ -1068,13 +1116,13 @@ window.__ModuleLoader__.load({
|
|
|
1068
1116
|
title: t("upgradeAvailableHint"),
|
|
1069
1117
|
children: [
|
|
1070
1118
|
"v",
|
|
1071
|
-
"0.1.
|
|
1119
|
+
"0.1.44",
|
|
1072
1120
|
" → v",
|
|
1073
1121
|
upgrade.latestVersion
|
|
1074
1122
|
]
|
|
1075
1123
|
}) : (0, react_jsx_runtime.jsxs)("span", {
|
|
1076
1124
|
className: TokenQuotaPanel_module_css_default.version,
|
|
1077
|
-
children: ["v", "0.1.
|
|
1125
|
+
children: ["v", "0.1.44"]
|
|
1078
1126
|
})]
|
|
1079
1127
|
})
|
|
1080
1128
|
}),
|
|
@@ -1738,6 +1786,50 @@ window.__ModuleLoader__.load({
|
|
|
1738
1786
|
className: TokenQuotaPanel_module_css_default.dialogHint,
|
|
1739
1787
|
children: t("transcribeApiKeyEnvHint")
|
|
1740
1788
|
}),
|
|
1789
|
+
(0, react_jsx_runtime.jsxs)("label", {
|
|
1790
|
+
className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
|
|
1791
|
+
children: [(0, react_jsx_runtime.jsx)("span", { children: t("transcribeKeyLabel") }), (0, react_jsx_runtime.jsx)("input", {
|
|
1792
|
+
className: TokenQuotaPanel_module_css_default.resetSelect,
|
|
1793
|
+
type: "password",
|
|
1794
|
+
autoComplete: "off",
|
|
1795
|
+
value: keyDraft,
|
|
1796
|
+
placeholder: keyConfigured === true ? t("transcribeKeyPlaceholderSet") : t("transcribeKeyPlaceholder"),
|
|
1797
|
+
onChange: (event) => {
|
|
1798
|
+
setKeyDraft(event.target.value);
|
|
1799
|
+
setKeySaved(false);
|
|
1800
|
+
setKeyError(null);
|
|
1801
|
+
},
|
|
1802
|
+
onKeyDown: (event) => {
|
|
1803
|
+
if (event.key === "Enter") {
|
|
1804
|
+
event.preventDefault();
|
|
1805
|
+
saveKey();
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
})]
|
|
1809
|
+
}),
|
|
1810
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
1811
|
+
className: TokenQuotaPanel_module_css_default.dialogHint,
|
|
1812
|
+
children: t("transcribeKeyHint")
|
|
1813
|
+
}),
|
|
1814
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
1815
|
+
className: TokenQuotaPanel_module_css_default.keyRow,
|
|
1816
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
1817
|
+
type: "button",
|
|
1818
|
+
className: TokenQuotaPanel_module_css_default.keySaveBtn,
|
|
1819
|
+
disabled: keyDraft === "" || keySaving,
|
|
1820
|
+
onClick: () => {
|
|
1821
|
+
saveKey();
|
|
1822
|
+
},
|
|
1823
|
+
children: keySaving ? t("transcribeKeySaving") : t("transcribeKeySave")
|
|
1824
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
1825
|
+
className: keyConfigured === true ? TokenQuotaPanel_module_css_default.keyBadgeOk : TokenQuotaPanel_module_css_default.keyBadgeOff,
|
|
1826
|
+
children: keySaved ? t("transcribeKeySaved") : keyConfigured === true ? t("transcribeKeyConfigured") : t("transcribeKeyMissing")
|
|
1827
|
+
})]
|
|
1828
|
+
}),
|
|
1829
|
+
keyError !== null && (0, react_jsx_runtime.jsx)("div", {
|
|
1830
|
+
className: TokenQuotaPanel_module_css_default.keyError,
|
|
1831
|
+
children: keyError
|
|
1832
|
+
}),
|
|
1741
1833
|
(0, react_jsx_runtime.jsxs)("label", {
|
|
1742
1834
|
className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
|
|
1743
1835
|
children: [(0, react_jsx_runtime.jsx)("span", { children: t("transcribeModelLabel") }), (0, react_jsx_runtime.jsx)("input", {
|
|
@@ -2890,12 +2982,12 @@ window.__ModuleLoader__.load({
|
|
|
2890
2982
|
document.head.appendChild(tag);
|
|
2891
2983
|
}
|
|
2892
2984
|
var mic_module_css_default = {
|
|
2893
|
-
"micRec": "KCoVpa_micRec",
|
|
2894
|
-
"micWrap": "KCoVpa_micWrap",
|
|
2895
|
-
"micBtn": "KCoVpa_micBtn",
|
|
2896
|
-
"micBusy": "KCoVpa_micBusy",
|
|
2897
2985
|
"micErr": "KCoVpa_micErr",
|
|
2898
2986
|
"micErrTip": "KCoVpa_micErrTip",
|
|
2987
|
+
"micBtn": "KCoVpa_micBtn",
|
|
2988
|
+
"micRec": "KCoVpa_micRec",
|
|
2989
|
+
"micBusy": "KCoVpa_micBusy",
|
|
2990
|
+
"micWrap": "KCoVpa_micWrap",
|
|
2899
2991
|
"micPulse": "KCoVpa_micPulse"
|
|
2900
2992
|
};
|
|
2901
2993
|
//#endregion
|
|
@@ -3088,8 +3180,18 @@ window.__ModuleLoader__.load({
|
|
|
3088
3180
|
transcribeEnabledHint: "在对话框右上角显示麦克风按钮",
|
|
3089
3181
|
transcribeBaseURLLabel: "接口地址",
|
|
3090
3182
|
transcribeBaseURLHint: "OpenAI 兼容的转录接口 base URL",
|
|
3091
|
-
transcribeApiKeyEnvLabel: "
|
|
3092
|
-
transcribeApiKeyEnvHint: "
|
|
3183
|
+
transcribeApiKeyEnvLabel: "凭证名称",
|
|
3184
|
+
transcribeApiKeyEnvHint: "密钥在凭证库中保存的名称,一般无需修改",
|
|
3185
|
+
transcribeKeyLabel: "API Key",
|
|
3186
|
+
transcribeKeyHint: "在此填入密钥并点「保存」,密钥会写入 DSH 凭证库(保存后不会回显)",
|
|
3187
|
+
transcribeKeyPlaceholder: "粘贴 API Key",
|
|
3188
|
+
transcribeKeyPlaceholderSet: "已配置,填入新值可覆盖",
|
|
3189
|
+
transcribeKeySave: "保存",
|
|
3190
|
+
transcribeKeySaving: "保存中…",
|
|
3191
|
+
transcribeKeySaved: "已保存",
|
|
3192
|
+
transcribeKeyConfigured: "已配置",
|
|
3193
|
+
transcribeKeyMissing: "未配置",
|
|
3194
|
+
transcribeKeyFailed: "保存失败",
|
|
3093
3195
|
transcribeModelLabel: "模型",
|
|
3094
3196
|
transcribeModelHint: "语音转文本模型名",
|
|
3095
3197
|
reorderHint: "拖动排序",
|
|
@@ -3217,8 +3319,18 @@ window.__ModuleLoader__.load({
|
|
|
3217
3319
|
transcribeEnabledHint: "Show a mic button in the top-right of the composer",
|
|
3218
3320
|
transcribeBaseURLLabel: "Base URL",
|
|
3219
3321
|
transcribeBaseURLHint: "OpenAI-compatible transcription endpoint base URL",
|
|
3220
|
-
transcribeApiKeyEnvLabel: "
|
|
3221
|
-
transcribeApiKeyEnvHint: "
|
|
3322
|
+
transcribeApiKeyEnvLabel: "Credential name",
|
|
3323
|
+
transcribeApiKeyEnvHint: "Name the key is stored under in the credential store; usually unchanged",
|
|
3324
|
+
transcribeKeyLabel: "API key",
|
|
3325
|
+
transcribeKeyHint: "Paste the key here and press Save — it is written to the DSH credential store and never read back",
|
|
3326
|
+
transcribeKeyPlaceholder: "Paste API key",
|
|
3327
|
+
transcribeKeyPlaceholderSet: "Configured — enter a new value to replace",
|
|
3328
|
+
transcribeKeySave: "Save",
|
|
3329
|
+
transcribeKeySaving: "Saving…",
|
|
3330
|
+
transcribeKeySaved: "Saved",
|
|
3331
|
+
transcribeKeyConfigured: "Configured",
|
|
3332
|
+
transcribeKeyMissing: "Not configured",
|
|
3333
|
+
transcribeKeyFailed: "Save failed",
|
|
3222
3334
|
transcribeModelLabel: "Model",
|
|
3223
3335
|
transcribeModelHint: "Speech-to-text model name",
|
|
3224
3336
|
reorderHint: "Drag to reorder",
|
|
@@ -3328,7 +3440,8 @@ window.__ModuleLoader__.load({
|
|
|
3328
3440
|
"locale",
|
|
3329
3441
|
"settingsScope",
|
|
3330
3442
|
"remote",
|
|
3331
|
-
"remote.session"
|
|
3443
|
+
"remote.session",
|
|
3444
|
+
"remote.credentials"
|
|
3332
3445
|
];
|
|
3333
3446
|
/**
|
|
3334
3447
|
* Client plugin body: poll the Host snapshot route, run the full-quota
|
|
@@ -3428,6 +3541,23 @@ window.__ModuleLoader__.load({
|
|
|
3428
3541
|
apiKeyEnv: typeof raw?.apiKeyEnv === "string" && raw.apiKeyEnv !== "" ? raw.apiKeyEnv : TOKEN_QUOTA_DEFAULT_TRANSCRIBE.apiKeyEnv,
|
|
3429
3542
|
model: typeof raw?.model === "string" && raw.model !== "" ? raw.model : TOKEN_QUOTA_DEFAULT_TRANSCRIBE.model
|
|
3430
3543
|
});
|
|
3544
|
+
let currentTranscribe = TOKEN_QUOTA_DEFAULT_TRANSCRIBE;
|
|
3545
|
+
const transcribeSubscribers = /* @__PURE__ */ new Set();
|
|
3546
|
+
const emitTranscribe = () => {
|
|
3547
|
+
for (const fn of transcribeSubscribers) fn();
|
|
3548
|
+
};
|
|
3549
|
+
const subscribeTranscribe = (cb) => {
|
|
3550
|
+
transcribeSubscribers.add(cb);
|
|
3551
|
+
return () => {
|
|
3552
|
+
transcribeSubscribers.delete(cb);
|
|
3553
|
+
};
|
|
3554
|
+
};
|
|
3555
|
+
const getTranscribe = () => currentTranscribe;
|
|
3556
|
+
const applyTranscribe = (settings) => {
|
|
3557
|
+
if (settings.enabled === currentTranscribe.enabled && settings.baseURL === currentTranscribe.baseURL && settings.apiKeyEnv === currentTranscribe.apiKeyEnv && settings.model === currentTranscribe.model) return;
|
|
3558
|
+
currentTranscribe = settings;
|
|
3559
|
+
emitTranscribe();
|
|
3560
|
+
};
|
|
3431
3561
|
const keyOf = (selection) => {
|
|
3432
3562
|
if (selection === null) return void 0;
|
|
3433
3563
|
return `${selection.provider}/${selection.model}`;
|
|
@@ -3643,29 +3773,42 @@ window.__ModuleLoader__.load({
|
|
|
3643
3773
|
});
|
|
3644
3774
|
};
|
|
3645
3775
|
/** Persist the voice transcription settings and mirror them into the store. */
|
|
3646
|
-
let currentTranscribe = TOKEN_QUOTA_DEFAULT_TRANSCRIBE;
|
|
3647
|
-
const transcribeSubscribers = /* @__PURE__ */ new Set();
|
|
3648
|
-
const emitTranscribe = () => {
|
|
3649
|
-
for (const fn of transcribeSubscribers) fn();
|
|
3650
|
-
};
|
|
3651
|
-
const subscribeTranscribe = (cb) => {
|
|
3652
|
-
transcribeSubscribers.add(cb);
|
|
3653
|
-
return () => {
|
|
3654
|
-
transcribeSubscribers.delete(cb);
|
|
3655
|
-
};
|
|
3656
|
-
};
|
|
3657
|
-
const getTranscribe = () => currentTranscribe;
|
|
3658
|
-
const applyTranscribe = (settings) => {
|
|
3659
|
-
if (settings.enabled === currentTranscribe.enabled && settings.baseURL === currentTranscribe.baseURL && settings.apiKeyEnv === currentTranscribe.apiKeyEnv && settings.model === currentTranscribe.model) return;
|
|
3660
|
-
currentTranscribe = settings;
|
|
3661
|
-
emitTranscribe();
|
|
3662
|
-
};
|
|
3663
3776
|
const setTranscribeSettings = (settings) => {
|
|
3664
3777
|
applyTranscribe(settings);
|
|
3665
3778
|
bound?.setTranscribeSettings(settings);
|
|
3666
3779
|
scope.set("transcribe", settings);
|
|
3667
3780
|
};
|
|
3668
3781
|
/**
|
|
3782
|
+
* Read whether the transcription credential reference currently holds a key,
|
|
3783
|
+
* so the settings page can show 已配置 / 未配置 without ever reading the
|
|
3784
|
+
* secret back (the wire carries it in one direction only).
|
|
3785
|
+
*/
|
|
3786
|
+
const checkTranscribeKey = async (ref) => {
|
|
3787
|
+
try {
|
|
3788
|
+
const result = await ctx.remote.credentials.describe([ref]);
|
|
3789
|
+
if (!result.ok) return false;
|
|
3790
|
+
return result.value[ref]?.configured === true;
|
|
3791
|
+
} catch {
|
|
3792
|
+
return false;
|
|
3793
|
+
}
|
|
3794
|
+
};
|
|
3795
|
+
/**
|
|
3796
|
+
* Store the transcription API key through the credential seam, so it lives
|
|
3797
|
+
* in the same credential store the Host resolves from — the user never has
|
|
3798
|
+
* to edit a file by hand.
|
|
3799
|
+
*/
|
|
3800
|
+
const saveTranscribeKey = async (ref, value) => {
|
|
3801
|
+
try {
|
|
3802
|
+
await ctx.remote.credentials.set(ref, value);
|
|
3803
|
+
return { ok: true };
|
|
3804
|
+
} catch (error) {
|
|
3805
|
+
return {
|
|
3806
|
+
ok: false,
|
|
3807
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3808
|
+
};
|
|
3809
|
+
}
|
|
3810
|
+
};
|
|
3811
|
+
/**
|
|
3669
3812
|
* Send a recorded audio blob to the Host, which forwards it to the
|
|
3670
3813
|
* configured OpenAI-compatible transcription endpoint. Resolves with the
|
|
3671
3814
|
* recognised text.
|
|
@@ -3819,7 +3962,9 @@ window.__ModuleLoader__.load({
|
|
|
3819
3962
|
saveNotes,
|
|
3820
3963
|
setBalanceSettings,
|
|
3821
3964
|
refreshBalance,
|
|
3822
|
-
setTranscribeSettings
|
|
3965
|
+
setTranscribeSettings,
|
|
3966
|
+
checkTranscribeKey,
|
|
3967
|
+
saveTranscribeKey
|
|
3823
3968
|
};
|
|
3824
3969
|
};
|
|
3825
3970
|
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
package/lib/index.js
CHANGED
|
@@ -651,7 +651,7 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
651
651
|
return this.upgradeCheck;
|
|
652
652
|
}
|
|
653
653
|
async doRefreshUpgrade() {
|
|
654
|
-
const current = "0.1.
|
|
654
|
+
const current = "0.1.44";
|
|
655
655
|
let latest;
|
|
656
656
|
try {
|
|
657
657
|
const response = await fetch(REGISTRY_LATEST_URL, {
|
|
@@ -38,6 +38,13 @@ export interface TokenQuotaPanelInjected {
|
|
|
38
38
|
setMusicOnlyCurrentSession: (only: boolean) => void;
|
|
39
39
|
/** Persist the voice transcription settings (endpoint, key ref, model). */
|
|
40
40
|
setTranscribeSettings: (settings: TokenQuotaTranscribeSettings) => void;
|
|
41
|
+
/** Read whether the transcription credential reference currently holds a key. */
|
|
42
|
+
checkTranscribeKey: (ref: string) => Promise<boolean>;
|
|
43
|
+
/** Store the transcription API key through the credential seam. */
|
|
44
|
+
saveTranscribeKey: (ref: string, value: string) => Promise<{
|
|
45
|
+
ok: boolean;
|
|
46
|
+
error?: string;
|
|
47
|
+
}>;
|
|
41
48
|
/** Ask the Host to check the registry right now, then refresh the snapshot. */
|
|
42
49
|
checkUpdatesNow: () => void;
|
|
43
50
|
/** Ask the Host to clear log entries before a date, then refresh the log. */
|
|
@@ -50,5 +57,5 @@ export type TokenQuotaPanelComponentProps = PropsRuntime<'shell.overlay'> & Prop
|
|
|
50
57
|
* @param props - composed slot props.
|
|
51
58
|
* @returns the panel element tree.
|
|
52
59
|
*/
|
|
53
|
-
export declare function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle, setModelOrder, saveNotes, setBalanceSettings, refreshBalance, setMusicEnabled, setMusicVolume, setMusicStyle, setMusicOnlyCurrentSession, setTranscribeSettings, useStore, actions, useSessions, }: TokenQuotaPanelComponentProps): import("react").JSX.Element;
|
|
60
|
+
export declare function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle, setModelOrder, saveNotes, setBalanceSettings, refreshBalance, setMusicEnabled, setMusicVolume, setMusicStyle, setMusicOnlyCurrentSession, setTranscribeSettings, checkTranscribeKey, saveTranscribeKey, useStore, actions, useSessions, }: TokenQuotaPanelComponentProps): import("react").JSX.Element;
|
|
54
61
|
//# sourceMappingURL=TokenQuotaPanel.d.ts.map
|
|
@@ -149,7 +149,7 @@ function loadPanelPos() {
|
|
|
149
149
|
* @param props - composed slot props.
|
|
150
150
|
* @returns the panel element tree.
|
|
151
151
|
*/
|
|
152
|
-
export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle, setModelOrder, saveNotes, setBalanceSettings, refreshBalance, setMusicEnabled, setMusicVolume, setMusicStyle, setMusicOnlyCurrentSession, setTranscribeSettings, useStore, actions, useSessions, }) {
|
|
152
|
+
export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle, setModelOrder, saveNotes, setBalanceSettings, refreshBalance, setMusicEnabled, setMusicVolume, setMusicStyle, setMusicOnlyCurrentSession, setTranscribeSettings, checkTranscribeKey, saveTranscribeKey, useStore, actions, useSessions, }) {
|
|
153
153
|
const [collapsed, setCollapsed] = useState(false);
|
|
154
154
|
const [drafts, setDrafts] = useState({});
|
|
155
155
|
const [editingKey, setEditingKey] = useState(null);
|
|
@@ -160,6 +160,13 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
160
160
|
const [inputActive, setInputActive] = useState(false);
|
|
161
161
|
// Active settings-dialog tab: quota limits vs. live-music vs. misc.
|
|
162
162
|
const [settingsTab, setSettingsTab] = useState('quota');
|
|
163
|
+
// Transcription API-key editor: the staged secret (never read back from the
|
|
164
|
+
// Host), whether the Host already holds one, and the last save outcome.
|
|
165
|
+
const [keyDraft, setKeyDraft] = useState('');
|
|
166
|
+
const [keyConfigured, setKeyConfigured] = useState(null);
|
|
167
|
+
const [keySaving, setKeySaving] = useState(false);
|
|
168
|
+
const [keySaved, setKeySaved] = useState(false);
|
|
169
|
+
const [keyError, setKeyError] = useState(null);
|
|
163
170
|
// Drag-to-reorder state for the model rows: the key being dragged and
|
|
164
171
|
// the key currently hovered as the drop target.
|
|
165
172
|
const [dragKey, setDragKey] = useState(null);
|
|
@@ -381,6 +388,47 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
381
388
|
if (sessionId !== undefined)
|
|
382
389
|
load(sessionId);
|
|
383
390
|
}, [sessionId, load]);
|
|
391
|
+
// Ask the Host whether the transcription credential reference already holds
|
|
392
|
+
// a key, so the settings page can show 已配置 / 未配置. The secret itself is
|
|
393
|
+
// never readable over the wire — only presence is.
|
|
394
|
+
useEffect(() => {
|
|
395
|
+
if (settingsTab !== 'transcribe')
|
|
396
|
+
return;
|
|
397
|
+
const ref = transcribe.apiKeyEnv;
|
|
398
|
+
if (ref === '')
|
|
399
|
+
return;
|
|
400
|
+
let cancelled = false;
|
|
401
|
+
void checkTranscribeKey(ref).then((configured) => {
|
|
402
|
+
if (!cancelled) {
|
|
403
|
+
setKeyConfigured(configured);
|
|
404
|
+
setKeySaved(false);
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
return () => { cancelled = true; };
|
|
408
|
+
}, [settingsTab, transcribe.apiKeyEnv, checkTranscribeKey]);
|
|
409
|
+
/**
|
|
410
|
+
* Write the staged transcription key through the credential seam, then
|
|
411
|
+
* re-read presence. The secret is never read back, so the badge reflects
|
|
412
|
+
* what the Host reports rather than what was typed.
|
|
413
|
+
*/
|
|
414
|
+
const saveKey = () => {
|
|
415
|
+
const ref = transcribe.apiKeyEnv;
|
|
416
|
+
if (ref === '' || keyDraft === '')
|
|
417
|
+
return;
|
|
418
|
+
setKeySaving(true);
|
|
419
|
+
setKeyError(null);
|
|
420
|
+
void saveTranscribeKey(ref, keyDraft).then((result) => {
|
|
421
|
+
setKeySaving(false);
|
|
422
|
+
if (result.ok) {
|
|
423
|
+
setKeyDraft('');
|
|
424
|
+
setKeyConfigured(true);
|
|
425
|
+
setKeySaved(true);
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
setKeyError(result.error ?? t('transcribeKeyFailed'));
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
};
|
|
384
432
|
// Track whether any text input (composer, search, dialogs) currently has
|
|
385
433
|
// focus, so the panel can dim while the user types elsewhere.
|
|
386
434
|
useEffect(() => {
|
|
@@ -818,7 +866,18 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
818
866
|
hour: reset?.hour ?? 0,
|
|
819
867
|
minute: Number(event.target.value),
|
|
820
868
|
});
|
|
821
|
-
}, children: Array.from({ length: 12 }, (_, i) => i * 5).map(minute => (_jsxs("option", { value: minute, children: [String(minute).padStart(2, '0'), " \u5206"] }, minute))) })] })] }), _jsxs("div", { className: css.dialogSection, children: [_jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("input", { type: "checkbox", checked: dimWhenIdle, onChange: (event) => { setDimWhenIdle(event.target.checked); } }), _jsx("span", { children: t('dimWhenIdleLabel') })] }), _jsx("div", { className: css.dialogHint, children: t('dimWhenIdleHint') })] })] })), settingsTab === 'music' && (_jsxs(_Fragment, { children: [_jsxs("div", { className: css.dialogSection, children: [_jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("input", { type: "checkbox", checked: musicEnabled, onChange: (event) => { setMusicEnabled(event.target.checked); } }), _jsx("span", { children: t('musicLabel') })] }), _jsx("div", { className: css.dialogHint, children: t('musicHint') })] }), musicEnabled && (_jsxs("div", { className: css.dialogSection, children: [_jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("span", { children: t('musicVolume') }), _jsx("input", { type: "range", min: 0, max: 1, step: 0.05, value: musicVolume, onChange: (event) => { setMusicVolume(Number(event.target.value)); } })] }), _jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("span", { children: t('musicStyle') }), _jsxs("select", { value: musicStyle, onChange: (event) => { setMusicStyle(event.target.value); }, children: [_jsx("option", { value: "major", children: t('musicStyleMajor') }), _jsx("option", { value: "minor", children: t('musicStyleMinor') }), _jsx("option", { value: "pentatonic", children: t('musicStylePentatonic') })] })] }), _jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("input", { type: "checkbox", checked: musicOnlyCurrentSession, onChange: (event) => { setMusicOnlyCurrentSession(event.target.checked); } }), _jsx("span", { children: t('musicOnlyCurrentSessionLabel') })] }), _jsx("div", { className: css.dialogHint, children: t('musicOnlyCurrentSessionHint') })] }))] })), settingsTab === 'transcribe' && (_jsxs(_Fragment, { children: [_jsxs("div", { className: css.dialogSection, children: [_jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("input", { type: "checkbox", checked: transcribe.enabled, onChange: (event) => { setTranscribeSettings({ ...transcribe, enabled: event.target.checked }); } }), _jsx("span", { children: t('transcribeEnabledLabel') })] }), _jsx("div", { className: css.dialogHint, children: t('transcribeEnabledHint') })] }), transcribe.enabled && (_jsxs("div", { className: css.dialogSection, children: [_jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("span", { children: t('transcribeBaseURLLabel') }), _jsx("input", { className: css.resetSelect, type: "text", value: transcribe.baseURL, onChange: (event) => { setTranscribeSettings({ ...transcribe, baseURL: event.target.value }); } })] }), _jsx("div", { className: css.dialogHint, children: t('transcribeBaseURLHint') }), _jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("span", { children: t('transcribeApiKeyEnvLabel') }), _jsx("input", { className: css.resetSelect, type: "text", value: transcribe.apiKeyEnv, onChange: (event) => { setTranscribeSettings({ ...transcribe, apiKeyEnv: event.target.value }); } })] }), _jsx("div", { className: css.dialogHint, children: t('transcribeApiKeyEnvHint') }), _jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("span", { children: t('
|
|
869
|
+
}, children: Array.from({ length: 12 }, (_, i) => i * 5).map(minute => (_jsxs("option", { value: minute, children: [String(minute).padStart(2, '0'), " \u5206"] }, minute))) })] })] }), _jsxs("div", { className: css.dialogSection, children: [_jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("input", { type: "checkbox", checked: dimWhenIdle, onChange: (event) => { setDimWhenIdle(event.target.checked); } }), _jsx("span", { children: t('dimWhenIdleLabel') })] }), _jsx("div", { className: css.dialogHint, children: t('dimWhenIdleHint') })] })] })), settingsTab === 'music' && (_jsxs(_Fragment, { children: [_jsxs("div", { className: css.dialogSection, children: [_jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("input", { type: "checkbox", checked: musicEnabled, onChange: (event) => { setMusicEnabled(event.target.checked); } }), _jsx("span", { children: t('musicLabel') })] }), _jsx("div", { className: css.dialogHint, children: t('musicHint') })] }), musicEnabled && (_jsxs("div", { className: css.dialogSection, children: [_jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("span", { children: t('musicVolume') }), _jsx("input", { type: "range", min: 0, max: 1, step: 0.05, value: musicVolume, onChange: (event) => { setMusicVolume(Number(event.target.value)); } })] }), _jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("span", { children: t('musicStyle') }), _jsxs("select", { value: musicStyle, onChange: (event) => { setMusicStyle(event.target.value); }, children: [_jsx("option", { value: "major", children: t('musicStyleMajor') }), _jsx("option", { value: "minor", children: t('musicStyleMinor') }), _jsx("option", { value: "pentatonic", children: t('musicStylePentatonic') })] })] }), _jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("input", { type: "checkbox", checked: musicOnlyCurrentSession, onChange: (event) => { setMusicOnlyCurrentSession(event.target.checked); } }), _jsx("span", { children: t('musicOnlyCurrentSessionLabel') })] }), _jsx("div", { className: css.dialogHint, children: t('musicOnlyCurrentSessionHint') })] }))] })), settingsTab === 'transcribe' && (_jsxs(_Fragment, { children: [_jsxs("div", { className: css.dialogSection, children: [_jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("input", { type: "checkbox", checked: transcribe.enabled, onChange: (event) => { setTranscribeSettings({ ...transcribe, enabled: event.target.checked }); } }), _jsx("span", { children: t('transcribeEnabledLabel') })] }), _jsx("div", { className: css.dialogHint, children: t('transcribeEnabledHint') })] }), transcribe.enabled && (_jsxs("div", { className: css.dialogSection, children: [_jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("span", { children: t('transcribeBaseURLLabel') }), _jsx("input", { className: css.resetSelect, type: "text", value: transcribe.baseURL, onChange: (event) => { setTranscribeSettings({ ...transcribe, baseURL: event.target.value }); } })] }), _jsx("div", { className: css.dialogHint, children: t('transcribeBaseURLHint') }), _jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("span", { children: t('transcribeApiKeyEnvLabel') }), _jsx("input", { className: css.resetSelect, type: "text", value: transcribe.apiKeyEnv, onChange: (event) => { setTranscribeSettings({ ...transcribe, apiKeyEnv: event.target.value }); } })] }), _jsx("div", { className: css.dialogHint, children: t('transcribeApiKeyEnvHint') }), _jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("span", { children: t('transcribeKeyLabel') }), _jsx("input", { className: css.resetSelect, type: "password", autoComplete: "off", value: keyDraft, placeholder: keyConfigured === true ? t('transcribeKeyPlaceholderSet') : t('transcribeKeyPlaceholder'), onChange: (event) => {
|
|
870
|
+
setKeyDraft(event.target.value);
|
|
871
|
+
setKeySaved(false);
|
|
872
|
+
setKeyError(null);
|
|
873
|
+
}, onKeyDown: (event) => {
|
|
874
|
+
if (event.key === 'Enter') {
|
|
875
|
+
event.preventDefault();
|
|
876
|
+
saveKey();
|
|
877
|
+
}
|
|
878
|
+
} })] }), _jsx("div", { className: css.dialogHint, children: t('transcribeKeyHint') }), _jsxs("div", { className: css.keyRow, children: [_jsx("button", { type: "button", className: css.keySaveBtn, disabled: keyDraft === '' || keySaving, onClick: () => { saveKey(); }, children: keySaving ? t('transcribeKeySaving') : t('transcribeKeySave') }), _jsx("span", { className: keyConfigured === true ? css.keyBadgeOk : css.keyBadgeOff, children: keySaved
|
|
879
|
+
? t('transcribeKeySaved')
|
|
880
|
+
: keyConfigured === true ? t('transcribeKeyConfigured') : t('transcribeKeyMissing') })] }), keyError !== null && _jsx("div", { className: css.keyError, children: keyError }), _jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("span", { children: t('transcribeModelLabel') }), _jsx("input", { className: css.resetSelect, type: "text", value: transcribe.model, onChange: (event) => { setTranscribeSettings({ ...transcribe, model: event.target.value }); } })] }), _jsx("div", { className: css.dialogHint, children: t('transcribeModelHint') })] }))] })), settingsTab === 'other' && (_jsxs(_Fragment, { children: [_jsxs("div", { className: css.dialogSection, children: [_jsxs("div", { className: css.checkUpdatesRow, children: [_jsxs("label", { className: css.checkUpdatesLabel, children: [_jsx("input", { type: "checkbox", checked: checkUpdates, onChange: (event) => { setCheckUpdates(event.target.checked); } }), _jsx("span", { children: t('checkUpdatesLabel') })] }), _jsx("button", { type: "button", className: css.checkBtn, disabled: checkingUpdates, onClick: checkUpdatesNow, children: checkingUpdates
|
|
822
881
|
? t('checkingUpdates')
|
|
823
882
|
: lastCheckResult === 'up-to-date'
|
|
824
883
|
? t('checkUpToDate')
|
|
@@ -12,7 +12,7 @@ const TOKEN_QUOTA_NAMESPACE = 'token-quota';
|
|
|
12
12
|
/** Snapshot pull cadence in milliseconds. */
|
|
13
13
|
const POLL_INTERVAL_MS = 3000;
|
|
14
14
|
/** Required services: slot registry, sessions, locale, settings scope, and the Host remote faces. */
|
|
15
|
-
export const inject = ['slots', 'sessions', 'locale', 'settingsScope', 'remote', 'remote.session'];
|
|
15
|
+
export const inject = ['slots', 'sessions', 'locale', 'settingsScope', 'remote', 'remote.session', 'remote.credentials'];
|
|
16
16
|
/**
|
|
17
17
|
* Client plugin body: poll the Host snapshot route, run the full-quota
|
|
18
18
|
* strategy, wire the injected face (directory load, limit write, model
|
|
@@ -129,6 +129,28 @@ export function apply(ctx) {
|
|
|
129
129
|
apiKeyEnv: typeof raw?.apiKeyEnv === 'string' && raw.apiKeyEnv !== '' ? raw.apiKeyEnv : TOKEN_QUOTA_DEFAULT_TRANSCRIBE.apiKeyEnv,
|
|
130
130
|
model: typeof raw?.model === 'string' && raw.model !== '' ? raw.model : TOKEN_QUOTA_DEFAULT_TRANSCRIBE.model,
|
|
131
131
|
});
|
|
132
|
+
// --- Transcription settings source (independent of the panel store, so the
|
|
133
|
+
// mic entry — mounted in the session-scoped conversation.input.overlay
|
|
134
|
+
// slot — can subscribe without sharing the panel's root-scoped store
|
|
135
|
+
// instance (which would fork state across scopes). ---
|
|
136
|
+
let currentTranscribe = TOKEN_QUOTA_DEFAULT_TRANSCRIBE;
|
|
137
|
+
const transcribeSubscribers = new Set();
|
|
138
|
+
const emitTranscribe = () => { for (const fn of transcribeSubscribers)
|
|
139
|
+
fn(); };
|
|
140
|
+
const subscribeTranscribe = (cb) => {
|
|
141
|
+
transcribeSubscribers.add(cb);
|
|
142
|
+
return () => { transcribeSubscribers.delete(cb); };
|
|
143
|
+
};
|
|
144
|
+
const getTranscribe = () => currentTranscribe;
|
|
145
|
+
const applyTranscribe = (settings) => {
|
|
146
|
+
if (settings.enabled === currentTranscribe.enabled
|
|
147
|
+
&& settings.baseURL === currentTranscribe.baseURL
|
|
148
|
+
&& settings.apiKeyEnv === currentTranscribe.apiKeyEnv
|
|
149
|
+
&& settings.model === currentTranscribe.model)
|
|
150
|
+
return;
|
|
151
|
+
currentTranscribe = settings;
|
|
152
|
+
emitTranscribe();
|
|
153
|
+
};
|
|
132
154
|
const keyOf = (selection) => {
|
|
133
155
|
if (selection === null)
|
|
134
156
|
return undefined;
|
|
@@ -391,33 +413,41 @@ export function apply(ctx) {
|
|
|
391
413
|
void scope.set('balance', { enabled, pollMinutes });
|
|
392
414
|
};
|
|
393
415
|
/** Persist the voice transcription settings and mirror them into the store. */
|
|
394
|
-
// --- Transcription settings source (independent of the panel store, so the
|
|
395
|
-
// mic entry — mounted in the session-scoped conversation.input.overlay
|
|
396
|
-
// slot — can subscribe without sharing the panel's root-scoped store
|
|
397
|
-
// instance (which would fork state across scopes). ---
|
|
398
|
-
let currentTranscribe = TOKEN_QUOTA_DEFAULT_TRANSCRIBE;
|
|
399
|
-
const transcribeSubscribers = new Set();
|
|
400
|
-
const emitTranscribe = () => { for (const fn of transcribeSubscribers)
|
|
401
|
-
fn(); };
|
|
402
|
-
const subscribeTranscribe = (cb) => {
|
|
403
|
-
transcribeSubscribers.add(cb);
|
|
404
|
-
return () => { transcribeSubscribers.delete(cb); };
|
|
405
|
-
};
|
|
406
|
-
const getTranscribe = () => currentTranscribe;
|
|
407
|
-
const applyTranscribe = (settings) => {
|
|
408
|
-
if (settings.enabled === currentTranscribe.enabled
|
|
409
|
-
&& settings.baseURL === currentTranscribe.baseURL
|
|
410
|
-
&& settings.apiKeyEnv === currentTranscribe.apiKeyEnv
|
|
411
|
-
&& settings.model === currentTranscribe.model)
|
|
412
|
-
return;
|
|
413
|
-
currentTranscribe = settings;
|
|
414
|
-
emitTranscribe();
|
|
415
|
-
};
|
|
416
416
|
const setTranscribeSettings = (settings) => {
|
|
417
417
|
applyTranscribe(settings);
|
|
418
418
|
bound?.setTranscribeSettings(settings);
|
|
419
419
|
void scope.set('transcribe', settings);
|
|
420
420
|
};
|
|
421
|
+
/**
|
|
422
|
+
* Read whether the transcription credential reference currently holds a key,
|
|
423
|
+
* so the settings page can show 已配置 / 未配置 without ever reading the
|
|
424
|
+
* secret back (the wire carries it in one direction only).
|
|
425
|
+
*/
|
|
426
|
+
const checkTranscribeKey = async (ref) => {
|
|
427
|
+
try {
|
|
428
|
+
const result = await ctx.remote.credentials.describe([ref]);
|
|
429
|
+
if (!result.ok)
|
|
430
|
+
return false;
|
|
431
|
+
return result.value[ref]?.configured === true;
|
|
432
|
+
}
|
|
433
|
+
catch {
|
|
434
|
+
return false;
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
/**
|
|
438
|
+
* Store the transcription API key through the credential seam, so it lives
|
|
439
|
+
* in the same credential store the Host resolves from — the user never has
|
|
440
|
+
* to edit a file by hand.
|
|
441
|
+
*/
|
|
442
|
+
const saveTranscribeKey = async (ref, value) => {
|
|
443
|
+
try {
|
|
444
|
+
await ctx.remote.credentials.set(ref, value);
|
|
445
|
+
return { ok: true };
|
|
446
|
+
}
|
|
447
|
+
catch (error) {
|
|
448
|
+
return { ok: false, error: error instanceof Error ? error.message : String(error) };
|
|
449
|
+
}
|
|
450
|
+
};
|
|
421
451
|
/**
|
|
422
452
|
* Send a recorded audio blob to the Host, which forwards it to the
|
|
423
453
|
* configured OpenAI-compatible transcription endpoint. Resolves with the
|
|
@@ -572,7 +602,7 @@ export function apply(ctx) {
|
|
|
572
602
|
setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle,
|
|
573
603
|
setMusicEnabled, setMusicVolume, setMusicStyle, setMusicOnlyCurrentSession,
|
|
574
604
|
setModelOrder, saveNotes, setBalanceSettings, refreshBalance,
|
|
575
|
-
setTranscribeSettings,
|
|
605
|
+
setTranscribeSettings, checkTranscribeKey, saveTranscribeKey,
|
|
576
606
|
};
|
|
577
607
|
};
|
|
578
608
|
ctx.slots.inject('shell.overlay', () => ctx.slots.register({
|
|
@@ -39,6 +39,16 @@ export declare const zh: {
|
|
|
39
39
|
transcribeBaseURLHint: string;
|
|
40
40
|
transcribeApiKeyEnvLabel: string;
|
|
41
41
|
transcribeApiKeyEnvHint: string;
|
|
42
|
+
transcribeKeyLabel: string;
|
|
43
|
+
transcribeKeyHint: string;
|
|
44
|
+
transcribeKeyPlaceholder: string;
|
|
45
|
+
transcribeKeyPlaceholderSet: string;
|
|
46
|
+
transcribeKeySave: string;
|
|
47
|
+
transcribeKeySaving: string;
|
|
48
|
+
transcribeKeySaved: string;
|
|
49
|
+
transcribeKeyConfigured: string;
|
|
50
|
+
transcribeKeyMissing: string;
|
|
51
|
+
transcribeKeyFailed: string;
|
|
42
52
|
transcribeModelLabel: string;
|
|
43
53
|
transcribeModelHint: string;
|
|
44
54
|
reorderHint: string;
|
|
@@ -170,6 +180,16 @@ export declare const en: {
|
|
|
170
180
|
transcribeBaseURLHint: string;
|
|
171
181
|
transcribeApiKeyEnvLabel: string;
|
|
172
182
|
transcribeApiKeyEnvHint: string;
|
|
183
|
+
transcribeKeyLabel: string;
|
|
184
|
+
transcribeKeyHint: string;
|
|
185
|
+
transcribeKeyPlaceholder: string;
|
|
186
|
+
transcribeKeyPlaceholderSet: string;
|
|
187
|
+
transcribeKeySave: string;
|
|
188
|
+
transcribeKeySaving: string;
|
|
189
|
+
transcribeKeySaved: string;
|
|
190
|
+
transcribeKeyConfigured: string;
|
|
191
|
+
transcribeKeyMissing: string;
|
|
192
|
+
transcribeKeyFailed: string;
|
|
173
193
|
transcribeModelLabel: string;
|
|
174
194
|
transcribeModelHint: string;
|
|
175
195
|
reorderHint: string;
|
|
@@ -37,8 +37,18 @@ export const zh = {
|
|
|
37
37
|
transcribeEnabledHint: '在对话框右上角显示麦克风按钮',
|
|
38
38
|
transcribeBaseURLLabel: '接口地址',
|
|
39
39
|
transcribeBaseURLHint: 'OpenAI 兼容的转录接口 base URL',
|
|
40
|
-
transcribeApiKeyEnvLabel: '
|
|
41
|
-
transcribeApiKeyEnvHint: '
|
|
40
|
+
transcribeApiKeyEnvLabel: '凭证名称',
|
|
41
|
+
transcribeApiKeyEnvHint: '密钥在凭证库中保存的名称,一般无需修改',
|
|
42
|
+
transcribeKeyLabel: 'API Key',
|
|
43
|
+
transcribeKeyHint: '在此填入密钥并点「保存」,密钥会写入 DSH 凭证库(保存后不会回显)',
|
|
44
|
+
transcribeKeyPlaceholder: '粘贴 API Key',
|
|
45
|
+
transcribeKeyPlaceholderSet: '已配置,填入新值可覆盖',
|
|
46
|
+
transcribeKeySave: '保存',
|
|
47
|
+
transcribeKeySaving: '保存中…',
|
|
48
|
+
transcribeKeySaved: '已保存',
|
|
49
|
+
transcribeKeyConfigured: '已配置',
|
|
50
|
+
transcribeKeyMissing: '未配置',
|
|
51
|
+
transcribeKeyFailed: '保存失败',
|
|
42
52
|
transcribeModelLabel: '模型',
|
|
43
53
|
transcribeModelHint: '语音转文本模型名',
|
|
44
54
|
reorderHint: '拖动排序',
|
|
@@ -166,8 +176,18 @@ export const en = {
|
|
|
166
176
|
transcribeEnabledHint: 'Show a mic button in the top-right of the composer',
|
|
167
177
|
transcribeBaseURLLabel: 'Base URL',
|
|
168
178
|
transcribeBaseURLHint: 'OpenAI-compatible transcription endpoint base URL',
|
|
169
|
-
transcribeApiKeyEnvLabel: '
|
|
170
|
-
transcribeApiKeyEnvHint: '
|
|
179
|
+
transcribeApiKeyEnvLabel: 'Credential name',
|
|
180
|
+
transcribeApiKeyEnvHint: 'Name the key is stored under in the credential store; usually unchanged',
|
|
181
|
+
transcribeKeyLabel: 'API key',
|
|
182
|
+
transcribeKeyHint: 'Paste the key here and press Save — it is written to the DSH credential store and never read back',
|
|
183
|
+
transcribeKeyPlaceholder: 'Paste API key',
|
|
184
|
+
transcribeKeyPlaceholderSet: 'Configured — enter a new value to replace',
|
|
185
|
+
transcribeKeySave: 'Save',
|
|
186
|
+
transcribeKeySaving: 'Saving…',
|
|
187
|
+
transcribeKeySaved: 'Saved',
|
|
188
|
+
transcribeKeyConfigured: 'Configured',
|
|
189
|
+
transcribeKeyMissing: 'Not configured',
|
|
190
|
+
transcribeKeyFailed: 'Save failed',
|
|
171
191
|
transcribeModelLabel: 'Model',
|
|
172
192
|
transcribeModelHint: 'Speech-to-text model name',
|
|
173
193
|
reorderHint: 'Drag to reorder',
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jxgame2020/dsh-token-quota",
|
|
3
3
|
"description": "Daily per-model token quota accounting, enforcement, and a floating quota panel for the DeepSeek Harness — a fully self-contained plugin (no core-Harness wiring, no generated RPC contract)",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.44",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -43,7 +43,8 @@
|
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"bundle": "tsdown",
|
|
46
|
-
"watch": "tsdown --watch"
|
|
46
|
+
"watch": "tsdown --watch",
|
|
47
|
+
"smoke": "node tools/smoke-client.mjs"
|
|
47
48
|
},
|
|
48
49
|
"files": [
|
|
49
50
|
"lib/index.js",
|
|
@@ -168,4 +169,4 @@
|
|
|
168
169
|
"optional": true
|
|
169
170
|
}
|
|
170
171
|
}
|
|
171
|
-
}
|
|
172
|
+
}
|