tokentracker-cli 0.64.2 → 0.65.0

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.
Files changed (61) hide show
  1. package/dashboard/dist/assets/ActivityHeatmap-Ccf0I3uP.js +42 -0
  2. package/dashboard/dist/assets/{Card-Cg-6DDbN.js → Card-BSF8dYEt.js} +1 -1
  3. package/dashboard/dist/assets/ConfirmModal-Bjp6eg2f.js +1 -0
  4. package/dashboard/dist/assets/DashboardPage-BInQkoDe.js +19 -0
  5. package/dashboard/dist/assets/{DevicePage-C78nzmZm.js → DevicePage-B0yxbDDR.js} +1 -1
  6. package/dashboard/dist/assets/DialogTitle-uw-Oa5Qv.js +1 -0
  7. package/dashboard/dist/assets/{FadeIn-RZKrtHup.js → FadeIn-DPIBqXRl.js} +1 -1
  8. package/dashboard/dist/assets/{HeaderGithubStar-B1gFlLrg.js → HeaderGithubStar-DDXfJ1uC.js} +1 -1
  9. package/dashboard/dist/assets/{IpCheckPage-RrZDmOFh.js → IpCheckPage-KC93tPlt.js} +1 -1
  10. package/dashboard/dist/assets/LandingPage-Itx2uPWI.js +4415 -0
  11. package/dashboard/dist/assets/{LeaderboardAvatar-_tiTs_tT.js → LeaderboardAvatar-Bv44b_Kl.js} +1 -1
  12. package/dashboard/dist/assets/LeaderboardPage-DDq5gzyz.js +2 -0
  13. package/dashboard/dist/assets/{LeaderboardProfileModal-BiQREZ6Z.js → LeaderboardProfileModal-LQyYrCf1.js} +2 -2
  14. package/dashboard/dist/assets/{LeaderboardProfilePage-DU43hEuh.js → LeaderboardProfilePage-3you3mbA.js} +2 -2
  15. package/dashboard/dist/assets/LimitsPage-CrLvR8vE.js +3 -0
  16. package/dashboard/dist/assets/{LocalOnlyNotice-Dvcf7F9s.js → LocalOnlyNotice-Di1gnfIi.js} +1 -1
  17. package/dashboard/dist/assets/{LoginPage-UlbsYFKJ.js → LoginPage-f9QHz_uZ.js} +1 -1
  18. package/dashboard/dist/assets/{PopoverPopup-BsBKLiJu.js → PopoverPopup-7rjAxAqk.js} +1 -1
  19. package/dashboard/dist/assets/{ResetPasswordPage-BuKemqhr.js → ResetPasswordPage-DKA7HGpJ.js} +1 -1
  20. package/dashboard/dist/assets/{Select-9oplHX46.js → Select-2gikPo1a.js} +1 -1
  21. package/dashboard/dist/assets/{SelectItemText-CnL08w_W.js → SelectItemText-DZx33XF1.js} +1 -1
  22. package/dashboard/dist/assets/SettingsPage-CwHPmuZV.js +1 -0
  23. package/dashboard/dist/assets/SkillsPage-B6BJ9UZp.js +1 -0
  24. package/dashboard/dist/assets/WidgetsPage-D8p3Tx7E.js +1 -0
  25. package/dashboard/dist/assets/{WrappedPage-DPAz_bit.js → WrappedPage-cXEfhti9.js} +1 -1
  26. package/dashboard/dist/assets/{agent-logos-uSGgZshc.js → agent-logos-D3iFlaWg.js} +1 -1
  27. package/dashboard/dist/assets/{arrow-up-right-9sot4sNP.js → arrow-up-right-D87Aw_ZN.js} +1 -1
  28. package/dashboard/dist/assets/{download-3O0nnnqv.js → download-BtcEs1OB.js} +1 -1
  29. package/dashboard/dist/assets/index-BFIcLxb4.js +2 -0
  30. package/dashboard/dist/assets/main-CGx8BJ4O.css +1 -0
  31. package/dashboard/dist/assets/{main-C5qSiLnL.js → main-DqnXui98.js} +30 -19
  32. package/dashboard/dist/assets/{use-limits-display-prefs-Bh7PFn6x.js → use-limits-display-prefs-DAxlRSu2.js} +1 -1
  33. package/dashboard/dist/assets/{use-native-settings-MKCjJWeQ.js → use-native-settings-CgvB_B6W.js} +1 -1
  34. package/dashboard/dist/assets/use-ordered-list-DOfX6aSy.js +5 -0
  35. package/dashboard/dist/assets/{use-quality-per-dollar-pref-D-m9WqCz.js → use-quality-per-dollar-pref-kEbwQwk2.js} +1 -1
  36. package/dashboard/dist/assets/{use-usage-limits-CCu4bGI4.js → use-usage-limits-la-KPfJj.js} +1 -1
  37. package/dashboard/dist/assets/{useCurrency-BZmZ49MO.js → useCurrency-LDRg7ST0.js} +1 -1
  38. package/dashboard/dist/assets/{useScrollLock-BdBmNNmw.js → useScrollLock-lP1Is9IY.js} +1 -1
  39. package/dashboard/dist/index.html +2 -2
  40. package/dashboard/dist/share.html +2 -2
  41. package/package.json +1 -1
  42. package/src/cli.js +7 -0
  43. package/src/commands/status.js +38 -0
  44. package/src/commands/sync.js +1 -0
  45. package/src/lib/pricing/curated-overrides.json +1 -0
  46. package/src/lib/pricing/seed-snapshot.json +1 -1
  47. package/src/lib/project-usage-purge.js +13 -2
  48. package/src/lib/rollout.js +364 -44
  49. package/src/lib/usage-limits.js +210 -2
  50. package/dashboard/dist/assets/ActivityHeatmap-CrW1u40M.js +0 -42
  51. package/dashboard/dist/assets/DashboardPage-Bl8jvnt-.js +0 -19
  52. package/dashboard/dist/assets/DialogTitle-COVyZQVB.js +0 -1
  53. package/dashboard/dist/assets/LandingPage-CV9EvgTg.js +0 -4411
  54. package/dashboard/dist/assets/LeaderboardPage-2tltO9IR.js +0 -6
  55. package/dashboard/dist/assets/LimitsPage-C7xuyH5P.js +0 -3
  56. package/dashboard/dist/assets/SettingsPage-CeqgABWP.js +0 -1
  57. package/dashboard/dist/assets/SkillsPage-CW6aD8GD.js +0 -1
  58. package/dashboard/dist/assets/WidgetsPage-DtOkMdxK.js +0 -1
  59. package/dashboard/dist/assets/index-BeoRn2gJ.js +0 -2
  60. package/dashboard/dist/assets/info-CfCBZRtQ.js +0 -1
  61. package/dashboard/dist/assets/main-DWsITcdg.css +0 -1
@@ -42,6 +42,12 @@ const ANTIGRAVITY_LIMITS_CACHE_UNKNOWN_RESET_TTL_MS = 12 * 60 * 60 * 1000;
42
42
  const CLAUDE_LIMITS_CACHE_FILE = "claude-usage-limits-cache.json";
43
43
  const CLAUDE_LIMITS_CACHE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
44
44
  const CLAUDE_LIMITS_CACHE_FRESH_TTL_MS = 10 * 60 * 1000;
45
+ // Codex has no rate-limit cooldown like Claude, but its two sequential chatgpt.com requests
46
+ // (/wham/usage + /wham/rate-limit-reset-credits) make it the provider most exposed to slow
47
+ // networks. Persist the last successful read so a timeout serves stale bars instead of a red
48
+ // error, mirroring the Claude stale-fallback path.
49
+ const CODEX_LIMITS_CACHE_FILE = "codex-usage-limits-cache.json";
50
+ const CODEX_LIMITS_CACHE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
45
51
  // A 429 from the usage endpoint carries a long `retry-after` (often 20+ minutes). Persist
46
52
  // the cooldown so every surface — this process, the menu bar app's embedded server, a later
47
53
  // restart — stops calling until it expires. Hammering during the cooldown just renews the
@@ -59,6 +65,12 @@ function clampPercent(value) {
59
65
  return n;
60
66
  }
61
67
 
