@jxgame2020/dsh-token-quota 0.1.30 → 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 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.30" ? upgrade : null;
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: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}";
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,95 +201,96 @@ 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",
207
- "gearBtn": "NPLLIq_gearBtn",
208
- "monitorHint": "NPLLIq_monitorHint",
204
+ "body": "NPLLIq_body",
209
205
  "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",
206
+ "rowName": "NPLLIq_rowName",
216
207
  "rowHeader": "NPLLIq_rowHeader",
217
- "input": "NPLLIq_input",
218
- "settingsBtnActive": "NPLLIq_settingsBtnActive",
219
- "settingsBtn": "NPLLIq_settingsBtn",
208
+ "gearBtn": "NPLLIq_gearBtn",
209
+ "radioRow": "NPLLIq_radioRow",
210
+ "resetRow": "NPLLIq_resetRow",
211
+ "logModelCol": "NPLLIq_logModelCol",
212
+ "logClearDialog": "NPLLIq_logClearDialog",
213
+ "upgradeClose": "NPLLIq_upgradeClose",
220
214
  "subtitle": "NPLLIq_subtitle",
215
+ "fillWarn": "NPLLIq_fillWarn",
216
+ "noticeError": "NPLLIq_noticeError",
217
+ "upgradeCommandRow": "NPLLIq_upgradeCommandRow",
218
+ "logDialog": "NPLLIq_logDialog",
219
+ "dialogLabel": "NPLLIq_dialogLabel",
220
+ "settingsBtn": "NPLLIq_settingsBtn",
221
+ "dialogHeader": "NPLLIq_dialogHeader",
222
+ "upgradeBannerFlash": "NPLLIq_upgradeBannerFlash",
221
223
  "copyBtnDone": "NPLLIq_copyBtnDone",
222
- "checkBtn": "NPLLIq_checkBtn",
223
- "dialogTitle": "NPLLIq_dialogTitle",
224
- "monitorRow": "NPLLIq_monitorRow",
224
+ "upgradeBanner": "NPLLIq_upgradeBanner",
225
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",
232
226
  "logDayCol": "NPLLIq_logDayCol",
233
- "resetRow": "NPLLIq_resetRow",
234
227
  "logPager": "NPLLIq_logPager",
235
- "collapse": "NPLLIq_collapse",
236
- "upgradeHint": "NPLLIq_upgradeHint",
237
- "logClearBtn": "NPLLIq_logClearBtn",
238
- "version": "NPLLIq_version",
239
228
  "upgradeCommands": "NPLLIq_upgradeCommands",
240
- "notice": "NPLLIq_notice",
241
- "upgradeBannerText": "NPLLIq_upgradeBannerText",
242
- "monitorList": "NPLLIq_monitorList",
243
- "logClearDialog": "NPLLIq_logClearDialog",
229
+ "fillOver": "NPLLIq_fillOver",
230
+ "checkUpdatesRow": "NPLLIq_checkUpdatesRow",
244
231
  "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",
256
- "dialogClose": "NPLLIq_dialogClose",
257
232
  "switch": "NPLLIq_switch",
258
- "logToolbar": "NPLLIq_logToolbar",
259
- "dialog": "NPLLIq_dialog",
260
- "tabLabel": "NPLLIq_tabLabel",
261
- "currentBadge": "NPLLIq_currentBadge",
262
- "copyBtn": "NPLLIq_copyBtn",
263
- "logDialog": "NPLLIq_logDialog",
264
- "logSearch": "NPLLIq_logSearch",
233
+ "dialogHint": "NPLLIq_dialogHint",
265
234
  "dialogOverlay": "NPLLIq_dialogOverlay",
266
- "noticeError": "NPLLIq_noticeError",
267
- "headerActions": "NPLLIq_headerActions",
235
+ "version": "NPLLIq_version",
236
+ "input": "NPLLIq_input",
237
+ "logPagerControls": "NPLLIq_logPagerControls",
238
+ "settingsDialog": "NPLLIq_settingsDialog",
239
+ "logPageSizeSelect": "NPLLIq_logPageSizeSelect",
268
240
  "panelDim": "NPLLIq_panelDim",
