dsh-token-pulse 0.4.1 → 0.4.3
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 +413 -125
- package/lib/client.js.map +1 -1
- package/lib/index.mjs +12 -2
- package/lib/index.mjs.map +1 -1
- package/package.json +9 -9
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["formatTokens","formatTokensShort","React","React","React","a","enDict","React"],"sources":["../src/client/StatsCards.tsx","../src/date-bucket.ts","../src/aggregation.ts","../src/client/HeatmapGrid.tsx","../src/client/ModelTop5.tsx","../src/client/trend.ts","../src/client/TrendChart.tsx","../src/client/locales.ts","../src/client/hooks.ts","../src/client/SettingsSection.tsx","../src/client/index.ts"],"sourcesContent":["import * as React from \"react\";\n\nexport type Totals = {\n today: number;\n thisWeek: number;\n thisMonth: number;\n all: number;\n};\n\nexport function formatTokens(n: number): string {\n if (n >= 1_000_000_000) return (n / 1_000_000_000).toFixed(2) + \"B\";\n if (n >= 1_000_000) return (n / 1_000_000).toFixed(2) + \"M\";\n if (n >= 1000) return (n / 1000).toFixed(2) + \"k\";\n return n.toLocaleString();\n}\n\ntype CardProps = {\n label: string;\n value: number;\n hint?: string;\n};\n\nfunction StatCard({ label, value, hint }: CardProps) {\n return (\n <div\n style={{\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n borderRadius: 12,\n padding: \"12px 14px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 4,\n minWidth: 0,\n }}\n >\n <div style={{ fontSize: 12, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: \"18px\" }}>{label}</div>\n <div style={{ fontSize: 18, fontWeight: 600, color: \"var(--dsw-alias-label-primary)\", lineHeight: \"28px\", overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>\n {formatTokens(value)}\n </div>\n {hint ? <div style={{ fontSize: 12, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: \"16px\" }}>{hint}</div> : null}\n </div>\n );\n}\n\nexport function StatsCards({\n t,\n totals,\n todayCount,\n}: {\n t: (key: string, params?: Record<string, any>) => string;\n totals: Totals;\n todayCount?: number;\n}) {\n return (\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"repeat(4, minmax(0, 1fr))\",\n gap: 12,\n }}\n >\n <StatCard label={t(\"stats.today\")} value={totals.today} hint={todayCount !== undefined ? t(\"stats.count\", { count: todayCount }) : undefined} />\n <StatCard label={t(\"stats.week\")} value={totals.thisWeek} />\n <StatCard label={t(\"stats.month\")} value={totals.thisMonth} />\n <StatCard label={t(\"stats.all\")} value={totals.all} />\n </div>\n );\n}\n\nexport default StatsCards;\n","const TZ = \"Asia/Shanghai\";\n\nexport function toDayKey(ms: number, tz = TZ): string {\n const fmt = new Intl.DateTimeFormat(\"en-CA\", {\n timeZone: tz,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n });\n return fmt.format(new Date(ms));\n}\n\nexport function dayKeyToDate(key: string, _tz = TZ): Date {\n return new Date(key + \"T12:00:00+08:00\");\n}\n\nexport function weekStartOf(dayKey: string): string {\n const d = dayKeyToDate(dayKey);\n const dow = (d.getDay() + 6) % 7; // Mon=0\n d.setDate(d.getDate() - dow);\n return toDayKey(d.getTime());\n}\n\nexport function monthStartOf(dayKey: string): string {\n const d = dayKeyToDate(dayKey);\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, \"0\")}-01`;\n}\n\nexport function quarterStartOf(dayKey: string): string {\n const d = dayKeyToDate(dayKey);\n const q = Math.floor(d.getMonth() / 3);\n const m = q * 3 + 1;\n return `${d.getFullYear()}-${String(m).padStart(2, \"0\")}-01`;\n}\n\nexport function yearStartOf(dayKey: string): string {\n const d = dayKeyToDate(dayKey);\n return `${d.getFullYear()}-01-01`;\n}\n\nexport function addDays(dayKey: string, n: number): string {\n const d = dayKeyToDate(dayKey);\n d.setDate(d.getDate() + n);\n return toDayKey(d.getTime());\n}\n\nexport function listDaysInRange(startKey: string, endKey: string): string[] {\n const result: string[] = [];\n let cur = startKey;\n while (cur <= endKey) {\n result.push(cur);\n cur = addDays(cur, 1);\n }\n return result;\n}\n\nexport function weekRangeFor(dateKey: string): [string, string] {\n const s = weekStartOf(dateKey);\n return [s, addDays(s, 6)];\n}\n\nexport function monthRangeFor(dateKey: string): [string, string] {\n const s = monthStartOf(dateKey);\n const d = dayKeyToDate(s);\n const lastDay = new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();\n return [s, `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, \"0\")}-${String(lastDay).padStart(2, \"0\")}`];\n}\n\n/** Last ~90 days: sliding window for the \"Quarter\" tab (not calendar quarter). */\nexport function quarterRangeFor(dateKey: string): [string, string] {\n return [addDays(dateKey, -89), dateKey];\n}\n\nexport function yearRangeFor(dateKey: string): [string, string] {\n const s = yearStartOf(dateKey);\n const d = dayKeyToDate(s);\n return [s, `${d.getFullYear()}-12-31`];\n}\n","import {\n toDayKey,\n addDays,\n listDaysInRange,\n weekRangeFor,\n monthRangeFor,\n quarterRangeFor,\n yearRangeFor,\n} from \"./date-bucket.ts\";\n\nexport type RawUsageEvent = {\n time: number;\n provider: string;\n model: string;\n usage: {\n inputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n outputTokens: number;\n };\n /** Session id this usage belongs to. Used by HeatmapStore.refresh() to\n * replace a live session's events in place without duplicating history. */\n sid?: string;\n};\n\nexport type DayAgg = {\n dayKey: string;\n totalTokens: number;\n uncachedInputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n outputTokens: number;\n count: number;\n byModel: Map<string, number>;\n byProvider: Map<string, number>;\n /** 24 hourly buckets in Asia/Shanghai, index 0 = 00:00-01:00 */\n hourlyTokens: number[];\n winnerModel: string | null;\n winnerProvider: string | null;\n};\n\nexport type TopItem = { name: string; tokens: number };\n\nexport type Aggregated = {\n byDay: Map<string, DayAgg>;\n totals: { today: number; thisWeek: number; thisMonth: number; all: number };\n topModels: Array<{ model: string; tokens: number }>;\n topProviders: Array<{ provider: string; tokens: number }>;\n /** @deprecated use topModels */\n top5: Array<{ model: string; tokens: number }>;\n weekDays(dayKey: string): DayAgg[];\n monthDays(dayKey: string): DayAgg[];\n quarterDays(dayKey: string): DayAgg[];\n yearDays(dayKey: string): DayAgg[];\n top5InWindow(days: DayAgg[]): Array<{ model: string; tokens: number }>;\n topProvidersInWindow(days: DayAgg[]): Array<{ provider: string; tokens: number }>;\n};\n\nfunction emptyDay(dayKey: string): DayAgg {\n return {\n dayKey,\n totalTokens: 0,\n uncachedInputTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n outputTokens: 0,\n count: 0,\n byModel: new Map(),\n byProvider: new Map(),\n hourlyTokens: new Array(24).fill(0),\n winnerModel: null,\n winnerProvider: null,\n };\n}\n\nfunction sumByDay(days: DayAgg[]): number {\n return days.reduce((s, d) => s + d.totalTokens, 0);\n}\n\nfunction resolveDay(byDay: Map<string, DayAgg>, key: string): DayAgg {\n return byDay.get(key) ?? emptyDay(key);\n}\n\nfunction resolveRange(byDay: Map<string, DayAgg>, start: string, end: string): DayAgg[] {\n return listDaysInRange(start, end).map((k) => resolveDay(byDay, k));\n}\n\n/**\n * 5-level fallback for callers without a view-aware max (e.g. legacy tests).\n * For view-aware quantile, use levelForView().\n */\nexport function clampLevel(value: number): 0 | 1 | 2 | 3 | 4 {\n if (value === 0) return 0;\n if (value <= 2000) return 1;\n if (value <= 10000) return 2;\n if (value <= 50000) return 3;\n return 4;\n}\n\n/** View-aware quantile: 0, (0,25%], (25%,50%], (50%,75%], (75%,100%] so month/quarter spread across the palette. */\nexport function levelForView(value: number, viewMax: number): 0 | 1 | 2 | 3 | 4 {\n if (value === 0) return 0;\n if (viewMax <= 0) return 1;\n const r = value / viewMax;\n if (r <= 0.25) return 1;\n if (r <= 0.5) return 2;\n if (r <= 0.75) return 3;\n return 4;\n}\n\n/** Minimum number of non-zero values before rank-based bucketing kicks in. Below this we fall back to logLevel(). */\nexport const MIN_RANK_POINTS = 5;\n\n/**\n * Rank-based (percentile) level. Outlier-proof: no matter how large one day is,\n * lower values still spread across levels 1-4 by their position among non-zero\n * values — a single huge day no longer flattens everything to level 1.\n * `sortedNonZero` must be the ascending-sorted array of all non-zero values in\n * the view. Uses the midpoint of the \"below\" and \"at-or-below\" ranks, so ties\n * sit in the middle of their band; the maximum always lands on level 4 and the\n * minimum on level 1, guaranteeing all four colored levels appear (n ≥ 2).\n * 0 maps to 0.\n */\nexport function levelByRank(value: number, sortedNonZero: number[]): 0 | 1 | 2 | 3 | 4 {\n if (value <= 0) return 0;\n const n = sortedNonZero.length;\n if (n === 0) return 1;\n let below = 0;\n let atOrBelow = 0;\n for (const v of sortedNonZero) {\n if (v < value) below++;\n if (v <= value) atOrBelow++;\n }\n const rank = (below / n + atOrBelow / n) / 2; // midpoint rank ∈ (0, 1)\n if (rank <= 0.25) return 1; // bottom quarter\n if (rank <= 0.5) return 2; // 25-50%\n if (rank <= 0.75) return 3; // 50-75%\n return 4; // top quarter, max always here\n}\n\n/**\n * Log-scaled ratio fallback for sparse data (< MIN_RANK_POINTS non-zero values).\n * Compresses outliers logarithmically so a single large value doesn't flatten\n * the rest, while keeping \"larger = darker\" intuition.\n */\nexport function logLevel(value: number, viewMax: number): 0 | 1 | 2 | 3 | 4 {\n if (value <= 0) return 0;\n if (viewMax <= 0) return 1;\n const r = Math.log1p(value) / Math.log1p(viewMax);\n if (r <= 0.25) return 1;\n if (r <= 0.5) return 2;\n if (r <= 0.75) return 3;\n return 4;\n}\n\nfunction hourInShanghai(ms: number): number {\n // Convert to Asia/Shanghai hour 0-23. en-GB is used because en-US may emit\n // \"24\" for midnight on some ICU data; we also defensively clamp.\n const s = new Date(ms).toLocaleString(\"en-GB\", { timeZone: \"Asia/Shanghai\", hour: \"2-digit\", hour12: false });\n const h = Number(s);\n return h === 24 ? 0 : h;\n}\n\nexport function aggregate(events: RawUsageEvent[], nowMs: number): Aggregated {\n const byDay = new Map<string, DayAgg>();\n const globalByModel = new Map<string, number>();\n const globalByProvider = new Map<string, number>();\n\n for (const ev of events) {\n const dayKey = toDayKey(ev.time);\n let agg = byDay.get(dayKey);\n if (!agg) {\n agg = emptyDay(dayKey);\n byDay.set(dayKey, agg);\n }\n const u = ev.usage;\n const total = (u.inputTokens ?? 0) + (u.cacheReadTokens ?? 0) + (u.cacheWriteTokens ?? 0) + (u.outputTokens ?? 0);\n agg.totalTokens += total;\n agg.uncachedInputTokens += u.inputTokens ?? 0;\n agg.cacheReadTokens += u.cacheReadTokens ?? 0;\n agg.cacheWriteTokens += u.cacheWriteTokens ?? 0;\n agg.outputTokens += u.outputTokens ?? 0;\n agg.count += 1;\n const h = hourInShanghai(ev.time);\n if (h >= 0 && h < 24) agg.hourlyTokens[h] += total;\n\n const modelKey = ev.model || \"unknown\";\n const providerKey = ev.provider || \"unknown\";\n agg.byModel.set(modelKey, (agg.byModel.get(modelKey) ?? 0) + total);\n agg.byProvider.set(providerKey, (agg.byProvider.get(providerKey) ?? 0) + total);\n globalByModel.set(modelKey, (globalByModel.get(modelKey) ?? 0) + total);\n globalByProvider.set(providerKey, (globalByProvider.get(providerKey) ?? 0) + total);\n }\n\n // compute winners per day\n for (const agg of byDay.values()) {\n let bestM: string | null = null;\n let bestMVal = -1;\n for (const [m, v] of agg.byModel) {\n if (v > bestMVal) {\n bestMVal = v;\n bestM = m;\n }\n }\n agg.winnerModel = bestM;\n\n let bestP: string | null = null;\n let bestPVal = -1;\n for (const [p, v] of agg.byProvider) {\n if (v > bestPVal) {\n bestPVal = v;\n bestP = p;\n }\n }\n agg.winnerProvider = bestP;\n }\n\n const todayKey = toDayKey(nowMs);\n const [wStart, wEnd] = weekRangeFor(todayKey);\n const [mStart, mEnd] = monthRangeFor(todayKey);\n\n const today = byDay.get(todayKey)?.totalTokens ?? 0;\n const thisWeek = sumByDay(resolveRange(byDay, wStart, wEnd));\n const thisMonth = sumByDay(resolveRange(byDay, mStart, mEnd));\n let all = 0;\n for (const v of byDay.values()) all += v.totalTokens;\n\n const topModels = [...globalByModel.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([model, tokens]) => ({ model, tokens }));\n\n const topProviders = [...globalByProvider.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([provider, tokens]) => ({ provider, tokens }));\n\n function top5InWindow(days: DayAgg[]): Array<{ model: string; tokens: number }> {\n const m = new Map<string, number>();\n for (const d of days) {\n for (const [model, tokens] of d.byModel) {\n m.set(model, (m.get(model) ?? 0) + tokens);\n }\n }\n return [...m.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([model, tokens]) => ({ model, tokens }));\n }\n\n function topProvidersInWindow(days: DayAgg[]): Array<{ provider: string; tokens: number }> {\n const m = new Map<string, number>();\n for (const d of days) {\n for (const [provider, tokens] of d.byProvider) {\n m.set(provider, (m.get(provider) ?? 0) + tokens);\n }\n }\n return [...m.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([provider, tokens]) => ({ provider, tokens }));\n }\n\n return {\n byDay,\n totals: { today, thisWeek, thisMonth, all },\n topModels,\n topProviders,\n top5: topModels,\n weekDays: (k: string) => {\n const [s, e] = weekRangeFor(k);\n return resolveRange(byDay, s, e);\n },\n monthDays: (k: string) => {\n const [s, e] = monthRangeFor(k);\n return resolveRange(byDay, s, e);\n },\n quarterDays: (k: string) => {\n const [s, e] = quarterRangeFor(k);\n return resolveRange(byDay, s, e);\n },\n yearDays: (k: string) => {\n const [s, e] = yearRangeFor(k);\n return resolveRange(byDay, s, e);\n },\n top5InWindow,\n topProvidersInWindow,\n };\n}\n","import * as React from \"react\";\nimport { levelByRank, logLevel, MIN_RANK_POINTS, type DayAgg } from \"../aggregation.ts\";\n\nexport type ViewKind = \"week\" | \"month\" | \"quarter\" | \"year\";\n\nconst VIEW_ORDER: ViewKind[] = [\"week\", \"month\", \"quarter\", \"year\"];\n\n/** Thresholds (tokens/day). Day-grid only: above HIGH always level 4; below LOW\n * always level 1; the band in between uses percentile ranking. Configurable in\n * the ⋯ menu. Hour bars in the Week view ignore absolute thresholds entirely —\n * they are rank-based only, so all four levels stay visible. */\nexport type LevelThresholds = { high: number; low: number };\n\nexport const DEFAULT_THRESHOLDS: LevelThresholds = { high: 100_000_000, low: 10_000_000 };\n\n/**\n * Build a rank-based (percentile) level map for a day-window, keyed by dayKey.\n * Outlier-proof: a single huge day no longer flattens the rest of the window\n * to level 1. Falls back to log-scaled ratio when non-zero days are too few.\n * Absolute thresholds override ranking: >= high -> always 4, < low -> always 1.\n * (Day grids only — week-hour bars skip these, see buildHourLevels.)\n */\nfunction buildDayLevels(days: DayAgg[], th: LevelThresholds): Map<string, number> {\n const nonZero = days\n .filter((d) => d.totalTokens > 0)\n .map((d) => d.totalTokens)\n .sort((a, b) => a - b);\n const viewMax = days.reduce((m, d) => Math.max(m, d.totalTokens), 0);\n const map = new Map<string, number>();\n for (const d of days) {\n let level: number;\n if (d.totalTokens <= 0) level = 0;\n else if (th.high > 0 && d.totalTokens >= th.high) level = 4; // absolute deep green\n else if (th.low > 0 && d.totalTokens < th.low) level = 1; // absolute light green\n else if (nonZero.length < MIN_RANK_POINTS) level = logLevel(d.totalTokens, viewMax);\n else level = levelByRank(d.totalTokens, nonZero);\n map.set(d.dayKey, level);\n }\n return map;\n}\n\n/**\n * Build rank-based level arrays for hour bars across a week (cross-day comparable).\n * Maps dayKey -> number[24] of levels. NO absolute thresholds here: the 37-ish\n * small hours would otherwise be pinned to level 1 and the mid band would pile\n * into 3/4, leaving level 2 empty. Pure rank keeps all four levels populated.\n */\nfunction buildHourLevels(days: DayAgg[]): Map<string, number[]> {\n const nonZero: number[] = [];\n const raw = new Map<string, number[]>();\n for (const d of days) {\n const h = d.hourlyTokens ?? new Array(24).fill(0);\n raw.set(d.dayKey, h);\n for (const v of h) if (v > 0) nonZero.push(v);\n }\n nonZero.sort((a, b) => a - b);\n const weekMax = nonZero.length ? nonZero[nonZero.length - 1] : 1;\n const out = new Map<string, number[]>();\n for (const [k, h] of raw) {\n out.set(\n k,\n h.map((v) => {\n if (v <= 0) return 0;\n if (nonZero.length < MIN_RANK_POINTS) return logLevel(v, weekMax);\n return levelByRank(v, nonZero);\n }),\n );\n }\n return out;\n}\n\nfunction formatTokensShort(n: number): string {\n if (n >= 1_000_000_000) return (n / 1_000_000_000).toFixed(2) + \"B\";\n if (n >= 1_000_000) return (n / 1_000_000).toFixed(2) + \"M\";\n if (n >= 1000) return (n / 1000).toFixed(2) + \"k\";\n return n.toLocaleString();\n}\n\nfunction tooltipTotal(day: DayAgg): string {\n if (day.totalTokens === 0) return `${day.dayKey}: No usage`;\n return `${day.dayKey}: ${formatTokensShort(day.totalTokens)} tokens`;\n}\n\nfunction HeatCell({ day, level, size = 14 }: { day: DayAgg; level: number; size?: number }) {\n const colors: Record<number, string> = {\n 0: \"var(--dsw-alias-bg-layer-2, #ebedf0)\",\n 1: \"#c6e48b\",\n 2: \"#7bc96f\",\n 3: \"#239a3b\",\n 4: \"#196127\",\n };\n return (\n <div\n title={tooltipTotal(day)}\n aria-label={tooltipTotal(day)}\n style={{\n width: size,\n height: size,\n borderRadius: 3,\n background: colors[level],\n border: level === 0 ? \"1px solid var(--dsw-alias-border-l2, #e5e7eb)\" : \"1px solid transparent\",\n boxSizing: \"border-box\",\n cursor: \"pointer\",\n flexShrink: 0,\n }}\n />\n );\n}\n\nfunction HourStrip({ day, hourLevels }: { day: DayAgg; hourLevels: number[] }) {\n const hourly = day.hourlyTokens ?? new Array(24).fill(0);\n const colors: Record<number, string> = {\n 0: \"var(--dsw-alias-bg-layer-2, #ebedf0)\",\n 1: \"#c6e48b\",\n 2: \"#7bc96f\",\n 3: \"#239a3b\",\n 4: \"#196127\",\n };\n return (\n <div style={{ display: \"flex\", gap: 1, alignItems: \"end\", flex: 1, minWidth: 0 }}>\n {hourly.map((v, h) => {\n const lv = hourLevels[h] ?? 0;\n const hh = v === 0 ? `${String(h).padStart(2, \"0\")}:00 — No usage` : `${String(h).padStart(2, \"0\")}:00 — ${formatTokensShort(v)} tokens`;\n return (\n <div\n key={h}\n title={hh}\n aria-label={hh}\n style={{\n flex: 1,\n height: 6 + lv * 4,\n borderRadius: 1,\n background: colors[lv],\n border: lv === 0 ? \"1px solid var(--dsw-alias-border-l2)\" : \"none\",\n boxSizing: \"border-box\",\n minWidth: 0,\n }}\n />\n );\n })}\n </div>\n );\n}\n\nfunction ViewSwitcher({\n t,\n value,\n onChange,\n}: {\n t: (k: string, p?: any) => string;\n value: ViewKind;\n onChange: (v: ViewKind) => void;\n}) {\n return (\n <div\n role=\"tablist\"\n aria-label=\"view switcher\"\n style={{\n display: \"inline-flex\",\n border: \"1px solid var(--dsw-alias-border-l2)\",\n borderRadius: 8,\n overflow: \"hidden\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n }}\n >\n {VIEW_ORDER.map((v) => (\n <button\n key={v}\n role=\"tab\"\n aria-selected={value === v}\n onClick={() => onChange(v)}\n style={{\n padding: \"6px 14px\",\n fontSize: 13,\n lineHeight: \"20px\",\n border: \"none\",\n cursor: \"pointer\",\n background: value === v ? \"var(--dsw-alias-label-primary)\" : \"transparent\",\n color: value === v ? \"var(--dsw-alias-bg-layer-3)\" : \"var(--dsw-alias-label-primary)\",\n fontWeight: value === v ? 600 : 400,\n }}\n >\n {t(`view.${v}`)}\n </button>\n ))}\n </div>\n );\n}\n\nfunction MonthHeader({ weeks, cellSize }: { weeks: DayAgg[][]; cellSize: number }) {\n const seen = new Set<string>();\n return (\n <div style={{ display: \"flex\", gap: 3, paddingLeft: cellSize + 20, marginBottom: 2 }}>\n {weeks.map((week, i) => {\n const m = week.find((d) => d.totalTokens !== -1)?.dayKey.slice(0, 7) ?? \"\";\n let label = \"\";\n if (m && !seen.has(m)) { seen.add(m); const n = Number(m.slice(5,7)); label = [\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"][n-1]; }\n return <span key={i} style={{ width: cellSize, fontSize: 10, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: \"12px\", whiteSpace: \"nowrap\", overflow: \"visible\" }}>{label}</span>;\n })}\n </div>\n );\n}\n\nfunction GitHubGrid({ days, t, cellSize, twoRows, isEn, dayLevels }: { days: DayAgg[]; t: (k: string, p?: any) => string; cellSize: number; twoRows?: boolean; isEn?: boolean; dayLevels: Map<string, number> }) {\n const weeks: DayAgg[][] = [];\n let cur: DayAgg[] = [];\n for (const d of days) {\n const rawDow = new Date(d.dayKey + \"T12:00:00+08:00\").getDay();\n const dow = isEn ? rawDow : (rawDow + 6) % 7;\n if (cur.length === 0 && weeks.length === 0 && dow !== 0) {\n for (let i = 0; i < dow; i++) {\n cur.push({ dayKey: `pad-${i}`, totalTokens: -1, uncachedInputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, outputTokens: 0, count: 0, byModel: new Map(), byProvider: new Map(), hourlyTokens: new Array(24).fill(0), winnerModel: null, winnerProvider: null });\n }\n }\n cur.push(d);\n if (cur.length === 7) {\n weeks.push(cur);\n cur = [];\n }\n }\n if (cur.length > 0) {\n while (cur.length < 7) cur.push({ dayKey: `pad-end-${cur.length}`, totalTokens: -1, uncachedInputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, outputTokens: 0, count: 0, byModel: new Map(), byProvider: new Map(), hourlyTokens: new Array(24).fill(0), winnerModel: null, winnerProvider: null });\n weeks.push(cur);\n }\n\n const renderWeeks = (ws: DayAgg[][]) => (\n <div style={{ display: \"flex\", gap: cellSize >= 22 ? 10 : 5 }}>\n {ws.map((week, wi) => (\n <div key={wi} style={{ display: \"flex\", flexDirection: \"column\", gap: 3 }}>\n {week.map((d) =>\n d.totalTokens === -1 ? (\n <div key={d.dayKey} style={{ width: cellSize, height: cellSize }} />\n ) : (\n <HeatCell key={d.dayKey} day={d} level={dayLevels.get(d.dayKey) ?? 0} size={cellSize} />\n ),\n )}\n </div>\n ))}\n </div>\n );\n\n if (twoRows && weeks.length > 26) {\n const mid = Math.ceil(weeks.length / 2);\n const top = weeks.slice(0, mid);\n const bot = weeks.slice(mid);\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 16, alignItems: \"center\" }}>\n <div>\n <MonthHeader weeks={top} cellSize={cellSize} />\n <div style={{ display: \"flex\", gap: 3 }}>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 3 }}>\n <span style={{ height: cellSize, fontSize: cellSize >= 22 ? 13 : 10, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: `${cellSize}px` }}>{isEn ? \"Sun\" : \"Mon\"}</span>\n <span style={{ height: cellSize }} />\n <span style={{ height: cellSize, fontSize: cellSize >= 22 ? 13 : 10, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: `${cellSize}px` }}>{isEn ? \"Tue\" : \"Wed\"}</span>\n <span style={{ height: cellSize }} />\n <span style={{ height: cellSize, fontSize: cellSize >= 22 ? 13 : 10, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: `${cellSize}px` }}>{isEn ? \"Thu\" : \"Fri\"}</span>\n <span style={{ height: cellSize }} />\n <span style={{ height: cellSize }} />\n </div>\n {renderWeeks(top)}\n </div>\n </div>\n <div>\n <MonthHeader weeks={bot} cellSize={cellSize} />\n <div style={{ display: \"flex\", gap: 3 }}>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 3 }}>\n <span style={{ height: cellSize, fontSize: cellSize >= 22 ? 13 : 10, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: `${cellSize}px` }}>{isEn ? \"Sun\" : \"Mon\"}</span>\n <span style={{ height: cellSize }} />\n <span style={{ height: cellSize, fontSize: cellSize >= 22 ? 13 : 10, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: `${cellSize}px` }}>{isEn ? \"Tue\" : \"Wed\"}</span>\n <span style={{ height: cellSize }} />\n <span style={{ height: cellSize, fontSize: cellSize >= 22 ? 13 : 10, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: `${cellSize}px` }}>{isEn ? \"Thu\" : \"Fri\"}</span>\n <span style={{ height: cellSize }} />\n <span style={{ height: cellSize }} />\n </div>\n {renderWeeks(bot)}\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <div style={{ overflowX: \"auto\", paddingBottom: 4, display: \"flex\", flexDirection: \"column\", alignItems: \"center\", gap: 6 }}>\n <MonthHeader weeks={weeks} cellSize={cellSize} />\n <div style={{ display: \"flex\", gap: cellSize >= 22 ? 10 : 5, justifyContent: \"center\" }}>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 3, fontSize: cellSize >= 22 ? 13 : 10, color: \"var(--dsw-alias-label-tertiary)\" }}>\n {(isEn ? [\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"] : [\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\"]).map((w, i) => (\n <span key={w} style={{ height: cellSize, lineHeight: `${cellSize}px`, textAlign: \"right\", paddingRight: 4, fontWeight: 500 }}>{w}</span>\n ))}\n </div>\n {renderWeeks(weeks)}\n </div>\n </div>\n );\n}\n\nfunction CalendarGrid({ days, t, dayLevels, selectedKey, onSelect, isEn }: { days: DayAgg[]; t: (k:string,p?:any)=>string; dayLevels: Map<string, number>; selectedKey: string | null; onSelect: (k: string | null) => void; isEn?: boolean }) {\n const weekdaysZh = [\"一\",\"二\",\"三\",\"四\",\"五\",\"六\",\"日\"];\n const weekdaysEn = [\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\"];\n const isZh = (t(\"heatmap.title\") || \"\").includes(\"Token\") ? false : false;\n // Use locale-aware: check if nav is Chinese\n const header = [\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\"];\n const headerZh = [\"一\",\"二\",\"三\",\"四\",\"五\",\"六\",\"日\"];\n // Simple: show Mon-Sun always (github style), but tint weekend header\n const firstDow = firstDowOf(days);\n const pad = firstDow;\n const cells: (DayAgg | null)[] = [];\n for (let i = 0; i < pad; i++) cells.push(null);\n for (const d of days) cells.push(d);\n while (cells.length % 7 !== 0) cells.push(null);\n\n function firstDowOf(ds: DayAgg[]): number {\n if (ds.length === 0) return 0;\n const raw = new Date(ds[0].dayKey + \"T12:00:00+08:00\").getDay();\n return isEn ? raw : (raw + 6) % 7;\n }\n\n return (\n <div style={{ border: \"1px solid var(--dsw-alias-border-l2)\", borderRadius: 12, overflow: \"hidden\", background: \"var(--dsw-alias-bg-layer-3)\" }}>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(7, 1fr)\", gap: 6, padding: \"8px 6px 6px\" }}>\n {(isEn ? [\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"] : header).map((w) => (\n <div key={w} style={{ textAlign: \"center\", fontSize: 11, fontWeight: 500, color: \"var(--dsw-alias-label-tertiary)\" }}>\n {w}\n </div>\n ))}\n </div>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(7, 1fr)\", gap: 6, padding: \"0 6px\" }}>\n {cells.map((d, idx) => {\n if (!d) return <div key={`pad-${idx}`} style={{ minHeight: 50 }} />;\n const selected = d.dayKey === selectedKey;\n const level = dayLevels.get(d.dayKey) ?? 0;\n const bgMap: Record<number,string> = { 0: \"var(--dsw-alias-bg-layer-3)\", 1: \"#c6e48b\", 2: \"#7bc96f\", 3: \"#239a3b\", 4: \"#196127\" };\n return (\n <button\n key={d.dayKey}\n onClick={() => onSelect(selected ? null : d.dayKey)}\n title={tooltipTotal(d)}\n aria-label={tooltipTotal(d)}\n style={{\n minHeight: 50,\n padding: \"6px 6px 4px\",\n textAlign: \"left\",\n border: selected ? \"1.5px solid var(--dsw-alias-brand-primary, #1677ff)\" : \"1px solid var(--dsw-alias-border-l2, #e5e7eb)\",\n borderRadius: 8,\n background: selected ? \"var(--dsw-alias-brand-primary, #1677ff)\" : bgMap[level],\n color: selected ? \"#fff\" : level === 0 ? \"var(--dsw-alias-label-primary)\" : level <= 2 ? \"#1a1a1a\" : \"#fff\",\n cursor: \"pointer\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 1,\n alignItems: \"flex-start\",\n }}\n >\n <span style={{ fontSize: 12, fontWeight: 600, lineHeight: \"16px\" }}>{d.dayKey.slice(8, 10).replace(/^0/, \"\")}</span>\n <span style={{ fontSize: 10, lineHeight: \"12px\", opacity: 0.8, whiteSpace: \"nowrap\", overflow: \"hidden\", textOverflow: \"ellipsis\", maxWidth: \"100%\" }}>{d.totalTokens > 0 ? formatTokensShort(d.totalTokens) : \"\"}</span>\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n\nexport function HeatmapGrid({\n t,\n days,\n view,\n onViewChange,\n selectedKey,\n onSelect,\n isEn,\n thresholds = DEFAULT_THRESHOLDS,\n}: {\n t: (k: string, p?: any) => string;\n days: DayAgg[];\n view: ViewKind;\n onViewChange: (v: ViewKind) => void;\n selectedKey?: string | null;\n onSelect?: (k: string | null) => void;\n isEn?: boolean;\n thresholds?: LevelThresholds;\n}) {\n const isWeek = view === \"week\";\n const hasAny = days.some((d) => d.totalTokens > 0);\n const dayLevels = buildDayLevels(days, thresholds);\n const hourLevels = buildHourLevels(days);\n const cellSize = isWeek ? 16 : view === \"quarter\" ? 23 : (view === \"year\" ? 14 : 14);\n\n const handleViewChange = (v: ViewKind) => {\n onSelect?.(null);\n onViewChange(v);\n };\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n <ViewSwitcher t={t} value={view} onChange={handleViewChange} />\n\n {!hasAny ? (\n <div\n style={{\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n borderRadius: 12,\n padding: 24,\n color: \"var(--dsw-alias-label-tertiary)\",\n fontSize: 13,\n }}\n >\n {t(\"heatmap.empty\")}\n </div>\n ) : null}\n\n {isWeek ? (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 5 }}>\n {days.map((d) => {\n const wd = new Date(d.dayKey + \"T12:00:00+08:00\").getDay();\n const weekday = isEn\n ? [\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"][wd]\n : [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"][(wd + 6) % 7];\n const sel = d.dayKey === selectedKey;\n return (\n <button\n key={d.dayKey}\n onClick={() => onSelect?.(sel ? null : d.dayKey)}\n title={tooltipTotal(d)}\n style={{\n display: \"flex\", alignItems: \"center\", gap: 10, minWidth: 0, width: \"100%\",\n padding: \"6px 8px\", borderRadius: 8,\n border: sel ? \"1px solid var(--dsw-alias-brand-primary)\" : \"1px solid transparent\",\n background: sel ? \"var(--dsw-alias-bg-layer-2)\" : \"transparent\",\n cursor: \"pointer\", textAlign: \"left\",\n }}\n >\n <div style={{ width: 52, flexShrink: 0, display: \"flex\", flexDirection: \"column\", gap: 1 }}>\n <span style={{ fontSize: 12, fontWeight: 600, color: \"var(--dsw-alias-label-primary)\", lineHeight: \"16px\" }}>{weekday}</span>\n <span style={{ fontSize: 10, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: \"12px\" }}>{d.dayKey.slice(5)}</span>\n </div>\n <HourStrip day={d} hourLevels={hourLevels.get(d.dayKey) ?? new Array(24).fill(0)} />\n <span style={{ fontSize: 11, color: \"var(--dsw-alias-label-tertiary)\", whiteSpace: \"nowrap\", width: 80, textAlign: \"right\" }}>\n {d.totalTokens === 0 ? \"No usage\" : `${formatTokensShort(d.totalTokens)} tokens`}\n </span>\n </button>\n );\n })}\n </div>\n ) : view === \"month\" ? (\n <CalendarGrid days={days} t={t} dayLevels={dayLevels} selectedKey={selectedKey ?? null} onSelect={onSelect ?? (() => {})} isEn={isEn} />\n ) : view === \"year\" ? (\n <GitHubGrid days={days} t={t} cellSize={cellSize} twoRows isEn={isEn} dayLevels={dayLevels} />\n ) : (\n <GitHubGrid days={days} t={t} cellSize={cellSize} isEn={isEn} dayLevels={dayLevels} />\n )}\n\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 6, justifyContent: \"flex-end\", fontSize: 12, color: \"var(--dsw-alias-label-tertiary)\" }}>\n <span>{t(\"heatmap.legend.less\")}</span>\n <span style={{ width: 12, height: 12, borderRadius: 2, background: \"var(--dsw-alias-bg-layer-2, #ebedf0)\", border: \"1px solid var(--dsw-alias-border-l2)\" }} />\n <span style={{ width: 12, height: 12, borderRadius: 2, background: \"#c6e48b\" }} />\n <span style={{ width: 12, height: 12, borderRadius: 2, background: \"#7bc96f\" }} />\n <span style={{ width: 12, height: 12, borderRadius: 2, background: \"#239a3b\" }} />\n <span style={{ width: 12, height: 12, borderRadius: 2, background: \"#196127\" }} />\n <span>{t(\"heatmap.legend.more\")}</span>\n </div>\n </div>\n );\n}\n\nexport default HeatmapGrid;\n","import * as React from \"react\";\nimport type { DayAgg } from \"../aggregation.ts\";\n\nexport type TopItem = { model?: string; provider?: string; name: string; tokens: number };\n\nfunction formatTokens(n: number): string {\n if (n >= 1_000_000_000) return (n / 1_000_000_000).toFixed(2) + \"B\";\n if (n >= 1_000_000) return (n / 1_000_000).toFixed(2) + \"M\";\n if (n >= 1000) return (n / 1000).toFixed(2) + \"k\";\n return n.toLocaleString();\n}\n\nexport function ModelTop5({\n t,\n topModels,\n topProviders,\n days,\n mode = \"model\",\n onModeChange,\n}: {\n t: (k: string, p?: any) => string;\n topModels: TopItem[];\n topProviders: TopItem[];\n days?: DayAgg[];\n mode?: \"model\" | \"provider\";\n onModeChange?: (m: \"model\" | \"provider\") => void;\n}) {\n const active = mode === \"provider\" ? topProviders : topModels;\n\n if (active.length === 0) {\n return (\n <div\n style={{\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n borderRadius: 12,\n padding: 16,\n color: \"var(--dsw-alias-label-tertiary)\",\n fontSize: 13,\n }}\n >\n {t(\"model.none\")}\n </div>\n );\n }\n\n const max = active[0]?.tokens ?? 1;\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 12 }}>\n <div\n style={{\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n borderRadius: 12,\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n padding: \"12px 16px 8px\",\n borderBottom: \"1px solid var(--dsw-alias-border-l2)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: 8,\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <span style={{ fontSize: 13, fontWeight: 600, color: \"var(--dsw-alias-label-primary)\" }}>\n {mode === \"provider\" ? t(\"provider.top5\") : t(\"model.top5\")}\n </span>\n <span style={{ fontSize: 11, color: \"var(--dsw-alias-label-tertiary)\" }}>{t(\"model.top5.hint\")}</span>\n </div>\n {onModeChange ? (\n <div style={{ display: \"inline-flex\", border: \"1px solid var(--dsw-alias-border-l2)\", borderRadius: 6, overflow: \"hidden\" }}>\n <button\n onClick={() => onModeChange(\"model\")}\n style={{\n padding: \"2px 8px\",\n fontSize: 11,\n border: \"none\",\n cursor: \"pointer\",\n background: mode === \"model\" ? \"var(--dsw-alias-label-primary)\" : \"transparent\",\n color: mode === \"model\" ? \"var(--dsw-alias-bg-layer-3)\" : \"var(--dsw-alias-label-secondary)\",\n }}\n >\n {t(\"view.model\")}\n </button>\n <button\n onClick={() => onModeChange(\"provider\")}\n style={{\n padding: \"2px 8px\",\n fontSize: 11,\n border: \"none\",\n cursor: \"pointer\",\n background: mode === \"provider\" ? \"var(--dsw-alias-label-primary)\" : \"transparent\",\n color: mode === \"provider\" ? \"var(--dsw-alias-bg-layer-3)\" : \"var(--dsw-alias-label-secondary)\",\n }}\n >\n {t(\"view.provider\")}\n </button>\n </div>\n ) : null}\n </div>\n <div style={{ display: \"flex\", flexDirection: \"column\" }}>\n {active.map((item, idx) => (\n <div\n key={item.name}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n padding: \"10px 16px\",\n borderTop: idx === 0 ? \"none\" : \"1px solid var(--dsw-alias-border-l2)\",\n }}\n >\n <span style={{ width: 20, textAlign: \"center\", fontSize: 12, fontWeight: 600, color: \"var(--dsw-alias-label-tertiary)\" }}>\n {idx + 1}\n </span>\n <span\n style={{\n flex: \"0 1 40%\",\n minWidth: 0,\n fontSize: 13,\n color: \"var(--dsw-alias-label-primary)\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n title={item.name}\n >\n {item.name}\n </span>\n <div style={{ flex: 1, height: 6, borderRadius: 3, background: \"var(--dsw-alias-bg-layer-2, #ebedf0)\", overflow: \"hidden\" }}>\n <div style={{ width: `${Math.max(4, (item.tokens / max) * 100)}%`, height: \"100%\", background: \"#40c463\", borderRadius: 3 }} />\n </div>\n <span style={{ fontSize: 12, color: \"var(--dsw-alias-label-secondary)\", whiteSpace: \"nowrap\" }}>\n {formatTokens(item.tokens)}\n </span>\n </div>\n ))}\n </div>\n </div>\n\n\n </div>\n );\n}\n\nexport default ModelTop5;\n","import type { DayAgg } from \"../aggregation.ts\";\nimport { addDays } from \"../date-bucket.ts\";\n\n/**\n * Pure logic for the bottom-of-page trend line chart: window slicing,\n * top-model selection, per-model series building and monotone cubic smoothing.\n * Kept free of React/DOM so it is unit-testable and reusable.\n */\n\n/** N consecutive day keys ending at `endKey` (inclusive). */\nexport function recentDayKeys(endKey: string, n: number): string[] {\n const out: string[] = [];\n for (let i = n - 1; i >= 0; i--) out.push(addDays(endKey, -i));\n return out;\n}\n\n/** Sum each model's tokens over `dayKeys`. */\nfunction modelTotals(days: DayAgg[], dayKeys: string[]): Map<string, number> {\n const inWindow = new Set(dayKeys);\n const totals = new Map<string, number>();\n for (const d of days) {\n if (!inWindow.has(d.dayKey)) continue;\n for (const [model, tokens] of d.byModel) {\n totals.set(model, (totals.get(model) ?? 0) + tokens);\n }\n }\n return totals;\n}\n\nconst byTotalDesc = (a: [string, number], b: [string, number]) => (b[1] - a[1]) || (a[0] < b[0] ? -1 : 1);\n\n/** Sum each model's tokens over `dayKeys`, return up to `k` names by total desc. */\nexport function pickTopModels(days: DayAgg[], dayKeys: string[], k = 5): string[] {\n return [...modelTotals(days, dayKeys).entries()]\n .sort(byTotalDesc)\n .slice(0, k)\n .map(([model]) => model);\n}\n\n/**\n * Legend selection for the trend chart: the range's top-k models PLUS the\n * week's top-`weekTopN` models guaranteed (a model that took over this week\n * must stay visible in a 30/90-day view). If the union exceeds `k`, the\n * weakest range-ranked models give up their slots. Result is ordered by range\n * usage desc, deduplicated, at most `k` names.\n */\nexport function pickTrendModels(\n days: DayAgg[],\n dayKeys: string[],\n weekKeys: string[],\n k = 10,\n weekTopN = 3,\n): string[] {\n const rangeTotals = modelTotals(days, dayKeys);\n const rangeRanked = [...rangeTotals.entries()].sort(byTotalDesc).slice(0, k).map(([m]) => m);\n const weekTop = pickTopModels(days, weekKeys, weekTopN);\n const selected = new Set<string>(weekTop);\n for (const m of rangeRanked) {\n if (selected.size >= k) break;\n selected.add(m);\n }\n return [...selected].sort(\n (a, b) => ((rangeTotals.get(b) ?? 0) - (rangeTotals.get(a) ?? 0)) || (a < b ? -1 : 1),\n );\n}\n\nexport type TrendSeries = { model: string; points: number[] };\n\n/** One series per model: its daily tokens aligned to `dayKeys`, 0 where absent. */\nexport function buildSeries(days: DayAgg[], dayKeys: string[], models: string[]): TrendSeries[] {\n const index = new Map(days.map((d) => [d.dayKey, d]));\n return models.map((model) => ({\n model,\n points: dayKeys.map((k) => index.get(k)?.byModel.get(model) ?? 0),\n }));\n}\n\nexport type Segment = {\n p0: [number, number];\n c1: [number, number];\n c2: [number, number];\n p1: [number, number];\n};\n\n/**\n * Monotone cubic (Fritsch–Carlson) Hermite interpolation of 2-D points as\n * cubic bezier segments. Used instead of plain Catmull-Rom because a smooth\n * trend line must NOT overshoot: a zero day between two peaks stays at zero\n * instead of dipping below the axis and inventing a fake trough.\n */\nexport function monotoneSegments(pts: Array<[number, number]>): Segment[] {\n const n = pts.length;\n if (n < 2) return [];\n // slopes (secants) between neighbours\n const h: number[] = [];\n const delta: number[] = [];\n for (let i = 0; i < n - 1; i++) {\n const dx = pts[i + 1][0] - pts[i][0];\n h.push(dx);\n delta.push(dx === 0 ? 0 : (pts[i + 1][1] - pts[i][1]) / dx);\n }\n // tangents: start with mean of neighbouring secants\n const m: number[] = new Array(n);\n m[0] = delta[0];\n m[n - 1] = delta[n - 2];\n for (let i = 1; i < n - 1; i++) {\n m[i] = delta[i - 1] * delta[i] <= 0 ? 0 : (delta[i - 1] + delta[i]) / 2;\n }\n // Fritsch–Carlson limiter: keep the curve monotone (no overshoot)\n for (let i = 0; i < n - 1; i++) {\n if (delta[i] === 0) {\n m[i] = 0;\n m[i + 1] = 0;\n continue;\n }\n const a = m[i] / delta[i];\n const b = m[i + 1] / delta[i];\n const s = a * a + b * b;\n if (s > 9) {\n const t = 3 / Math.sqrt(s);\n m[i] = t * a * delta[i];\n m[i + 1] = t * b * delta[i];\n }\n }\n // Hermite -> cubic bezier control points\n const segs: Segment[] = [];\n for (let i = 0; i < n - 1; i++) {\n const [x0, y0] = pts[i];\n const [x1, y1] = pts[i + 1];\n const dx = (x1 - x0) / 3;\n segs.push({\n p0: [x0, y0],\n c1: [x0 + dx, y0 + m[i] * (x1 - x0) / 3],\n c2: [x1 - dx, y1 - m[i + 1] * (x1 - x0) / 3],\n p1: [x1, y1],\n });\n }\n return segs;\n}\n\nconst fmtNum = (v: number) => Math.round(v * 100) / 100;\n\n/** SVG path `d` for a smoothed polyline through `points` ([x,y] pairs). */\nexport function seriesPath(points: Array<[number, number]>): string {\n if (points.length === 0) return \"\";\n const head = `M ${fmtNum(points[0][0])} ${fmtNum(points[0][1])}`;\n if (points.length === 1) return head;\n const segs = monotoneSegments(points);\n return head + segs\n .map((s) => ` C ${fmtNum(s.c1[0])} ${fmtNum(s.c1[1])}, ${fmtNum(s.c2[0])} ${fmtNum(s.c2[1])}, ${fmtNum(s.p1[0])} ${fmtNum(s.p1[1])}`)\n .join(\"\");\n}\n\n/** Compact token count for axis labels (same semantics as the heatmap). */\nexport function formatTokensShort(n: number): string {\n if (n >= 1_000_000_000) return (n / 1_000_000_000).toFixed(2) + \"B\";\n if (n >= 1_000_000) return (n / 1_000_000).toFixed(2) + \"M\";\n if (n >= 1000) return (n / 1000).toFixed(2) + \"k\";\n return n.toLocaleString();\n}\n","import * as React from \"react\";\nimport type { DayAgg } from \"../aggregation.ts\";\nimport { toDayKey } from \"../date-bucket.ts\";\nimport { recentDayKeys, pickTrendModels, buildSeries, seriesPath, formatTokensShort } from \"./trend.ts\";\n\n/** Distinct, colorblind-tolerant series colors (first matches the heatmap green). */\nconst COLORS = [\n \"#40c463\", \"#4c8dff\", \"#f6a609\", \"#c956e0\", \"#ff7a59\",\n \"#26c6da\", \"#ff5c8a\", \"#9ccc65\", \"#7e57c2\", \"#ffd54f\",\n];\n\n/** Round a max up to a friendly axis ceiling (steps of half a decade). */\nfunction niceCeil(v: number): number {\n if (v <= 0) return 1;\n const unit = Math.pow(10, Math.floor(Math.log10(v))) / 2;\n return Math.ceil(v / unit) * unit;\n}\n\nconst W = 720;\nconst H = 280;\nconst PAD = { top: 10, right: 28, bottom: 34, left: 76 }; // right: 给最右日期标签留出空间,避免贴边裁字\n/** chart container horizontal padding (must match the div below) */\nconst CX_PAD = 8;\n\n/**\n * Trend line chart at the bottom of the settings section: one smoothed line\n * per model (top 10 of the selected range), legend chips toggle visibility,\n * range switch between the last 7 / 30 / 90 days. Hovering a date column shows a\n * compact translucent tooltip BESIDE the cursor (never covering the hovered\n * point): date, day total, per-model totals with color dots.\n * Pure SVG + absolutely-positioned HTML tooltip, no dependencies.\n */\nexport function TrendChart({\n t,\n days,\n isEn = false,\n}: {\n t: (k: string, p?: any) => string;\n days: DayAgg[];\n isEn?: boolean;\n}) {\n const [rangeDays, setRangeDays] = React.useState<7 | 30 | 90>(7);\n const [hidden, setHidden] = React.useState<ReadonlySet<string>>(new Set());\n /** hovered column index + pointer position in wrapper px (for side placement) */\n const [hover, setHover] = React.useState<{ idx: number; px: number; py: number } | null>(null);\n\n const endKey = toDayKey(Date.now());\n const dayKeys = React.useMemo(() => recentDayKeys(endKey, rangeDays), [endKey, rangeDays]);\n const weekKeys = React.useMemo(() => recentDayKeys(endKey, 7), [endKey]);\n // 范围前 10 + 近一周前 3 必进列表(本周冒头的模型在 30/90 天视图里也可见)\n const topModels = React.useMemo(() => pickTrendModels(days, dayKeys, weekKeys, 10, 3), [days, dayKeys, weekKeys]);\n const series = React.useMemo(() => buildSeries(days, dayKeys, topModels), [days, dayKeys, topModels]);\n\n const totalsByModel = React.useMemo(() => {\n const m = new Map<string, number>();\n for (const s of series) m.set(s.model, s.points.reduce((a, b) => a + b, 0));\n return m;\n }, [series]);\n\n // wrapper size for pixel-accurate tooltip positioning under the scaled SVG\n const wrapRef = React.useRef<HTMLDivElement | null>(null);\n const [wrap, setWrap] = React.useState({ w: 0, h: 0 });\n React.useEffect(() => {\n const el = wrapRef.current;\n if (!el) return;\n const measure = () => setWrap({ w: el.clientWidth, h: el.clientHeight });\n measure();\n const ro = new ResizeObserver(measure);\n ro.observe(el);\n return () => ro.disconnect();\n }, []);\n\n const toggle = (model: string) => {\n setHidden((prev) => {\n const next = new Set(prev);\n if (next.has(model)) next.delete(model);\n else next.add(model);\n return next;\n });\n };\n\n const colorOf = (model: string) => COLORS[Math.max(0, topModels.indexOf(model)) % COLORS.length];\n const visible = series.filter((s) => !hidden.has(s.model));\n\n const plotW = W - PAD.left - PAD.right;\n const plotH = H - PAD.top - PAD.bottom;\n const yMax = niceCeil(Math.max(1, ...visible.map((s) => Math.max(0, ...s.points))));\n const step = dayKeys.length > 1 ? plotW / (dayKeys.length - 1) : plotW;\n const xOf = (i: number) => PAD.left + (dayKeys.length > 1 ? i * step : plotW / 2);\n const yOf = (v: number) => PAD.top + (1 - v / yMax) * plotH;\n\n const fmtDay = (k: string) => `${Number(k.slice(5, 7))}/${Number(k.slice(8, 10))}`;\n const fmtDayLong = (k: string) =>\n isEn\n ? `${Number(k.slice(5, 7))}/${Number(k.slice(8, 10))}`\n : `${Number(k.slice(5, 7))}月${Number(k.slice(8, 10))}日`;\n // x tick indices: every day for a week, sparse ticks for month/quarter ranges\n const tickEvery = rangeDays === 7 ? 1 : rangeDays === 30 ? 5 : 10;\n const tickIdx = dayKeys.map((_, i) => i).filter((i) => i % tickEvery === 0 || i === dayKeys.length - 1);\n\n const onMove = (e: React.MouseEvent<SVGSVGElement>) => {\n const wrapEl = wrapRef.current;\n if (!wrapEl) return;\n const wrapRect = wrapEl.getBoundingClientRect();\n const svgRect = e.currentTarget.getBoundingClientRect();\n const scale = svgRect.width / W || 1;\n const xvb = (e.clientX - svgRect.left) / scale;\n const i = Math.round((xvb - PAD.left) / step);\n setHover({\n idx: Math.max(0, Math.min(dayKeys.length - 1, i)),\n px: e.clientX - wrapRect.left,\n py: e.clientY - wrapRect.top,\n });\n };\n\n // hovered column: date, day total and one row per visible model —\n // sorted by that day's usage desc, zero-usage models hidden\n const hoverRows = hover == null ? [] : visible\n .map((s) => ({\n model: s.model,\n color: colorOf(s.model),\n value: s.points[hover.idx],\n }))\n .filter((r) => r.value > 0)\n .sort((a, b) => b.value - a.value);\n const hoverTotal = hoverRows.reduce((a, r) => a + r.value, 0);\n\n // tooltip placement: to the SIDE of the hovered column (flips near edges),\n // vertically centered on the pointer, so the hovered point is never covered\n const tipW = 200;\n const tipH = 56 + hoverRows.length * 19;\n const gap = 14;\n const svgW = Math.max(0, wrap.w - CX_PAD * 2);\n const colPx = hover == null ? 0 : CX_PAD + (xOf(hover.idx) / W) * svgW;\n let tipLeft = hover == null ? 0 : colPx + gap;\n if (hover != null && tipLeft + tipW > wrap.w - 4) tipLeft = colPx - gap - tipW;\n tipLeft = Math.max(4, tipLeft);\n const tipTop = hover == null ? 0 : Math.max(4, Math.min(hover.py - tipH / 2, Math.max(4, wrap.h - tipH - 4)));\n\n const segStyle: React.CSSProperties = {\n padding: \"2px 8px\",\n fontSize: 12,\n border: \"none\",\n cursor: \"pointer\",\n borderRadius: 5,\n background: \"var(--dsw-alias-bg-layer-3)\",\n color: \"var(--dsw-alias-label-secondary)\",\n };\n\n return (\n <div\n style={{\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n borderRadius: 12,\n overflow: \"hidden\",\n }}\n >\n {/* header: title + range switch */}\n <div\n style={{\n padding: \"12px 16px 8px\",\n borderBottom: \"1px solid var(--dsw-alias-border-l2)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: 8,\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <span style={{ fontSize: 13, fontWeight: 600, color: \"var(--dsw-alias-label-primary)\" }}>{t(\"trend.title\")}</span>\n <span style={{ fontSize: 12, color: \"var(--dsw-alias-label-tertiary)\" }}>{t(\"trend.hint\")}</span>\n </div>\n <div style={{ display: \"inline-flex\", border: \"1px solid var(--dsw-alias-border-l2)\", borderRadius: 6, overflow: \"hidden\" }}>\n {([7, 30, 90] as const).map((n) => (\n <button\n key={n}\n onClick={() => { setRangeDays(n); setHover(null); }}\n style={{\n ...segStyle,\n background: rangeDays === n ? \"var(--dsw-alias-label-primary)\" : \"transparent\",\n color: rangeDays === n ? \"var(--dsw-alias-bg-layer-3)\" : \"var(--dsw-alias-label-secondary)\",\n }}\n >\n {n === 7 ? t(\"trend.range7\") : n === 30 ? t(\"trend.range30\") : t(\"trend.range90\")}\n </button>\n ))}\n </div>\n </div>\n\n {/* legend chips: top-10 models of the range, 5 per row, click to toggle a line */}\n <div style={{ padding: \"10px 16px 4px\" }}>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(5, minmax(0, 1fr))\", gap: 6 }}>\n {series.map((s) => {\n const off = hidden.has(s.model);\n return (\n <button\n key={s.model}\n onClick={() => toggle(s.model)}\n title={s.model}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 4,\n padding: \"1px 6px\",\n borderRadius: 999,\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: \"transparent\",\n cursor: \"pointer\",\n opacity: off ? 0.35 : 1,\n fontSize: 11,\n color: \"var(--dsw-alias-label-primary)\",\n minWidth: 0,\n }}\n >\n <span style={{ width: 6, height: 6, borderRadius: 3, background: colorOf(s.model), flexShrink: 0 }} />\n <span style={{ flex: 1, minWidth: 0, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", textAlign: \"left\", textDecoration: off ? \"line-through\" : \"none\" }}>\n {s.model}\n </span>\n <span style={{ fontSize: 10, color: \"var(--dsw-alias-label-tertiary)\", flexShrink: 0 }}>{formatTokensShort(totalsByModel.get(s.model) ?? 0)}</span>\n </button>\n );\n })}\n </div>\n {series.length === 0 ? null : (\n <div style={{ fontSize: 10, color: \"var(--dsw-alias-label-tertiary)\", marginTop: 4 }}>{t(\"trend.legend.hint\")}</div>\n )}\n </div>\n\n {/* chart + hover tooltip */}\n <div ref={wrapRef} style={{ position: \"relative\", padding: `4px ${CX_PAD}px 12px` }}>\n {topModels.length === 0 ? (\n <div style={{ padding: 24, textAlign: \"center\", fontSize: 14, color: \"var(--dsw-alias-label-tertiary)\" }}>{t(\"trend.empty\")}</div>\n ) : (\n <svg\n viewBox={`0 0 ${W} ${H}`}\n width=\"100%\"\n style={{ display: \"block\" }}\n role=\"img\"\n aria-label={t(\"trend.title\")}\n onMouseMove={onMove}\n onMouseLeave={() => setHover(null)}\n >\n {/* y grid + labels */}\n {[0, 0.25, 0.5, 0.75, 1].map((f) => {\n const y = PAD.top + (1 - f) * plotH;\n return (\n <g key={f}>\n <line x1={PAD.left} y1={y} x2={W - PAD.right} y2={y} stroke=\"var(--dsw-alias-border-l2)\" strokeWidth={1} strokeDasharray={f === 0 ? undefined : \"3 3\"} />\n <text x={PAD.left - 8} y={y + 5} textAnchor=\"end\" fontSize={14} fill=\"var(--dsw-alias-label-tertiary)\">\n {formatTokensShort(yMax * f)}\n </text>\n </g>\n );\n })}\n {/* x labels */}\n {tickIdx.map((i) => (\n <text key={i} x={xOf(i)} y={H - 10} textAnchor=\"middle\" fontSize={14} fill=\"var(--dsw-alias-label-tertiary)\">\n {fmtDay(dayKeys[i])}\n </text>\n ))}\n {/* hovered column guide */}\n {hover != null ? (\n <line x1={xOf(hover.idx)} y1={PAD.top} x2={xOf(hover.idx)} y2={PAD.top + plotH} stroke=\"var(--dsw-alias-label-tertiary)\" strokeWidth={1} strokeDasharray=\"4 3\" opacity={0.6} />\n ) : null}\n {/* smoothed lines + points */}\n {visible.map((s) => {\n const color = colorOf(s.model);\n const pts: Array<[number, number]> = s.points.map((v, i) => [xOf(i), yOf(v)]);\n return (\n <g key={s.model} opacity={0.8}>\n <path d={seriesPath(pts)} fill=\"none\" stroke={color} strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n {/* 用量为 0 的日期不显示点 */}\n {pts.map(([x, y], i) => (s.points[i] > 0 ? (\n <circle key={i} cx={x} cy={y} r={hover?.idx === i ? 4 : 2} fill={color} />\n ) : null))}\n </g>\n );\n })}\n {/* all lines hidden hint */}\n {visible.length === 0 ? (\n <text x={W / 2} y={PAD.top + plotH / 2} textAnchor=\"middle\" fontSize={13} fill=\"var(--dsw-alias-label-tertiary)\">\n {t(\"trend.legend.hint\")}\n </text>\n ) : null}\n </svg>\n )}\n\n {/* compact translucent tooltip: date / day total / per-model totals, beside the cursor */}\n {hover != null && topModels.length > 0 ? (\n <div\n style={{\n position: \"absolute\",\n left: tipLeft,\n top: tipTop,\n width: tipW,\n opacity: 0.7,\n pointerEvents: \"none\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n border: \"1px solid var(--dsw-alias-border-l2)\",\n borderRadius: 8,\n boxShadow: \"0 6px 18px rgba(0,0,0,0.25)\",\n padding: \"6px 10px\",\n fontSize: 11,\n lineHeight: 1.5,\n color: \"var(--dsw-alias-label-primary)\",\n zIndex: 5,\n }}\n >\n <div style={{ fontWeight: 600, fontSize: 12, marginBottom: 4 }}>{fmtDayLong(dayKeys[hover.idx])}</div>\n <div style={{ display: \"flex\", justifyContent: \"space-between\", gap: 10, fontWeight: 600 }}>\n <span>{isEn ? \"Total\" : \"消耗总量\"}</span>\n <span>{formatTokensShort(hoverTotal)} tokens</span>\n </div>\n <div style={{ borderTop: \"1px solid var(--dsw-alias-border-l2)\", margin: \"4px 0\" }} />\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 3 }}>\n {hoverRows.map((r) => (\n <div key={r.model} style={{ display: \"flex\", alignItems: \"center\", gap: 6 }}>\n <span style={{ width: 7, height: 7, borderRadius: 4, background: r.color, flexShrink: 0 }} />\n <span style={{ flex: 1, minWidth: 0, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }} title={r.model}>\n {r.model}\n </span>\n <span style={{ fontWeight: 500, whiteSpace: \"nowrap\" }}>{formatTokensShort(r.value)} tokens</span>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\nexport default TrendChart;\n","export const zh: Record<string, string> = {\n \"nav\": \"Token Pulse\",\n \"heatmap.title\": \"Token Pulse\",\n \"heatmap.subtitle\": \"基于本地会话日志统计 Token 用量,北京时间自然日分桶,零网络零计费。首次同步后持久化,删除会话不丢历史。\",\n \"heatmap.empty\": \"暂无用量数据,开始一次对话后这里会出现热图。\",\n \"heatmap.legend.less\": \"少\",\n \"heatmap.legend.more\": \"多\",\n \"heatmap.tooltip.tokens\": \"{count} tokens\",\n \"heatmap.tooltip.none\": \"无用量\",\n \"heatmap.refresh\": \"刷新\",\n \"heatmap.refreshing\": \"刷新中…\",\n \"heatmap.lastRefresh\": \"上次刷新:{time}\",\n \"heatmap.autoRefresh\": \"自动刷新\",\n \"heatmap.autoRefresh.off\": \"关闭\",\n \"heatmap.autoRefresh.hint\": \"设置自动刷新间隔(分钟)\",\n \"heatmap.reset\": \"重置历史\",\n \"heatmap.reset.confirm\": \"确定重置所有历史数据?此操作不可撤销。\",\n \"heatmap.reset.done\": \"已重置\",\n \"view.week\": \"周\",\n \"view.month\": \"月\",\n \"view.quarter\": \"季度\",\n \"view.year\": \"年\",\n \"view.model\": \"模型\",\n \"view.provider\": \"供应商\",\n \"stats.today\": \"今日\",\n \"stats.week\": \"本周\",\n \"stats.month\": \"本月\",\n \"stats.all\": \"累计\",\n \"stats.count\": \"{count} 次\",\n \"model.top5\": \"Top 5 模型\",\n \"model.top5.hint\": \"按 Token 用量排序\",\n \"model.winner\": \"当日最常用模型\",\n \"model.none\": \"暂无模型数据\",\n \"model.tokens\": \"{count} tokens\",\n \"provider.top5\": \"Top 5 供应商\",\n \"provider.winner\": \"当日最常用供应商\",\n \"trend.title\": \"用量趋势\",\n \"trend.hint\": \"按模型的每日 Token 用量\",\n \"trend.range7\": \"近一周\",\n \"trend.range30\": \"近一月\",\n \"trend.range90\": \"近90天\",\n \"trend.empty\": \"所选范围内暂无数据\",\n \"trend.legend.hint\": \"点击图例可显示/隐藏\",\n \"common.tokens\": \"tokens\",\n};\n\nexport const en: Record<string, string> = {\n \"nav\": \"Token Pulse\",\n \"heatmap.title\": \"Token Pulse\",\n \"heatmap.subtitle\": \"Local token usage from session logs, bucketed by Asia/Shanghai, no network or billing. Synced once then persisted, surviving session deletion.\",\n \"heatmap.empty\": \"No usage yet. Start a conversation and the heatmap will appear here.\",\n \"heatmap.legend.less\": \"Less\",\n \"heatmap.legend.more\": \"More\",\n \"heatmap.tooltip.tokens\": \"{count} tokens\",\n \"heatmap.tooltip.none\": \"No usage\",\n \"heatmap.refresh\": \"Refresh\",\n \"heatmap.refreshing\": \"Refreshing…\",\n \"heatmap.lastRefresh\": \"Last refresh: {time}\",\n \"heatmap.autoRefresh\": \"Auto refresh\",\n \"heatmap.autoRefresh.off\": \"Off\",\n \"heatmap.autoRefresh.hint\": \"Auto refresh interval (minutes)\",\n \"heatmap.reset\": \"Reset history\",\n \"heatmap.reset.confirm\": \"Reset all historical data? This cannot be undone.\",\n \"heatmap.reset.done\": \"Reset done\",\n \"view.week\": \"Week\",\n \"view.month\": \"Month\",\n \"view.quarter\": \"Quarter\",\n \"view.year\": \"Year\",\n \"view.model\": \"Model\",\n \"view.provider\": \"Provider\",\n \"stats.today\": \"Today\",\n \"stats.week\": \"This week\",\n \"stats.month\": \"This month\",\n \"stats.all\": \"All time\",\n \"stats.count\": \"{count} turns\",\n \"model.top5\": \"Top 5 Models\",\n \"model.top5.hint\": \"By token usage\",\n \"model.winner\": \"Daily winner (model)\",\n \"model.none\": \"No model data\",\n \"model.tokens\": \"{count} tokens\",\n \"provider.top5\": \"Top 5 Providers\",\n \"provider.winner\": \"Daily winner (provider)\",\n \"trend.title\": \"Usage Trend\",\n \"trend.hint\": \"Daily token usage per model\",\n \"trend.range7\": \"7 days\",\n \"trend.range30\": \"30 days\",\n \"trend.range90\": \"90 days\",\n \"trend.empty\": \"No data in this range\",\n \"trend.legend.hint\": \"Click legend to toggle\",\n \"common.tokens\": \"tokens\",\n};\n\nexport type LocaleDict = typeof zh;\n","import * as React from \"react\";\nimport { aggregate, type Aggregated, type DayAgg } from \"../aggregation.ts\";\nimport { toDayKey } from \"../date-bucket.ts\";\n\nconst LS_INTERVAL_KEY = \"dsh-token-pulse:autoRefreshMinutes\";\n\nexport function getAutoRefreshMinutes(): number {\n try {\n const v = localStorage.getItem(LS_INTERVAL_KEY);\n if (v === null) return 10;\n const n = Number(v);\n if (!Number.isFinite(n) || n < 0) return 10;\n return Math.min(1440, Math.max(0, Math.round(n)));\n } catch {\n return 10;\n }\n}\n\nexport function setAutoRefreshMinutes(minutes: number) {\n try {\n localStorage.setItem(LS_INTERVAL_KEY, String(minutes));\n } catch {}\n}\n\nconst API_TIMEOUT_MS = 5000;\n\nasync function fetchFromApi(): Promise<Aggregated | null> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), API_TIMEOUT_MS);\n try {\n const res = await fetch(\"/api/dsh-token-pulse/daily.json\", { cache: \"no-store\", signal: ctrl.signal });\n if (!res.ok) return null;\n const json = await res.json();\n if (!json || !Array.isArray(json.days)) return null;\n // Host still scanning disk (init in progress): signal \"not ready\" so the\n // caller retries shortly instead of caching a partial snapshot.\n if ((json as any).ready === false) return { __notReady: true } as any;\n const byDay = new Map<string, DayAgg>();\n for (const d of json.days) {\n byDay.set(d.dayKey, {\n dayKey: d.dayKey,\n totalTokens: d.totalTokens ?? 0,\n uncachedInputTokens: d.uncachedInputTokens ?? 0,\n cacheReadTokens: d.cacheReadTokens ?? 0,\n cacheWriteTokens: d.cacheWriteTokens ?? 0,\n outputTokens: d.outputTokens ?? 0,\n count: d.count ?? 0,\n byModel: new Map(Object.entries(d.byModel ?? {})) as Map<string, number>,\n byProvider: new Map(Object.entries(d.byProvider ?? {})) as Map<string, number>,\n hourlyTokens: Array.isArray(d.hourlyTokens) && d.hourlyTokens.length === 24 ? d.hourlyTokens : new Array(24).fill(0),\n winnerModel: d.winnerModel ?? null,\n winnerProvider: d.winnerProvider ?? null,\n });\n }\n const totals = json.totals ?? { today: 0, thisWeek: 0, thisMonth: 0, all: 0 };\n const topModels = Array.isArray(json.topModels) ? json.topModels.map((x: any) => ({ model: x.name ?? x.model, tokens: x.tokens })) : [];\n const topProviders = Array.isArray(json.topProviders) ? json.topProviders.map((x: any) => ({ provider: x.name ?? x.provider, tokens: x.tokens })) : [];\n const nowMs = Date.now();\n // Reuse aggregation helpers by building a synthetic Aggregated that delegates to byDay\n const fakeAgg = aggregate([], nowMs);\n (fakeAgg as any).byDay = byDay;\n (fakeAgg as any).totals = totals;\n (fakeAgg as any).topModels = topModels;\n (fakeAgg as any).topProviders = topProviders;\n (fakeAgg as any).top5 = topModels;\n // Patch window helpers to use our byDay\n const { weekRangeFor, monthRangeFor, quarterRangeFor, yearRangeFor, listDaysInRange } = await import(\"../date-bucket.ts\");\n const resolveDay = (k: string) => byDay.get(k) ?? { dayKey: k, totalTokens: 0, uncachedInputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, outputTokens: 0, count: 0, byModel: new Map(), byProvider: new Map(), hourlyTokens: new Array(24).fill(0), winnerModel: null, winnerProvider: null };\n const resolveRange = (s: string, e: string) => listDaysInRange(s, e).map(resolveDay);\n (fakeAgg as any).weekDays = (k: string) => resolveRange(...weekRangeFor(k));\n (fakeAgg as any).monthDays = (k: string) => resolveRange(...monthRangeFor(k));\n (fakeAgg as any).quarterDays = (k: string) => resolveRange(...quarterRangeFor(k));\n (fakeAgg as any).yearDays = (k: string) => resolveRange(...yearRangeFor(k));\n (fakeAgg as any).top5InWindow = (days: DayAgg[]) => {\n const m = new Map<string, number>();\n for (const d of days) for (const [model, tokens] of d.byModel) m.set(model, (m.get(model) ?? 0) + tokens);\n return [...m.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([model, tokens]) => ({ model, tokens }));\n };\n (fakeAgg as any).topProvidersInWindow = (days: DayAgg[]) => {\n const m = new Map<string, number>();\n for (const d of days) for (const [provider, tokens] of d.byProvider) m.set(provider, (m.get(provider) ?? 0) + tokens);\n return [...m.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([provider, tokens]) => ({ provider, tokens }));\n };\n return fakeAgg as Aggregated;\n } catch {\n return null;\n } finally {\n clearTimeout(timer);\n }\n}\n\n// Module-level cache that survives SettingsSection remounts (opening the card\n// again unmounts/remounts the component). Reopening renders the cached snapshot\n// immediately (no blank flash); a real fetch happens on the refresh button, on\n// the auto-refresh interval while mounted, or on (re)mount when the cache is\n// older than the configured interval — so toggling the panel open/closed still\n// picks up fresh data once the interval has elapsed.\nlet _cache: { agg: Aggregated; label: string; at: number } | null = null;\n\nexport function useHeatmapData(ctx: any | null, refreshMs?: number, manualTick?: number) {\n const [data, setData] = React.useState<Aggregated | null>(() => _cache?.agg ?? null);\n const [refreshing, setRefreshing] = React.useState(false);\n const [lastRefresh, setLastRefresh] = React.useState<string | null>(() => _cache?.label ?? null);\n // M1 fix: track + cancel the notReady retry so an unmounted component can't\n // leave an orphan retry chain polling every 2s until the host reports ready.\n const cancelledRef = React.useRef(false);\n const retryTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n const mountedRef = React.useRef(false);\n\n const intervalMs = React.useMemo(() => {\n if (refreshMs !== undefined) return refreshMs;\n const mins = getAutoRefreshMinutes();\n return mins === 0 ? 0 : mins * 60 * 1000;\n }, [refreshMs, manualTick]);\n\n const fetchData = React.useCallback(async () => {\n setRefreshing(true);\n const commit = (agg: Aggregated) => {\n const label = new Date().toLocaleString();\n _cache = { agg, label, at: Date.now() };\n setData(agg);\n setLastRefresh(label);\n };\n try {\n const apiData = await fetchFromApi();\n if (apiData && !(apiData as any).__notReady) {\n commit(apiData);\n return;\n }\n if (apiData && (apiData as any).__notReady) {\n // Host init still scanning disk: retry shortly; keep old data showing.\n // Cancel any prior scheduled retry (prevents stacking chains when a\n // manual refresh or interval fires while a retry is already pending),\n // and skip scheduling if this instance has been unmounted (M1).\n if (retryTimerRef.current) clearTimeout(retryTimerRef.current);\n if (!cancelledRef.current) {\n retryTimerRef.current = setTimeout(() => { void fetchData(); }, 2000);\n }\n setRefreshing(false);\n return;\n }\n const store = ctx?.get?.(\"heatmapStore\") ?? (typeof window !== \"undefined\" ? (window as any).__dsh_heatmapStore : null);\n if (store?.refresh) await store.refresh();\n if (store?.getAggregated) {\n commit(store.getAggregated());\n return;\n }\n const snap = typeof window !== \"undefined\" ? (window as any).__dsh_heatmapSnapshot : null;\n if (snap?.byDay && snap?.totals) {\n commit(snap);\n return;\n }\n } catch {\n // keep previous (and cache) on failure\n } finally {\n setRefreshing(false);\n }\n // No successful source this time: only fall back to an empty snapshot if we\n // have nothing cached — never blank out a card that already has data.\n if (!_cache) setData((prev) => prev ?? aggregate([], Date.now()));\n }, [ctx]);\n\n // Fetch policy: on first mount fetch when nothing is cached OR the cached\n // snapshot is older than the configured interval (so reopening the panel\n // after the interval elapses still refreshes — the setInterval alone wouldn't,\n // because it resets on every remount). If auto-refresh is off (intervalMs 0),\n // only fetch on a cold cache. Any later `manualTick` change forces a fetch.\n React.useEffect(() => {\n if (!mountedRef.current) {\n mountedRef.current = true;\n const stale = !_cache || (intervalMs > 0 && Date.now() - _cache.at >= intervalMs);\n if (stale) void fetchData();\n return;\n }\n void fetchData();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fetchData, manualTick]);\n\n // M1 fix: on (re)mount clear any cancelled flag from a previous cycle, and on\n // unmount mark cancelled + drop the pending retry so the chain terminates.\n React.useEffect(() => {\n cancelledRef.current = false;\n return () => {\n cancelledRef.current = true;\n if (retryTimerRef.current) {\n clearTimeout(retryTimerRef.current);\n retryTimerRef.current = null;\n }\n };\n }, []);\n\n // Auto-refresh only on the configured interval (no visibility-triggered\n // refetch — per user request, refresh happens only on button + interval).\n React.useEffect(() => {\n if (intervalMs === 0) return;\n const id = setInterval(fetchData, intervalMs);\n return () => {\n clearInterval(id);\n };\n }, [fetchData, intervalMs]);\n\n const refresh = React.useCallback(() => fetchData(), [fetchData]);\n\n return { data, refreshing, lastRefresh, refresh, intervalMs };\n}\n\nexport function useHeatmapView(aggregated: Aggregated | null, initial: import(\"./HeatmapGrid.tsx\").ViewKind = \"month\") {\n const [view, setView] = React.useState(initial);\n const [anchor, setAnchor] = React.useState(() => toDayKey(Date.now()));\n\n const days: DayAgg[] | null = React.useMemo(() => {\n if (!aggregated) return null;\n switch (view) {\n case \"week\":\n return aggregated.weekDays(anchor);\n case \"month\":\n return aggregated.monthDays(anchor);\n case \"quarter\":\n return aggregated.quarterDays(anchor);\n case \"year\":\n return aggregated.yearDays(anchor);\n }\n }, [aggregated, view, anchor]);\n\n const topModels = React.useMemo(() => {\n if (!aggregated || !days) return aggregated?.topModels ?? [];\n return aggregated.top5InWindow(days);\n }, [aggregated, days]);\n\n const topProviders = React.useMemo(() => {\n if (!aggregated || !days) return aggregated?.topProviders ?? [];\n return aggregated.topProvidersInWindow(days);\n }, [aggregated, days]);\n\n return { view, setView, anchor, setAnchor, days, topModels, topProviders };\n}\n","declare const __PLUGIN_VERSION__: string;\n\nimport * as React from \"react\";\nimport { StatsCards } from \"./StatsCards.tsx\";\nimport { HeatmapGrid, type ViewKind, type LevelThresholds, DEFAULT_THRESHOLDS } from \"./HeatmapGrid.tsx\";\nimport { ModelTop5 } from \"./ModelTop5.tsx\";\nimport { TrendChart } from \"./TrendChart.tsx\";\nimport { en as enDict } from \"./locales.ts\";\nimport { useHeatmapData, useHeatmapView, getAutoRefreshMinutes, setAutoRefreshMinutes } from \"./hooks.ts\";\nimport type { DayAgg } from \"../aggregation.ts\";\n\ntype SettingsSectionProps = {\n t: (key: string, params?: Record<string, any>) => string;\n ctx?: any;\n days?: DayAgg[];\n totals?: any;\n top5?: any;\n};\n\nexport function SettingsSection({ t, ctx, days: injectedDays, totals: injectedTotals, top5: injectedTop5 }: SettingsSectionProps) {\n const [tick, setTick] = React.useState(0);\n const { data: aggregated, refreshing, lastRefresh, refresh } = useHeatmapData(ctx ?? null, undefined, tick);\n const { view, setView, anchor, setAnchor, days: computedDays, topModels: computedTopModels, topProviders: computedTopProviders } = useHeatmapView(aggregated);\n const [topMode, setTopMode] = React.useState<\"model\" | \"provider\">(\"model\");\n const [selectedKey, setSelectedKey] = React.useState<string | null>(null);\n const [intervalMins, setIntervalMins] = React.useState(() => getAutoRefreshMinutes());\n const [lang, setLang] = React.useState<\"zh\" | \"en\">(() => {\n try { const v = localStorage.getItem(\"dsh-token-pulse:lang\"); return v === \"en\" ? \"en\" : \"zh\"; } catch { return \"zh\"; }\n });\n // 分档阈值设置:>= high 恒为深绿(4档),< low 恒为浅绿(1档);localStorage 持久化(tokens)\n // UI 上以 M tokens 为单位显示与输入\n const LS_TH_KEY = \"dsh-token-pulse:thresholds\";\n const [thresholds, setThresholds] = React.useState<LevelThresholds>(() => {\n try {\n const raw = localStorage.getItem(LS_TH_KEY);\n if (!raw) return DEFAULT_THRESHOLDS;\n const parsed = JSON.parse(raw);\n const high = Number(parsed?.high) || 0;\n const low = Number(parsed?.low) || 0;\n return { high: Math.max(0, high), low: Math.max(0, low) };\n } catch { return DEFAULT_THRESHOLDS; }\n });\n // 弹出式设置窗口(⋯ 打开),点遮罩/完成关闭;内部不再互相退出\n const [settingsOpen, setSettingsOpen] = React.useState(false);\n const applyThresholdsM = (highM: number, lowM: number) => {\n const next = { high: Math.max(0, highM) * 1_000_000, low: Math.max(0, lowM) * 1_000_000 };\n setThresholds(next);\n try { localStorage.setItem(LS_TH_KEY, JSON.stringify(next)); } catch {} // ← was missing: edits never persisted\n };\n const thInM = { high: thresholds.high / 1_000_000, low: thresholds.low / 1_000_000 };\n const applyThresholds = (t: LevelThresholds) => {\n setThresholds(t);\n try { localStorage.setItem(LS_TH_KEY, JSON.stringify(t)); } catch {}\n };\n // ⋯ 菜单:显式开关 + 点击外部自动收回\n\n const days = injectedDays ?? computedDays;\n // 趋势图用全量历史(aggregated.byDay),与上面的周/月视图解耦:\n // days 是按视图窗口裁剪的,月视图下看不到上月的天\n const allDays: DayAgg[] = React.useMemo(() => {\n if (aggregated?.byDay) return [...aggregated.byDay.values()];\n return days ?? [];\n }, [aggregated, days]);\n const totals = injectedTotals ?? aggregated?.totals;\n const viewTopModelsRaw = computedTopModels.length ? computedTopModels : (aggregated?.topModels ?? []);\n const viewTopProvidersRaw = computedTopProviders.length ? computedTopProviders : (aggregated?.topProviders ?? []);\n\n // If a day is selected, show that day's Top 5 instead of the view's\n let viewTopModels: typeof viewTopModelsRaw = viewTopModelsRaw;\n let viewTopProviders: typeof viewTopProvidersRaw = viewTopProvidersRaw;\n let topTitleExtra = \"\";\n if (selectedKey && aggregated) {\n const sel = aggregated.byDay.get(selectedKey);\n if (sel) {\n viewTopModels = [...sel.byModel.entries()].sort((a,b)=>b[1]-a[1]).slice(0,5).map(([model,tokens])=>({model,tokens}));\n viewTopProviders = [...sel.byProvider.entries()].sort((a,b)=>b[1]-a[1]).slice(0,5).map(([provider,tokens])=>({provider,tokens}));\n topTitleExtra = ` · ${selectedKey}`;\n }\n }\n const viewTopModelsNamed = viewTopModels.map((x) => ({ name: x.model, tokens: x.tokens }));\n const viewTopProvidersNamed = viewTopProviders.map((x) => ({ name: (x as any).provider ?? (x as any).name, tokens: x.tokens }));\n\n const injectedTop = injectedTop5;\n const hasData = totals && (totals.today > 0 || totals.thisWeek > 0 || totals.thisMonth > 0 || totals.all > 0);\n\n const tt = (key: string, params?: Record<string, any>) => {\n // lang-aware: prefer current lang's dictionary, fallback to t()\n // For now t() is already bound to the plugin's locale (zh by default). We override a few keys manually.\n const zhEn: Record<string, {zh:string,en:string}> = {\n \"heatmap.lang.zh\": { zh: \"中文\", en: \"中文\" },\n \"heatmap.lang.en\": { zh: \"English\", en: \"English\" },\n \"heatmap.lang.label\": { zh: \"语言\", en: \"Language\" },\n \"heatmap.dayDetail\": { zh: `${selectedKey ?? \"\"} · 当日 Top 5`, en: `${selectedKey ?? \"\"} · Top 5 of the day` },\n \"heatmap.clearSelection\": { zh: \"清除选择\", en: \"Clear\" },\n };\n const entry = zhEn[key];\n if (entry) {\n let s = entry[lang];\n if (params) for (const [k,v] of Object.entries(params)) s = s.replace(`{${k}}`, String(v));\n return s;\n }\n return t(key, params);\n };\n\n const handleRefresh = async () => {\n // refresh() already pulls + updates the module cache; no setTick (which\n // would trigger a second fetch).\n await refresh();\n };\n\n const handleIntervalChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n const v = Number(e.target.value);\n setAutoRefreshMinutes(v);\n setIntervalMins(v);\n setTick((x) => x + 1);\n };\n\n const handleLangChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n const v = e.target.value as \"zh\" | \"en\";\n setLang(v);\n try { localStorage.setItem(\"dsh-token-pulse:lang\", v); } catch {}\n };\n\n const handleReset = () => {\n if (!confirm(t(\"heatmap.reset.confirm\"))) return;\n const store = ctx?.get?.(\"heatmapStore\") ?? (typeof window !== \"undefined\" ? (window as any).__dsh_heatmapStore : null);\n if (store?.clearPersisted) {\n store.clearPersisted();\n setTick((x) => x + 1);\n }\n };\n\n const handleViewChange = (v: typeof view) => {\n setSelectedKey(null);\n setView(v);\n };\n\n const handleSelect = (k: string | null) => setSelectedKey(k);\n\n return (\n <section aria-labelledby=\"heatmap-title\" style={{ display: \"flex\", flexDirection: \"column\", gap: 16 }}>\n <div style={{ display: \"flex\", alignItems: \"flex-start\", justifyContent: \"space-between\", gap: 12 }}>\n <div>\n <h2 id=\"heatmap-title\" style={{ margin: 0, fontSize: 16, fontWeight: 600, color: \"var(--dsw-alias-label-primary)\" }}>\n {t(\"heatmap.title\")}\n <span style={{ marginLeft: 8, fontSize: 11, fontWeight: 400, color: \"var(--dsw-alias-label-tertiary)\", verticalAlign: \"middle\" }}>\n v{__PLUGIN_VERSION__}\n </span>\n </h2>\n <p style={{ margin: \"4px 0 0\", fontSize: 13, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: 1.5 }}>\n {lang === \"en\" ? \"Token usage from local session logs, bucketed by Asia/Shanghai. Synced once then persisted — deleting sessions keeps history.\" : t(\"heatmap.subtitle\")}\n </p>\n </div>\n <label style={{ display: \"flex\", alignItems: \"center\", gap: 6, fontSize: 12, color: \"var(--dsw-alias-label-secondary)\", flexShrink: 0 }}>\n {tt(\"heatmap.lang.label\")}\n <select value={lang} onChange={handleLangChange} style={{ padding: \"4px 8px\", fontSize: 12, borderRadius: 6, border: \"1px solid var(--dsw-alias-border-l2)\", background: \"var(--dsw-alias-bg-layer-3)\", color: \"var(--dsw-alias-label-primary)\" }}>\n <option value=\"zh\">{tt(\"heatmap.lang.zh\")}</option>\n <option value=\"en\">{tt(\"heatmap.lang.en\")}</option>\n </select>\n </label>\n </div>\n\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8, flexWrap: \"wrap\" }}>\n <button\n onClick={handleRefresh}\n disabled={refreshing}\n style={{\n padding: \"6px 14px\",\n fontSize: 13,\n borderRadius: 8,\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: refreshing ? \"var(--dsw-alias-bg-layer-2)\" : \"var(--dsw-alias-bg-layer-3)\",\n color: \"var(--dsw-alias-label-primary)\",\n cursor: refreshing ? \"wait\" : \"pointer\",\n }}\n >\n {lang === \"en\" ? (refreshing ? \"Refreshing…\" : \"Refresh\") : (refreshing ? t(\"heatmap.refreshing\") : t(\"heatmap.refresh\"))}\n </button>\n <span style={{ fontSize: 12, color: \"var(--dsw-alias-label-tertiary)\" }}>\n {lastRefresh ? (lang === \"en\" ? `Last refresh: ${lastRefresh}` : t(\"heatmap.lastRefresh\", { time: lastRefresh })) : \"\"}\n </span>\n <span style={{ flex: 1 }} />\n <label style={{ display: \"flex\", alignItems: \"center\", gap: 6, fontSize: 12, color: \"var(--dsw-alias-label-secondary)\" }}>\n {lang === \"en\" ? \"Auto refresh\" : t(\"heatmap.autoRefresh\")}\n <select\n value={intervalMins}\n onChange={handleIntervalChange}\n title={t(\"heatmap.autoRefresh.hint\")}\n style={{\n padding: \"4px 8px\",\n fontSize: 12,\n borderRadius: 6,\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n color: \"var(--dsw-alias-label-primary)\",\n }}\n >\n <option value={0}>{t(\"heatmap.autoRefresh.off\")}</option>\n <option value={5}>5 min</option>\n <option value={10}>10 min</option>\n <option value={30}>30 min</option>\n <option value={60}>60 min</option>\n </select>\n </label>\n <button\n onClick={() => setSettingsOpen(true)}\n aria-haspopup=\"dialog\"\n style={{ listStyle: \"none\", cursor: \"pointer\", padding: \"2px 8px\", fontSize: 13, color: \"var(--dsw-alias-label-tertiary)\", opacity: 0.7, border: \"none\", background: \"transparent\" }}\n title={lang === \"en\" ? \"Settings\" : \"设置\"}\n >⋯</button>\n\n {settingsOpen ? (\n <div\n onClick={() => setSettingsOpen(false)} // 点遮罩关闭\n style={{\n position: \"fixed\", inset: 0, zIndex: 50,\n background: \"rgba(0,0,0,0.35)\",\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n }}\n >\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n onClick={(e) => e.stopPropagation()} // 内容区阻止冒泡,不关窗\n style={{\n background: \"var(--dsw-alias-bg-layer-3)\",\n border: \"1px solid var(--dsw-alias-border-l2)\",\n borderRadius: 12,\n minWidth: 340,\n maxWidth: \"90vw\",\n boxShadow: \"0 8px 24px rgba(0,0,0,0.2)\",\n padding: 16,\n display: \"flex\", flexDirection: \"column\", gap: 12,\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\" }}>\n <span style={{ fontSize: 14, fontWeight: 600, color: \"var(--dsw-alias-label-primary)\" }}>\n {lang === \"en\" ? \"Pulse Settings\" : \"Pulse 设置\"}\n </span>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 10 }}>\n <button\n onClick={() => { if (confirm(lang === \"en\" ? \"Reset all historical data? This cannot be undone.\" : \"确定重置所有历史数据?此操作不可撤销。\")) { handleReset(); } }}\n title={lang === \"en\" ? \"Reset history (advanced)\" : \"重置历史(高级)\"}\n style={{ border: \"none\", background: \"transparent\", fontSize: 11, cursor: \"pointer\", color: \"var(--dsw-alias-label-tertiary)\", opacity: 0.55, textDecoration: \"underline\" }}\n >\n {lang === \"en\" ? \"Reset history…\" : \"重置历史…\"}\n </button>\n <button onClick={() => setSettingsOpen(false)} aria-label=\"close\" style={{ border: \"none\", background: \"transparent\", fontSize: 16, cursor: \"pointer\", color: \"var(--dsw-alias-label-tertiary)\" }}>✕</button>\n </div>\n </div>\n\n {/* 分档阈值 */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n <div style={{ fontSize: 12, fontWeight: 600, color: \"var(--dsw-alias-label-secondary)\" }}>\n {lang === \"en\" ? \"Level thresholds (M tokens)\" : \"分档阈值(M tokens)\"}\n </div>\n {([\n { key: \"high\" as const, label: lang === \"en\" ? \"Deep green ≥ (M)\" : \"深绿阈值 ≥(M)\" },\n { key: \"low\" as const, label: lang === \"en\" ? \"Light green < (M)\" : \"浅绿阈值 <(M)\" },\n ]).map(({ key, label }) => (\n <label key={key} style={{ display: \"flex\", flexDirection: \"column\", gap: 2, fontSize: 11, color: \"var(--dsw-alias-label-secondary)\" }}>\n {label}\n <input\n type=\"number\"\n min={0}\n step={10}\n value={thInM[key]}\n onChange={(e) => applyThresholdsM(\n key === \"high\" ? Math.max(0, Number(e.target.value) || 0) : thInM.high,\n key === \"low\" ? Math.max(0, Number(e.target.value) || 0) : thInM.low,\n )}\n placeholder=\"0 = off\"\n style={{ padding: \"6px 10px\", fontSize: 13, borderRadius: 6, border: \"1px solid var(--dsw-alias-border-l2)\", background: \"var(--dsw-alias-bg-layer-3)\", color: \"var(--dsw-alias-label-primary)\" }}\n />\n </label>\n ))}\n <div style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\" }}>\n <button onClick={() => applyThresholds(DEFAULT_THRESHOLDS)} style={{ padding: \"4px 10px\", fontSize: 11, borderRadius: 5, border: \"1px solid var(--dsw-alias-border-l2)\", background: \"var(--dsw-alias-bg-layer-3)\", cursor: \"pointer\" }}>{lang === \"en\" ? \"Defaults (100M / 10M)\" : \"恢复默认(100M / 10M)\"}</button>\n <span style={{ fontSize: 10, color: \"var(--dsw-alias-label-tertiary)\" }}>0 = off</span>\n </div>\n </div>\n\n <button onClick={() => setSettingsOpen(false)} style={{ width: \"100%\", padding: \"8px 10px\", fontSize: 13, borderRadius: 8, border: \"1px solid var(--dsw-alias-border-l2)\", background: \"var(--dsw-alias-bg-layer-3)\", color: \"var(--dsw-alias-label-primary)\", cursor: \"pointer\" }}>\n {lang === \"en\" ? \"Done\" : \"完成\"}\n </button>\n </div>\n </div>\n ) : null}\n </div>\n\n {view === \"week\" || view === \"month\" ? (\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8, justifyContent: \"space-between\" }}>\n <button onClick={() => setAnchor((a: string) => { const d = new Date(a + \"T12:00:00+08:00\"); if (view === \"week\") d.setDate(d.getDate() - 7); else d.setMonth(d.getMonth() - 1); const ms = d.getTime(); return new Date(ms).toLocaleDateString(\"en-CA\", { timeZone: \"Asia/Shanghai\" } as any); })} style={{ padding: \"4px 10px\", fontSize: 12, borderRadius: 6, border: \"1px solid var(--dsw-alias-border-l2)\", background: \"var(--dsw-alias-bg-layer-3)\", cursor: \"pointer\" }}>{lang === \"en\" ? \"‹ Prev\" : \"‹ 上一\"}{view === \"week\" ? (lang===\"en\"?\" Week\":\"周\") : (lang===\"en\"?\" Month\":\"月\")}</button>\n <span style={{ fontSize: 12, color: \"var(--dsw-alias-label-secondary)\", fontWeight: 500 }}>\n {view === \"week\" ? (()=>{ const a = anchor; const d = new Date(a+\"T12:00:00+08:00\"); const dow=(d.getDay()+6)%7; const mon=new Date(d); mon.setDate(d.getDate()-dow); const sun=new Date(mon); sun.setDate(mon.getDate()+6); const fmt=(x:Date)=> `${x.getMonth()+1}/${x.getDate()}`; return lang===\"en\" ? `Week of ${fmt(mon)} - ${fmt(sun)}` : `${mon.getMonth()+1}月${mon.getDate()}日 - ${sun.getMonth()+1}月${sun.getDate()}日`; })() : `${Number(anchor.slice(0,4))}年${Number(anchor.slice(5,7))}月`}\n {lang === \"en\" && view===\"month\" ? ` ${anchor.slice(0,7)}` : \"\"}\n </span>\n <button onClick={() => setAnchor((a: string) => { const d = new Date(a + \"T12:00:00+08:00\"); if (view === \"week\") d.setDate(d.getDate() + 7); else d.setMonth(d.getMonth() + 1); const ms = d.getTime(); return new Date(ms).toLocaleDateString(\"en-CA\", { timeZone: \"Asia/Shanghai\" } as any); })} style={{ padding: \"4px 10px\", fontSize: 12, borderRadius: 6, border: \"1px solid var(--dsw-alias-border-l2)\", background: \"var(--dsw-alias-bg-layer-3)\", cursor: \"pointer\" }}>{lang === \"en\" ? \"Next ›\" : \"下一\"}{view === \"week\" ? (lang===\"en\"?\" Week\":\"周\") : (lang===\"en\"?\" Month\":\"月\")} ›</button>\n </div>\n ) : null}\n\n {totals ? <StatsCards t={lang === \"en\" ? (k:string,p?:any)=> { const enMap:Record<string,string>={\"stats.today\":\"Today\",\"stats.week\":\"This week\",\"stats.month\":\"This month\",\"stats.all\":\"All time\"}; if(k===\"stats.count\") return `${p?.count ?? \"\"} turns`; return (enMap as any)[k] ?? t(k,p); } : t} totals={totals} todayCount={undefined} /> : null}\n {days ? <HeatmapGrid t={lang === \"en\" ? (k:string,p?:any)=> { const enM:Record<string,string>={\"view.week\":\"Week\",\"view.month\":\"Month\",\"view.quarter\":\"Quarter\",\"view.year\":\"Year\",\"heatmap.legend.less\":\"Less\",\"heatmap.legend.more\":\"More\",\"heatmap.empty\":\"No data yet\",\"heatmap.tooltip.none\":\"No usage\",\"heatmap.subtitle\":\"Token usage from local session logs, bucketed by Asia/Shanghai. First sync is persisted — deleting sessions keeps history.\",\"heatmap.title\":\"Token Pulse\"}; return (enM as any)[k] ?? t(k,p); } : t} days={days} view={view} onViewChange={handleViewChange} selectedKey={selectedKey} onSelect={handleSelect} isEn={lang === \"en\"} thresholds={thresholds} /> : null}\n {selectedKey ? (\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8, fontSize: 12, color: \"var(--dsw-alias-label-secondary)\" }}>\n <span>{tt(\"heatmap.dayDetail\")}</span>\n <button onClick={() => setSelectedKey(null)} style={{ padding: \"2px 8px\", fontSize: 11, borderRadius: 6, border: \"1px solid var(--dsw-alias-border-l2)\", background: \"var(--dsw-alias-bg-layer-3)\", cursor: \"pointer\" }}>{tt(\"heatmap.clearSelection\")}</button>\n </div>\n ) : null}\n {injectedTop ? (\n <ModelTop5 t={t} topModels={injectedTop} topProviders={[]} days={days ?? undefined} mode={topMode} onModeChange={setTopMode} />\n ) : viewTopModelsNamed.length > 0 || viewTopProvidersNamed.length > 0 ? (\n <ModelTop5 t={lang === \"en\" ? (k:string,p?:any)=> ({ \"model.top5\":\"Top 5 Models\",\"provider.top5\":\"Top 5 Providers\",\"model.top5.hint\":\"By token usage\",\"model.none\":\"No data\",\"view.model\":\"Model\",\"view.provider\":\"Provider\"} as any)[k] ?? t(k,p) : t} topModels={viewTopModelsNamed} topProviders={viewTopProvidersNamed} days={days ?? undefined} mode={topMode} onModeChange={setTopMode} />\n ) : null}\n {!hasData && !days ? (\n <div\n style={{\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n borderRadius: 12,\n padding: 24,\n color: \"var(--dsw-alias-label-tertiary)\",\n fontSize: 13,\n }}\n >\n {t(\"heatmap.empty\")}\n </div>\n ) : null}\n {/* 用量趋势线图:横轴时间、纵轴用量、每模型一条线(Top5 可开关);固定最近 7/30 天,与上面的视图选择解耦 */}\n {allDays.some((d) => d.totalTokens > 0) ? (\n <TrendChart\n t={lang === \"en\" ? (k: string, p?: any) => ((enDict as any)[k] ?? t(k, p)) : t}\n days={allDays}\n isEn={lang === \"en\"}\n />\n ) : null}\n </section>\n );\n}\n\nexport default SettingsSection;\n","import * as React from \"react\";\nimport { SettingsSection } from \"./SettingsSection.tsx\";\nimport { zh, en } from \"./locales.ts\";\n\nconst NS = \"dsh-token-pulse\";\n\nexport const inject = [\"locale\", \"slots\"] as const;\n\n// CSS: replace default gear with a heatmap/grid icon for this settings entry\nconst NAV_CSS = `\n[data-dsh-token-pulse-nav] > svg:first-child { display: none; }\n[data-dsh-token-pulse-nav]::before {\n content: ''; flex: none; width: 16px; height: 16px; background: currentColor;\n -webkit-mask: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='3' width='7' height='7' rx='1'/%3E%3Crect x='14' y='3' width='7' height='7' rx='1'/%3E%3Crect x='3' y='14' width='7' height='7' rx='1'/%3E%3Crect x='14' y='14' width='7' height='7' rx='1'/%3E%3C/svg%3E\") center / contain no-repeat;\n mask: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='3' width='7' height='7' rx='1'/%3E%3Crect x='14' y='3' width='7' height='7' rx='1'/%3E%3Crect x='3' y='14' width='7' height='7' rx='1'/%3E%3Crect x='14' y='14' width='7' height='7' rx='1'/%3E%3C/svg%3E\") center / contain no-repeat;\n}\n`;\n\nfunction injectNavCss() {\n if (typeof document === \"undefined\") return;\n const id = \"dsh-token-pulse-nav-css\";\n if (document.getElementById(id)) return;\n const el = document.createElement(\"style\");\n el.id = id;\n el.textContent = NAV_CSS;\n document.head.appendChild(el);\n}\n\nfunction markNavRow() {\n if (typeof document === \"undefined\") return;\n const nav = t_global();\n // Match by the plugin's own label so future copy changes need only one edit.\n // Legacy strings kept as belt-and-suspenders fallbacks for the icon injection.\n const dynamic = typeof nav === \"function\" ? nav(\"nav\") : \"\";\n const labels = [dynamic, \"Token Pulse\", \"Token Heatmap\", \"用量热图\"].filter(Boolean);\n for (const label of labels) {\n const btn = [...document.querySelectorAll('button')].find((b) => b.textContent?.trim().includes(label));\n if (btn) btn.setAttribute(\"data-dsh-token-pulse-nav\", \"\");\n }\n}\n\nlet t_global: () => any = () => (k: string) => k;\n\n// One-time migration from the pre-rename `dsh-token-heatmap:*` localStorage\n// keys. The plugin was renamed to `dsh-token-pulse`; carry lang, thresholds\n// and auto-refresh forward so existing users keep their settings.\nfunction migrateLegacyLocalStorage() {\n if (typeof localStorage === \"undefined\") return;\n const pairs = [\n [\"dsh-token-heatmap:lang\", \"dsh-token-pulse:lang\"],\n [\"dsh-token-heatmap:thresholds\", \"dsh-token-pulse:thresholds\"],\n [\"dsh-token-heatmap:autoRefreshMinutes\", \"dsh-token-pulse:autoRefreshMinutes\"],\n ] as const;\n for (const [from, to] of pairs) {\n try {\n if (localStorage.getItem(to) === null) {\n const v = localStorage.getItem(from);\n if (v !== null) localStorage.setItem(to, v);\n }\n } catch {}\n }\n}\n\nexport function apply(ctx: any) {\n migrateLegacyLocalStorage();\n injectNavCss();\n ctx.effect(\n () => ctx.locale.register(NS, { zh, en }),\n \"dsh-token-pulse: dictionaries\",\n );\n const t = ctx.locale.bind(NS);\n t_global = () => t;\n\n ctx.slots.inject(\"settings.section\", () =>\n ctx.slots.register(\n {\n name: \"settings.section\",\n id: \"heatmap\",\n order: 55,\n label: () => t(\"nav\"),\n locale: NS,\n },\n (props: any) => {\n // Mark nav row on render (settings panel is open, rows are mounted)\n setTimeout(markNavRow, 50);\n return React.createElement(SettingsSection, { t, ctx, ...props });\n },\n ),\n );\n // Also try to mark whenever settings panel opens (poll a bit)\n if (typeof document !== \"undefined\") {\n const mo = new MutationObserver(() => markNavRow());\n mo.observe(document.documentElement, { childList: true, subtree: true });\n setTimeout(() => mo.disconnect(), 30000);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["formatTokens","formatTokensShort","React","React","React","a","enDict","React"],"sources":["../src/client/StatsCards.tsx","../src/date-bucket.ts","../src/aggregation.ts","../src/client/HeatmapGrid.tsx","../src/client/ModelTop5.tsx","../src/client/trend.ts","../src/client/TrendChart.tsx","../src/client/locales.ts","../src/client/hooks.ts","../src/client/SettingsSection.tsx","../src/client/index.ts"],"sourcesContent":["import * as React from \"react\";\n\nexport type Totals = {\n today: number;\n thisWeek: number;\n thisMonth: number;\n all: number;\n};\n\nexport function formatTokens(n: number): string {\n if (n >= 1_000_000_000) return (n / 1_000_000_000).toFixed(2) + \"B\";\n if (n >= 1_000_000) return (n / 1_000_000).toFixed(2) + \"M\";\n if (n >= 1000) return (n / 1000).toFixed(2) + \"k\";\n return n.toLocaleString();\n}\n\ntype CardProps = {\n label: string;\n value: number;\n hint?: string;\n};\n\nfunction StatCard({ label, value, hint }: CardProps) {\n return (\n <div\n style={{\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n borderRadius: 12,\n padding: \"12px 14px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 4,\n minWidth: 0,\n }}\n >\n <div style={{ fontSize: 12, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: \"18px\" }}>{label}</div>\n <div style={{ fontSize: 18, fontWeight: 600, color: \"var(--dsw-alias-label-primary)\", lineHeight: \"28px\", overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }}>\n {formatTokens(value)}\n </div>\n {hint ? <div style={{ fontSize: 12, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: \"16px\" }}>{hint}</div> : null}\n </div>\n );\n}\n\nexport function StatsCards({\n t,\n totals,\n todayCount,\n}: {\n t: (key: string, params?: Record<string, any>) => string;\n totals: Totals;\n todayCount?: number;\n}) {\n return (\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"repeat(4, minmax(0, 1fr))\",\n gap: 12,\n }}\n >\n <StatCard label={t(\"stats.today\")} value={totals.today} hint={todayCount !== undefined ? t(\"stats.count\", { count: todayCount }) : undefined} />\n <StatCard label={t(\"stats.week\")} value={totals.thisWeek} />\n <StatCard label={t(\"stats.month\")} value={totals.thisMonth} />\n <StatCard label={t(\"stats.all\")} value={totals.all} />\n </div>\n );\n}\n\nexport default StatsCards;\n","const TZ = \"Asia/Shanghai\";\n\nexport function toDayKey(ms: number, tz = TZ): string {\n const fmt = new Intl.DateTimeFormat(\"en-CA\", {\n timeZone: tz,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n });\n return fmt.format(new Date(ms));\n}\n\nexport function dayKeyToDate(key: string, _tz = TZ): Date {\n return new Date(key + \"T12:00:00+08:00\");\n}\n\nexport function weekStartOf(dayKey: string): string {\n const d = dayKeyToDate(dayKey);\n const dow = (d.getDay() + 6) % 7; // Mon=0\n d.setDate(d.getDate() - dow);\n return toDayKey(d.getTime());\n}\n\nexport function monthStartOf(dayKey: string): string {\n const d = dayKeyToDate(dayKey);\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, \"0\")}-01`;\n}\n\nexport function quarterStartOf(dayKey: string): string {\n const d = dayKeyToDate(dayKey);\n const q = Math.floor(d.getMonth() / 3);\n const m = q * 3 + 1;\n return `${d.getFullYear()}-${String(m).padStart(2, \"0\")}-01`;\n}\n\nexport function yearStartOf(dayKey: string): string {\n const d = dayKeyToDate(dayKey);\n return `${d.getFullYear()}-01-01`;\n}\n\nexport function addDays(dayKey: string, n: number): string {\n const d = dayKeyToDate(dayKey);\n d.setDate(d.getDate() + n);\n return toDayKey(d.getTime());\n}\n\nexport function listDaysInRange(startKey: string, endKey: string): string[] {\n const result: string[] = [];\n let cur = startKey;\n while (cur <= endKey) {\n result.push(cur);\n cur = addDays(cur, 1);\n }\n return result;\n}\n\nexport function weekRangeFor(dateKey: string): [string, string] {\n const s = weekStartOf(dateKey);\n return [s, addDays(s, 6)];\n}\n\nexport function monthRangeFor(dateKey: string): [string, string] {\n const s = monthStartOf(dateKey);\n const d = dayKeyToDate(s);\n const lastDay = new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();\n return [s, `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, \"0\")}-${String(lastDay).padStart(2, \"0\")}`];\n}\n\n/** Last ~90 days: sliding window for the \"Quarter\" tab (not calendar quarter). */\nexport function quarterRangeFor(dateKey: string): [string, string] {\n return [addDays(dateKey, -89), dateKey];\n}\n\nexport function yearRangeFor(dateKey: string): [string, string] {\n const s = yearStartOf(dateKey);\n const d = dayKeyToDate(s);\n return [s, `${d.getFullYear()}-12-31`];\n}\n","import {\n toDayKey,\n addDays,\n listDaysInRange,\n weekRangeFor,\n monthRangeFor,\n quarterRangeFor,\n yearRangeFor,\n} from \"./date-bucket.ts\";\n\nexport type RawUsageEvent = {\n time: number;\n provider: string;\n model: string;\n usage: {\n inputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n outputTokens: number;\n };\n /** Session id this usage belongs to. Used by HeatmapStore.refresh() to\n * replace a live session's events in place without duplicating history. */\n sid?: string;\n};\n\nexport type DayAgg = {\n dayKey: string;\n totalTokens: number;\n uncachedInputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n outputTokens: number;\n count: number;\n byModel: Map<string, number>;\n byProvider: Map<string, number>;\n /** 24 hourly buckets in Asia/Shanghai, index 0 = 00:00-01:00 */\n hourlyTokens: number[];\n winnerModel: string | null;\n winnerProvider: string | null;\n};\n\nexport type TopItem = { name: string; tokens: number };\n\nexport type Aggregated = {\n byDay: Map<string, DayAgg>;\n totals: { today: number; thisWeek: number; thisMonth: number; all: number };\n topModels: Array<{ model: string; tokens: number }>;\n topProviders: Array<{ provider: string; tokens: number }>;\n /** @deprecated use topModels */\n top5: Array<{ model: string; tokens: number }>;\n weekDays(dayKey: string): DayAgg[];\n monthDays(dayKey: string): DayAgg[];\n quarterDays(dayKey: string): DayAgg[];\n yearDays(dayKey: string): DayAgg[];\n top5InWindow(days: DayAgg[]): Array<{ model: string; tokens: number }>;\n topProvidersInWindow(days: DayAgg[]): Array<{ provider: string; tokens: number }>;\n};\n\nfunction emptyDay(dayKey: string): DayAgg {\n return {\n dayKey,\n totalTokens: 0,\n uncachedInputTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n outputTokens: 0,\n count: 0,\n byModel: new Map(),\n byProvider: new Map(),\n hourlyTokens: new Array(24).fill(0),\n winnerModel: null,\n winnerProvider: null,\n };\n}\n\nfunction sumByDay(days: DayAgg[]): number {\n return days.reduce((s, d) => s + d.totalTokens, 0);\n}\n\nfunction resolveDay(byDay: Map<string, DayAgg>, key: string): DayAgg {\n return byDay.get(key) ?? emptyDay(key);\n}\n\nfunction resolveRange(byDay: Map<string, DayAgg>, start: string, end: string): DayAgg[] {\n return listDaysInRange(start, end).map((k) => resolveDay(byDay, k));\n}\n\n/**\n * 5-level fallback for callers without a view-aware max (e.g. legacy tests).\n * For view-aware quantile, use levelForView().\n */\nexport function clampLevel(value: number): 0 | 1 | 2 | 3 | 4 {\n if (value === 0) return 0;\n if (value <= 2000) return 1;\n if (value <= 10000) return 2;\n if (value <= 50000) return 3;\n return 4;\n}\n\n/** View-aware quantile: 0, (0,25%], (25%,50%], (50%,75%], (75%,100%] so month/quarter spread across the palette. */\nexport function levelForView(value: number, viewMax: number): 0 | 1 | 2 | 3 | 4 {\n if (value === 0) return 0;\n if (viewMax <= 0) return 1;\n const r = value / viewMax;\n if (r <= 0.25) return 1;\n if (r <= 0.5) return 2;\n if (r <= 0.75) return 3;\n return 4;\n}\n\n/** Minimum number of non-zero values before rank-based bucketing kicks in. Below this we fall back to logLevel(). */\nexport const MIN_RANK_POINTS = 5;\n\n/**\n * Rank-based (percentile) level. Outlier-proof: no matter how large one day is,\n * lower values still spread across levels 1-4 by their position among non-zero\n * values — a single huge day no longer flattens everything to level 1.\n * `sortedNonZero` must be the ascending-sorted array of all non-zero values in\n * the view. Uses the midpoint of the \"below\" and \"at-or-below\" ranks, so ties\n * sit in the middle of their band; the maximum always lands on level 4 and the\n * minimum on level 1, guaranteeing all four colored levels appear (n ≥ 2).\n * 0 maps to 0.\n */\nexport function levelByRank(value: number, sortedNonZero: number[]): 0 | 1 | 2 | 3 | 4 {\n if (value <= 0) return 0;\n const n = sortedNonZero.length;\n if (n === 0) return 1;\n let below = 0;\n let atOrBelow = 0;\n for (const v of sortedNonZero) {\n if (v < value) below++;\n if (v <= value) atOrBelow++;\n }\n const rank = (below / n + atOrBelow / n) / 2; // midpoint rank ∈ (0, 1)\n if (rank <= 0.25) return 1; // bottom quarter\n if (rank <= 0.5) return 2; // 25-50%\n if (rank <= 0.75) return 3; // 50-75%\n return 4; // top quarter, max always here\n}\n\n/**\n * Log-scaled ratio fallback for sparse data (< MIN_RANK_POINTS non-zero values).\n * Compresses outliers logarithmically so a single large value doesn't flatten\n * the rest, while keeping \"larger = darker\" intuition.\n */\nexport function logLevel(value: number, viewMax: number): 0 | 1 | 2 | 3 | 4 {\n if (value <= 0) return 0;\n if (viewMax <= 0) return 1;\n const r = Math.log1p(value) / Math.log1p(viewMax);\n if (r <= 0.25) return 1;\n if (r <= 0.5) return 2;\n if (r <= 0.75) return 3;\n return 4;\n}\n\nfunction hourInShanghai(ms: number): number {\n // Convert to Asia/Shanghai hour 0-23. en-GB is used because en-US may emit\n // \"24\" for midnight on some ICU data; we also defensively clamp.\n const s = new Date(ms).toLocaleString(\"en-GB\", { timeZone: \"Asia/Shanghai\", hour: \"2-digit\", hour12: false });\n const h = Number(s);\n return h === 24 ? 0 : h;\n}\n\nexport function aggregate(events: RawUsageEvent[], nowMs: number): Aggregated {\n const byDay = new Map<string, DayAgg>();\n const globalByModel = new Map<string, number>();\n const globalByProvider = new Map<string, number>();\n\n for (const ev of events) {\n const dayKey = toDayKey(ev.time);\n let agg = byDay.get(dayKey);\n if (!agg) {\n agg = emptyDay(dayKey);\n byDay.set(dayKey, agg);\n }\n const u = ev.usage;\n const total = (u.inputTokens ?? 0) + (u.cacheReadTokens ?? 0) + (u.cacheWriteTokens ?? 0) + (u.outputTokens ?? 0);\n agg.totalTokens += total;\n agg.uncachedInputTokens += u.inputTokens ?? 0;\n agg.cacheReadTokens += u.cacheReadTokens ?? 0;\n agg.cacheWriteTokens += u.cacheWriteTokens ?? 0;\n agg.outputTokens += u.outputTokens ?? 0;\n agg.count += 1;\n const h = hourInShanghai(ev.time);\n if (h >= 0 && h < 24) agg.hourlyTokens[h] += total;\n\n const modelKey = ev.model || \"unknown\";\n const providerKey = ev.provider || \"unknown\";\n agg.byModel.set(modelKey, (agg.byModel.get(modelKey) ?? 0) + total);\n agg.byProvider.set(providerKey, (agg.byProvider.get(providerKey) ?? 0) + total);\n globalByModel.set(modelKey, (globalByModel.get(modelKey) ?? 0) + total);\n globalByProvider.set(providerKey, (globalByProvider.get(providerKey) ?? 0) + total);\n }\n\n // compute winners per day\n for (const agg of byDay.values()) {\n let bestM: string | null = null;\n let bestMVal = -1;\n for (const [m, v] of agg.byModel) {\n if (v > bestMVal) {\n bestMVal = v;\n bestM = m;\n }\n }\n agg.winnerModel = bestM;\n\n let bestP: string | null = null;\n let bestPVal = -1;\n for (const [p, v] of agg.byProvider) {\n if (v > bestPVal) {\n bestPVal = v;\n bestP = p;\n }\n }\n agg.winnerProvider = bestP;\n }\n\n const todayKey = toDayKey(nowMs);\n const [wStart, wEnd] = weekRangeFor(todayKey);\n const [mStart, mEnd] = monthRangeFor(todayKey);\n\n const today = byDay.get(todayKey)?.totalTokens ?? 0;\n const thisWeek = sumByDay(resolveRange(byDay, wStart, wEnd));\n const thisMonth = sumByDay(resolveRange(byDay, mStart, mEnd));\n let all = 0;\n for (const v of byDay.values()) all += v.totalTokens;\n\n const topModels = [...globalByModel.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([model, tokens]) => ({ model, tokens }));\n\n const topProviders = [...globalByProvider.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([provider, tokens]) => ({ provider, tokens }));\n\n function top5InWindow(days: DayAgg[]): Array<{ model: string; tokens: number }> {\n const m = new Map<string, number>();\n for (const d of days) {\n for (const [model, tokens] of d.byModel) {\n m.set(model, (m.get(model) ?? 0) + tokens);\n }\n }\n return [...m.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([model, tokens]) => ({ model, tokens }));\n }\n\n function topProvidersInWindow(days: DayAgg[]): Array<{ provider: string; tokens: number }> {\n const m = new Map<string, number>();\n for (const d of days) {\n for (const [provider, tokens] of d.byProvider) {\n m.set(provider, (m.get(provider) ?? 0) + tokens);\n }\n }\n return [...m.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([provider, tokens]) => ({ provider, tokens }));\n }\n\n return {\n byDay,\n totals: { today, thisWeek, thisMonth, all },\n topModels,\n topProviders,\n top5: topModels,\n weekDays: (k: string) => {\n const [s, e] = weekRangeFor(k);\n return resolveRange(byDay, s, e);\n },\n monthDays: (k: string) => {\n const [s, e] = monthRangeFor(k);\n return resolveRange(byDay, s, e);\n },\n quarterDays: (k: string) => {\n const [s, e] = quarterRangeFor(k);\n return resolveRange(byDay, s, e);\n },\n yearDays: (k: string) => {\n const [s, e] = yearRangeFor(k);\n return resolveRange(byDay, s, e);\n },\n top5InWindow,\n topProvidersInWindow,\n };\n}\n","import * as React from \"react\";\nimport { levelByRank, logLevel, MIN_RANK_POINTS, type DayAgg } from \"../aggregation.ts\";\n\nexport type ViewKind = \"week\" | \"month\" | \"quarter\" | \"year\";\n\nconst VIEW_ORDER: ViewKind[] = [\"week\", \"month\", \"quarter\", \"year\"];\n\n/** Thresholds (tokens/day). Day-grid only: above HIGH always level 4; below LOW\n * always level 1; the band in between uses percentile ranking. Configurable in\n * the ⋯ menu. Hour bars in the Week view ignore absolute thresholds entirely —\n * they are rank-based only, so all four levels stay visible. */\nexport type LevelThresholds = { high: number; low: number };\n\nexport const DEFAULT_THRESHOLDS: LevelThresholds = { high: 100_000_000, low: 10_000_000 };\n\n/**\n * Build a rank-based (percentile) level map for a day-window, keyed by dayKey.\n * Outlier-proof: a single huge day no longer flattens the rest of the window\n * to level 1. Falls back to log-scaled ratio when non-zero days are too few.\n * Absolute thresholds override ranking: >= high -> always 4, < low -> always 1.\n * (Day grids only — week-hour bars skip these, see buildHourLevels.)\n */\nfunction buildDayLevels(days: DayAgg[], th: LevelThresholds): Map<string, number> {\n const nonZero = days\n .filter((d) => d.totalTokens > 0)\n .map((d) => d.totalTokens)\n .sort((a, b) => a - b);\n const viewMax = days.reduce((m, d) => Math.max(m, d.totalTokens), 0);\n const map = new Map<string, number>();\n for (const d of days) {\n let level: number;\n if (d.totalTokens <= 0) level = 0;\n else if (th.high > 0 && d.totalTokens >= th.high) level = 4; // absolute deep green\n else if (th.low > 0 && d.totalTokens < th.low) level = 1; // absolute light green\n else if (nonZero.length < MIN_RANK_POINTS) level = logLevel(d.totalTokens, viewMax);\n else level = levelByRank(d.totalTokens, nonZero);\n map.set(d.dayKey, level);\n }\n return map;\n}\n\n/**\n * Build rank-based level arrays for hour bars across a week (cross-day comparable).\n * Maps dayKey -> number[24] of levels. NO absolute thresholds here: the 37-ish\n * small hours would otherwise be pinned to level 1 and the mid band would pile\n * into 3/4, leaving level 2 empty. Pure rank keeps all four levels populated.\n */\nfunction buildHourLevels(days: DayAgg[]): Map<string, number[]> {\n const nonZero: number[] = [];\n const raw = new Map<string, number[]>();\n for (const d of days) {\n const h = d.hourlyTokens ?? new Array(24).fill(0);\n raw.set(d.dayKey, h);\n for (const v of h) if (v > 0) nonZero.push(v);\n }\n nonZero.sort((a, b) => a - b);\n const weekMax = nonZero.length ? nonZero[nonZero.length - 1] : 1;\n const out = new Map<string, number[]>();\n for (const [k, h] of raw) {\n out.set(\n k,\n h.map((v) => {\n if (v <= 0) return 0;\n if (nonZero.length < MIN_RANK_POINTS) return logLevel(v, weekMax);\n return levelByRank(v, nonZero);\n }),\n );\n }\n return out;\n}\n\nfunction formatTokensShort(n: number): string {\n if (n >= 1_000_000_000) return (n / 1_000_000_000).toFixed(2) + \"B\";\n if (n >= 1_000_000) return (n / 1_000_000).toFixed(2) + \"M\";\n if (n >= 1000) return (n / 1000).toFixed(2) + \"k\";\n return n.toLocaleString();\n}\n\nfunction tooltipTotal(day: DayAgg): string {\n if (day.totalTokens === 0) return `${day.dayKey}: No usage`;\n return `${day.dayKey}: ${formatTokensShort(day.totalTokens)} tokens`;\n}\n\nfunction HeatCell({ day, level, size = 14 }: { day: DayAgg; level: number; size?: number }) {\n const colors: Record<number, string> = {\n 0: \"var(--dsw-alias-bg-layer-2, #ebedf0)\",\n 1: \"#c6e48b\",\n 2: \"#7bc96f\",\n 3: \"#239a3b\",\n 4: \"#196127\",\n };\n return (\n <div\n title={tooltipTotal(day)}\n aria-label={tooltipTotal(day)}\n style={{\n width: size,\n height: size,\n borderRadius: 3,\n background: colors[level],\n border: level === 0 ? \"1px solid var(--dsw-alias-border-l2, #e5e7eb)\" : \"1px solid transparent\",\n boxSizing: \"border-box\",\n cursor: \"pointer\",\n flexShrink: 0,\n }}\n />\n );\n}\n\nfunction HourStrip({ day, hourLevels }: { day: DayAgg; hourLevels: number[] }) {\n const hourly = day.hourlyTokens ?? new Array(24).fill(0);\n const colors: Record<number, string> = {\n 0: \"var(--dsw-alias-bg-layer-2, #ebedf0)\",\n 1: \"#c6e48b\",\n 2: \"#7bc96f\",\n 3: \"#239a3b\",\n 4: \"#196127\",\n };\n return (\n <div style={{ display: \"flex\", gap: 1, alignItems: \"end\", flex: 1, minWidth: 0 }}>\n {hourly.map((v, h) => {\n const lv = hourLevels[h] ?? 0;\n const hh = v === 0 ? `${String(h).padStart(2, \"0\")}:00 — No usage` : `${String(h).padStart(2, \"0\")}:00 — ${formatTokensShort(v)} tokens`;\n return (\n <div\n key={h}\n title={hh}\n aria-label={hh}\n style={{\n flex: 1,\n height: 6 + lv * 4,\n borderRadius: 1,\n background: colors[lv],\n border: lv === 0 ? \"1px solid var(--dsw-alias-border-l2)\" : \"none\",\n boxSizing: \"border-box\",\n minWidth: 0,\n }}\n />\n );\n })}\n </div>\n );\n}\n\nfunction ViewSwitcher({\n t,\n value,\n onChange,\n}: {\n t: (k: string, p?: any) => string;\n value: ViewKind;\n onChange: (v: ViewKind) => void;\n}) {\n return (\n <div\n role=\"tablist\"\n aria-label=\"view switcher\"\n style={{\n display: \"inline-flex\",\n border: \"1px solid var(--dsw-alias-border-l2)\",\n borderRadius: 8,\n overflow: \"hidden\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n }}\n >\n {VIEW_ORDER.map((v) => (\n <button\n key={v}\n role=\"tab\"\n aria-selected={value === v}\n onClick={() => onChange(v)}\n style={{\n padding: \"6px 14px\",\n fontSize: 13,\n lineHeight: \"20px\",\n border: \"none\",\n cursor: \"pointer\",\n background: value === v ? \"var(--dsw-alias-label-primary)\" : \"transparent\",\n color: value === v ? \"var(--dsw-alias-bg-layer-3)\" : \"var(--dsw-alias-label-primary)\",\n fontWeight: value === v ? 600 : 400,\n }}\n >\n {t(`view.${v}`)}\n </button>\n ))}\n </div>\n );\n}\n\nfunction MonthHeader({ weeks, cellSize }: { weeks: DayAgg[][]; cellSize: number }) {\n const seen = new Set<string>();\n return (\n <div style={{ display: \"flex\", gap: 3, paddingLeft: cellSize + 20, marginBottom: 2 }}>\n {weeks.map((week, i) => {\n const m = week.find((d) => d.totalTokens !== -1)?.dayKey.slice(0, 7) ?? \"\";\n let label = \"\";\n if (m && !seen.has(m)) { seen.add(m); const n = Number(m.slice(5,7)); label = [\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"][n-1]; }\n return <span key={i} style={{ width: cellSize, fontSize: 10, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: \"12px\", whiteSpace: \"nowrap\", overflow: \"visible\" }}>{label}</span>;\n })}\n </div>\n );\n}\n\nfunction GitHubGrid({ days, t, cellSize, twoRows, isEn, dayLevels }: { days: DayAgg[]; t: (k: string, p?: any) => string; cellSize: number; twoRows?: boolean; isEn?: boolean; dayLevels: Map<string, number> }) {\n const weeks: DayAgg[][] = [];\n let cur: DayAgg[] = [];\n for (const d of days) {\n const rawDow = new Date(d.dayKey + \"T12:00:00+08:00\").getDay();\n const dow = isEn ? rawDow : (rawDow + 6) % 7;\n if (cur.length === 0 && weeks.length === 0 && dow !== 0) {\n for (let i = 0; i < dow; i++) {\n cur.push({ dayKey: `pad-${i}`, totalTokens: -1, uncachedInputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, outputTokens: 0, count: 0, byModel: new Map(), byProvider: new Map(), hourlyTokens: new Array(24).fill(0), winnerModel: null, winnerProvider: null });\n }\n }\n cur.push(d);\n if (cur.length === 7) {\n weeks.push(cur);\n cur = [];\n }\n }\n if (cur.length > 0) {\n while (cur.length < 7) cur.push({ dayKey: `pad-end-${cur.length}`, totalTokens: -1, uncachedInputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, outputTokens: 0, count: 0, byModel: new Map(), byProvider: new Map(), hourlyTokens: new Array(24).fill(0), winnerModel: null, winnerProvider: null });\n weeks.push(cur);\n }\n\n const renderWeeks = (ws: DayAgg[][]) => (\n <div style={{ display: \"flex\", gap: cellSize >= 22 ? 10 : 5 }}>\n {ws.map((week, wi) => (\n <div key={wi} style={{ display: \"flex\", flexDirection: \"column\", gap: 3 }}>\n {week.map((d) =>\n d.totalTokens === -1 ? (\n <div key={d.dayKey} style={{ width: cellSize, height: cellSize }} />\n ) : (\n <HeatCell key={d.dayKey} day={d} level={dayLevels.get(d.dayKey) ?? 0} size={cellSize} />\n ),\n )}\n </div>\n ))}\n </div>\n );\n\n if (twoRows && weeks.length > 26) {\n const mid = Math.ceil(weeks.length / 2);\n const top = weeks.slice(0, mid);\n const bot = weeks.slice(mid);\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 16, alignItems: \"center\" }}>\n <div>\n <MonthHeader weeks={top} cellSize={cellSize} />\n <div style={{ display: \"flex\", gap: 3 }}>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 3 }}>\n <span style={{ height: cellSize, fontSize: cellSize >= 22 ? 13 : 10, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: `${cellSize}px` }}>{isEn ? \"Sun\" : \"Mon\"}</span>\n <span style={{ height: cellSize }} />\n <span style={{ height: cellSize, fontSize: cellSize >= 22 ? 13 : 10, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: `${cellSize}px` }}>{isEn ? \"Tue\" : \"Wed\"}</span>\n <span style={{ height: cellSize }} />\n <span style={{ height: cellSize, fontSize: cellSize >= 22 ? 13 : 10, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: `${cellSize}px` }}>{isEn ? \"Thu\" : \"Fri\"}</span>\n <span style={{ height: cellSize }} />\n <span style={{ height: cellSize }} />\n </div>\n {renderWeeks(top)}\n </div>\n </div>\n <div>\n <MonthHeader weeks={bot} cellSize={cellSize} />\n <div style={{ display: \"flex\", gap: 3 }}>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 3 }}>\n <span style={{ height: cellSize, fontSize: cellSize >= 22 ? 13 : 10, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: `${cellSize}px` }}>{isEn ? \"Sun\" : \"Mon\"}</span>\n <span style={{ height: cellSize }} />\n <span style={{ height: cellSize, fontSize: cellSize >= 22 ? 13 : 10, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: `${cellSize}px` }}>{isEn ? \"Tue\" : \"Wed\"}</span>\n <span style={{ height: cellSize }} />\n <span style={{ height: cellSize, fontSize: cellSize >= 22 ? 13 : 10, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: `${cellSize}px` }}>{isEn ? \"Thu\" : \"Fri\"}</span>\n <span style={{ height: cellSize }} />\n <span style={{ height: cellSize }} />\n </div>\n {renderWeeks(bot)}\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <div style={{ overflowX: \"auto\", paddingBottom: 4, display: \"flex\", flexDirection: \"column\", alignItems: \"center\", gap: 6 }}>\n <MonthHeader weeks={weeks} cellSize={cellSize} />\n <div style={{ display: \"flex\", gap: cellSize >= 22 ? 10 : 5, justifyContent: \"center\" }}>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 3, fontSize: cellSize >= 22 ? 13 : 10, color: \"var(--dsw-alias-label-tertiary)\" }}>\n {(isEn ? [\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"] : [\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\"]).map((w, i) => (\n <span key={w} style={{ height: cellSize, lineHeight: `${cellSize}px`, textAlign: \"right\", paddingRight: 4, fontWeight: 500 }}>{w}</span>\n ))}\n </div>\n {renderWeeks(weeks)}\n </div>\n </div>\n );\n}\n\nfunction CalendarGrid({ days, t, dayLevels, selectedKey, onSelect, isEn }: { days: DayAgg[]; t: (k:string,p?:any)=>string; dayLevels: Map<string, number>; selectedKey: string | null; onSelect: (k: string | null) => void; isEn?: boolean }) {\n const weekdaysZh = [\"一\",\"二\",\"三\",\"四\",\"五\",\"六\",\"日\"];\n const weekdaysEn = [\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\"];\n const isZh = (t(\"heatmap.title\") || \"\").includes(\"Token\") ? false : false;\n // Use locale-aware: check if nav is Chinese\n const header = [\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\"];\n const headerZh = [\"一\",\"二\",\"三\",\"四\",\"五\",\"六\",\"日\"];\n // Simple: show Mon-Sun always (github style), but tint weekend header\n const firstDow = firstDowOf(days);\n const pad = firstDow;\n const cells: (DayAgg | null)[] = [];\n for (let i = 0; i < pad; i++) cells.push(null);\n for (const d of days) cells.push(d);\n while (cells.length % 7 !== 0) cells.push(null);\n\n function firstDowOf(ds: DayAgg[]): number {\n if (ds.length === 0) return 0;\n const raw = new Date(ds[0].dayKey + \"T12:00:00+08:00\").getDay();\n return isEn ? raw : (raw + 6) % 7;\n }\n\n return (\n <div style={{ border: \"1px solid var(--dsw-alias-border-l2)\", borderRadius: 12, overflow: \"hidden\", background: \"var(--dsw-alias-bg-layer-3)\" }}>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(7, 1fr)\", gap: 6, padding: \"8px 6px 6px\" }}>\n {(isEn ? [\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"] : header).map((w) => (\n <div key={w} style={{ textAlign: \"center\", fontSize: 11, fontWeight: 500, color: \"var(--dsw-alias-label-tertiary)\" }}>\n {w}\n </div>\n ))}\n </div>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(7, 1fr)\", gap: 6, padding: \"0 6px\" }}>\n {cells.map((d, idx) => {\n if (!d) return <div key={`pad-${idx}`} style={{ minHeight: 50 }} />;\n const selected = d.dayKey === selectedKey;\n const level = dayLevels.get(d.dayKey) ?? 0;\n const bgMap: Record<number,string> = { 0: \"var(--dsw-alias-bg-layer-3)\", 1: \"#c6e48b\", 2: \"#7bc96f\", 3: \"#239a3b\", 4: \"#196127\" };\n return (\n <button\n key={d.dayKey}\n onClick={() => onSelect(selected ? null : d.dayKey)}\n title={tooltipTotal(d)}\n aria-label={tooltipTotal(d)}\n style={{\n minHeight: 50,\n padding: \"6px 6px 4px\",\n textAlign: \"left\",\n border: selected ? \"1.5px solid var(--dsw-alias-brand-primary, #1677ff)\" : \"1px solid var(--dsw-alias-border-l2, #e5e7eb)\",\n borderRadius: 8,\n background: selected ? \"var(--dsw-alias-brand-primary, #1677ff)\" : bgMap[level],\n color: selected ? \"#fff\" : level === 0 ? \"var(--dsw-alias-label-primary)\" : level <= 2 ? \"#1a1a1a\" : \"#fff\",\n cursor: \"pointer\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 1,\n alignItems: \"flex-start\",\n }}\n >\n <span style={{ fontSize: 12, fontWeight: 600, lineHeight: \"16px\" }}>{d.dayKey.slice(8, 10).replace(/^0/, \"\")}</span>\n <span style={{ fontSize: 10, lineHeight: \"12px\", opacity: 0.8, whiteSpace: \"nowrap\", overflow: \"hidden\", textOverflow: \"ellipsis\", maxWidth: \"100%\" }}>{d.totalTokens > 0 ? formatTokensShort(d.totalTokens) : \"\"}</span>\n </button>\n );\n })}\n </div>\n </div>\n );\n}\n\nexport function HeatmapGrid({\n t,\n days,\n view,\n onViewChange,\n selectedKey,\n onSelect,\n isEn,\n thresholds = DEFAULT_THRESHOLDS,\n}: {\n t: (k: string, p?: any) => string;\n days: DayAgg[];\n view: ViewKind;\n onViewChange: (v: ViewKind) => void;\n selectedKey?: string | null;\n onSelect?: (k: string | null) => void;\n isEn?: boolean;\n thresholds?: LevelThresholds;\n}) {\n const isWeek = view === \"week\";\n const hasAny = days.some((d) => d.totalTokens > 0);\n const dayLevels = buildDayLevels(days, thresholds);\n const hourLevels = buildHourLevels(days);\n const cellSize = isWeek ? 16 : view === \"quarter\" ? 23 : (view === \"year\" ? 14 : 14);\n\n const handleViewChange = (v: ViewKind) => {\n onSelect?.(null);\n onViewChange(v);\n };\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 6 }}>\n <ViewSwitcher t={t} value={view} onChange={handleViewChange} />\n\n {!hasAny ? (\n <div\n style={{\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n borderRadius: 12,\n padding: 24,\n color: \"var(--dsw-alias-label-tertiary)\",\n fontSize: 13,\n }}\n >\n {t(\"heatmap.empty\")}\n </div>\n ) : null}\n\n {isWeek ? (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 5 }}>\n {days.map((d) => {\n const wd = new Date(d.dayKey + \"T12:00:00+08:00\").getDay();\n const weekday = isEn\n ? [\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"][wd]\n : [\"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"][(wd + 6) % 7];\n const sel = d.dayKey === selectedKey;\n return (\n <button\n key={d.dayKey}\n onClick={() => onSelect?.(sel ? null : d.dayKey)}\n title={tooltipTotal(d)}\n style={{\n display: \"flex\", alignItems: \"center\", gap: 10, minWidth: 0, width: \"100%\",\n padding: \"6px 8px\", borderRadius: 8,\n border: sel ? \"1px solid var(--dsw-alias-brand-primary)\" : \"1px solid transparent\",\n background: sel ? \"var(--dsw-alias-bg-layer-2)\" : \"transparent\",\n cursor: \"pointer\", textAlign: \"left\",\n }}\n >\n <div style={{ width: 52, flexShrink: 0, display: \"flex\", flexDirection: \"column\", gap: 1 }}>\n <span style={{ fontSize: 12, fontWeight: 600, color: \"var(--dsw-alias-label-primary)\", lineHeight: \"16px\" }}>{weekday}</span>\n <span style={{ fontSize: 10, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: \"12px\" }}>{d.dayKey.slice(5)}</span>\n </div>\n <HourStrip day={d} hourLevels={hourLevels.get(d.dayKey) ?? new Array(24).fill(0)} />\n <span style={{ fontSize: 11, color: \"var(--dsw-alias-label-tertiary)\", whiteSpace: \"nowrap\", width: 80, textAlign: \"right\" }}>\n {d.totalTokens === 0 ? \"No usage\" : `${formatTokensShort(d.totalTokens)} tokens`}\n </span>\n </button>\n );\n })}\n </div>\n ) : view === \"month\" ? (\n <CalendarGrid days={days} t={t} dayLevels={dayLevels} selectedKey={selectedKey ?? null} onSelect={onSelect ?? (() => {})} isEn={isEn} />\n ) : view === \"year\" ? (\n <GitHubGrid days={days} t={t} cellSize={cellSize} twoRows isEn={isEn} dayLevels={dayLevels} />\n ) : (\n <GitHubGrid days={days} t={t} cellSize={cellSize} isEn={isEn} dayLevels={dayLevels} />\n )}\n\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 6, justifyContent: \"flex-end\", fontSize: 12, color: \"var(--dsw-alias-label-tertiary)\" }}>\n <span>{t(\"heatmap.legend.less\")}</span>\n <span style={{ width: 12, height: 12, borderRadius: 2, background: \"var(--dsw-alias-bg-layer-2, #ebedf0)\", border: \"1px solid var(--dsw-alias-border-l2)\" }} />\n <span style={{ width: 12, height: 12, borderRadius: 2, background: \"#c6e48b\" }} />\n <span style={{ width: 12, height: 12, borderRadius: 2, background: \"#7bc96f\" }} />\n <span style={{ width: 12, height: 12, borderRadius: 2, background: \"#239a3b\" }} />\n <span style={{ width: 12, height: 12, borderRadius: 2, background: \"#196127\" }} />\n <span>{t(\"heatmap.legend.more\")}</span>\n </div>\n </div>\n );\n}\n\nexport default HeatmapGrid;\n","import * as React from \"react\";\nimport type { DayAgg } from \"../aggregation.ts\";\n\nexport type TopItem = { model?: string; provider?: string; name: string; tokens: number };\n\nfunction formatTokens(n: number): string {\n if (n >= 1_000_000_000) return (n / 1_000_000_000).toFixed(2) + \"B\";\n if (n >= 1_000_000) return (n / 1_000_000).toFixed(2) + \"M\";\n if (n >= 1000) return (n / 1000).toFixed(2) + \"k\";\n return n.toLocaleString();\n}\n\nexport function ModelTop5({\n t,\n topModels,\n topProviders,\n days,\n mode = \"model\",\n onModeChange,\n othersModelTokens,\n othersProviderTokens,\n}: {\n t: (k: string, p?: any) => string;\n topModels: TopItem[];\n topProviders: TopItem[];\n days?: DayAgg[];\n mode?: \"model\" | \"provider\";\n onModeChange?: (m: \"model\" | \"provider\") => void;\n /** sum of every model/provider beyond the top 5 (rendered as an extra tail row) */\n othersModelTokens?: number;\n othersProviderTokens?: number;\n}) {\n const active = mode === \"provider\" ? topProviders : topModels;\n const othersTokens = mode === \"provider\" ? othersProviderTokens : othersModelTokens;\n const hasOthers = (othersTokens ?? 0) > 0;\n\n if (active.length === 0) {\n return (\n <div\n style={{\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n borderRadius: 12,\n padding: 16,\n color: \"var(--dsw-alias-label-tertiary)\",\n fontSize: 13,\n }}\n >\n {t(\"model.none\")}\n </div>\n );\n }\n\n const max = active[0]?.tokens ?? 1;\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 12 }}>\n <div\n style={{\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n borderRadius: 12,\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n padding: \"12px 16px 8px\",\n borderBottom: \"1px solid var(--dsw-alias-border-l2)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: 8,\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <span style={{ fontSize: 13, fontWeight: 600, color: \"var(--dsw-alias-label-primary)\" }}>\n {mode === \"provider\" ? t(\"provider.top5\") : t(\"model.top5\")}\n </span>\n <span style={{ fontSize: 11, color: \"var(--dsw-alias-label-tertiary)\" }}>{t(\"model.top5.hint\")}</span>\n </div>\n {onModeChange ? (\n <div style={{ display: \"inline-flex\", border: \"1px solid var(--dsw-alias-border-l2)\", borderRadius: 6, overflow: \"hidden\" }}>\n <button\n onClick={() => onModeChange(\"model\")}\n style={{\n padding: \"2px 8px\",\n fontSize: 11,\n border: \"none\",\n cursor: \"pointer\",\n background: mode === \"model\" ? \"var(--dsw-alias-label-primary)\" : \"transparent\",\n color: mode === \"model\" ? \"var(--dsw-alias-bg-layer-3)\" : \"var(--dsw-alias-label-secondary)\",\n }}\n >\n {t(\"view.model\")}\n </button>\n <button\n onClick={() => onModeChange(\"provider\")}\n style={{\n padding: \"2px 8px\",\n fontSize: 11,\n border: \"none\",\n cursor: \"pointer\",\n background: mode === \"provider\" ? \"var(--dsw-alias-label-primary)\" : \"transparent\",\n color: mode === \"provider\" ? \"var(--dsw-alias-bg-layer-3)\" : \"var(--dsw-alias-label-secondary)\",\n }}\n >\n {t(\"view.provider\")}\n </button>\n </div>\n ) : null}\n </div>\n <div style={{ display: \"flex\", flexDirection: \"column\" }}>\n {active.map((item, idx) => (\n <div\n key={item.name}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n padding: \"10px 16px\",\n borderTop: idx === 0 ? \"none\" : \"1px solid var(--dsw-alias-border-l2)\",\n }}\n >\n <span style={{ width: 20, textAlign: \"center\", fontSize: 12, fontWeight: 600, color: \"var(--dsw-alias-label-tertiary)\" }}>\n {idx + 1}\n </span>\n <span\n style={{\n flex: \"0 1 40%\",\n minWidth: 0,\n fontSize: 13,\n color: \"var(--dsw-alias-label-primary)\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n title={item.name}\n >\n {item.name}\n </span>\n <div style={{ flex: 1, height: 6, borderRadius: 3, background: \"var(--dsw-alias-bg-layer-2, #ebedf0)\", overflow: \"hidden\" }}>\n <div style={{ width: `${Math.max(4, (item.tokens / max) * 100)}%`, height: \"100%\", background: \"#40c463\", borderRadius: 3 }} />\n </div>\n <span style={{ fontSize: 12, color: \"var(--dsw-alias-label-secondary)\", whiteSpace: \"nowrap\" }}>\n {formatTokens(item.tokens)}\n </span>\n </div>\n ))}\n {/* tail row: every model/provider beyond the top 5, aggregated */}\n {hasOthers ? (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n padding: \"10px 16px\",\n borderTop: \"1px solid var(--dsw-alias-border-l2)\",\n opacity: 0.75,\n }}\n >\n <span style={{ width: 20, textAlign: \"center\", fontSize: 12, color: \"var(--dsw-alias-label-tertiary)\" }}>…</span>\n <span\n style={{\n flex: \"0 1 40%\",\n minWidth: 0,\n fontSize: 13,\n color: \"var(--dsw-alias-label-secondary)\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n title={t(\"model.others\")}\n >\n {t(\"model.others\")}\n </span>\n <div style={{ flex: 1, height: 6, borderRadius: 3, background: \"var(--dsw-alias-bg-layer-2, #ebedf0)\", overflow: \"hidden\" }}>\n <div style={{ width: `${Math.min(100, Math.max(4, ((othersTokens ?? 0) / max) * 100))}%`, height: \"100%\", background: \"#9aa3ad\", borderRadius: 3 }} />\n </div>\n <span style={{ fontSize: 12, color: \"var(--dsw-alias-label-secondary)\", whiteSpace: \"nowrap\" }}>\n {formatTokens(othersTokens ?? 0)}\n </span>\n </div>\n ) : null}\n </div>\n </div>\n\n\n </div>\n );\n}\n\nexport default ModelTop5;\n","import type { DayAgg } from \"../aggregation.ts\";\nimport { addDays } from \"../date-bucket.ts\";\n\n/**\n * Pure logic for the bottom-of-page trend line chart: window slicing,\n * top-model selection, per-model series building and monotone cubic smoothing.\n * Kept free of React/DOM so it is unit-testable and reusable.\n */\n\n/** N consecutive day keys ending at `endKey` (inclusive). */\nexport function recentDayKeys(endKey: string, n: number): string[] {\n const out: string[] = [];\n for (let i = n - 1; i >= 0; i--) out.push(addDays(endKey, -i));\n return out;\n}\n\n/** Sum each model's tokens over `dayKeys`. */\nfunction modelTotals(days: DayAgg[], dayKeys: string[]): Map<string, number> {\n const inWindow = new Set(dayKeys);\n const totals = new Map<string, number>();\n for (const d of days) {\n if (!inWindow.has(d.dayKey)) continue;\n for (const [model, tokens] of d.byModel) {\n totals.set(model, (totals.get(model) ?? 0) + tokens);\n }\n }\n return totals;\n}\n\nconst byTotalDesc = (a: [string, number], b: [string, number]) => (b[1] - a[1]) || (a[0] < b[0] ? -1 : 1);\n\n/** Synthetic series key for \"all other models combined\". */\nexport const OTHER_KEY = \"__other__\";\n\n/** Sum of every model NOT in `exclude`, per day, aligned to `dayKeys`. */\nexport function buildOtherSeries(days: DayAgg[], dayKeys: string[], exclude: Set<string>): TrendSeries {\n const index = new Map(dayKeys.map((k, i) => [k, i] as const));\n const points = new Array<number>(dayKeys.length).fill(0);\n for (const d of days) {\n const i = index.get(d.dayKey);\n if (i === undefined) continue;\n for (const [m, v] of d.byModel) {\n if (!exclude.has(m)) points[i] += v;\n }\n }\n return { model: OTHER_KEY, points };\n}\n\n/** Sum each model's tokens over `dayKeys`, return up to `k` names by total desc. */\nexport function pickTopModels(days: DayAgg[], dayKeys: string[], k = 5): string[] {\n return [...modelTotals(days, dayKeys).entries()]\n .sort(byTotalDesc)\n .slice(0, k)\n .map(([model]) => model);\n}\n\n/**\n * Legend selection for the trend chart: the range's top-k models PLUS the\n * week's top-`weekTopN` models guaranteed (a model that took over this week\n * must stay visible in a 30/90-day view). If the union exceeds `k`, the\n * weakest range-ranked models give up their slots. Result is ordered by range\n * usage desc, deduplicated, at most `k` names.\n */\nexport function pickTrendModels(\n days: DayAgg[],\n dayKeys: string[],\n weekKeys: string[],\n k = 10,\n weekTopN = 3,\n): string[] {\n const rangeTotals = modelTotals(days, dayKeys);\n const rangeRanked = [...rangeTotals.entries()].sort(byTotalDesc).slice(0, k).map(([m]) => m);\n const weekTop = pickTopModels(days, weekKeys, weekTopN);\n const selected = new Set<string>(weekTop);\n for (const m of rangeRanked) {\n if (selected.size >= k) break;\n selected.add(m);\n }\n return [...selected].sort(\n (a, b) => ((rangeTotals.get(b) ?? 0) - (rangeTotals.get(a) ?? 0)) || (a < b ? -1 : 1),\n );\n}\n\nexport type TrendSeries = { model: string; points: number[] };\n\n/** One series per model: its daily tokens aligned to `dayKeys`, 0 where absent. */\nexport function buildSeries(days: DayAgg[], dayKeys: string[], models: string[]): TrendSeries[] {\n const index = new Map(days.map((d) => [d.dayKey, d]));\n return models.map((model) => ({\n model,\n points: dayKeys.map((k) => index.get(k)?.byModel.get(model) ?? 0),\n }));\n}\n\nexport type Segment = {\n p0: [number, number];\n c1: [number, number];\n c2: [number, number];\n p1: [number, number];\n};\n\n/**\n * Monotone cubic (Fritsch–Carlson) Hermite interpolation of 2-D points as\n * cubic bezier segments. Used instead of plain Catmull-Rom because a smooth\n * trend line must NOT overshoot: a zero day between two peaks stays at zero\n * instead of dipping below the axis and inventing a fake trough.\n */\nexport function monotoneSegments(pts: Array<[number, number]>): Segment[] {\n const n = pts.length;\n if (n < 2) return [];\n // slopes (secants) between neighbours\n const h: number[] = [];\n const delta: number[] = [];\n for (let i = 0; i < n - 1; i++) {\n const dx = pts[i + 1][0] - pts[i][0];\n h.push(dx);\n delta.push(dx === 0 ? 0 : (pts[i + 1][1] - pts[i][1]) / dx);\n }\n // tangents: start with mean of neighbouring secants\n const m: number[] = new Array(n);\n m[0] = delta[0];\n m[n - 1] = delta[n - 2];\n for (let i = 1; i < n - 1; i++) {\n m[i] = delta[i - 1] * delta[i] <= 0 ? 0 : (delta[i - 1] + delta[i]) / 2;\n }\n // Fritsch–Carlson limiter: keep the curve monotone (no overshoot)\n for (let i = 0; i < n - 1; i++) {\n if (delta[i] === 0) {\n m[i] = 0;\n m[i + 1] = 0;\n continue;\n }\n const a = m[i] / delta[i];\n const b = m[i + 1] / delta[i];\n const s = a * a + b * b;\n if (s > 9) {\n const t = 3 / Math.sqrt(s);\n m[i] = t * a * delta[i];\n m[i + 1] = t * b * delta[i];\n }\n }\n // Hermite -> cubic bezier control points\n const segs: Segment[] = [];\n for (let i = 0; i < n - 1; i++) {\n const [x0, y0] = pts[i];\n const [x1, y1] = pts[i + 1];\n const dx = (x1 - x0) / 3;\n segs.push({\n p0: [x0, y0],\n c1: [x0 + dx, y0 + m[i] * (x1 - x0) / 3],\n c2: [x1 - dx, y1 - m[i + 1] * (x1 - x0) / 3],\n p1: [x1, y1],\n });\n }\n return segs;\n}\n\nconst fmtNum = (v: number) => Math.round(v * 100) / 100;\n\n/** SVG path `d` for a smoothed polyline through `points` ([x,y] pairs). */\nexport function seriesPath(points: Array<[number, number]>): string {\n if (points.length === 0) return \"\";\n const head = `M ${fmtNum(points[0][0])} ${fmtNum(points[0][1])}`;\n if (points.length === 1) return head;\n const segs = monotoneSegments(points);\n return head + segs\n .map((s) => ` C ${fmtNum(s.c1[0])} ${fmtNum(s.c1[1])}, ${fmtNum(s.c2[0])} ${fmtNum(s.c2[1])}, ${fmtNum(s.p1[0])} ${fmtNum(s.p1[1])}`)\n .join(\"\");\n}\n\n/**\n * Same curve as seriesPath, but resampled at `samples` evenly spaced x\n * positions into a FIXED-structure polyline (M + samples L). Every path then\n * has an identical command count no matter how many days it represents, so\n * CSS `transition: d` can morph lines across range switches too — where raw\n * bezier paths (M + n-1 C) have mismatched structures and would jump.\n * Visual output is indistinguishable at this density.\n */\nexport function seriesPathFixed(points: Array<[number, number]>, samples = 89): string {\n if (points.length === 0) return \"\";\n const x0 = points[0][0];\n const x1 = points[points.length - 1][0];\n const head = `M ${fmtNum(x0)} ${fmtNum(points[0][1])}`;\n if (points.length === 1) return head;\n const segs = monotoneSegments(points);\n let out = \"\";\n let seg = 0;\n for (let s = 1; s <= samples; s++) {\n const x = x0 + ((x1 - x0) * s) / samples;\n while (seg < segs.length - 1 && x > segs[seg].p1[0]) seg++;\n const g = segs[seg];\n const t = g.p1[0] === g.p0[0] ? 0 : Math.min(1, Math.max(0, (x - g.p0[0]) / (g.p1[0] - g.p0[0])));\n const mt = 1 - t;\n const y = mt * mt * mt * g.p0[1] + 3 * mt * mt * t * g.c1[1] + 3 * mt * t * t * g.c2[1] + t * t * t * g.p1[1];\n out += ` L ${fmtNum(x)} ${fmtNum(y)}`;\n }\n return head + out;\n}\n\n/** Compact token count for axis labels (same semantics as the heatmap). */\nexport function formatTokensShort(n: number): string {\n if (n >= 1_000_000_000) return (n / 1_000_000_000).toFixed(2) + \"B\";\n if (n >= 1_000_000) return (n / 1_000_000).toFixed(2) + \"M\";\n if (n >= 1000) return (n / 1000).toFixed(2) + \"k\";\n return n.toLocaleString();\n}\n","import * as React from \"react\";\nimport type { DayAgg } from \"../aggregation.ts\";\nimport { toDayKey } from \"../date-bucket.ts\";\nimport { recentDayKeys, pickTrendModels, buildSeries, buildOtherSeries, OTHER_KEY, seriesPathFixed, formatTokensShort } from \"./trend.ts\";\n\n/** Distinct, colorblind-tolerant series colors (first matches the heatmap green). */\nconst COLORS = [\n \"#40c463\", \"#4c8dff\", \"#f6a609\", \"#c956e0\", \"#ff7a59\",\n \"#26c6da\", \"#ff5c8a\", \"#9ccc65\", \"#7e57c2\", \"#ffd54f\",\n];\n\n/** Round a max up to a friendly axis ceiling (steps of half a decade). */\nfunction niceCeil(v: number): number {\n if (v <= 0) return 1;\n const unit = Math.pow(10, Math.floor(Math.log10(v))) / 2;\n return Math.ceil(v / unit) * unit;\n}\n\n/** \"z-ai/glm-5.3\" -> \"glm-5.3\": display only the part after the last \"/\". */\nfunction shortName(model: string): string {\n const i = model.lastIndexOf(\"/\");\n return i >= 0 ? model.slice(i + 1) : model;\n}\n\nconst W = 720;\nconst H = 280;\nconst PAD = { top: 10, right: 28, bottom: 34, left: 76 }; // right: 给最右日期标签留出空间,避免贴边裁字\n/** chart container horizontal padding (must match the div below) */\nconst CX_PAD = 8;\nconst LS_TYPE_KEY = \"dsh-token-pulse:trendChartType\";\n/** transition/animation duration for the value/axis morphs (one tempo everywhere) */\nconst DUR = \".55s\";\nconst T_POS = `x ${DUR} ease, y ${DUR} ease, width ${DUR} ease, height ${DUR} ease`;\nconst T_D = `d ${DUR} ease`;\nconst T_POINT = `cx ${DUR} ease, cy ${DUR} ease, r .2s ease`;\nconst T_FADE = `opacity ${DUR} ease`;\nconst T_SHIFT = `transform ${DUR} ease`;\nconst GHOST_MS = 650;\n\n/**\n * Stable color assignment per MODEL (not per rank): the same model keeps its\n * color across range switches and legend toggles, so the animation never\n * repaints a series. First-seen order locks the palette slot for good.\n * Module-level so the assignment survives closing/reopening the panel.\n */\nconst modelColorSlot = new Map<string, number>();\nfunction colorFor(model: string): string {\n let slot = modelColorSlot.get(model);\n if (slot === undefined) {\n slot = modelColorSlot.size % COLORS.length;\n modelColorSlot.set(model, slot);\n }\n return COLORS[slot];\n}\n\n/**\n * Animation styles. Elements that ENTER on a range/type switch (CSS transitions\n * only animate elements that already existed) play a keyframe in the same 0.55s\n * tempo as the gliding elements, and elements that LEAVE stay mounted for one\n * beat as a \"ghost\" layer that collapses/fades — so the whole chart moves\n * together instead of mixing instant pops with in-flight marks.\n * The enter classes self-remove on animationend so live styles (hover opacity,\n * legend toggles) keep working afterwards.\n */\nconst ANIM_CSS = `\n@keyframes dtp-grow { from { transform: scaleY(.02); opacity: .3; } }\n@keyframes dtp-fadein { from { opacity: 0; } }\n@keyframes dtp-shrink { to { transform: scaleY(.02); opacity: 0; } }\n@keyframes dtp-fadeout { to { opacity: 0; } }\n.dtp-growin { transform-box: fill-box; transform-origin: bottom; animation: dtp-grow ${DUR} ease; }\n.dtp-fadein { animation: dtp-fadein ${DUR} ease; }\n.dtp-ghost-bars { transform-box: fill-box; transform-origin: bottom; animation: dtp-shrink ${DUR} ease forwards; }\n.dtp-ghost-lines { animation: dtp-fadeout ${DUR} ease forwards; }\n`;\n\n/**\n * Usage chart at the bottom of the settings section, two switchable forms:\n * - \"line\": one smoothed (monotone cubic) line per model over the days\n * - \"bar\": one stacked bar per day, visible models layered bottom-up\n * Both share the legend (top-10 + week's top-3, chips toggle models), the\n * 7 / 30 / 90-day ranges and a compact translucent hover tooltip BESIDE the\n * cursor (date, day total, per-model totals sorted desc, zero rows hidden).\n *\n * Range/type switches animate as ONE coordinated beat: retained marks glide\n * by date identity (the last 7 days of a 30-day view sit in the rightmost\n * slots, so 7→30 slides the week's bars right+down), entering marks grow from\n * the baseline / fade in, and leaving marks collapse in a ghost overlay.\n * Model colors are locked to model identity, never to rank position.\n *\n * Pure SVG + absolutely-positioned HTML tooltip, no dependencies.\n */\nexport function TrendChart({\n t,\n days,\n isEn = false,\n}: {\n t: (k: string, p?: any) => string;\n days: DayAgg[];\n isEn?: boolean;\n}) {\n const [rangeDays, setRangeDays] = React.useState<7 | 30 | 90>(7);\n const [chartType, setChartType] = React.useState<\"line\" | \"bar\">(() => {\n try { return localStorage.getItem(LS_TYPE_KEY) === \"line\" ? \"line\" : \"bar\"; } catch { return \"bar\"; }\n });\n const [hidden, setHidden] = React.useState<ReadonlySet<string>>(new Set());\n /** hovered column index + pointer position in wrapper px (for side placement) */\n const [hover, setHover] = React.useState<{ idx: number; px: number; py: number } | null>(null);\n /** one-beat overlay of the PREVIOUS layout's marks, collapsing out on switches */\n const [ghost, setGhost] = React.useState<{ marks: React.ReactNode; labels: React.ReactNode; type: \"line\" | \"bar\" } | null>(null);\n\n const endKey = toDayKey(Date.now());\n const dayKeys = React.useMemo(() => recentDayKeys(endKey, rangeDays), [endKey, rangeDays]);\n const weekKeys = React.useMemo(() => recentDayKeys(endKey, 7), [endKey]);\n // 范围前 9 + 近一周前 3 必进列表(本周冒头的模型在 30/90 天视图里也可见);\n // 第 10 位固定为「其它」——聚合剩余所有模型,柱子总量即全天真实用量\n const topModels = React.useMemo(() => pickTrendModels(days, dayKeys, weekKeys, 9, 3), [days, dayKeys, weekKeys]);\n const series = React.useMemo(() => {\n const base = buildSeries(days, dayKeys, topModels);\n const other = buildOtherSeries(days, dayKeys, new Set(topModels));\n return other.points.some((v) => v > 0) ? [...base, other] : base;\n }, [days, dayKeys, topModels]);\n\n // wrapper size for pixel-accurate tooltip positioning under the scaled SVG\n const wrapRef = React.useRef<HTMLDivElement | null>(null);\n const [wrap, setWrap] = React.useState({ w: 0, h: 0 });\n React.useEffect(() => {\n const el = wrapRef.current;\n if (!el) return;\n const measure = () => setWrap({ w: el.clientWidth, h: el.clientHeight });\n measure();\n const ro = new ResizeObserver(measure);\n ro.observe(el);\n return () => ro.disconnect();\n }, []);\n\n // previous-render identity sets (for enter animations) + last-render mark\n // nodes (reused as the ghost overlay on switches)\n const prevDaysRef = React.useRef<string[] | null>(null);\n const prevModelsRef = React.useRef<string[] | null>(null);\n const prevTickRef = React.useRef<string[] | null>(null);\n const prevTypeRef = React.useRef<\"line\" | \"bar\" | null>(null);\n const marksRef = React.useRef<React.ReactNode>(null);\n const labelsRef = React.useRef<React.ReactNode>(null);\n\n const toggle = (model: string) => {\n setHidden((prev) => {\n const next = new Set(prev);\n if (next.has(model)) next.delete(model);\n else next.add(model);\n return next;\n });\n };\n\n const colorOf = (model: string) => (model === OTHER_KEY ? \"#8b949e\" : colorFor(model));\n /** 其它 series 用固定中性灰;显示名:其它系列显示「其它/Other」,模型只显示 \"/\" 后半段 */\n const dispName = (model: string) => (model === OTHER_KEY ? t(\"model.others\") : shortName(model));\n const isHidden = (model: string) => hidden.has(model);\n const visible = series.filter((s) => !isHidden(s.model));\n\n const plotW = W - PAD.left - PAD.right;\n const plotH = H - PAD.top - PAD.bottom;\n // line mode: points spread edge-to-edge; bar mode: one slot per day\n const step = dayKeys.length > 1 ? plotW / (dayKeys.length - 1) : plotW;\n const xOf = (i: number) => PAD.left + (dayKeys.length > 1 ? i * step : plotW / 2);\n const slot = plotW / dayKeys.length;\n const barW = Math.max(2, slot * 0.6);\n const cxOf = (i: number) => PAD.left + slot * (i + 0.5);\n const anchorX = (i: number) => (chartType === \"bar\" ? cxOf(i) : xOf(i));\n // bars stack every visible model per day, so their axis max is the largest\n // daily stack total; lines scale by the largest single point\n const dayTotals = dayKeys.map((_, i) => visible.reduce((a, s) => a + s.points[i], 0));\n const yMax = chartType === \"bar\"\n ? niceCeil(Math.max(1, ...dayTotals))\n : niceCeil(Math.max(1, ...visible.map((s) => Math.max(0, ...s.points))));\n const yOf = (v: number) => PAD.top + (1 - v / yMax) * plotH;\n\n const fmtDay = (k: string) => `${Number(k.slice(5, 7))}/${Number(k.slice(8, 10))}`;\n const fmtDayLong = (k: string) =>\n isEn\n ? `${Number(k.slice(5, 7))}/${Number(k.slice(8, 10))}`\n : `${Number(k.slice(5, 7))}月${Number(k.slice(8, 10))}日`;\n // x tick indices: every day for a week, sparse ticks for month/quarter ranges\n const tickEvery = rangeDays === 7 ? 1 : rangeDays === 30 ? 5 : 10;\n const tickIdx = dayKeys.map((_, i) => i).filter((i) => i % tickEvery === 0 || i === dayKeys.length - 1);\n\n // enter-anim eligibility: element identities that did not exist last render\n const typeChanged = prevTypeRef.current !== null && prevTypeRef.current !== chartType;\n const isNewDay = (k: string) =>\n prevDaysRef.current !== null && (typeChanged || !prevDaysRef.current.includes(k));\n const isNewModel = (m: string) =>\n prevModelsRef.current !== null && (typeChanged || !prevModelsRef.current.includes(m));\n const isNewTick = (k: string) =>\n prevTickRef.current !== null && (typeChanged || !prevTickRef.current.includes(k));\n const enterCls = (isNew: boolean, grow: boolean) => (isNew ? (grow ? \"dtp-growin\" : \"dtp-fadein\") : undefined);\n const onAnimEnd = (e: React.AnimationEvent<SVGElement>) => {\n e.currentTarget.classList.remove(\"dtp-growin\", \"dtp-fadein\");\n };\n\n React.useEffect(() => {\n marksRef.current = marksNode;\n labelsRef.current = labelsNode;\n prevDaysRef.current = dayKeys;\n // 按实际系列列表记身份(含「其它」),否则「其它」每次切换都被误判为新模型而重复长出\n prevModelsRef.current = series.map((s) => s.model);\n prevTickRef.current = tickIdx.map((i) => dayKeys[i]);\n prevTypeRef.current = chartType;\n });\n\n React.useEffect(() => {\n if (!ghost) return;\n const timer = setTimeout(() => setGhost(null), GHOST_MS);\n return () => clearTimeout(timer);\n }, [ghost]);\n\n const switchTo = (patch: { range?: 7 | 30 | 90; type?: \"line\" | \"bar\" }) => {\n // capture the CURRENT layout's mark nodes as the exiting ghost overlay\n setGhost({ marks: marksRef.current, labels: labelsRef.current, type: chartType });\n if (patch.range !== undefined) setRangeDays(patch.range);\n if (patch.type !== undefined) {\n setChartType(patch.type);\n try { localStorage.setItem(LS_TYPE_KEY, patch.type); } catch {}\n }\n setHover(null);\n };\n\n const onMove = (e: React.MouseEvent<SVGSVGElement>) => {\n const wrapEl = wrapRef.current;\n if (!wrapEl) return;\n const wrapRect = wrapEl.getBoundingClientRect();\n const svgRect = e.currentTarget.getBoundingClientRect();\n const scale = svgRect.width / W || 1;\n const xvb = (e.clientX - svgRect.left) / scale;\n const i = chartType === \"bar\"\n ? Math.floor((xvb - PAD.left) / slot)\n : Math.round((xvb - PAD.left) / step);\n setHover({\n idx: Math.max(0, Math.min(dayKeys.length - 1, i)),\n px: e.clientX - wrapRect.left,\n py: e.clientY - wrapRect.top,\n });\n };\n\n // hovered column: date, day total and one row per visible model —\n // sorted by that day's usage desc, zero-usage models hidden\n const hoverRows = hover == null ? [] : visible\n .map((s) => ({\n model: s.model,\n color: colorOf(s.model),\n value: s.points[hover.idx],\n }))\n .filter((r) => r.value > 0)\n .sort((a, b) => b.value - a.value);\n const hoverTotal = hoverRows.reduce((a, r) => a + r.value, 0);\n\n // tooltip placement: to the SIDE of the hovered column (flips near edges),\n // vertically centered on the pointer, so the hovered mark is never covered\n const tipW = 200;\n const tipH = 56 + hoverRows.length * 19;\n const gap = 14;\n const svgW = Math.max(0, wrap.w - CX_PAD * 2);\n const colPx = hover == null ? 0 : CX_PAD + (anchorX(hover.idx) / W) * svgW;\n let tipLeft = hover == null ? 0 : colPx + gap;\n if (hover != null && tipLeft + tipW > wrap.w - 4) tipLeft = colPx - gap - tipW;\n tipLeft = Math.max(4, tipLeft);\n const tipTop = hover == null ? 0 : Math.max(4, Math.min(hover.py - tipH / 2, Math.max(4, wrap.h - tipH - 4)));\n\n const segStyle: React.CSSProperties = {\n padding: \"2px 8px\",\n fontSize: 12,\n border: \"none\",\n cursor: \"pointer\",\n borderRadius: 5,\n background: \"var(--dsw-alias-bg-layer-3)\",\n color: \"var(--dsw-alias-label-secondary)\",\n };\n const segBtn = (active: boolean): React.CSSProperties => ({\n ...segStyle,\n background: active ? \"var(--dsw-alias-label-primary)\" : \"transparent\",\n color: active ? \"var(--dsw-alias-bg-layer-3)\" : \"var(--dsw-alias-label-secondary)\",\n transition: \"background .25s ease, color .25s ease\",\n });\n\n // ---- mark nodes (also captured as the ghost overlay on switches) ----\n const labelsNode = (\n <>\n {tickIdx.map((i) => (\n <text\n key={dayKeys[i]}\n x={0}\n y={0}\n textAnchor=\"middle\"\n fontSize={14}\n fill=\"var(--dsw-alias-label-tertiary)\"\n className={enterCls(isNewTick(dayKeys[i]), false)}\n onAnimationEnd={onAnimEnd}\n style={{ transform: `translate(${anchorX(i)}px, ${H - 10}px)`, transition: T_SHIFT }}\n >\n {fmtDay(dayKeys[i])}\n </text>\n ))}\n </>\n );\n\n const marksNode = chartType === \"bar\" ? (\n <>\n {dayKeys.map((k, i) => {\n const dayNew = isNewDay(k);\n let cum = 0;\n const segs = series.map((s) => {\n const v = isHidden(s.model) ? 0 : s.points[i];\n const yTop = yOf(cum + v);\n const h = v > 0 ? Math.max(0.5, yOf(cum) - yTop) : 0;\n cum += v;\n return (\n <rect\n key={s.model}\n x={cxOf(i) - barW / 2}\n y={yTop}\n width={barW}\n height={h}\n fill={colorOf(s.model)}\n className={enterCls(!dayNew && isNewModel(s.model), true)}\n onAnimationEnd={onAnimEnd}\n style={{ transition: T_POS }}\n />\n );\n });\n return (\n <g key={k} opacity={hover?.idx === i ? 1 : 0.8} className={enterCls(dayNew, true)} onAnimationEnd={onAnimEnd} style={{ transition: T_FADE }}>\n {segs}\n </g>\n );\n })}\n </>\n ) : (\n <>\n {series.map((s) => {\n const color = colorOf(s.model);\n const off = isHidden(s.model);\n const modelNew = isNewModel(s.model);\n const pts: Array<[number, number]> = s.points.map((v, i) => [xOf(i), yOf(v)]);\n return (\n <g key={s.model} opacity={off ? 0 : 0.8} className={enterCls(modelNew, false)} onAnimationEnd={onAnimEnd} style={{ transition: T_FADE }}>\n <path d={seriesPathFixed(pts)} fill=\"none\" stroke={color} strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" style={{ transition: T_D }} />\n {/* 用量为 0 的日期不显示点;点按日期键控,跨范围切换时沿 x 轴滑动 */}\n {pts.map(([x, y], i) => (s.points[i] > 0 ? (\n <circle\n key={dayKeys[i]}\n cx={x}\n cy={y}\n r={hover?.idx === i ? 4 : 2}\n fill={color}\n className={enterCls(!modelNew && isNewDay(dayKeys[i]), false)}\n onAnimationEnd={onAnimEnd}\n style={{ transition: T_POINT }}\n />\n ) : null))}\n </g>\n );\n })}\n </>\n );\n\n return (\n <div\n style={{\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n borderRadius: 12,\n overflow: \"hidden\",\n }}\n >\n <style>{ANIM_CSS}</style>\n {/* header: title + chart-type switch (line/bar) + range switch */}\n <div\n style={{\n padding: \"12px 16px 8px\",\n borderBottom: \"1px solid var(--dsw-alias-border-l2)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: 8,\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <span style={{ fontSize: 13, fontWeight: 600, color: \"var(--dsw-alias-label-primary)\" }}>{t(\"trend.title\")}</span>\n <span style={{ fontSize: 12, color: \"var(--dsw-alias-label-tertiary)\" }}>{t(\"trend.hint\")}</span>\n </div>\n <div style={{ display: \"flex\", gap: 8 }}>\n <div style={{ display: \"inline-flex\", border: \"1px solid var(--dsw-alias-border-l2)\", borderRadius: 6, overflow: \"hidden\" }}>\n {([\"line\", \"bar\"] as const).map((ty) => (\n <button key={ty} onClick={() => switchTo({ type: ty })} style={segBtn(chartType === ty)}>\n {ty === \"line\" ? t(\"trend.type.line\") : t(\"trend.type.bar\")}\n </button>\n ))}\n </div>\n <div style={{ display: \"inline-flex\", border: \"1px solid var(--dsw-alias-border-l2)\", borderRadius: 6, overflow: \"hidden\" }}>\n {([7, 30, 90] as const).map((n) => (\n <button\n key={n}\n onClick={() => switchTo({ range: n })}\n style={segBtn(rangeDays === n)}\n >\n {n === 7 ? t(\"trend.range7\") : n === 30 ? t(\"trend.range30\") : t(\"trend.range90\")}\n </button>\n ))}\n </div>\n </div>\n </div>\n\n {/* legend chips: top-10 models of the range, 5 per row, click to toggle.\n Shows the short name (after \"/\") only — usage reads off the chart. */}\n <div style={{ padding: \"10px 16px 4px\" }}>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(5, minmax(0, 1fr))\", gap: 6 }}>\n {series.map((s) => {\n const off = isHidden(s.model);\n return (\n <button\n key={s.model}\n onClick={() => toggle(s.model)}\n title={s.model === OTHER_KEY ? dispName(s.model) : s.model}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n padding: \"2px 8px\",\n borderRadius: 999,\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: \"transparent\",\n cursor: \"pointer\",\n opacity: off ? 0.35 : 1,\n transition: T_FADE,\n fontSize: 12,\n color: \"var(--dsw-alias-label-primary)\",\n minWidth: 0,\n }}\n >\n <span style={{ width: 8, height: 8, borderRadius: 4, background: colorOf(s.model), flexShrink: 0 }} />\n <span style={{ flex: 1, minWidth: 0, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\", textAlign: \"left\", textDecoration: off ? \"line-through\" : \"none\" }}>\n {dispName(s.model)}\n </span>\n </button>\n );\n })}\n </div>\n {series.length === 0 ? null : (\n <div style={{ fontSize: 11, color: \"var(--dsw-alias-label-tertiary)\", marginTop: 4 }}>{t(\"trend.legend.hint\")}</div>\n )}\n </div>\n\n {/* chart + hover tooltip */}\n <div ref={wrapRef} style={{ position: \"relative\", padding: `4px ${CX_PAD}px 12px` }}>\n {topModels.length === 0 ? (\n <div style={{ padding: 24, textAlign: \"center\", fontSize: 14, color: \"var(--dsw-alias-label-tertiary)\" }}>{t(\"trend.empty\")}</div>\n ) : (\n <svg\n viewBox={`0 0 ${W} ${H}`}\n width=\"100%\"\n style={{ display: \"block\" }}\n role=\"img\"\n aria-label={t(\"trend.title\")}\n onMouseMove={onMove}\n onMouseLeave={() => setHover(null)}\n >\n {/* y grid + labels (path/transform so axis rescaling morphs smoothly) */}\n {[0, 0.25, 0.5, 0.75, 1].map((f) => {\n const y = PAD.top + (1 - f) * plotH;\n return (\n <g key={f}>\n <path\n d={`M ${PAD.left} ${y} L ${W - PAD.right} ${y}`}\n fill=\"none\"\n stroke=\"var(--dsw-alias-border-l2)\"\n strokeWidth={1}\n strokeDasharray={f === 0 ? undefined : \"3 3\"}\n style={{ transition: T_D }}\n />\n <text\n x={0}\n y={0}\n textAnchor=\"end\"\n fontSize={14}\n fill=\"var(--dsw-alias-label-tertiary)\"\n style={{ transform: `translate(${PAD.left - 8}px, ${y + 5}px)`, transition: T_SHIFT }}\n >\n {formatTokensShort(yMax * f)}\n </text>\n </g>\n );\n })}\n\n {/* ghost overlay: the previous layout's marks, collapsing out */}\n {ghost ? (\n <>\n <g className={ghost.type === \"bar\" ? \"dtp-ghost-bars\" : \"dtp-ghost-lines\"}>{ghost.marks}</g>\n <g className=\"dtp-ghost-lines\">{ghost.labels}</g>\n </>\n ) : null}\n\n {labelsNode}\n {marksNode}\n\n {/* hovered column guide */}\n {hover != null ? (\n <path\n d={`M ${anchorX(hover.idx)} ${PAD.top} L ${anchorX(hover.idx)} ${PAD.top + plotH}`}\n fill=\"none\"\n stroke=\"var(--dsw-alias-label-tertiary)\"\n strokeWidth={1}\n strokeDasharray=\"4 3\"\n opacity={0.6}\n style={{ transition: T_D }}\n />\n ) : null}\n\n {/* all models hidden hint */}\n {visible.length === 0 ? (\n <text x={W / 2} y={PAD.top + plotH / 2} textAnchor=\"middle\" fontSize={13} fill=\"var(--dsw-alias-label-tertiary)\">\n {t(\"trend.legend.hint\")}\n </text>\n ) : null}\n </svg>\n )}\n\n {/* compact translucent tooltip: date / day total / per-model totals, beside the cursor */}\n {hover != null && topModels.length > 0 ? (\n <div\n style={{\n position: \"absolute\",\n left: tipLeft,\n top: tipTop,\n width: tipW,\n opacity: 0.7,\n pointerEvents: \"none\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n border: \"1px solid var(--dsw-alias-border-l2)\",\n borderRadius: 8,\n boxShadow: \"0 6px 18px rgba(0,0,0,0.25)\",\n padding: \"6px 10px\",\n fontSize: 11,\n lineHeight: 1.5,\n color: \"var(--dsw-alias-label-primary)\",\n zIndex: 5,\n }}\n >\n <div style={{ fontWeight: 600, fontSize: 12, marginBottom: 4 }}>{fmtDayLong(dayKeys[hover.idx])}</div>\n <div style={{ display: \"flex\", justifyContent: \"space-between\", gap: 10, fontWeight: 600 }}>\n <span>{isEn ? \"Total\" : \"消耗总量\"}</span>\n <span>{formatTokensShort(hoverTotal)} tokens</span>\n </div>\n <div style={{ borderTop: \"1px solid var(--dsw-alias-border-l2)\", margin: \"4px 0\" }} />\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 3 }}>\n {hoverRows.map((r) => (\n <div key={r.model} style={{ display: \"flex\", alignItems: \"center\", gap: 6 }}>\n <span style={{ width: 7, height: 7, borderRadius: 4, background: r.color, flexShrink: 0 }} />\n <span style={{ flex: 1, minWidth: 0, overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" }} title={r.model}>\n {dispName(r.model)}\n </span>\n <span style={{ fontWeight: 500, whiteSpace: \"nowrap\" }}>{formatTokensShort(r.value)} tokens</span>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\nexport default TrendChart;\n","export const zh: Record<string, string> = {\n \"nav\": \"Token Pulse\",\n \"heatmap.title\": \"Token Pulse\",\n \"heatmap.subtitle\": \"基于本地会话日志统计 Token 用量,北京时间自然日分桶,零网络零计费。首次同步后持久化,删除会话不丢历史。\",\n \"heatmap.empty\": \"暂无用量数据,开始一次对话后这里会出现热图。\",\n \"heatmap.legend.less\": \"少\",\n \"heatmap.legend.more\": \"多\",\n \"heatmap.tooltip.tokens\": \"{count} tokens\",\n \"heatmap.tooltip.none\": \"无用量\",\n \"heatmap.refresh\": \"刷新\",\n \"heatmap.refreshing\": \"刷新中…\",\n \"heatmap.lastRefresh\": \"上次刷新:{time}\",\n \"heatmap.autoRefresh\": \"自动刷新\",\n \"heatmap.autoRefresh.off\": \"关闭\",\n \"heatmap.autoRefresh.hint\": \"设置自动刷新间隔(分钟)\",\n \"heatmap.reset\": \"重置历史\",\n \"heatmap.reset.confirm\": \"确定重置所有历史数据?此操作不可撤销。\",\n \"heatmap.reset.done\": \"已重置\",\n \"view.week\": \"周\",\n \"view.month\": \"月\",\n \"view.quarter\": \"季度\",\n \"view.year\": \"年\",\n \"view.model\": \"模型\",\n \"view.provider\": \"供应商\",\n \"stats.today\": \"今日\",\n \"stats.week\": \"本周\",\n \"stats.month\": \"本月\",\n \"stats.all\": \"累计\",\n \"stats.count\": \"{count} 次\",\n \"model.top5\": \"Top 5 模型\",\n \"model.top5.hint\": \"按 Token 用量排序\",\n \"model.others\": \"其它\",\n \"model.winner\": \"当日最常用模型\",\n \"model.none\": \"暂无模型数据\",\n \"model.tokens\": \"{count} tokens\",\n \"provider.top5\": \"Top 5 供应商\",\n \"provider.winner\": \"当日最常用供应商\",\n \"trend.title\": \"用量趋势\",\n \"trend.hint\": \"按模型的每日 Token 用量\",\n \"trend.range7\": \"近一周\",\n \"trend.range30\": \"近一月\",\n \"trend.range90\": \"近90天\",\n \"trend.type.line\": \"折线\",\n \"trend.type.bar\": \"柱状\",\n \"trend.empty\": \"所选范围内暂无数据\",\n \"trend.legend.hint\": \"点击图例可显示/隐藏\",\n \"common.tokens\": \"tokens\",\n};\n\nexport const en: Record<string, string> = {\n \"nav\": \"Token Pulse\",\n \"heatmap.title\": \"Token Pulse\",\n \"heatmap.subtitle\": \"Local token usage from session logs, bucketed by Asia/Shanghai, no network or billing. Synced once then persisted, surviving session deletion.\",\n \"heatmap.empty\": \"No usage yet. Start a conversation and the heatmap will appear here.\",\n \"heatmap.legend.less\": \"Less\",\n \"heatmap.legend.more\": \"More\",\n \"heatmap.tooltip.tokens\": \"{count} tokens\",\n \"heatmap.tooltip.none\": \"No usage\",\n \"heatmap.refresh\": \"Refresh\",\n \"heatmap.refreshing\": \"Refreshing…\",\n \"heatmap.lastRefresh\": \"Last refresh: {time}\",\n \"heatmap.autoRefresh\": \"Auto refresh\",\n \"heatmap.autoRefresh.off\": \"Off\",\n \"heatmap.autoRefresh.hint\": \"Auto refresh interval (minutes)\",\n \"heatmap.reset\": \"Reset history\",\n \"heatmap.reset.confirm\": \"Reset all historical data? This cannot be undone.\",\n \"heatmap.reset.done\": \"Reset done\",\n \"view.week\": \"Week\",\n \"view.month\": \"Month\",\n \"view.quarter\": \"Quarter\",\n \"view.year\": \"Year\",\n \"view.model\": \"Model\",\n \"view.provider\": \"Provider\",\n \"stats.today\": \"Today\",\n \"stats.week\": \"This week\",\n \"stats.month\": \"This month\",\n \"stats.all\": \"All time\",\n \"stats.count\": \"{count} turns\",\n \"model.top5\": \"Top 5 Models\",\n \"model.top5.hint\": \"By token usage\",\n \"model.others\": \"Others\",\n \"model.winner\": \"Daily winner (model)\",\n \"model.none\": \"No model data\",\n \"model.tokens\": \"{count} tokens\",\n \"provider.top5\": \"Top 5 Providers\",\n \"provider.winner\": \"Daily winner (provider)\",\n \"trend.title\": \"Usage Trend\",\n \"trend.hint\": \"Daily token usage per model\",\n \"trend.range7\": \"7 days\",\n \"trend.range30\": \"30 days\",\n \"trend.range90\": \"90 days\",\n \"trend.type.line\": \"Lines\",\n \"trend.type.bar\": \"Bars\",\n \"trend.empty\": \"No data in this range\",\n \"trend.legend.hint\": \"Click legend to toggle\",\n \"common.tokens\": \"tokens\",\n};\n\nexport type LocaleDict = typeof zh;\n","import * as React from \"react\";\nimport { aggregate, type Aggregated, type DayAgg } from \"../aggregation.ts\";\nimport { toDayKey } from \"../date-bucket.ts\";\n\nconst LS_INTERVAL_KEY = \"dsh-token-pulse:autoRefreshMinutes\";\n\nexport function getAutoRefreshMinutes(): number {\n try {\n const v = localStorage.getItem(LS_INTERVAL_KEY);\n if (v === null) return 10;\n const n = Number(v);\n if (!Number.isFinite(n) || n < 0) return 10;\n return Math.min(1440, Math.max(0, Math.round(n)));\n } catch {\n return 10;\n }\n}\n\nexport function setAutoRefreshMinutes(minutes: number) {\n try {\n localStorage.setItem(LS_INTERVAL_KEY, String(minutes));\n } catch {}\n}\n\nconst API_TIMEOUT_MS = 5000;\n\nasync function fetchFromApi(): Promise<Aggregated | null> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), API_TIMEOUT_MS);\n try {\n const res = await fetch(\"/api/dsh-token-pulse/daily.json\", { cache: \"no-store\", signal: ctrl.signal });\n if (!res.ok) return null;\n const json = await res.json();\n if (!json || !Array.isArray(json.days)) return null;\n // Host still scanning disk (init in progress): signal \"not ready\" so the\n // caller retries shortly instead of caching a partial snapshot.\n if ((json as any).ready === false) return { __notReady: true } as any;\n const byDay = new Map<string, DayAgg>();\n for (const d of json.days) {\n byDay.set(d.dayKey, {\n dayKey: d.dayKey,\n totalTokens: d.totalTokens ?? 0,\n uncachedInputTokens: d.uncachedInputTokens ?? 0,\n cacheReadTokens: d.cacheReadTokens ?? 0,\n cacheWriteTokens: d.cacheWriteTokens ?? 0,\n outputTokens: d.outputTokens ?? 0,\n count: d.count ?? 0,\n byModel: new Map(Object.entries(d.byModel ?? {})) as Map<string, number>,\n byProvider: new Map(Object.entries(d.byProvider ?? {})) as Map<string, number>,\n hourlyTokens: Array.isArray(d.hourlyTokens) && d.hourlyTokens.length === 24 ? d.hourlyTokens : new Array(24).fill(0),\n winnerModel: d.winnerModel ?? null,\n winnerProvider: d.winnerProvider ?? null,\n });\n }\n const totals = json.totals ?? { today: 0, thisWeek: 0, thisMonth: 0, all: 0 };\n const topModels = Array.isArray(json.topModels) ? json.topModels.map((x: any) => ({ model: x.name ?? x.model, tokens: x.tokens })) : [];\n const topProviders = Array.isArray(json.topProviders) ? json.topProviders.map((x: any) => ({ provider: x.name ?? x.provider, tokens: x.tokens })) : [];\n const nowMs = Date.now();\n // Reuse aggregation helpers by building a synthetic Aggregated that delegates to byDay\n const fakeAgg = aggregate([], nowMs);\n (fakeAgg as any).byDay = byDay;\n (fakeAgg as any).totals = totals;\n (fakeAgg as any).topModels = topModels;\n (fakeAgg as any).topProviders = topProviders;\n (fakeAgg as any).top5 = topModels;\n // Patch window helpers to use our byDay\n const { weekRangeFor, monthRangeFor, quarterRangeFor, yearRangeFor, listDaysInRange } = await import(\"../date-bucket.ts\");\n const resolveDay = (k: string) => byDay.get(k) ?? { dayKey: k, totalTokens: 0, uncachedInputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, outputTokens: 0, count: 0, byModel: new Map(), byProvider: new Map(), hourlyTokens: new Array(24).fill(0), winnerModel: null, winnerProvider: null };\n const resolveRange = (s: string, e: string) => listDaysInRange(s, e).map(resolveDay);\n (fakeAgg as any).weekDays = (k: string) => resolveRange(...weekRangeFor(k));\n (fakeAgg as any).monthDays = (k: string) => resolveRange(...monthRangeFor(k));\n (fakeAgg as any).quarterDays = (k: string) => resolveRange(...quarterRangeFor(k));\n (fakeAgg as any).yearDays = (k: string) => resolveRange(...yearRangeFor(k));\n (fakeAgg as any).top5InWindow = (days: DayAgg[]) => {\n const m = new Map<string, number>();\n for (const d of days) for (const [model, tokens] of d.byModel) m.set(model, (m.get(model) ?? 0) + tokens);\n return [...m.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([model, tokens]) => ({ model, tokens }));\n };\n (fakeAgg as any).topProvidersInWindow = (days: DayAgg[]) => {\n const m = new Map<string, number>();\n for (const d of days) for (const [provider, tokens] of d.byProvider) m.set(provider, (m.get(provider) ?? 0) + tokens);\n return [...m.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([provider, tokens]) => ({ provider, tokens }));\n };\n return fakeAgg as Aggregated;\n } catch {\n return null;\n } finally {\n clearTimeout(timer);\n }\n}\n\n// Module-level cache that survives SettingsSection remounts (opening the card\n// again unmounts/remounts the component). Reopening renders the cached snapshot\n// immediately (no blank flash); a real fetch happens on the refresh button, on\n// the auto-refresh interval while mounted, or on (re)mount when the cache is\n// older than the configured interval — so toggling the panel open/closed still\n// picks up fresh data once the interval has elapsed.\nlet _cache: { agg: Aggregated; label: string; at: number } | null = null;\n\nexport function useHeatmapData(ctx: any | null, refreshMs?: number, manualTick?: number) {\n const [data, setData] = React.useState<Aggregated | null>(() => _cache?.agg ?? null);\n const [refreshing, setRefreshing] = React.useState(false);\n const [lastRefresh, setLastRefresh] = React.useState<string | null>(() => _cache?.label ?? null);\n // M1 fix: track + cancel the notReady retry so an unmounted component can't\n // leave an orphan retry chain polling every 2s until the host reports ready.\n const cancelledRef = React.useRef(false);\n const retryTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n const mountedRef = React.useRef(false);\n\n const intervalMs = React.useMemo(() => {\n if (refreshMs !== undefined) return refreshMs;\n const mins = getAutoRefreshMinutes();\n return mins === 0 ? 0 : mins * 60 * 1000;\n }, [refreshMs, manualTick]);\n\n const fetchData = React.useCallback(async () => {\n setRefreshing(true);\n const commit = (agg: Aggregated) => {\n const label = new Date().toLocaleString();\n _cache = { agg, label, at: Date.now() };\n setData(agg);\n setLastRefresh(label);\n };\n try {\n const apiData = await fetchFromApi();\n if (apiData && !(apiData as any).__notReady) {\n commit(apiData);\n return;\n }\n if (apiData && (apiData as any).__notReady) {\n // Host init still scanning disk: retry shortly; keep old data showing.\n // Cancel any prior scheduled retry (prevents stacking chains when a\n // manual refresh or interval fires while a retry is already pending),\n // and skip scheduling if this instance has been unmounted (M1).\n if (retryTimerRef.current) clearTimeout(retryTimerRef.current);\n if (!cancelledRef.current) {\n retryTimerRef.current = setTimeout(() => { void fetchData(); }, 2000);\n }\n setRefreshing(false);\n return;\n }\n const store = ctx?.get?.(\"heatmapStore\") ?? (typeof window !== \"undefined\" ? (window as any).__dsh_heatmapStore : null);\n if (store?.refresh) await store.refresh();\n if (store?.getAggregated) {\n commit(store.getAggregated());\n return;\n }\n const snap = typeof window !== \"undefined\" ? (window as any).__dsh_heatmapSnapshot : null;\n if (snap?.byDay && snap?.totals) {\n commit(snap);\n return;\n }\n } catch {\n // keep previous (and cache) on failure\n } finally {\n setRefreshing(false);\n }\n // No successful source this time: only fall back to an empty snapshot if we\n // have nothing cached — never blank out a card that already has data.\n if (!_cache) setData((prev) => prev ?? aggregate([], Date.now()));\n }, [ctx]);\n\n // Fetch policy: on first mount fetch when nothing is cached OR the cached\n // snapshot is older than the configured interval (so reopening the panel\n // after the interval elapses still refreshes — the setInterval alone wouldn't,\n // because it resets on every remount). If auto-refresh is off (intervalMs 0),\n // only fetch on a cold cache. Any later `manualTick` change forces a fetch.\n React.useEffect(() => {\n if (!mountedRef.current) {\n mountedRef.current = true;\n const stale = !_cache || (intervalMs > 0 && Date.now() - _cache.at >= intervalMs);\n if (stale) void fetchData();\n return;\n }\n void fetchData();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fetchData, manualTick]);\n\n // M1 fix: on (re)mount clear any cancelled flag from a previous cycle, and on\n // unmount mark cancelled + drop the pending retry so the chain terminates.\n React.useEffect(() => {\n cancelledRef.current = false;\n return () => {\n cancelledRef.current = true;\n if (retryTimerRef.current) {\n clearTimeout(retryTimerRef.current);\n retryTimerRef.current = null;\n }\n };\n }, []);\n\n // Auto-refresh only on the configured interval (no visibility-triggered\n // refetch — per user request, refresh happens only on button + interval).\n React.useEffect(() => {\n if (intervalMs === 0) return;\n const id = setInterval(fetchData, intervalMs);\n return () => {\n clearInterval(id);\n };\n }, [fetchData, intervalMs]);\n\n const refresh = React.useCallback(() => fetchData(), [fetchData]);\n\n return { data, refreshing, lastRefresh, refresh, intervalMs };\n}\n\nexport function useHeatmapView(aggregated: Aggregated | null, initial: import(\"./HeatmapGrid.tsx\").ViewKind = \"month\") {\n const [view, setView] = React.useState(initial);\n const [anchor, setAnchor] = React.useState(() => toDayKey(Date.now()));\n\n const days: DayAgg[] | null = React.useMemo(() => {\n if (!aggregated) return null;\n switch (view) {\n case \"week\":\n return aggregated.weekDays(anchor);\n case \"month\":\n return aggregated.monthDays(anchor);\n case \"quarter\":\n return aggregated.quarterDays(anchor);\n case \"year\":\n return aggregated.yearDays(anchor);\n }\n }, [aggregated, view, anchor]);\n\n const topModels = React.useMemo(() => {\n if (!aggregated || !days) return aggregated?.topModels ?? [];\n return aggregated.top5InWindow(days);\n }, [aggregated, days]);\n\n const topProviders = React.useMemo(() => {\n if (!aggregated || !days) return aggregated?.topProviders ?? [];\n return aggregated.topProvidersInWindow(days);\n }, [aggregated, days]);\n\n return { view, setView, anchor, setAnchor, days, topModels, topProviders };\n}\n","declare const __PLUGIN_VERSION__: string;\n\nimport * as React from \"react\";\nimport { StatsCards } from \"./StatsCards.tsx\";\nimport { HeatmapGrid, type ViewKind, type LevelThresholds, DEFAULT_THRESHOLDS } from \"./HeatmapGrid.tsx\";\nimport { ModelTop5 } from \"./ModelTop5.tsx\";\nimport { TrendChart } from \"./TrendChart.tsx\";\nimport { en as enDict } from \"./locales.ts\";\nimport { useHeatmapData, useHeatmapView, getAutoRefreshMinutes, setAutoRefreshMinutes } from \"./hooks.ts\";\nimport type { DayAgg } from \"../aggregation.ts\";\n\ntype SettingsSectionProps = {\n t: (key: string, params?: Record<string, any>) => string;\n ctx?: any;\n days?: DayAgg[];\n totals?: any;\n top5?: any;\n};\n\nexport function SettingsSection({ t, ctx, days: injectedDays, totals: injectedTotals, top5: injectedTop5 }: SettingsSectionProps) {\n const [tick, setTick] = React.useState(0);\n const { data: aggregated, refreshing, lastRefresh, refresh } = useHeatmapData(ctx ?? null, undefined, tick);\n const { view, setView, anchor, setAnchor, days: computedDays, topModels: computedTopModels, topProviders: computedTopProviders } = useHeatmapView(aggregated);\n const [topMode, setTopMode] = React.useState<\"model\" | \"provider\">(\"model\");\n const [selectedKey, setSelectedKey] = React.useState<string | null>(null);\n const [intervalMins, setIntervalMins] = React.useState(() => getAutoRefreshMinutes());\n const [lang, setLang] = React.useState<\"zh\" | \"en\">(() => {\n try { const v = localStorage.getItem(\"dsh-token-pulse:lang\"); return v === \"en\" ? \"en\" : \"zh\"; } catch { return \"zh\"; }\n });\n // 分档阈值设置:>= high 恒为深绿(4档),< low 恒为浅绿(1档);localStorage 持久化(tokens)\n // UI 上以 M tokens 为单位显示与输入\n const LS_TH_KEY = \"dsh-token-pulse:thresholds\";\n const [thresholds, setThresholds] = React.useState<LevelThresholds>(() => {\n try {\n const raw = localStorage.getItem(LS_TH_KEY);\n if (!raw) return DEFAULT_THRESHOLDS;\n const parsed = JSON.parse(raw);\n const high = Number(parsed?.high) || 0;\n const low = Number(parsed?.low) || 0;\n return { high: Math.max(0, high), low: Math.max(0, low) };\n } catch { return DEFAULT_THRESHOLDS; }\n });\n // 弹出式设置窗口(⋯ 打开),点遮罩/完成关闭;内部不再互相退出\n const [settingsOpen, setSettingsOpen] = React.useState(false);\n const applyThresholdsM = (highM: number, lowM: number) => {\n const next = { high: Math.max(0, highM) * 1_000_000, low: Math.max(0, lowM) * 1_000_000 };\n setThresholds(next);\n try { localStorage.setItem(LS_TH_KEY, JSON.stringify(next)); } catch {} // ← was missing: edits never persisted\n };\n const thInM = { high: thresholds.high / 1_000_000, low: thresholds.low / 1_000_000 };\n const applyThresholds = (t: LevelThresholds) => {\n setThresholds(t);\n try { localStorage.setItem(LS_TH_KEY, JSON.stringify(t)); } catch {}\n };\n // ⋯ 菜单:显式开关 + 点击外部自动收回\n\n const days = injectedDays ?? computedDays;\n // 趋势图用全量历史(aggregated.byDay),与上面的周/月视图解耦:\n // days 是按视图窗口裁剪的,月视图下看不到上月的天\n const allDays: DayAgg[] = React.useMemo(() => {\n if (aggregated?.byDay) return [...aggregated.byDay.values()];\n return days ?? [];\n }, [aggregated, days]);\n const totals = injectedTotals ?? aggregated?.totals;\n const viewTopModelsRaw = computedTopModels.length ? computedTopModels : (aggregated?.topModels ?? []);\n const viewTopProvidersRaw = computedTopProviders.length ? computedTopProviders : (aggregated?.topProviders ?? []);\n\n // If a day is selected, show that day's Top 5 instead of the view's\n let viewTopModels: typeof viewTopModelsRaw = viewTopModelsRaw;\n let viewTopProviders: typeof viewTopProvidersRaw = viewTopProvidersRaw;\n let topTitleExtra = \"\";\n if (selectedKey && aggregated) {\n const sel = aggregated.byDay.get(selectedKey);\n if (sel) {\n viewTopModels = [...sel.byModel.entries()].sort((a,b)=>b[1]-a[1]).slice(0,5).map(([model,tokens])=>({model,tokens}));\n viewTopProviders = [...sel.byProvider.entries()].sort((a,b)=>b[1]-a[1]).slice(0,5).map(([provider,tokens])=>({provider,tokens}));\n topTitleExtra = ` · ${selectedKey}`;\n }\n }\n const viewTopModelsNamed = viewTopModels.map((x) => ({ name: x.model, tokens: x.tokens }));\n const viewTopProvidersNamed = viewTopProviders.map((x) => ({ name: (x as any).provider ?? (x as any).name, tokens: x.tokens }));\n\n // 「其它」汇总:同一统计口径下,Top 5 之外的所有模型/供应商用量之和\n const othersScope = selectedKey && aggregated?.byDay.has(selectedKey)\n ? [aggregated.byDay.get(selectedKey)!]\n : (days ?? []);\n const sumField = (field: \"byModel\" | \"byProvider\") => {\n let total = 0;\n for (const d of othersScope) for (const [, v] of d[field]) total += v;\n return total;\n };\n const modelOthersTokens = sumField(\"byModel\") - viewTopModels.reduce((a, x) => a + x.tokens, 0);\n const providerOthersTokens = sumField(\"byProvider\") - viewTopProviders.reduce((a, x) => a + x.tokens, 0);\n\n const injectedTop = injectedTop5;\n const hasData = totals && (totals.today > 0 || totals.thisWeek > 0 || totals.thisMonth > 0 || totals.all > 0);\n\n const tt = (key: string, params?: Record<string, any>) => {\n // lang-aware: prefer current lang's dictionary, fallback to t()\n // For now t() is already bound to the plugin's locale (zh by default). We override a few keys manually.\n const zhEn: Record<string, {zh:string,en:string}> = {\n \"heatmap.lang.zh\": { zh: \"中文\", en: \"中文\" },\n \"heatmap.lang.en\": { zh: \"English\", en: \"English\" },\n \"heatmap.lang.label\": { zh: \"语言\", en: \"Language\" },\n \"heatmap.dayDetail\": { zh: `${selectedKey ?? \"\"} · 当日 Top 5`, en: `${selectedKey ?? \"\"} · Top 5 of the day` },\n \"heatmap.clearSelection\": { zh: \"清除选择\", en: \"Clear\" },\n };\n const entry = zhEn[key];\n if (entry) {\n let s = entry[lang];\n if (params) for (const [k,v] of Object.entries(params)) s = s.replace(`{${k}}`, String(v));\n return s;\n }\n return t(key, params);\n };\n\n const handleRefresh = async () => {\n // refresh() already pulls + updates the module cache; no setTick (which\n // would trigger a second fetch).\n await refresh();\n };\n\n const handleIntervalChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n const v = Number(e.target.value);\n setAutoRefreshMinutes(v);\n setIntervalMins(v);\n setTick((x) => x + 1);\n };\n\n const handleLangChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n const v = e.target.value as \"zh\" | \"en\";\n setLang(v);\n try { localStorage.setItem(\"dsh-token-pulse:lang\", v); } catch {}\n };\n\n const handleReset = () => {\n if (!confirm(t(\"heatmap.reset.confirm\"))) return;\n const store = ctx?.get?.(\"heatmapStore\") ?? (typeof window !== \"undefined\" ? (window as any).__dsh_heatmapStore : null);\n if (store?.clearPersisted) {\n store.clearPersisted();\n setTick((x) => x + 1);\n }\n };\n\n const handleViewChange = (v: typeof view) => {\n setSelectedKey(null);\n setView(v);\n };\n\n const handleSelect = (k: string | null) => setSelectedKey(k);\n\n return (\n <section aria-labelledby=\"heatmap-title\" style={{ display: \"flex\", flexDirection: \"column\", gap: 16 }}>\n <div style={{ display: \"flex\", alignItems: \"flex-start\", justifyContent: \"space-between\", gap: 12 }}>\n <div>\n <h2 id=\"heatmap-title\" style={{ margin: 0, fontSize: 16, fontWeight: 600, color: \"var(--dsw-alias-label-primary)\" }}>\n {t(\"heatmap.title\")}\n <span style={{ marginLeft: 8, fontSize: 11, fontWeight: 400, color: \"var(--dsw-alias-label-tertiary)\", verticalAlign: \"middle\" }}>\n v{__PLUGIN_VERSION__}\n </span>\n </h2>\n <p style={{ margin: \"4px 0 0\", fontSize: 13, color: \"var(--dsw-alias-label-tertiary)\", lineHeight: 1.5 }}>\n {lang === \"en\" ? \"Token usage from local session logs, bucketed by Asia/Shanghai. Synced once then persisted — deleting sessions keeps history.\" : t(\"heatmap.subtitle\")}\n </p>\n </div>\n <label style={{ display: \"flex\", alignItems: \"center\", gap: 6, fontSize: 12, color: \"var(--dsw-alias-label-secondary)\", flexShrink: 0 }}>\n {tt(\"heatmap.lang.label\")}\n <select value={lang} onChange={handleLangChange} style={{ padding: \"4px 8px\", fontSize: 12, borderRadius: 6, border: \"1px solid var(--dsw-alias-border-l2)\", background: \"var(--dsw-alias-bg-layer-3)\", color: \"var(--dsw-alias-label-primary)\" }}>\n <option value=\"zh\">{tt(\"heatmap.lang.zh\")}</option>\n <option value=\"en\">{tt(\"heatmap.lang.en\")}</option>\n </select>\n </label>\n </div>\n\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8, flexWrap: \"wrap\" }}>\n <button\n onClick={handleRefresh}\n disabled={refreshing}\n style={{\n padding: \"6px 14px\",\n fontSize: 13,\n borderRadius: 8,\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: refreshing ? \"var(--dsw-alias-bg-layer-2)\" : \"var(--dsw-alias-bg-layer-3)\",\n color: \"var(--dsw-alias-label-primary)\",\n cursor: refreshing ? \"wait\" : \"pointer\",\n }}\n >\n {lang === \"en\" ? (refreshing ? \"Refreshing…\" : \"Refresh\") : (refreshing ? t(\"heatmap.refreshing\") : t(\"heatmap.refresh\"))}\n </button>\n <span style={{ fontSize: 12, color: \"var(--dsw-alias-label-tertiary)\" }}>\n {lastRefresh ? (lang === \"en\" ? `Last refresh: ${lastRefresh}` : t(\"heatmap.lastRefresh\", { time: lastRefresh })) : \"\"}\n </span>\n <span style={{ flex: 1 }} />\n <label style={{ display: \"flex\", alignItems: \"center\", gap: 6, fontSize: 12, color: \"var(--dsw-alias-label-secondary)\" }}>\n {lang === \"en\" ? \"Auto refresh\" : t(\"heatmap.autoRefresh\")}\n <select\n value={intervalMins}\n onChange={handleIntervalChange}\n title={t(\"heatmap.autoRefresh.hint\")}\n style={{\n padding: \"4px 8px\",\n fontSize: 12,\n borderRadius: 6,\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n color: \"var(--dsw-alias-label-primary)\",\n }}\n >\n <option value={0}>{t(\"heatmap.autoRefresh.off\")}</option>\n <option value={5}>5 min</option>\n <option value={10}>10 min</option>\n <option value={30}>30 min</option>\n <option value={60}>60 min</option>\n </select>\n </label>\n <button\n onClick={() => setSettingsOpen(true)}\n aria-haspopup=\"dialog\"\n style={{ listStyle: \"none\", cursor: \"pointer\", padding: \"2px 8px\", fontSize: 13, color: \"var(--dsw-alias-label-tertiary)\", opacity: 0.7, border: \"none\", background: \"transparent\" }}\n title={lang === \"en\" ? \"Settings\" : \"设置\"}\n >⋯</button>\n\n {settingsOpen ? (\n <div\n onClick={() => setSettingsOpen(false)} // 点遮罩关闭\n style={{\n position: \"fixed\", inset: 0, zIndex: 50,\n background: \"rgba(0,0,0,0.35)\",\n display: \"flex\", alignItems: \"center\", justifyContent: \"center\",\n }}\n >\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n onClick={(e) => e.stopPropagation()} // 内容区阻止冒泡,不关窗\n style={{\n background: \"var(--dsw-alias-bg-layer-3)\",\n border: \"1px solid var(--dsw-alias-border-l2)\",\n borderRadius: 12,\n minWidth: 340,\n maxWidth: \"90vw\",\n boxShadow: \"0 8px 24px rgba(0,0,0,0.2)\",\n padding: 16,\n display: \"flex\", flexDirection: \"column\", gap: 12,\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\" }}>\n <span style={{ fontSize: 14, fontWeight: 600, color: \"var(--dsw-alias-label-primary)\" }}>\n {lang === \"en\" ? \"Pulse Settings\" : \"Pulse 设置\"}\n </span>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 10 }}>\n <button\n onClick={() => { if (confirm(lang === \"en\" ? \"Reset all historical data? This cannot be undone.\" : \"确定重置所有历史数据?此操作不可撤销。\")) { handleReset(); } }}\n title={lang === \"en\" ? \"Reset history (advanced)\" : \"重置历史(高级)\"}\n style={{ border: \"none\", background: \"transparent\", fontSize: 11, cursor: \"pointer\", color: \"var(--dsw-alias-label-tertiary)\", opacity: 0.55, textDecoration: \"underline\" }}\n >\n {lang === \"en\" ? \"Reset history…\" : \"重置历史…\"}\n </button>\n <button onClick={() => setSettingsOpen(false)} aria-label=\"close\" style={{ border: \"none\", background: \"transparent\", fontSize: 16, cursor: \"pointer\", color: \"var(--dsw-alias-label-tertiary)\" }}>✕</button>\n </div>\n </div>\n\n {/* 分档阈值 */}\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 8 }}>\n <div style={{ fontSize: 12, fontWeight: 600, color: \"var(--dsw-alias-label-secondary)\" }}>\n {lang === \"en\" ? \"Level thresholds (M tokens)\" : \"分档阈值(M tokens)\"}\n </div>\n {([\n { key: \"high\" as const, label: lang === \"en\" ? \"Deep green ≥ (M)\" : \"深绿阈值 ≥(M)\" },\n { key: \"low\" as const, label: lang === \"en\" ? \"Light green < (M)\" : \"浅绿阈值 <(M)\" },\n ]).map(({ key, label }) => (\n <label key={key} style={{ display: \"flex\", flexDirection: \"column\", gap: 2, fontSize: 11, color: \"var(--dsw-alias-label-secondary)\" }}>\n {label}\n <input\n type=\"number\"\n min={0}\n step={10}\n value={thInM[key]}\n onChange={(e) => applyThresholdsM(\n key === \"high\" ? Math.max(0, Number(e.target.value) || 0) : thInM.high,\n key === \"low\" ? Math.max(0, Number(e.target.value) || 0) : thInM.low,\n )}\n placeholder=\"0 = off\"\n style={{ padding: \"6px 10px\", fontSize: 13, borderRadius: 6, border: \"1px solid var(--dsw-alias-border-l2)\", background: \"var(--dsw-alias-bg-layer-3)\", color: \"var(--dsw-alias-label-primary)\" }}\n />\n </label>\n ))}\n <div style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\" }}>\n <button onClick={() => applyThresholds(DEFAULT_THRESHOLDS)} style={{ padding: \"4px 10px\", fontSize: 11, borderRadius: 5, border: \"1px solid var(--dsw-alias-border-l2)\", background: \"var(--dsw-alias-bg-layer-3)\", cursor: \"pointer\" }}>{lang === \"en\" ? \"Defaults (100M / 10M)\" : \"恢复默认(100M / 10M)\"}</button>\n <span style={{ fontSize: 10, color: \"var(--dsw-alias-label-tertiary)\" }}>0 = off</span>\n </div>\n </div>\n\n <button onClick={() => setSettingsOpen(false)} style={{ width: \"100%\", padding: \"8px 10px\", fontSize: 13, borderRadius: 8, border: \"1px solid var(--dsw-alias-border-l2)\", background: \"var(--dsw-alias-bg-layer-3)\", color: \"var(--dsw-alias-label-primary)\", cursor: \"pointer\" }}>\n {lang === \"en\" ? \"Done\" : \"完成\"}\n </button>\n </div>\n </div>\n ) : null}\n </div>\n\n {view === \"week\" || view === \"month\" ? (\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8, justifyContent: \"space-between\" }}>\n <button onClick={() => setAnchor((a: string) => { const d = new Date(a + \"T12:00:00+08:00\"); if (view === \"week\") d.setDate(d.getDate() - 7); else d.setMonth(d.getMonth() - 1); const ms = d.getTime(); return new Date(ms).toLocaleDateString(\"en-CA\", { timeZone: \"Asia/Shanghai\" } as any); })} style={{ padding: \"4px 10px\", fontSize: 12, borderRadius: 6, border: \"1px solid var(--dsw-alias-border-l2)\", background: \"var(--dsw-alias-bg-layer-3)\", cursor: \"pointer\" }}>{lang === \"en\" ? \"‹ Prev\" : \"‹ 上一\"}{view === \"week\" ? (lang===\"en\"?\" Week\":\"周\") : (lang===\"en\"?\" Month\":\"月\")}</button>\n <span style={{ fontSize: 12, color: \"var(--dsw-alias-label-secondary)\", fontWeight: 500 }}>\n {view === \"week\" ? (()=>{ const a = anchor; const d = new Date(a+\"T12:00:00+08:00\"); const dow=(d.getDay()+6)%7; const mon=new Date(d); mon.setDate(d.getDate()-dow); const sun=new Date(mon); sun.setDate(mon.getDate()+6); const fmt=(x:Date)=> `${x.getMonth()+1}/${x.getDate()}`; return lang===\"en\" ? `Week of ${fmt(mon)} - ${fmt(sun)}` : `${mon.getMonth()+1}月${mon.getDate()}日 - ${sun.getMonth()+1}月${sun.getDate()}日`; })() : `${Number(anchor.slice(0,4))}年${Number(anchor.slice(5,7))}月`}\n {lang === \"en\" && view===\"month\" ? ` ${anchor.slice(0,7)}` : \"\"}\n </span>\n <button onClick={() => setAnchor((a: string) => { const d = new Date(a + \"T12:00:00+08:00\"); if (view === \"week\") d.setDate(d.getDate() + 7); else d.setMonth(d.getMonth() + 1); const ms = d.getTime(); return new Date(ms).toLocaleDateString(\"en-CA\", { timeZone: \"Asia/Shanghai\" } as any); })} style={{ padding: \"4px 10px\", fontSize: 12, borderRadius: 6, border: \"1px solid var(--dsw-alias-border-l2)\", background: \"var(--dsw-alias-bg-layer-3)\", cursor: \"pointer\" }}>{lang === \"en\" ? \"Next ›\" : \"下一\"}{view === \"week\" ? (lang===\"en\"?\" Week\":\"周\") : (lang===\"en\"?\" Month\":\"月\")} ›</button>\n </div>\n ) : null}\n\n {totals ? <StatsCards t={lang === \"en\" ? (k:string,p?:any)=> { const enMap:Record<string,string>={\"stats.today\":\"Today\",\"stats.week\":\"This week\",\"stats.month\":\"This month\",\"stats.all\":\"All time\"}; if(k===\"stats.count\") return `${p?.count ?? \"\"} turns`; return (enMap as any)[k] ?? t(k,p); } : t} totals={totals} todayCount={undefined} /> : null}\n {days ? <HeatmapGrid t={lang === \"en\" ? (k:string,p?:any)=> { const enM:Record<string,string>={\"view.week\":\"Week\",\"view.month\":\"Month\",\"view.quarter\":\"Quarter\",\"view.year\":\"Year\",\"heatmap.legend.less\":\"Less\",\"heatmap.legend.more\":\"More\",\"heatmap.empty\":\"No data yet\",\"heatmap.tooltip.none\":\"No usage\",\"heatmap.subtitle\":\"Token usage from local session logs, bucketed by Asia/Shanghai. First sync is persisted — deleting sessions keeps history.\",\"heatmap.title\":\"Token Pulse\"}; return (enM as any)[k] ?? t(k,p); } : t} days={days} view={view} onViewChange={handleViewChange} selectedKey={selectedKey} onSelect={handleSelect} isEn={lang === \"en\"} thresholds={thresholds} /> : null}\n {selectedKey ? (\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8, fontSize: 12, color: \"var(--dsw-alias-label-secondary)\" }}>\n <span>{tt(\"heatmap.dayDetail\")}</span>\n <button onClick={() => setSelectedKey(null)} style={{ padding: \"2px 8px\", fontSize: 11, borderRadius: 6, border: \"1px solid var(--dsw-alias-border-l2)\", background: \"var(--dsw-alias-bg-layer-3)\", cursor: \"pointer\" }}>{tt(\"heatmap.clearSelection\")}</button>\n </div>\n ) : null}\n {injectedTop ? (\n <ModelTop5 t={t} topModels={injectedTop} topProviders={[]} days={days ?? undefined} mode={topMode} onModeChange={setTopMode} othersModelTokens={modelOthersTokens} othersProviderTokens={providerOthersTokens} />\n ) : viewTopModelsNamed.length > 0 || viewTopProvidersNamed.length > 0 ? (\n <ModelTop5 t={lang === \"en\" ? (k:string,p?:any)=> ({ \"model.top5\":\"Top 5 Models\",\"provider.top5\":\"Top 5 Providers\",\"model.top5.hint\":\"By token usage\",\"model.none\":\"No data\",\"view.model\":\"Model\",\"view.provider\":\"Provider\",\"model.others\":\"Others\"} as any)[k] ?? t(k,p) : t} topModels={viewTopModelsNamed} topProviders={viewTopProvidersNamed} days={days ?? undefined} mode={topMode} onModeChange={setTopMode} othersModelTokens={modelOthersTokens} othersProviderTokens={providerOthersTokens} />\n ) : null}\n {!hasData && !days ? (\n <div\n style={{\n border: \"1px solid var(--dsw-alias-border-l2)\",\n background: \"var(--dsw-alias-bg-layer-3)\",\n borderRadius: 12,\n padding: 24,\n color: \"var(--dsw-alias-label-tertiary)\",\n fontSize: 13,\n }}\n >\n {t(\"heatmap.empty\")}\n </div>\n ) : null}\n {/* 用量趋势线图:横轴时间、纵轴用量、每模型一条线(Top5 可开关);固定最近 7/30 天,与上面的视图选择解耦 */}\n {allDays.some((d) => d.totalTokens > 0) ? (\n <TrendChart\n t={lang === \"en\" ? (k: string, p?: any) => ((enDict as any)[k] ?? t(k, p)) : t}\n days={allDays}\n isEn={lang === \"en\"}\n />\n ) : null}\n </section>\n );\n}\n\nexport default SettingsSection;\n","import * as React from \"react\";\nimport { SettingsSection } from \"./SettingsSection.tsx\";\nimport { zh, en } from \"./locales.ts\";\n\nconst NS = \"dsh-token-pulse\";\n\nexport const inject = [\"locale\", \"slots\"] as const;\n\n// CSS: replace default gear with a heatmap/grid icon for this settings entry\nconst NAV_CSS = `\n[data-dsh-token-pulse-nav] > svg:first-child { display: none; }\n[data-dsh-token-pulse-nav]::before {\n content: ''; flex: none; width: 16px; height: 16px; background: currentColor;\n -webkit-mask: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='3' width='7' height='7' rx='1'/%3E%3Crect x='14' y='3' width='7' height='7' rx='1'/%3E%3Crect x='3' y='14' width='7' height='7' rx='1'/%3E%3Crect x='14' y='14' width='7' height='7' rx='1'/%3E%3C/svg%3E\") center / contain no-repeat;\n mask: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='3' width='7' height='7' rx='1'/%3E%3Crect x='14' y='3' width='7' height='7' rx='1'/%3E%3Crect x='3' y='14' width='7' height='7' rx='1'/%3E%3Crect x='14' y='14' width='7' height='7' rx='1'/%3E%3C/svg%3E\") center / contain no-repeat;\n}\n`;\n\nfunction injectNavCss() {\n if (typeof document === \"undefined\") return;\n const id = \"dsh-token-pulse-nav-css\";\n if (document.getElementById(id)) return;\n const el = document.createElement(\"style\");\n el.id = id;\n el.textContent = NAV_CSS;\n document.head.appendChild(el);\n}\n\nfunction markNavRow() {\n if (typeof document === \"undefined\") return;\n const nav = t_global();\n // Match by the plugin's own label so future copy changes need only one edit.\n // Legacy strings kept as belt-and-suspenders fallbacks for the icon injection.\n const dynamic = typeof nav === \"function\" ? nav(\"nav\") : \"\";\n const labels = [dynamic, \"Token Pulse\", \"Token Heatmap\", \"用量热图\"].filter(Boolean);\n for (const label of labels) {\n const btn = [...document.querySelectorAll('button')].find((b) => b.textContent?.trim().includes(label));\n if (btn) btn.setAttribute(\"data-dsh-token-pulse-nav\", \"\");\n }\n}\n\nlet t_global: () => any = () => (k: string) => k;\n\n// One-time migration from the pre-rename `dsh-token-heatmap:*` localStorage\n// keys. The plugin was renamed to `dsh-token-pulse`; carry lang, thresholds\n// and auto-refresh forward so existing users keep their settings.\nfunction migrateLegacyLocalStorage() {\n if (typeof localStorage === \"undefined\") return;\n const pairs = [\n [\"dsh-token-heatmap:lang\", \"dsh-token-pulse:lang\"],\n [\"dsh-token-heatmap:thresholds\", \"dsh-token-pulse:thresholds\"],\n [\"dsh-token-heatmap:autoRefreshMinutes\", \"dsh-token-pulse:autoRefreshMinutes\"],\n ] as const;\n for (const [from, to] of pairs) {\n try {\n if (localStorage.getItem(to) === null) {\n const v = localStorage.getItem(from);\n if (v !== null) localStorage.setItem(to, v);\n }\n } catch {}\n }\n}\n\nexport function apply(ctx: any) {\n migrateLegacyLocalStorage();\n injectNavCss();\n ctx.effect(\n () => ctx.locale.register(NS, { zh, en }),\n \"dsh-token-pulse: dictionaries\",\n );\n const t = ctx.locale.bind(NS);\n t_global = () => t;\n\n ctx.slots.inject(\"settings.section\", () =>\n ctx.slots.register(\n {\n name: \"settings.section\",\n id: \"heatmap\",\n order: 55,\n label: () => t(\"nav\"),\n locale: NS,\n },\n (props: any) => {\n // Mark nav row on render (settings panel is open, rows are mounted)\n setTimeout(markNavRow, 50);\n return React.createElement(SettingsSection, { t, ctx, ...props });\n },\n ),\n );\n // Also try to mark whenever settings panel opens (poll a bit)\n if (typeof document !== \"undefined\") {\n const mo = new MutationObserver(() => markNavRow());\n mo.observe(document.documentElement, { childList: true, subtree: true });\n setTimeout(() => mo.disconnect(), 30000);\n }\n}\n"],"mappings":"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"}
|