68
+ function toFiniteNumberOrNull(value) {
69
+ if (value === null || value === undefined || value === "") return null;
70
+ const n = Number(value);
71
+ return Number.isFinite(n) ? n : null;
72
+ }
73
+
62
74
  function buildWindow({ usedPercent, resetAt }) {
63
75
  const pct = clampPercent(usedPercent);
64
76
  if (pct === null) return null;
@@ -132,6 +144,34 @@ function formatClaudeRateLimitMessage(retryAfterSec) {
132
144
  return "Claude API rate limited (429) — retry shortly.";
133
145
  }
134
146
 
147
+ // Model-scoped weekly windows (e.g. Fable) arrive only in the newer generic `limits`
148
+ // array (`kind: "weekly_scoped"` + `scope.model.display_name`) — the legacy top-level
149
+ // fields (`seven_day_opus` etc.) stay null for them. Extract them into
150
+ // `weekly_scoped: [{ label, utilization, resets_at }]`. Entries that duplicate a
151
+ // populated legacy field (an "Opus" scoped entry alongside `seven_day_opus`) are
152
+ // dropped so the same window never renders twice.
153
+ function extractClaudeScopedWeekly(body) {
154
+ if (!Array.isArray(body?.limits)) return null;
155
+ const out = [];
156
+ for (const entry of body.limits) {
157
+ if (!entry || typeof entry !== "object" || entry.kind !== "weekly_scoped") continue;
158
+ const model = entry.scope?.model;
159
+ const label = typeof model?.display_name === "string" && model.display_name.trim()
160
+ ? model.display_name.trim()
161
+ : typeof model?.id === "string" && model.id.trim() ? model.id.trim() : null;
162
+ if (!label) continue;
163
+ if (body.seven_day_opus && label.toLowerCase() === "opus") continue;
164
+ const utilization = Number(entry.percent);
165
+ if (!Number.isFinite(utilization)) continue;
166
+ out.push({
167
+ label,
168
+ utilization,
169
+ resets_at: typeof entry.resets_at === "string" ? entry.resets_at : null,
170
+ });
171
+ }
172
+ return out.length > 0 ? out : null;
173
+ }
174
+
135
175
  async function fetchClaudeUsageLimits(accessToken, { fetchImpl = fetch, maxAttempts = 3 } = {}) {
136
176
  const url = "https://api.anthropic.com/api/oauth/usage";
137
177
  const headers = {
@@ -166,6 +206,7 @@ async function fetchClaudeUsageLimits(accessToken, { fetchImpl = fetch, maxAttem
166
206
  five_hour: body.five_hour ?? null,
167
207
  seven_day: body.seven_day ?? null,
168
208
  seven_day_opus: body.seven_day_opus ?? null,
209
+ weekly_scoped: extractClaudeScopedWeekly(body),
169
210
  extra_usage: body.extra_usage ?? null,
170
211
  };
171
212
  }
@@ -221,6 +262,60 @@ function normalizeCodexRateWindows(rateLimit) {
221
262
  return { primary_window: session, secondary_window: weekly };
222
263
  }
223
264
 
265
+ function normalizeCodexCreditWindow(individualLimit) {
266
+ if (!individualLimit || typeof individualLimit !== "object" || Array.isArray(individualLimit)) {
267
+ return null;
268
+ }
269
+
270
+ const limitCredits = toFiniteNumberOrNull(individualLimit.limit);
271
+ const usedCredits = toFiniteNumberOrNull(individualLimit.used);
272
+ const remainingCredits = toFiniteNumberOrNull(individualLimit.remaining);
273
+
274
+ let usedPercent = clampPercent(individualLimit.used_percent);
275
+ if (limitCredits && limitCredits > 0 && usedCredits !== null) {
276
+ const derivedUsedPercent = clampPercent((usedCredits / limitCredits) * 100);
277
+ if (derivedUsedPercent !== null && (usedPercent === null || (usedPercent === 0 && usedCredits > 0))) {
278
+ usedPercent = derivedUsedPercent;
279
+ }
280
+ }
281
+
282
+ let remainingPercent = clampPercent(individualLimit.remaining_percent);
283
+ if (limitCredits && limitCredits > 0 && remainingCredits !== null) {
284
+ const derivedRemainingPercent = clampPercent((remainingCredits / limitCredits) * 100);
285
+ if (
286
+ derivedRemainingPercent !== null
287
+ && (remainingPercent === null || (remainingPercent === 100 && (usedCredits || 0) > 0))
288
+ ) {
289
+ remainingPercent = derivedRemainingPercent;
290
+ }
291
+ }
292
+
293
+ const resetAt = toFiniteNumberOrNull(individualLimit.reset_at);
294
+ const source = typeof individualLimit.source === "string" && individualLimit.source.trim()
295
+ ? individualLimit.source.trim()
296
+ : null;
297
+
298
+ if (
299
+ usedPercent === null
300
+ && limitCredits === null
301
+ && usedCredits === null
302
+ && remainingCredits === null
303
+ && resetAt === null
304
+ ) {
305
+ return null;
306
+ }
307
+
308
+ return {
309
+ source,
310
+ used_percent: usedPercent ?? 0,
311
+ remaining_percent: remainingPercent,
312
+ reset_at: resetAt,
313
+ limit_credits: limitCredits,
314
+ used_credits: usedCredits,
315
+ remaining_credits: remainingCredits,
316
+ };
317
+ }
318
+
224
319
  function isCodexSparkLimit(entry) {
225
320
  if (!entry || typeof entry !== "object") return false;
226
321
  return [entry.limit_name, entry.metered_feature].some((value) => (
@@ -425,6 +520,7 @@ async function fetchCodexUsageLimits(
425
520
  return {
426
521
  primary_window: null,
427
522
  secondary_window: null,
523
+ credit_window: null,
428
524
  spark_primary_window: null,
429
525
  spark_secondary_window: null,
430
526
  reset_credits: null,
@@ -449,6 +545,7 @@ async function fetchCodexUsageLimits(
449
545
  }
450
546
  return {
451
547
  ...normalizeCodexRateWindows(body.rate_limit || {}),
548
+ credit_window: normalizeCodexCreditWindow(body.spend_control?.individual_limit),
452
549
  ...normalizeCodexSparkRateWindows(body.additional_rate_limits),
453
550
  reset_credits: resetCredits,
454
551
  };
@@ -1780,7 +1877,21 @@ function isClaudeCacheWindowUsable(window, { nowMs } = {}) {
1780
1877
  }
1781
1878
 
1782
1879
  function hasClaudeWindow(limits) {
1783
- return Boolean(limits?.five_hour || limits?.seven_day || limits?.seven_day_opus);
1880
+ return Boolean(
1881
+ limits?.five_hour || limits?.seven_day || limits?.seven_day_opus ||
1882
+ (Array.isArray(limits?.weekly_scoped) && limits.weekly_scoped.length > 0),
1883
+ );
1884
+ }
1885
+
1886
+ // Cached scoped windows are filtered per-entry like the fixed windows: a scoped
1887
+ // window whose reset has passed is stale data, not a usable fallback.
1888
+ function normalizeClaudeCachedScopedWeekly(raw, { nowMs } = {}) {
1889
+ if (!Array.isArray(raw)) return null;
1890
+ const usable = raw.filter(
1891
+ (w) => w && typeof w.label === "string" && Number.isFinite(Number(w.utilization)) &&
1892
+ isClaudeCacheWindowUsable(w, { nowMs }),
1893
+ );
1894
+ return usable.length > 0 ? usable : null;
1784
1895
  }
1785
1896
 
1786
1897
  function normalizeClaudeCachedLimits(
@@ -1802,6 +1913,7 @@ function normalizeClaudeCachedLimits(
1802
1913
  five_hour: isClaudeCacheWindowUsable(raw?.five_hour, { nowMs }) ? raw.five_hour : null,
1803
1914
  seven_day: isClaudeCacheWindowUsable(raw?.seven_day, { nowMs }) ? raw.seven_day : null,
1804
1915
  seven_day_opus: isClaudeCacheWindowUsable(raw?.seven_day_opus, { nowMs }) ? raw.seven_day_opus : null,
1916
+ weekly_scoped: normalizeClaudeCachedScopedWeekly(raw?.weekly_scoped, { nowMs }),
1805
1917
  extra_usage: raw?.extra_usage ?? null,
1806
1918
  stale,
1807
1919
  cached_at: raw.cached_at,
@@ -1841,6 +1953,9 @@ function writeClaudeLimitsCache(limits, { home, nowMs = Date.now() } = {}) {
1841
1953
  five_hour: limits.five_hour || null,
1842
1954
  seven_day: limits.seven_day || null,
1843
1955
  seven_day_opus: limits.seven_day_opus || null,
1956
+ weekly_scoped: Array.isArray(limits.weekly_scoped) && limits.weekly_scoped.length > 0
1957
+ ? limits.weekly_scoped
1958
+ : null,
1844
1959
  extra_usage: limits.extra_usage || null,
1845
1960
  cached_at: new Date(nowMs).toISOString(),
1846
1961
  },
@@ -1853,6 +1968,88 @@ function writeClaudeLimitsCache(limits, { home, nowMs = Date.now() } = {}) {
1853
1968
  } catch (_error) {}
1854
1969
  }
1855
1970
 
1971
+ function resolveCodexLimitsCachePath({ home } = {}) {
1972
+ return path.join(home || os.homedir(), ".tokentracker", "tracker", CODEX_LIMITS_CACHE_FILE);
1973
+ }
1974
+
1975
+ // Codex windows carry `reset_at` as unix seconds (not an ISO string). A window whose reset has
1976
+ // already passed is stale data, not a usable fallback, so drop it. Windows without a reset stamp
1977
+ // are kept — the overall cached_at max-age gate already bounds them.
1978
+ function isCodexCacheWindowUsable(window, { nowMs } = {}) {
1979
+ if (!window || typeof window !== "object") return false;
1980
+ const resetAt = Number(window.reset_at);
1981
+ if (!Number.isFinite(resetAt) || resetAt <= 0) return true;
1982
+ return resetAt * 1000 > nowMs;
1983
+ }
1984
+
1985
+ function hasCodexWindow(limits) {
1986
+ return Boolean(
1987
+ limits?.primary_window
1988
+ || limits?.secondary_window
1989
+ || limits?.credit_window
1990
+ || limits?.spark_primary_window
1991
+ || limits?.spark_secondary_window,
1992
+ );
1993
+ }
1994
+
1995
+ function normalizeCodexCachedLimits(
1996
+ raw,
1997
+ { nowMs = Date.now(), maxAgeMs = CODEX_LIMITS_CACHE_MAX_AGE_MS } = {},
1998
+ ) {
1999
+ const cachedAtMs = parseTimeMs(raw?.cached_at);
2000
+ if (!Number.isFinite(cachedAtMs)) return null;
2001
+ if (cachedAtMs > nowMs + 60_000) return null;
2002
+ if (nowMs - cachedAtMs > maxAgeMs) return null;
2003
+
2004
+ const cached = {
2005
+ configured: true,
2006
+ error: null,
2007
+ plan_type: typeof raw?.plan_type === "string" ? raw.plan_type : null,
2008
+ primary_window: isCodexCacheWindowUsable(raw?.primary_window, { nowMs }) ? raw.primary_window : null,
2009
+ secondary_window: isCodexCacheWindowUsable(raw?.secondary_window, { nowMs }) ? raw.secondary_window : null,
2010
+ credit_window: isCodexCacheWindowUsable(raw?.credit_window, { nowMs }) ? raw.credit_window : null,
2011
+ spark_primary_window: isCodexCacheWindowUsable(raw?.spark_primary_window, { nowMs }) ? raw.spark_primary_window : null,
2012
+ spark_secondary_window: isCodexCacheWindowUsable(raw?.spark_secondary_window, { nowMs }) ? raw.spark_secondary_window : null,
2013
+ reset_credits: raw?.reset_credits ?? null,
2014
+ stale: true,
2015
+ cached_at: raw.cached_at,
2016
+ };
2017
+ return hasCodexWindow(cached) ? cached : null;
2018
+ }
2019
+
2020
+ function readCodexLimitsCache({ home, nowMs = Date.now(), maxAgeMs = CODEX_LIMITS_CACHE_MAX_AGE_MS } = {}) {
2021
+ const cachePath = resolveCodexLimitsCachePath({ home });
2022
+ try {
2023
+ const parsed = JSON.parse(fs.readFileSync(cachePath, "utf8"));
2024
+ return normalizeCodexCachedLimits(parsed?.codex, { nowMs, maxAgeMs });
2025
+ } catch (_error) {
2026
+ return null;
2027
+ }
2028
+ }
2029
+
2030
+ function writeCodexLimitsCache(limits, { home, nowMs = Date.now() } = {}) {
2031
+ if (!limits?.configured || limits.error || !hasCodexWindow(limits)) return;
2032
+ const cachePath = resolveCodexLimitsCachePath({ home });
2033
+ const payload = {
2034
+ codex: {
2035
+ plan_type: limits.plan_type || null,
2036
+ primary_window: limits.primary_window || null,
2037
+ secondary_window: limits.secondary_window || null,
2038
+ credit_window: limits.credit_window || null,
2039
+ spark_primary_window: limits.spark_primary_window || null,
2040
+ spark_secondary_window: limits.spark_secondary_window || null,
2041
+ reset_credits: limits.reset_credits || null,
2042
+ cached_at: new Date(nowMs).toISOString(),
2043
+ },
2044
+ };
2045
+ try {
2046
+ fs.mkdirSync(path.dirname(cachePath), { recursive: true });
2047
+ const tmpPath = `${cachePath}.${process.pid}.tmp`;
2048
+ fs.writeFileSync(tmpPath, JSON.stringify(payload, null, 2), { encoding: "utf8", mode: 0o600 });
2049
+ fs.renameSync(tmpPath, cachePath);
2050
+ } catch (_error) {}
2051
+ }
2052
+
1856
2053
  function resolveClaudeRateLimitPath({ home } = {}) {
1857
2054
  return path.join(home || os.homedir(), ".tokentracker", "tracker", CLAUDE_RATE_LIMIT_FILE);
1858
2055
  }
@@ -2496,6 +2693,7 @@ async function fetchUsageLimitsUncached({
2496
2693
  five_hour: claudeResult.value.five_hour,
2497
2694
  seven_day: claudeResult.value.seven_day,
2498
2695
  seven_day_opus: claudeResult.value.seven_day_opus,
2696
+ weekly_scoped: claudeResult.value.weekly_scoped,
2499
2697
  extra_usage: claudeResult.value.extra_usage,
2500
2698
  };
2501
2699
  writeClaudeLimitsCache(claude, { home, nowMs });
@@ -2534,7 +2732,15 @@ async function fetchUsageLimitsUncached({
2534
2732
  auth_action_required: "reauth",
2535
2733
  };
2536
2734
  } else if (!codexResult || codexResult.status === "rejected") {
2537
- codex = { configured: true, error: codexResult?.reason?.message || "Unknown error" };
2735
+ // Live fetch failed or timed out (Codex hits chatgpt.com fresh every poll with no
2736
+ // rate-limit cooldown, so a slow network shows up here often). Serve the last successful
2737
+ // read so the bars stay visible instead of a red error, mirroring the Claude stale path.
2738
+ const cached = readCodexLimitsCache({ home, nowMs });
2739
+ if (cached) {
2740
+ codex = cached;
2741
+ } else {
2742
+ codex = { configured: true, error: codexResult?.reason?.message || "Unknown error" };
2743
+ }
2538
2744
  } else {
2539
2745
  codex = {
2540
2746
  configured: true,
@@ -2542,10 +2748,12 @@ async function fetchUsageLimitsUncached({
2542
2748
  plan_type: codexPlanType || null,
2543
2749
  primary_window: codexResult.value.primary_window,
2544
2750
  secondary_window: codexResult.value.secondary_window,
2751
+ credit_window: codexResult.value.credit_window,
2545
2752
  spark_primary_window: codexResult.value.spark_primary_window,
2546
2753
  spark_secondary_window: codexResult.value.spark_secondary_window,
2547
2754
  reset_credits: codexResult.value.reset_credits,
2548
2755
  };
2756
+ writeCodexLimitsCache(codex, { home, nowMs });
2549
2757
  }
2550
2758
 
2551
2759
  const data = {
@@ -1,42 +0,0 @@
1
- import{c as ue,r as i,j as e,G as n,T as We,n as Fe,I as Ie,X as He,av as Ge,J as Oe}from"./main-C5qSiLnL.js";import{u as qe}from"./useCurrency-BZmZ49MO.js";import{I as Ze}from"./info-CfCBZRtQ.js";const Ke=[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"m21 3-7 7",key:"1l2asr"}],["path",{d:"m3 21 7-7",key:"tjx5ai"}],["path",{d:"M9 21H3v-6",key:"wtvkvv"}]],Ve=ue("maximize-2",Ke);const Je=[["rect",{x:"14",y:"3",width:"5",height:"18",rx:"1",key:"kaeet6"}],["rect",{x:"5",y:"3",width:"5",height:"18",rx:"1",key:"1wsw3u"}]],Qe=ue("pause",Je);const et=[["path",{d:"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",key:"10ikf1"}]],tt=ue("play",et);const at=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}]],rt=ue("rotate-ccw",at);const ot=[["path",{d:"M12 19h8",key:"baeox8"}],["path",{d:"m4 17 6-6-6-6",key:"1yngyt"}]],nt=ue("terminal",ot),Q={emerald:{light:["#ebedf0","#a7f3d0","#6ee7b7","#34d399","#10b981"],dark:["#2d333b","#065f46","#059669","#10b981","#34d399"],gridColor:{light:"rgba(16, 185, 129, 0.12)",dark:"rgba(52, 211, 153, 0.08)"}},ocean:{light:["#f1f5f9","#93c5fd","#60a5fa","#3b82f6","#1d4ed8"],dark:["#1e293b","#1e3a8a","#2563eb","#3b82f6","#60a5fa"],gridColor:{light:"rgba(59, 130, 246, 0.12)",dark:"rgba(96, 165, 250, 0.08)"}},neon:{light:["#faf5ff","#ebd5ff","#c084fc","#a855f7","#7e22ce"],dark:["#2e1065","#581c87","#8b5cf6","#a855f7","#c084fc"],gridColor:{light:"rgba(168, 85, 247, 0.12)",dark:"rgba(192, 132, 252, 0.08)"}},amber:{light:["#fffbeb","#fde68a","#f59e0b","#d97706","#b45309"],dark:["#451a03","#78350f","#b45309","#d97706","#f59e0b"],gridColor:{light:"rgba(245, 158, 11, 0.12)",dark:"rgba(245, 158, 11, 0.08)"}}};function st(l,x){const p=/^#([0-9a-f]{6})$/i.exec(l);if(!p)return l;const c=parseInt(p[1],16),z=c>>16&255,P=c>>8&255,$=c&255,S=E=>Math.max(0,Math.min(255,Math.round(E*x)));return`rgb(${S(z)}, ${S(P)}, ${S($)})`}function O(l,x,p,c,z){const P=Math.cos(c),$=Math.sin(c),S=l*P-x*$,E=l*$+x*P,L=p,_=Math.cos(z),m=Math.sin(z),N=S,ee=E*_-L*m,te=E*m+L*_;return{x:N,y:ee,z:te}}function lt(l,x,p,c,z){return O(l,x,p,c,z)}function Se(l,x){const p=Number(x).toLocaleString();if(l>=4){const c=Math.floor(Math.random()*3)+1;return n(`heatmap.3d.voxel.joke.${c}`,{value:p})}else return l===3?n("heatmap.3d.voxel.level3",{value:p}):l===2?n("heatmap.3d.voxel.level2",{value:p}):l===1?n("heatmap.3d.voxel.level1",{value:p}):n("heatmap.3d.voxel.level0")}function _e({weeks:l,palette:x="auto",isDark:p=!1,interactive:c=!1,autoRotateInit:z=!1,onResetViewRef:P=null}){const $=Q[x]||(x==="auto"?Q.emerald:null),S=$?p?$.dark:$.light:Array.isArray(x)?x:p?Q.emerald.dark:Q.emerald.light,E=$?p?$.gridColor.dark:$.gridColor.light:p?"rgba(255,255,255,0.06)":"rgba(0,0,0,0.06)",L=-.2,_=.88,[m,N]=i.useState({yaw:L,pitch:_}),[ee,te]=i.useState(z),[he,A]=i.useState(1),j=c?13:10.5,pe=i.useMemo(()=>{const t=[],r=l.length;if(r===0||!c)return[];for(let s=0;s<=7;s++){const o=(s-3.5)*j,d=O(-r/2*j,o,0,m.yaw,m.pitch),h=O(r/2*j,o,0,m.yaw,m.pitch);t.push({d:`M${d.x},${d.y} L${h.x},${h.y}`,key:`horiz-${s}`})}for(let s=0;s<=r;s+=4){const o=(s-r/2)*j,d=O(o,-3.5*j,0,m.yaw,m.pitch),h=O(o,3.5*j,0,m.yaw,m.pitch);t.push({d:`M${d.x},${d.y} L${h.x},${h.y}`,key:`vert-${s}`})}if(r%4!==0){const s=(r-r/2)*j,o=O(s,-3.5*j,0,m.yaw,m.pitch),d=O(s,3.5*j,0,m.yaw,m.pitch);t.push({d:`M${o.x},${o.y} L${d.x},${d.y}`,key:"vert-last"})}return t},[l.length,m,j,c]);i.useEffect(()=>{P&&(P.current={reset:()=>{N({yaw:L,pitch:_}),te(!1),A(1),ye()},toggleAutoRotate:t=>{te(t)}})},[P]);const q=i.useRef(null),F=i.useRef(null),W=i.useRef(!1),ie=i.useRef({x:0,y:0}),Z=i.useRef({yaw:L,pitch:_}),Y=i.useRef({x:0,y:0}),oe=i.useRef({x:0,y:0,time:0}),ne=i.useRef(null),[fe,ge]=i.useState(0),K=i.useRef(null),se=i.useRef(!0);i.useEffect(()=>(se.current=!0,()=>{se.current=!1}),[]);const ye=()=>{K.current&&cancelAnimationFrame(K.current),ge(0);const t=performance.now(),r=1200,s=o=>{if(!se.current)return;const d=o-t,h=Math.min(1,d/r),k=1-Math.pow(1-h,3);ge(k),h<1?K.current=requestAnimationFrame(s):K.current=null};K.current=requestAnimationFrame(s)};i.useEffect(()=>(ye(),()=>{K.current&&cancelAnimationFrame(K.current)}),[c]),i.useEffect(()=>{if(!ee||W.current||typeof window>"u"||typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches)return;let r;const s=()=>{if(typeof document<"u"&&document.visibilityState==="hidden"){r=requestAnimationFrame(s);return}N(o=>({yaw:o.yaw+.002,pitch:o.pitch})),r=requestAnimationFrame(s)};return r=requestAnimationFrame(s),()=>cancelAnimationFrame(r)},[ee]);const ce=(t,r)=>{c&&(W.current=!0,ie.current={x:t,y:r},Z.current={yaw:m.yaw,pitch:m.pitch},Y.current={x:0,y:0},oe.current={x:t,y:r,time:performance.now()},ne.current&&cancelAnimationFrame(ne.current))},U=(t,r)=>{if(!W.current)return;const s=t-ie.current.x,o=r-ie.current.y,d=performance.now(),h=d-oe.current.time;h>0&&(Y.current={x:(t-oe.current.x)/h,y:(r-oe.current.y)/h}),oe.current={x:t,y:r,time:d};const k=.005,f=Z.current.yaw-s*k,g=Math.PI/2.3,D=Math.max(-g,Math.min(g,Z.current.pitch-o*k));N({yaw:f,pitch:D})},be=()=>{if(!W.current)return;W.current=!1;let t=-Y.current.x*12,r=-Y.current.y*12;const s=.95,o=()=>{W.current||(t*=s,r*=s,!(Math.abs(t)<.01&&Math.abs(r)<.01)&&(N(d=>{const h=d.yaw+t*.005,k=Math.PI/2.3,f=Math.max(-k,Math.min(k,d.pitch+r*.005));return{yaw:h,pitch:f}}),ne.current=requestAnimationFrame(o)))};ne.current=requestAnimationFrame(o)},[b,de]=i.useState(null),[V,xe]=i.useState({x:0,y:0,shiftX:0}),y=i.useRef(null);i.useEffect(()=>()=>{y.current&&clearTimeout(y.current)},[]),i.useEffect(()=>{if(!c||!F.current)return;const t=s=>{s.preventDefault();const o=-s.deltaY*.0025;A(d=>{const h=d+o;return Math.max(.5,Math.min(3,h))})},r=F.current;return r.addEventListener("wheel",t,{passive:!1}),()=>{r.removeEventListener("wheel",t)}},[c]);const C=i.useMemo(()=>{const t=[];return l.forEach((r,s)=>{(Array.isArray(r)?r:[]).forEach((o,d)=>{o&&t.push({key:o.day||`${s}-${d}`,col:s,row:d,level:o.level||0,value:o.value||0,day:o.day,models:o.models||null})})}),t},[l]),ve=j-(c?1.8:1.5),ke=c?38:28,J=t=>Math.max(1.8,Number(t)/4*ke),ae=i.useMemo(()=>{if(C.length===0)return[];const t=l.length;return C.map(r=>{const s=J(r.level),o=Math.sqrt(Math.pow(r.col-t/2,2)+Math.pow(r.row-3.5,2)),d=Math.sqrt(Math.pow(t/2,2)+Math.pow(3.5,2)),h=o/d*.4,k=Math.min(1,Math.max(0,(fe-h)*(1/.6))),f=s*k,g=(r.col-t/2)*j,D=(r.row-3.5)*j,w=ve/2,I=[{x:g-w,y:D-w,z:0},{x:g+w,y:D-w,z:0},{x:g+w,y:D+w,z:0},{x:g-w,y:D+w,z:0},{x:g-w,y:D-w,z:f},{x:g+w,y:D-w,z:f},{x:g+w,y:D+w,z:f},{x:g-w,y:D+w,z:f}].map(B=>O(B.x,B.y,B.z,m.yaw,m.pitch)),me=O(g,D,f/2,m.yaw,m.pitch),Le=[{name:"top",indices:[4,5,6,7],scale:1,normal:[0,0,1]},{name:"bottom",indices:[3,2,1,0],scale:.4,normal:[0,0,-1]},{name:"left",indices:[3,0,4,7],scale:.55,normal:[-1,0,0]},{name:"right",indices:[1,2,6,5],scale:.75,normal:[1,0,0]},{name:"front",indices:[0,1,5,4],scale:.85,normal:[0,-1,0]},{name:"back",indices:[2,3,7,6],scale:.65,normal:[0,1,0]}],Re=S[Math.min(4,Math.max(0,Number(r.level)||0))],Ne=[],Ae=.35,De=-.4,Pe=.83;return Le.forEach(B=>{const we=lt(B.normal[0],B.normal[1],B.normal[2],m.yaw,m.pitch);if(we.z>.001){const Ce=I[B.indices[0]],ze=I[B.indices[1]],Me=I[B.indices[2]],Te=I[B.indices[3]],Ye=`M${Ce.x},${Ce.y} L${ze.x},${ze.y} L${Me.x},${Me.y} L${Te.x},${Te.y} Z`,Ue=we.x*Ae+we.y*De+we.z*Pe,Xe=p?.18:0,Be=B.scale*(.82+.28*Math.max(0,Ue))+Xe;Ne.push({name:B.name,d:Ye,fill:st(Re,Be)})}}),{...r,centerProj:me,renderedFaces:Ne}})},[C,m,S,l.length,fe,j,ve,ke]),le=i.useMemo(()=>[...ae].sort((t,r)=>t.centerProj.z-r.centerProj.z),[ae]),M=i.useMemo(()=>{if(le.length===0)return{minX:-100,minY:-100,maxX:100,maxY:100};let t=1/0,r=1/0,s=-1/0,o=-1/0;return le.forEach(d=>{const h=j*2,k=d.centerProj.x,f=d.centerProj.y;k-h<t&&(t=k-h),k+h>s&&(s=k+h),f-h<r&&(r=f-h),f+h>o&&(o=f+h)}),{minX:t,minY:r,maxX:s,maxY:o}},[le,j]),R=12,a=M.maxX-M.minX+R*2,u=M.maxY-M.minY+R*2,T=a/he,v=u/he,X=M.minX-R+(a-T)/2,H=M.minY-R+(u-v)/2,G=`${X} ${H} ${T} ${v}`;return C.length===0?e.jsx("div",{className:"py-8 text-center text-sm text-oai-gray-500",children:n("heatmap.empty")}):e.jsxs("div",{ref:F,className:`relative select-none outline-none ${c?"cursor-grab active:cursor-grabbing w-full h-full flex items-center justify-center":"w-full overflow-hidden flex justify-center"}`,onMouseDown:t=>{if(!c)return;ce(t.clientX,t.clientY);const r=o=>U(o.clientX,o.clientY),s=()=>{be(),window.removeEventListener("mousemove",r),window.removeEventListener("mouseup",s)};window.addEventListener("mousemove",r),window.addEventListener("mouseup",s)},onTouchStart:t=>{!c||t.touches.length===0||ce(t.touches[0].clientX,t.touches[0].clientY)},onTouchMove:t=>{!c||t.touches.length===0||U(t.touches[0].clientX,t.touches[0].clientY)},onTouchEnd:()=>{c&&be()},children:[e.jsxs("svg",{ref:q,viewBox:G,width:c?"95%":"100%",height:c?"95%":"auto",role:"img","aria-label":n("heatmap.iso.aria")||"3D interactive activity heatmap",style:{display:"block",width:"100%",height:"auto",maxWidth:c?"none":`${a}px`,maxHeight:c?"78vh":"none"},className:"transition-transform duration-300 ease-out",children:[c&&pe.map(t=>e.jsx("path",{d:t.d,fill:"none",stroke:E,strokeWidth:.25,strokeDasharray:"1.5 2.5",strokeLinecap:"round"},t.key)),le.map(t=>{const r=b&&b.key===t.key;return e.jsxs("g",{onMouseEnter:s=>{if(y.current&&(clearTimeout(y.current),y.current=null),de(t),c&&q.current){const o=O((t.col-l.length/2)*j,(t.row-3.5)*j,J(t.level),m.yaw,m.pitch);let d=0,h=0;const k=q.current;if(F.current&&typeof k.createSVGPoint=="function"&&typeof k.getScreenCTM=="function")try{const w=k.createSVGPoint();w.x=o.x,w.y=o.y;const re=k.getScreenCTM();if(re){const I=w.matrixTransform(re),me=F.current.getBoundingClientRect();d=I.x-me.left,h=I.y-me.top}}catch{const re=k.getBoundingClientRect(),I=M.maxX-M.minX+R*2,me=M.maxY-M.minY+R*2;d=(o.x-(M.minX-R))/I*re.width,h=(o.y-(M.minY-R))/me*re.height}else{const w=k.getBoundingClientRect(),re=M.maxX-M.minX+R*2,I=M.maxY-M.minY+R*2;d=(o.x-(M.minX-R))/re*w.width,h=(o.y-(M.minY-R))/I*w.height}const f=140;let g=0;const D=F.current?F.current.getBoundingClientRect().width:k.getBoundingClientRect().width;d<f?g=f-d:d>D-f&&(g=D-f-d),xe({x:d,y:h,shiftX:g})}},onMouseLeave:()=>{y.current&&clearTimeout(y.current),y.current=setTimeout(()=>{de(null)},150)},className:"transition-all duration-200",style:{filter:r?"brightness(1.15) drop-shadow(0 4px 6px rgba(0,0,0,0.15))":"none",cursor:c?"pointer":"default"},children:[!c&&t.day&&e.jsx("title",{children:`${t.day}: ${Number(t.value).toLocaleString()} tokens`}),t.renderedFaces.map((s,o)=>e.jsx("path",{d:s.d,fill:s.fill,stroke:s.fill,strokeWidth:.25,strokeLinejoin:"round"},o))]},t.key)})]}),c&&b&&e.jsxs("div",{onMouseEnter:()=>{y.current&&(clearTimeout(y.current),y.current=null)},onMouseLeave:()=>{y.current&&clearTimeout(y.current),y.current=setTimeout(()=>{de(null)},150)},className:"absolute z-[9999] w-0 h-0 transition-all duration-100 ease-out",style:{left:`${V.x}px`,top:`${V.y}px`},children:[e.jsxs("div",{className:"absolute left-0 bottom-[10px] backdrop-blur-md bg-white/90 dark:bg-oai-gray-900/90 border border-oai-gray-200/50 dark:border-oai-gray-800/50 shadow-xl rounded-xl p-3.5 max-w-[280px] min-w-[200px] flex flex-col gap-2 animate-in fade-in zoom-in-95 duration-100",style:{transform:`translateX(calc(-50% + ${V.shiftX}px))`},children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-oai-gray-100 dark:border-oai-gray-800/80 pb-1.5",children:[e.jsx("span",{className:"text-[11px] font-semibold text-oai-gray-500 dark:text-oai-gray-400",children:b.day}),(()=>{const t=b.level===0?p?"#9ca3af":"#6b7280":S[b.level];return e.jsxs("span",{className:"text-[10px] px-2 py-0.5 rounded-full font-medium",style:{backgroundColor:t+"22",color:t,border:`1px solid ${t}44`},children:["Level ",b.level]})})()]}),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-baseline gap-1",children:[e.jsx("span",{className:"text-lg font-bold text-oai-gray-900 dark:text-white leading-none",children:Number(b.value).toLocaleString()}),e.jsx("span",{className:"text-[10px] text-oai-gray-400 uppercase tracking-wider font-semibold",children:"Tokens"})]}),b.models&&Object.keys(b.models).length>0?e.jsxs("div",{className:"mt-1.5 border-t border-oai-gray-100 dark:border-oai-gray-800/60 pt-2 flex flex-col gap-1.5",children:[e.jsx("div",{className:"text-[10px] font-semibold text-oai-gray-400 dark:text-oai-gray-500 uppercase tracking-wider",children:"Model Breakdown"}),e.jsx("div",{className:"flex flex-col gap-2 max-h-[150px] overflow-y-auto pr-1.5 scrollbar-thin",children:Object.entries(b.models).map(([t,r])=>({name:t,val:Number(r)})).sort((t,r)=>r.val-t.val).map(({name:t,val:r})=>{const s=Number(b.value)||1,o=Math.round(r/s*100);return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between text-[11px] gap-3",children:[e.jsx("span",{className:"font-medium text-oai-gray-750 dark:text-oai-gray-200 truncate max-w-[120px]",title:t,children:t}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[e.jsx("span",{className:"font-mono text-oai-gray-900 dark:text-oai-gray-100 font-semibold",children:r.toLocaleString()}),e.jsxs("span",{className:"text-[9px] text-oai-gray-450 dark:text-oai-gray-500 min-w-[28px] text-right font-medium",children:[o,"%"]})]})]}),e.jsx("div",{className:"w-full h-1 bg-oai-gray-100 dark:bg-oai-gray-800/85 rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-300",style:{width:`${o}%`,backgroundColor:S[4],boxShadow:`0 0 4px ${S[4]}55`}})})]},t)})})]}):e.jsx("p",{className:"text-[11px] text-oai-gray-600 dark:text-oai-gray-300 leading-relaxed font-normal mt-1 border-t border-dashed border-oai-gray-100 dark:border-oai-gray-800/60 pt-1.5",children:Se(b.level,b.value)})]})]}),e.jsx("div",{className:"absolute bottom-[6px] left-0 -translate-x-1/2 w-2.5 h-2.5 rotate-45 bg-white dark:bg-oai-gray-900 border-r border-b border-oai-gray-200/50 dark:border-oai-gray-800/50 shadow-sm",style:{marginBottom:"1px"}})]})]})}const it=12,ct=3,dt=26,mt=["#ebedf0","#a7f3d0","#6ee7b7","#34d399","#10b981"],xt=["#30363d","#065f46","#059669","#10b981","#34d399"];function $e(l){const x=Number(l);return Number.isFinite(x)?x<1e3?x.toLocaleString():Oe(x,{decimals:2}):"0"}function ut(l){if(typeof l!="string")return null;const x=/^(\d{4})-(\d{2})-(\d{2})$/.exec(l.trim());if(!x)return null;const p=new Date(Date.UTC(Number(x[1]),Number(x[2])-1,Number(x[3])));return Number.isFinite(p.getTime())?p:null}function Ee(l,x){return new Date(Date.UTC(l.getUTCFullYear(),l.getUTCMonth(),l.getUTCDate()+x))}function ht(l,x){return Math.floor((Date.UTC(x.getUTCFullYear(),x.getUTCMonth(),x.getUTCDate())-Date.UTC(l.getUTCFullYear(),l.getUTCMonth(),l.getUTCDate()))/864e5)}function pt(l,x){const p=x==="mon"?1:0,c=l.getUTCDay();return Ee(l,-((c-p+7)%7))}function ft(l,x,p,c){if(!l)return[];const z=ut(x)||new Date,P=[];for(let _=11;_>=0;_-=1)P.push(new Date(Date.UTC(z.getUTCFullYear(),z.getUTCMonth()-_,1)));const $=pt(z,p),S=Ee($,-(l-1)*7),E=[],L=new Set;for(const _ of P){const m=Math.floor(ht(S,_)/7);m<0||m>=l||L.has(m)||(L.add(m),E.push({label:c[_.getUTCMonth()],index:m}))}return E}function vt({heatmap:l,timeZoneLabel:x,timeZoneShortLabel:p,hideLegend:c=!1,embedded:z=!1}){const{resolvedTheme:P}=We(),{currency:$,rate:S}=qe(),E=P==="dark",L=E?xt:mt,_=i.useRef(null),m=i.useRef(null),[N,ee]=i.useState(null),[te,he]=i.useState({x:0,y:0,shiftX:0}),A=i.useRef(null);i.useEffect(()=>()=>{A.current&&clearTimeout(A.current)},[]);const[j,pe]=i.useState(!1),[q,F]=i.useState(!1),[W,ie]=i.useState(!1),Z=i.useRef(null),[Y,oe]=i.useState("emerald"),ne=[n("heatmap.month.jan"),n("heatmap.month.feb"),n("heatmap.month.mar"),n("heatmap.month.apr"),n("heatmap.month.may"),n("heatmap.month.jun"),n("heatmap.month.jul"),n("heatmap.month.aug"),n("heatmap.month.sep"),n("heatmap.month.oct"),n("heatmap.month.nov"),n("heatmap.month.dec")],fe=(a,u)=>{if(!u||!u.day)return;A.current&&(clearTimeout(A.current),A.current=null),ee(u);const T=a.currentTarget.getBoundingClientRect(),v=typeof window<"u"?window.innerWidth:1024,X=T.left+T.width/2,H=T.top,G=140;let t=0;X<G?t=G-X:X>v-G&&(t=v-G-X),he({x:X,y:H,shiftX:t})},ge=()=>{A.current&&clearTimeout(A.current),A.current=setTimeout(()=>{ee(null)},150)},K=()=>{F(!1),pe(!0)},se=()=>{F(!0)},ye=a=>{a.target===a.currentTarget&&q&&(pe(!1),F(!1))};i.useEffect(()=>{if(!j||q)return;const a=u=>{u.key==="Escape"&&se()};return window.addEventListener("keydown",a),()=>{window.removeEventListener("keydown",a)}},[j,q]);const ce=i.useMemo(()=>({emerald:{accentText:"text-emerald-500 dark:text-emerald-400",accentBg:"bg-emerald-500/10 dark:bg-emerald-400/10",accentBorder:"border-emerald-500/20 dark:border-emerald-400/15",hoverBorder:"hover:border-emerald-500/30 dark:hover:border-emerald-400/30",hoverGlow:"hover:shadow-[0_0_20px_-3px_rgba(16,185,129,0.15)] hover:dark:shadow-[0_0_20px_-3px_rgba(52,211,153,0.25)]",rawColor:"#10b981"},ocean:{accentText:"text-blue-500 dark:text-blue-400",accentBg:"bg-blue-500/10 dark:bg-blue-400/10",accentBorder:"border-blue-500/20 dark:border-blue-400/15",hoverBorder:"hover:border-blue-500/30 dark:hover:border-blue-400/30",hoverGlow:"hover:shadow-[0_0_20px_-3px_rgba(59,130,246,0.15)] hover:dark:shadow-[0_0_20px_-3px_rgba(96,165,250,0.25)]",rawColor:"#3b82f6"},neon:{accentText:"text-purple-500 dark:text-purple-400",accentBg:"bg-purple-500/10 dark:bg-purple-400/10",accentBorder:"border-purple-500/20 dark:border-purple-400/15",hoverBorder:"hover:border-purple-500/30 dark:hover:border-purple-400/30",hoverGlow:"hover:shadow-[0_0_20px_-3px_rgba(168,85,247,0.15)] hover:dark:shadow-[0_0_20px_-3px_rgba(192,132,252,0.25)]",rawColor:"#a855f7"},amber:{accentText:"text-amber-500 dark:text-amber-400",accentBg:"bg-amber-500/10 dark:bg-amber-400/10",accentBorder:"border-amber-500/20 dark:border-amber-400/15",hoverBorder:"hover:border-amber-500/30 dark:hover:border-amber-400/30",hoverGlow:"hover:shadow-[0_0_20px_-3px_rgba(245,158,11,0.15)] hover:dark:shadow-[0_0_20px_-3px_rgba(245,158,11,0.25)]",rawColor:"#f59e0b"}}),[]),U=ce[Y]||ce.emerald,be=Q[Y]?E?Q[Y].dark:Q[Y].light:E?Q.emerald.dark:Q.emerald.light,[b,de]=i.useState(()=>{if(z)return"2d";try{return window.localStorage?.getItem("tt:heatmap-view")==="3d"?"3d":"2d"}catch{return"2d"}});i.useEffect(()=>{if(!z)try{window.localStorage?.setItem("tt:heatmap-view",b)}catch{}},[b,z]),i.useEffect(()=>{if(b!=="2d")return;const a=_.current;a&&(a.scrollLeft=a.scrollWidth)},[l?.weeks,b]),i.useEffect(()=>{const a=_.current;if(!a)return;const u=()=>{A.current&&(clearTimeout(A.current),A.current=null),ee(null)};return a.addEventListener("scroll",u),()=>a.removeEventListener("scroll",u)},[]);const V=l?.week_starts_on==="mon"?"mon":"sun",xe=i.useMemo(()=>{const a=Array.isArray(l?.weeks)?l.weeks:[];if(!a.length)return{weeks:[]};const u=[];for(const T of a)for(const v of Array.isArray(T)?T:[])v?.day&&u.push({day:v.day,total_tokens:v.total_tokens??v.value??0,billable_total_tokens:v.billable_total_tokens??v.value??v.total_tokens??0,models:v.models??null});return Fe({dailyRows:u,weeks:Math.max(52,a.length),to:l?.to,weekStartsOn:V})},[l?.to,l?.weeks,V]),y=xe?.weeks||[],C=i.useMemo(()=>{let a=0,u=0,T={day:"无数据",value:0},v=0,X=0;const H=[];y.forEach(f=>{(Array.isArray(f)?f:[]).forEach(g=>{g&&g.day&&H.push(g)})}),H.sort((f,g)=>f.day.localeCompare(g.day)),H.forEach(f=>{const g=Number(f.value)||0;a+=g,g>0?(u++,v++,v>X&&(X=v)):v=0,g>T.value&&(T={day:f.day,value:g})});const G=H.length||365,t=(u/G*100).toFixed(1);let r="heatmap.3d.modal.ai.eval.default",s="heatmap.3d.modal.ai.title.default";a>=15e6?(s="heatmap.3d.modal.ai.title.peak",r="heatmap.3d.modal.ai.eval.peak"):a>=5e6?(s="heatmap.3d.modal.ai.title.heavy",r="heatmap.3d.modal.ai.eval.heavy"):a>=1e6?(s="heatmap.3d.modal.ai.title.core",r="heatmap.3d.modal.ai.eval.core"):a>=2e4&&(s="heatmap.3d.modal.ai.title.steady",r="heatmap.3d.modal.ai.eval.steady");const o=l?.total_cost_usd,d=Number(o),k=o!=null&&(typeof o!="string"||o.trim()!=="")&&Number.isFinite(d)?d:a/15e5;return{totalTokens:a,activeDays:u,activeRate:t,maxSingleDay:T,maxStreak:X,aiEvaluationTitleKey:s,aiEvaluationKey:r,totalCostUsd:k}},[y,l?.total_cost_usd]),je=i.useMemo(()=>Ie(C.totalCostUsd,{currency:$,rate:S}),[C.totalCostUsd,$,S]),ve=V==="mon"?["Mon","Tue","Wed","Thu","Fri","Sat","Sun"].map(a=>n(`heatmap.day.${a.toLowerCase()}`)):["Sun","Mon","Tue","Wed","Thu","Fri","Sat"].map(a=>n(`heatmap.day.${a.toLowerCase()}`)),ke=i.useMemo(()=>ft(y.length,xe?.to,V,ne),[xe?.to,y.length,V,ne]);if(!y.length)return e.jsx("div",{className:"py-8 text-center text-sm text-oai-gray-500",children:n("heatmap.empty")});const J=z?10:it,ae=z?2:ct,le=z?22:dt,M=le+y.length*J+Math.max(0,y.length-1)*ae,R=`${le}px repeat(${y.length}, ${J}px)`;return e.jsxs("div",{ref:m,className:z?"relative":"relative rounded-xl border border-oai-gray-200 dark:border-oai-gray-800 bg-white dark:bg-oai-gray-900 p-5",children:[!z&&e.jsxs("div",{className:"flex items-baseline justify-between mb-3",children:[e.jsx("h3",{className:"text-sm font-medium text-oai-gray-500 dark:text-oai-gray-300 uppercase tracking-wide",children:n("heatmap.title")}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("div",{role:"tablist","aria-label":"Heatmap view",className:"flex rounded-md border border-oai-gray-200 dark:border-oai-gray-800 p-0.5 text-[10px]",children:[e.jsx("button",{type:"button",role:"tab","aria-selected":b==="2d",onClick:()=>de("2d"),className:b==="2d"?"px-2 py-0.5 rounded bg-oai-gray-100 text-oai-black dark:bg-oai-gray-800 dark:text-oai-white font-medium":"px-2 py-0.5 rounded text-oai-gray-500 dark:text-oai-gray-400 hover:text-oai-gray-700 dark:hover:text-oai-gray-200",children:n("heatmap.view.2d")}),e.jsx("button",{type:"button",role:"tab","aria-selected":b==="3d",onClick:()=>de("3d"),className:b==="3d"?"px-2 py-0.5 rounded bg-oai-gray-100 text-oai-black dark:bg-oai-gray-800 dark:text-oai-white font-medium":"px-2 py-0.5 rounded text-oai-gray-500 dark:text-oai-gray-400 hover:text-oai-gray-700 dark:hover:text-oai-gray-200",children:n("heatmap.view.3d")})]}),e.jsx("span",{className:"text-xs text-oai-gray-400 dark:text-oai-gray-450",children:p||n("heatmap.legend.utc")})]})]}),b==="3d"&&e.jsxs("div",{onClick:K,className:"cursor-pointer group relative overflow-hidden rounded-lg hover:border-oai-gray-350 dark:hover:border-oai-gray-700 border border-transparent transition-all",title:n("heatmap.3d.hover_tip"),children:[e.jsx(_e,{weeks:y,isDark:E,palette:Y}),e.jsx("div",{className:"absolute inset-0 bg-gradient-to-t from-oai-gray-900/5 to-transparent pointer-events-none opacity-0 group-hover:opacity-100 transition-opacity flex items-end justify-center pb-2",children:e.jsxs("span",{className:"text-[10px] bg-white/95 dark:bg-oai-gray-900/95 shadow border border-oai-gray-200/60 dark:border-oai-gray-800/80 px-2.5 py-1 rounded-full font-medium text-oai-gray-500 dark:text-oai-gray-400 flex items-center gap-1 transform translate-y-2 group-hover:translate-y-0 transition-transform duration-200",children:[e.jsx(Ve,{size:9}),n("heatmap.3d.hover_tip")]})})]}),b==="2d"&&e.jsx("div",{ref:_,className:"overflow-x-auto overflow-y-hidden heatmap-scroll-thin",children:e.jsxs("div",{style:{minWidth:M},children:[e.jsxs("div",{className:"grid text-[10px] uppercase text-oai-gray-400 dark:text-oai-gray-400 mb-1",style:{gridTemplateColumns:R,columnGap:ae},children:[e.jsx("span",{}),ke.map(a=>e.jsx("span",{style:{gridColumnStart:a.index+2},className:"whitespace-nowrap",children:a.label},`${a.label}-${a.index}`))]}),e.jsxs("div",{className:"grid",style:{gridTemplateColumns:R,columnGap:ae},children:[e.jsx("div",{className:"grid text-[10px] text-oai-gray-400 dark:text-oai-gray-400 sticky left-0 bg-white dark:bg-oai-gray-900 pr-2",style:{gridTemplateRows:`repeat(7, ${J}px)`,rowGap:ae},children:ve.map(a=>e.jsx("span",{className:"leading-none",children:a},a))}),e.jsx("div",{className:"grid",style:{gridAutoFlow:"column",gridTemplateRows:`repeat(7, ${J}px)`,gap:ae},children:y.map((a,u)=>(Array.isArray(a)?a:[]).map((T,v)=>{if(!T)return null;const X=T.day||`e-${u}-${v}`,H=Number(T.level)||0,G=L[H]||L[0];return e.jsx("span",{onMouseEnter:t=>fe(t,T),onMouseLeave:ge,className:"rounded-[2px] transition-transform hover:scale-125 hover:z-10 cursor-pointer",style:{width:J,height:J,background:G}},X)}))})]})]})}),!c&&e.jsxs("div",{className:"flex items-center justify-center gap-2 mt-3",children:[e.jsx("span",{className:"text-[10px] text-oai-gray-400 dark:text-oai-gray-400",children:n("heatmap.legend.less")}),e.jsx("div",{className:"flex gap-0.5",children:L.map((a,u)=>e.jsx("span",{className:"rounded-[1px]",style:{width:10,height:10,background:a}},u))}),e.jsx("span",{className:"text-[10px] text-oai-gray-400 dark:text-oai-gray-400",children:n("heatmap.legend.more")})]}),j&&e.jsx("div",{onAnimationEnd:ye,onClick:a=>{a.target===a.currentTarget&&se()},className:`fixed inset-0 z-50 flex items-center justify-center p-3 md:p-6 backdrop-blur-md bg-black/15 dark:bg-black/40 ${q?"animate-tt-fade-out":"animate-tt-fade-in"}`,children:e.jsxs("div",{className:`relative w-full max-w-6xl h-[88vh] backdrop-blur-2xl bg-white/90 dark:bg-oai-gray-900/90 border border-oai-gray-200/50 dark:border-white/10 shadow-2xl rounded-2xl flex flex-col md:flex-row overflow-hidden ${q?"animate-tt-modal-exit":"animate-tt-modal"}`,children:[e.jsx("button",{type:"button",onClick:se,className:"absolute top-4 right-4 z-50 p-2 rounded-full border border-oai-gray-200/60 dark:border-oai-gray-800/60 bg-white/50 dark:bg-oai-gray-900/50 text-oai-gray-500 dark:text-oai-gray-400 hover:text-oai-gray-900 dark:hover:text-white hover:rotate-90 hover:scale-105 active:scale-95 transition-all duration-300",children:e.jsx(He,{size:16})}),e.jsxs("div",{className:"w-full md:w-[340px] border-b md:border-b-0 md:border-r border-zinc-200/50 dark:border-zinc-800/40 p-5 md:p-6 flex flex-col gap-6 overflow-y-auto backdrop-blur-md bg-zinc-50/50 dark:bg-zinc-950/50",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-1.5 select-none",children:[e.jsxs("span",{className:"relative flex h-1.5 w-1.5",children:[e.jsx("span",{className:"animate-ping absolute inline-flex h-full w-full rounded-full opacity-75",style:{backgroundColor:U.rawColor}}),e.jsx("span",{className:"relative inline-flex rounded-full h-1.5 w-1.5",style:{backgroundColor:U.rawColor}})]}),e.jsx("span",{className:"text-[9px] font-extrabold uppercase tracking-widest font-mono text-zinc-400 dark:text-zinc-500",children:"3D Insight"})]}),e.jsx("h4",{className:"text-xl font-black text-zinc-900 dark:text-zinc-50 tracking-tight leading-none mt-2 select-none",children:n("heatmap.3d.modal.title")}),e.jsx("p",{className:"text-[11px] leading-relaxed text-zinc-400 dark:text-zinc-500 mt-2 font-normal select-none",children:n("heatmap.3d.modal.desc")})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-5 gap-y-5 border-y border-zinc-200/50 dark:border-zinc-800/50 py-5 select-none",children:[e.jsxs("div",{className:"flex flex-col gap-1 relative group cursor-help",children:[e.jsx("div",{className:"absolute left-0 bottom-full mb-2 pointer-events-none opacity-0 translate-y-1 group-hover:opacity-100 group-hover:translate-y-0 transition-all duration-200 z-50",children:e.jsxs("div",{className:"bg-white dark:bg-zinc-950 text-zinc-900 dark:text-zinc-50 text-[10px] font-semibold font-mono rounded-lg px-2.5 py-1.5 shadow-xl border border-zinc-200 dark:border-zinc-800/80 whitespace-nowrap flex flex-col",children:[e.jsx("span",{className:"text-[9px] text-zinc-400 dark:text-zinc-500",children:n("heatmap.3d.modal.stats.precision_total_tokens")}),e.jsxs("span",{className:"mt-0.5 font-bold text-zinc-900 dark:text-zinc-50",children:[C.totalTokens.toLocaleString()," Tokens"]})]})}),e.jsx("span",{className:"text-[9px] font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest font-mono",children:n("heatmap.3d.modal.stats.total_tokens")}),e.jsxs("div",{className:"flex items-baseline gap-1.5",children:[e.jsx("span",{className:"text-xl font-black text-zinc-900 dark:text-zinc-50 tracking-tight font-mono transition-transform duration-200 group-hover:-translate-y-[1px]",children:$e(C.totalTokens)}),e.jsx("div",{className:"opacity-30 group-hover:opacity-60 transition-opacity",children:e.jsx("svg",{width:"24",height:"10",viewBox:"0 0 24 10",fill:"none",children:e.jsx("path",{d:"M1 9C3 7 5 7 7 4C9 1 11 0 13 2C15 4 17 0 23 0",stroke:U.rawColor,strokeWidth:"1.2",strokeLinecap:"round",strokeLinejoin:"round"})})})]})]}),e.jsxs("div",{className:"flex flex-col gap-1 group cursor-default",children:[e.jsx("span",{className:"text-[9px] font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest font-mono",children:n("heatmap.3d.modal.stats.estimated_cost")}),e.jsx("span",{className:"text-xl font-black text-zinc-900 dark:text-zinc-50 tracking-tight font-mono transition-transform duration-200 group-hover:-translate-y-[1px]",children:je})]}),e.jsxs("div",{className:"flex flex-col gap-1 group cursor-default",children:[e.jsx("span",{className:"text-[9px] font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest font-mono",children:n("heatmap.3d.modal.stats.active_rate_days")}),e.jsxs("span",{className:"text-xl font-black text-zinc-900 dark:text-zinc-50 tracking-tight font-mono transition-transform duration-200 group-hover:-translate-y-[1px]",children:[C.activeRate,"% ",e.jsxs("span",{className:"text-[10px] font-bold text-zinc-400 dark:text-zinc-500 font-mono",children:["(",C.activeDays,"D)"]})]})]}),e.jsxs("div",{className:"flex flex-col gap-1 group cursor-default",children:[e.jsx("span",{className:"text-[9px] font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest font-mono",children:n("heatmap.3d.modal.stats.max_streak")}),e.jsxs("span",{className:"text-xl font-black text-amber-500 tracking-tight font-mono transition-transform duration-200 group-hover:-translate-y-[1px]",children:[C.maxStreak," ",e.jsx("span",{className:"text-[10px] font-bold text-amber-500/80 font-mono",children:n("heatmap.3d.modal.stats.days_suffix")})]})]}),e.jsxs("div",{className:"flex flex-col gap-1 col-span-2 relative group cursor-help",children:[e.jsx("div",{className:"absolute left-0 bottom-full mb-2 pointer-events-none opacity-0 translate-y-1 group-hover:opacity-100 group-hover:translate-y-0 transition-all duration-200 z-50",children:e.jsxs("div",{className:"bg-white dark:bg-zinc-950 text-zinc-900 dark:text-zinc-50 text-[10px] font-semibold font-mono rounded-lg px-2.5 py-1.5 shadow-xl border border-zinc-200 dark:border-zinc-800/80 whitespace-nowrap flex flex-col",children:[e.jsx("span",{className:"text-[9px] text-zinc-400 dark:text-zinc-500",children:n("heatmap.3d.modal.stats.precision_peak_value")}),e.jsxs("span",{className:"mt-0.5 font-bold text-zinc-900 dark:text-zinc-50",children:[C.maxSingleDay.value>0?C.maxSingleDay.value.toLocaleString():n("heatmap.3d.modal.stats.no_data")," Tokens"]}),e.jsx("span",{className:"text-[8px] text-zinc-400 dark:text-zinc-500 mt-0.5",children:C.maxSingleDay.day!=="无数据"?C.maxSingleDay.day:n("heatmap.3d.modal.stats.no_data")})]})}),e.jsx("span",{className:"text-[9px] font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest font-mono",children:n("heatmap.3d.modal.stats.peak_day")}),e.jsxs("span",{className:"text-xl font-black text-zinc-900 dark:text-zinc-50 tracking-tight font-mono transition-transform duration-200 group-hover:-translate-y-[1px]",children:[C.maxSingleDay.value>0?$e(C.maxSingleDay.value):n("heatmap.3d.modal.stats.no_data")," ",e.jsxs("span",{className:"text-[10px] font-bold text-zinc-400 dark:text-zinc-500 font-mono",children:["(",C.maxSingleDay.day!=="无数据"?C.maxSingleDay.day:n("heatmap.3d.modal.stats.no_data"),")"]})]})]})]}),e.jsxs("div",{className:"flex flex-col gap-2.5 py-1",children:[e.jsxs("div",{className:"flex items-center gap-1.5 select-none",children:[e.jsx(nt,{size:11,style:{color:U.rawColor}}),e.jsx("span",{className:"text-[9px] font-extrabold uppercase tracking-widest font-mono",style:{color:U.rawColor},children:n(C.aiEvaluationTitleKey)})]}),e.jsxs("div",{className:"pl-3.5 border-l-2 relative transition-all duration-300 group",style:{borderColor:U.rawColor},children:[e.jsx("div",{className:"absolute inset-y-0 left-0 w-[3px] blur-[2px] opacity-15 pointer-events-none rounded-full",style:{backgroundColor:U.rawColor}}),e.jsx("p",{className:"text-[11px] leading-relaxed text-zinc-600 dark:text-zinc-400 font-normal",children:n(C.aiEvaluationKey)})]})]}),e.jsx("div",{className:"mt-auto border-t border-zinc-200/50 dark:border-zinc-800/50 pt-4 select-none",children:e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[9px] font-bold text-zinc-400 dark:text-zinc-500 uppercase tracking-widest font-mono",children:n("heatmap.3d.modal.legend.title")}),e.jsx("span",{className:"text-[10px] font-medium text-zinc-500 dark:text-zinc-400",children:n(`heatmap.3d.modal.palette.${Y}`)})]}),e.jsx("div",{className:"flex gap-1",children:be.map((a,u)=>e.jsx("div",{className:"flex-1 h-1 rounded-[2px]",style:{backgroundColor:a},title:`Level ${u}`},u))})]})})]}),e.jsxs("div",{className:"flex-1 h-full relative flex items-center justify-center overflow-hidden p-4",children:[e.jsx("div",{className:"absolute top-1/4 left-1/3 w-96 h-96 rounded-full blur-[130px] pointer-events-none -translate-x-1/2 -translate-y-1/2 transition-all duration-500",style:{backgroundColor:U.rawColor+"15"}}),e.jsx("div",{className:"absolute bottom-1/4 right-1/3 w-80 h-80 rounded-full blur-[120px] pointer-events-none translate-x-1/2 translate-y-1/2 bg-purple-500/[0.04] dark:bg-purple-500/[0.08]"}),e.jsxs("div",{className:"absolute top-4 left-1/2 -translate-x-1/2 flex items-center gap-3 p-1.5 backdrop-blur-md bg-white/70 dark:bg-oai-gray-900/75 border border-oai-gray-200/60 dark:border-oai-gray-800/80 rounded-full shadow-lg z-30 select-none",children:[e.jsx("div",{className:"flex items-center gap-1.5 px-2",children:Object.keys(ce).map(a=>{const u=Y===a;return e.jsx("button",{type:"button",onClick:()=>oe(a),title:n(`heatmap.3d.modal.palette.${a}`),className:`w-3.5 h-3.5 rounded-full transition-all duration-200 relative hover:scale-125 ${a==="emerald"?"bg-[#10b981]":a==="ocean"?"bg-[#3b82f6]":a==="neon"?"bg-[#a855f7]":"bg-[#f59e0b]"}`,children:u&&e.jsx("span",{className:"absolute inset-0 rounded-full ring-2 ring-offset-1 ring-offset-white dark:ring-offset-oai-gray-900 ring-oai-gray-900 dark:ring-white scale-110"})},a)})}),e.jsx("div",{className:"w-[1px] h-4 bg-oai-gray-200 dark:bg-oai-gray-800"}),e.jsxs("div",{className:"flex items-center gap-1 pr-1",children:[e.jsx("button",{type:"button",onClick:()=>{const a=!W;ie(a),Z.current&&Z.current.toggleAutoRotate(a)},title:W?n("heatmap.3d.modal.control.pause"):n("heatmap.3d.modal.control.play"),className:`p-1.5 rounded-full transition-all duration-200 hover:bg-oai-gray-100 dark:hover:bg-oai-gray-800 ${W?U.accentText:"text-oai-gray-400 hover:text-oai-gray-600 dark:hover:text-oai-gray-250"}`,children:W?e.jsx(Qe,{size:12}):e.jsx(tt,{size:12})}),e.jsx("button",{type:"button",onClick:()=>{ie(!1),Z.current&&Z.current.reset()},title:n("heatmap.3d.modal.control.reset"),className:"p-1.5 rounded-full text-oai-gray-400 hover:text-oai-gray-600 dark:hover:text-oai-gray-250 hover:bg-oai-gray-100 dark:hover:bg-oai-gray-800 transition-all duration-200",children:e.jsx(rt,{size:12})})]})]}),e.jsx(_e,{weeks:y,isDark:E,interactive:!0,palette:Y,autoRotateInit:W,onResetViewRef:Z}),e.jsxs("div",{className:"absolute bottom-4 right-4 flex items-center gap-1.5 text-[9px] font-bold text-oai-gray-400 bg-white/80 dark:bg-oai-gray-900/80 border border-oai-gray-200/50 dark:border-oai-gray-800/80 rounded-md px-2.5 py-1.5 select-none pointer-events-none backdrop-blur-md shadow-sm",children:[e.jsx(Ze,{size:10,className:U.accentText}),e.jsx("span",{children:n("heatmap.3d.modal.footer.tip")})]})]})]})}),N&&!j&&typeof document<"u"&&Ge.createPortal(e.jsxs("div",{className:"fixed z-[9999] w-0 h-0 transition-all duration-100 ease-out pointer-events-none",style:{left:`${te.x}px`,top:`${te.y}px`},children:[e.jsxs("div",{className:"absolute left-0 bottom-[10px] backdrop-blur-md bg-white/95 dark:bg-oai-gray-900/95 border border-oai-gray-200/50 dark:border-oai-gray-800/50 shadow-xl rounded-xl p-3.5 max-w-[280px] min-w-[200px] flex flex-col gap-2 animate-in fade-in zoom-in-95 duration-100",style:{transform:`translateX(calc(-50% + ${te.shiftX}px))`},children:[e.jsxs("div",{className:"flex items-center justify-between border-b border-oai-gray-100 dark:border-oai-gray-800/80 pb-1.5",children:[e.jsx("span",{className:"text-[11px] font-semibold text-oai-gray-500 dark:text-oai-gray-400",children:N.day}),(()=>{const a=N.level===0?E?"#9ca3af":"#6b7280":L[N.level];return e.jsxs("span",{className:"text-[10px] px-2 py-0.5 rounded-full font-medium",style:{backgroundColor:a+"22",color:a,border:`1px solid ${a}44`},children:["Level ",N.level]})})()]}),e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-baseline gap-1",children:[e.jsx("span",{className:"text-lg font-bold text-oai-gray-900 dark:text-white leading-none",children:Number(N.total_tokens??N.value).toLocaleString()}),e.jsx("span",{className:"text-[10px] text-oai-gray-400 uppercase tracking-wider font-semibold",children:"Tokens"})]}),N.models&&Object.keys(N.models).length>0?e.jsxs("div",{className:"mt-1.5 border-t border-oai-gray-100 dark:border-oai-gray-800/60 pt-2 flex flex-col gap-1.5",children:[e.jsx("div",{className:"text-[10px] font-semibold text-oai-gray-400 dark:text-oai-gray-500 uppercase tracking-wider",children:"Model Breakdown"}),e.jsx("div",{className:"flex flex-col gap-2 max-h-[150px] overflow-y-auto pr-1.5 oai-scrollbar",children:Object.entries(N.models).map(([a,u])=>({name:a,val:Number(u)})).sort((a,u)=>u.val-a.val).map(({name:a,val:u})=>{const T=Number(N.total_tokens??N.value)||1,v=Math.round(u/T*100);return e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex items-center justify-between text-[11px] gap-3",children:[e.jsx("span",{className:"font-medium text-oai-gray-750 dark:text-oai-gray-200 truncate max-w-[120px]",title:a,children:a}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[e.jsx("span",{className:"font-mono text-oai-gray-900 dark:text-oai-gray-100 font-semibold",children:u.toLocaleString()}),e.jsxs("span",{className:"text-[9px] text-oai-gray-450 dark:text-oai-gray-500 min-w-[28px] text-right font-medium",children:[v,"%"]})]})]}),e.jsx("div",{className:"w-full h-1 bg-oai-gray-100 dark:bg-oai-gray-800/85 rounded-full overflow-hidden",children:e.jsx("div",{className:"h-full rounded-full transition-all duration-300",style:{width:`${v}%`,backgroundColor:L[4],boxShadow:`0 0 4px ${L[4]}55`}})})]},a)})})]}):e.jsx("p",{className:"text-[11px] text-oai-gray-600 dark:text-oai-gray-300 leading-relaxed font-normal mt-1 border-t border-dashed border-oai-gray-100 dark:border-oai-gray-800/60 pt-1.5",children:Se(N.level,N.total_tokens??N.value)})]})]}),e.jsx("div",{className:"absolute bottom-[6px] left-0 -translate-x-1/2 w-2.5 h-2.5 rotate-45 bg-white dark:bg-oai-gray-900 border-r border-b border-oai-gray-200/50 dark:border-oai-gray-800/50 shadow-sm",style:{marginBottom:"1px"}})]}),document.body),e.jsx("style",{children:`
2
- @keyframes tt-fade-in {
3
- from { opacity: 0; }
4
- to { opacity: 1; }
5
- }
6
- @keyframes tt-fade-out {
7
- from { opacity: 1; }
8
- to { opacity: 0; }
9
- }
10
- @keyframes tt-modal-entrance {
11
- from {
12
- opacity: 0;
13
- transform: scale(0.96) translateY(10px);
14
- }
15
- to {
16
- opacity: 1;
17
- transform: scale(1) translateY(0);
18
- }
19
- }
20
- @keyframes tt-modal-exit {
21
- from {
22
- opacity: 1;
23
- transform: scale(1) translateY(0);
24
- }
25
- to {
26
- opacity: 0;
27
- transform: scale(0.96) translateY(10px);
28
- }
29
- }
30
- .animate-tt-fade-in {
31
- animation: tt-fade-in 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
32
- }
33
- .animate-tt-fade-out {
34
- animation: tt-fade-out 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
35
- }
36
- .animate-tt-modal {
37
- animation: tt-modal-entrance 0.3s cubic-bezier(0.34, 1.3, 0.64, 1) forwards;
38
- }
39
- .animate-tt-modal-exit {
40
- animation: tt-modal-exit 0.2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
41
- }
42
- `})]})}export{vt as A,Ve as M,nt as T};