269
- "tab": "NPLLIq_tab",
270
- "upgradeCommandRow": "NPLLIq_upgradeCommandRow",
271
- "checkUpdatesRow": "NPLLIq_checkUpdatesRow",
272
- "dialogHint": "NPLLIq_dialogHint",
273
- "logPagerPages": "NPLLIq_logPagerPages",
241
+ "settingsBtnActive": "NPLLIq_settingsBtnActive",
274
242
  "versionNew": "NPLLIq_versionNew",
275
- "body": "NPLLIq_body",
276
- "rowMeta": "NPLLIq_rowMeta",
277
- "dialogSection": "NPLLIq_dialogSection",
278
- "logUsedCol": "NPLLIq_logUsedCol",
279
- "logPagerControls": "NPLLIq_logPagerControls",
280
- "fillIdle": "NPLLIq_fillIdle",
243
+ "dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
244
+ "dialogTabActive": "NPLLIq_dialogTabActive",
245
+ "copyBtn": "NPLLIq_copyBtn",
246
+ "headerActions": "NPLLIq_headerActions",
247
+ "logSearch": "NPLLIq_logSearch",
248
+ "checkUpdatesLabel": "NPLLIq_checkUpdatesLabel",
249
+ "dialogTab": "NPLLIq_dialogTab",
250
+ "upgradeHint": "NPLLIq_upgradeHint",
251
+ "collapse": "NPLLIq_collapse",
252
+ "dialogTabs": "NPLLIq_dialogTabs",
253
+ "title": "NPLLIq_title",
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",
281
266
  "save": "NPLLIq_save",
282
- "upgradeBanner": "NPLLIq_upgradeBanner",
283
- "logPagerBtn": "NPLLIq_logPagerBtn",
267
+ "logUsedCol": "NPLLIq_logUsedCol",
284
268
  "monitorName": "NPLLIq_monitorName",
285
- "rowName": "NPLLIq_rowName",
286
- "upgradeBannerFlash": "NPLLIq_upgradeBannerFlash",
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",
281
+ "checkErrorHint": "NPLLIq_checkErrorHint",
282
+ "dialogTitle": "NPLLIq_dialogTitle",
283
+ "monitorHint": "NPLLIq_monitorHint",
284
+ "tabIcon": "NPLLIq_tabIcon",
287
285
  "panel": "NPLLIq_panel",
288
- "dialogBody": "NPLLIq_dialogBody",
289
- "fillOver": "NPLLIq_fillOver",
290
- "dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
286
+ "resetSelect": "NPLLIq_resetSelect",
287
+ "checkBtn": "NPLLIq_checkBtn",
291
288
  "logTable": "NPLLIq_logTable",
292
- "upgradeClose": "NPLLIq_upgradeClose"
289
+ "tab": "NPLLIq_tab",
290
+ "rowMeta": "NPLLIq_rowMeta",
291
+ "logToolbar": "NPLLIq_logToolbar",
292
+ "fullNotice": "NPLLIq_fullNotice",
293
+ "dialogSection": "NPLLIq_dialogSection"
293
294
  };
294
295
  //#endregion
295
296
  //#region lib/types/client/TokenQuotaPanel.js
@@ -596,13 +597,13 @@ window.__ModuleLoader__.load({
596
597
  title: t("upgradeAvailableHint"),
597
598
  children: [
598
599
  "v",
599
- "0.1.30",
600
+ "0.1.31",
600
601
  " → v",
601
602
  upgrade.latestVersion
602
603
  ]
603
604
  }) : (0, react_jsx_runtime.jsxs)("span", {
604
605
  className: TokenQuotaPanel_module_css_default.version,
605
- children: ["v", "0.1.30"]
606
+ children: ["v", "0.1.31"]
606
607
  })]
