@jxgame2020/dsh-token-quota 0.1.29 → 0.1.31
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 +240 -154
- package/lib/index.js +1 -1
- package/lib/types/client/TokenQuotaPanel.js +36 -34
- package/lib/types/client/index.js +23 -0
- package/lib/types/client/locales.d.ts +6 -0
- package/lib/types/client/locales.js +8 -2
- package/lib/types/client/music.d.ts +11 -0
- package/lib/types/client/music.js +50 -19
- 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.31" ? 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);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: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_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;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,96 @@ window.__ModuleLoader__.load({
|
|
|
201
201
|
document.head.appendChild(tag);
|
|
202
202
|
}
|
|
203
203
|
var TokenQuotaPanel_module_css_default = {
|
|
204
|
-
"
|
|
205
|
-
"
|
|
204
|
+
"body": "NPLLIq_body",
|
|
205
|
+
"bar": "NPLLIq_bar",
|
|
206
|
+
"rowName": "NPLLIq_rowName",
|
|
207
|
+
"rowHeader": "NPLLIq_rowHeader",
|
|
208
|
+
"gearBtn": "NPLLIq_gearBtn",
|
|
209
|
+
"radioRow": "NPLLIq_radioRow",
|
|
206
210
|
"resetRow": "NPLLIq_resetRow",
|
|
211
|
+
"logModelCol": "NPLLIq_logModelCol",
|
|
212
|
+
"logClearDialog": "NPLLIq_logClearDialog",
|
|
213
|
+
"upgradeClose": "NPLLIq_upgradeClose",
|
|
214
|
+
"subtitle": "NPLLIq_subtitle",
|
|
215
|
+
"fillWarn": "NPLLIq_fillWarn",
|
|
207
216
|
"noticeError": "NPLLIq_noticeError",
|
|
208
|
-
"selectBtn": "NPLLIq_selectBtn",
|
|
209
|
-
"monitorList": "NPLLIq_monitorList",
|
|
210
217
|
"upgradeCommandRow": "NPLLIq_upgradeCommandRow",
|
|
211
|
-
"
|
|
212
|
-
"
|
|
213
|
-
"fillIdle": "NPLLIq_fillIdle",
|
|
214
|
-
"logPagerBtn": "NPLLIq_logPagerBtn",
|
|
215
|
-
"panel": "NPLLIq_panel",
|
|
216
|
-
"subtitle": "NPLLIq_subtitle",
|
|
217
|
-
"notice": "NPLLIq_notice",
|
|
218
|
-
"settingsBtnActive": "NPLLIq_settingsBtnActive",
|
|
219
|
-
"gearBtn": "NPLLIq_gearBtn",
|
|
220
|
-
"panelDimStrong": "NPLLIq_panelDimStrong",
|
|
221
|
-
"logClearDate": "NPLLIq_logClearDate",
|
|
218
|
+
"logDialog": "NPLLIq_logDialog",
|
|
219
|
+
"dialogLabel": "NPLLIq_dialogLabel",
|
|
222
220
|
"settingsBtn": "NPLLIq_settingsBtn",
|
|
223
|
-
"
|
|
221
|
+
"dialogHeader": "NPLLIq_dialogHeader",
|
|
222
|
+
"upgradeBannerFlash": "NPLLIq_upgradeBannerFlash",
|
|
223
|
+
"copyBtnDone": "NPLLIq_copyBtnDone",
|
|
224
|
+
"upgradeBanner": "NPLLIq_upgradeBanner",
|
|
225
|
+
"logScroll": "NPLLIq_logScroll",
|
|
226
|
+
"logDayCol": "NPLLIq_logDayCol",
|
|
224
227
|
"logPager": "NPLLIq_logPager",
|
|
225
|
-
"tab": "NPLLIq_tab",
|
|
226
|
-
"tabIcon": "NPLLIq_tabIcon",
|
|
227
|
-
"dialog": "NPLLIq_dialog",
|
|
228
228
|
"upgradeCommands": "NPLLIq_upgradeCommands",
|
|
229
|
-
"
|
|
230
|
-
"version": "NPLLIq_version",
|
|
229
|
+
"fillOver": "NPLLIq_fillOver",
|
|
231
230
|
"checkUpdatesRow": "NPLLIq_checkUpdatesRow",
|
|
232
|
-
"dialogTitle": "NPLLIq_dialogTitle",
|
|
233
231
|
"headerText": "NPLLIq_headerText",
|
|
234
|
-
"dialogActions": "NPLLIq_dialogActions",
|
|
235
|
-
"logDialog": "NPLLIq_logDialog",
|
|
236
|
-
"fillOver": "NPLLIq_fillOver",
|
|
237
|
-
"monitorRow": "NPLLIq_monitorRow",
|
|
238
|
-
"upgradeBanner": "NPLLIq_upgradeBanner",
|
|
239
|
-
"dialogHint": "NPLLIq_dialogHint",
|
|
240
|
-
"dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
|
|
241
|
-
"logClearDialog": "NPLLIq_logClearDialog",
|
|
242
|
-
"logHeader": "NPLLIq_logHeader",
|
|
243
|
-
"upgradeHint": "NPLLIq_upgradeHint",
|
|
244
|
-
"row": "NPLLIq_row",
|
|
245
|
-
"logToolbar": "NPLLIq_logToolbar",
|
|
246
|
-
"logSearch": "NPLLIq_logSearch",
|
|
247
232
|
"switch": "NPLLIq_switch",
|
|
248
|
-
"
|
|
249
|
-
"
|
|
250
|
-
"
|
|
251
|
-
"logPagerPages": "NPLLIq_logPagerPages",
|
|
233
|
+
"dialogHint": "NPLLIq_dialogHint",
|
|
234
|
+
"dialogOverlay": "NPLLIq_dialogOverlay",
|
|
235
|
+
"version": "NPLLIq_version",
|
|
252
236
|
"input": "NPLLIq_input",
|
|
253
|
-
"rowHeader": "NPLLIq_rowHeader",
|
|
254
|
-
"copyBtnDone": "NPLLIq_copyBtnDone",
|
|
255
|
-
"dialogClose": "NPLLIq_dialogClose",
|
|
256
|
-
"logScroll": "NPLLIq_logScroll",
|
|
257
|
-
"versionNew": "NPLLIq_versionNew",
|
|
258
|
-
"header": "NPLLIq_header",
|
|
259
|
-
"upgradeCommand": "NPLLIq_upgradeCommand",
|
|
260
237
|
"logPagerControls": "NPLLIq_logPagerControls",
|
|
261
|
-
"
|
|
262
|
-
"tabLabel": "NPLLIq_tabLabel",
|
|
238
|
+
"settingsDialog": "NPLLIq_settingsDialog",
|
|
263
239
|
"logPageSizeSelect": "NPLLIq_logPageSizeSelect",
|
|
264
|
-
"
|
|
265
|
-
"
|
|
266
|
-
"
|
|
267
|
-
"
|
|
268
|
-
"
|
|
269
|
-
"
|
|
270
|
-
"
|
|
240
|
+
"panelDim": "NPLLIq_panelDim",
|
|
241
|
+
"settingsBtnActive": "NPLLIq_settingsBtnActive",
|
|
242
|
+
"versionNew": "NPLLIq_versionNew",
|
|
243
|
+
"dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
|
|
244
|
+
"dialogTabActive": "NPLLIq_dialogTabActive",
|
|
245
|
+
"copyBtn": "NPLLIq_copyBtn",
|
|
246
|
+
"headerActions": "NPLLIq_headerActions",
|
|
247
|
+
"logSearch": "NPLLIq_logSearch",
|
|
271
248
|
"checkUpdatesLabel": "NPLLIq_checkUpdatesLabel",
|
|
272
|
-
"
|
|
249
|
+
"dialogTab": "NPLLIq_dialogTab",
|
|
250
|
+
"upgradeHint": "NPLLIq_upgradeHint",
|
|
273
251
|
"collapse": "NPLLIq_collapse",
|
|
274
|
-
"
|
|
275
|
-
"radioRow": "NPLLIq_radioRow",
|
|
276
|
-
"dialogHeader": "NPLLIq_dialogHeader",
|
|
252
|
+
"dialogTabs": "NPLLIq_dialogTabs",
|
|
277
253
|
"title": "NPLLIq_title",
|
|
278
|
-
"
|
|
254
|
+
"controls": "NPLLIq_controls",
|
|
255
|
+
"logClearBtn": "NPLLIq_logClearBtn",
|
|
256
|
+
"header": "NPLLIq_header",
|
|
257
|
+
"logPagerInfo": "NPLLIq_logPagerInfo",
|
|
258
|
+
"logPagerPages": "NPLLIq_logPagerPages",
|
|
259
|
+
"dialogClose": "NPLLIq_dialogClose",
|
|
260
|
+
"logHeader": "NPLLIq_logHeader",
|
|
261
|
+
"notice": "NPLLIq_notice",
|
|
262
|
+
"dialogBody": "NPLLIq_dialogBody",
|
|
263
|
+
"dialog": "NPLLIq_dialog",
|
|
264
|
+
"panelDimStrong": "NPLLIq_panelDimStrong",
|
|
265
|
+
"logClearDate": "NPLLIq_logClearDate",
|
|
279
266
|
"save": "NPLLIq_save",
|
|
267
|
+
"logUsedCol": "NPLLIq_logUsedCol",
|
|
268
|
+
"monitorName": "NPLLIq_monitorName",
|
|
269
|
+
"monitorRow": "NPLLIq_monitorRow",
|
|
270
|
+
"dialogBtn": "NPLLIq_dialogBtn",
|
|
271
|
+
"dialogActions": "NPLLIq_dialogActions",
|
|
272
|
+
"upgradeBannerText": "NPLLIq_upgradeBannerText",
|
|
273
|
+
"selectBtn": "NPLLIq_selectBtn",
|
|
274
|
+
"logPagerBtn": "NPLLIq_logPagerBtn",
|
|
275
|
+
"upgradeCommand": "NPLLIq_upgradeCommand",
|
|
276
|
+
"row": "NPLLIq_row",
|
|
277
|
+
"currentBadge": "NPLLIq_currentBadge",
|
|
278
|
+
"monitorList": "NPLLIq_monitorList",
|
|
279
|
+
"tabLabel": "NPLLIq_tabLabel",
|
|
280
|
+
"fillIdle": "NPLLIq_fillIdle",
|
|
280
281
|
"checkErrorHint": "NPLLIq_checkErrorHint",
|
|
281
|
-
"
|
|
282
|
-
"dialogLabel": "NPLLIq_dialogLabel",
|
|
283
|
-
"logPagerInfo": "NPLLIq_logPagerInfo",
|
|
284
|
-
"panelDim": "NPLLIq_panelDim",
|
|
285
|
-
"fillWarn": "NPLLIq_fillWarn",
|
|
282
|
+
"dialogTitle": "NPLLIq_dialogTitle",
|
|
286
283
|
"monitorHint": "NPLLIq_monitorHint",
|
|
287
|
-
"
|
|
288
|
-
"
|
|
289
|
-
"
|
|
284
|
+
"tabIcon": "NPLLIq_tabIcon",
|
|
285
|
+
"panel": "NPLLIq_panel",
|
|
286
|
+
"resetSelect": "NPLLIq_resetSelect",
|
|
287
|
+
"checkBtn": "NPLLIq_checkBtn",
|
|
288
|
+
"logTable": "NPLLIq_logTable",
|
|
289
|
+
"tab": "NPLLIq_tab",
|
|
290
|
+
"rowMeta": "NPLLIq_rowMeta",
|
|
291
|
+
"logToolbar": "NPLLIq_logToolbar",
|
|
292
|
+
"fullNotice": "NPLLIq_fullNotice",
|
|
293
|
+
"dialogSection": "NPLLIq_dialogSection"
|
|
290
294
|
};
|
|
291
295
|
//#endregion
|
|
292
296
|
//#region lib/types/client/TokenQuotaPanel.js
|
|
@@ -379,6 +383,7 @@ window.__ModuleLoader__.load({
|
|
|
379
383
|
const [editingKey, setEditingKey] = (0, react.useState)(null);
|
|
380
384
|
const [hovered, setHovered] = (0, react.useState)(false);
|
|
381
385
|
const [inputActive, setInputActive] = (0, react.useState)(false);
|
|
386
|
+
const [settingsTab, setSettingsTab] = (0, react.useState)("quota");
|
|
382
387
|
const [copiedCmd, setCopiedCmd] = (0, react.useState)(null);
|
|
383
388
|
const copyTimerRef = (0, react.useRef)(null);
|
|
384
389
|
const [upgradeFlash, setUpgradeFlash] = (0, react.useState)(false);
|
|
@@ -592,13 +597,13 @@ window.__ModuleLoader__.load({
|
|
|
592
597
|
title: t("upgradeAvailableHint"),
|
|
593
598
|
children: [
|
|
594
599
|
"v",
|
|
595
|
-
"0.1.
|
|
600
|
+
"0.1.31",
|
|
596
601
|
" → v",
|
|
597
602
|
upgrade.latestVersion
|
|
598
603
|
]
|
|
599
604
|
}) : (0, react_jsx_runtime.jsxs)("span", {
|
|
600
605
|
className: TokenQuotaPanel_module_css_default.version,
|
|
601
|
-
children: ["v", "0.1.
|
|
606
|
+
children: ["v", "0.1.31"]
|
|
602
607
|
})]
|
|
603
608
|
}), (0, react_jsx_runtime.jsx)("div", {
|
|
604
609
|
className: TokenQuotaPanel_module_css_default.subtitle,
|
|
@@ -787,7 +792,7 @@ window.__ModuleLoader__.load({
|
|
|
787
792
|
}),
|
|
788
793
|
dialogOpen && (0, react_jsx_runtime.jsxs)("div", {
|
|
789
794
|
ref: settingsRef,
|
|
790
|
-
className: TokenQuotaPanel_module_css_default.dialog
|
|
795
|
+
className: `${TokenQuotaPanel_module_css_default.dialog} ${TokenQuotaPanel_module_css_default.settingsDialog}`,
|
|
791
796
|
style: settingsPos !== null ? {
|
|
792
797
|
left: settingsPos.x,
|
|
793
798
|
top: settingsPos.y,
|
|
@@ -816,6 +821,42 @@ window.__ModuleLoader__.load({
|
|
|
816
821
|
})]
|
|
817
822
|
}),
|
|
818
823
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
824
|
+
className: TokenQuotaPanel_module_css_default.dialogTabs,
|
|
825
|
+
role: "tablist",
|
|
826
|
+
children: [
|
|
827
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
828
|
+
type: "button",
|
|
829
|
+
role: "tab",
|
|
830
|
+
"aria-selected": settingsTab === "quota",
|
|
831
|
+
className: `${TokenQuotaPanel_module_css_default.dialogTab}${settingsTab === "quota" ? ` ${TokenQuotaPanel_module_css_default.dialogTabActive}` : ""}`,
|
|
832
|
+
onClick: () => {
|
|
833
|
+
setSettingsTab("quota");
|
|
834
|
+
},
|
|
835
|
+
children: t("settingsTabQuota")
|
|
836
|
+
}),
|
|
837
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
838
|
+
type: "button",
|
|
839
|
+
role: "tab",
|
|
840
|
+
"aria-selected": settingsTab === "music",
|
|
841
|
+
className: `${TokenQuotaPanel_module_css_default.dialogTab}${settingsTab === "music" ? ` ${TokenQuotaPanel_module_css_default.dialogTabActive}` : ""}`,
|
|
842
|
+
onClick: () => {
|
|
843
|
+
setSettingsTab("music");
|
|
844
|
+
},
|
|
845
|
+
children: t("settingsTabMusic")
|
|
846
|
+
}),
|
|
847
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
848
|
+
type: "button",
|
|
849
|
+
role: "tab",
|
|
850
|
+
"aria-selected": settingsTab === "other",
|
|
851
|
+
className: `${TokenQuotaPanel_module_css_default.dialogTab}${settingsTab === "other" ? ` ${TokenQuotaPanel_module_css_default.dialogTabActive}` : ""}`,
|
|
852
|
+
onClick: () => {
|
|
853
|
+
setSettingsTab("other");
|
|
854
|
+
},
|
|
855
|
+
children: t("settingsTabOther")
|
|
856
|
+
})
|
|
857
|
+
]
|
|
858
|
+
}),
|
|
859
|
+
settingsTab === "quota" && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
819
860
|
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
820
861
|
children: [
|
|
821
862
|
(0, react_jsx_runtime.jsx)("div", {
|
|
@@ -848,8 +889,7 @@ window.__ModuleLoader__.load({
|
|
|
848
889
|
}, model.key))
|
|
849
890
|
})
|
|
850
891
|
]
|
|
851
|
-
}),
|
|
852
|
-
(0, react_jsx_runtime.jsxs)("div", {
|
|
892
|
+
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
853
893
|
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
854
894
|
children: [(0, react_jsx_runtime.jsx)("div", {
|
|
855
895
|
className: TokenQuotaPanel_module_css_default.dialogLabel,
|
|
@@ -865,8 +905,8 @@ window.__ModuleLoader__.load({
|
|
|
865
905
|
}
|
|
866
906
|
}), (0, react_jsx_runtime.jsx)("span", { children: t(action.labelKey) })]
|
|
867
907
|
}, action.value))]
|
|
868
|
-
}),
|
|
869
|
-
(0, react_jsx_runtime.jsxs)("div", {
|
|
908
|
+
})] }),
|
|
909
|
+
settingsTab === "other" && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
870
910
|
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
871
911
|
children: [
|
|
872
912
|
(0, react_jsx_runtime.jsx)("div", {
|
|
@@ -928,8 +968,7 @@ window.__ModuleLoader__.load({
|
|
|
928
968
|
]
|
|
929
969
|
})
|
|
930
970
|
]
|
|
931
|
-
}),
|
|
932
|
-
(0, react_jsx_runtime.jsxs)("div", {
|
|
971
|
+
}), (0, react_jsx_runtime.jsxs)("div", {
|
|
933
972
|
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
934
973
|
children: [(0, react_jsx_runtime.jsxs)("label", {
|
|
935
974
|
className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
|
|
@@ -944,79 +983,78 @@ window.__ModuleLoader__.load({
|
|
|
944
983
|
className: TokenQuotaPanel_module_css_default.dialogHint,
|
|
945
984
|
children: t("dimWhenIdleHint")
|
|
946
985
|
})]
|
|
947
|
-
}),
|
|
948
|
-
(0, react_jsx_runtime.jsxs)("div", {
|
|
986
|
+
})] }),
|
|
987
|
+
settingsTab === "music" && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
988
|
+
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
989
|
+
children: [(0, react_jsx_runtime.jsxs)("label", {
|
|
990
|
+
className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
|
|
991
|
+
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
992
|
+
type: "checkbox",
|
|
993
|
+
checked: musicEnabled,
|
|
994
|
+
onChange: (event) => {
|
|
995
|
+
setMusicEnabled(event.target.checked);
|
|
996
|
+
}
|
|
997
|
+
}), (0, react_jsx_runtime.jsx)("span", { children: t("musicLabel") })]
|
|
998
|
+
}), (0, react_jsx_runtime.jsx)("div", {
|
|
999
|
+
className: TokenQuotaPanel_module_css_default.dialogHint,
|
|
1000
|
+
children: t("musicHint")
|
|
1001
|
+
})]
|
|
1002
|
+
}), musicEnabled && (0, react_jsx_runtime.jsxs)("div", {
|
|
949
1003
|
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
950
1004
|
children: [
|
|
1005
|
+
(0, react_jsx_runtime.jsxs)("label", {
|
|
1006
|
+
className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
|
|
1007
|
+
children: [(0, react_jsx_runtime.jsx)("span", { children: t("musicVolume") }), (0, react_jsx_runtime.jsx)("input", {
|
|
1008
|
+
type: "range",
|
|
1009
|
+
min: 0,
|
|
1010
|
+
max: 1,
|
|
1011
|
+
step: .05,
|
|
1012
|
+
value: musicVolume,
|
|
1013
|
+
onChange: (event) => {
|
|
1014
|
+
setMusicVolume(Number(event.target.value));
|
|
1015
|
+
}
|
|
1016
|
+
})]
|
|
1017
|
+
}),
|
|
1018
|
+
(0, react_jsx_runtime.jsxs)("label", {
|
|
1019
|
+
className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
|
|
1020
|
+
children: [(0, react_jsx_runtime.jsx)("span", { children: t("musicStyle") }), (0, react_jsx_runtime.jsxs)("select", {
|
|
1021
|
+
value: musicStyle,
|
|
1022
|
+
onChange: (event) => {
|
|
1023
|
+
setMusicStyle(event.target.value);
|
|
1024
|
+
},
|
|
1025
|
+
children: [
|
|
1026
|
+
(0, react_jsx_runtime.jsx)("option", {
|
|
1027
|
+
value: "major",
|
|
1028
|
+
children: t("musicStyleMajor")
|
|
1029
|
+
}),
|
|
1030
|
+
(0, react_jsx_runtime.jsx)("option", {
|
|
1031
|
+
value: "minor",
|
|
1032
|
+
children: t("musicStyleMinor")
|
|
1033
|
+
}),
|
|
1034
|
+
(0, react_jsx_runtime.jsx)("option", {
|
|
1035
|
+
value: "pentatonic",
|
|
1036
|
+
children: t("musicStylePentatonic")
|
|
1037
|
+
})
|
|
1038
|
+
]
|
|
1039
|
+
})]
|
|
1040
|
+
}),
|
|
951
1041
|
(0, react_jsx_runtime.jsxs)("label", {
|
|
952
1042
|
className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
|
|
953
1043
|
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
954
1044
|
type: "checkbox",
|
|
955
|
-
checked:
|
|
1045
|
+
checked: musicOnlyCurrentSession,
|
|
956
1046
|
onChange: (event) => {
|
|
957
|
-
|
|
1047
|
+
setMusicOnlyCurrentSession(event.target.checked);
|
|
958
1048
|
}
|
|
959
|
-
}), (0, react_jsx_runtime.jsx)("span", { children: t("
|
|
1049
|
+
}), (0, react_jsx_runtime.jsx)("span", { children: t("musicOnlyCurrentSessionLabel") })]
|
|
960
1050
|
}),
|
|
961
1051
|
(0, react_jsx_runtime.jsx)("div", {
|
|
962
1052
|
className: TokenQuotaPanel_module_css_default.dialogHint,
|
|
963
|
-
children: t("
|
|
964
|
-
})
|
|
965
|
-
musicEnabled && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
966
|
-
(0, react_jsx_runtime.jsxs)("label", {
|
|
967
|
-
className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
|
|
968
|
-
children: [(0, react_jsx_runtime.jsx)("span", { children: t("musicVolume") }), (0, react_jsx_runtime.jsx)("input", {
|
|
969
|
-
type: "range",
|
|
970
|
-
min: 0,
|
|
971
|
-
max: 1,
|
|
972
|
-
step: .05,
|
|
973
|
-
value: musicVolume,
|
|
974
|
-
onChange: (event) => {
|
|
975
|
-
setMusicVolume(Number(event.target.value));
|
|
976
|
-
}
|
|
977
|
-
})]
|
|
978
|
-
}),
|
|
979
|
-
(0, react_jsx_runtime.jsxs)("label", {
|
|
980
|
-
className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
|
|
981
|
-
children: [(0, react_jsx_runtime.jsx)("span", { children: t("musicStyle") }), (0, react_jsx_runtime.jsxs)("select", {
|
|
982
|
-
value: musicStyle,
|
|
983
|
-
onChange: (event) => {
|
|
984
|
-
setMusicStyle(event.target.value);
|
|
985
|
-
},
|
|
986
|
-
children: [
|
|
987
|
-
(0, react_jsx_runtime.jsx)("option", {
|
|
988
|
-
value: "major",
|
|
989
|
-
children: t("musicStyleMajor")
|
|
990
|
-
}),
|
|
991
|
-
(0, react_jsx_runtime.jsx)("option", {
|
|
992
|
-
value: "minor",
|
|
993
|
-
children: t("musicStyleMinor")
|
|
994
|
-
}),
|
|
995
|
-
(0, react_jsx_runtime.jsx)("option", {
|
|
996
|
-
value: "pentatonic",
|
|
997
|
-
children: t("musicStylePentatonic")
|
|
998
|
-
})
|
|
999
|
-
]
|
|
1000
|
-
})]
|
|
1001
|
-
}),
|
|
1002
|
-
(0, react_jsx_runtime.jsxs)("label", {
|
|
1003
|
-
className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
|
|
1004
|
-
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
1005
|
-
type: "checkbox",
|
|
1006
|
-
checked: musicOnlyCurrentSession,
|
|
1007
|
-
onChange: (event) => {
|
|
1008
|
-
setMusicOnlyCurrentSession(event.target.checked);
|
|
1009
|
-
}
|
|
1010
|
-
}), (0, react_jsx_runtime.jsx)("span", { children: t("musicOnlyCurrentSessionLabel") })]
|
|
1011
|
-
}),
|
|
1012
|
-
(0, react_jsx_runtime.jsx)("div", {
|
|
1013
|
-
className: TokenQuotaPanel_module_css_default.dialogHint,
|
|
1014
|
-
children: t("musicOnlyCurrentSessionHint")
|
|
1015
|
-
})
|
|
1016
|
-
] })
|
|
1053
|
+
children: t("musicOnlyCurrentSessionHint")
|
|
1054
|
+
})
|
|
1017
1055
|
]
|
|
1018
|
-
}),
|
|
1019
|
-
(0, react_jsx_runtime.jsxs)("div", {
|
|
1056
|
+
})] }),
|
|
1057
|
+
settingsTab === "other" && (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: (0, react_jsx_runtime.jsxs)("div", {
|
|
1020
1058
|
className: TokenQuotaPanel_module_css_default.dialogSection,
|
|
1021
1059
|
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
1022
1060
|
className: TokenQuotaPanel_module_css_default.checkUpdatesRow,
|
|
@@ -1041,7 +1079,7 @@ window.__ModuleLoader__.load({
|
|
|
1041
1079
|
role: "alert",
|
|
1042
1080
|
children: upgradeError
|
|
1043
1081
|
})]
|
|
1044
|
-
})
|
|
1082
|
+
}) })
|
|
1045
1083
|
]
|
|
1046
1084
|
}),
|
|
1047
1085
|
logOpen && (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1512,6 +1550,10 @@ window.__ModuleLoader__.load({
|
|
|
1512
1550
|
get started() {
|
|
1513
1551
|
return this.audio !== null;
|
|
1514
1552
|
}
|
|
1553
|
+
/** True when the master switch is on (mirrors the settings document). */
|
|
1554
|
+
get isEnabled() {
|
|
1555
|
+
return this.enabled;
|
|
1556
|
+
}
|
|
1515
1557
|
/**
|
|
1516
1558
|
* Start the audio context and probe for a MIDI output (once). Must be
|
|
1517
1559
|
* called inside a user gesture so the AudioContext can resume.
|
|
@@ -1584,7 +1626,7 @@ window.__ModuleLoader__.load({
|
|
|
1584
1626
|
break;
|
|
1585
1627
|
case "request/header":
|
|
1586
1628
|
if (!this.playing) this.startPiece();
|
|
1587
|
-
else this.pluck(
|
|
1629
|
+
else this.pluck(this.tone(5, 1), .3, .9);
|
|
1588
1630
|
break;
|
|
1589
1631
|
case "step/start": {
|
|
1590
1632
|
const prog = PROGRESSION[this.style];
|
|
@@ -1596,31 +1638,51 @@ window.__ModuleLoader__.load({
|
|
|
1596
1638
|
break;
|
|
1597
1639
|
}
|
|
1598
1640
|
case "tool/call":
|
|
1599
|
-
this.pluck(
|
|
1600
|
-
this.pluck(
|
|
1641
|
+
this.pluck(this.tone(4, 1), .38, .9);
|
|
1642
|
+
setTimeout(() => this.pluck(this.tone(5, 1), .34, .9), 90);
|
|
1643
|
+
this.pluck(this.tonicRoot - 12, .22, .9);
|
|
1601
1644
|
break;
|
|
1602
1645
|
case "tool/result":
|
|
1603
1646
|
if (action.error) {
|
|
1604
|
-
|
|
1605
|
-
|
|
1647
|
+
const t = this.tone(2, 1);
|
|
1648
|
+
this.pluck(t - 1, .4, .7);
|
|
1649
|
+
setTimeout(() => this.pluck(t - 3, .4, 1), 110);
|
|
1606
1650
|
} else {
|
|
1607
|
-
this.pluck(
|
|
1608
|
-
setTimeout(() => this.pluck(
|
|
1651
|
+
this.pluck(this.tone(3, 1), .34, 1);
|
|
1652
|
+
setTimeout(() => this.pluck(this.tone(1, 1), .32, 1), 90);
|
|
1653
|
+
setTimeout(() => this.pluck(this.tone(0, 1), .34, 1.2), 180);
|
|
1609
1654
|
}
|
|
1610
1655
|
break;
|
|
1611
1656
|
case "assistant/attempt":
|
|
1612
|
-
this.pluck(
|
|
1613
|
-
setTimeout(() => this.pluck(
|
|
1614
|
-
setTimeout(() => this.pluck(
|
|
1657
|
+
this.pluck(this.tone(4, 1), .36, .8);
|
|
1658
|
+
setTimeout(() => this.pluck(this.tone(2, 1), .36, .9), 110);
|
|
1659
|
+
setTimeout(() => this.pluck(this.tone(0), .36, 1.1), 220);
|
|
1615
1660
|
break;
|
|
1616
1661
|
case "assistant/message":
|
|
1617
|
-
this.
|
|
1662
|
+
this.pluck(this.tone(2, 1), .3, 1);
|
|
1663
|
+
setTimeout(() => this.breath(this.tone(0, action.interrupted ? 0 : 1), 1.4), 140);
|
|
1618
1664
|
break;
|
|
1619
1665
|
case "turn/end":
|
|
1620
1666
|
this.stopPiece(true);
|
|
1621
1667
|
break;
|
|
1622
1668
|
}
|
|
1623
1669
|
}
|
|
1670
|
+
/** Current tonic root in MIDI note numbers. */
|
|
1671
|
+
get tonicRoot() {
|
|
1672
|
+
return TokenQuotaMusic.BASE_MIDI + (PROGRESSION[this.style][this.tonicIndex] ?? 0);
|
|
1673
|
+
}
|
|
1674
|
+
/**
|
|
1675
|
+
* A scale tone relative to the current tonic — degrees wrap up octaves
|
|
1676
|
+
* (deg 5 on a 5-note scale = the octave). Event figures use this so every
|
|
1677
|
+
* accent stays inside the key and melts into the piece instead of
|
|
1678
|
+
* clashing with it.
|
|
1679
|
+
*/
|
|
1680
|
+
tone(deg, oct = 0) {
|
|
1681
|
+
const scale = SCALES[this.style];
|
|
1682
|
+
const len = scale.length;
|
|
1683
|
+
const d = (deg % len + len) % len;
|
|
1684
|
+
return this.tonicRoot + 12 * (Math.floor(deg / len) + oct) + (scale[d] ?? 0);
|
|
1685
|
+
}
|
|
1624
1686
|
/** Start a new piece: intro run, then the phrase chain. */
|
|
1625
1687
|
startPiece() {
|
|
1626
1688
|
if (!this.audio || this.playing) return;
|
|
@@ -1852,7 +1914,10 @@ window.__ModuleLoader__.load({
|
|
|
1852
1914
|
expand: "展开",
|
|
1853
1915
|
expandHint: "展开每日 Token 限额面板",
|
|
1854
1916
|
settings: "设置",
|
|
1855
|
-
settingsTitle: "
|
|
1917
|
+
settingsTitle: "设置",
|
|
1918
|
+
settingsTabQuota: "限额设置",
|
|
1919
|
+
settingsTabMusic: "音乐设置",
|
|
1920
|
+
settingsTabOther: "其它",
|
|
1856
1921
|
monitorLabel: "监控模型",
|
|
1857
1922
|
monitorHint: "未勾选的模型不显示、不计入用量、不受限额限制",
|
|
1858
1923
|
monitorAll: "全部",
|
|
@@ -1930,7 +1995,10 @@ window.__ModuleLoader__.load({
|
|
|
1930
1995
|
expand: "Expand",
|
|
1931
1996
|
expandHint: "Expand the daily token quota panel",
|
|
1932
1997
|
settings: "Settings",
|
|
1933
|
-
settingsTitle: "
|
|
1998
|
+
settingsTitle: "Settings",
|
|
1999
|
+
settingsTabQuota: "Quota",
|
|
2000
|
+
settingsTabMusic: "Music",
|
|
2001
|
+
settingsTabOther: "Other",
|
|
1934
2002
|
monitorLabel: "Monitored models",
|
|
1935
2003
|
monitorHint: "Unchecked models are hidden, not metered, and never capped",
|
|
1936
2004
|
monitorAll: "All",
|
|
@@ -2049,6 +2117,24 @@ window.__ModuleLoader__.load({
|
|
|
2049
2117
|
ctx.effect(() => () => {
|
|
2050
2118
|
sse.close();
|
|
2051
2119
|
}, "token-quota-ui: music SSE");
|
|
2120
|
+
const autoStartMusic = () => {
|
|
2121
|
+
if (!music.isEnabled || music.started) {
|
|
2122
|
+
if (music.started) {
|
|
2123
|
+
window.removeEventListener("pointerdown", autoStartMusic);
|
|
2124
|
+
window.removeEventListener("keydown", autoStartMusic);
|
|
2125
|
+
}
|
|
2126
|
+
return;
|
|
2127
|
+
}
|
|
2128
|
+
music.ensureStarted();
|
|
2129
|
+
window.removeEventListener("pointerdown", autoStartMusic);
|
|
2130
|
+
window.removeEventListener("keydown", autoStartMusic);
|
|
2131
|
+
};
|
|
2132
|
+
window.addEventListener("pointerdown", autoStartMusic);
|
|
2133
|
+
window.addEventListener("keydown", autoStartMusic);
|
|
2134
|
+
ctx.effect(() => () => {
|
|
2135
|
+
window.removeEventListener("pointerdown", autoStartMusic);
|
|
2136
|
+
window.removeEventListener("keydown", autoStartMusic);
|
|
2137
|
+
}, "token-quota-ui: music autostart gestures");
|
|
2052
2138
|
/** Build a writable music-settings clone with defaults applied. */
|
|
2053
2139
|
const musicDefaults = (raw) => ({
|
|
2054
2140
|
enabled: raw?.enabled ?? false,
|
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.31";
|
|
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 vs. misc.
|
|
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);
|
|
@@ -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
|
|
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} ${css.settingsDialog}`, 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') }), _jsx("button", { type: "button", role: "tab", "aria-selected": settingsTab === 'other', className: `${css.dialogTab}${settingsTab === 'other' ? ` ${css.dialogTabActive}` : ''}`, onClick: () => { setSettingsTab('other'); }, children: t('settingsTabOther') })] }), 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)))] })] })), settingsTab === 'other' && (_jsxs(_Fragment, { children: [_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(_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 === 'other' && (_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') })] })] }) }))] }));
|
|
@@ -66,6 +66,29 @@ export function apply(ctx) {
|
|
|
66
66
|
music.onAction(action);
|
|
67
67
|
});
|
|
68
68
|
ctx.effect(() => () => { sse.close(); }, 'token-quota-ui: music SSE');
|
|
69
|
+
// Browser autoplay policy: an AudioContext only starts inside a user
|
|
70
|
+
// gesture. When the switch was left ON and the page reloads, the setting
|
|
71
|
+
// is enabled but no gesture has happened yet — so the engine stays silent
|
|
72
|
+
// until the user toggles it off/on. Arm a one-shot gesture listener that
|
|
73
|
+
// starts the engine on the first click / keypress instead.
|
|
74
|
+
const autoStartMusic = () => {
|
|
75
|
+
if (!music.isEnabled || music.started) {
|
|
76
|
+
if (music.started) {
|
|
77
|
+
window.removeEventListener('pointerdown', autoStartMusic);
|
|
78
|
+
window.removeEventListener('keydown', autoStartMusic);
|
|
79
|
+
}
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
void music.ensureStarted();
|
|
83
|
+
window.removeEventListener('pointerdown', autoStartMusic);
|
|
84
|
+
window.removeEventListener('keydown', autoStartMusic);
|
|
85
|
+
};
|
|
86
|
+
window.addEventListener('pointerdown', autoStartMusic);
|
|
87
|
+
window.addEventListener('keydown', autoStartMusic);
|
|
88
|
+
ctx.effect(() => () => {
|
|
89
|
+
window.removeEventListener('pointerdown', autoStartMusic);
|
|
90
|
+
window.removeEventListener('keydown', autoStartMusic);
|
|
91
|
+
}, 'token-quota-ui: music autostart gestures');
|
|
69
92
|
/** Build a writable music-settings clone with defaults applied. */
|
|
70
93
|
const musicDefaults = (raw) => ({
|
|
71
94
|
enabled: raw?.enabled ?? false,
|
|
@@ -25,6 +25,9 @@ export declare const zh: {
|
|
|
25
25
|
expandHint: string;
|
|
26
26
|
settings: string;
|
|
27
27
|
settingsTitle: string;
|
|
28
|
+
settingsTabQuota: string;
|
|
29
|
+
settingsTabMusic: string;
|
|
30
|
+
settingsTabOther: string;
|
|
28
31
|
monitorLabel: string;
|
|
29
32
|
monitorHint: string;
|
|
30
33
|
monitorAll: string;
|
|
@@ -105,6 +108,9 @@ export declare const en: {
|
|
|
105
108
|
expandHint: string;
|
|
106
109
|
settings: string;
|
|
107
110
|
settingsTitle: string;
|
|
111
|
+
settingsTabQuota: string;
|
|
112
|
+
settingsTabMusic: string;
|
|
113
|
+
settingsTabOther: string;
|
|
108
114
|
monitorLabel: string;
|
|
109
115
|
monitorHint: string;
|
|
110
116
|
monitorAll: string;
|
|
@@ -24,7 +24,10 @@ export const zh = {
|
|
|
24
24
|
expand: '展开',
|
|
25
25
|
expandHint: '展开每日 Token 限额面板',
|
|
26
26
|
settings: '设置',
|
|
27
|
-
settingsTitle: '
|
|
27
|
+
settingsTitle: '设置',
|
|
28
|
+
settingsTabQuota: '限额设置',
|
|
29
|
+
settingsTabMusic: '音乐设置',
|
|
30
|
+
settingsTabOther: '其它',
|
|
28
31
|
monitorLabel: '监控模型',
|
|
29
32
|
monitorHint: '未勾选的模型不显示、不计入用量、不受限额限制',
|
|
30
33
|
monitorAll: '全部',
|
|
@@ -102,7 +105,10 @@ export const en = {
|
|
|
102
105
|
expand: 'Expand',
|
|
103
106
|
expandHint: 'Expand the daily token quota panel',
|
|
104
107
|
settings: 'Settings',
|
|
105
|
-
settingsTitle: '
|
|
108
|
+
settingsTitle: 'Settings',
|
|
109
|
+
settingsTabQuota: 'Quota',
|
|
110
|
+
settingsTabMusic: 'Music',
|
|
111
|
+
settingsTabOther: 'Other',
|
|
106
112
|
monitorLabel: 'Monitored models',
|
|
107
113
|
monitorHint: 'Unchecked models are hidden, not metered, and never capped',
|
|
108
114
|
monitorAll: 'All',
|
|
@@ -56,6 +56,8 @@ export declare class TokenQuotaMusic {
|
|
|
56
56
|
private static readonly STREAM_TIMEOUT_MS;
|
|
57
57
|
/** True once the audio context has been started (needs a user gesture). */
|
|
58
58
|
get started(): boolean;
|
|
59
|
+
/** True when the master switch is on (mirrors the settings document). */
|
|
60
|
+
get isEnabled(): boolean;
|
|
59
61
|
/**
|
|
60
62
|
* Start the audio context and probe for a MIDI output (once). Must be
|
|
61
63
|
* called inside a user gesture so the AudioContext can resume.
|
|
@@ -70,6 +72,15 @@ export declare class TokenQuotaMusic {
|
|
|
70
72
|
stop(): void;
|
|
71
73
|
/** Handle one incoming host action and steer the piece. */
|
|
72
74
|
onAction(action: TokenQuotaMusicAction): void;
|
|
75
|
+
/** Current tonic root in MIDI note numbers. */
|
|
76
|
+
private get tonicRoot();
|
|
77
|
+
/**
|
|
78
|
+
* A scale tone relative to the current tonic — degrees wrap up octaves
|
|
79
|
+
* (deg 5 on a 5-note scale = the octave). Event figures use this so every
|
|
80
|
+
* accent stays inside the key and melts into the piece instead of
|
|
81
|
+
* clashing with it.
|
|
82
|
+
*/
|
|
83
|
+
private tone;
|
|
73
84
|
/** Start a new piece: intro run, then the phrase chain. */
|
|
74
85
|
private startPiece;
|
|
75
86
|
/** Play one phrase, then chain into the next after a one-beat rest. */
|
|
@@ -98,6 +98,10 @@ export class TokenQuotaMusic {
|
|
|
98
98
|
get started() {
|
|
99
99
|
return this.audio !== null;
|
|
100
100
|
}
|
|
101
|
+
/** True when the master switch is on (mirrors the settings document). */
|
|
102
|
+
get isEnabled() {
|
|
103
|
+
return this.enabled;
|
|
104
|
+
}
|
|
101
105
|
/**
|
|
102
106
|
* Start the audio context and probe for a MIDI output (once). Must be
|
|
103
107
|
* called inside a user gesture so the AudioContext can resume.
|
|
@@ -194,7 +198,7 @@ export class TokenQuotaMusic {
|
|
|
194
198
|
if (!this.playing)
|
|
195
199
|
this.startPiece();
|
|
196
200
|
else
|
|
197
|
-
this.pluck(
|
|
201
|
+
this.pluck(this.tone(5, 1), 0.3, 0.9);
|
|
198
202
|
break;
|
|
199
203
|
}
|
|
200
204
|
case 'step/start': {
|
|
@@ -207,40 +211,67 @@ export class TokenQuotaMusic {
|
|
|
207
211
|
}
|
|
208
212
|
break;
|
|
209
213
|
}
|
|
210
|
-
case 'tool/call':
|
|
211
|
-
//
|
|
212
|
-
|
|
213
|
-
this.pluck(
|
|
214
|
+
case 'tool/call': {
|
|
215
|
+
// Rising two-note figure drawn from the current scale (so it blends
|
|
216
|
+
// with the piece, not pokes out of it) over a soft low root for body.
|
|
217
|
+
this.pluck(this.tone(4, 1), 0.38, 0.9);
|
|
218
|
+
setTimeout(() => this.pluck(this.tone(5, 1), 0.34, 0.9), 90);
|
|
219
|
+
this.pluck(this.tonicRoot - 12, 0.22, 0.9);
|
|
214
220
|
break;
|
|
221
|
+
}
|
|
215
222
|
case 'tool/result': {
|
|
216
223
|
if (action.error) {
|
|
217
|
-
|
|
218
|
-
|
|
224
|
+
// Deliberately sour (an error should feel off): a half-step below a
|
|
225
|
+
// scale tone, then sinking further.
|
|
226
|
+
const t = this.tone(2, 1);
|
|
227
|
+
this.pluck(t - 1, 0.4, 0.7);
|
|
228
|
+
setTimeout(() => this.pluck(t - 3, 0.4, 1.0), 110);
|
|
219
229
|
}
|
|
220
230
|
else {
|
|
221
|
-
|
|
222
|
-
|
|
231
|
+
// Gentle in-key resolve landing on the tonic octave.
|
|
232
|
+
this.pluck(this.tone(3, 1), 0.34, 1.0);
|
|
233
|
+
setTimeout(() => this.pluck(this.tone(1, 1), 0.32, 1.0), 90);
|
|
234
|
+
setTimeout(() => this.pluck(this.tone(0, 1), 0.34, 1.2), 180);
|
|
223
235
|
}
|
|
224
236
|
break;
|
|
225
237
|
}
|
|
226
|
-
case 'assistant/attempt':
|
|
227
|
-
// Failed attempt: falling tension figure.
|
|
228
|
-
this.pluck(
|
|
229
|
-
setTimeout(() => this.pluck(
|
|
230
|
-
setTimeout(() => this.pluck(
|
|
238
|
+
case 'assistant/attempt': {
|
|
239
|
+
// Failed attempt: falling in-key tension figure.
|
|
240
|
+
this.pluck(this.tone(4, 1), 0.36, 0.8);
|
|
241
|
+
setTimeout(() => this.pluck(this.tone(2, 1), 0.36, 0.9), 110);
|
|
242
|
+
setTimeout(() => this.pluck(this.tone(0), 0.36, 1.1), 220);
|
|
231
243
|
break;
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
//
|
|
235
|
-
//
|
|
236
|
-
|
|
244
|
+
}
|
|
245
|
+
case 'assistant/message': {
|
|
246
|
+
// Sentence end: a short cadence figure, then a breath on the tonic
|
|
247
|
+
// octave (in key — the old fixed C clashed with the mode rotation).
|
|
248
|
+
// The bed keeps playing until the turn fully ends (turn/end).
|
|
249
|
+
this.pluck(this.tone(2, 1), 0.3, 1.0);
|
|
250
|
+
setTimeout(() => this.breath(this.tone(0, action.interrupted ? 0 : 1), 1.4), 140);
|
|
237
251
|
break;
|
|
252
|
+
}
|
|
238
253
|
case 'turn/end':
|
|
239
254
|
this.stopPiece(true);
|
|
240
255
|
break;
|
|
241
256
|
}
|
|
242
257
|
}
|
|
243
258
|
// ── piece lifecycle ───────────────────────────────────────────────────
|
|
259
|
+
/** Current tonic root in MIDI note numbers. */
|
|
260
|
+
get tonicRoot() {
|
|
261
|
+
return TokenQuotaMusic.BASE_MIDI + (PROGRESSION[this.style][this.tonicIndex] ?? 0);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* A scale tone relative to the current tonic — degrees wrap up octaves
|
|
265
|
+
* (deg 5 on a 5-note scale = the octave). Event figures use this so every
|
|
266
|
+
* accent stays inside the key and melts into the piece instead of
|
|
267
|
+
* clashing with it.
|
|
268
|
+
*/
|
|
269
|
+
tone(deg, oct = 0) {
|
|
270
|
+
const scale = SCALES[this.style];
|
|
271
|
+
const len = scale.length;
|
|
272
|
+
const d = ((deg % len) + len) % len;
|
|
273
|
+
return this.tonicRoot + 12 * (Math.floor(deg / len) + oct) + (scale[d] ?? 0);
|
|
274
|
+
}
|
|
244
275
|
/** Start a new piece: intro run, then the phrase chain. */
|
|
245
276
|
startPiece() {
|
|
246
277
|
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.31",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|