@jxgame2020/dsh-token-quota 0.1.22 → 0.1.23

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
@@ -37,6 +37,9 @@ window.__ModuleLoader__.load({
37
37
  onFull: "stop",
38
38
  checkUpdates: true,
39
39
  dimWhenIdle: false,
40
+ musicEnabled: false,
41
+ musicVolume: .5,
42
+ musicStyle: "major",
40
43
  upgrade: null,
41
44
  upgradeDismissed: false,
42
45
  checkingUpdates: false,
@@ -78,8 +81,17 @@ window.__ModuleLoader__.load({
78
81
  setDimWhenIdle: (d, dimWhenIdle) => {
79
82
  d.dimWhenIdle = dimWhenIdle;
80
83
  },
84
+ setMusicEnabled: (d, enabled) => {
85
+ d.musicEnabled = enabled;
86
+ },
87
+ setMusicVolume: (d, volume) => {
88
+ d.musicVolume = volume;
89
+ },
90
+ setMusicStyle: (d, style) => {
91
+ d.musicStyle = style;
92
+ },
81
93
  setUpgrade: (d, upgrade) => {
82
- const normalized = upgrade !== null && upgrade.latestVersion !== "" && upgrade.latestVersion !== "0.1.22" ? upgrade : null;
94
+ const normalized = upgrade !== null && upgrade.latestVersion !== "" && upgrade.latestVersion !== "0.1.23" ? upgrade : null;
83
95
  if (d.upgrade === null || d.upgrade.latestVersion !== normalized?.latestVersion) d.upgradeDismissed = false;
84
96
  d.upgrade = normalized;
85
97
  },
@@ -175,7 +187,7 @@ window.__ModuleLoader__.load({
175
187
  }
176
188
  //#endregion
177
189
  //#region \0dsh-css:/Users/jxgame/Desktop/works/deepseek-harness-package/dsh-token-quota/packages/token-quota/src/client/TokenQuotaPanel.module.css.mjs
178
- 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_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_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}";
190
+ const css = ".NPLLIq_panel{box-sizing:border-box;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);pointer-events:auto;z-index:40;opacity:1;border-radius:12px;flex-direction:column;width:320px;max-height:min(72vh,560px);transition:opacity .18s;display:flex;position:fixed;top:56px;right:12px;overflow:hidden;box-shadow:0 8px 28px #0000002e}.NPLLIq_panelDim{opacity:.55}.NPLLIq_panelDimStrong{opacity:.3}.NPLLIq_header{border-bottom:1px solid var(--dsw-alias-border-l1);cursor:grab;user-select:none;touch-action:none;justify-content:space-between;align-items:flex-start;gap:8px;padding:10px 12px;display:flex}.NPLLIq_header:active{cursor:grabbing}.NPLLIq_headerText{flex-direction:column;gap:2px;min-width:0;display:flex}.NPLLIq_title{color:var(--dsw-alias-label-primary);align-items:baseline;gap:6px;font-size:13px;font-weight:600;display:flex}.NPLLIq_version{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:10px;font-weight:500}.NPLLIq_versionNew{color:var(--dsw-alias-status-warning-foreground,#b56900);background:var(--dsw-alias-status-warning-background,#fff6d7);cursor:default;border-radius:4px;padding:1px 6px}.NPLLIq_subtitle{color:var(--dsw-alias-label-secondary);font-size:11px}.NPLLIq_collapse{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;padding:2px 6px;font-size:11px}.NPLLIq_collapse:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_body{padding:4px 0;overflow-y:auto}.NPLLIq_row{border-bottom:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:6px;padding:8px 12px;display:flex}.NPLLIq_rowHeader{justify-content:space-between;align-items:center;gap:8px;display:flex}.NPLLIq_rowName{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;align-items:center;gap:6px;font-size:12px;font-weight:500;display:inline-flex;overflow:hidden}.NPLLIq_currentBadge{color:var(--dsw-alias-state-success-primary);border:1px solid var(--dsw-alias-state-success-primary);border-radius:8px;flex:none;padding:1px 6px;font-size:10px}.NPLLIq_rowMeta{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;font-size:11px}.NPLLIq_bar{background:var(--dsw-alias-bg-layer-1);border-radius:3px;height:6px;overflow:hidden}.NPLLIq_fillIdle{background:var(--dsw-alias-brand-primary);height:100%;transition:width .2s}.NPLLIq_fillWarn{background:var(--dsw-alias-state-warn-primary);height:100%;transition:width .2s}.NPLLIq_fillOver{background:var(--dsw-alias-state-error-primary);height:100%;transition:width .2s}.NPLLIq_controls{align-items:center;gap:6px;display:flex}.NPLLIq_input{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);min-width:0;color:var(--dsw-alias-label-primary);border-radius:6px;flex:1;padding:4px 8px;font-size:11px}.NPLLIq_input::placeholder{color:var(--dsw-alias-label-secondary)}.NPLLIq_save,.NPLLIq_switch{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;flex:none;padding:4px 10px;font-size:11px}.NPLLIq_save:hover,.NPLLIq_switch:hover:not(:disabled){background:var(--dsw-alias-bg-layer-2)}.NPLLIq_switch:disabled{opacity:.5;cursor:default}.NPLLIq_notice,.NPLLIq_noticeError{color:var(--dsw-alias-label-secondary);padding:10px 12px;font-size:12px}.NPLLIq_noticeError{color:var(--dsw-alias-state-error-primary)}.NPLLIq_tab{background:var(--dsw-alias-brand-primary);border:1px solid var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-overlay);pointer-events:auto;cursor:pointer;z-index:90;border-radius:10px;align-items:center;gap:6px;padding:9px 14px;font-size:12px;font-weight:600;display:inline-flex;position:fixed;top:56px;right:12px;box-shadow:0 6px 20px #00000040}.NPLLIq_tab:hover{filter:brightness(1.08)}.NPLLIq_tabIcon{font-size:12px;line-height:1}.NPLLIq_tabLabel{white-space:nowrap}.NPLLIq_headerActions{flex:none;align-items:center;gap:4px;display:flex}.NPLLIq_settingsBtn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;padding:2px 6px;font-size:11px}.NPLLIq_settingsBtn:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_settingsBtnActive{color:var(--dsw-alias-brand-primary)}.NPLLIq_selectBtn{border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-brand-primary);cursor:pointer;background:0 0;border-radius:6px;flex:none;padding:1px 6px;font-size:10px}.NPLLIq_selectBtn:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_gearBtn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;flex:none;margin-left:6px;padding:0 2px;font-size:12px;line-height:1}.NPLLIq_gearBtn:hover{color:var(--dsw-alias-label-primary)}.NPLLIq_fullNotice{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-state-error-primary);border-radius:8px;margin:6px 12px;padding:8px 10px;font-size:12px}.NPLLIq_upgradeBanner{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-divider-1,#0000001a);border-radius:8px;margin:6px 12px;padding:10px 30px 10px 10px;font-size:12px;position:relative}@keyframes NPLLIq_upgradeBannerFlash{0%,to{border-color:var(--dsw-alias-divider-1,#0000001a);box-shadow:0 0 #f0a02000}50%{border-color:var(--dsw-alias-status-warning-foreground,#b56900);box-shadow:0 0 0 5px #f0a02073}}.NPLLIq_upgradeBannerFlash{border-color:var(--dsw-alias-status-warning-foreground,#b56900);animation:.6s ease-in-out 4 NPLLIq_upgradeBannerFlash}.NPLLIq_upgradeBannerText{margin-bottom:6px;font-weight:600}.NPLLIq_upgradeCommands{flex-direction:column;gap:4px;display:flex}.NPLLIq_upgradeCommandRow{align-items:center;gap:6px;display:flex}.NPLLIq_upgradeCommand{background:var(--dsw-alias-bg-layer-2,#0000000a);white-space:nowrap;border-radius:4px;flex:1;min-width:0;padding:4px 6px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;overflow-x:auto}.NPLLIq_copyBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;flex:none;padding:3px 8px;font-size:11px;transition:transform 80ms,background .12s,color .12s}.NPLLIq_copyBtn:hover{background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_copyBtn:active{transform:scale(.92)}.NPLLIq_copyBtnDone{background:var(--dsw-alias-status-success-background,#14963c1f);border-color:var(--dsw-alias-status-success-foreground,#0a7d32);color:var(--dsw-alias-status-success-foreground,#0a7d32);font-weight:600}.NPLLIq_upgradeHint{color:var(--dsw-alias-label-secondary);margin-top:6px;font-size:11px}.NPLLIq_upgradeClose{width:20px;height:20px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:4px;font-size:16px;line-height:1;position:absolute;top:4px;right:6px}.NPLLIq_upgradeClose:hover{background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary)}.NPLLIq_checkUpdatesRow{justify-content:space-between;align-items:center;gap:12px;display:flex}.NPLLIq_checkUpdatesLabel{color:var(--dsw-alias-label-primary);cursor:pointer;align-items:center;gap:6px;font-size:12px;display:flex}.NPLLIq_checkUpdatesLabel input{margin:0}.NPLLIq_checkUpdatesLabel input[type=range]{min-width:90px;accent-color:var(--dsw-alias-brand-primary);flex:1}.NPLLIq_checkUpdatesLabel select{background:var(--dsw-alias-bg-layer-2,#0000000a);min-width:90px;color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-divider-1,#00000026);border-radius:4px;flex:1;padding:2px 4px;font-size:12px}.NPLLIq_checkBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-2,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;white-space:nowrap;text-align:center;border-radius:4px;flex:none;min-width:72px;padding:4px 10px;font-size:12px}.NPLLIq_checkBtn:hover:not(:disabled){background:var(--dsw-alias-bg-layer-3,#00000014)}.NPLLIq_checkBtn:disabled{opacity:.6;cursor:default}.NPLLIq_checkErrorHint{color:var(--dsw-alias-state-error-primary,#c00);background:var(--dsw-alias-state-error-background,#ff00000f);border:1px solid var(--dsw-alias-state-error-border,#b4000040);word-break:break-all;border-radius:6px;margin-top:8px;padding:6px 8px;font-size:11px;line-height:1.4}.NPLLIq_dialog{z-index:100;box-sizing:border-box;background:var(--dsw-alias-bg-overlay);border:1px solid var(--dsw-alias-border-l1);border-radius:12px;flex-direction:column;gap:12px;width:280px;max-height:80vh;padding:14px;display:flex;position:fixed;top:50%;left:50%;overflow-y:auto;transform:translate(-50%,-50%);box-shadow:0 8px 28px #00000040}.NPLLIq_dialogTitle{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:600}.NPLLIq_dialogSection{flex-direction:column;gap:6px;display:flex}.NPLLIq_dialogLabel{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:500}.NPLLIq_monitorHint{color:var(--dsw-alias-label-secondary);font-size:11px}.NPLLIq_dialogHint{color:var(--dsw-alias-label-secondary);margin-top:4px;font-size:11px;line-height:1.4}.NPLLIq_monitorList{flex-direction:column;gap:2px;max-height:180px;display:flex;overflow-y:auto}.NPLLIq_monitorRow{color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:6px;padding:2px 4px;font-size:12px;display:flex}.NPLLIq_monitorRow:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_monitorName{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.NPLLIq_radioRow{color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:6px;padding:3px 4px;font-size:12px;display:flex}.NPLLIq_radioRow:hover{background:var(--dsw-alias-bg-layer-1)}.NPLLIq_dialogActions{justify-content:flex-end;gap:6px;display:flex}.NPLLIq_dialogBtn,.NPLLIq_dialogBtnPrimary{border:1px solid var(--dsw-alias-border-l1);cursor:pointer;border-radius:6px;padding:4px 12px;font-size:11px}.NPLLIq_dialogBtn{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary)}.NPLLIq_dialogBtnPrimary{background:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-overlay)}.NPLLIq_dialogHeader{z-index:2;background:var(--dsw-alias-bg-overlay);cursor:grab;user-select:none;touch-action:none;justify-content:space-between;align-items:center;gap:8px;margin:-14px -14px 0;padding:14px 14px 8px;display:flex;position:sticky;top:-14px}.NPLLIq_dialogHeader:active{cursor:grabbing}.NPLLIq_dialogClose{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:8px;flex:none;justify-content:center;align-items:center;font-size:18px;line-height:1;display:flex}.NPLLIq_dialogClose:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1)}.NPLLIq_resetRow{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.NPLLIq_resetSelect{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:6px;padding:3px 6px;font-size:12px}.NPLLIq_logTable{border-collapse:collapse;width:100%;font-size:11px}.NPLLIq_logTable th{text-align:left;color:var(--dsw-alias-label-secondary);border-bottom:1px solid var(--dsw-alias-border-l1);padding:4px 6px;font-weight:500}.NPLLIq_logTable td{color:var(--dsw-alias-label-primary);border-bottom:1px solid var(--dsw-alias-border-l1);font-variant-numeric:tabular-nums;padding:4px 6px}.NPLLIq_logDayCol{white-space:nowrap;color:var(--dsw-alias-label-secondary)}.NPLLIq_logModelCol{text-overflow:ellipsis;white-space:nowrap;max-width:160px;overflow:hidden}.NPLLIq_logUsedCol{text-align:right}.NPLLIq_logDialog{gap:0;width:380px;max-height:min(72vh,480px);padding:0}.NPLLIq_logHeader{background:var(--dsw-alias-bg-overlay);cursor:grab;user-select:none;touch-action:none;flex:none;justify-content:space-between;align-items:center;gap:8px;padding:14px 14px 8px;display:flex}.NPLLIq_logHeader:active{cursor:grabbing}.NPLLIq_logScroll{flex:1;min-height:0;padding:0 14px 14px;overflow:auto}.NPLLIq_logToolbar{flex:1;align-items:center;gap:6px;display:flex}.NPLLIq_logSearch{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);min-width:0;color:var(--dsw-alias-label-primary);border-radius:4px;flex:1;padding:3px 6px;font-size:11px}.NPLLIq_logSearch:focus{border-color:var(--dsw-alias-accent-1,#4a9eff);outline:none}.NPLLIq_logClearBtn{border:1px solid var(--dsw-alias-state-error-border,#b400004d);color:var(--dsw-alias-state-error-primary,#c00);cursor:pointer;white-space:nowrap;background:0 0;border-radius:4px;flex:none;padding:3px 8px;font-size:11px}.NPLLIq_logClearBtn:hover{background:var(--dsw-alias-state-error-background,#ff00000f)}.NPLLIq_logPager{border-top:1px solid var(--dsw-alias-divider-1,#00000014);background:var(--dsw-alias-bg-overlay);color:var(--dsw-alias-label-secondary);flex:none;justify-content:space-between;align-items:center;gap:8px;padding:6px 14px;font-size:11px;display:flex}.NPLLIq_logPagerInfo{white-space:nowrap}.NPLLIq_logPagerControls{align-items:center;gap:4px;display:flex}.NPLLIq_logPagerBtn{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);width:24px;height:24px;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;font-size:13px;line-height:1}.NPLLIq_logPagerBtn:disabled{opacity:.4;cursor:default}.NPLLIq_logPagerPages{text-align:center;min-width:50px;color:var(--dsw-alias-label-secondary)}.NPLLIq_logPageSizeSelect{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:4px;padding:2px 4px;font-size:11px}.NPLLIq_dialogOverlay{z-index:100001;background:#0000004d;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.NPLLIq_logClearDialog{gap:0;width:320px;padding:16px}.NPLLIq_dialogBody{color:var(--dsw-alias-label-secondary);margin:6px 0 10px;font-size:12px;line-height:1.5}.NPLLIq_logClearDate{border:1px solid var(--dsw-alias-divider-1,#00000026);background:var(--dsw-alias-bg-layer-1,#0000000a);width:100%;color:var(--dsw-alias-label-primary);border-radius:6px;margin-bottom:12px;padding:6px 8px;font-size:13px}.NPLLIq_logClearDate:focus{border-color:var(--dsw-alias-accent-1,#4a9eff);outline:none}";
179
191
  const tagId = "@jxgame2020/dsh-token-quota/TokenQuotaPanel.module.css";
180
192
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
181
193
  const tag = document.createElement("style");
@@ -185,91 +197,92 @@ window.__ModuleLoader__.load({
185
197
  document.head.appendChild(tag);
186
198
  }
187
199
  var TokenQuotaPanel_module_css_default = {
188
- "logUsedCol": "NPLLIq_logUsedCol",
189
- "controls": "NPLLIq_controls",
190
- "save": "NPLLIq_save",
191
- "upgradeCommand": "NPLLIq_upgradeCommand",
192
- "versionNew": "NPLLIq_versionNew",
200
+ "row": "NPLLIq_row",
201
+ "upgradeBannerFlash": "NPLLIq_upgradeBannerFlash",
202
+ "bar": "NPLLIq_bar",
193
203
  "title": "NPLLIq_title",
194
- "rowName": "NPLLIq_rowName",
195
- "currentBadge": "NPLLIq_currentBadge",
196
- "resetSelect": "NPLLIq_resetSelect",
197
- "checkBtn": "NPLLIq_checkBtn",
198
- "panel": "NPLLIq_panel",
204
+ "noticeError": "NPLLIq_noticeError",
205
+ "rowHeader": "NPLLIq_rowHeader",
199
206
  "settingsBtn": "NPLLIq_settingsBtn",
200
- "logPager": "NPLLIq_logPager",
201
- "upgradeClose": "NPLLIq_upgradeClose",
207
+ "checkUpdatesRow": "NPLLIq_checkUpdatesRow",
208
+ "logHeader": "NPLLIq_logHeader",
209
+ "logTable": "NPLLIq_logTable",
210
+ "dialogTitle": "NPLLIq_dialogTitle",
211
+ "dialogSection": "NPLLIq_dialogSection",
212
+ "dialogActions": "NPLLIq_dialogActions",
213
+ "tabLabel": "NPLLIq_tabLabel",
214
+ "logModelCol": "NPLLIq_logModelCol",
215
+ "logPagerPages": "NPLLIq_logPagerPages",
202
216
  "logSearch": "NPLLIq_logSearch",
203
- "fullNotice": "NPLLIq_fullNotice",
217
+ "monitorName": "NPLLIq_monitorName",
218
+ "controls": "NPLLIq_controls",
204
219
  "dialogClose": "NPLLIq_dialogClose",
205
- "fillIdle": "NPLLIq_fillIdle",
206
- "logPagerPages": "NPLLIq_logPagerPages",
207
- "logClearBtn": "NPLLIq_logClearBtn",
208
- "header": "NPLLIq_header",
209
- "dialogOverlay": "NPLLIq_dialogOverlay",
210
- "dialogHeader": "NPLLIq_dialogHeader",
211
- "upgradeCommands": "NPLLIq_upgradeCommands",
212
- "dialog": "NPLLIq_dialog",
213
- "logHeader": "NPLLIq_logHeader",
214
220
  "logPageSizeSelect": "NPLLIq_logPageSizeSelect",
215
- "dialogActions": "NPLLIq_dialogActions",
216
- "subtitle": "NPLLIq_subtitle",
217
- "rowHeader": "NPLLIq_rowHeader",
218
- "copyBtn": "NPLLIq_copyBtn",
219
- "headerActions": "NPLLIq_headerActions",
220
- "selectBtn": "NPLLIq_selectBtn",
221
- "upgradeHint": "NPLLIq_upgradeHint",
222
- "resetRow": "NPLLIq_resetRow",
223
- "logClearDate": "NPLLIq_logClearDate",
224
- "input": "NPLLIq_input",
221
+ "dialogHint": "NPLLIq_dialogHint",
222
+ "checkBtn": "NPLLIq_checkBtn",
223
+ "dialogBody": "NPLLIq_dialogBody",
224
+ "rowName": "NPLLIq_rowName",
225
225
  "copyBtnDone": "NPLLIq_copyBtnDone",
226
- "bar": "NPLLIq_bar",
227
- "version": "NPLLIq_version",
228
- "tabIcon": "NPLLIq_tabIcon",
229
- "dialogTitle": "NPLLIq_dialogTitle",
230
- "logDialog": "NPLLIq_logDialog",
231
- "checkErrorHint": "NPLLIq_checkErrorHint",
232
- "body": "NPLLIq_body",
226
+ "logClearDate": "NPLLIq_logClearDate",
227
+ "notice": "NPLLIq_notice",
228
+ "resetRow": "NPLLIq_resetRow",
233
229
  "rowMeta": "NPLLIq_rowMeta",
234
- "collapse": "NPLLIq_collapse",
235
- "dialogSection": "NPLLIq_dialogSection",
236
- "dialogBody": "NPLLIq_dialogBody",
230
+ "logClearDialog": "NPLLIq_logClearDialog",
231
+ "subtitle": "NPLLIq_subtitle",
232
+ "panel": "NPLLIq_panel",
233
+ "monitorHint": "NPLLIq_monitorHint",
234
+ "logPager": "NPLLIq_logPager",
235
+ "save": "NPLLIq_save",
236
+ "tab": "NPLLIq_tab",
237
+ "selectBtn": "NPLLIq_selectBtn",
238
+ "upgradeCommand": "NPLLIq_upgradeCommand",
239
+ "resetSelect": "NPLLIq_resetSelect",
237
240
  "logScroll": "NPLLIq_logScroll",
238
- "upgradeBanner": "NPLLIq_upgradeBanner",
239
- "row": "NPLLIq_row",
240
- "panelDimStrong": "NPLLIq_panelDimStrong",
241
241
  "monitorRow": "NPLLIq_monitorRow",
242
- "tabLabel": "NPLLIq_tabLabel",
243
- "upgradeBannerText": "NPLLIq_upgradeBannerText",
244
- "checkUpdatesRow": "NPLLIq_checkUpdatesRow",
245
- "dialogLabel": "NPLLIq_dialogLabel",
246
- "gearBtn": "NPLLIq_gearBtn",
247
- "dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
248
- "notice": "NPLLIq_notice",
242
+ "upgradeCommandRow": "NPLLIq_upgradeCommandRow",
243
+ "logPagerControls": "NPLLIq_logPagerControls",
244
+ "logDayCol": "NPLLIq_logDayCol",
245
+ "header": "NPLLIq_header",
246
+ "logDialog": "NPLLIq_logDialog",
247
+ "radioRow": "NPLLIq_radioRow",
248
+ "dialogOverlay": "NPLLIq_dialogOverlay",
249
+ "collapse": "NPLLIq_collapse",
249
250
  "fillWarn": "NPLLIq_fillWarn",
250
- "fillOver": "NPLLIq_fillOver",
251
+ "tabIcon": "NPLLIq_tabIcon",
251
252
  "checkUpdatesLabel": "NPLLIq_checkUpdatesLabel",
252
- "radioRow": "NPLLIq_radioRow",
253
- "panelDim": "NPLLIq_panelDim",
254
- "logDayCol": "NPLLIq_logDayCol",
255
- "logModelCol": "NPLLIq_logModelCol",
256
- "monitorHint": "NPLLIq_monitorHint",
257
- "logPagerControls": "NPLLIq_logPagerControls",
258
- "upgradeBannerFlash": "NPLLIq_upgradeBannerFlash",
259
253
  "switch": "NPLLIq_switch",
260
- "headerText": "NPLLIq_headerText",
261
- "upgradeCommandRow": "NPLLIq_upgradeCommandRow",
262
- "dialogHint": "NPLLIq_dialogHint",
263
- "dialogBtn": "NPLLIq_dialogBtn",
264
- "logTable": "NPLLIq_logTable",
254
+ "gearBtn": "NPLLIq_gearBtn",
255
+ "dialogLabel": "NPLLIq_dialogLabel",
256
+ "upgradeBannerText": "NPLLIq_upgradeBannerText",
257
+ "versionNew": "NPLLIq_versionNew",
265
258
  "monitorList": "NPLLIq_monitorList",
266
- "noticeError": "NPLLIq_noticeError",
267
- "tab": "NPLLIq_tab",
268
- "monitorName": "NPLLIq_monitorName",
269
- "logPagerInfo": "NPLLIq_logPagerInfo",
259
+ "logClearBtn": "NPLLIq_logClearBtn",
260
+ "settingsBtnActive": "NPLLIq_settingsBtnActive",
261
+ "currentBadge": "NPLLIq_currentBadge",
262
+ "fullNotice": "NPLLIq_fullNotice",
263
+ "dialogBtn": "NPLLIq_dialogBtn",
264
+ "input": "NPLLIq_input",
265
+ "panelDimStrong": "NPLLIq_panelDimStrong",
266
+ "logToolbar": "NPLLIq_logToolbar",
270
267
  "logPagerBtn": "NPLLIq_logPagerBtn",
271
- "logClearDialog": "NPLLIq_logClearDialog",
272
- "logToolbar": "NPLLIq_logToolbar"
268
+ "panelDim": "NPLLIq_panelDim",
269
+ "upgradeBanner": "NPLLIq_upgradeBanner",
270
+ "copyBtn": "NPLLIq_copyBtn",
271
+ "body": "NPLLIq_body",
272
+ "upgradeHint": "NPLLIq_upgradeHint",
273
+ "dialog": "NPLLIq_dialog",
274
+ "fillIdle": "NPLLIq_fillIdle",
275
+ "headerText": "NPLLIq_headerText",
276
+ "logPagerInfo": "NPLLIq_logPagerInfo",
277
+ "headerActions": "NPLLIq_headerActions",
278
+ "checkErrorHint": "NPLLIq_checkErrorHint",
279
+ "upgradeCommands": "NPLLIq_upgradeCommands",
280
+ "dialogBtnPrimary": "NPLLIq_dialogBtnPrimary",
281
+ "version": "NPLLIq_version",
282
+ "upgradeClose": "NPLLIq_upgradeClose",
283
+ "dialogHeader": "NPLLIq_dialogHeader",
284
+ "logUsedCol": "NPLLIq_logUsedCol",
285
+ "fillOver": "NPLLIq_fillOver"
273
286
  };
274
287
  //#endregion
275
288
  //#region lib/types/client/TokenQuotaPanel.js
@@ -356,7 +369,7 @@ window.__ModuleLoader__.load({
356
369
  * @param props - composed slot props.
357
370
  * @returns the panel element tree.
358
371
  */
359
- function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle, useStore, actions, useSessions }) {
372
+ function TokenQuotaPanel({ t, load, setLimit, selectModel, setMonitored, setOnFull, setReset, setCheckUpdates, checkUpdatesNow, clearLogBefore, setDimWhenIdle, setMusicEnabled, setMusicVolume, setMusicStyle, useStore, actions, useSessions }) {
360
373
  const [collapsed, setCollapsed] = (0, react.useState)(false);
361
374
  const [drafts, setDrafts] = (0, react.useState)({});
362
375
  const [editingKey, setEditingKey] = (0, react.useState)(null);
@@ -387,6 +400,9 @@ window.__ModuleLoader__.load({
387
400
  const onFull = useStore((s) => s.onFull);
388
401
  const checkUpdates = useStore((s) => s.checkUpdates);
389
402
  const dimWhenIdle = useStore((s) => s.dimWhenIdle);
403
+ const musicEnabled = useStore((s) => s.musicEnabled);
404
+ const musicVolume = useStore((s) => s.musicVolume);
405
+ const musicStyle = useStore((s) => s.musicStyle);
390
406
  const upgrade = useStore((s) => s.upgrade);
391
407
  const upgradeDismissed = useStore((s) => s.upgradeDismissed);
392
408
  const checkingUpdates = useStore((s) => s.checkingUpdates);
@@ -571,13 +587,13 @@ window.__ModuleLoader__.load({
571
587
  title: t("upgradeAvailableHint"),
572
588
  children: [
573
589
  "v",
574
- "0.1.22",
590
+ "0.1.23",
575
591
  " → v",
576
592
  upgrade.latestVersion
577
593
  ]
578
594
  }) : (0, react_jsx_runtime.jsxs)("span", {
579
595
  className: TokenQuotaPanel_module_css_default.version,
580
- children: ["v", "0.1.22"]
596
+ children: ["v", "0.1.23"]
581
597
  })]
582
598
  }), (0, react_jsx_runtime.jsx)("div", {
583
599
  className: TokenQuotaPanel_module_css_default.subtitle,
@@ -589,6 +605,15 @@ window.__ModuleLoader__.load({
589
605
  event.stopPropagation();
590
606
  },
591
607
  children: [
608
+ (0, react_jsx_runtime.jsx)("button", {
609
+ type: "button",
610
+ className: `${TokenQuotaPanel_module_css_default.settingsBtn}${musicEnabled ? ` ${TokenQuotaPanel_module_css_default.settingsBtnActive}` : ""}`,
611
+ title: t("musicHint"),
612
+ onClick: () => {
613
+ setMusicEnabled(!musicEnabled);
614
+ },
615
+ children: musicEnabled ? "🔊" : "♪"
616
+ }),
592
617
  (0, react_jsx_runtime.jsx)("button", {
593
618
  type: "button",
594
619
  className: TokenQuotaPanel_module_css_default.settingsBtn,
@@ -914,6 +939,60 @@ window.__ModuleLoader__.load({
914
939
  children: t("dimWhenIdleHint")
915
940
  })]
916
941
  }),
942
+ (0, react_jsx_runtime.jsxs)("div", {
943
+ className: TokenQuotaPanel_module_css_default.dialogSection,
944
+ children: [
945
+ (0, react_jsx_runtime.jsxs)("label", {
946
+ className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
947
+ children: [(0, react_jsx_runtime.jsx)("input", {
948
+ type: "checkbox",
949
+ checked: musicEnabled,
950
+ onChange: (event) => {
951
+ setMusicEnabled(event.target.checked);
952
+ }
953
+ }), (0, react_jsx_runtime.jsx)("span", { children: t("musicLabel") })]
954
+ }),
955
+ (0, react_jsx_runtime.jsx)("div", {
956
+ className: TokenQuotaPanel_module_css_default.dialogHint,
957
+ children: t("musicHint")
958
+ }),
959
+ musicEnabled && (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)("label", {
960
+ className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
961
+ children: [(0, react_jsx_runtime.jsx)("span", { children: t("musicVolume") }), (0, react_jsx_runtime.jsx)("input", {
962
+ type: "range",
963
+ min: 0,
964
+ max: 1,
965
+ step: .05,
966
+ value: musicVolume,
967
+ onChange: (event) => {
968
+ setMusicVolume(Number(event.target.value));
969
+ }
970
+ })]
971
+ }), (0, react_jsx_runtime.jsxs)("label", {
972
+ className: TokenQuotaPanel_module_css_default.checkUpdatesLabel,
973
+ children: [(0, react_jsx_runtime.jsx)("span", { children: t("musicStyle") }), (0, react_jsx_runtime.jsxs)("select", {
974
+ value: musicStyle,
975
+ onChange: (event) => {
976
+ setMusicStyle(event.target.value);
977
+ },
978
+ children: [
979
+ (0, react_jsx_runtime.jsx)("option", {
980
+ value: "major",
981
+ children: t("musicStyleMajor")
982
+ }),
983
+ (0, react_jsx_runtime.jsx)("option", {
984
+ value: "minor",
985
+ children: t("musicStyleMinor")
986
+ }),
987
+ (0, react_jsx_runtime.jsx)("option", {
988
+ value: "pentatonic",
989
+ children: t("musicStylePentatonic")
990
+ })
991
+ ]
992
+ })]
993
+ })] })
994
+ ]
995
+ }),
917
996
  (0, react_jsx_runtime.jsxs)("div", {
918
997
  className: TokenQuotaPanel_module_css_default.dialogSection,
919
998
  children: [(0, react_jsx_runtime.jsxs)("div", {
@@ -1129,6 +1208,278 @@ window.__ModuleLoader__.load({
1129
1208
  });
1130
1209
  }
1131
1210
  //#endregion
1211
+ //#region lib/types/client/music.js
1212
+ /**
1213
+ * Live-composed soundtrack driven by host actions (turns, steps, tool calls,
1214
+ * etc.). Outputs through Web Audio (built-in synthesis) by default, and also
1215
+ * sends MIDI NoteOn/NoteOff to the first available MIDI output when one is
1216
+ * detected (both play simultaneously when MIDI is present — use the panel
1217
+ * volume for overall level, the MIDI output has its own gain on the receiver).
1218
+ *
1219
+ * The composition is intentionally simple: a fixed chord progression under a
1220
+ * scale-constrained melody, with one short musical gesture per host action.
1221
+ * It is meant as gentle ambience while waiting for LLM responses, not as a
1222
+ * full piece — everything stays in key so you can never hit a wrong note.
1223
+ *
1224
+ * @module @jxgame2020/dsh-token-quota/music
1225
+ */
1226
+ /** Scale degrees in semitones from the root. */
1227
+ const SCALES = {
1228
+ major: [
1229
+ 0,
1230
+ 2,
1231
+ 4,
1232
+ 5,
1233
+ 7,
1234
+ 9,
1235
+ 11
1236
+ ],
1237
+ minor: [
1238
+ 0,
1239
+ 2,
1240
+ 3,
1241
+ 5,
1242
+ 7,
1243
+ 8,
1244
+ 10
1245
+ ],
1246
+ pentatonic: [
1247
+ 0,
1248
+ 2,
1249
+ 4,
1250
+ 7,
1251
+ 9
1252
+ ]
1253
+ };
1254
+ /**
1255
+ * Chord progression roots in semitones from the key centre. Loops — every
1256
+ * step advance moves one position forward.
1257
+ */
1258
+ const CHORD_PROGRESSIONS = {
1259
+ major: [
1260
+ 0,
1261
+ 9,
1262
+ 5,
1263
+ 7
1264
+ ],
1265
+ minor: [
1266
+ 0,
1267
+ 9,
1268
+ 4,
1269
+ 11
1270
+ ],
1271
+ pentatonic: [
1272
+ 0,
1273
+ 7,
1274
+ 2,
1275
+ 9
1276
+ ]
1277
+ };
1278
+ const CHORD_QUALITIES = {
1279
+ major: [
1280
+ "major",
1281
+ "minor",
1282
+ "major",
1283
+ "major"
1284
+ ],
1285
+ minor: [
1286
+ "minor",
1287
+ "major",
1288
+ "major",
1289
+ "major"
1290
+ ],
1291
+ pentatonic: [
1292
+ "major",
1293
+ "major",
1294
+ "major",
1295
+ "major"
1296
+ ]
1297
+ };
1298
+ /**
1299
+ * Turn a MIDI note number into a frequency (Hz) using equal temperament at
1300
+ * A4 = 440 Hz.
1301
+ */
1302
+ function midiToFreq(midi) {
1303
+ return 440 * Math.pow(2, (midi - 69) / 12);
1304
+ }
1305
+ /** Live-composed music engine driven by host actions. */
1306
+ var TokenQuotaMusic = class TokenQuotaMusic {
1307
+ audio = null;
1308
+ midiOutput = null;
1309
+ midiDetected = false;
1310
+ enabled = false;
1311
+ volume = .5;
1312
+ style = "major";
1313
+ /** Current position in the chord progression (advances per step). */
1314
+ chordIndex = 0;
1315
+ /** Step counter — used for melody degree selection. */
1316
+ stepCount = 0;
1317
+ /** Tool counter — used for tool-note pitch. */
1318
+ toolCount = 0;
1319
+ /** Base MIDI note of the current key. C4 = middle C. */
1320
+ static BASE_MIDI = 60;
1321
+ /** True once the audio context has been started (needs a user gesture). */
1322
+ get started() {
1323
+ return this.audio !== null;
1324
+ }
1325
+ /**
1326
+ * Start the audio context and try to find a MIDI output.
1327
+ * Must be called inside a user gesture (the panel switch click) so the
1328
+ * AudioContext can resume. Safe to call multiple times.
1329
+ */
1330
+ async ensureStarted() {
1331
+ if (this.audio !== null) return true;
1332
+ if (typeof window === "undefined") return false;
1333
+ try {
1334
+ this.audio = new AudioContext();
1335
+ await this.audio.resume();
1336
+ } catch {
1337
+ this.audio = null;
1338
+ return false;
1339
+ }
1340
+ if (!this.midiDetected && "requestMIDIAccess" in navigator) {
1341
+ this.midiDetected = true;
1342
+ try {
1343
+ const access = await navigator.requestMIDIAccess();
1344
+ for (const output of access.outputs.values()) {
1345
+ this.midiOutput = output;
1346
+ break;
1347
+ }
1348
+ } catch {
1349
+ this.midiOutput = null;
1350
+ }
1351
+ }
1352
+ return true;
1353
+ }
1354
+ setEnabled(value) {
1355
+ this.enabled = value;
1356
+ }
1357
+ setVolume(value) {
1358
+ this.volume = Math.max(0, Math.min(1, value));
1359
+ }
1360
+ setStyle(value) {
1361
+ this.style = value;
1362
+ }
1363
+ /** Handle one incoming host action and turn it into sound. */
1364
+ onAction(action) {
1365
+ if (!this.enabled || this.audio === null) return;
1366
+ const base = TokenQuotaMusic.BASE_MIDI;
1367
+ switch (action.type) {
1368
+ case "turn/start":
1369
+ this.chordIndex = 0;
1370
+ this.stepCount = 0;
1371
+ this.toolCount = 0;
1372
+ this.playChord(base, this.currentChordQuality(), 1.6, .55);
1373
+ break;
1374
+ case "step/start": {
1375
+ this.chordIndex = (this.chordIndex + 1) % CHORD_PROGRESSIONS[this.style].length;
1376
+ this.stepCount += 1;
1377
+ this.playNote(this.currentChordRoot(base) - 12, 1.2, .35);
1378
+ const root = this.currentChordRoot(base);
1379
+ const [d1, d2, d3] = this.arpeggioDegrees();
1380
+ setTimeout(() => this.playNote(root + d1, .2, .4), 0);
1381
+ setTimeout(() => this.playNote(root + d2, .2, .4), 80);
1382
+ setTimeout(() => this.playNote(root + d3, .35, .4), 160);
1383
+ break;
1384
+ }
1385
+ case "request/header": {
1386
+ const degree = (this.stepCount * 2 + this.toolCount) % SCALES[this.style].length;
1387
+ const note = base + 12 + SCALES[this.style][degree];
1388
+ this.playNote(note, .18, .35);
1389
+ break;
1390
+ }
1391
+ case "tool/call":
1392
+ this.toolCount += 1;
1393
+ this.playNote(base + 24 + this.toolCount % 3 * 2, .12, .45);
1394
+ this.playNote(base - 12, .08, .25);
1395
+ break;
1396
+ case "tool/result":
1397
+ if (action.error) {
1398
+ this.playNote(base + 13, .18, .4);
1399
+ setTimeout(() => this.playNote(base + 12, .25, .4), 90);
1400
+ } else {
1401
+ this.playNote(base + 9, .14, .3);
1402
+ setTimeout(() => this.playNote(base + 11, .22, .3), 70);
1403
+ }
1404
+ break;
1405
+ case "assistant/message":
1406
+ if (action.interrupted) this.playChord(base + 7, "dim", .9, .5);
1407
+ else this.playChord(this.currentChordRoot(base), this.currentChordQuality(), 1.1, .55);
1408
+ break;
1409
+ case "turn/end":
1410
+ this.playChord(base, this.style === "minor" ? "minor" : "major", 2.2, .65);
1411
+ this.chordIndex = 0;
1412
+ break;
1413
+ }
1414
+ }
1415
+ currentChordRoot(base) {
1416
+ const prog = CHORD_PROGRESSIONS[this.style];
1417
+ return base + prog[this.chordIndex % prog.length];
1418
+ }
1419
+ currentChordQuality() {
1420
+ const q = CHORD_QUALITIES[this.style];
1421
+ return q[this.chordIndex % q.length] ?? "major";
1422
+ }
1423
+ /** Intervals of an ascending arpeggio from the chord root. */
1424
+ arpeggioDegrees() {
1425
+ return this.style === "pentatonic" ? [
1426
+ 0,
1427
+ 7,
1428
+ 12
1429
+ ] : this.currentChordQuality() === "major" ? [
1430
+ 0,
1431
+ 4,
1432
+ 7
1433
+ ] : [
1434
+ 0,
1435
+ 3,
1436
+ 7
1437
+ ];
1438
+ }
1439
+ /** Play one note: Web Audio + MIDI simultaneously when available. */
1440
+ playNote(midi, durationSec, velocity) {
1441
+ if (!this.audio) return;
1442
+ const now = this.audio.currentTime;
1443
+ const peak = this.volume * velocity * .5;
1444
+ if (peak <= 0) return;
1445
+ const osc = this.audio.createOscillator();
1446
+ osc.type = "sine";
1447
+ osc.frequency.value = midiToFreq(midi);
1448
+ const gain = this.audio.createGain();
1449
+ gain.gain.setValueAtTime(0, now);
1450
+ gain.gain.linearRampToValueAtTime(peak, now + .008);
1451
+ gain.gain.exponentialRampToValueAtTime(.001, now + durationSec);
1452
+ osc.connect(gain);
1453
+ gain.connect(this.audio.destination);
1454
+ osc.start(now);
1455
+ osc.stop(now + durationSec + .05);
1456
+ if (this.midiOutput !== null) {
1457
+ const vel = Math.max(1, Math.floor(velocity * 127));
1458
+ this.midiOutput.send([
1459
+ 144,
1460
+ midi & 127,
1461
+ vel
1462
+ ]);
1463
+ setTimeout(() => {
1464
+ this.midiOutput?.send([
1465
+ 128,
1466
+ midi & 127,
1467
+ 0
1468
+ ]);
1469
+ }, durationSec * 1e3);
1470
+ }
1471
+ }
1472
+ /** Play a three-note chord plus a bass octave below. */
1473
+ playChord(rootMidi, quality, durationSec, velocity) {
1474
+ const third = quality === "major" ? 4 : 3;
1475
+ const fifth = quality === "dim" ? 6 : 7;
1476
+ this.playNote(rootMidi, durationSec, velocity * .45);
1477
+ this.playNote(rootMidi + third, durationSec, velocity * .35);
1478
+ this.playNote(rootMidi + fifth, durationSec, velocity * .35);
1479
+ this.playNote(rootMidi - 12, durationSec * 1.15, velocity * .45);
1480
+ }
1481
+ };
1482
+ //#endregion
1132
1483
  //#region lib/types/client/locales.js
1133
1484
  /**
1134
1485
  * Token-quota panel copy (zh + en). The panel is a product surface, so the
@@ -1198,6 +1549,13 @@ window.__ModuleLoader__.load({
1198
1549
  checkUpdatesLabel: "自动检查更新",
1199
1550
  dimWhenIdleLabel: "失焦时窗口透明",
1200
1551
  dimWhenIdleHint: "鼠标移开面板时降低不透明度,输入文字时更透明;鼠标悬停恢复",
1552
+ musicLabel: "动作音乐",
1553
+ musicHint: "根据 Harness 动作实时作曲:请求开始、工具调用、回合结束等(需点击开关启动音频;检测到 MIDI 输出时同步发送 MIDI)",
1554
+ musicVolume: "音量",
1555
+ musicStyle: "风格",
1556
+ musicStyleMajor: "大调",
1557
+ musicStyleMinor: "小调",
1558
+ musicStylePentatonic: "五声",
1201
1559
  checkUpdatesNow: "立即检查",
1202
1560
  checkingUpdates: "检查中…",
1203
1561
  checkUpToDate: "已是最新",
@@ -1265,6 +1623,13 @@ window.__ModuleLoader__.load({
1265
1623
  checkUpdatesLabel: "Check for updates automatically",
1266
1624
  dimWhenIdleLabel: "Dim panel when unfocused",
1267
1625
  dimWhenIdleHint: "Fade the panel out when the pointer is away (more while typing); hover to restore",
1626
+ musicLabel: "Action music",
1627
+ musicHint: "Live-composes from Harness actions: request starts, tool calls, turn ends, etc. (click the switch to start audio; a detected MIDI output is driven as well)",
1628
+ musicVolume: "Volume",
1629
+ musicStyle: "Style",
1630
+ musicStyleMajor: "Major",
1631
+ musicStyleMinor: "Minor",
1632
+ musicStylePentatonic: "Pentatonic",
1268
1633
  checkUpdatesNow: "Check now",
1269
1634
  checkingUpdates: "Checking…",
1270
1635
  checkUpToDate: "Up to date",
@@ -1309,6 +1674,21 @@ window.__ModuleLoader__.load({
1309
1674
  let lastMonitored = null;
1310
1675
  let lastOnFull = "stop";
1311
1676
  let lastReset = null;
1677
+ const music = new TokenQuotaMusic();
1678
+ const sse = new EventSource("/token-quota/events");
1679
+ sse.addEventListener("action", (event) => {
1680
+ let action;
1681
+ try {
1682
+ action = JSON.parse(event.data);
1683
+ } catch {
1684
+ return;
1685
+ }
1686
+ if (lastSessionId !== void 0 && action.sessionId !== String(lastSessionId)) return;
1687
+ music.onAction(action);
1688
+ });
1689
+ ctx.effect(() => () => {
1690
+ sse.close();
1691
+ }, "token-quota-ui: music SSE");
1312
1692
  const keyOf = (selection) => {
1313
1693
  if (selection === null) return void 0;
1314
1694
  return `${selection.provider}/${selection.model}`;
@@ -1418,6 +1798,18 @@ window.__ModuleLoader__.load({
1418
1798
  bound?.setCheckUpdates(doc?.checkUpdates ?? true);
1419
1799
  bound?.setDimWhenIdle(doc?.dimWhenIdle ?? false);
1420
1800
  bound?.setReset(lastReset);
1801
+ const musicSettings = {
1802
+ enabled: false,
1803
+ volume: .5,
1804
+ style: "major",
1805
+ ...doc?.music ?? {}
1806
+ };
1807
+ music.setEnabled(musicSettings.enabled);
1808
+ music.setVolume(musicSettings.volume);
1809
+ music.setStyle(musicSettings.style);
1810
+ bound?.setMusicEnabled(musicSettings.enabled);
1811
+ bound?.setMusicVolume(musicSettings.volume);
1812
+ bound?.setMusicStyle(musicSettings.style);
1421
1813
  fetch("/token-quota", { headers: { accept: "application/json" } }).then((response) => {
1422
1814
  if (!response.ok) {
1423
1815
  bound?.setError(`quota route: ${String(response.status)}`);
@@ -1487,6 +1879,37 @@ window.__ModuleLoader__.load({
1487
1879
  bound?.setDimWhenIdle(enabled);
1488
1880
  scope.set("dimWhenIdle", enabled);
1489
1881
  };
1882
+ const setMusicEnabled = (enabled) => {
1883
+ const current = {
1884
+ enabled: false,
1885
+ volume: .5,
1886
+ style: "major",
1887
+ ...scope.getSnapshot().value?.music ?? {}
1888
+ };
1889
+ current.enabled = enabled;
1890
+ scope.set("music", current);
1891
+ if (enabled) music.ensureStarted();
1892
+ };
1893
+ const setMusicVolume = (volume) => {
1894
+ const current = {
1895
+ enabled: false,
1896
+ volume: .5,
1897
+ style: "major",
1898
+ ...scope.getSnapshot().value?.music ?? {}
1899
+ };
1900
+ current.volume = Math.max(0, Math.min(1, volume));
1901
+ scope.set("music", current);
1902
+ };
1903
+ const setMusicStyle = (style) => {
1904
+ const current = {
1905
+ enabled: false,
1906
+ volume: .5,
1907
+ style: "major",
1908
+ ...scope.getSnapshot().value?.music ?? {}
1909
+ };
1910
+ current.style = style;
1911
+ scope.set("music", current);
1912
+ };
1490
1913
  /** Ask the Host to check the registry right now, then refresh the snapshot. */
1491
1914
  const checkUpdatesNow = () => {
1492
1915
  bound?.setCheckingUpdates(true);
@@ -1570,7 +1993,10 @@ window.__ModuleLoader__.load({
1570
1993
  setCheckUpdates,
1571
1994
  checkUpdatesNow,
1572
1995
  clearLogBefore,
1573
- setDimWhenIdle
1996
+ setDimWhenIdle,
1997
+ setMusicEnabled,
1998
+ setMusicVolume,
1999
+ setMusicStyle
1574
2000
  };
1575
2001
  };
1576
2002
  ctx.slots.inject("shell.overlay", () => ctx.slots.register({