607
608
  }), (0, react_jsx_runtime.jsx)("div", {
608
609
  className: TokenQuotaPanel_module_css_default.subtitle,
@@ -791,7 +792,7 @@ window.__ModuleLoader__.load({
791
792
  }),
792
793
  dialogOpen && (0, react_jsx_runtime.jsxs)("div", {
793
794
  ref: settingsRef,
794
- className: TokenQuotaPanel_module_css_default.dialog,
795
+ className: `${TokenQuotaPanel_module_css_default.dialog} ${TokenQuotaPanel_module_css_default.settingsDialog}`,
795
796
  style: settingsPos !== null ? {
796
797
  left: settingsPos.x,
797
798
  top: settingsPos.y,
@@ -822,230 +823,238 @@ window.__ModuleLoader__.load({
822
823
  (0, react_jsx_runtime.jsxs)("div", {
823
824
  className: TokenQuotaPanel_module_css_default.dialogTabs,
824
825
  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")
843
- })]
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
+ ]
844
858
  }),
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", {
859
+ settingsTab === "quota" && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)("div", {
860
+ className: TokenQuotaPanel_module_css_default.dialogSection,
861
+ children: [
862
+ (0, react_jsx_runtime.jsx)("div", {
883
863
  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);
864
+ children: t("monitorLabel")
865
+ }),
866
+ (0, react_jsx_runtime.jsx)("div", {
867
+ className: TokenQuotaPanel_module_css_default.monitorHint,
868
+ children: t("monitorHint")
869
+ }),
870
+ (0, react_jsx_runtime.jsx)("div", {
871
+ className: TokenQuotaPanel_module_css_default.monitorList,
872
+ children: allModels.map((model) => (0, react_jsx_runtime.jsxs)("label", {
873
+ className: TokenQuotaPanel_module_css_default.monitorRow,
874
+ children: [(0, react_jsx_runtime.jsx)("input", {
875
+ type: "checkbox",
876
+ checked: monitored === null || monitored.includes(model.key),
877
+ onChange: (event) => {
878
+ const base = monitored === null ? allModels.map((m) => m.key) : monitored;
879
+ const next = new Set(base);
880
+ if (event.target.checked) next.add(model.key);
881
+ else next.delete(model.key);
882
+ setMonitored(next.size === allModels.length ? null : [...next]);
883
+ }
884
+ }), (0, react_jsx_runtime.jsx)("span", {
885
+ className: TokenQuotaPanel_module_css_default.monitorName,
886
+ title: model.key,
887
+ children: model.name
888
+ })]
889
+ }, model.key))
890
+ })
891
+ ]
892
+ }), (0, react_jsx_runtime.jsxs)("div", {
893
+ className: TokenQuotaPanel_module_css_default.dialogSection,
894
+ children: [(0, react_jsx_runtime.jsx)("div", {
895
+ className: TokenQuotaPanel_module_css_default.dialogLabel,
896
+ children: t("fullActionLabel")
897
+ }), FULL_ACTIONS.map((action) => (0, react_jsx_runtime.jsxs)("label", {
898
+ className: TokenQuotaPanel_module_css_default.radioRow,
899
+ children: [(0, react_jsx_runtime.jsx)("input", {
900
+ type: "radio",
901
+ name: "token-quota-onfull",
902
+ checked: onFull === action.value,
903
+ onChange: () => {
904
+ setOnFull(action.value);
905
+ }
906
+ }), (0, react_jsx_runtime.jsx)("span", { children: t(action.labelKey) })]
907
+ }, action.value))]
908
+ })] }),
909
+ settingsTab === "other" && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)("div", {
910
+ className: TokenQuotaPanel_module_css_default.dialogSection,
911
+ children: [
912
+ (0, react_jsx_runtime.jsx)("div", {
913
+ className: TokenQuotaPanel_module_css_default.dialogLabel,
914
+ children: t("resetLabel")
915
+ }),
916
+ (0, react_jsx_runtime.jsx)("div", {
917
+ className: TokenQuotaPanel_module_css_default.monitorHint,
918
+ children: t("resetHint")
919
+ }),
920
+ (0, react_jsx_runtime.jsxs)("div", {
921
+ className: TokenQuotaPanel_module_css_default.resetRow,
922
+ children: [
923
+ (0, react_jsx_runtime.jsx)("select", {
924
+ className: TokenQuotaPanel_module_css_default.resetSelect,
925
+ value: reset?.offsetHours ?? -(/* @__PURE__ */ new Date()).getTimezoneOffset() / 60,
926
+ onChange: (event) => {
927
+ setReset({
928
+ offsetHours: Number(event.target.value),
929
+ hour: reset?.hour ?? 0,
930
+ minute: reset?.minute ?? 0
931
+ });
932
+ },
933
+ children: Array.from({ length: 27 }, (_, i) => i - 12).map((offset) => (0, react_jsx_runtime.jsxs)("option", {
934
+ value: offset,
935
+ children: ["UTC", offset >= 0 ? `+${offset}` : offset]
936
+ }, offset))
937
+ }),
938
+ (0, react_jsx_runtime.jsx)("select", {
939
+ className: TokenQuotaPanel_module_css_default.resetSelect,
940
+ value: reset?.hour ?? 0,
941
+ onChange: (event) => {
942
+ setReset({
943
+ offsetHours: reset?.offsetHours ?? -(/* @__PURE__ */ new Date()).getTimezoneOffset() / 60,
944
+ hour: Number(event.target.value),
945
+ minute: reset?.minute ?? 0
946
+ });
947
+ },
948
+ children: Array.from({ length: 24 }, (_, i) => i).map((hour) => (0, react_jsx_runtime.jsxs)("option", {
949
+ value: hour,
950
+ children: [String(hour).padStart(2, "0"), " 时"]
951
+ }, hour))
952
+ }),
953
+ (0, react_jsx_runtime.jsx)("select", {
954
+ className: TokenQuotaPanel_module_css_default.resetSelect,
955
+ value: reset?.minute ?? 0,
956
+ onChange: (event) => {
957
+ setReset({
958
+ offsetHours: reset?.offsetHours ?? -(/* @__PURE__ */ new Date()).getTimezoneOffset() / 60,
959
+ hour: reset?.hour ?? 0,
960
+ minute: Number(event.target.value)
961
+ });
962
+ },
963
+ children: Array.from({ length: 12 }, (_, i) => i * 5).map((minute) => (0, react_jsx_runtime.jsxs)("option", {
964
+ value: minute,
965
+ children: [String(minute).padStart(2, "0"), " 分"]
966
+ }, minute))
967
+ })
968
+ ]
969
+ })
970
+ ]
971
+ }), (0, react_jsx_runtime.jsxs)("div", {
972
+ className: TokenQuotaPanel_module_css_default.dialogSection,
973
+ children: [(0, react_jsx_runtime.jsxs)("label", {
974
+ className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
975
+ children: [(0, react_jsx_runtime.jsx)("input", {
976
+ type: "checkbox",
977
+ checked: dimWhenIdle,
978
+ onChange: (event) => {
979
+ setDimWhenIdle(event.target.checked);
980
+ }
981
+ }), (0, react_jsx_runtime.jsx)("span", { children: t("dimWhenIdleLabel") })]
982
+ }), (0, react_jsx_runtime.jsx)("div", {
983
+ className: TokenQuotaPanel_module_css_default.dialogHint,
984
+ children: t("dimWhenIdleHint")
985
+ })]
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", {
1003
+ className: TokenQuotaPanel_module_css_default.dialogSection,
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));
893
1015
  }
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,
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
+ },
910
1025
  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))
