@linxin666/dsh-usage 0.4.6 → 0.4.8

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/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # node scripts/verify-docs.mjs --write <dir>
5
- README.md: 6300aa8ace7fe2d26e7b1bf19627760731b3e9d8
6
- README.zh.md: 0ea06549aeea2a968655f42f2fb3287e38c01c40
5
+ README.md: 09251404a6aa753795f71a9b378fa4df13cd0595
6
+ README.zh.md: 1e71587e55dbb3285423af2ec69bad7b091e91c0
package/README.md CHANGED
@@ -5,7 +5,7 @@ English | [中文](README.zh.md)
5
5
  <p align="center">
6
6
  <img src="https://img.shields.io/npm/v/@linxin666/dsh-usage?style=flat-square" alt="Version">
7
7
  &nbsp;
8
- <img src="https://img.shields.io/badge/DSH-%3E%3D0.2.0--rc.2-4c6ef5?style=flat-square&amp;labelColor=454a54" alt="DSH">
8
+ <img src="https://img.shields.io/badge/DSH-%3E%3D0.2.1--rc.2-4c6ef5?style=flat-square&amp;labelColor=454a54" alt="DSH">
9
9
  &nbsp;
10
10
  <img src="https://img.shields.io/badge/license-Apache--2.0-blue?style=flat-square" alt="License">
11
11
  </p>
@@ -21,10 +21,10 @@ A dedicated token usage and cost monitoring plugin for DeepSeek Harness (DSH) We
21
21
 
22
22
  The plugin runs a host-side service and a first-level settings section (使用统计, directly below the Workshop entry):
23
23
 
24
- - **Usage tab (用量)**: today's token totals per bucket (input / output / cache read / cache write, disjoint as the provider reports them) with per-provider and per-model breakdown, the last 30 days as a horizontal provider/model bar chart, and the balance of every configured provider (one row per adapter family: a dormant catalog alias shadowed by the family's live route no longer renders its own balance row). A **day picker** switches that card to any retained day that recorded usage (today first, then the other days newest first) and the card then shows that day's own totals, provider rows, and estimated spend; the peak/off-peak line stays on today because it describes the pricing window now. The ledger folds live `session/event` streams (`request/header` route attribution plus `assistant/message` usage) into `$DSH_HOME/dsh-usage/usage-ledger.json` with day-based retention, so past days survive restarts; counting starts when the plugin is first enabled. For the official DeepSeek family the tab also shows the current peak/off-peak pricing period (Beijing weekdays 09:00-12:00 and 14:00-18:00 are peak, billed at double) and today's estimated spend in CNY.
24
+ - **Usage tab (用量)**: today's token totals per bucket (input / output / cache read / cache write, disjoint as the provider reports them) with per-provider and per-model breakdown, the last 30 days as a horizontal provider/model bar chart, and the balance of every configured provider (one row per adapter family: a dormant catalog alias shadowed by the family's live route no longer renders its own balance row). A **day picker** switches that card to any retained day that recorded usage (today first, then the other days newest first) and the card then shows that day's own totals, provider rows, and estimated spend; the peak/off-peak line stays on today because it describes the pricing window now. The ledger folds live `session/event` streams (`request/header` route attribution plus `assistant/message` usage) into `$DSH_HOME/dsh-usage/usage-ledger.json` with day-based retention, so past days survive restarts; counting starts when the plugin is first enabled. For the official DeepSeek family the tab also shows the current peak/off-peak pricing period (Beijing weekdays 09:00-12:00 and 14:00-18:00 are peak, billed at double) and today's estimated spend in CNY; that line is toned by the current clock — red while peak, green while off-peak — and always carries the word plus a dot, so colour is never the only signal.
25
25
  - **Plans tab (个人套餐)**: coding-plan quota windows for every configured provider that exposes one — used percent and reset time per window (Kimi For Coding 5h/week, GLM Coding Plan 5h/week/month, OpenCode Go rolling/weekly/monthly, MiniMax 5h/week, Codex / ChatGPT subscription 5h/week). Providers without a real plan or subscription (DeepSeek, ZenMux, Moonshot, OpenRouter, SiliconFlow) never appear on this tab; their balance shows on the usage tab instead.
26
26
  - **Token Bank tab (Token 银行)**: the whale-yuan voucher (鲸元券) minted from the official DeepSeek family's ledger at an anti-inflation exchange rate of 1,000,000 tokens per whale yuan. The tab sums the family's retained-ledger tokens (the `deepseek` catalog alias and the live `deepseek-official` route combined), stamps the minted face value onto the banknote artwork with a serial line carrying the minting window, and offers a save-image button plus a native share button when the browser supports sharing files. The spend line shows the real CNY total observed from the official balance once available — balance decreases accrue as spend, top-ups never count — and falls back to the fold-time estimate before the first observation. The minted total prefers the host's whole-ledger aggregate and falls back to the last 30 days on an older host; with no official DeepSeek usage the tab shows its empty state. A day picker mints the note from one picked day instead of the whole retention window (the observed-spend line, which accrues from the first balance reading, is whole-window only and falls back to that day's fold-time estimate on a single day). The on-note text is locale-neutral (digits, latin captions, ISO dates) and the export is rendered locally in the browser.
27
- - **Sidebar foot card**: a compact glance seated above the sidebar's Settings row — today's estimated spend as the headline (today's tokens when nothing priced is recorded yet), the tokens/calls line, and up to two configured-provider balances with a +N overflow. The whole card is one button that opens the usage settings section, so detail stays in one place, and the corner chevron folds it into a one-line strip (the spending provider's name, the label, and the headline value), a choice persisted across reloads. It polls at a relaxed 30 s cadence while the tab is visible, hides in the collapsed 56 px rail, and disappears while the plugin is disabled.
27
+ - **Sidebar foot card**: a compact glance seated above the sidebar's Settings row — today's estimated spend as the headline (today's tokens when nothing priced is recorded yet), the tokens/calls line, and up to two configured-provider balances with a +N overflow. The whole card is one button that opens the usage settings section, so detail stays in one place, and the corner chevron folds it into a one-line strip (the spending provider's name, the peak marker, the label, and the headline value), a choice persisted across reloads. When today's spend runs on the official DeepSeek route the card marks the pricing clock for the current date and hour (weekends and Chinese public holidays are off-peak for the whole day, so the red state only ever appears inside a weekday peak window): a red dot with 高峰 (peak) or a green dot with 空闲 (off-peak), plus a line naming when the current period ends or when peak returns in the expanded state; a card for any other provider never carries the marker. It polls at a relaxed 30 s cadence while the tab is visible, hides in the collapsed 56 px rail, and disappears while the plugin is disabled.
28
28
  - Probes run entirely host-side on a poll cycle (default 60 s, manual refresh button); API keys are resolved through the harness credential seam (`llm-pi-ai` records, `apiKeyEnv` references) and never reach the browser.
