dsh-token-pulse 0.3.1 → 0.4.1

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.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["formatTokens","React","React","a","React"],"sources":["../src/client/StatsCards.tsx","../src/date-bucket.ts","../src/aggregation.ts","../src/client/HeatmapGrid.tsx","../src/client/ModelTop5.tsx","../src/client/hooks.ts","../src/client/SettingsSection.tsx","../src/client/locales.ts","../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 * 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 { 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 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 </section>\n );\n}\n\nexport default SettingsSection;\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 \"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 \"common.tokens\": \"tokens\",\n};\n\nexport type LocaleDict = typeof zh;\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}: {\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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"}