1026
+ (0, react_jsx_runtime.jsx)("option", {
1027
+ value: "major",
1028
+ children: t("musicStyleMajor")
925
1029
  }),
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))
1030
+ (0, react_jsx_runtime.jsx)("option", {
1031
+ value: "minor",
1032
+ children: t("musicStyleMinor")
940
1033
  }),
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))
1034
+ (0, react_jsx_runtime.jsx)("option", {
1035
+ value: "pentatonic",
1036
+ children: t("musicStylePentatonic")
955
1037
  })
956
1038
  ]
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", {
978
- className: TokenQuotaPanel_module_css_default.dialogSection,
979
- children: [
1039
+ })]
1040
+ }),
980
1041
  (0, react_jsx_runtime.jsxs)("label", {
981
1042
  className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
982
1043
  children: [(0, react_jsx_runtime.jsx)("input", {
983
1044
  type: "checkbox",
984
- checked: musicEnabled,
1045
+ checked: musicOnlyCurrentSession,
985
1046
  onChange: (event) => {
986
- setMusicEnabled(event.target.checked);
1047
+ setMusicOnlyCurrentSession(event.target.checked);
987
1048
  }
988
- }), (0, react_jsx_runtime.jsx)("span", { children: t("musicLabel") })]
1049
+ }), (0, react_jsx_runtime.jsx)("span", { children: t("musicOnlyCurrentSessionLabel") })]
989
1050
  }),