29
29
 
30
30
  Supported balance endpoints: DeepSeek (the official live route `deepseek-official` and the catalog alias `deepseek` both resolve), Moonshot (CN/international), OpenRouter, SiliconFlow (CN/international), ZenMux. Supported plan endpoints: Kimi For Coding, GLM Coding Plan (CN via open.bigmodel.cn, international via api.z.ai — the `zai` route the pi-ai catalog registers, plus the `zai-coding` / `zai-coding-cn` aliases; 5-hour, weekly and monthly windows, token-metered and credit-metered plans), OpenCode Go, MiniMax, Codex / ChatGPT subscription (OAuth access token from the pi-ai grant; a stale token shows an error until the harness next refreshes it). Providers without a programmatic endpoint (Qwen token plans, OpenCode Zen PAYG, Anthropic, OpenAI) are listed without facts.
@@ -39,7 +39,7 @@ The published rule bills a Chinese public holiday entirely off-peak even on a Mo
39
39
 
40
40
  ## Install
41
41
 
42
- Requires DSH 0.2.0-rc.2 or later: the plugin is developed against the 0.2.0-rc.2 DSH cohort (its settings page is the Host-generated page of the plugin's own Config schema) and its `@deepseek-ai/*` runtime imports are provided by the host itself.
42
+ Requires DSH 0.2.1-rc.2 or later: the plugin is developed against the 0.2.1-rc.2 DSH cohort (its settings page is the Host-generated page of the plugin's own Config schema) and its `@deepseek-ai/*` runtime imports are provided by the host itself.
43
43
 
44
44
  In your profile (e.g. `~/.dsh/profiles/web`):
45
45
 
package/README.zh.md CHANGED
@@ -5,7 +5,7 @@
5
5
  <p align="center">
6
6
  <img src="https://img.shields.io/npm/v/@linxin666/dsh-usage?style=flat-square" alt="Version">
7
7
  &nbsp;
8
- <img src="https://img.shields.io/badge/DSH-%3E%3D0.2.0--rc.2-4c6ef5?style=flat-square&amp;labelColor=454a54" alt="DSH">
8
+ <img src="https://img.shields.io/badge/DSH-%3E%3D0.2.1--rc.2-4c6ef5?style=flat-square&amp;labelColor=454a54" alt="DSH">
9
9
  &nbsp;
10
10
  <img src="https://img.shields.io/badge/license-Apache--2.0-blue?style=flat-square" alt="License">
11
11
  </p>
@@ -21,10 +21,10 @@
21
21
 
22
22
  插件由宿主侧服务与设置页一级分区(使用统计,位于创意工坊下方)组成:
23
23
 
24
- - **用量页签**:今日 token 分桶合计(输入 / 输出 / 缓存读 / 缓存写,按 provider 上报口径互不相加),分 provider 与模型细分,近 30 天以「提供方-模型」水平条形图展示,以及所有已配置 provider 的余额(同一适配器家族只渲染一行:被该家族运行时路由遮蔽的休眠目录别名不再单独出余额行)。卡片顶部的**日期选择器**可切换到保留期内任何有记录的一天(今日在最前,其余按新到旧排列),此时卡片展示该日自己的合计、分 provider 行与消费估算;峰谷计价时段行只跟随今日,因为它描述的是当前时段的计价。对 DeepSeek 官方路由,页签还展示当前峰谷计价时段(北京时间工作日 09:00-12:00、14:00-18:00 为高峰,按双倍计费)与今日消费估算(CNY)。台账从 `session/event` 实时流折叠(`request/header` 归因路由 + `assistant/message` 用量),持久化到 `$DSH_HOME/dsh-usage/usage-ledger.json`,按本地日保留,因此历史日重启后仍在;统计自插件首次启用起计。
24
+ - **用量页签**:今日 token 分桶合计(输入 / 输出 / 缓存读 / 缓存写,按 provider 上报口径互不相加),分 provider 与模型细分,近 30 天以「提供方-模型」水平条形图展示,以及所有已配置 provider 的余额(同一适配器家族只渲染一行:被该家族运行时路由遮蔽的休眠目录别名不再单独出余额行)。卡片顶部的**日期选择器**可切换到保留期内任何有记录的一天(今日在最前,其余按新到旧排列),此时卡片展示该日自己的合计、分 provider 行与消费估算;峰谷计价时段行只跟随今日,因为它描述的是当前时段的计价。对 DeepSeek 官方路由,页签还展示当前峰谷计价时段(北京时间工作日 09:00-12:00、14:00-18:00 为高峰,按双倍计费)与今日消费估算(CNY);该时段行按当时钟点着色——高峰为红、空闲为绿,并始终带「高峰 / 空闲」文字与圆点,颜色不是唯一信号。台账从 `session/event` 实时流折叠(`request/header` 归因路由 + `assistant/message` 用量),持久化到 `$DSH_HOME/dsh-usage/usage-ledger.json`,按本地日保留,因此历史日重启后仍在;统计自插件首次启用起计。
25
25
  - **个人套餐页签**:每个已配置且暴露套餐端点的 provider 的配额窗口——已用百分比与重置时间(Kimi For Coding 5 小时/每周、GLM 编程计划 5 小时/每周/每月、OpenCode Go 滚动/每周/每月、MiniMax 5 小时/每周、Codex / ChatGPT 订阅 5 小时/每周)。没有真实套餐/订阅体系的厂商(DeepSeek、ZenMux、Moonshot、OpenRouter、SiliconFlow)不出现在此页签,其余额显示在用量页签。
26
26
  - **Token 银行页签**:以 DeepSeek 官方家族的台账用量铸造「鲸元券」,汇率按 100 万 tokens 兑 1 鲸元(防膨胀)。页签把该家族保留台账内的 token 总量(`deepseek` 目录别名与运行时路由 `deepseek-official` 合并计算)折算成票面面额印在钞票图上,附带走票窗口的序列号行,并提供保存图片按钮与(浏览器支持文件分享时的)系统分享按钮。消费行优先展示从官方余额观测到的真实累计花费——余额下降即计为消费,充值上涨不计——首次观测到下降之前回落为折叠时刻估算。铸造总量优先取宿主的全台账聚合,旧宿主回落为近 30 天;无官方用量时展示空状态。页签的日期选择器可把票券改为按某一天铸造(真实花费观测行是自首次余额观测起的累计值,只在整段窗口下展示,单日票券回落为该日的折叠时刻估算)。票面文字与语言无关(数字、拉丁小字、ISO 日期),导出图在浏览器本地渲染。
27
- - **侧栏底部速览卡**:位于侧栏「设置」行上方、与更新/远程触发器同组的紧凑卡片——头条为今日消费估算(今日尚无可计价用量时回落为 tokens 总量),下方是 tokens/调用次数行,以及最多两个已配置 provider 的余额(超出折叠为 +N)。整张卡片主体是一个按钮,点击打开使用统计设置分区,细节只保留在一处;右上角箭头可把卡片收成一行摘要条(消费提供方名称 + 标签 + 头条值),选择跨刷新保持。标签页可见时以 30 秒的宽松周期轮询,侧栏折叠为 56px 栏轨时隐藏,插件停用时消失。
27
+ - **侧栏底部速览卡**:位于侧栏「设置」行上方、与更新/远程触发器同组的紧凑卡片——头条为今日消费估算(今日尚无可计价用量时回落为 tokens 总量),下方是 tokens/调用次数行,以及最多两个已配置 provider 的余额(超出折叠为 +N)。整张卡片主体是一个按钮,点击打开使用统计设置分区,细节只保留在一处;右上角箭头可把卡片收成一行摘要条(消费提供方名称 + 峰谷标记 + 标签 + 头条值),选择跨刷新保持。今日消费走 DeepSeek 官方路由时,卡片按当前钟点与日期标出峰谷(周末与中国法定节假日全天算空闲,红色只出现在工作日的高峰窗口):红色圆点加「高峰」、绿色圆点加「空闲」,展开态另有一行注明当前时段何时结束(高峰)或何时进入高峰(空闲);其他 provider 的卡片不出现该标记。标签页可见时以 30 秒的宽松周期轮询,侧栏折叠为 56px 栏轨时隐藏,插件停用时消失。
28
28
  - 探测完全在宿主侧按轮询周期执行(默认 60 秒,可手动刷新);API key 经宿主凭据缝解析(`llm-pi-ai` 记录、`apiKeyEnv` 引用),永不进入浏览器。
29
29
 
30
30
  支持的余额端点:DeepSeek(官方运行时路由 `deepseek-official` 与目录别名 `deepseek` 均可解析)、Moonshot(国内/国际)、OpenRouter、SiliconFlow(国内/国际)、ZenMux。支持的套餐端点:Kimi For Coding、GLM 编程计划(国内 open.bigmodel.cn、国际 api.z.ai——即 pi-ai 目录注册的 `zai` 路由,另兼容 `zai-coding` / `zai-coding-cn` 别名;覆盖 5 小时 / 每周 / 每月窗口与 token 制、积分制套餐)、OpenCode Go、MiniMax、Codex / ChatGPT 订阅(OAuth access token 取自 pi-ai grant;token 过期时显示错误行,宿主下次跑 Codex 请求自动刷新后恢复)。没有程序化端点的 provider(Qwen token 套餐、OpenCode Zen 按量、Anthropic、OpenAI)仅列出,不展示数据。
@@ -39,7 +39,7 @@
39
39
 
40
40
  ## 安装
41
41
 
42
- 要求 DSH 0.2.0-rc.2 或更高:插件基于 0.2.0-rc.2 DSH cohort 开发(其设置页即宿主根据插件自身 Config schema 生成的页面),`@deepseek-ai/*` 运行时导入由宿主本体提供。
42
+ 要求 DSH 0.2.1-rc.2 或更高:插件基于 0.2.1-rc.2 DSH cohort 开发(其设置页即宿主根据插件自身 Config schema 生成的页面),`@deepseek-ai/*` 运行时导入由宿主本体提供。
43
43
 
44
44
  在 profile(如 `~/.dsh/profiles/web`)中:
45
45
 
package/lib/client.js CHANGED
@@ -4,22 +4,10 @@ window.__ModuleLoader__.load({
4
4
  var module = { exports: {} };
5
5
  var exports = module.exports;
6
6
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
7
8
  let react = require("react");
8
9
  let react_jsx_runtime = require("react/jsx-runtime");
9
10
  let react_dom_client = require("react-dom/client");
10
- //#region \0dsh-store-engine
11
- const platform = ["@deepseek-ai/dsh-client", "-store"].join("");
12
- const legacy = ["@deepseek-ai/dsh-client-runtime", "/client"].join("");
13
- let engine;
14
- try {
15
- engine = require(platform);
16
- } catch {
17
- engine = require(legacy);
18
- }
19
- engine.createSnapshotStore;
20
- const defineStore = engine.defineStore;
21
- engine.shallowEqual;
22
- //#endregion
23
11
  //#region src/client/usage-store.ts
24
12
  /**
25
13
  * Browser-side usage store: the overview snapshot polled from the host plus
@@ -29,7 +17,7 @@ window.__ModuleLoader__.load({
29
17
  */
30
18
  /** Create the usage store handle (apply world only; never module-level). */
31
19
  function createUsageStore() {
32
- return defineStore({
20
+ return (0, _deepseek_ai_dsh_client_store.defineStore)({
33
21
  init: () => ({
34
22
  snapshot: null,
35
23
  status: "loading",
@@ -81,6 +69,10 @@ window.__ModuleLoader__.load({
81
69
  "usage.day.error": "该日用量加载失败:{error}",
82
70
  "usage.peak.on": "DeepSeek 高峰时段:计价 ×2,{time} 结束",
83
71
  "usage.peak.off": "DeepSeek 空闲时段:计价为高峰一半,{time} 进入高峰",
72
+ "usage.peak.tag.on": "高峰",
73
+ "usage.peak.tag.off": "空闲",
74
+ "usage.peak.ends": "{time} 结束",
75
+ "usage.peak.starts": "{time} 进入高峰",
84
76
  "usage.calls": "{n} 次调用",
85
77
  "usage.tokens.total": "总 tokens",
86
78
  "usage.tokens.input": "输入",
@@ -147,6 +139,10 @@ window.__ModuleLoader__.load({
147
139
  "usage.day.error": "Failed to load that day: {error}",
148
140
  "usage.peak.on": "DeepSeek peak hours: 2x pricing, ends {time}",
149
141
  "usage.peak.off": "DeepSeek off-peak: half of peak pricing, peak returns {time}",
142
+ "usage.peak.tag.on": "Peak",
143
+ "usage.peak.tag.off": "Off-peak",
144
+ "usage.peak.ends": "ends {time}",
145
+ "usage.peak.starts": "peak at {time}",
150
146
  "usage.calls": "{n} calls",
151
147
  "usage.tokens.total": "Total tokens",
152
148
  "usage.tokens.input": "Input",
@@ -205,7 +201,7 @@ window.__ModuleLoader__.load({
205
201
  }
206
202
  //#endregion
207
203
  //#region \0dsh-css:packages/dsh-usage/src/client/usage.module.css.mjs
208
- const css = ".cvtkAW_section{color:inherit;flex-direction:column;gap:16px;display:flex}.cvtkAW_header{justify-content:space-between;align-items:center;gap:12px;display:flex}.cvtkAW_currentProvider{opacity:.75;font-size:13px}.cvtkAW_refreshBtn{appearance:none;color:inherit;font:inherit;cursor:pointer;opacity:.85;background:0 0;border:1px solid;border-radius:8px;padding:4px 12px;font-size:12px;transition:opacity .12s,background-color .12s}.cvtkAW_refreshBtn:hover:not(:disabled){opacity:1;background:color-mix(in srgb, currentColor 8%, transparent)}.cvtkAW_refreshBtn:disabled{cursor:default;opacity:.5}.cvtkAW_refreshBtn:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, currentColor 45%, transparent);outline:none}.cvtkAW_tabs{border-bottom:1px solid color-mix(in srgb, currentColor 14%, transparent);gap:4px;display:flex}.cvtkAW_tab{appearance:none;color:inherit;font:inherit;cursor:pointer;opacity:.65;background:0 0;border:none;border-bottom:2px solid #0000;margin-bottom:-1px;padding:6px 14px;font-size:13px}.cvtkAW_tab:hover{opacity:.9}.cvtkAW_tab:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, currentColor 45%, transparent);outline:none}.cvtkAW_tabActive{opacity:1;border-bottom-color:currentColor;font-weight:600}.cvtkAW_card{border:1px solid color-mix(in srgb, currentColor 14%, transparent);border-radius:12px;flex-direction:column;gap:10px;padding:14px 16px;display:flex}.cvtkAW_cardTitle{letter-spacing:.04em;text-transform:uppercase;opacity:.6;font-size:12px;font-weight:600}.cvtkAW_dayPicker{align-items:center;gap:8px;display:flex}.cvtkAW_dayPickerLabel{opacity:.6;font-size:11px}.cvtkAW_daySelect{border:1px solid color-mix(in srgb, currentColor 25%, transparent);color:inherit;font:inherit;font-variant-numeric:tabular-nums;background:0 0;border-radius:6px;padding:3px 8px;font-size:12px}.cvtkAW_daySelect:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, currentColor 45%, transparent);outline:none}.cvtkAW_daySelect option,.cvtkAW_settingItem select option{background-color:var(--dsw-alias-bg-multi-select,Canvas);color:var(--dsw-alias-label-primary,CanvasText)}.cvtkAW_statRow{flex-wrap:wrap;gap:18px;display:flex}.cvtkAW_stat{flex-direction:column;gap:2px;display:flex}.cvtkAW_statValue{font-variant-numeric:tabular-nums;font-size:18px;font-weight:600}.cvtkAW_statLabel{opacity:.6;font-size:11px}.cvtkAW_providerRow{border-top:1px solid color-mix(in srgb, currentColor 8%, transparent);flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;padding:6px 0;font-size:13px;display:flex}.cvtkAW_providerRow:first-of-type{border-top:none}.cvtkAW_providerName{align-items:center;gap:8px;min-width:0;display:flex}.cvtkAW_providerTokens{font-variant-numeric:tabular-nums;opacity:.75;white-space:nowrap}.cvtkAW_providerBalance{font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:600}.cvtkAW_currentBadge{border:1px solid color-mix(in srgb, currentColor 35%, transparent);opacity:.8;border-radius:999px;flex:none;padding:1px 7px;font-size:10px;font-weight:600}.cvtkAW_chart{flex-direction:column;gap:12px;display:flex}.cvtkAW_chartProvider{flex-direction:column;gap:4px;display:flex}.cvtkAW_chartHead{justify-content:space-between;align-items:baseline;gap:10px;font-size:13px;display:flex}.cvtkAW_chartTokens{font-variant-numeric:tabular-nums;opacity:.65;white-space:nowrap;font-size:11px}.cvtkAW_chartBar{background:color-mix(in srgb, currentColor 8%, transparent);border-radius:999px;height:8px;display:block;overflow:hidden}.cvtkAW_chartFill{background:color-mix(in srgb, currentColor 55%, transparent);border-radius:999px;height:100%;transition:width .3s;display:block}.cvtkAW_chartModel{opacity:.8;grid-template-columns:minmax(80px,180px) 1fr auto;align-items:center;gap:8px;padding-left:14px;font-size:11px;display:grid}.cvtkAW_chartModelName{text-overflow:ellipsis;white-space:nowrap;opacity:.8;overflow:hidden}.cvtkAW_chartModelBar{background:color-mix(in srgb, currentColor 6%, transparent);border-radius:999px;height:4px;display:block;overflow:hidden}.cvtkAW_chartModelFill{background:color-mix(in srgb, currentColor 35%, transparent);border-radius:999px;height:100%;transition:width .3s;display:block}.cvtkAW_trendAxis{opacity:.5;font-variant-numeric:tabular-nums;justify-content:space-between;font-size:10px;display:flex}.cvtkAW_muted{opacity:.6;font-size:12px}.cvtkAW_voucherPreview canvas{border-radius:8px;width:100%;height:auto;display:block}.cvtkAW_buttonRow{gap:8px;display:flex}.cvtkAW_errorLine{opacity:.75;font-size:12px}.cvtkAW_planCard{flex-direction:column;gap:8px;display:flex}.cvtkAW_planHead{justify-content:space-between;align-items:baseline;gap:10px;display:flex}.cvtkAW_planName{font-size:14px;font-weight:600}.cvtkAW_windowRow{flex-direction:column;gap:4px;display:flex}.cvtkAW_windowLabel{opacity:.8;font-variant-numeric:tabular-nums;justify-content:space-between;font-size:12px;display:flex}.cvtkAW_bar{background:color-mix(in srgb, currentColor 10%, transparent);border-radius:999px;height:6px;overflow:hidden}.cvtkAW_barFill{background:color-mix(in srgb, currentColor 55%, transparent);border-radius:999px;height:100%;transition:width .3s}.cvtkAW_barWarn{background:#d97706}.cvtkAW_barLow{background:#dc2626}.cvtkAW_resetLine{opacity:.55;font-variant-numeric:tabular-nums;font-size:11px}.cvtkAW_settingsGrid{flex-wrap:wrap;align-items:center;gap:16px;display:flex}.cvtkAW_settingItem{align-items:center;gap:8px;font-size:13px;display:flex}.cvtkAW_settingItem input[type=checkbox]{accent-color:currentColor}.cvtkAW_settingItem input[type=number]{border:1px solid color-mix(in srgb, currentColor 25%, transparent);width:90px;color:inherit;font:inherit;background:0 0;border-radius:6px;padding:3px 8px;font-size:13px}.cvtkAW_settingItem select{border:1px solid color-mix(in srgb, currentColor 25%, transparent);color:inherit;font:inherit;background:0 0;border-radius:6px;padding:3px 8px;font-size:13px}.cvtkAW_settingItem input:focus-visible,.cvtkAW_settingItem select:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, currentColor 45%, transparent);outline:none}.cvtkAW_footCard{box-sizing:border-box;background:color-mix(in srgb, currentColor 4%, transparent);width:100%;color:inherit;border:none;border-radius:12px;margin:2px 0 4px;transition:background-color .12s;position:relative}.cvtkAW_footCard:hover{background:var(--dsw-alias-interactive-bg-hover)}.cvtkAW_footCardCollapsed{background:0 0}.cvtkAW_footMain{appearance:none;box-sizing:border-box;width:100%;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:12px;flex-direction:column;gap:4px;padding:8px;display:flex}.cvtkAW_footMain:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, currentColor 45%, transparent);outline:none}.cvtkAW_footToggle{appearance:none;width:20px;height:20px;color:inherit;cursor:pointer;opacity:.55;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:0;transition:opacity .12s,background-color .12s;display:inline-flex;position:absolute;top:6px;right:6px}.cvtkAW_footCard:hover .cvtkAW_footToggle{opacity:.8}.cvtkAW_footToggle:hover{opacity:1;background:color-mix(in srgb, currentColor 10%, transparent)}.cvtkAW_footToggle:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, currentColor 45%, transparent);outline:none}.cvtkAW_footToggle svg{display:block}.cvtkAW_footHead{justify-content:space-between;align-items:baseline;gap:8px;display:flex}.cvtkAW_footTitle{opacity:.65;white-space:nowrap;align-items:center;gap:6px;min-width:0;font-size:12px;display:inline-flex}.cvtkAW_footTitle svg{flex:none;display:block}.cvtkAW_footValue{font-variant-numeric:tabular-nums;white-space:nowrap;margin-right:18px;font-size:15px;font-weight:600}.cvtkAW_footLine{opacity:.7;font-variant-numeric:tabular-nums;text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.cvtkAW_footMeta{opacity:.5;font-variant-numeric:tabular-nums;font-size:10px}.cvtkAW_footCardCollapsed .cvtkAW_footMain{min-height:36px;padding:7px 8px}.cvtkAW_footStrip{white-space:nowrap;align-items:center;gap:6px;padding-right:20px;font-size:12px;display:flex;overflow:hidden}.cvtkAW_footStrip svg{opacity:.65;flex:none;display:block}.cvtkAW_footStripProvider{text-overflow:ellipsis;flex:none;max-width:45%;font-weight:500;overflow:hidden}.cvtkAW_footStripLabel{opacity:.65;text-overflow:ellipsis;overflow:hidden}.cvtkAW_footStripValue{font-variant-numeric:tabular-nums;margin-left:auto;font-weight:600}[data-dsh-frame][data-sidebar-collapsed] .cvtkAW_footCard,[data-sidebar-collapsed] .cvtkAW_footCard{display:none}";
204
+ const css = ".cvtkAW_section{color:inherit;flex-direction:column;gap:16px;display:flex}.cvtkAW_header{justify-content:space-between;align-items:center;gap:12px;display:flex}.cvtkAW_currentProvider{opacity:.75;font-size:13px}.cvtkAW_refreshBtn{appearance:none;color:inherit;font:inherit;cursor:pointer;opacity:.85;background:0 0;border:1px solid;border-radius:8px;padding:4px 12px;font-size:12px;transition:opacity .12s,background-color .12s}.cvtkAW_refreshBtn:hover:not(:disabled){opacity:1;background:color-mix(in srgb, currentColor 8%, transparent)}.cvtkAW_refreshBtn:disabled{cursor:default;opacity:.5}.cvtkAW_refreshBtn:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, currentColor 45%, transparent);outline:none}.cvtkAW_tabs{border-bottom:1px solid color-mix(in srgb, currentColor 14%, transparent);gap:4px;display:flex}.cvtkAW_tab{appearance:none;color:inherit;font:inherit;cursor:pointer;opacity:.65;background:0 0;border:none;border-bottom:2px solid #0000;margin-bottom:-1px;padding:6px 14px;font-size:13px}.cvtkAW_tab:hover{opacity:.9}.cvtkAW_tab:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, currentColor 45%, transparent);outline:none}.cvtkAW_tabActive{opacity:1;border-bottom-color:currentColor;font-weight:600}.cvtkAW_card{border:1px solid color-mix(in srgb, currentColor 14%, transparent);border-radius:12px;flex-direction:column;gap:10px;padding:14px 16px;display:flex}.cvtkAW_cardTitle{letter-spacing:.04em;text-transform:uppercase;opacity:.6;font-size:12px;font-weight:600}.cvtkAW_dayPicker{align-items:center;gap:8px;display:flex}.cvtkAW_dayPickerLabel{opacity:.6;font-size:11px}.cvtkAW_daySelect{border:1px solid color-mix(in srgb, currentColor 25%, transparent);color:inherit;font:inherit;font-variant-numeric:tabular-nums;background:0 0;border-radius:6px;padding:3px 8px;font-size:12px}.cvtkAW_daySelect:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, currentColor 45%, transparent);outline:none}.cvtkAW_daySelect option,.cvtkAW_settingItem select option{background-color:var(--dsw-alias-bg-multi-select,Canvas);color:var(--dsw-alias-label-primary,CanvasText)}.cvtkAW_statRow{flex-wrap:wrap;gap:18px;display:flex}.cvtkAW_stat{flex-direction:column;gap:2px;display:flex}.cvtkAW_statValue{font-variant-numeric:tabular-nums;font-size:18px;font-weight:600}.cvtkAW_statLabel{opacity:.6;font-size:11px}.cvtkAW_providerRow{border-top:1px solid color-mix(in srgb, currentColor 8%, transparent);flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;padding:6px 0;font-size:13px;display:flex}.cvtkAW_providerRow:first-of-type{border-top:none}.cvtkAW_providerName{align-items:center;gap:8px;min-width:0;display:flex}.cvtkAW_providerTokens{font-variant-numeric:tabular-nums;opacity:.75;white-space:nowrap}.cvtkAW_providerBalance{font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:600}.cvtkAW_currentBadge{border:1px solid color-mix(in srgb, currentColor 35%, transparent);opacity:.8;border-radius:999px;flex:none;padding:1px 7px;font-size:10px;font-weight:600}.cvtkAW_chart{flex-direction:column;gap:12px;display:flex}.cvtkAW_chartProvider{flex-direction:column;gap:4px;display:flex}.cvtkAW_chartHead{justify-content:space-between;align-items:baseline;gap:10px;font-size:13px;display:flex}.cvtkAW_chartTokens{font-variant-numeric:tabular-nums;opacity:.65;white-space:nowrap;font-size:11px}.cvtkAW_chartBar{background:color-mix(in srgb, currentColor 8%, transparent);border-radius:999px;height:8px;display:block;overflow:hidden}.cvtkAW_chartFill{background:color-mix(in srgb, currentColor 55%, transparent);border-radius:999px;height:100%;transition:width .3s;display:block}.cvtkAW_chartModel{opacity:.8;grid-template-columns:minmax(80px,180px) 1fr auto;align-items:center;gap:8px;padding-left:14px;font-size:11px;display:grid}.cvtkAW_chartModelName{text-overflow:ellipsis;white-space:nowrap;opacity:.8;overflow:hidden}.cvtkAW_chartModelBar{background:color-mix(in srgb, currentColor 6%, transparent);border-radius:999px;height:4px;display:block;overflow:hidden}.cvtkAW_chartModelFill{background:color-mix(in srgb, currentColor 35%, transparent);border-radius:999px;height:100%;transition:width .3s;display:block}.cvtkAW_trendAxis{opacity:.5;font-variant-numeric:tabular-nums;justify-content:space-between;font-size:10px;display:flex}.cvtkAW_muted{opacity:.6;font-size:12px}.cvtkAW_voucherPreview canvas{border-radius:8px;width:100%;height:auto;display:block}.cvtkAW_buttonRow{gap:8px;display:flex}.cvtkAW_errorLine{opacity:.75;font-size:12px}.cvtkAW_planCard{flex-direction:column;gap:8px;display:flex}.cvtkAW_planHead{justify-content:space-between;align-items:baseline;gap:10px;display:flex}.cvtkAW_planName{font-size:14px;font-weight:600}.cvtkAW_windowRow{flex-direction:column;gap:4px;display:flex}.cvtkAW_windowLabel{opacity:.8;font-variant-numeric:tabular-nums;justify-content:space-between;font-size:12px;display:flex}.cvtkAW_bar{background:color-mix(in srgb, currentColor 10%, transparent);border-radius:999px;height:6px;overflow:hidden}.cvtkAW_barFill{background:color-mix(in srgb, currentColor 55%, transparent);border-radius:999px;height:100%;transition:width .3s}.cvtkAW_barWarn{background:#d97706}.cvtkAW_barLow{background:#dc2626}.cvtkAW_resetLine{opacity:.55;font-variant-numeric:tabular-nums;font-size:11px}.cvtkAW_settingsGrid{flex-wrap:wrap;align-items:center;gap:16px;display:flex}.cvtkAW_settingItem{align-items:center;gap:8px;font-size:13px;display:flex}.cvtkAW_settingItem input[type=checkbox]{accent-color:currentColor}.cvtkAW_settingItem input[type=number]{border:1px solid color-mix(in srgb, currentColor 25%, transparent);width:90px;color:inherit;font:inherit;background:0 0;border-radius:6px;padding:3px 8px;font-size:13px}.cvtkAW_settingItem select{border:1px solid color-mix(in srgb, currentColor 25%, transparent);color:inherit;font:inherit;background:0 0;border-radius:6px;padding:3px 8px;font-size:13px}.cvtkAW_settingItem input:focus-visible,.cvtkAW_settingItem select:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, currentColor 45%, transparent);outline:none}.cvtkAW_footCard{box-sizing:border-box;background:color-mix(in srgb, currentColor 4%, transparent);width:100%;color:inherit;border:none;border-radius:12px;margin:2px 0 4px;transition:background-color .12s;position:relative}.cvtkAW_footCard:hover{background:var(--dsw-alias-interactive-bg-hover)}.cvtkAW_footCardCollapsed{background:0 0}.cvtkAW_footMain{appearance:none;box-sizing:border-box;width:100%;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:12px;flex-direction:column;gap:4px;padding:8px;display:flex}.cvtkAW_footMain:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, currentColor 45%, transparent);outline:none}.cvtkAW_footToggle{appearance:none;width:20px;height:20px;color:inherit;cursor:pointer;opacity:.55;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:0;transition:opacity .12s,background-color .12s;display:inline-flex;position:absolute;top:6px;right:6px}.cvtkAW_footCard:hover .cvtkAW_footToggle{opacity:.8}.cvtkAW_footToggle:hover{opacity:1;background:color-mix(in srgb, currentColor 10%, transparent)}.cvtkAW_footToggle:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb, currentColor 45%, transparent);outline:none}.cvtkAW_footToggle svg{display:block}.cvtkAW_footHead{justify-content:space-between;align-items:baseline;gap:8px;display:flex}.cvtkAW_footTitle{opacity:.65;white-space:nowrap;align-items:center;gap:6px;min-width:0;font-size:12px;display:inline-flex}.cvtkAW_footTitle svg{flex:none;display:block}.cvtkAW_footValue{font-variant-numeric:tabular-nums;white-space:nowrap;margin-right:18px;font-size:15px;font-weight:600}.cvtkAW_footLine{opacity:.7;font-variant-numeric:tabular-nums;text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.cvtkAW_footMeta{opacity:.5;font-variant-numeric:tabular-nums;font-size:10px}.cvtkAW_footCardCollapsed .cvtkAW_footMain{min-height:36px;padding:7px 8px}.cvtkAW_footStrip{white-space:nowrap;align-items:center;gap:6px;padding-right:20px;font-size:12px;display:flex;overflow:hidden}.cvtkAW_footStrip svg{opacity:.65;flex:none;display:block}.cvtkAW_footStripProvider{text-overflow:ellipsis;flex:none;max-width:38%;font-weight:500;overflow:hidden}.cvtkAW_footStripLabel{opacity:.65;text-overflow:ellipsis;overflow:hidden}.cvtkAW_footStripValue{font-variant-numeric:tabular-nums;margin-left:auto;font-weight:600}[data-dsh-frame][data-sidebar-collapsed] .cvtkAW_footCard,[data-sidebar-collapsed] .cvtkAW_footCard{display:none}.cvtkAW_peakBadge,.cvtkAW_peakLine{font-variant-numeric:tabular-nums;white-space:nowrap;align-items:center;gap:4px;font-size:11px;display:inline-flex}.cvtkAW_peakBadge{flex:none}.cvtkAW_peakLine{gap:6px}.cvtkAW_peakBadge[data-peak=on],.cvtkAW_peakLine[data-peak=on]{color:var(--dsw-alias-state-error-primary,#b42318)}.cvtkAW_peakBadge[data-peak=off],.cvtkAW_peakLine[data-peak=off]{color:var(--dsw-alias-state-success-primary,#067647)}.cvtkAW_peakDot{background:currentColor;border-radius:50%;flex:none;width:6px;height:6px}.cvtkAW_footPeak{white-space:nowrap;align-items:center;gap:5px;font-size:10px;display:flex;overflow:hidden}.cvtkAW_footPeakClock{opacity:.7;font-variant-numeric:tabular-nums}";
209
205
  const tagId = "@linxin666/dsh-usage/packages/dsh-usage/src/client/usage.module.css";
210
206
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
211
207
  const tag = document.createElement("style");
@@ -244,6 +240,8 @@ window.__ModuleLoader__.load({
244
240
  "footLine": "cvtkAW_footLine",
245
241
  "footMain": "cvtkAW_footMain",
246
242
  "footMeta": "cvtkAW_footMeta",
243
+ "footPeak": "cvtkAW_footPeak",
244
+ "footPeakClock": "cvtkAW_footPeakClock",
247
245
  "footStrip": "cvtkAW_footStrip",
248
246
  "footStripLabel": "cvtkAW_footStripLabel",
249
247
  "footStripProvider": "cvtkAW_footStripProvider",
@@ -253,6 +251,9 @@ window.__ModuleLoader__.load({
253
251
  "footValue": "cvtkAW_footValue",
254
252
  "header": "cvtkAW_header",
255
253
  "muted": "cvtkAW_muted",
254
+ "peakBadge": "cvtkAW_peakBadge",
255
+ "peakDot": "cvtkAW_peakDot",
256
+ "peakLine": "cvtkAW_peakLine",
256
257
  "planCard": "cvtkAW_planCard",
257
258
  "planHead": "cvtkAW_planHead",
258
259
  "planName": "cvtkAW_planName",
@@ -278,6 +279,34 @@ window.__ModuleLoader__.load({
278
279
  "windowRow": "cvtkAW_windowRow"
279
280
  };
280
281
  //#endregion
282
+ //#region src/client/PeakBadge.tsx
283
+ /** HH:MM of one instant; an unparsable instant drops the time. */
284
+ function formatClock(ms) {
285
+ try {
286
+ return new Date(ms).toLocaleTimeString([], {
287
+ hour: "2-digit",
288
+ minute: "2-digit"
289
+ });
290
+ } catch {
291
+ return "";
292
+ }
293
+ }
294
+ /** The peak/off-peak marker itself; nothing renders outside the DeepSeek family. */
295
+ function PeakBadge(props) {
296
+ const { peak, boundaryMs, variant } = props;
297
+ const sentence = t(peak ? "usage.peak.on" : "usage.peak.off", { time: formatClock(boundaryMs) });
298
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
299
+ className: variant === "full" ? usage_module_css_default.peakLine : usage_module_css_default.peakBadge,
300
+ "data-peak": peak ? "on" : "off",
301
+ "data-dsh-part": "peak-status",
302
+ title: sentence,
303
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
304
+ className: usage_module_css_default.peakDot,
305
+ "aria-hidden": "true"
306
+ }), variant === "full" ? sentence : t(peak ? "usage.peak.tag.on" : "usage.peak.tag.off")]
307
+ });
308
+ }
309
+ //#endregion
281
310
  //#region src/core/adapters.ts
282
311
  /** Parse a string/number into a finite number, else undefined. */
283
312
  function toNum(value) {
@@ -1235,16 +1264,6 @@ window.__ModuleLoader__.load({
1235
1264
  return "";
1236
1265
  }
1237
1266
  }
1238
- function formatClock$1(ms) {
1239
- try {
1240
- return new Date(ms).toLocaleTimeString([], {
1241
- hour: "2-digit",
1242
- minute: "2-digit"
1243
- });
1244
- } catch {
1245
- return "";
1246
- }
1247
- }
1248
1267
  /** Formatted CNY spend estimate (the only priced currency today). */
1249
1268
  function formatCost(cost) {
1250
1269
  return "¥" + cost.toFixed(2);
@@ -1594,10 +1613,10 @@ window.__ModuleLoader__.load({
1594
1613
  setUsageDay(date === todayDate ? void 0 : date);
1595
1614
  }
1596
1615
  }),
1597
- deepseekVisible && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1598
- className: usage_module_css_default.muted,
1599
- "data-dsh-part": "peak-status",
1600
- children: t(deepseekPeriod.peak ? "usage.peak.on" : "usage.peak.off", { time: formatClock$1(deepseekPeriod.boundaryMs) })
1616
+ deepseekVisible && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PeakBadge, {
1617
+ peak: deepseekPeriod.peak,
1618
+ boundaryMs: deepseekPeriod.boundaryMs,
1619
+ variant: "full"
1601
1620
  }),
1602
1621
  usageDayLoad?.status === "error" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1603
1622
  className: usage_module_css_default.errorLine,
@@ -2269,29 +2288,22 @@ window.__ModuleLoader__.load({
2269
2288
  if (currency === "USD") return "$" + balance.totalBalance;
2270
2289
  return currency + " " + balance.totalBalance;
2271
2290
  }
2272
- function formatClock(ms) {
2273
- try {
2274
- return new Date(ms).toLocaleTimeString([], {
2275
- hour: "2-digit",
2276
- minute: "2-digit"
2277
- });
2278
- } catch {
2279
- return "";
2280
- }
2281
- }
2282
2291
  /**
2283
- * Display name of the provider owning today's priced spend: the day's highest
2284
- * cost row, else the current session route, resolved through the provider
2285
- * snapshot (an older host without the day rows falls back to the current
2286
- * route). Undefined when there is no route to name.
2292
+ * Route key owning today's priced spend: the day's highest cost row, else the
2293
+ * current session route (an older host without the day rows falls back to the
2294
+ * current route). Undefined when neither names one.
2287
2295
  */
2288
- function spendProvider(snapshot) {
2296
+ function spendRoute(snapshot) {
2289
2297
  let top;
2290
2298
  for (const row of snapshot.usage.today.providers) {
2291
2299
  if (row.totals.cost <= 0) continue;
2292
2300
  if (top === void 0 || row.totals.cost > top.totals.cost) top = row;
2293
2301
  }
2294
- const route = top?.provider ?? snapshot.current.provider;
2302
+ return top?.provider ?? snapshot.current.provider;
2303
+ }
2304
+ /** Display name of the route spendRoute() names, resolved through the snapshot. */
2305
+ function spendProvider(snapshot) {
2306
+ const route = spendRoute(snapshot);
2295
2307
  if (route === void 0) return void 0;
2296
2308
  return snapshot.providers.find((entry) => entry.provider === route)?.displayName ?? (route === snapshot.current.provider ? snapshot.current.displayName : void 0) ?? route;
2297
2309
  }
@@ -2426,6 +2438,8 @@ window.__ModuleLoader__.load({
2426
2438
  }
2427
2439
  const head = headline(snapshot);
2428
2440
  const balances = balanceLine(snapshot);
2441
+ const route = spendRoute(snapshot);
2442
+ const period = route !== void 0 && isDeepSeekProviderRoute(route) ? deepseekPeriodAt(Date.now()) : void 0;
2429
2443
  if (collapsed) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2430
2444
  className: cardClass(true),
2431
2445
  "data-dsh-plugin": "usage",
@@ -2446,6 +2460,11 @@ window.__ModuleLoader__.load({
2446
2460
  className: usage_module_css_default.footStripProvider,
2447
2461
  children: head.provider
2448
2462
  }),
2463
+ period !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PeakBadge, {
2464
+ peak: period.peak,
2465
+ boundaryMs: period.boundaryMs,
2466
+ variant: "compact"
2467
+ }),
2449
2468
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2450
2469
  className: usage_module_css_default.footStripLabel,
2451
2470
  children: head.label
@@ -2490,6 +2509,17 @@ window.__ModuleLoader__.load({
2490
2509
  "data-dsh-part": "foot-card-balances",
2491
2510
  children: balances
2492
2511
  }),
2512
+ period !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2513
+ className: usage_module_css_default.footPeak,
2514
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PeakBadge, {
2515
+ peak: period.peak,
2516
+ boundaryMs: period.boundaryMs,
2517
+ variant: "compact"
2518
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2519
+ className: usage_module_css_default.footPeakClock,
2520
+ children: t(period.peak ? "usage.peak.ends" : "usage.peak.starts", { time: formatClock(period.boundaryMs) })
2521
+ })]
2522
+ }),
2493
2523
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2494
2524
  className: usage_module_css_default.footMeta,
2495
2525
  children: t("usage.updated", { time: formatClock(snapshot.updatedAt) })
@@ -2578,8 +2608,7 @@ window.__ModuleLoader__.load({
2578
2608
  base: void 0,
2579
2609
  user: void 0,
2580
2610
  revision: void 0,
2581
- writable: false,
2582
- mode: "host"
2611
+ writable: false
2583
2612
  };
2584
2613
  }
2585
2614
  /**