@jxgame2020/dsh-token-quota 0.1.28 → 0.1.30
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 +288 -221
- package/lib/index.js +1 -1
- package/lib/types/client/TokenQuotaPanel.js +37 -35
- package/lib/types/client/index.js +5 -0
- package/lib/types/client/locales.d.ts +8 -0
- package/lib/types/client/locales.js +10 -2
- package/lib/types/client/music.d.ts +13 -0
- package/lib/types/client/music.js +64 -21
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -95,7 +95,7 @@ window.__ModuleLoader__.load({
|
|
|
95
95
|
d.musicOnlyCurrentSession = only;
|
|
96
96
|
},
|
|
97
97
|
setUpgrade: (d, upgrade) => {
|
|
98
|
-
const normalized = upgrade !== null && upgrade.latestVersion !== "" && upgrade.latestVersion !== "0.1.
|
|
98
|
+
const normalized = upgrade !== null && upgrade.latestVersion !== "" && upgrade.latestVersion !== "0.1.30" ? upgrade : null;
|
|
99
99
|
if (d.upgrade === null || d.upgrade.latestVersion !== normalized?.latestVersion) d.upgradeDismissed = false;
|
|
100
100
|
d.upgrade = normalized;
|
|
101
101
|
},
|
|
@@ -191,7 +191,7 @@ window.__ModuleLoader__.load({
|
|
|
191
191
|
}
|
|
192
192
|
//#endregion
|
|
193
193
|
//#region \0dsh-css:/Users/jxgame/Desktop/works/deepseek-harness-package/dsh-token-quota/packages/token-quota/src/client/TokenQuotaPanel.module.css.mjs
|
|
194
|
-
const css = ".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;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_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_rowName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;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_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)}.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;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:280px;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_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;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}";
|
|
194
|
+
const css = ".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;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_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_rowName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;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_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;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_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;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}";
|
|
195
195
|
const tagId = "@jxgame2020/dsh-token-quota/TokenQuotaPanel.module.css";
|
|
196
196
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
197
197
|
const tag = document.createElement("style");
|
|
@@ -201,92 +201,95 @@ window.__ModuleLoader__.load({
|
|
|
201
201
|
document.head.appendChild(tag);
|
|
202
202
|
}
|
|
203
203
|
var TokenQuotaPanel_module_css_default = {
|
|
204
|
+
"controls": "NPLLIq_controls",
|
|
205
|
+
"logHeader": "NPLLIq_logHeader",
|
|
206
|
+
"logModelCol": "NPLLIq_logModelCol",
|
|
204
207
|
"gearBtn": "NPLLIq_gearBtn",
|
|
205
|
-
"
|
|
206
|
-
"
|
|
207
|
-
"
|
|
208
|
+
"monitorHint": "NPLLIq_monitorHint",
|
|
209
|
+
"bar": "NPLLIq_bar",
|
|
210
|
+
"resetSelect": "NPLLIq_resetSelect",
|
|
211
|
+
"dialogTab": "NPLLIq_dialogTab",
|
|
212
|
+
"dialogTabActive": "NPLLIq_dialogTabActive",
|
|
213
|
+
"logPagerInfo": "NPLLIq_logPagerInfo",
|
|
214
|
+
"radioRow": "NPLLIq_radioRow",
|
|
215
|
+
"header": "NPLLIq_header",
|
|
216
|
+
"rowHeader": "NPLLIq_rowHeader",
|
|
217
|
+
"input": "NPLLIq_input",
|
|
218
|
+
"settingsBtnActive": "NPLLIq_settingsBtnActive",
|
|
219
|
+
"settingsBtn": "NPLLIq_settingsBtn",
|
|
220
|
+
"subtitle": "NPLLIq_subtitle",
|
|
221
|
+
"copyBtnDone": "NPLLIq_copyBtnDone",
|
|
222
|
+
"checkBtn": "NPLLIq_checkBtn",
|
|
208
223
|
"dialogTitle": "NPLLIq_dialogTitle",
|
|
224
|
+
"monitorRow": "NPLLIq_monitorRow",
|
|
225
|
+
"logScroll": "NPLLIq_logScroll",
|
|
226
|
+
"dialogTabs": "NPLLIq_dialogTabs",
|
|
227
|
+
"logPageSizeSelect": "NPLLIq_logPageSizeSelect",
|
|
228
|
+
"checkErrorHint": "NPLLIq_checkErrorHint",
|
|
229
|
+
"logClearDate": "NPLLIq_logClearDate",
|
|
230
|
+
"dialogBtn": "NPLLIq_dialogBtn",
|
|
231
|
+
"upgradeCommand": "NPLLIq_upgradeCommand",
|
|
209
232
|
"logDayCol": "NPLLIq_logDayCol",
|
|
233
|
+
"resetRow": "NPLLIq_resetRow",
|
|
234
|
+
"logPager": "NPLLIq_logPager",
|
|
235
|
+
"collapse": "NPLLIq_collapse",
|
|
236
|
+
"upgradeHint": "NPLLIq_upgradeHint",
|
|
237
|
+
"logClearBtn": "NPLLIq_logClearBtn",
|
|
238
|
+
"version": "NPLLIq_version",
|
|
239
|
+
"upgradeCommands": "NPLLIq_upgradeCommands",
|
|
240
|
+
"notice": "NPLLIq_notice",
|
|
210
241
|
"upgradeBannerText": "NPLLIq_upgradeBannerText",
|
|
211
|
-
"
|
|
212
|
-
"monitorHint": "NPLLIq_monitorHint",
|
|
242
|
+
"monitorList": "NPLLIq_monitorList",
|
|
213
243
|
"logClearDialog": "NPLLIq_logClearDialog",
|
|
244
|
+
"headerText": "NPLLIq_headerText",
|
|
245
|
+
"fullNotice": "NPLLIq_fullNotice",
|
|
246
|
+
"dialogActions": "NPLLIq_dialogActions",
|
|
247
|
+
"row": "NPLLIq_row",
|
|
248
|
+
"dialogHeader": "NPLLIq_dialogHeader",
|
|
249
|
+
"title": "NPLLIq_title",
|
|
250
|
+
"selectBtn": "NPLLIq_selectBtn",
|
|
251
|
+
"tabIcon": "NPLLIq_tabIcon",
|
|
252
|
+
"fillWarn": "NPLLIq_fillWarn",
|
|
253
|
+
"checkUpdatesLabel": "NPLLIq_checkUpdatesLabel",
|
|
254
|
+
"dialogLabel": "NPLLIq_dialogLabel",
|
|
255
|
+
"panelDimStrong": "NPLLIq_panelDimStrong",
|
|
214
256
|
"dialogClose": "NPLLIq_dialogClose",
|
|
215
|
-
"
|
|
257
|
+
"switch": "NPLLIq_switch",
|
|
258
|
+
"logToolbar": "NPLLIq_logToolbar",
|
|
216
259
|
"dialog": "NPLLIq_dialog",
|
|
217
|
-
"
|
|
218
|
-
"
|
|
260
|
+
"tabLabel": "NPLLIq_tabLabel",
|
|
261
|
+
"currentBadge": "NPLLIq_currentBadge",
|
|
262
|
+
"copyBtn": "NPLLIq_copyBtn",
|
|
263
|
+
"logDialog": "NPLLIq_logDialog",
|
|
219
264
|
"logSearch": "NPLLIq_logSearch",
|
|
220
|
-
"
|
|
265
|
+
"dialogOverlay": "NPLLIq_dialogOverlay",
|
|
266
|
+
"noticeError": "NPLLIq_noticeError",
|
|
267
|
+
"headerActions": "NPLLIq_headerActions",
|
|
221
268
|
"panelDim": "NPLLIq_panelDim",
|
|
222
|
-
"
|
|
223
|
-
"rowHeader": "NPLLIq_rowHeader",
|
|
224
|
-
"checkBtn": "NPLLIq_checkBtn",
|
|
225
|
-
"dialogHint": "NPLLIq_dialogHint",
|
|
226
|
-
"logPagerInfo": "NPLLIq_logPagerInfo",
|
|
227
|
-
"logModelCol": "NPLLIq_logModelCol",
|
|
228
|
-
"upgradeClose": "NPLLIq_upgradeClose",
|
|
229
|
-
"resetRow": "NPLLIq_resetRow",
|
|
230
|
-
"dialogActions": "NPLLIq_dialogActions",
|
|
269
|
+
"tab": "NPLLIq_tab",
|
|
231
270
|
"upgradeCommandRow": "NPLLIq_upgradeCommandRow",
|
|
232
|
-
"
|
|
233
|
-
"
|
|
234
|
-
"
|
|
235
|
-
"logScroll": "NPLLIq_logScroll",
|
|
271
|
+
"checkUpdatesRow": "NPLLIq_checkUpdatesRow",
|
|
272
|
+
"dialogHint": "NPLLIq_dialogHint",
|
|
273
|
+
"logPagerPages": "NPLLIq_logPagerPages",
|
|
236
274
|
"versionNew": "NPLLIq_versionNew",
|
|
237
|
-
"
|
|
238
|
-
"
|
|
239
|
-
"logPageSizeSelect": "NPLLIq_logPageSizeSelect",
|
|
240
|
-
"monitorRow": "NPLLIq_monitorRow",
|
|
275
|
+
"body": "NPLLIq_body",
|
|
276
|
+
"rowMeta": "NPLLIq_rowMeta",
|
|
241
277
|
"dialogSection": "NPLLIq_dialogSection",
|
|
242
278
|
"logUsedCol": "NPLLIq_logUsedCol",
|
|
243
|
-
"subtitle": "NPLLIq_subtitle",
|
|
244
|
-
"tabLabel": "NPLLIq_tabLabel",
|
|
245
|
-
"dialogLabel": "NPLLIq_dialogLabel",
|
|
246
|
-
"row": "NPLLIq_row",
|
|
247
|
-
"dialogBtn": "NPLLIq_dialogBtn",
|
|
248
|
-
"dialogBody": "NPLLIq_dialogBody",
|
|
249
|
-
"version": "NPLLIq_version",
|
|
250
|
-
"checkUpdatesLabel": "NPLLIq_checkUpdatesLabel",
|
|
251
|
-
"copyBtnDone": "NPLLIq_copyBtnDone",
|
|
252
|
-
"logHeader": "NPLLIq_logHeader",
|
|
253
|
-
"headerText": "NPLLIq_headerText",
|
|
254
|
-
"fillWarn": "NPLLIq_fillWarn",
|
|
255
|
-
"upgradeBannerFlash": "NPLLIq_upgradeBannerFlash",
|
|
256
|
-
"fullNotice": "NPLLIq_fullNotice",
|
|
257
|
-
"upgradeCommand": "NPLLIq_upgradeCommand",
|
|
258
|
-
"dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
|
|
259
|
-
"logPagerPages": "NPLLIq_logPagerPages",
|
|
260
|
-
"upgradeCommands": "NPLLIq_upgradeCommands",
|
|
261
|
-
"save": "NPLLIq_save",
|
|
262
|
-
"logClearDate": "NPLLIq_logClearDate",
|
|
263
|
-
"settingsBtn": "NPLLIq_settingsBtn",
|
|
264
|
-
"logPager": "NPLLIq_logPager",
|
|
265
|
-
"dialogOverlay": "NPLLIq_dialogOverlay",
|
|
266
|
-
"logDialog": "NPLLIq_logDialog",
|
|
267
|
-
"headerActions": "NPLLIq_headerActions",
|
|
268
|
-
"monitorList": "NPLLIq_monitorList",
|
|
269
|
-
"bar": "NPLLIq_bar",
|
|
270
|
-
"input": "NPLLIq_input",
|
|
271
|
-
"noticeError": "NPLLIq_noticeError",
|
|
272
|
-
"fillIdle": "NPLLIq_fillIdle",
|
|
273
|
-
"copyBtn": "NPLLIq_copyBtn",
|
|
274
279
|
"logPagerControls": "NPLLIq_logPagerControls",
|
|
280
|
+
"fillIdle": "NPLLIq_fillIdle",
|
|
281
|
+
"save": "NPLLIq_save",
|
|
282
|
+
"upgradeBanner": "NPLLIq_upgradeBanner",
|
|
275
283
|
"logPagerBtn": "NPLLIq_logPagerBtn",
|
|
276
|
-
"
|
|
284
|
+
"monitorName": "NPLLIq_monitorName",
|
|
277
285
|
"rowName": "NPLLIq_rowName",
|
|
278
|
-
"
|
|
279
|
-
"resetSelect": "NPLLIq_resetSelect",
|
|
280
|
-
"tab": "NPLLIq_tab",
|
|
281
|
-
"notice": "NPLLIq_notice",
|
|
282
|
-
"body": "NPLLIq_body",
|
|
283
|
-
"tabIcon": "NPLLIq_tabIcon",
|
|
284
|
-
"panelDimStrong": "NPLLIq_panelDimStrong",
|
|
285
|
-
"switch": "NPLLIq_switch",
|
|
286
|
-
"settingsBtnActive": "NPLLIq_settingsBtnActive",
|
|
286
|
+
"upgradeBannerFlash": "NPLLIq_upgradeBannerFlash",
|
|
287
287
|
"panel": "NPLLIq_panel",
|
|
288
|
-
"
|
|
289
|
-
"
|
|
288
|
+
"dialogBody": "NPLLIq_dialogBody",
|
|
289
|
+
"fillOver": "NPLLIq_fillOver",
|
|
290
|
+
"dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
|
|
291
|
+
"logTable": "NPLLIq_logTable",
|
|
292
|
+
"upgradeClose": "NPLLIq_upgradeClose"
|
|
290
293
|
};
|
|
291
294
|
//#endregion
|
|
292
295
|
//#region lib/types/client/TokenQuotaPanel.js
|
|
@@ -379,6 +382,7 @@ window.__ModuleLoader__.load({
|
|
|
379
382
|
const [editingKey, setEditingKey] = (0, react.useState)(null);
|
|
380
383
|
const [hovered, setHovered] = (0, react.useState)(false);
|
|
381
384
|
const [inputActive, setInputActive] = (0, react.useState)(false);
|
|
385
|
+
const [settingsTab, setSettingsTab] = (0, react.useState)("quota");
|
|
382
386
|
const [copiedCmd, setCopiedCmd] = (0, react.useState)(null);
|
|
383
387
|
const copyTimerRef = (0, react.useRef)(null);
|
|
384
388
|
const [upgradeFlash, setUpgradeFlash] = (0, react.useState)(false);
|
|
@@ -592,13 +596,13 @@ window.__ModuleLoader__.load({
|
|
|
592
596
|
title: t("upgradeAvailableHint"),
|
|
593
597
|
children: [
|
|
594
598
|
"v",
|
|
595
|
-
"0.1.
|
|
599
|
+
"0.1.30",
|
|
596
600
|
" → v",
|
|
597
601
|
upgrade.latestVersion
|
|
598
602
|
]
|
|
599
603
|
}) : (0, react_jsx_runtime.jsxs)("span", {
|
|
600
604
|
className: TokenQuotaPanel_module_css_default.version,
|
|
601
|
-
children: ["v", "0.1.
|
|
605
|
+
children: ["v", "0.1.30"]
|
|
602
606
|
})]
|
|
603
607
|
}), (0, react_jsx_runtime.jsx)("div", {
|
|
604
608
|
className: TokenQuotaPanel_module_css_default.subtitle,
|
|
@@ -612,12 +616,13 @@ window.__ModuleLoader__.load({
|
|
|
612
616
|
children: [
|
|
613
617
|
(0, react_jsx_runtime.jsx)("button", {
|
|
614
618
|
type: "button",
|
|
619
|
+
"aria-pressed": musicEnabled,
|
|
615
620
|
className: `${TokenQuotaPanel_module_css_default.settingsBtn}${musicEnabled ? ` ${TokenQuotaPanel_module_css_default.settingsBtnActive}` : ""}`,
|
|
616
|
-
title: t("
|
|
621
|
+
title: `${t("musicLabel")}:${musicEnabled ? t("musicOn") : t("musicOff")}`,
|
|
617
622
|
onClick: () => {
|
|
618
623
|
setMusicEnabled(!musicEnabled);
|
|
619
624
|
},
|
|
620
|
-
children:
|
|
625
|
+
children: "♪"
|
|
621
626
|
}),
|
|
622
627
|
(0, react_jsx_runtime.jsx)("button", {
|
|
623
628
|
type: "button",
|
|
@@ -815,136 +820,161 @@ window.__ModuleLoader__.load({
|
|
|
815
820
|
})]
|
|
816
821
|
}),
|
|
817
822
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
818
|
-
className: TokenQuotaPanel_module_css_default.
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
if (event.target.checked) next.add(model.key);
|
|
839
|
-
else next.delete(model.key);
|
|
840
|
-
setMonitored(next.size === allModels.length ? null : [...next]);
|
|
841
|
-
}
|
|
842
|
-
}), (0, react_jsx_runtime.jsx)("span", {
|
|
843
|
-
className: TokenQuotaPanel_module_css_default.monitorName,
|
|
844
|
-
title: model.key,
|
|
845
|
-
children: model.name
|
|
846
|
-
})]
|
|
847
|
-
}, model.key))
|
|
848
|
-
})
|
|
849
|
-
]
|
|
850
|
-
}),
|
|
851
|
-
(0, react_jsx_runtime.jsxs)("div", {
|
|
852
|
-
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
853
|
-
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
854
|
-
className: TokenQuotaPanel_module_css_default.dialogLabel,
|
|
855
|
-
children: t("fullActionLabel")
|
|
856
|
-
}), FULL_ACTIONS.map((action) => (0, react_jsx_runtime.jsxs)("label", {
|
|
857
|
-
className: TokenQuotaPanel_module_css_default.radioRow,
|
|
858
|
-
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
859
|
-
type: "radio",
|
|
860
|
-
name: "token-quota-onfull",
|
|
861
|
-
checked: onFull === action.value,
|
|
862
|
-
onChange: () => {
|
|
863
|
-
setOnFull(action.value);
|
|
864
|
-
}
|
|
865
|
-
}), (0, react_jsx_runtime.jsx)("span", { children: t(action.labelKey) })]
|
|
866
|
-
}, action.value))]
|
|
867
|
-
}),
|
|
868
|
-
(0, react_jsx_runtime.jsxs)("div", {
|
|
869
|
-
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
870
|
-
children: [
|
|
871
|
-
(0, react_jsx_runtime.jsx)("div", {
|
|
872
|
-
className: TokenQuotaPanel_module_css_default.dialogLabel,
|
|
873
|
-
children: t("resetLabel")
|
|
874
|
-
}),
|
|
875
|
-
(0, react_jsx_runtime.jsx)("div", {
|
|
876
|
-
className: TokenQuotaPanel_module_css_default.monitorHint,
|
|
877
|
-
children: t("resetHint")
|
|
878
|
-
}),
|
|
879
|
-
(0, react_jsx_runtime.jsxs)("div", {
|
|
880
|
-
className: TokenQuotaPanel_module_css_default.resetRow,
|
|
881
|
-
children: [
|
|
882
|
-
(0, react_jsx_runtime.jsx)("select", {
|
|
883
|
-
className: TokenQuotaPanel_module_css_default.resetSelect,
|
|
884
|
-
value: reset?.offsetHours ?? -(/* @__PURE__ */ new Date()).getTimezoneOffset() / 60,
|
|
885
|
-
onChange: (event) => {
|
|
886
|
-
setReset({
|
|
887
|
-
offsetHours: Number(event.target.value),
|
|
888
|
-
hour: reset?.hour ?? 0,
|
|
889
|
-
minute: reset?.minute ?? 0
|
|
890
|
-
});
|
|
891
|
-
},
|
|
892
|
-
children: Array.from({ length: 27 }, (_, i) => i - 12).map((offset) => (0, react_jsx_runtime.jsxs)("option", {
|
|
893
|
-
value: offset,
|
|
894
|
-
children: ["UTC", offset >= 0 ? `+${offset}` : offset]
|
|
895
|
-
}, offset))
|
|
896
|
-
}),
|
|
897
|
-
(0, react_jsx_runtime.jsx)("select", {
|
|
898
|
-
className: TokenQuotaPanel_module_css_default.resetSelect,
|
|
899
|
-
value: reset?.hour ?? 0,
|
|
900
|
-
onChange: (event) => {
|
|
901
|
-
setReset({
|
|
902
|
-
offsetHours: reset?.offsetHours ?? -(/* @__PURE__ */ new Date()).getTimezoneOffset() / 60,
|
|
903
|
-
hour: Number(event.target.value),
|
|
904
|
-
minute: reset?.minute ?? 0
|
|
905
|
-
});
|
|
906
|
-
},
|
|
907
|
-
children: Array.from({ length: 24 }, (_, i) => i).map((hour) => (0, react_jsx_runtime.jsxs)("option", {
|
|
908
|
-
value: hour,
|
|
909
|
-
children: [String(hour).padStart(2, "0"), " 时"]
|
|
910
|
-
}, hour))
|
|
911
|
-
}),
|
|
912
|
-
(0, react_jsx_runtime.jsx)("select", {
|
|
913
|
-
className: TokenQuotaPanel_module_css_default.resetSelect,
|
|
914
|
-
value: reset?.minute ?? 0,
|
|
915
|
-
onChange: (event) => {
|
|
916
|
-
setReset({
|
|
917
|
-
offsetHours: reset?.offsetHours ?? -(/* @__PURE__ */ new Date()).getTimezoneOffset() / 60,
|
|
918
|
-
hour: reset?.hour ?? 0,
|
|
919
|
-
minute: Number(event.target.value)
|
|
920
|
-
});
|
|
921
|
-
},
|
|
922
|
-
children: Array.from({ length: 12 }, (_, i) => i * 5).map((minute) => (0, react_jsx_runtime.jsxs)("option", {
|
|
923
|
-
value: minute,
|
|
924
|
-
children: [String(minute).padStart(2, "0"), " 分"]
|
|
925
|
-
}, minute))
|
|
926
|
-
})
|
|
927
|
-
]
|
|
928
|
-
})
|
|
929
|
-
]
|
|
930
|
-
}),
|
|
931
|
-
(0, react_jsx_runtime.jsxs)("div", {
|
|
932
|
-
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
933
|
-
children: [(0, react_jsx_runtime.jsxs)("label", {
|
|
934
|
-
className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
|
|
935
|
-
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
936
|
-
type: "checkbox",
|
|
937
|
-
checked: dimWhenIdle,
|
|
938
|
-
onChange: (event) => {
|
|
939
|
-
setDimWhenIdle(event.target.checked);
|
|
940
|
-
}
|
|
941
|
-
}), (0, react_jsx_runtime.jsx)("span", { children: t("dimWhenIdleLabel") })]
|
|
942
|
-
}), (0, react_jsx_runtime.jsx)("div", {
|
|
943
|
-
className: TokenQuotaPanel_module_css_default.dialogHint,
|
|
944
|
-
children: t("dimWhenIdleHint")
|
|
823
|
+
className: TokenQuotaPanel_module_css_default.dialogTabs,
|
|
824
|
+
role: "tablist",
|
|
825
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
826
|
+
type: "button",
|
|
827
|
+
role: "tab",
|
|
828
|
+
"aria-selected": settingsTab === "quota",
|
|
829
|
+
className: `${TokenQuotaPanel_module_css_default.dialogTab}${settingsTab === "quota" ? ` ${TokenQuotaPanel_module_css_default.dialogTabActive}` : ""}`,
|
|
830
|
+
onClick: () => {
|
|
831
|
+
setSettingsTab("quota");
|
|
832
|
+
},
|
|
833
|
+
children: t("settingsTabQuota")
|
|
834
|
+
}), (0, react_jsx_runtime.jsx)("button", {
|
|
835
|
+
type: "button",
|
|
836
|
+
role: "tab",
|
|
837
|
+
"aria-selected": settingsTab === "music",
|
|
838
|
+
className: `${TokenQuotaPanel_module_css_default.dialogTab}${settingsTab === "music" ? ` ${TokenQuotaPanel_module_css_default.dialogTabActive}` : ""}`,
|
|
839
|
+
onClick: () => {
|
|
840
|
+
setSettingsTab("music");
|
|
841
|
+
},
|
|
842
|
+
children: t("settingsTabMusic")
|
|
945
843
|
})]
|
|
946
844
|
}),
|
|
947
|
-
(0, react_jsx_runtime.jsxs)(
|
|
845
|
+
settingsTab === "quota" && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
846
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
847
|
+
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
848
|
+
children: [
|
|
849
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
850
|
+
className: TokenQuotaPanel_module_css_default.dialogLabel,
|
|
851
|
+
children: t("monitorLabel")
|
|
852
|
+
}),
|
|
853
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
854
|
+
className: TokenQuotaPanel_module_css_default.monitorHint,
|
|
855
|
+
children: t("monitorHint")
|
|
856
|
+
}),
|
|
857
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
858
|
+
className: TokenQuotaPanel_module_css_default.monitorList,
|
|
859
|
+
children: allModels.map((model) => (0, react_jsx_runtime.jsxs)("label", {
|
|
860
|
+
className: TokenQuotaPanel_module_css_default.monitorRow,
|
|
861
|
+
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
862
|
+
type: "checkbox",
|
|
863
|
+
checked: monitored === null || monitored.includes(model.key),
|
|
864
|
+
onChange: (event) => {
|
|
865
|
+
const base = monitored === null ? allModels.map((m) => m.key) : monitored;
|
|
866
|
+
const next = new Set(base);
|
|
867
|
+
if (event.target.checked) next.add(model.key);
|
|
868
|
+
else next.delete(model.key);
|
|
869
|
+
setMonitored(next.size === allModels.length ? null : [...next]);
|
|
870
|
+
}
|
|
871
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
872
|
+
className: TokenQuotaPanel_module_css_default.monitorName,
|
|
873
|
+
title: model.key,
|
|
874
|
+
children: model.name
|
|
875
|
+
})]
|
|
876
|
+
}, model.key))
|
|
877
|
+
})
|
|
878
|
+
]
|
|
879
|
+
}),
|
|
880
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
881
|
+
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
882
|
+
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
883
|
+
className: TokenQuotaPanel_module_css_default.dialogLabel,
|
|
884
|
+
children: t("fullActionLabel")
|
|
885
|
+
}), FULL_ACTIONS.map((action) => (0, react_jsx_runtime.jsxs)("label", {
|
|
886
|
+
className: TokenQuotaPanel_module_css_default.radioRow,
|
|
887
|
+
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
888
|
+
type: "radio",
|
|
889
|
+
name: "token-quota-onfull",
|
|
890
|
+
checked: onFull === action.value,
|
|
891
|
+
onChange: () => {
|
|
892
|
+
setOnFull(action.value);
|
|
893
|
+
}
|
|
894
|
+
}), (0, react_jsx_runtime.jsx)("span", { children: t(action.labelKey) })]
|
|
895
|
+
}, action.value))]
|
|
896
|
+
}),
|
|
897
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
898
|
+
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
899
|
+
children: [
|
|
900
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
901
|
+
className: TokenQuotaPanel_module_css_default.dialogLabel,
|
|
902
|
+
children: t("resetLabel")
|
|
903
|
+
}),
|
|
904
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
905
|
+
className: TokenQuotaPanel_module_css_default.monitorHint,
|
|
906
|
+
children: t("resetHint")
|
|
907
|
+
}),
|
|
908
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
909
|
+
className: TokenQuotaPanel_module_css_default.resetRow,
|
|
910
|
+
children: [
|
|
911
|
+
(0, react_jsx_runtime.jsx)("select", {
|
|
912
|
+
className: TokenQuotaPanel_module_css_default.resetSelect,
|
|
913
|
+
value: reset?.offsetHours ?? -(/* @__PURE__ */ new Date()).getTimezoneOffset() / 60,
|
|
914
|
+
onChange: (event) => {
|
|
915
|
+
setReset({
|
|
916
|
+
offsetHours: Number(event.target.value),
|
|
917
|
+
hour: reset?.hour ?? 0,
|
|
918
|
+
minute: reset?.minute ?? 0
|
|
919
|
+
});
|
|
920
|
+
},
|
|
921
|
+
children: Array.from({ length: 27 }, (_, i) => i - 12).map((offset) => (0, react_jsx_runtime.jsxs)("option", {
|
|
922
|
+
value: offset,
|
|
923
|
+
children: ["UTC", offset >= 0 ? `+${offset}` : offset]
|
|
924
|
+
}, offset))
|
|
925
|
+
}),
|
|
926
|
+
(0, react_jsx_runtime.jsx)("select", {
|
|
927
|
+
className: TokenQuotaPanel_module_css_default.resetSelect,
|
|
928
|
+
value: reset?.hour ?? 0,
|
|
929
|
+
onChange: (event) => {
|
|
930
|
+
setReset({
|
|
931
|
+
offsetHours: reset?.offsetHours ?? -(/* @__PURE__ */ new Date()).getTimezoneOffset() / 60,
|
|
932
|
+
hour: Number(event.target.value),
|
|
933
|
+
minute: reset?.minute ?? 0
|
|
934
|
+
});
|
|
935
|
+
},
|
|
936
|
+
children: Array.from({ length: 24 }, (_, i) => i).map((hour) => (0, react_jsx_runtime.jsxs)("option", {
|
|
937
|
+
value: hour,
|
|
938
|
+
children: [String(hour).padStart(2, "0"), " 时"]
|
|
939
|
+
}, hour))
|
|
940
|
+
}),
|
|
941
|
+
(0, react_jsx_runtime.jsx)("select", {
|
|
942
|
+
className: TokenQuotaPanel_module_css_default.resetSelect,
|
|
943
|
+
value: reset?.minute ?? 0,
|
|
944
|
+
onChange: (event) => {
|
|
945
|
+
setReset({
|
|
946
|
+
offsetHours: reset?.offsetHours ?? -(/* @__PURE__ */ new Date()).getTimezoneOffset() / 60,
|
|
947
|
+
hour: reset?.hour ?? 0,
|
|
948
|
+
minute: Number(event.target.value)
|
|
949
|
+
});
|
|
950
|
+
},
|
|
951
|
+
children: Array.from({ length: 12 }, (_, i) => i * 5).map((minute) => (0, react_jsx_runtime.jsxs)("option", {
|
|
952
|
+
value: minute,
|
|
953
|
+
children: [String(minute).padStart(2, "0"), " 分"]
|
|
954
|
+
}, minute))
|
|
955
|
+
})
|
|
956
|
+
]
|
|
957
|
+
})
|
|
958
|
+
]
|
|
959
|
+
}),
|
|
960
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
961
|
+
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
962
|
+
children: [(0, react_jsx_runtime.jsxs)("label", {
|
|
963
|
+
className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
|
|
964
|
+
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
965
|
+
type: "checkbox",
|
|
966
|
+
checked: dimWhenIdle,
|
|
967
|
+
onChange: (event) => {
|
|
968
|
+
setDimWhenIdle(event.target.checked);
|
|
969
|
+
}
|
|
970
|
+
}), (0, react_jsx_runtime.jsx)("span", { children: t("dimWhenIdleLabel") })]
|
|
971
|
+
}), (0, react_jsx_runtime.jsx)("div", {
|
|
972
|
+
className: TokenQuotaPanel_module_css_default.dialogHint,
|
|
973
|
+
children: t("dimWhenIdleHint")
|
|
974
|
+
})]
|
|
975
|
+
})
|
|
976
|
+
] }),
|
|
977
|
+
settingsTab === "music" && (0, react_jsx_runtime.jsxs)("div", {
|
|
948
978
|
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
949
979
|
children: [
|
|
950
980
|
(0, react_jsx_runtime.jsxs)("label", {
|
|
@@ -1015,7 +1045,7 @@ window.__ModuleLoader__.load({
|
|
|
1015
1045
|
] })
|
|
1016
1046
|
]
|
|
1017
1047
|
}),
|
|
1018
|
-
(0, react_jsx_runtime.jsxs)("div", {
|
|
1048
|
+
settingsTab === "quota" && (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: (0, react_jsx_runtime.jsxs)("div", {
|
|
1019
1049
|
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
1020
1050
|
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
1021
1051
|
className: TokenQuotaPanel_module_css_default.checkUpdatesRow,
|
|
@@ -1040,7 +1070,7 @@ window.__ModuleLoader__.load({
|
|
|
1040
1070
|
role: "alert",
|
|
1041
1071
|
children: upgradeError
|
|
1042
1072
|
})]
|
|
1043
|
-
})
|
|
1073
|
+
}) })
|
|
1044
1074
|
]
|
|
1045
1075
|
}),
|
|
1046
1076
|
logOpen && (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1495,6 +1525,8 @@ window.__ModuleLoader__.load({
|
|
|
1495
1525
|
phraseIndex = 0;
|
|
1496
1526
|
/** True when the next piece start should play the full intro glissando. */
|
|
1497
1527
|
introPending = true;
|
|
1528
|
+
/** Session the current piece belongs to (turn/start carries it). */
|
|
1529
|
+
sessionId;
|
|
1498
1530
|
phraseTimer;
|
|
1499
1531
|
lastStreamActivity = 0;
|
|
1500
1532
|
watchdogTimer;
|
|
@@ -1560,20 +1592,28 @@ window.__ModuleLoader__.load({
|
|
|
1560
1592
|
markStreamActivity() {
|
|
1561
1593
|
this.lastStreamActivity = Date.now();
|
|
1562
1594
|
}
|
|
1595
|
+
/** Stop any playing piece — e.g. when the panel switches sessions. */
|
|
1596
|
+
stop() {
|
|
1597
|
+
this.stopPiece(false);
|
|
1598
|
+
}
|
|
1563
1599
|
/** Handle one incoming host action and steer the piece. */
|
|
1564
1600
|
onAction(action) {
|
|
1565
1601
|
if (!this.enabled || this.audio === null) return;
|
|
1566
1602
|
const base = TokenQuotaMusic.BASE_MIDI;
|
|
1567
1603
|
switch (action.type) {
|
|
1568
1604
|
case "turn/start":
|
|
1569
|
-
this.stopPiece(false);
|
|
1605
|
+
if (this.sessionId !== void 0 && this.sessionId !== action.sessionId) this.stopPiece(false);
|
|
1606
|
+
this.sessionId = action.sessionId;
|
|
1607
|
+
this.stopMelody();
|
|
1608
|
+
this.playing = false;
|
|
1570
1609
|
this.tonicIndex = 0;
|
|
1571
1610
|
this.phraseIndex = 0;
|
|
1572
1611
|
this.introPending = true;
|
|
1612
|
+
this.startPiece();
|
|
1573
1613
|
break;
|
|
1574
1614
|
case "request/header":
|
|
1575
1615
|
if (!this.playing) this.startPiece();
|
|
1576
|
-
else this.pluck(
|
|
1616
|
+
else this.pluck(this.tone(5, 1), .3, .9);
|
|
1577
1617
|
break;
|
|
1578
1618
|
case "step/start": {
|
|
1579
1619
|
const prog = PROGRESSION[this.style];
|
|
@@ -1585,33 +1625,51 @@ window.__ModuleLoader__.load({
|
|
|
1585
1625
|
break;
|
|
1586
1626
|
}
|
|
1587
1627
|
case "tool/call":
|
|
1588
|
-
this.pluck(
|
|
1589
|
-
this.pluck(
|
|
1628
|
+
this.pluck(this.tone(4, 1), .38, .9);
|
|
1629
|
+
setTimeout(() => this.pluck(this.tone(5, 1), .34, .9), 90);
|
|
1630
|
+
this.pluck(this.tonicRoot - 12, .22, .9);
|
|
1590
1631
|
break;
|
|
1591
1632
|
case "tool/result":
|
|
1592
1633
|
if (action.error) {
|
|
1593
|
-
|
|
1594
|
-
|
|
1634
|
+
const t = this.tone(2, 1);
|
|
1635
|
+
this.pluck(t - 1, .4, .7);
|
|
1636
|
+
setTimeout(() => this.pluck(t - 3, .4, 1), 110);
|
|
1595
1637
|
} else {
|
|
1596
|
-
this.pluck(
|
|
1597
|
-
setTimeout(() => this.pluck(
|
|
1638
|
+
this.pluck(this.tone(3, 1), .34, 1);
|
|
1639
|
+
setTimeout(() => this.pluck(this.tone(1, 1), .32, 1), 90);
|
|
1640
|
+
setTimeout(() => this.pluck(this.tone(0, 1), .34, 1.2), 180);
|
|
1598
1641
|
}
|
|
1599
1642
|
break;
|
|
1600
1643
|
case "assistant/attempt":
|
|
1601
|
-
this.pluck(
|
|
1602
|
-
setTimeout(() => this.pluck(
|
|
1603
|
-
setTimeout(() => this.pluck(
|
|
1644
|
+
this.pluck(this.tone(4, 1), .36, .8);
|
|
1645
|
+
setTimeout(() => this.pluck(this.tone(2, 1), .36, .9), 110);
|
|
1646
|
+
setTimeout(() => this.pluck(this.tone(0), .36, 1.1), 220);
|
|
1604
1647
|
break;
|
|
1605
1648
|
case "assistant/message":
|
|
1606
|
-
this.
|
|
1607
|
-
this.
|
|
1608
|
-
this.breath(action.interrupted ? base + 6 : base + 12, 1.6);
|
|
1649
|
+
this.pluck(this.tone(2, 1), .3, 1);
|
|
1650
|
+
setTimeout(() => this.breath(this.tone(0, action.interrupted ? 0 : 1), 1.4), 140);
|
|
1609
1651
|
break;
|
|
1610
1652
|
case "turn/end":
|
|
1611
1653
|
this.stopPiece(true);
|
|
1612
1654
|
break;
|
|
1613
1655
|
}
|
|
1614
1656
|
}
|
|
1657
|
+
/** Current tonic root in MIDI note numbers. */
|
|
1658
|
+
get tonicRoot() {
|
|
1659
|
+
return TokenQuotaMusic.BASE_MIDI + (PROGRESSION[this.style][this.tonicIndex] ?? 0);
|
|
1660
|
+
}
|
|
1661
|
+
/**
|
|
1662
|
+
* A scale tone relative to the current tonic — degrees wrap up octaves
|
|
1663
|
+
* (deg 5 on a 5-note scale = the octave). Event figures use this so every
|
|
1664
|
+
* accent stays inside the key and melts into the piece instead of
|
|
1665
|
+
* clashing with it.
|
|
1666
|
+
*/
|
|
1667
|
+
tone(deg, oct = 0) {
|
|
1668
|
+
const scale = SCALES[this.style];
|
|
1669
|
+
const len = scale.length;
|
|
1670
|
+
const d = (deg % len + len) % len;
|
|
1671
|
+
return this.tonicRoot + 12 * (Math.floor(deg / len) + oct) + (scale[d] ?? 0);
|
|
1672
|
+
}
|
|
1615
1673
|
/** Start a new piece: intro run, then the phrase chain. */
|
|
1616
1674
|
startPiece() {
|
|
1617
1675
|
if (!this.audio || this.playing) return;
|
|
@@ -1843,7 +1901,9 @@ window.__ModuleLoader__.load({
|
|
|
1843
1901
|
expand: "展开",
|
|
1844
1902
|
expandHint: "展开每日 Token 限额面板",
|
|
1845
1903
|
settings: "设置",
|
|
1846
|
-
settingsTitle: "
|
|
1904
|
+
settingsTitle: "设置",
|
|
1905
|
+
settingsTabQuota: "限额设置",
|
|
1906
|
+
settingsTabMusic: "音乐设置",
|
|
1847
1907
|
monitorLabel: "监控模型",
|
|
1848
1908
|
monitorHint: "未勾选的模型不显示、不计入用量、不受限额限制",
|
|
1849
1909
|
monitorAll: "全部",
|
|
@@ -1887,6 +1947,8 @@ window.__ModuleLoader__.load({
|
|
|
1887
1947
|
dimWhenIdleHint: "鼠标移开面板时降低不透明度,输入文字时更透明;鼠标悬停恢复",
|
|
1888
1948
|
musicLabel: "动作音乐",
|
|
1889
1949
|
musicHint: "根据 Harness 动作实时作曲:请求开始、工具调用、回合结束等(需点击开关启动音频;检测到 MIDI 输出时同步发送 MIDI)",
|
|
1950
|
+
musicOn: "开",
|
|
1951
|
+
musicOff: "关",
|
|
1890
1952
|
musicVolume: "音量",
|
|
1891
1953
|
musicStyle: "风格",
|
|
1892
1954
|
musicStyleMajor: "大调",
|
|
@@ -1919,7 +1981,9 @@ window.__ModuleLoader__.load({
|
|
|
1919
1981
|
expand: "Expand",
|
|
1920
1982
|
expandHint: "Expand the daily token quota panel",
|
|
1921
1983
|
settings: "Settings",
|
|
1922
|
-
settingsTitle: "
|
|
1984
|
+
settingsTitle: "Settings",
|
|
1985
|
+
settingsTabQuota: "Quota",
|
|
1986
|
+
settingsTabMusic: "Music",
|
|
1923
1987
|
monitorLabel: "Monitored models",
|
|
1924
1988
|
monitorHint: "Unchecked models are hidden, not metered, and never capped",
|
|
1925
1989
|
monitorAll: "All",
|
|
@@ -1963,6 +2027,8 @@ window.__ModuleLoader__.load({
|
|
|
1963
2027
|
dimWhenIdleHint: "Fade the panel out when the pointer is away (more while typing); hover to restore",
|
|
1964
2028
|
musicLabel: "Action music",
|
|
1965
2029
|
musicHint: "Live-composes from Harness actions: request starts, tool calls, turn ends, etc. (click the switch to start audio; a detected MIDI output is driven as well)",
|
|
2030
|
+
musicOn: "On",
|
|
2031
|
+
musicOff: "Off",
|
|
1966
2032
|
musicVolume: "Volume",
|
|
1967
2033
|
musicStyle: "Style",
|
|
1968
2034
|
musicStyleMajor: "Major",
|
|
@@ -2186,6 +2252,7 @@ window.__ModuleLoader__.load({
|
|
|
2186
2252
|
};
|
|
2187
2253
|
}, "token-quota-ui: snapshot poll + full strategy");
|
|
2188
2254
|
const load = (sessionId) => {
|
|
2255
|
+
if (lastSessionId !== void 0 && lastSessionId !== sessionId) music.stop();
|
|
2189
2256
|
lastSessionId = sessionId;
|
|
2190
2257
|
bound?.setLoading(true);
|
|
2191
2258
|
bound?.setError(null);
|
package/lib/index.js
CHANGED
|
@@ -515,7 +515,7 @@ var TokenQuotaService = class TokenQuotaService extends Service {
|
|
|
515
515
|
return this.upgradeCheck;
|
|
516
516
|
}
|
|
517
517
|
async doRefreshUpgrade() {
|
|
518
|
-
const current = "0.1.
|
|
518
|
+
const current = "0.1.30";
|
|
519
519
|
let latest;
|
|
520
520
|
try {
|
|
521
521
|
const response = await fetch(REGISTRY_LATEST_URL, {
|
|
@@ -95,6 +95,8 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
95
95
|
// so the chat content behind it stays readable; hovering restores it.
|
|
96
96
|
const [hovered, setHovered] = useState(false);
|
|
97
97
|
const [inputActive, setInputActive] = useState(false);
|
|
98
|
+
// Active settings-dialog tab: quota limits vs. live-music options.
|
|
99
|
+
const [settingsTab, setSettingsTab] = useState('quota');
|
|
98
100
|
// Copy-button feedback: which command was just copied (label flips to
|
|
99
101
|
// 「已复制」for a moment so the click is perceivable).
|
|
100
102
|
const [copiedCmd, setCopiedCmd] = useState(null);
|
|
@@ -298,7 +300,7 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
298
300
|
: '';
|
|
299
301
|
return (_jsxs("div", { ref: panelRef, className: `${css.panel}${panelDimClass !== '' ? ` ${panelDimClass}` : ''}`, style: panelPos !== null ? { left: panelPos.x, top: panelPos.y, right: 'auto' } : undefined, onPointerEnter: () => { setHovered(true); }, onPointerLeave: () => { setHovered(false); }, children: [_jsxs("div", { className: css.header, onPointerDown: (event) => { beginDrag(event, panelRef.current, applyPanelPos); }, children: [_jsxs("div", { className: css.headerText, children: [_jsxs("div", { className: css.title, children: [t('title'), __TOKEN_QUOTA_VERSION__ !== undefined && __TOKEN_QUOTA_VERSION__ !== '' && (upgrade !== null
|
|
300
302
|
? (_jsxs("span", { className: `${css.version} ${css.versionNew}`, title: t('upgradeAvailableHint'), children: ["v", __TOKEN_QUOTA_VERSION__, " \u2192 v", upgrade.latestVersion] }))
|
|
301
|
-
: (_jsxs("span", { className: css.version, children: ["v", __TOKEN_QUOTA_VERSION__] })))] }), _jsx("div", { className: css.subtitle, children: t('subtitle') })] }), _jsxs("div", { className: css.headerActions, onPointerDown: (event) => { event.stopPropagation(); }, children: [_jsx("button", { type: "button", className: `${css.settingsBtn}${musicEnabled ? ` ${css.settingsBtnActive}` : ''}`, title: t('
|
|
303
|
+
: (_jsxs("span", { className: css.version, children: ["v", __TOKEN_QUOTA_VERSION__] })))] }), _jsx("div", { className: css.subtitle, children: t('subtitle') })] }), _jsxs("div", { className: css.headerActions, onPointerDown: (event) => { event.stopPropagation(); }, children: [_jsx("button", { type: "button", "aria-pressed": musicEnabled, className: `${css.settingsBtn}${musicEnabled ? ` ${css.settingsBtnActive}` : ''}`, title: `${t('musicLabel')}:${musicEnabled ? t('musicOn') : t('musicOff')}`, onClick: () => { setMusicEnabled(!musicEnabled); }, children: "\u266A" }), _jsx("button", { type: "button", className: css.settingsBtn, onClick: () => { actions.setLogOpen(true); }, children: t('logs') }), _jsx("button", { type: "button", className: css.settingsBtn, onClick: openSettings, children: t('settings') }), _jsx("button", { type: "button", className: css.collapse, onClick: () => { setCollapsed(true); }, children: t('collapse') })] })] }), _jsxs("div", { className: css.body, children: [loading && _jsx("div", { className: css.notice, children: t('loading') }), error !== null && _jsx("div", { className: css.noticeError, children: error }), fullNotice !== null && (_jsx("div", { className: css.fullNotice, role: "alert", children: fullNotice })), upgrade !== null && !upgradeDismissed && (_jsxs("div", { className: `${css.upgradeBanner}${upgradeFlash ? ` ${css.upgradeBannerFlash}` : ''}`, role: "alert", children: [_jsx("div", { className: css.upgradeBannerText, children: t('upgradeAvailable').replace('{version}', upgrade.latestVersion) }), _jsx("div", { className: css.upgradeCommands, children: upgrade.commands.map(cmd => (_jsxs("div", { className: css.upgradeCommandRow, children: [_jsx("code", { className: css.upgradeCommand, children: cmd }), _jsx("button", { type: "button", className: `${css.copyBtn}${copiedCmd === cmd ? ` ${css.copyBtnDone}` : ''}`, onClick: () => { copyUpgradeCommand(cmd); }, children: copiedCmd === cmd ? t('copied') : t('copy') })] }, cmd))) }), _jsx("div", { className: css.upgradeHint, children: t('upgradeHint') }), _jsx("button", { type: "button", className: css.upgradeClose, onClick: () => { actions.setUpgradeDismissed(true); }, "aria-label": t('close'), children: "\u00D7" })] })), !loading && error === null && visibleRows.length === 0 && (_jsx("div", { className: css.notice, children: monitored !== null && monitored.length === 0 ? t('noMonitored') : t('waiting') })), visibleRows.map((row) => {
|
|
302
304
|
const state = barStateOf(row);
|
|
303
305
|
const pct = row.limit > 0 ? Math.min(100, Math.round((row.used / row.limit) * 100)) : 0;
|
|
304
306
|
const barClass = state === 'over'
|
|
@@ -311,40 +313,40 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
|
|
|
311
313
|
? `${formatTokens(row.used)} / ${formatTokens(row.limit)}`
|
|
312
314
|
: `${formatTokens(row.used)} · ${t('unlimited')}`, _jsx("button", { type: "button", className: css.gearBtn, title: t('setLimitHint'), onClick: () => { setEditingKey(editing ? null : row.key); }, children: "\u2699" })] })] }), _jsx("div", { className: css.bar, children: _jsx("div", { className: barClass, style: { width: `${pct}%` } }) }), editing && (_jsxs("div", { className: css.controls, children: [_jsx("input", { className: css.input, type: "number", min: 0, step: 10000, placeholder: t('limitPlaceholder'), value: drafts[row.key] ?? '', onChange: (event) => { setDrafts(prev => ({ ...prev, [row.key]: event.target.value })); }, onKeyDown: (event) => { if (event.key === 'Enter')
|
|
313
315
|
commitLimit(row); } }), _jsx("button", { type: "button", className: css.save, onClick: () => { commitLimit(row); }, children: t('save') })] }))] }, row.key));
|
|
314
|
-
})] }), dialogOpen && (_jsxs("div", { ref: settingsRef, className: css.dialog, style: settingsPos !== null ? { left: settingsPos.x, top: settingsPos.y, transform: 'none' } : undefined, children: [_jsxs("div", { className: css.dialogHeader, onPointerDown: (event) => { beginDrag(event, settingsRef.current, setSettingsPos); }, children: [_jsx("div", { className: css.dialogTitle, children: t('settingsTitle') }), _jsx("button", { type: "button", className: css.dialogClose, title: t('close'), onClick: () => { actions.setDialogOpen(false); }, onPointerDown: (event) => { event.stopPropagation(); }, children: "\u00D7" })] }), _jsxs("div", { className: css.dialogSection, children: [_jsx("div", { className: css.dialogLabel, children: t('monitorLabel') }), _jsx("div", { className: css.monitorHint, children: t('monitorHint') }), _jsx("div", { className: css.monitorList, children: allModels.map(model => (_jsxs("label", { className: css.monitorRow, children: [_jsx("input", { type: "checkbox", checked: monitored === null || monitored.includes(model.key), onChange: (event) => {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
316
|
+
})] }), dialogOpen && (_jsxs("div", { ref: settingsRef, className: css.dialog, style: settingsPos !== null ? { left: settingsPos.x, top: settingsPos.y, transform: 'none' } : undefined, children: [_jsxs("div", { className: css.dialogHeader, onPointerDown: (event) => { beginDrag(event, settingsRef.current, setSettingsPos); }, children: [_jsx("div", { className: css.dialogTitle, children: t('settingsTitle') }), _jsx("button", { type: "button", className: css.dialogClose, title: t('close'), onClick: () => { actions.setDialogOpen(false); }, onPointerDown: (event) => { event.stopPropagation(); }, children: "\u00D7" })] }), _jsxs("div", { className: css.dialogTabs, role: "tablist", children: [_jsx("button", { type: "button", role: "tab", "aria-selected": settingsTab === 'quota', className: `${css.dialogTab}${settingsTab === 'quota' ? ` ${css.dialogTabActive}` : ''}`, onClick: () => { setSettingsTab('quota'); }, children: t('settingsTabQuota') }), _jsx("button", { type: "button", role: "tab", "aria-selected": settingsTab === 'music', className: `${css.dialogTab}${settingsTab === 'music' ? ` ${css.dialogTabActive}` : ''}`, onClick: () => { setSettingsTab('music'); }, children: t('settingsTabMusic') })] }), settingsTab === 'quota' && (_jsxs(_Fragment, { children: [_jsxs("div", { className: css.dialogSection, children: [_jsx("div", { className: css.dialogLabel, children: t('monitorLabel') }), _jsx("div", { className: css.monitorHint, children: t('monitorHint') }), _jsx("div", { className: css.monitorList, children: allModels.map(model => (_jsxs("label", { className: css.monitorRow, children: [_jsx("input", { type: "checkbox", checked: monitored === null || monitored.includes(model.key), onChange: (event) => {
|
|
317
|
+
const base = monitored === null ? allModels.map(m => m.key) : monitored;
|
|
318
|
+
const next = new Set(base);
|
|
319
|
+
if (event.target.checked)
|
|
320
|
+
next.add(model.key);
|
|
321
|
+
else
|
|
322
|
+
next.delete(model.key);
|
|
323
|
+
// Auto-save on every change; all selected stores as null.
|
|
324
|
+
setMonitored(next.size === allModels.length ? null : [...next]);
|
|
325
|
+
} }), _jsx("span", { className: css.monitorName, title: model.key, children: model.name })] }, model.key))) })] }), _jsxs("div", { className: css.dialogSection, children: [_jsx("div", { className: css.dialogLabel, children: t('fullActionLabel') }), FULL_ACTIONS.map(action => (_jsxs("label", { className: css.radioRow, children: [_jsx("input", { type: "radio", name: "token-quota-onfull", checked: onFull === action.value, onChange: () => { setOnFull(action.value); } }), _jsx("span", { children: t(action.labelKey) })] }, action.value)))] }), _jsxs("div", { className: css.dialogSection, children: [_jsx("div", { className: css.dialogLabel, children: t('resetLabel') }), _jsx("div", { className: css.monitorHint, children: t('resetHint') }), _jsxs("div", { className: css.resetRow, children: [_jsx("select", { className: css.resetSelect, value: reset?.offsetHours ?? -new Date().getTimezoneOffset() / 60, onChange: (event) => {
|
|
326
|
+
setReset({
|
|
327
|
+
offsetHours: Number(event.target.value),
|
|
328
|
+
hour: reset?.hour ?? 0,
|
|
329
|
+
minute: reset?.minute ?? 0,
|
|
330
|
+
});
|
|
331
|
+
}, children: Array.from({ length: 27 }, (_, i) => i - 12).map(offset => (_jsxs("option", { value: offset, children: ["UTC", offset >= 0 ? `+${offset}` : offset] }, offset))) }), _jsx("select", { className: css.resetSelect, value: reset?.hour ?? 0, onChange: (event) => {
|
|
332
|
+
setReset({
|
|
333
|
+
offsetHours: reset?.offsetHours ?? -new Date().getTimezoneOffset() / 60,
|
|
334
|
+
hour: Number(event.target.value),
|
|
335
|
+
minute: reset?.minute ?? 0,
|
|
336
|
+
});
|
|
337
|
+
}, children: Array.from({ length: 24 }, (_, i) => i).map(hour => (_jsxs("option", { value: hour, children: [String(hour).padStart(2, '0'), " \u65F6"] }, hour))) }), _jsx("select", { className: css.resetSelect, value: reset?.minute ?? 0, onChange: (event) => {
|
|
338
|
+
setReset({
|
|
339
|
+
offsetHours: reset?.offsetHours ?? -new Date().getTimezoneOffset() / 60,
|
|
340
|
+
hour: reset?.hour ?? 0,
|
|
341
|
+
minute: Number(event.target.value),
|
|
342
|
+
});
|
|
343
|
+
}, 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("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(_Fragment, { 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 === 'quota' && (_jsx(_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
|
|
344
|
+
? t('checkingUpdates')
|
|
345
|
+
: lastCheckResult === 'up-to-date'
|
|
346
|
+
? t('checkUpToDate')
|
|
347
|
+
: lastCheckResult === 'error'
|
|
348
|
+
? t('checkFailed')
|
|
349
|
+
: t('checkUpdatesNow') })] }), lastCheckResult === 'error' && upgradeError !== null && (_jsx("div", { className: css.checkErrorHint, role: "alert", children: upgradeError }))] }) }))] })), logOpen && (_jsxs("div", { ref: logRef, className: `${css.dialog} ${css.logDialog}`, style: logPos !== null ? { left: logPos.x, top: logPos.y, transform: 'none' } : undefined, children: [_jsxs("div", { className: css.logHeader, onPointerDown: (event) => { beginDrag(event, logRef.current, setLogPos); }, children: [_jsx("div", { className: css.dialogTitle, children: t('logsTitle') }), _jsxs("div", { className: css.logToolbar, onPointerDown: (event) => { event.stopPropagation(); }, children: [_jsx("input", { type: "search", className: css.logSearch, placeholder: t('logSearchPlaceholder'), value: logSearch, onChange: (event) => { actions.setLogSearch(event.target.value); } }), _jsx("button", { type: "button", className: css.logClearBtn, onClick: () => { actions.setLogClearOpen(true); }, children: t('logClear') })] }), _jsx("button", { type: "button", className: css.dialogClose, title: t('close'), onClick: () => { actions.setLogOpen(false); }, children: "\u00D7" })] }), log !== null && filteredLogEntries.length === 0 && (_jsx("div", { className: css.notice, children: logSearch.trim() !== '' ? t('logNoMatch') : t('logEmpty') })), _jsx("div", { className: css.logScroll, children: _jsxs("table", { className: css.logTable, children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: t('logDay') }), _jsx("th", { children: t('logModel') }), _jsx("th", { className: css.logUsedCol, children: t('logUsed') })] }) }), _jsx("tbody", { children: logPageEntries.map(entry => (_jsxs("tr", { children: [_jsx("td", { className: css.logDayCol, children: entry.day }), _jsx("td", { className: css.logModelCol, title: entry.key, children: entry.key }), _jsx("td", { className: css.logUsedCol, children: formatTokens(entry.used) })] }, `${entry.day}/${entry.key}`))) })] }) }), _jsxs("div", { className: css.logPager, children: [_jsx("span", { className: css.logPagerInfo, children: t('logPagerInfo')
|
|
348
350
|
.replace('{from}', String(logCurrentPage * logPageSize + 1))
|
|
349
351
|
.replace('{to}', String(Math.min((logCurrentPage + 1) * logPageSize, filteredLogEntries.length)))
|
|
350
352
|
.replace('{total}', String(filteredLogEntries.length)) }), _jsxs("div", { className: css.logPagerControls, children: [_jsx("button", { type: "button", className: css.logPagerBtn, disabled: logCurrentPage <= 0, onClick: () => { actions.setLogPage(logCurrentPage - 1); }, children: "\u2039" }), _jsxs("span", { className: css.logPagerPages, children: [logCurrentPage + 1, " / ", logTotalPages] }), _jsx("button", { type: "button", className: css.logPagerBtn, disabled: logCurrentPage >= logTotalPages - 1, onClick: () => { actions.setLogPage(logCurrentPage + 1); }, children: "\u203A" }), _jsx("select", { className: css.logPageSizeSelect, value: logPageSize, onChange: (event) => { actions.setLogPageSize(Number(event.target.value)); }, children: [10, 15, 20, 50, 100].map(size => (_jsxs("option", { value: size, children: [size, t('logPerPage')] }, size))) })] })] })] })), logClearOpen && (_jsx("div", { className: css.dialogOverlay, children: _jsxs("div", { className: `${css.dialog} ${css.logClearDialog}`, children: [_jsx("div", { className: css.dialogTitle, children: t('logClearTitle') }), _jsx("div", { className: css.dialogBody, children: t('logClearHint') }), _jsx("input", { type: "date", className: css.logClearDate, value: logClearBefore, onChange: (event) => { actions.setLogClearBefore(event.target.value); } }), _jsxs("div", { className: css.dialogActions, children: [_jsx("button", { type: "button", className: css.checkBtn, disabled: logClearBefore === '' || logClearing, onClick: () => { clearLogBefore(logClearBefore); }, children: logClearing ? t('logClearing') : t('logClearConfirm') }), _jsx("button", { type: "button", className: css.checkBtn, onClick: () => { actions.setLogClearOpen(false); }, children: t('logClearCancel') })] })] }) }))] }));
|
|
@@ -262,6 +262,11 @@ export function apply(ctx) {
|
|
|
262
262
|
return () => { clearInterval(timer); };
|
|
263
263
|
}, 'token-quota-ui: snapshot poll + full strategy');
|
|
264
264
|
const load = (sessionId) => {
|
|
265
|
+
// Switching the panel to another session: stop the previous session's
|
|
266
|
+
// soundtrack — while scoped to the current session its stop events are
|
|
267
|
+
// filtered out, so without this it could play forever.
|
|
268
|
+
if (lastSessionId !== undefined && lastSessionId !== sessionId)
|
|
269
|
+
music.stop();
|
|
265
270
|
lastSessionId = sessionId;
|
|
266
271
|
bound?.setLoading(true);
|
|
267
272
|
bound?.setError(null);
|
|
@@ -25,6 +25,8 @@ export declare const zh: {
|
|
|
25
25
|
expandHint: string;
|
|
26
26
|
settings: string;
|
|
27
27
|
settingsTitle: string;
|
|
28
|
+
settingsTabQuota: string;
|
|
29
|
+
settingsTabMusic: string;
|
|
28
30
|
monitorLabel: string;
|
|
29
31
|
monitorHint: string;
|
|
30
32
|
monitorAll: string;
|
|
@@ -68,6 +70,8 @@ export declare const zh: {
|
|
|
68
70
|
dimWhenIdleHint: string;
|
|
69
71
|
musicLabel: string;
|
|
70
72
|
musicHint: string;
|
|
73
|
+
musicOn: string;
|
|
74
|
+
musicOff: string;
|
|
71
75
|
musicVolume: string;
|
|
72
76
|
musicStyle: string;
|
|
73
77
|
musicStyleMajor: string;
|
|
@@ -103,6 +107,8 @@ export declare const en: {
|
|
|
103
107
|
expandHint: string;
|
|
104
108
|
settings: string;
|
|
105
109
|
settingsTitle: string;
|
|
110
|
+
settingsTabQuota: string;
|
|
111
|
+
settingsTabMusic: string;
|
|
106
112
|
monitorLabel: string;
|
|
107
113
|
monitorHint: string;
|
|
108
114
|
monitorAll: string;
|
|
@@ -146,6 +152,8 @@ export declare const en: {
|
|
|
146
152
|
dimWhenIdleHint: string;
|
|
147
153
|
musicLabel: string;
|
|
148
154
|
musicHint: string;
|
|
155
|
+
musicOn: string;
|
|
156
|
+
musicOff: string;
|
|
149
157
|
musicVolume: string;
|
|
150
158
|
musicStyle: string;
|
|
151
159
|
musicStyleMajor: string;
|
|
@@ -24,7 +24,9 @@ export const zh = {
|
|
|
24
24
|
expand: '展开',
|
|
25
25
|
expandHint: '展开每日 Token 限额面板',
|
|
26
26
|
settings: '设置',
|
|
27
|
-
settingsTitle: '
|
|
27
|
+
settingsTitle: '设置',
|
|
28
|
+
settingsTabQuota: '限额设置',
|
|
29
|
+
settingsTabMusic: '音乐设置',
|
|
28
30
|
monitorLabel: '监控模型',
|
|
29
31
|
monitorHint: '未勾选的模型不显示、不计入用量、不受限额限制',
|
|
30
32
|
monitorAll: '全部',
|
|
@@ -68,6 +70,8 @@ export const zh = {
|
|
|
68
70
|
dimWhenIdleHint: '鼠标移开面板时降低不透明度,输入文字时更透明;鼠标悬停恢复',
|
|
69
71
|
musicLabel: '动作音乐',
|
|
70
72
|
musicHint: '根据 Harness 动作实时作曲:请求开始、工具调用、回合结束等(需点击开关启动音频;检测到 MIDI 输出时同步发送 MIDI)',
|
|
73
|
+
musicOn: '开',
|
|
74
|
+
musicOff: '关',
|
|
71
75
|
musicVolume: '音量',
|
|
72
76
|
musicStyle: '风格',
|
|
73
77
|
musicStyleMajor: '大调',
|
|
@@ -100,7 +104,9 @@ export const en = {
|
|
|
100
104
|
expand: 'Expand',
|
|
101
105
|
expandHint: 'Expand the daily token quota panel',
|
|
102
106
|
settings: 'Settings',
|
|
103
|
-
settingsTitle: '
|
|
107
|
+
settingsTitle: 'Settings',
|
|
108
|
+
settingsTabQuota: 'Quota',
|
|
109
|
+
settingsTabMusic: 'Music',
|
|
104
110
|
monitorLabel: 'Monitored models',
|
|
105
111
|
monitorHint: 'Unchecked models are hidden, not metered, and never capped',
|
|
106
112
|
monitorAll: 'All',
|
|
@@ -144,6 +150,8 @@ export const en = {
|
|
|
144
150
|
dimWhenIdleHint: 'Fade the panel out when the pointer is away (more while typing); hover to restore',
|
|
145
151
|
musicLabel: 'Action music',
|
|
146
152
|
musicHint: 'Live-composes from Harness actions: request starts, tool calls, turn ends, etc. (click the switch to start audio; a detected MIDI output is driven as well)',
|
|
153
|
+
musicOn: 'On',
|
|
154
|
+
musicOff: 'Off',
|
|
147
155
|
musicVolume: 'Volume',
|
|
148
156
|
musicStyle: 'Style',
|
|
149
157
|
musicStyleMajor: 'Major',
|
|
@@ -42,6 +42,8 @@ export declare class TokenQuotaMusic {
|
|
|
42
42
|
private phraseIndex;
|
|
43
43
|
/** True when the next piece start should play the full intro glissando. */
|
|
44
44
|
private introPending;
|
|
45
|
+
/** Session the current piece belongs to (turn/start carries it). */
|
|
46
|
+
private sessionId;
|
|
45
47
|
private phraseTimer;
|
|
46
48
|
private lastStreamActivity;
|
|
47
49
|
private watchdogTimer;
|
|
@@ -64,8 +66,19 @@ export declare class TokenQuotaMusic {
|
|
|
64
66
|
setStyle(value: TokenQuotaMusicStyle): void;
|
|
65
67
|
/** Feed the engine one SSE activity timestamp (action or heartbeat). */
|
|
66
68
|
markStreamActivity(): void;
|
|
69
|
+
/** Stop any playing piece — e.g. when the panel switches sessions. */
|
|
70
|
+
stop(): void;
|
|
67
71
|
/** Handle one incoming host action and steer the piece. */
|
|
68
72
|
onAction(action: TokenQuotaMusicAction): void;
|
|
73
|
+
/** Current tonic root in MIDI note numbers. */
|
|
74
|
+
private get tonicRoot();
|
|
75
|
+
/**
|
|
76
|
+
* A scale tone relative to the current tonic — degrees wrap up octaves
|
|
77
|
+
* (deg 5 on a 5-note scale = the octave). Event figures use this so every
|
|
78
|
+
* accent stays inside the key and melts into the piece instead of
|
|
79
|
+
* clashing with it.
|
|
80
|
+
*/
|
|
81
|
+
private tone;
|
|
69
82
|
/** Start a new piece: intro run, then the phrase chain. */
|
|
70
83
|
private startPiece;
|
|
71
84
|
/** Play one phrase, then chain into the next after a one-beat rest. */
|
|
@@ -80,6 +80,8 @@ export class TokenQuotaMusic {
|
|
|
80
80
|
phraseIndex = 0;
|
|
81
81
|
/** True when the next piece start should play the full intro glissando. */
|
|
82
82
|
introPending = true;
|
|
83
|
+
/** Session the current piece belongs to (turn/start carries it). */
|
|
84
|
+
sessionId;
|
|
83
85
|
phraseTimer;
|
|
84
86
|
// Watchdog: host heartbeat freshness (ms timestamp)
|
|
85
87
|
lastStreamActivity = 0;
|
|
@@ -161,6 +163,10 @@ export class TokenQuotaMusic {
|
|
|
161
163
|
markStreamActivity() {
|
|
162
164
|
this.lastStreamActivity = Date.now();
|
|
163
165
|
}
|
|
166
|
+
/** Stop any playing piece — e.g. when the panel switches sessions. */
|
|
167
|
+
stop() {
|
|
168
|
+
this.stopPiece(false);
|
|
169
|
+
}
|
|
164
170
|
/** Handle one incoming host action and steer the piece. */
|
|
165
171
|
onAction(action) {
|
|
166
172
|
if (!this.enabled || this.audio === null)
|
|
@@ -168,16 +174,27 @@ export class TokenQuotaMusic {
|
|
|
168
174
|
const base = TokenQuotaMusic.BASE_MIDI;
|
|
169
175
|
switch (action.type) {
|
|
170
176
|
case 'turn/start':
|
|
171
|
-
|
|
177
|
+
// A new turn = the user sent a message: begin a fresh piece right
|
|
178
|
+
// away (request/header only fires on the first request of a session
|
|
179
|
+
// or on model changes — it cannot be the music's start trigger).
|
|
180
|
+
// If another session's music was still playing, stop it first.
|
|
181
|
+
if (this.sessionId !== undefined && this.sessionId !== action.sessionId) {
|
|
182
|
+
this.stopPiece(false);
|
|
183
|
+
}
|
|
184
|
+
this.sessionId = action.sessionId;
|
|
185
|
+
this.stopMelody();
|
|
186
|
+
this.playing = false;
|
|
172
187
|
this.tonicIndex = 0;
|
|
173
188
|
this.phraseIndex = 0;
|
|
174
189
|
this.introPending = true;
|
|
190
|
+
this.startPiece();
|
|
175
191
|
break;
|
|
176
192
|
case 'request/header': {
|
|
193
|
+
// Safety net (and a light "request fired" accent when already playing).
|
|
177
194
|
if (!this.playing)
|
|
178
195
|
this.startPiece();
|
|
179
196
|
else
|
|
180
|
-
this.pluck(
|
|
197
|
+
this.pluck(this.tone(5, 1), 0.3, 0.9);
|
|
181
198
|
break;
|
|
182
199
|
}
|
|
183
200
|
case 'step/start': {
|
|
@@ -190,41 +207,67 @@ export class TokenQuotaMusic {
|
|
|
190
207
|
}
|
|
191
208
|
break;
|
|
192
209
|
}
|
|
193
|
-
case 'tool/call':
|
|
194
|
-
//
|
|
195
|
-
|
|
196
|
-
this.pluck(
|
|
210
|
+
case 'tool/call': {
|
|
211
|
+
// Rising two-note figure drawn from the current scale (so it blends
|
|
212
|
+
// with the piece, not pokes out of it) over a soft low root for body.
|
|
213
|
+
this.pluck(this.tone(4, 1), 0.38, 0.9);
|
|
214
|
+
setTimeout(() => this.pluck(this.tone(5, 1), 0.34, 0.9), 90);
|
|
215
|
+
this.pluck(this.tonicRoot - 12, 0.22, 0.9);
|
|
197
216
|
break;
|
|
217
|
+
}
|
|
198
218
|
case 'tool/result': {
|
|
199
219
|
if (action.error) {
|
|
200
|
-
|
|
201
|
-
|
|
220
|
+
// Deliberately sour (an error should feel off): a half-step below a
|
|
221
|
+
// scale tone, then sinking further.
|
|
222
|
+
const t = this.tone(2, 1);
|
|
223
|
+
this.pluck(t - 1, 0.4, 0.7);
|
|
224
|
+
setTimeout(() => this.pluck(t - 3, 0.4, 1.0), 110);
|
|
202
225
|
}
|
|
203
226
|
else {
|
|
204
|
-
|
|
205
|
-
|
|
227
|
+
// Gentle in-key resolve landing on the tonic octave.
|
|
228
|
+
this.pluck(this.tone(3, 1), 0.34, 1.0);
|
|
229
|
+
setTimeout(() => this.pluck(this.tone(1, 1), 0.32, 1.0), 90);
|
|
230
|
+
setTimeout(() => this.pluck(this.tone(0, 1), 0.34, 1.2), 180);
|
|
206
231
|
}
|
|
207
232
|
break;
|
|
208
233
|
}
|
|
209
|
-
case 'assistant/attempt':
|
|
210
|
-
// Failed attempt: falling tension figure.
|
|
211
|
-
this.pluck(
|
|
212
|
-
setTimeout(() => this.pluck(
|
|
213
|
-
setTimeout(() => this.pluck(
|
|
234
|
+
case 'assistant/attempt': {
|
|
235
|
+
// Failed attempt: falling in-key tension figure.
|
|
236
|
+
this.pluck(this.tone(4, 1), 0.36, 0.8);
|
|
237
|
+
setTimeout(() => this.pluck(this.tone(2, 1), 0.36, 0.9), 110);
|
|
238
|
+
setTimeout(() => this.pluck(this.tone(0), 0.36, 1.1), 220);
|
|
214
239
|
break;
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
//
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
this.
|
|
240
|
+
}
|
|
241
|
+
case 'assistant/message': {
|
|
242
|
+
// Sentence end: a short cadence figure, then a breath on the tonic
|
|
243
|
+
// octave (in key — the old fixed C clashed with the mode rotation).
|
|
244
|
+
// The bed keeps playing until the turn fully ends (turn/end).
|
|
245
|
+
this.pluck(this.tone(2, 1), 0.3, 1.0);
|
|
246
|
+
setTimeout(() => this.breath(this.tone(0, action.interrupted ? 0 : 1), 1.4), 140);
|
|
221
247
|
break;
|
|
248
|
+
}
|
|
222
249
|
case 'turn/end':
|
|
223
250
|
this.stopPiece(true);
|
|
224
251
|
break;
|
|
225
252
|
}
|
|
226
253
|
}
|
|
227
254
|
// ── piece lifecycle ───────────────────────────────────────────────────
|
|
255
|
+
/** Current tonic root in MIDI note numbers. */
|
|
256
|
+
get tonicRoot() {
|
|
257
|
+
return TokenQuotaMusic.BASE_MIDI + (PROGRESSION[this.style][this.tonicIndex] ?? 0);
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* A scale tone relative to the current tonic — degrees wrap up octaves
|
|
261
|
+
* (deg 5 on a 5-note scale = the octave). Event figures use this so every
|
|
262
|
+
* accent stays inside the key and melts into the piece instead of
|
|
263
|
+
* clashing with it.
|
|
264
|
+
*/
|
|
265
|
+
tone(deg, oct = 0) {
|
|
266
|
+
const scale = SCALES[this.style];
|
|
267
|
+
const len = scale.length;
|
|
268
|
+
const d = ((deg % len) + len) % len;
|
|
269
|
+
return this.tonicRoot + 12 * (Math.floor(deg / len) + oct) + (scale[d] ?? 0);
|
|
270
|
+
}
|
|
228
271
|
/** Start a new piece: intro run, then the phrase chain. */
|
|
229
272
|
startPiece() {
|
|
230
273
|
if (!this.audio || this.playing)
|
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.30",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|