990
1051
  (0, react_jsx_runtime.jsx)("div", {
991
1052
  className: TokenQuotaPanel_module_css_default.dialogHint,
992
- children: t("musicHint")
993
- }),
994
- musicEnabled && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
995
- (0, react_jsx_runtime.jsxs)("label", {
996
- className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
997
- children: [(0, react_jsx_runtime.jsx)("span", { children: t("musicVolume") }), (0, react_jsx_runtime.jsx)("input", {
998
- type: "range",
999
- min: 0,
1000
- max: 1,
1001
- step: .05,
1002
- value: musicVolume,
1003
- onChange: (event) => {
1004
- setMusicVolume(Number(event.target.value));
1005
- }
1006
- })]
1007
- }),
1008
- (0, react_jsx_runtime.jsxs)("label", {
1009
- className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
1010
- children: [(0, react_jsx_runtime.jsx)("span", { children: t("musicStyle") }), (0, react_jsx_runtime.jsxs)("select", {
1011
- value: musicStyle,
1012
- onChange: (event) => {
1013
- setMusicStyle(event.target.value);
1014
- },
1015
- children: [
1016
- (0, react_jsx_runtime.jsx)("option", {
1017
- value: "major",
1018
- children: t("musicStyleMajor")
1019
- }),
1020
- (0, react_jsx_runtime.jsx)("option", {
1021
- value: "minor",
1022
- children: t("musicStyleMinor")
1023
- }),
1024
- (0, react_jsx_runtime.jsx)("option", {
1025
- value: "pentatonic",
1026
- children: t("musicStylePentatonic")
1027
- })
1028
- ]
1029
- })]
1030
- }),
1031
- (0, react_jsx_runtime.jsxs)("label", {
1032
- className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
1033
- children: [(0, react_jsx_runtime.jsx)("input", {
1034
- type: "checkbox",
1035
- checked: musicOnlyCurrentSession,
1036
- onChange: (event) => {
1037
- setMusicOnlyCurrentSession(event.target.checked);
1038
- }
1039
- }), (0, react_jsx_runtime.jsx)("span", { children: t("musicOnlyCurrentSessionLabel") })]
1040
- }),
1041
- (0, react_jsx_runtime.jsx)("div", {
1042
- className: TokenQuotaPanel_module_css_default.dialogHint,
1043
- children: t("musicOnlyCurrentSessionHint")
1044
- })
1045
- ] })
1053
+ children: t("musicOnlyCurrentSessionHint")
1054
+ })
1046
1055
  ]
1047
- }),
1048
- settingsTab === "quota" && (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: (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", {
1049
1058
  className: TokenQuotaPanel_module_css_default.dialogSection,
1050
1059
  children: [(0, react_jsx_runtime.jsxs)("div", {
1051
1060
  className: TokenQuotaPanel_module_css_default.checkUpdatesRow,
@@ -1541,6 +1550,10 @@ window.__ModuleLoader__.load({
1541
1550
  get started() {
1542
1551
  return this.audio !== null;
1543
1552
  }
1553
+ /** True when the master switch is on (mirrors the settings document). */
1554
+ get isEnabled() {
1555
+ return this.enabled;
1556
+ }
1544
1557
  /**
1545
1558
  * Start the audio context and probe for a MIDI output (once). Must be
1546
1559
  * called inside a user gesture so the AudioContext can resume.
@@ -1904,6 +1917,7 @@ window.__ModuleLoader__.load({
1904
1917
  settingsTitle: "设置",
1905
1918
  settingsTabQuota: "限额设置",
1906
1919
  settingsTabMusic: "音乐设置",
1920
+ settingsTabOther: "其它",
1907
1921
  monitorLabel: "监控模型",
1908
1922
  monitorHint: "未勾选的模型不显示、不计入用量、不受限额限制",
1909
1923
  monitorAll: "全部",
@@ -1984,6 +1998,7 @@ window.__ModuleLoader__.load({
1984
1998
  settingsTitle: "Settings",
1985
1999
  settingsTabQuota: "Quota",
1986
2000
  settingsTabMusic: "Music",
2001
+ settingsTabOther: "Other",
1987
2002
  monitorLabel: "Monitored models",
1988
2003
  monitorHint: "Unchecked models are hidden, not metered, and never capped",
1989
2004
  monitorAll: "All",
@@ -2102,6 +2117,24 @@ window.__ModuleLoader__.load({
2102
2117
  ctx.effect(() => () => {
2103
2118
  sse.close();
2104
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");
2105
2138
  /** Build a writable music-settings clone with defaults applied. */
2106
2139
  const musicDefaults = (raw) => ({
2107
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.30";
518
+ const current = "0.1.31";
519
519
  let latest;
520
520
  try {
521
521
  const response = await fetch(REGISTRY_LATEST_URL, {
@@ -95,7 +95,7 @@ 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.
98
+ // Active settings-dialog tab: quota limits vs. live-music vs. misc.
99
99
  const [settingsTab, setSettingsTab] = useState('quota');
100
100
  // Copy-button feedback: which command was just copied (label flips to
101
101
  // 「已复制」for a moment so the click is perceivable).
@@ -313,7 +313,7 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
313
313
  ? `${formatTokens(row.used)} / ${formatTokens(row.limit)}`
314
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')
315
315
  commitLimit(row); } }), _jsx("button", { type: "button", className: css.save, onClick: () => { commitLimit(row); }, children: t('save') })] }))] }, row.key));
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) => {
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
317
  const base = monitored === null ? allModels.map(m => m.key) : monitored;
318
318
  const next = new Set(base);
319
319
  if (event.target.checked)
@@ -322,7 +322,7 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
322
322
  next.delete(model.key);
323
323
  // Auto-save on every change; all selected stores as null.
324
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) => {
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
326
  setReset({
327
327
  offsetHours: Number(event.target.value),
328
328
  hour: reset?.hour ?? 0,
@@ -340,7 +340,7 @@ export function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored,
340
340
  hour: reset?.hour ?? 0,
341
341
  minute: Number(event.target.value),
342
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
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
344
  ? t('checkingUpdates')
345
345
  : lastCheckResult === 'up-to-date'
346
346
  ? t('checkUpToDate')
@@ -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,
@@ -27,6 +27,7 @@ export declare const zh: {
27
27
  settingsTitle: string;
28
28
  settingsTabQuota: string;
29
29
  settingsTabMusic: string;
30
+ settingsTabOther: string;
30
31
  monitorLabel: string;
31
32
  monitorHint: string;
32
33
  monitorAll: string;
@@ -109,6 +110,7 @@ export declare const en: {
109
110
  settingsTitle: string;
110
111
  settingsTabQuota: string;
111
112
  settingsTabMusic: string;
113
+ settingsTabOther: string;
112
114
  monitorLabel: string;
113
115
  monitorHint: string;
114
116
  monitorAll: string;
@@ -27,6 +27,7 @@ export const zh = {
27
27
  settingsTitle: '设置',
28
28
  settingsTabQuota: '限额设置',
29
29
  settingsTabMusic: '音乐设置',
30
+ settingsTabOther: '其它',
30
31
  monitorLabel: '监控模型',
31
32
  monitorHint: '未勾选的模型不显示、不计入用量、不受限额限制',
32
33
  monitorAll: '全部',
@@ -107,6 +108,7 @@ export const en = {
107
108
  settingsTitle: 'Settings',
108
109
  settingsTabQuota: 'Quota',
109
110
  settingsTabMusic: 'Music',
111
+ settingsTabOther: 'Other',
110
112
  monitorLabel: 'Monitored models',
111
113
  monitorHint: 'Unchecked models are hidden, not metered, and never capped',
112
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.
@@ -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.
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.30",
4
+ "version": "0.1.31",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },