tokentracker-cli 1.1.1 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/README.de.md +5 -4
  2. package/README.ja.md +5 -4
  3. package/README.ko.md +5 -4
  4. package/README.md +6 -4
  5. package/README.zh-CN.md +5 -4
  6. package/dashboard/dist/assets/{AchievementBadge-Dk6u95zc.js → AchievementBadge-dt_UDU_h.js} +1 -1
  7. package/dashboard/dist/assets/{AchievementsPage-DGzIJJ2h.js → AchievementsPage-B5DJ3S9l.js} +2 -2
  8. package/dashboard/dist/assets/{AchievementsSection-DaVrpiJ4.js → AchievementsSection-CDxcyig2.js} +1 -1
  9. package/dashboard/dist/assets/{BadgeDetailModal-BFCscxTM.js → BadgeDetailModal-Cp98zNn2.js} +1 -1
  10. package/dashboard/dist/assets/{BotAnimated-CrQkI3wD.js → BotAnimated-CR7MiUpo.js} +1 -1
  11. package/dashboard/dist/assets/{Card-vaZ1_mSY.js → Card-C8IdDvlg.js} +1 -1
  12. package/dashboard/dist/assets/{ClawdAnimated-CV14fpL_.js → ClawdAnimated-COeTlW8z.js} +2 -2
  13. package/dashboard/dist/assets/{CommandPalette-XAR6FIiO.js → CommandPalette-Co9k2CCc.js} +1 -1
  14. package/dashboard/dist/assets/{CommunityStatsModal-DcMf6LXP.js → CommunityStatsModal-C6XQeRgw.js} +1 -1
  15. package/dashboard/dist/assets/{ConfirmModal-Cf6rWUl4.js → ConfirmModal-Ai4182O-.js} +1 -1
  16. package/dashboard/dist/assets/{Controls-BQLLIIii.js → Controls-BbKzN-Pe.js} +1 -1
  17. package/dashboard/dist/assets/{DashboardPage-wXkhfR3l.js → DashboardPage-DTcVGG4e.js} +1 -1
  18. package/dashboard/dist/assets/{DevicePage-DzCAsvYS.js → DevicePage-CZbrtJmb.js} +1 -1
  19. package/dashboard/dist/assets/{DialogClose-Dh1DXLjH.js → DialogClose-DMl8tAoX.js} +1 -1
  20. package/dashboard/dist/assets/DialogDescription-haPz7CX9.js +1 -0
  21. package/dashboard/dist/assets/{DialogTitle-BhRP2R4n.js → DialogTitle-BJxpp2t-.js} +1 -1
  22. package/dashboard/dist/assets/{FadeIn-C0rmYYmJ.js → FadeIn-hU_MXl6R.js} +1 -1
  23. package/dashboard/dist/assets/{HeaderGithubStar-198FQmDH.js → HeaderGithubStar-CM5RSxxN.js} +1 -1
  24. package/dashboard/dist/assets/{HoverTooltip-ClzkNc3q.js → HoverTooltip-BZKfQyZQ.js} +1 -1
  25. package/dashboard/dist/assets/{IpCheckPage-DpN9xGZc.js → IpCheckPage-BjDx-zja.js} +1 -1
  26. package/dashboard/dist/assets/{LandingPage-BImwSrmg.js → LandingPage-CAt8BCDv.js} +2 -2
  27. package/dashboard/dist/assets/{LeaderboardAvatar-CU42rgGA.js → LeaderboardAvatar-DiCrakjI.js} +1 -1
  28. package/dashboard/dist/assets/{LeaderboardPage-Le_J0I7b.js → LeaderboardPage-Dj3pHv6U.js} +2 -2
  29. package/dashboard/dist/assets/{LeaderboardProfileModal-DLyu6a2Y.js → LeaderboardProfileModal-DEWbcP9p.js} +3 -3
  30. package/dashboard/dist/assets/{LeaderboardProfilePage-Dkfit9_X.js → LeaderboardProfilePage-CTbWHQkY.js} +1 -1
  31. package/dashboard/dist/assets/{LimitsPage-CNTDR2Yf.js → LimitsPage-V-98OUhF.js} +1 -1
  32. package/dashboard/dist/assets/{LocalOnlyNotice-DcjSbtm8.js → LocalOnlyNotice-a4PqtUZY.js} +1 -1
  33. package/dashboard/dist/assets/LoginCard-oD1A2Ru8.js +1 -0
  34. package/dashboard/dist/assets/{LoginModal-BHNs7soq.js → LoginModal-D8aSmxok.js} +1 -1
  35. package/dashboard/dist/assets/{LoginPage-DaaWeKvj.js → LoginPage-DIjhBv2X.js} +1 -1
  36. package/dashboard/dist/assets/{PetPage-DSDJvZy7.js → PetPage-D7601BTX.js} +1 -1
  37. package/dashboard/dist/assets/{PopoverPopup-BJrL_Eyg.js → PopoverPopup-aPnmKopO.js} +1 -1
  38. package/dashboard/dist/assets/{ProviderIcon-De08Y4_I.js → ProviderIcon-rwyfcNlT.js} +1 -1
  39. package/dashboard/dist/assets/{ResetPasswordPage-C4dwdur6.js → ResetPasswordPage-AF3SBgW2.js} +1 -1
  40. package/dashboard/dist/assets/{SegmentedControl-CJRmt3or.js → SegmentedControl-fnlScNMT.js} +1 -1
  41. package/dashboard/dist/assets/{Select-Dojy3Frf.js → Select-DDjC3RjB.js} +1 -1
  42. package/dashboard/dist/assets/{SelectItemText-_uysSMQl.js → SelectItemText-VhBWE2O8.js} +1 -1
  43. package/dashboard/dist/assets/{ServiceStatusPage-C3ZC1csM.js → ServiceStatusPage-BL3qqEsp.js} +1 -1
  44. package/dashboard/dist/assets/{SessionsPage-BG-VlDWP.js → SessionsPage-DXYiuP2x.js} +1 -1
  45. package/dashboard/dist/assets/{SettingsPage-Dr5gq6qj.js → SettingsPage-DTeA_ahr.js} +2 -2
  46. package/dashboard/dist/assets/{SkillsPage-Dh6Udkc3.js → SkillsPage-CtTRwVQH.js} +1 -1
  47. package/dashboard/dist/assets/{TokenGalaxy-MVMMCH06.js → TokenGalaxy-CifK91V7.js} +1 -1
  48. package/dashboard/dist/assets/{ToolbarRootContext-CPEvPTvc.js → ToolbarRootContext-ClGAIYoa.js} +1 -1
  49. package/dashboard/dist/assets/{TrendMonitor-uFX8OtrM.js → TrendMonitor-D1evFHRM.js} +1 -1
  50. package/dashboard/dist/assets/{WidgetsPage-BqyLjoN0.js → WidgetsPage-Cq4RYJDE.js} +1 -1
  51. package/dashboard/dist/assets/{WrappedPage-CIHbEOoq.js → WrappedPage-CoC5RJH7.js} +1 -1
  52. package/dashboard/dist/assets/__vite-browser-external-BDugA6I0.js +45 -0
  53. package/dashboard/dist/assets/__vite-browser-external-Bg0J-a5P.css +1 -0
  54. package/dashboard/dist/assets/{agent-logos-CAF9WeKO.js → agent-logos-QLdA9OeA.js} +1 -1
  55. package/dashboard/dist/assets/{arrow-up-right-y3EAs6Hg.js → arrow-up-right-BYLgB3bH.js} +1 -1
  56. package/dashboard/dist/assets/{check-BH5FRF8F.js → check-DfnIvqZD.js} +1 -1
  57. package/dashboard/dist/assets/{composite-Bl68G4Qr.js → composite--JllTpIX.js} +1 -1
  58. package/dashboard/dist/assets/{copy-Ce6L4gOk.js → copy-ClKVBIgD.js} +1 -1
  59. package/dashboard/dist/assets/{download-p1XPZSMa.js → download-Di1-UFJX.js} +1 -1
  60. package/dashboard/dist/assets/{external-link-DGnoQUQ1.js → external-link-D7zPVFLO.js} +1 -1
  61. package/dashboard/dist/assets/{flame-CltKUU4A.js → flame-BMJTxjVg.js} +1 -1
  62. package/dashboard/dist/assets/{format-tokens-BEIqtfnO.js → format-tokens-DCZM5Nfn.js} +1 -1
  63. package/dashboard/dist/assets/{icons-ByLLrgdQ.js → icons-I615W2IU.js} +1 -1
  64. package/dashboard/dist/assets/{index-CKkbTkf_.js → index-BX3CXVdD.js} +1 -1
  65. package/dashboard/dist/assets/{index-B79BltL7.js → index-BejnmdPe.js} +1 -1
  66. package/dashboard/dist/assets/{index-DU7IUcrN.js → index-CwczM3BZ.js} +1 -1
  67. package/dashboard/dist/assets/{info-DOCG1uXG.js → info-CFJPny5Q.js} +1 -1
  68. package/dashboard/dist/assets/{link-2-B0HME1R-.js → link-2-D1ydWh_w.js} +1 -1
  69. package/dashboard/dist/assets/{loader-circle-B6dVl4Im.js → loader-circle-Cq-J-OFg.js} +1 -1
  70. package/dashboard/dist/assets/{maximize-2-P4lRVuFz.js → maximize-2-kIoSq57I.js} +1 -1
  71. package/dashboard/dist/assets/{modifiers.esm-C8Hm25xI.js → modifiers.esm-CLojthuF.js} +1 -1
  72. package/dashboard/dist/assets/{monitor-smartphone-CoKP2dcs.js → monitor-smartphone-DX2qWHYV.js} +1 -1
  73. package/dashboard/dist/assets/{plus-CaDzdXql.js → plus-B-JEpo3V.js} +1 -1
  74. package/dashboard/dist/assets/{provider-display-Cr0tI5r6.js → provider-display-DJDdrTAS.js} +2 -2
  75. package/dashboard/dist/assets/{react-C9Bg9RXS.js → react-Ctoe8iLl.js} +1 -1
  76. package/dashboard/dist/assets/{search-CPdoCrMk.js → search-BTSQrlW-.js} +1 -1
  77. package/dashboard/dist/assets/{skills-api-DVU6coYZ.js → skills-api-DKQyM8h7.js} +1 -1
  78. package/dashboard/dist/assets/{sortable.esm-Cj2-YumT.js → sortable.esm-pOEL13xU.js} +1 -1
  79. package/dashboard/dist/assets/{store-npers9xW.js → store-B2RplzvW.js} +1 -1
  80. package/dashboard/dist/assets/{terminal-CJyI1G2f.js → terminal-BH_6_EW_.js} +1 -1
  81. package/dashboard/dist/assets/{trash-BMmBe_XE.js → trash-CC444Mz6.js} +1 -1
  82. package/dashboard/dist/assets/{use-community-stats-DPEyQ7FC.js → use-community-stats-CBXLdD_j.js} +1 -1
  83. package/dashboard/dist/assets/{use-latest-request-guard-BIjzEUC7.js → use-latest-request-guard-DMuPfZQI.js} +1 -1
  84. package/dashboard/dist/assets/{use-limits-display-prefs-Dx9nZB5K.js → use-limits-display-prefs-CmsGTBA4.js} +1 -1
  85. package/dashboard/dist/assets/{use-ordered-list-BVfyhpWi.js → use-ordered-list-BNJNpXjB.js} +1 -1
  86. package/dashboard/dist/assets/use-reduced-motion-CNpG-Yoi.js +1 -0
  87. package/dashboard/dist/assets/{use-session-efficiency-pref-DFdlqCsV.js → use-session-efficiency-pref-g_0ISxe1.js} +1 -1
  88. package/dashboard/dist/assets/{use-transform-DYM391E0.js → use-transform-D36BHcXk.js} +1 -1
  89. package/dashboard/dist/assets/{use-usage-limits-ucoHKjM6.js → use-usage-limits-Dxw3vzsD.js} +1 -1
  90. package/dashboard/dist/assets/{useCurrency-Cp27r6z0.js → useCurrency-V2FE4TMo.js} +1 -1
  91. package/dashboard/dist/assets/{useTokenFormat-CXx5hVTJ.js → useTokenFormat-CEOwvzMt.js} +1 -1
  92. package/dashboard/dist/assets/{zap-D2E3JNcE.js → zap-BS7ZU76I.js} +1 -1
  93. package/dashboard/dist/index.html +14 -12
  94. package/dashboard/dist/ip-check.html +2 -2
  95. package/dashboard/dist/leaderboard.html +2 -2
  96. package/dashboard/dist/llms.txt +3 -2
  97. package/dashboard/dist/share.html +2 -2
  98. package/package.json +2 -2
  99. package/src/commands/init.js +11 -0
  100. package/src/commands/status.js +30 -0
  101. package/src/commands/sync.js +37 -1
  102. package/src/lib/pricing/seed-snapshot.json +1 -1
  103. package/src/lib/rollout.js +648 -2
  104. package/src/lib/wsl-probe.js +55 -12
  105. package/dashboard/dist/assets/DialogDescription-wLKjV-9l.js +0 -1
  106. package/dashboard/dist/assets/LoginCard-CgpzXY1G.js +0 -1
  107. package/dashboard/dist/assets/__vite-browser-external-5P7me0Qq.css +0 -1
  108. package/dashboard/dist/assets/__vite-browser-external-oFHfLR8i.js +0 -45
  109. package/dashboard/dist/assets/use-reduced-motion-D_7LzLSe.js +0 -1
package/README.de.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  ### Sieh genau, was du für KI ausgibst – über jedes CLI hinweg
8
8
 
9
- Sammle automatisch Token-Zahlen von **41 KI-Coding-Tools**, aggregiere sie lokal und sieh echte Kostentrends in einem schönen Dashboard. Kein Cloud-Konto, keine API-Keys, kein Setup – nur ein Befehl.
9
+ Sammle automatisch Token-Zahlen von **42 KI-Coding-Tools**, aggregiere sie lokal und sieh echte Kostentrends in einem schönen Dashboard. Kein Cloud-Konto, keine API-Keys, kein Setup – nur ein Befehl.
10
10
 
11
11
  [![npm version](https://img.shields.io/npm/v/tokentracker-cli.svg?color=blue)](https://www.npmjs.com/package/tokentracker-cli)
12
12
  [![npm downloads](https://img.shields.io/npm/dm/tokentracker-cli.svg?color=brightgreen)](https://www.npmjs.com/package/tokentracker-cli)
@@ -92,7 +92,7 @@ Aktualisieren mit `brew upgrade --cask xiufengsun/tokentracker/tokentracker`. De
92
92
 
93
93
  ## ✨ Features
94
94
 
95
- - 🔌 **41 KI-Tools out of the box** — Claude Code, Codex CLI, AStudio, Cursor, Gemini CLI, Antigravity, Kiro, OpenCode, OpenClaw, Every Code, Hermes Agent, GitHub Copilot, Kimi Code, CodeBuddy, WorkBuddy, Grok Build, oh-my-pi, OmO, pi, Dots, Prime Agent, Craft Agents, Reasonix, Kilo CLI, Kilo Code, Roo Code, Zed Agent, Goose, Droid, Mimo Code, ZCode, Qoder, AnythingLLM Desktop, Claude Science, DeepSeek Harness, TRAE Work CN, LM Studio, Unsloth Studio, Devin CLI, Cline, MiniMax Code
95
+ - 🔌 **42 KI-Tools out of the box** — Claude Code, Codex CLI, AStudio, Cursor, Gemini CLI, Antigravity, Kiro, OpenCode, OpenClaw, Every Code, Hermes Agent, GitHub Copilot, Kimi Code, CodeBuddy, WorkBuddy, Grok Build, oh-my-pi, OmO, pi, Dots, Prime Agent, Craft Agents, Reasonix, Kilo CLI, Kilo Code, Roo Code, Zed Agent, Goose, Droid, Mimo Code, ZCode, Qoder, AnythingLLM Desktop, Claude Science, DeepSeek Harness, TRAE Work CN, LM Studio, Unsloth Studio, Devin CLI, Cline, MiniMax Code, Command Code
96
96
  - 🏠 **Local-First** — Läuft auf deinem Rechner. Parst Logs lokal, ohne Konto oder API-Keys.
97
97
  - 🚀 **Zero Config** — Hooks installieren sich beim ersten Start automatisch. Von null zum Dashboard in 30 Sekunden.
98
98
  - 📊 **Schönes Dashboard** — Nutzungstrends, Kostenaufschlüsselung nach Modell, GitHub-ähnliche Aktivitäts-Heatmap, Projektzuordnung
@@ -206,6 +206,7 @@ Aktualisieren mit `brew upgrade --cask xiufengsun/tokentracker/tokentracker`. De
206
206
  | **Devin CLI** (Cognition) | ✅ Auto | Passiver SQLite-Reader (`$XDG_DATA_HOME/devin/cli/sessions.db`, Standard `~/.local/share/devin/cli/sessions.db`). Liest Usage-Metriken pro Anfrage, dedupliziert nach `request_id` — Replay-/Fork-/Compaction-Kopien werden nicht doppelt gezählt — und verwendet das aufgezeichnete Generation-Modell; niemals Prompts, Antworten oder `cogs_json`. Für Devin-Modelle (`swe-2`, `swe-2-high`, `compactor`) gibt es derzeit keine Preisdaten: Token-Zahlen werden erfasst, aber nicht in Dollar-Schätzungen einbezogen — ein $0-Wert bedeutet keine kostenlose Nutzung. Kein bekanntes natives Windows-Datenverzeichnis; eine WSL-Installation wird über `\\wsl$` gelesen. |
207
207
  | **Cline** (CLI v3 / Desktop-App) | ✅ Auto | Passiver Reader (`~/.cline/data/sessions/<id>/*.messages.json`). Die `metrics` jedes Turns sind Usage-Deltas, in denen `inputTokens` bereits Cache-Lesen+Schreiben und `outputTokens` bereits Reasoning enthalten — der Cache-Präfix wird abgezogen und Reasoning nie doppelt abgerechnet; Clines eigener gemeldeter `cost` hat Vorrang. `cline-free/*`- und `cline-pass/*`-Gateway-Modelle kosten $0. Der globalStorage der VS-Code-Erweiterung wird nicht gelesen. Pfad-Overrides: `TOKENTRACKER_CLINE_SESSIONS_DIR`, `TOKENTRACKER_CLINE_DATA_DIR`, `TOKENTRACKER_CLINE_HOME`, `CLINE_SESSION_DATA_DIR`, `CLINE_DATA_DIR` oder `CLINE_DIR` |
208
208
  | **MiniMax Code** | ✅ Auto | Passiver Reader (`~/.minimax/v2/sessions/YYYY/MM/DD/<session>/messages.jsonl`). Dedupliziert nach `message_id`, erfasst das geroutete Upstream-Modell pro Nachricht und ignoriert das stets leere `usage.cost` zugunsten der normalen Preise. Verzeichnis per `TOKENTRACKER_MINIMAX_HOME` überschreibbar |
209
+ | **Command Code** | ✅ Auto | Passiver Session-Log-Reader (`~/.commandcode/projects/<cwd-slug>/<session-id>.jsonl`; `*.checkpoints.jsonl`-Snapshots und `.prompts.`-Begleitdateien werden übersprungen). Scannt Transkripte lokal und extrahiert ausgewählte Nutzungsmetadaten wie Token-Zähler und den CLI-Anzeigeschätzwert `costUsd`. Token Tracker schätzt die Kosten stattdessen anhand seiner gemeinsamen Modellpreistabelle. Zieht Cache-Lese- und Cache-Schreib-Tokens vom cache-inklusiven Input ab, um Doppelzählungen zu vermeiden. Prompt-, Antwort- und Code-Inhalte werden von Token Tracker weder gespeichert noch hochgeladen. Verzeichnis per `TOKENTRACKER_COMMANDCODE_HOME` überschreibbar |
209
210
  | **Claude Science** | ✅ Auto | Passiver SQLite-Reader (`~/.claude-science/operon-cli.db`, nur die Token-Zähler der `frames`-Tabelle; keine Prompts, Artefakte oder Forschungsinhalte). Kein natives Windows-Build — unter Windows läuft die App in WSL und wird von dort gelesen. |
210
211
  | **DeepSeek Harness** | ✅ Auto | Passiver Session-Reader (`~/.dsh/sessions/**/session.jsonl[.zstd]`; liest Session-Header und Assistant-Ereignisse, unterstützt Zstandard mit mehreren Frames) |
211
212
  | **TRAE Work CN** | ✅ Auto | **Erfordert eine ausdrückliche Zustimmung: `TOKENTRACKER_TRAE_CN_USAGE=1` setzen.** Das Lesen der Nutzung überträgt die lokal gespeicherte Anmeldeautorisierung an die interne API von TRAE, daher wird nichts gesendet, bevor du es aktivierst. Danach: liest bei vorhandener lokaler TRAE Work CN-Anmeldung während eines zulässigen Syncs außerhalb des Hintergrundbetriebs unter macOS die Session-Token-Nutzung der angemeldeten App; die interne API kann sich ändern |
@@ -229,7 +230,7 @@ Fehlt dein Tool? [Erstelle ein Issue](https://github.com/xiufengsun/TokenTracker
229
230
 
230
231
  | Funktion | **[TokenTracker](https://github.com/xiufengsun/TokenTracker)** | **[ccusage](https://github.com/ccusage/ccusage)** | **[Tokscale](https://github.com/junhoyeo/tokscale)** |
231
232
  |---|:---:|:---:|:---:|
232
- | **Unterstützte KI-Tools** | **41** | Multi-Agent | Multi-Agent |
233
+ | **Unterstützte KI-Tools** | **42** | Multi-Agent | Multi-Agent |
233
234
  | **Primäre Benutzeroberfläche** | Native Desktop-Apps & Web-Dashboard | Terminal-CLI | Terminal-TUI & CLI |
234
235
  | **Local-First-Analyse** | ✅ | ✅ | ✅ |
235
236
  | **Native Desktop-Apps** | ✅ macOS, Windows, Linux | ❌ | ❌ |
@@ -245,7 +246,7 @@ Fehlt dein Tool? [Erstelle ein Issue](https://github.com/xiufengsun/TokenTracker
245
246
 
246
247
  ```mermaid
247
248
  flowchart LR
248
- A["KI-Coding-Tools<br/>Claude · Codex · AStudio · Cursor · Gemini · Kiro<br/>OpenCode · OpenClaw · Every Code · Hermes · Copilot<br/>Kimi · CodeBuddy · WorkBuddy · Grok · Kilo · Roo · Zed · Goose<br/>Antigravity · oh-my-pi · pi · Craft · Droid · Mimo · ZCode · Qoder · AnythingLLM · Claude Science · DeepSeek Harness · TRAE Work CN · LM Studio · Unsloth Studio · Devin CLI · MiniMax Code · Cline"]
249
+ A["KI-Coding-Tools<br/>Claude · Codex · AStudio · Cursor · Gemini · Kiro<br/>OpenCode · OpenClaw · Every Code · Hermes · Copilot<br/>Kimi · CodeBuddy · WorkBuddy · Grok · Kilo · Roo · Zed · Goose<br/>Antigravity · oh-my-pi · pi · Craft · Droid · Mimo · ZCode · Qoder · AnythingLLM · Claude Science · DeepSeek Harness · TRAE Work CN · LM Studio · Unsloth Studio · Devin CLI · MiniMax Code · Cline · Command Code"]
249
250
  A -->|Hooks lösen aus| B[Token Tracker]
250
251
  B -->|Logs parsen<br/>30-Min-UTC-Buckets| C[(Lokales SQLite)]
251
252
  C --> D[Web-Dashboard]
package/README.ja.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  ### AI に使ったコストを正確に把握 — すべての CLI を横断して
8
8
 
9
- **41 種類の AI コーディングツール**からトークン数を自動収集し、ローカルで集計、美しいダッシュボードで本当のコスト推移を可視化します。クラウドアカウント不要、API キー不要、セットアップ不要 — コマンド 1 つで完了です。
9
+ **42 種類の AI コーディングツール**からトークン数を自動収集し、ローカルで集計、美しいダッシュボードで本当のコスト推移を可視化します。クラウドアカウント不要、API キー不要、セットアップ不要 — コマンド 1 つで完了です。
10
10
 
11
11
  [![npm version](https://img.shields.io/npm/v/tokentracker-cli.svg?color=blue)](https://www.npmjs.com/package/tokentracker-cli)
12
12
  [![npm downloads](https://img.shields.io/npm/dm/tokentracker-cli.svg?color=brightgreen)](https://www.npmjs.com/package/tokentracker-cli)
@@ -88,7 +88,7 @@ brew install xiufengsun/tokentracker/tokentracker
88
88
 
89
89
  ## ✨ 機能
90
90
 
91
- - 🔌 **41 種類の AI ツールを標準対応** — Claude Code、Codex CLI、AStudio、Cursor、Gemini CLI、Antigravity、Kiro、OpenCode、OpenClaw、Every Code、Hermes Agent、GitHub Copilot、Kimi Code、CodeBuddy、WorkBuddy、Grok Build、oh-my-pi、OmO、pi、Dots、Prime Agent、Craft Agents、Reasonix、Kilo CLI、Kilo Code、Roo Code、Zed Agent、Goose、Droid、Mimo Code、ZCode、Qoder、AnythingLLM Desktop、Claude Science、DeepSeek Harness、TRAE Work CN、LM Studio、Unsloth Studio、Devin CLI、Cline、MiniMax Code
91
+ - 🔌 **42 種類の AI ツールを標準対応** — Claude Code、Codex CLI、AStudio、Cursor、Gemini CLI、Antigravity、Kiro、OpenCode、OpenClaw、Every Code、Hermes Agent、GitHub Copilot、Kimi Code、CodeBuddy、WorkBuddy、Grok Build、oh-my-pi、OmO、pi、Dots、Prime Agent、Craft Agents、Reasonix、Kilo CLI、Kilo Code、Roo Code、Zed Agent、Goose、Droid、Mimo Code、ZCode、Qoder、AnythingLLM Desktop、Claude Science、DeepSeek Harness、TRAE Work CN、LM Studio、Unsloth Studio、Devin CLI、Cline、MiniMax Code、Command Code
92
92
  - 🏠 **ローカルファースト** — すべてマシン上で動作。アカウントや API キーなしでログをローカル解析します。
93
93
  - 🚀 **ゼロコンフィグ** — Hook は初回実行で自動インストール。0 からダッシュボードまで 30 秒。
94
94
  - 📊 **美しいダッシュボード** — 使用トレンド、モデル別コスト内訳、GitHub スタイルのアクティビティヒートマップ、プロジェクト別の帰属表示
@@ -203,6 +203,7 @@ brew install xiufengsun/tokentracker/tokentracker
203
203
  | **Devin CLI** (Cognition) | ✅ 自動 | パッシブな SQLite リーダー (`$XDG_DATA_HOME/devin/cli/sessions.db`、デフォルト `~/.local/share/devin/cli/sessions.db`)。`request_id` でリクエスト単位の usage 指標を重複排除 (replay/fork/compaction のコピーは二重計上しない) し、記録された generation model を使います。prompt・応答・`cogs_json` は読みません。Devin のモデル (`swe-2`、`swe-2-high`、`compactor`) には現在価格データがないため、token 数は報告されますがドル見積りからは除外されます — $0 表示は無料を意味しません。ネイティブ Windows のデータディレクトリは未確認で、WSL インストールは `\\wsl$` 経由で読み取ります。 |
204
204
  | **Cline**(CLI v3 / デスクトップアプリ) | ✅ 自動 | パッシブリーダー (`~/.cline/data/sessions/<id>/*.messages.json`)。各ターンの `metrics` は使用量差分で、`inputTokens` には cache 読み書きが、`outputTokens` には reasoning が既に含まれるため、キャッシュ済みプレフィックスは差し引かれ、reasoning は二重計上されません。Cline 自身が報告する `cost` を優先します。`cline-free/*`・`cline-pass/*` のゲートウェイモデルは $0 扱い。VS Code 拡張の globalStorage は読み取りません。パス上書き: `TOKENTRACKER_CLINE_SESSIONS_DIR`、`TOKENTRACKER_CLINE_DATA_DIR`、`TOKENTRACKER_CLINE_HOME`、`CLINE_SESSION_DATA_DIR`、`CLINE_DATA_DIR`、`CLINE_DIR` |
205
205
  | **MiniMax Code** | ✅ 自動 | パッシブリーダー (`~/.minimax/v2/sessions/YYYY/MM/DD/<session>/messages.jsonl`)。`message_id` で重複排除し、メッセージごとにルーティング先の上流モデルを記録します。常に 0 の `usage.cost` は使わず通常の料金表で計算します。ディレクトリは `TOKENTRACKER_MINIMAX_HOME` で上書き可能 |
206
+ | **Command Code** | ✅ 自動 | パッシブなセッションログリーダー (`~/.commandcode/projects/<cwd-slug>/<session-id>.jsonl`、`*.checkpoints.jsonl` スナップショットと `.prompts.` 補助ファイルはスキップ)。トランスクリプトをローカルでスキャンし、トークン数や CLI の表示用見積もり `costUsd` など、必要な使用量メタデータを抽出します。費用は Token Tracker の共通モデル料金表で推定します。キャッシュを含む input からキャッシュ読み取り・書き込みの両方を差し引き、二重計上を防ぎます。Token Tracker はプロンプト・応答・コードの本文を保存・アップロードしません。ディレクトリは `TOKENTRACKER_COMMANDCODE_HOME` で上書き可能 |
206
207
  | **Claude Science** | ✅ 自動 | パッシブな SQLite リーダー (`~/.claude-science/operon-cli.db`、`frames` テーブルの token カウンタのみ。prompt・成果物・研究内容は読みません)。ネイティブ Windows 版はなく、Windows では WSL 内で動作するアプリを読み取ります。 |
207
208
  | **DeepSeek Harness** | ✅ 自動 | パッシブなセッションリーダー (`~/.dsh/sessions/**/session.jsonl[.zstd]`、セッションヘッダーと assistant イベントを解析し、複数フレームの zstd 展開に対応) |
208
209
  | **TRAE Work CN** | ✅ 自動 | **明示的なオプトインが必要です: `TOKENTRACKER_TRAE_CN_USAGE=1` を設定してください。** 使用量の読み取りはローカルに保存されたサインイン認証を TRAE の内部 API に送信するため、有効にするまで何も送信されません。有効化後: ローカル TRAE Work CN のサインイン認証がある場合、実行可能な非バックグラウンド同期中に macOS のサインイン済みアプリから session-token 使用量を読み取ります。内部 API は変更される可能性があります |
@@ -227,7 +228,7 @@ brew install xiufengsun/tokentracker/tokentracker
227
228
 
228
229
  | 機能 | **[TokenTracker](https://github.com/xiufengsun/TokenTracker)** | **[ccusage](https://github.com/ccusage/ccusage)** | **[Tokscale](https://github.com/junhoyeo/tokscale)** |
229
230
  |---|:---:|:---:|:---:|
230
- | **対応 AI ツール数** | **41** | マルチエージェント | マルチエージェント |
231
+ | **対応 AI ツール数** | **42** | マルチエージェント | マルチエージェント |
231
232
  | **主なインターフェース** | ネイティブデスクトップアプリ & Web ダッシュボード | ターミナル CLI | ターミナル TUI & CLI |
232
233
  | **ローカルファースト解析** | ✅ | ✅ | ✅ |
233
234
  | **ネイティブデスクトップアプリ** | ✅ macOS, Windows, Linux | ❌ | ❌ |
@@ -243,7 +244,7 @@ brew install xiufengsun/tokentracker/tokentracker
243
244
 
244
245
  ```mermaid
245
246
  flowchart LR
246
- A["AI coding tools<br/>Claude Code · Codex · AStudio · Cursor · Gemini · Kiro<br/>OpenCode · OpenClaw · Every Code · Hermes · Copilot<br/>Kimi · CodeBuddy · WorkBuddy · Grok · Kilo · Roo · Zed · Goose<br/>Antigravity · oh-my-pi · pi · Craft · Droid · Mimo · ZCode · Qoder · AnythingLLM · Claude Science · DeepSeek Harness · TRAE Work CN · LM Studio · Unsloth Studio · Devin CLI · MiniMax Code · Cline"]
247
+ A["AI coding tools<br/>Claude Code · Codex · AStudio · Cursor · Gemini · Kiro<br/>OpenCode · OpenClaw · Every Code · Hermes · Copilot<br/>Kimi · CodeBuddy · WorkBuddy · Grok · Kilo · Roo · Zed · Goose<br/>Antigravity · oh-my-pi · pi · Craft · Droid · Mimo · ZCode · Qoder · AnythingLLM · Claude Science · DeepSeek Harness · TRAE Work CN · LM Studio · Unsloth Studio · Devin CLI · MiniMax Code · Cline · Command Code"]
247
248
  A -->|hooks trigger| B[Token Tracker]
248
249
  B -->|parse logs<br/>30-min UTC buckets| C[(Local SQLite)]
249
250
  C --> D[Web Dashboard]
package/README.ko.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  ### 모든 CLI에서 AI에 쓰는 비용을 정확히 파악
8
8
 
9
- **41개의 AI 코딩 도구**에서 토큰 수치를 자동으로 수집하고 로컬에서 집계해, 실제 비용 추세를 아름다운 대시보드에서 확인. 클라우드 계정 불필요, API Key 불필요, 셋업 불필요 — 명령 한 줄이면 끝.
9
+ **42개의 AI 코딩 도구**에서 토큰 수치를 자동으로 수집하고 로컬에서 집계해, 실제 비용 추세를 아름다운 대시보드에서 확인. 클라우드 계정 불필요, API Key 불필요, 셋업 불필요 — 명령 한 줄이면 끝.
10
10
 
11
11
  [![npm version](https://img.shields.io/npm/v/tokentracker-cli.svg?color=blue)](https://www.npmjs.com/package/tokentracker-cli)
12
12
  [![npm downloads](https://img.shields.io/npm/dm/tokentracker-cli.svg?color=brightgreen)](https://www.npmjs.com/package/tokentracker-cli)
@@ -88,7 +88,7 @@ brew install xiufengsun/tokentracker/tokentracker
88
88
 
89
89
  ## ✨ 기능
90
90
 
91
- - 🔌 **41개의 AI 도구 기본 지원** — Claude Code, Codex CLI, AStudio, Cursor, Gemini CLI, Antigravity, Kiro, OpenCode, OpenClaw, Every Code, Hermes Agent, GitHub Copilot, Kimi Code, CodeBuddy, WorkBuddy, Grok Build, oh-my-pi, OmO, pi, Dots, Prime Agent, Craft Agents, Reasonix, Kilo CLI, Kilo Code, Roo Code, Zed Agent, Goose, Droid, Mimo Code, ZCode, Qoder, AnythingLLM Desktop, Claude Science, DeepSeek Harness, TRAE Work CN, LM Studio, Unsloth Studio, Devin CLI, Cline, MiniMax Code
91
+ - 🔌 **42개의 AI 도구 기본 지원** — Claude Code, Codex CLI, AStudio, Cursor, Gemini CLI, Antigravity, Kiro, OpenCode, OpenClaw, Every Code, Hermes Agent, GitHub Copilot, Kimi Code, CodeBuddy, WorkBuddy, Grok Build, oh-my-pi, OmO, pi, Dots, Prime Agent, Craft Agents, Reasonix, Kilo CLI, Kilo Code, Roo Code, Zed Agent, Goose, Droid, Mimo Code, ZCode, Qoder, AnythingLLM Desktop, Claude Science, DeepSeek Harness, TRAE Work CN, LM Studio, Unsloth Studio, Devin CLI, Cline, MiniMax Code, Command Code
92
92
  - 🏠 **로컬 우선** — 내 컴퓨터에서 실행됩니다. 계정이나 API Key 없이 로그를 로컬에서 파싱합니다.
93
93
  - 🚀 **제로 설정** — 첫 실행 시 Hook 자동 설치. 0에서 대시보드까지 30초.
94
94
  - 📊 **아름다운 대시보드** — 사용 추세, 모델별 비용 분석, GitHub 스타일 활동 히트맵, 프로젝트 귀속 정보
@@ -203,6 +203,7 @@ brew install xiufengsun/tokentracker/tokentracker
203
203
  | **Devin CLI** (Cognition) | ✅ 자동 | 패시브 SQLite 리더 (`$XDG_DATA_HOME/devin/cli/sessions.db`, 기본값 `~/.local/share/devin/cli/sessions.db`). `request_id`로 요청 단위 usage 지표를 중복 제거하고 (replay/fork/compaction 복사본은 이중 집계하지 않음) 기록된 generation model을 사용합니다. prompt·응답·`cogs_json`은 읽지 않습니다. Devin 모델 (`swe-2`, `swe-2-high`, `compactor`)에는 현재 가격 데이터가 없어 token 수는 보고되지만 달러 추정치에서 제외됩니다 — $0 표시가 무료를 의미하지는 않습니다. 네이티브 Windows 데이터 디렉터리는 확인되지 않았으며 WSL 설치는 `\\wsl$`을 통해 읽습니다. |
204
204
  | **Cline** (CLI v3 / 데스크톱 앱) | ✅ 자동 | 패시브 리더 (`~/.cline/data/sessions/<id>/*.messages.json`). 턴별 `metrics`는 사용량 델타이며 `inputTokens`에 cache 읽기+쓰기가, `outputTokens`에 reasoning이 이미 포함되어 있어 캐시 접두사는 차감되고 reasoning은 이중 청구되지 않습니다. Cline이 직접 보고한 `cost`를 우선 사용합니다. `cline-free/*`·`cline-pass/*` 게이트웨이 모델은 $0로 책정. VS Code 확장의 globalStorage는 읽지 않습니다. 경로 오버라이드: `TOKENTRACKER_CLINE_SESSIONS_DIR`, `TOKENTRACKER_CLINE_DATA_DIR`, `TOKENTRACKER_CLINE_HOME`, `CLINE_SESSION_DATA_DIR`, `CLINE_DATA_DIR`, `CLINE_DIR` |
205
205
  | **MiniMax Code** | ✅ 자동 | 패시브 리더 (`~/.minimax/v2/sessions/YYYY/MM/DD/<session>/messages.jsonl`). `message_id`로 중복 제거하고 메시지마다 라우팅된 상위 모델을 기록합니다. 항상 0인 `usage.cost`는 쓰지 않고 일반 가격표로 계산합니다. 디렉터리는 `TOKENTRACKER_MINIMAX_HOME`으로 변경 가능 |
206
+ | **Command Code** | ✅ 자동 | 패시브 세션 로그 리더 (`~/.commandcode/projects/<cwd-slug>/<session-id>.jsonl`, `*.checkpoints.jsonl` 스냅샷과 `.prompts.` 보조 파일은 건너뜀). 세션 로그를 로컬에서 스캔하고 토큰 수와 CLI의 표시용 추정치 `costUsd` 등 필요한 사용량 메타데이터를 추출합니다. 비용은 Token Tracker의 공통 모델 가격표로 추정합니다. 캐시를 포함한 input에서 캐시 읽기와 쓰기 토큰을 모두 빼 이중 계산을 방지합니다. Token Tracker는 프롬프트·응답·코드 본문을 저장하거나 업로드하지 않습니다. 디렉터리는 `TOKENTRACKER_COMMANDCODE_HOME`으로 변경 가능 |
206
207
  | **Claude Science** | ✅ 자동 | 패시브 SQLite 리더 (`~/.claude-science/operon-cli.db`, `frames` 테이블의 token 카운터만 읽으며 prompt·산출물·연구 내용은 읽지 않음). 네이티브 Windows 빌드가 없어 Windows에서는 WSL 안에서 실행되는 앱을 읽습니다. |
207
208
  | **DeepSeek Harness** | ✅ 자동 | 패시브 세션 리더 (`~/.dsh/sessions/**/session.jsonl[.zstd]`, 세션 헤더와 assistant 이벤트를 파싱하고 멀티 프레임 zstd 압축 해제를 지원) |
208
209
  | **TRAE Work CN** | ✅ 자동 | **명시적인 옵트인이 필요합니다: `TOKENTRACKER_TRAE_CN_USAGE=1` 을 설정하세요.** 사용량을 읽으면 로컬에 저장된 로그인 인증이 TRAE의 내부 API로 전송되므로, 켜기 전에는 아무것도 전송되지 않습니다. 켠 뒤에는: 로컬 TRAE Work CN 인증이 있을 때 실행 가능한 비백그라운드 동기화 중에 macOS의 로그인된 앱에서 session-token 사용량을 읽습니다. 내부 API는 변경될 수 있습니다 |
@@ -227,7 +228,7 @@ brew install xiufengsun/tokentracker/tokentracker
227
228
 
228
229
  | 기능 | **[TokenTracker](https://github.com/xiufengsun/TokenTracker)** | **[ccusage](https://github.com/ccusage/ccusage)** | **[Tokscale](https://github.com/junhoyeo/tokscale)** |
229
230
  |---|:---:|:---:|:---:|
230
- | **지원하는 AI 도구 수** | **41** | 멀티 에이전트 지원 | 멀티 에이전트 지원 |
231
+ | **지원하는 AI 도구 수** | **42** | 멀티 에이전트 지원 | 멀티 에이전트 지원 |
231
232
  | **기본 인터페이스** | 네이티브 데스크톱 앱 & 웹 대시보드 | 터미널 CLI | 터미널 TUI & CLI |
232
233
  | **로컬 우선 분석** | ✅ | ✅ | ✅ |
233
234
  | **네이티브 데스크톱 앱** | ✅ macOS, Windows, Linux | ❌ | ❌ |
@@ -243,7 +244,7 @@ brew install xiufengsun/tokentracker/tokentracker
243
244
 
244
245
  ```mermaid
245
246
  flowchart LR
246
- A["AI coding tools<br/>Claude Code · Codex · AStudio · Cursor · Gemini · Kiro<br/>OpenCode · OpenClaw · Every Code · Hermes · Copilot<br/>Kimi · CodeBuddy · WorkBuddy · Grok · Kilo · Roo · Zed · Goose<br/>Antigravity · oh-my-pi · pi · Craft · Droid · Mimo · ZCode · Qoder · AnythingLLM · Claude Science · DeepSeek Harness · TRAE Work CN · LM Studio · Unsloth Studio · Devin CLI · MiniMax Code · Cline"]
247
+ A["AI coding tools<br/>Claude Code · Codex · AStudio · Cursor · Gemini · Kiro<br/>OpenCode · OpenClaw · Every Code · Hermes · Copilot<br/>Kimi · CodeBuddy · WorkBuddy · Grok · Kilo · Roo · Zed · Goose<br/>Antigravity · oh-my-pi · pi · Craft · Droid · Mimo · ZCode · Qoder · AnythingLLM · Claude Science · DeepSeek Harness · TRAE Work CN · LM Studio · Unsloth Studio · Devin CLI · MiniMax Code · Cline · Command Code"]
247
248
  A -->|hooks trigger| B[Token Tracker]
248
249
  B -->|parse logs<br/>30-min UTC buckets| C[(Local SQLite)]
249
250
  C --> D[Web Dashboard]
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  ### Track every AI token — then bring your usage to life
8
8
 
9
- An accurate, local-first token usage and cost dashboard for **41 AI coding tools** — plus a desktop pet, **4 native widgets**, and **15 achievement tracks**. No cloud account, no API keys, no setup.
9
+ An accurate, local-first token usage and cost dashboard for **42 AI coding tools** — plus a desktop pet, **4 native widgets**, and **15 achievement tracks**. No cloud account, no API keys, no setup.
10
10
 
11
11
  [![npm version](https://img.shields.io/npm/v/tokentracker-cli.svg?color=blue)](https://www.npmjs.com/package/tokentracker-cli)
12
12
  [![npm downloads](https://img.shields.io/npm/dm/tokentracker-cli.svg?color=brightgreen)](https://www.npmjs.com/package/tokentracker-cli)
@@ -147,7 +147,7 @@ An Arch `PKGBUILD` for a local pacman install lives in `TokenTrackerLinux/packag
147
147
 
148
148
  ## ✨ Features
149
149
 
150
- - 🔌 **41 AI tools out of the box** — Claude Code, Codex CLI, AStudio, Cursor, Gemini CLI, Antigravity, Kiro, OpenCode, OpenClaw, Every Code, Hermes Agent, GitHub Copilot, Kimi Code, CodeBuddy, WorkBuddy, Grok Build, oh-my-pi, OmO, pi, Dots, Prime Agent, Craft Agents, Reasonix, Kilo CLI, Kilo Code, Roo Code, Zed Agent, Goose, Droid, Mimo Code, ZCode, Qoder, AnythingLLM Desktop, Claude Science, DeepSeek Harness, TRAE Work CN, LM Studio, Unsloth Studio, Devin CLI, Cline, MiniMax Code
150
+ - 🔌 **42 AI tools out of the box** — Claude Code, Codex CLI, AStudio, Cursor, Gemini CLI, Antigravity, Kiro, OpenCode, OpenClaw, Every Code, Hermes Agent, GitHub Copilot, Kimi Code, CodeBuddy, WorkBuddy, Grok Build, oh-my-pi, OmO, pi, Dots, Prime Agent, Craft Agents, Reasonix, Kilo CLI, Kilo Code, Roo Code, Zed Agent, Goose, Droid, Mimo Code, ZCode, Qoder, AnythingLLM Desktop, Claude Science, DeepSeek Harness, TRAE Work CN, LM Studio, Unsloth Studio, Devin CLI, Cline, MiniMax Code, Command Code
151
151
  - 🏠 **Local-first** — Runs on your machine. Parses logs locally with no account or API keys needed.
152
152
  - 🚀 **Zero config** — Hooks auto-install on first run. From zero to dashboard in 30 seconds.
153
153
  - 📊 **Beautiful dashboard** — Usage trends, cost breakdowns by model, GitHub-style activity heatmap, project attribution
@@ -274,6 +274,7 @@ An Arch `PKGBUILD` for a local pacman install lives in `TokenTrackerLinux/packag
274
274
  | **Devin CLI** (Cognition) | ✅ Auto | Passive SQLite reader (`$XDG_DATA_HOME/devin/cli/sessions.db`, default `~/.local/share/devin/cli/sessions.db`; reads per-request usage metrics deduplicated by `request_id` — replay/fork/compaction copies never double-count — using the recorded generation model, never prompts, responses, or `cogs_json`). Devin models (`swe-2`, `swe-2-high`, `compactor`) currently have no pricing data, so their token counts are reported but excluded from dollar estimates — a $0 figure does not mean free usage. No native Windows data dir is known; a WSL install is read via `\\wsl$`. |
275
275
  | **Cline** (CLI v3 / desktop app) | ✅ Auto | Passive reader (`~/.cline/data/sessions/<id>/*.messages.json`). Per-turn `metrics` are usage deltas where `inputTokens` already includes cache read+write and `outputTokens` already includes reasoning, so the cached prefix is subtracted and reasoning is never billed twice; Cline's own per-call `cost` is trusted when reported. `cline-free/*` and `cline-pass/*` gateway models are priced at $0. The VS Code extension's globalStorage layout is not read. Path overrides: `TOKENTRACKER_CLINE_SESSIONS_DIR`, `TOKENTRACKER_CLINE_DATA_DIR`, `TOKENTRACKER_CLINE_HOME`, `CLINE_SESSION_DATA_DIR`, `CLINE_DATA_DIR`, or `CLINE_DIR` |
276
276
  | **MiniMax Code** | ✅ Auto | Passive reader (`~/.minimax/v2/sessions/YYYY/MM/DD/<session>/messages.jsonl`). Dedupes on `message_id`, records the routed upstream model per message, and ignores the always-zero `usage.cost` in favor of normal pricing. Override the directory with `TOKENTRACKER_MINIMAX_HOME` |
277
+ | **Command Code** | ✅ Auto | Passive session reader (`~/.commandcode/projects/<cwd-slug>/<session-id>.jsonl`; `*.checkpoints.jsonl` snapshots and `.prompts.` sidecars are skipped). Scans transcripts locally and extracts selected usage metadata, including token counts and the CLI's `costUsd` display estimate. Token Tracker estimates cost with its shared model price table instead. Subtracts both cache reads and writes from cache-inclusive input to avoid double counting. Token Tracker does not persist or upload prompt, reply or code bodies. Override the directory with `TOKENTRACKER_COMMANDCODE_HOME` |
277
278
  | **Claude Science** | ✅ Auto | Passive SQLite reader (`~/.claude-science/operon-cli.db`; reads the `frames` table's token counters only, never prompts, artifacts or research content). No native Windows build — on Windows the app runs inside WSL and is read from there. |
278
279
  | **DeepSeek Harness** | ✅ Auto | Passive session reader (`~/.dsh/sessions/**/session.jsonl[.zstd]`; parses session header and assistant events, handles multi-frame zstd decompression) |
279
280
  | **TRAE Work CN** | ✅ Auto | **Requires an explicit opt-in: set `TOKENTRACKER_TRAE_CN_USAGE=1`.** Reading usage transmits the locally stored sign-in authorization to TRAE's internal API, so nothing is sent until you turn it on. Once opted in: during eligible non-background sync when local TRAE Work CN auth exists, reads session-token usage from the locally signed-in macOS / Windows app; its internal API may change |
@@ -301,7 +302,7 @@ Missing your tool? [Open an issue](https://github.com/xiufengsun/TokenTracker/is
301
302
 
302
303
  | Capability | **[TokenTracker](https://github.com/xiufengsun/TokenTracker)** | **[ccusage](https://github.com/ccusage/ccusage)** | **[Tokscale](https://github.com/junhoyeo/tokscale)** |
303
304
  |---|:---:|:---:|:---:|
304
- | **AI tools supported** | **41** | Multi-agent | Multi-agent |
305
+ | **AI tools supported** | **42** | Multi-agent | Multi-agent |
305
306
  | **Primary interface** | Desktop apps & web dashboard | Terminal CLI | Terminal TUI & CLI |
306
307
  | **Local analysis** | ✅ | ✅ | ✅ |
307
308
  | **Native desktop apps** | ✅ macOS, Windows, Linux | ❌ | ❌ |
@@ -317,7 +318,7 @@ Missing your tool? [Open an issue](https://github.com/xiufengsun/TokenTracker/is
317
318
 
318
319
  ```mermaid
319
320
  flowchart LR
320
- A["AI coding tools<br/>Claude Code · Codex · AStudio · Cursor · Gemini · Kiro<br/>OpenCode · OpenClaw · Every Code · Hermes · Copilot<br/>Kimi Code · CodeBuddy · WorkBuddy · Grok Build · Kilo CLI · Kilo Code<br/>Antigravity · oh-my-pi · OmO · pi · Dots · Craft · Roo · Zed · Goose · Droid · Mimo · ZCode · Qoder · AnythingLLM · Claude Science · DeepSeek Harness · TRAE Work CN · LM Studio · Unsloth Studio · Devin CLI · Cline · MiniMax Code"]
321
+ A["AI coding tools<br/>Claude Code · Codex · AStudio · Cursor · Gemini · Kiro<br/>OpenCode · OpenClaw · Every Code · Hermes · Copilot<br/>Kimi Code · CodeBuddy · WorkBuddy · Grok Build · Kilo CLI · Kilo Code<br/>Antigravity · oh-my-pi · OmO · pi · Dots · Craft · Roo · Zed · Goose · Droid · Mimo · ZCode · Qoder · AnythingLLM · Claude Science · DeepSeek Harness · TRAE Work CN · LM Studio · Unsloth Studio · Devin CLI · Cline · MiniMax Code · Command Code"]
321
322
  A -->|hooks trigger| B[Token Tracker]
322
323
  B -->|parse logs<br/>30-min UTC buckets| C[(Local SQLite)]
323
324
  C --> D[Web Dashboard]
@@ -371,6 +372,7 @@ Most users never need this — defaults are sensible. For advanced setups:
371
372
  | `TOKENTRACKER_UNSLOTH_DB` | Override the Unsloth Studio database file used by the passive usage reader | `$UNSLOTH_STUDIO_HOME/studio.db` |
372
373
  | `TOKENTRACKER_DEVIN_DB` | Override the Devin CLI database file used by the passive usage reader | `$XDG_DATA_HOME/devin/cli/sessions.db` |
373
374
  | `TOKENTRACKER_MINIMAX_HOME` | Override the MiniMax Code data directory used by the passive usage reader | `~/.minimax` |
375
+ | `TOKENTRACKER_COMMANDCODE_HOME` | Override the Command Code (`cmd`) data directory used by the passive session reader | `~/.commandcode` |
374
376
 
375
377
  ### 🐧 Windows Subsystem for Linux (WSL) Auto-Discovery
376
378
 
package/README.zh-CN.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  ### 跨所有 CLI,看清你到底在 AI 上花了多少钱
8
8
 
9
- 自动采集 **41 款 AI 编码工具** 的 token 用量,全程本地聚合,用一套漂亮的 Dashboard 看真实成本与趋势。不需要云账号、不需要 API Key、不需要任何配置 —— 一条命令搞定。
9
+ 自动采集 **42 款 AI 编码工具** 的 token 用量,全程本地聚合,用一套漂亮的 Dashboard 看真实成本与趋势。不需要云账号、不需要 API Key、不需要任何配置 —— 一条命令搞定。
10
10
 
11
11
  [![npm version](https://img.shields.io/npm/v/tokentracker-cli.svg?color=blue)](https://www.npmjs.com/package/tokentracker-cli)
12
12
  [![npm downloads](https://img.shields.io/npm/dm/tokentracker-cli.svg?color=brightgreen)](https://www.npmjs.com/package/tokentracker-cli)
@@ -90,7 +90,7 @@ brew install xiufengsun/tokentracker/tokentracker
90
90
 
91
91
  ## ✨ 特性
92
92
 
93
- - 🔌 **开箱即用支持 41 款 AI 工具** —— Claude Code、Codex CLI、AStudio、Cursor、Gemini CLI、Kiro、OpenCode、OpenClaw、Every Code、Hermes Agent、GitHub Copilot、Kimi Code、CodeBuddy、WorkBuddy、Grok Build、oh-my-pi、OmO、pi、Dots、Prime Agent、Craft Agents、Reasonix、Kilo CLI、Kilo Code、Roo Code、Antigravity、Zed Agent、Goose、Droid、Mimo Code、ZCode、Qoder、AnythingLLM Desktop、Claude Science、DeepSeek Harness、TRAE Work CN、LM Studio、Unsloth Studio、Devin CLI、Cline、MiniMax Code
93
+ - 🔌 **开箱即用支持 42 款 AI 工具** —— Claude Code、Codex CLI、AStudio、Cursor、Gemini CLI、Kiro、OpenCode、OpenClaw、Every Code、Hermes Agent、GitHub Copilot、Kimi Code、CodeBuddy、WorkBuddy、Grok Build、oh-my-pi、OmO、pi、Dots、Prime Agent、Craft Agents、Reasonix、Kilo CLI、Kilo Code、Roo Code、Antigravity、Zed Agent、Goose、Droid、Mimo Code、ZCode、Qoder、AnythingLLM Desktop、Claude Science、DeepSeek Harness、TRAE Work CN、LM Studio、Unsloth Studio、Devin CLI、Cline、MiniMax Code、Command Code
94
94
  - 🏠 **本地优先** —— 跑在本地。直接在本地机器解析日志,无需账号或 API Key。
95
95
  - 🚀 **零配置** —— 首次运行自动安装所有 hook。30 秒从零到 Dashboard
96
96
  - 📊 **漂亮的 Dashboard** —— 用量趋势、按模型的成本分解、GitHub 风格活跃度热力图、按项目归因
@@ -205,6 +205,7 @@ brew install xiufengsun/tokentracker/tokentracker
205
205
  | **Devin CLI** (Cognition) | ✅ 自动 | 被动 SQLite 读取(`$XDG_DATA_HOME/devin/cli/sessions.db`,默认 `~/.local/share/devin/cli/sessions.db`;按 `request_id` 对每次请求的用量指标去重——replay/fork/compaction 副本不会重复计数——使用记录的 generation model,不读取 prompt、回复或 `cogs_json`)。Devin 模型(`swe-2`、`swe-2-high`、`compactor`)当前没有定价数据,token 数照常统计但不计入美元估算——显示 $0 并不代表免费。没有已知的原生 Windows 数据目录;WSL 安装通过 `\\wsl$` 读取。 |
206
206
  | **Cline**(CLI v3 / 桌面 App) | ✅ 自动 | 被动读取 `~/.cline/data/sessions/<id>/*.messages.json`。每轮的 `metrics` 是用量增量,其中 `inputTokens` 已包含 cache 读+写、`outputTokens` 已包含 reasoning——因此缓存前缀会被扣除、reasoning 不会重复计费;Cline 自己上报的 `cost` 优先采用。`cline-free/*` 与 `cline-pass/*` 网关模型计 $0。不读取 VS Code 扩展的 globalStorage 目录。路径覆盖:`TOKENTRACKER_CLINE_SESSIONS_DIR`、`TOKENTRACKER_CLINE_DATA_DIR`、`TOKENTRACKER_CLINE_HOME`、`CLINE_SESSION_DATA_DIR`、`CLINE_DATA_DIR` 或 `CLINE_DIR` |
207
207
  | **MiniMax Code** | ✅ 自动 | 被动读取(`~/.minimax/v2/sessions/YYYY/MM/DD/<session>/messages.jsonl`)。按 `message_id` 去重,按消息记录实际路由到的上游模型;`usage.cost` 恒为 0,不采用,按常规定价计算。可用 `TOKENTRACKER_MINIMAX_HOME` 覆盖目录 |
208
+ | **Command Code** | ✅ 自动 | 被动会话读取器(`~/.commandcode/projects/<cwd-slug>/<session-id>.jsonl`,跳过 `*.checkpoints.jsonl` 快照与 `.prompts.` 辅助文件)。在本地扫描会话日志,提取选定的用量元数据,包括 token 计数与 CLI 的 `costUsd` 展示估算值;费用按 Token Tracker 的统一模型价目表估算。从包含缓存的 input 中同时扣除缓存读取和缓存写入,避免重复计数。Token Tracker 不保存或上传 prompt、回复或代码正文。可用 `TOKENTRACKER_COMMANDCODE_HOME` 覆盖目录 |
208
209
  | **Claude Science** | ✅ 自动 | 被动 SQLite 读取(`~/.claude-science/operon-cli.db`;只读取 `frames` 表的 token 计数,不读取 prompt、产物或研究内容)。没有原生 Windows 版——Windows 上该应用运行在 WSL 内,从 WSL 中读取。 |
209
210
  | **DeepSeek Harness** | ✅ 自动 | 被动读取会话日志(`~/.dsh/sessions/**/session.jsonl[.zstd]`;解析会话头部与 assistant 事件,支持多帧 zstd 解压) |
210
211
  | **TRAE Work CN** | ✅ 自动 | **需要显式开启:设置 `TOKENTRACKER_TRAE_CN_USAGE=1`。** 读取用量会把本地保存的登录授权发送到 TRAE 的内部 API,因此在你开启之前不会发出任何请求。开启后:仅在存在本地 TRAE Work CN 登录授权的可执行非后台同步期间,读取 macOS / Windows 本地登录应用的 session-token 用量;内部 API 可能变化 |
@@ -230,7 +231,7 @@ brew install xiufengsun/tokentracker/tokentracker
230
231
 
231
232
  | 功能维度 | **[TokenTracker](https://github.com/xiufengsun/TokenTracker)** | **[ccusage](https://github.com/ccusage/ccusage)** | **[Tokscale](https://github.com/junhoyeo/tokscale)** |
232
233
  |---|:---:|:---:|:---:|
233
- | **支持的 AI 工具数** | **41** | 多 Agent / 工具支持 | 多 Agent / 工具支持 |
234
+ | **支持的 AI 工具数** | **42** | 多 Agent / 工具支持 | 多 Agent / 工具支持 |
234
235
  | **主要交互方式** | 原生桌面 App 与 Web Dashboard | 终端命令行(CLI) | 终端 TUI 与 CLI |
235
236
  | **本地优先分析** | ✅ | ✅ | ✅ |
236
237
  | **原生桌面 App** | ✅ macOS、Windows、Linux | ❌ | ❌ |
@@ -246,7 +247,7 @@ brew install xiufengsun/tokentracker/tokentracker
246
247
 
247
248
  ```mermaid
248
249
  flowchart LR
249
- A["AI 编码工具<br/>Claude Code · Codex · AStudio · Cursor · Gemini · Kiro<br/>OpenCode · OpenClaw · Every Code · Hermes · Copilot<br/>Kimi · CodeBuddy · WorkBuddy · Grok · Kilo · Roo · Zed · Goose<br/>Antigravity · oh-my-pi · pi · Craft · Droid · Mimo · ZCode · Qoder · AnythingLLM · Claude Science · DeepSeek Harness · TRAE Work CN · LM Studio · Unsloth Studio · Devin CLI · MiniMax Code · Cline"]
250
+ A["AI 编码工具<br/>Claude Code · Codex · AStudio · Cursor · Gemini · Kiro<br/>OpenCode · OpenClaw · Every Code · Hermes · Copilot<br/>Kimi · CodeBuddy · WorkBuddy · Grok · Kilo · Roo · Zed · Goose<br/>Antigravity · oh-my-pi · pi · Craft · Droid · Mimo · ZCode · Qoder · AnythingLLM · Claude Science · DeepSeek Harness · TRAE Work CN · LM Studio · Unsloth Studio · Devin CLI · MiniMax Code · Cline · Command Code"]
250
251
  A -->|hook 触发| B[Token Tracker]
251
252
  B -->|解析日志<br/>30 分钟 UTC 桶| C[(本地 SQLite)]
252
253
  C --> D[Web Dashboard]
@@ -1 +1 @@
1
- import{m as n,d as F,j as i}from"./__vite-browser-external-oFHfLR8i.js";import{Z as I}from"./zap-D2E3JNcE.js";import{F as G}from"./flame-CltKUU4A.js";const k={name:"blocks",size:24,node:[["path",{d:"M10 22V7a1 1 0 0 0-1-1H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-5a1 1 0 0 0-1-1H2",key:"1ah6g2"}],["rect",{x:"14",y:"2",width:"8",height:"8",rx:"1",key:"88lufb"}]]};k.node;const N=n(k);const u={name:"brain",size:24,node:[["path",{d:"M12 18V5",key:"adv99a"}],["path",{d:"M15 13a4.17 4.17 0 0 1-3-4 4.17 4.17 0 0 1-3 4",key:"1e3is1"}],["path",{d:"M17.598 6.5A3 3 0 1 0 12 5a3 3 0 1 0-5.598 1.5",key:"1gqd8o"}],["path",{d:"M17.997 5.125a4 4 0 0 1 2.526 5.77",key:"iwvgf7"}],["path",{d:"M18 18a4 4 0 0 0 2-7.464",key:"efp6ie"}],["path",{d:"M19.967 17.483A4 4 0 1 1 12 18a4 4 0 1 1-7.967-.517",key:"1gq6am"}],["path",{d:"M6 18a4 4 0 0 1-2-7.464",key:"k1g0md"}],["path",{d:"M6.003 5.125a4 4 0 0 0-2.526 5.77",key:"q97ue3"}]]};u.node;const S=n(u);const v={name:"calendar-days",size:24,node:[["path",{d:"M8 2v3",key:"1ioesn"}],["path",{d:"M16 2v3",key:"otl347"}],["rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",key:"h1oib"}],["path",{d:"M3 9h18",key:"1pudct"}],["path",{d:"M8 13h.01",key:"1sbv64"}],["path",{d:"M12 13h.01",key:"y0uutt"}],["path",{d:"M16 13h.01",key:"wip0gl"}],["path",{d:"M8 17h.01",key:"p3bg7i"}],["path",{d:"M12 17h.01",key:"p32p05"}],["path",{d:"M16 17h.01",key:"ql8jdd"}]]};v.node;const V=n(v);const M={name:"crown",size:24,node:[["path",{d:"M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z",key:"1vdc57"}],["path",{d:"M5 21h14",key:"11awu3"}]]};M.node;const Z=n(M);const b={name:"feather",size:24,node:[["path",{d:"M14.086 18.412A2 2 0 0112.67 19H5v-7.672a2 2 0 01.586-1.414L11.75 3.75a6 6 0 118.49 8.49z",key:"1nq9jb"}],["path",{d:"M16 8 2 22",key:"vp34q"}],["path",{d:"M17.488 15H9",key:"16yirz"}]]};b.node;const O=n(b);const _={name:"folder-git-2",size:24,node:[["path",{d:"M18 19a5 5 0 0 1-5-5v8",key:"sz5oeg"}],["path",{d:"M9 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v5",key:"1w6njk"}],["circle",{cx:"13",cy:"12",r:"2",key:"1j92g6"}],["circle",{cx:"20",cy:"19",r:"2",key:"1obnsp"}]]};_.node;const P=n(_);const x={name:"footprints",size:24,node:[["path",{d:"M4 16v-2.38C4 11.5 2.97 10.5 3 8c.03-2.72 1.49-6 4.5-6C9.37 2 10 3.8 10 5.5c0 3.11-2 5.66-2 8.68V16a2 2 0 1 1-4 0Z",key:"1dudjm"}],["path",{d:"M20 20v-2.38c0-2.12 1.03-3.12 1-5.62-.03-2.72-1.49-6-4.5-6C14.63 6 14 7.8 14 9.5c0 3.11 2 5.66 2 8.68V20a2 2 0 1 0 4 0Z",key:"l2t8xc"}],["path",{d:"M16 17h4",key:"1dejxt"}],["path",{d:"M4 13h4",key:"1bwh8b"}]]};x.node;const X=n(x);const w={name:"heart",size:24,node:[["path",{d:"M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5",key:"mvr1a0"}]]};w.node;const K=n(w);const z={name:"medal",size:24,node:[["path",{d:"M7.21 15 2.66 7.14a2 2 0 0 1 .13-2.2L4.4 2.8A2 2 0 0 1 6 2h12a2 2 0 0 1 1.6.8l1.6 2.14a2 2 0 0 1 .14 2.2L16.79 15",key:"143lza"}],["path",{d:"M11 12 5.12 2.2",key:"qhuxz6"}],["path",{d:"m13 12 5.88-9.8",key:"hbye0f"}],["path",{d:"M8 7h8",key:"i86dvs"}],["circle",{cx:"12",cy:"17",r:"5",key:"qbz8iq"}],["path",{d:"M12 18v-2h-.5",key:"fawc4q"}]]};z.node;const U=n(z);const D={name:"moon-star",size:24,node:[["path",{d:"M18 5h4",key:"1lhgn2"}],["path",{d:"M20 3v4",key:"1olli1"}],["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]]};D.node;const W=n(D);const $={name:"rocket",size:24,node:[["path",{d:"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5",key:"qeys4"}],["path",{d:"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09",key:"u4xsad"}],["path",{d:"M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z",key:"676m9"}],["path",{d:"M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05",key:"92ym6u"}]]};$.node;const Y=n($);const A={name:"shield-check",size:24,node:[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]};A.node;const J=n(A);const j={name:"trending-up",size:24,node:[["path",{d:"M16 7h6v6",key:"box55l"}],["path",{d:"m22 7-8.5 8.5-5-5L2 17",key:"1t1m79"}]]};j.node;const Q=n(j),E=[{id:"token_titan",scope:"cloud",icon:Z,format:"tokens",art:"/achievements/token-titan.png"},{id:"big_day",scope:"cloud",icon:I,format:"tokens",art:"/achievements/big-day.png"},{id:"wordsmith",scope:"cloud",icon:O,format:"tokens",art:"/achievements/wordsmith.png"},{id:"marathoner",scope:"cloud",icon:X,format:"days",art:"/achievements/marathoner.png"},{id:"streak",scope:"cloud",icon:G,format:"days",art:"/achievements/streak.png"},{id:"weekend_warrior",scope:"cloud",icon:V,format:"days",art:"/achievements/weekend-warrior.png"},{id:"momentum",scope:"cloud",icon:Q,format:"multiplier",art:"/achievements/momentum.png"},{id:"polyglot",scope:"cloud",icon:S,format:"count",art:"/achievements/polyglot.png"},{id:"trendsetter",scope:"cloud",icon:Y,format:"count",art:"/achievements/trendsetter.png"},{id:"multitool",scope:"cloud",icon:N,format:"count",art:"/achievements/multitool.png"},{id:"podium",scope:"cloud",icon:U,format:"rank",art:"/achievements/podium.png"},{id:"veteran",scope:"cloud",icon:J,format:"days",art:"/achievements/veteran.png"},{id:"project_hopper",scope:"local",icon:P,format:"count",art:"/achievements/project-hopper.png"},{id:"project_devotion",scope:"local",icon:K,format:"tokens",art:"/achievements/project-devotion.png"},{id:"night_owl",scope:"local",icon:W,format:"count",art:"/achievements/night-owl.png"}],L=new Map(E.map(e=>[e.id,e])),m=new Map(E.map((e,a)=>[e.id,a]));function de(e,a){return`achievements.badge.${e}.${a}`}function ee(e){return[...e||[]].sort((a,t)=>{const c=(t?.tier||0)-(a?.tier||0);return c!==0?c:(m.get(a?.id)??99)-(m.get(t?.id)??99)})}function ie(e){const a=(e||[]).filter(t=>t&&(t.tier||0)>=1&&L.has(t.id));return a.length===0?null:ee(a)[0]}const C={1:"bronze",2:"silver",3:"gold",4:"diamond"},re=["bronze","silver","gold","diamond"],ae={bronze:{rim:["#a06a44","#5c3a22"],face:["#d29a6c","#96602f"],glyph:"#3f2817",ring:"#e8c3a0",sheen:"rgba(255, 236, 220, 0.45)",label:"#a06a44"},silver:{rim:["#aab3bb","#67707b"],face:["#dde2e7","#9ba5ae"],glyph:"#39424b",ring:"#f2f5f7",sheen:"rgba(255, 255, 255, 0.55)",label:"#8b959f"},gold:{rim:["#c9971c","#8a6508"],face:["#f2ca52","#cf9c26"],glyph:"#5c430e",ring:"#ffe9a8",sheen:"rgba(255, 248, 214, 0.55)",label:"#b8860b"},diamond:{rim:["#62b1e0","#7c6fd9"],face:["#c8ecf6","#84b4ea"],glyph:"#27496d",ring:"#eafcff",sheen:"rgba(255, 255, 255, 0.65)",label:"#5a9bd8"}},y={rim:["#a8ada9","#7c817d"],face:["#cdd2ce","#a3a8a4"],glyph:"#6a706c",ring:"#dde1de",sheen:"rgba(255, 255, 255, 0.25)",label:"#8b908c"};function te(e,a=!1){return a||!e||e<1?y:ae[C[Math.min(e,4)]]||y}function se(e){return C[e]||null}const g={xs:18,sm:24,md:44,xl:88,lg:108},f={xs:.75,sm:1,md:1.5,xl:2,lg:2};function le({badgeId:e,tier:a=0,size:t="md",locked:c=!1,label:r,className:T=""}){const s=L.get(e),h=c||!a||a<1,o=te(a,h),d=t==="fill",l=d?"100%":g[t]||g.md,q=d?4:f[t]||f.md,[B,H]=F.useState(!1),p=s?.icon||null,R=!!s?.art&&!B;return i.jsx("span",{role:r?"img":void 0,"aria-label":r||void 0,"aria-hidden":r?void 0:!0,className:`inline-flex shrink-0 rounded-full ${T}`,style:{width:l,height:l,padding:q,background:`linear-gradient(135deg, ${o.rim[0]} 0%, ${o.ring} 42%, ${o.rim[1]} 100%)`,boxShadow:d||t==="md"||t==="xl"||t==="lg"?"0 0 0 1px rgba(10, 15, 12, 0.06), 0 1px 2px rgba(10, 15, 12, 0.08)":void 0},children:R?i.jsx("img",{src:s.art,alt:"",draggable:!1,loading:"lazy",onError:()=>H(!0),className:"h-full w-full rounded-full object-cover",style:h?{filter:"grayscale(1)",opacity:.55}:void 0}):i.jsx("span",{className:"flex h-full w-full items-center justify-center rounded-full",style:{background:`linear-gradient(145deg, ${o.face[0]}, ${o.face[1]})`},children:p?i.jsx(p,{size:d?64:Math.round(l*.5),color:o.glyph,strokeWidth:2}):null})})}export{le as A,E as B,K as H,Q as T,ae as a,de as b,L as c,re as d,ie as h,te as p,ee as s,se as t};
1
+ import{m as n,d as F,j as i}from"./__vite-browser-external-BDugA6I0.js";import{Z as I}from"./zap-BS7ZU76I.js";import{F as G}from"./flame-BMJTxjVg.js";const k={name:"blocks",size:24,node:[["path",{d:"M10 22V7a1 1 0 0 0-1-1H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-5a1 1 0 0 0-1-1H2",key:"1ah6g2"}],["rect",{x:"14",y:"2",width:"8",height:"8",rx:"1",key:"88lufb"}]]};k.node;const N=n(k);const u={name:"brain",size:24,node:[["path",{d:"M12 18V5",key:"adv99a"}],["path",{d:"M15 13a4.17 4.17 0 0 1-3-4 4.17 4.17 0 0 1-3 4",key:"1e3is1"}],["path",{d:"M17.598 6.5A3 3 0 1 0 12 5a3 3 0 1 0-5.598 1.5",key:"1gqd8o"}],["path",{d:"M17.997 5.125a4 4 0 0 1 2.526 5.77",key:"iwvgf7"}],["path",{d:"M18 18a4 4 0 0 0 2-7.464",key:"efp6ie"}],["path",{d:"M19.967 17.483A4 4 0 1 1 12 18a4 4 0 1 1-7.967-.517",key:"1gq6am"}],["path",{d:"M6 18a4 4 0 0 1-2-7.464",key:"k1g0md"}],["path",{d:"M6.003 5.125a4 4 0 0 0-2.526 5.77",key:"q97ue3"}]]};u.node;const S=n(u);const v={name:"calendar-days",size:24,node:[["path",{d:"M8 2v3",key:"1ioesn"}],["path",{d:"M16 2v3",key:"otl347"}],["rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",key:"h1oib"}],["path",{d:"M3 9h18",key:"1pudct"}],["path",{d:"M8 13h.01",key:"1sbv64"}],["path",{d:"M12 13h.01",key:"y0uutt"}],["path",{d:"M16 13h.01",key:"wip0gl"}],["path",{d:"M8 17h.01",key:"p3bg7i"}],["path",{d:"M12 17h.01",key:"p32p05"}],["path",{d:"M16 17h.01",key:"ql8jdd"}]]};v.node;const V=n(v);const M={name:"crown",size:24,node:[["path",{d:"M11.562 3.266a.5.5 0 0 1 .876 0L15.39 8.87a1 1 0 0 0 1.516.294L21.183 5.5a.5.5 0 0 1 .798.519l-2.834 10.246a1 1 0 0 1-.956.734H5.81a1 1 0 0 1-.957-.734L2.02 6.02a.5.5 0 0 1 .798-.519l4.276 3.664a1 1 0 0 0 1.516-.294z",key:"1vdc57"}],["path",{d:"M5 21h14",key:"11awu3"}]]};M.node;const Z=n(M);const b={name:"feather",size:24,node:[["path",{d:"M14.086 18.412A2 2 0 0112.67 19H5v-7.672a2 2 0 01.586-1.414L11.75 3.75a6 6 0 118.49 8.49z",key:"1nq9jb"}],["path",{d:"M16 8 2 22",key:"vp34q"}],["path",{d:"M17.488 15H9",key:"16yirz"}]]};b.node;const O=n(b);const _={name:"folder-git-2",size:24,node:[["path",{d:"M18 19a5 5 0 0 1-5-5v8",key:"sz5oeg"}],["path",{d:"M9 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v5",key:"1w6njk"}],["circle",{cx:"13",cy:"12",r:"2",key:"1j92g6"}],["circle",{cx:"20",cy:"19",r:"2",key:"1obnsp"}]]};_.node;const P=n(_);const x={name:"footprints",size:24,node:[["path",{d:"M4 16v-2.38C4 11.5 2.97 10.5 3 8c.03-2.72 1.49-6 4.5-6C9.37 2 10 3.8 10 5.5c0 3.11-2 5.66-2 8.68V16a2 2 0 1 1-4 0Z",key:"1dudjm"}],["path",{d:"M20 20v-2.38c0-2.12 1.03-3.12 1-5.62-.03-2.72-1.49-6-4.5-6C14.63 6 14 7.8 14 9.5c0 3.11 2 5.66 2 8.68V20a2 2 0 1 0 4 0Z",key:"l2t8xc"}],["path",{d:"M16 17h4",key:"1dejxt"}],["path",{d:"M4 13h4",key:"1bwh8b"}]]};x.node;const X=n(x);const w={name:"heart",size:24,node:[["path",{d:"M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5",key:"mvr1a0"}]]};w.node;const K=n(w);const z={name:"medal",size:24,node:[["path",{d:"M7.21 15 2.66 7.14a2 2 0 0 1 .13-2.2L4.4 2.8A2 2 0 0 1 6 2h12a2 2 0 0 1 1.6.8l1.6 2.14a2 2 0 0 1 .14 2.2L16.79 15",key:"143lza"}],["path",{d:"M11 12 5.12 2.2",key:"qhuxz6"}],["path",{d:"m13 12 5.88-9.8",key:"hbye0f"}],["path",{d:"M8 7h8",key:"i86dvs"}],["circle",{cx:"12",cy:"17",r:"5",key:"qbz8iq"}],["path",{d:"M12 18v-2h-.5",key:"fawc4q"}]]};z.node;const U=n(z);const D={name:"moon-star",size:24,node:[["path",{d:"M18 5h4",key:"1lhgn2"}],["path",{d:"M20 3v4",key:"1olli1"}],["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]]};D.node;const W=n(D);const $={name:"rocket",size:24,node:[["path",{d:"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5",key:"qeys4"}],["path",{d:"M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09",key:"u4xsad"}],["path",{d:"M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z",key:"676m9"}],["path",{d:"M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05",key:"92ym6u"}]]};$.node;const Y=n($);const A={name:"shield-check",size:24,node:[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]};A.node;const J=n(A);const j={name:"trending-up",size:24,node:[["path",{d:"M16 7h6v6",key:"box55l"}],["path",{d:"m22 7-8.5 8.5-5-5L2 17",key:"1t1m79"}]]};j.node;const Q=n(j),E=[{id:"token_titan",scope:"cloud",icon:Z,format:"tokens",art:"/achievements/token-titan.png"},{id:"big_day",scope:"cloud",icon:I,format:"tokens",art:"/achievements/big-day.png"},{id:"wordsmith",scope:"cloud",icon:O,format:"tokens",art:"/achievements/wordsmith.png"},{id:"marathoner",scope:"cloud",icon:X,format:"days",art:"/achievements/marathoner.png"},{id:"streak",scope:"cloud",icon:G,format:"days",art:"/achievements/streak.png"},{id:"weekend_warrior",scope:"cloud",icon:V,format:"days",art:"/achievements/weekend-warrior.png"},{id:"momentum",scope:"cloud",icon:Q,format:"multiplier",art:"/achievements/momentum.png"},{id:"polyglot",scope:"cloud",icon:S,format:"count",art:"/achievements/polyglot.png"},{id:"trendsetter",scope:"cloud",icon:Y,format:"count",art:"/achievements/trendsetter.png"},{id:"multitool",scope:"cloud",icon:N,format:"count",art:"/achievements/multitool.png"},{id:"podium",scope:"cloud",icon:U,format:"rank",art:"/achievements/podium.png"},{id:"veteran",scope:"cloud",icon:J,format:"days",art:"/achievements/veteran.png"},{id:"project_hopper",scope:"local",icon:P,format:"count",art:"/achievements/project-hopper.png"},{id:"project_devotion",scope:"local",icon:K,format:"tokens",art:"/achievements/project-devotion.png"},{id:"night_owl",scope:"local",icon:W,format:"count",art:"/achievements/night-owl.png"}],L=new Map(E.map(e=>[e.id,e])),m=new Map(E.map((e,a)=>[e.id,a]));function de(e,a){return`achievements.badge.${e}.${a}`}function ee(e){return[...e||[]].sort((a,t)=>{const c=(t?.tier||0)-(a?.tier||0);return c!==0?c:(m.get(a?.id)??99)-(m.get(t?.id)??99)})}function ie(e){const a=(e||[]).filter(t=>t&&(t.tier||0)>=1&&L.has(t.id));return a.length===0?null:ee(a)[0]}const C={1:"bronze",2:"silver",3:"gold",4:"diamond"},re=["bronze","silver","gold","diamond"],ae={bronze:{rim:["#a06a44","#5c3a22"],face:["#d29a6c","#96602f"],glyph:"#3f2817",ring:"#e8c3a0",sheen:"rgba(255, 236, 220, 0.45)",label:"#a06a44"},silver:{rim:["#aab3bb","#67707b"],face:["#dde2e7","#9ba5ae"],glyph:"#39424b",ring:"#f2f5f7",sheen:"rgba(255, 255, 255, 0.55)",label:"#8b959f"},gold:{rim:["#c9971c","#8a6508"],face:["#f2ca52","#cf9c26"],glyph:"#5c430e",ring:"#ffe9a8",sheen:"rgba(255, 248, 214, 0.55)",label:"#b8860b"},diamond:{rim:["#62b1e0","#7c6fd9"],face:["#c8ecf6","#84b4ea"],glyph:"#27496d",ring:"#eafcff",sheen:"rgba(255, 255, 255, 0.65)",label:"#5a9bd8"}},y={rim:["#a8ada9","#7c817d"],face:["#cdd2ce","#a3a8a4"],glyph:"#6a706c",ring:"#dde1de",sheen:"rgba(255, 255, 255, 0.25)",label:"#8b908c"};function te(e,a=!1){return a||!e||e<1?y:ae[C[Math.min(e,4)]]||y}function se(e){return C[e]||null}const g={xs:18,sm:24,md:44,xl:88,lg:108},f={xs:.75,sm:1,md:1.5,xl:2,lg:2};function le({badgeId:e,tier:a=0,size:t="md",locked:c=!1,label:r,className:T=""}){const s=L.get(e),h=c||!a||a<1,o=te(a,h),d=t==="fill",l=d?"100%":g[t]||g.md,q=d?4:f[t]||f.md,[B,H]=F.useState(!1),p=s?.icon||null,R=!!s?.art&&!B;return i.jsx("span",{role:r?"img":void 0,"aria-label":r||void 0,"aria-hidden":r?void 0:!0,className:`inline-flex shrink-0 rounded-full ${T}`,style:{width:l,height:l,padding:q,background:`linear-gradient(135deg, ${o.rim[0]} 0%, ${o.ring} 42%, ${o.rim[1]} 100%)`,boxShadow:d||t==="md"||t==="xl"||t==="lg"?"0 0 0 1px rgba(10, 15, 12, 0.06), 0 1px 2px rgba(10, 15, 12, 0.08)":void 0},children:R?i.jsx("img",{src:s.art,alt:"",draggable:!1,loading:"lazy",onError:()=>H(!0),className:"h-full w-full rounded-full object-cover",style:h?{filter:"grayscale(1)",opacity:.55}:void 0}):i.jsx("span",{className:"flex h-full w-full items-center justify-center rounded-full",style:{background:`linear-gradient(145deg, ${o.face[0]}, ${o.face[1]})`},children:p?i.jsx(p,{size:d?64:Math.round(l*.5),color:o.glyph,strokeWidth:2}):null})})}export{le as A,E as B,K as H,Q as T,ae as a,de as b,L as c,re as d,ie as h,te as p,ee as s,se as t};
@@ -1,2 +1,2 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/BadgeDetailModal-BFCscxTM.js","assets/__vite-browser-external-oFHfLR8i.js","assets/__vite-browser-external-5P7me0Qq.css","assets/react-C9Bg9RXS.js","assets/AchievementBadge-Dk6u95zc.js","assets/zap-D2E3JNcE.js","assets/flame-CltKUU4A.js","assets/use-transform-DYM391E0.js","assets/use-reduced-motion-D_7LzLSe.js","assets/AchievementsSection-DaVrpiJ4.js","assets/format-tokens-BEIqtfnO.js","assets/DialogTitle-BhRP2R4n.js","assets/composite-Bl68G4Qr.js","assets/store-npers9xW.js"])))=>i.map(i=>d[i]);
2
- import{r as l,z as h,A as f,F as v,j as e,c,L as p,d as g,a as y,G as b,H as k,_ as j}from"./__vite-browser-external-oFHfLR8i.js";import{A as w}from"./AchievementsSection-DaVrpiJ4.js";import{B as x}from"./AchievementBadge-Dk6u95zc.js";import"./react-C9Bg9RXS.js";import"./format-tokens-BEIqtfnO.js";import"./use-reduced-motion-D_7LzLSe.js";import"./zap-D2E3JNcE.js";import"./flame-CltKUU4A.js";function N({enabled:a=!0}={}){const[n,t]=l.useState({status:"loading",achievements:[],error:null}),s=l.useMemo(()=>h(),[]);return l.useEffect(()=>{if(!a){t({status:"disabled",achievements:[],error:null});return}let i=!1;return t(r=>({...r,status:"loading"})),f({timeZone:s,tzOffsetMinutes:v()}).then(r=>{i||t({status:"ready",achievements:Array.isArray(r?.achievements)?r.achievements:[],error:null})}).catch(r=>{i||t({status:"error",achievements:[],error:r})}),()=>{i=!0}},[a,s]),n}const A=g.lazy(()=>j(()=>import("./BadgeDetailModal-BFCscxTM.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13])));function I({authLoading:a,authEnabled:n,authUserId:t,mockEnabled:s}){if(s)return{authLoading:!1,signedIn:!0,userId:"mock-user"};const i=!!(n&&t);return{authLoading:!!a,signedIn:i,userId:i?t:null}}function B(){const a=y(),[n,t]=l.useState({status:"loading",achievements:[],userId:null}),s=b(),{authLoading:i,signedIn:r,userId:o}=I({authLoading:a?.loading,authEnabled:a?.enabled,authUserId:a?.user?.id,mockEnabled:s});return l.useEffect(()=>{if(i){t({status:"loading",achievements:[],userId:null});return}if(!r){t({status:"signed-out",achievements:[],userId:null});return}let d=!1;return t({status:"loading",achievements:[],userId:o}),(async()=>{try{const u=s?null:await a.getAccessToken?.(),m=await k({accessToken:u,userId:o});if(d)return;t({status:"ready",achievements:Array.isArray(m?.badges)?m.badges:[],userId:o})}catch{d||t({status:"error",achievements:[],userId:o})}})(),()=>{d=!0}},[i,s,r,o]),{...n,signedIn:r,settled:_({authLoading:i,signedIn:r,userId:o,state:n})}}function _({authLoading:a,signedIn:n,userId:t,state:s}){return a?!1:n?s.userId===t&&(s.status==="ready"||s.status==="error"):s.status==="signed-out"}function S(){return e.jsx("div",{className:"mx-0 grid animate-pulse grid-cols-[repeat(3,max-content)] justify-between gap-y-7 sm:-mx-2 sm:grid-cols-[repeat(4,max-content)] lg:grid-cols-[repeat(5,max-content)]","aria-hidden":!0,children:Array.from({length:x.length}).map((a,n)=>e.jsxs("div",{className:"flex w-[6.75rem] flex-col items-center px-0 pb-3 pt-4 sm:w-[7.75rem]",children:[e.jsx("div",{className:"h-[108px] w-[108px] rounded-full bg-oai-gray-200 dark:bg-oai-gray-800"}),e.jsx("div",{className:"mt-3 h-3 w-16 rounded bg-oai-gray-200 dark:bg-oai-gray-800"}),e.jsx("div",{className:"mt-2 h-2 w-10 rounded bg-oai-gray-100 dark:bg-oai-gray-800/60"})]},n))})}function D(){const a=N(),n=B(),[t,s]=l.useState(null),i=a.status==="loading"||!n.settled,r=l.useMemo(()=>[...n.achievements||[],...a.achievements||[]],[n.achievements,a.achievements]),o=l.useMemo(()=>r.filter(u=>(u?.tier||0)>=1).length,[r]),d=x.length;return e.jsxs("div",{className:"flex flex-1 flex-col font-oai text-oai-black antialiased dark:text-oai-white",children:[e.jsx("main",{className:"flex-1 pb-12 pt-8 sm:pb-16 sm:pt-10",children:e.jsxs("div",{className:"mx-auto max-w-4xl px-4 sm:px-6",children:[e.jsxs("div",{className:"mb-7 flex items-baseline justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("h1",{className:"text-3xl font-semibold tracking-tight text-oai-black dark:text-white sm:text-4xl",children:c("achievements.page.title")}),e.jsx("p",{className:"mt-1.5 text-sm text-oai-gray-500 dark:text-oai-gray-400",children:c("achievements.page.local_note")})]}),!i&&e.jsxs("div",{className:"shrink-0 text-right",children:[e.jsxs("div",{className:"font-mono text-2xl font-semibold leading-none tabular-nums text-oai-black dark:text-white",children:[o,e.jsxs("span",{className:"text-oai-gray-400 dark:text-oai-gray-600",children:["/",d]})]}),e.jsx("div",{className:"mt-2 h-1 w-24 overflow-hidden rounded-full bg-oai-gray-200 dark:bg-oai-gray-800",children:e.jsx("div",{className:"h-full rounded-full bg-oai-brand-600 transition-[width] duration-500",style:{width:`${Math.round(o/d*100)}%`}})})]})]}),!n.signedIn&&!i&&e.jsxs("div",{className:"mb-6 flex flex-wrap items-center justify-between gap-x-4 gap-y-2 rounded-xl border border-oai-gray-200 bg-oai-gray-50 px-4 py-3 dark:border-oai-gray-800 dark:bg-oai-gray-900/60",children:[e.jsx("p",{className:"text-sm text-oai-gray-600 dark:text-oai-gray-300",children:c("achievements.signin.prompt")}),e.jsx(p,{to:"/login",className:"shrink-0 rounded-lg bg-oai-brand-600 px-3 py-1.5 text-sm font-medium text-white transition-colors duration-200 hover:bg-oai-brand-700 active:scale-[0.98]",children:c("achievements.signin.action")})]}),i?e.jsx(S,{}):e.jsxs(e.Fragment,{children:[e.jsx(w,{achievements:r,isOwn:!0,columns:"wide",size:"lg",animateIn:!0,onSelect:s}),e.jsxs("p",{className:"mt-10 text-center text-xs text-oai-gray-400 dark:text-oai-gray-500",children:[c("achievements.page.suggest")," ",e.jsx("a",{href:"https://github.com/xiufengsun/TokenTracker/issues",target:"_blank",rel:"noopener noreferrer",className:"underline decoration-oai-gray-300 underline-offset-2 transition-colors hover:text-oai-gray-700 hover:decoration-oai-gray-500 dark:decoration-oai-gray-600 dark:hover:text-oai-gray-300",children:c("achievements.page.suggest_link")})]})]})]})}),t&&e.jsx(g.Suspense,{fallback:null,children:e.jsx(A,{badge:t,onClose:()=>s(null)})})]})}export{_ as cloudBadgesSettled,D as default,I as resolveCloudBadgeIdentity};
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/BadgeDetailModal-Cp98zNn2.js","assets/__vite-browser-external-BDugA6I0.js","assets/__vite-browser-external-Bg0J-a5P.css","assets/react-Ctoe8iLl.js","assets/AchievementBadge-dt_UDU_h.js","assets/zap-BS7ZU76I.js","assets/flame-BMJTxjVg.js","assets/use-transform-D36BHcXk.js","assets/use-reduced-motion-CNpG-Yoi.js","assets/AchievementsSection-CDxcyig2.js","assets/format-tokens-DCZM5Nfn.js","assets/DialogTitle-BJxpp2t-.js","assets/composite--JllTpIX.js","assets/store-B2RplzvW.js"])))=>i.map(i=>d[i]);
2
+ import{r as l,z as h,A as f,F as v,j as e,c,L as p,d as g,a as y,G as b,H as k,_ as j}from"./__vite-browser-external-BDugA6I0.js";import{A as w}from"./AchievementsSection-CDxcyig2.js";import{B as x}from"./AchievementBadge-dt_UDU_h.js";import"./react-Ctoe8iLl.js";import"./format-tokens-DCZM5Nfn.js";import"./use-reduced-motion-CNpG-Yoi.js";import"./zap-BS7ZU76I.js";import"./flame-BMJTxjVg.js";function N({enabled:a=!0}={}){const[n,t]=l.useState({status:"loading",achievements:[],error:null}),s=l.useMemo(()=>h(),[]);return l.useEffect(()=>{if(!a){t({status:"disabled",achievements:[],error:null});return}let i=!1;return t(r=>({...r,status:"loading"})),f({timeZone:s,tzOffsetMinutes:v()}).then(r=>{i||t({status:"ready",achievements:Array.isArray(r?.achievements)?r.achievements:[],error:null})}).catch(r=>{i||t({status:"error",achievements:[],error:r})}),()=>{i=!0}},[a,s]),n}const A=g.lazy(()=>j(()=>import("./BadgeDetailModal-Cp98zNn2.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13])));function I({authLoading:a,authEnabled:n,authUserId:t,mockEnabled:s}){if(s)return{authLoading:!1,signedIn:!0,userId:"mock-user"};const i=!!(n&&t);return{authLoading:!!a,signedIn:i,userId:i?t:null}}function B(){const a=y(),[n,t]=l.useState({status:"loading",achievements:[],userId:null}),s=b(),{authLoading:i,signedIn:r,userId:o}=I({authLoading:a?.loading,authEnabled:a?.enabled,authUserId:a?.user?.id,mockEnabled:s});return l.useEffect(()=>{if(i){t({status:"loading",achievements:[],userId:null});return}if(!r){t({status:"signed-out",achievements:[],userId:null});return}let d=!1;return t({status:"loading",achievements:[],userId:o}),(async()=>{try{const u=s?null:await a.getAccessToken?.(),m=await k({accessToken:u,userId:o});if(d)return;t({status:"ready",achievements:Array.isArray(m?.badges)?m.badges:[],userId:o})}catch{d||t({status:"error",achievements:[],userId:o})}})(),()=>{d=!0}},[i,s,r,o]),{...n,signedIn:r,settled:_({authLoading:i,signedIn:r,userId:o,state:n})}}function _({authLoading:a,signedIn:n,userId:t,state:s}){return a?!1:n?s.userId===t&&(s.status==="ready"||s.status==="error"):s.status==="signed-out"}function S(){return e.jsx("div",{className:"mx-0 grid animate-pulse grid-cols-[repeat(3,max-content)] justify-between gap-y-7 sm:-mx-2 sm:grid-cols-[repeat(4,max-content)] lg:grid-cols-[repeat(5,max-content)]","aria-hidden":!0,children:Array.from({length:x.length}).map((a,n)=>e.jsxs("div",{className:"flex w-[6.75rem] flex-col items-center px-0 pb-3 pt-4 sm:w-[7.75rem]",children:[e.jsx("div",{className:"h-[108px] w-[108px] rounded-full bg-oai-gray-200 dark:bg-oai-gray-800"}),e.jsx("div",{className:"mt-3 h-3 w-16 rounded bg-oai-gray-200 dark:bg-oai-gray-800"}),e.jsx("div",{className:"mt-2 h-2 w-10 rounded bg-oai-gray-100 dark:bg-oai-gray-800/60"})]},n))})}function D(){const a=N(),n=B(),[t,s]=l.useState(null),i=a.status==="loading"||!n.settled,r=l.useMemo(()=>[...n.achievements||[],...a.achievements||[]],[n.achievements,a.achievements]),o=l.useMemo(()=>r.filter(u=>(u?.tier||0)>=1).length,[r]),d=x.length;return e.jsxs("div",{className:"flex flex-1 flex-col font-oai text-oai-black antialiased dark:text-oai-white",children:[e.jsx("main",{className:"flex-1 pb-12 pt-8 sm:pb-16 sm:pt-10",children:e.jsxs("div",{className:"mx-auto max-w-4xl px-4 sm:px-6",children:[e.jsxs("div",{className:"mb-7 flex items-baseline justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("h1",{className:"text-3xl font-semibold tracking-tight text-oai-black dark:text-white sm:text-4xl",children:c("achievements.page.title")}),e.jsx("p",{className:"mt-1.5 text-sm text-oai-gray-500 dark:text-oai-gray-400",children:c("achievements.page.local_note")})]}),!i&&e.jsxs("div",{className:"shrink-0 text-right",children:[e.jsxs("div",{className:"font-mono text-2xl font-semibold leading-none tabular-nums text-oai-black dark:text-white",children:[o,e.jsxs("span",{className:"text-oai-gray-400 dark:text-oai-gray-600",children:["/",d]})]}),e.jsx("div",{className:"mt-2 h-1 w-24 overflow-hidden rounded-full bg-oai-gray-200 dark:bg-oai-gray-800",children:e.jsx("div",{className:"h-full rounded-full bg-oai-brand-600 transition-[width] duration-500",style:{width:`${Math.round(o/d*100)}%`}})})]})]}),!n.signedIn&&!i&&e.jsxs("div",{className:"mb-6 flex flex-wrap items-center justify-between gap-x-4 gap-y-2 rounded-xl border border-oai-gray-200 bg-oai-gray-50 px-4 py-3 dark:border-oai-gray-800 dark:bg-oai-gray-900/60",children:[e.jsx("p",{className:"text-sm text-oai-gray-600 dark:text-oai-gray-300",children:c("achievements.signin.prompt")}),e.jsx(p,{to:"/login",className:"shrink-0 rounded-lg bg-oai-brand-600 px-3 py-1.5 text-sm font-medium text-white transition-colors duration-200 hover:bg-oai-brand-700 active:scale-[0.98]",children:c("achievements.signin.action")})]}),i?e.jsx(S,{}):e.jsxs(e.Fragment,{children:[e.jsx(w,{achievements:r,isOwn:!0,columns:"wide",size:"lg",animateIn:!0,onSelect:s}),e.jsxs("p",{className:"mt-10 text-center text-xs text-oai-gray-400 dark:text-oai-gray-500",children:[c("achievements.page.suggest")," ",e.jsx("a",{href:"https://github.com/xiufengsun/TokenTracker/issues",target:"_blank",rel:"noopener noreferrer",className:"underline decoration-oai-gray-300 underline-offset-2 transition-colors hover:text-oai-gray-700 hover:decoration-oai-gray-500 dark:decoration-oai-gray-600 dark:hover:text-oai-gray-300",children:c("achievements.page.suggest_link")})]})]})]})}),t&&e.jsx(g.Suspense,{fallback:null,children:e.jsx(A,{badge:t,onClose:()=>s(null)})})]})}export{_ as cloudBadgesSettled,D as default,I as resolveCloudBadgeIdentity};
@@ -1 +1 @@
1
- import{m as $,j as s,c as l}from"./__vite-browser-external-oFHfLR8i.js";import{m as C}from"./react-C9Bg9RXS.js";import{B as x,s as b,b as T,t as B,A as E,a as L}from"./AchievementBadge-Dk6u95zc.js";import{f as D}from"./format-tokens-BEIqtfnO.js";import{u as I}from"./use-reduced-motion-D_7LzLSe.js";const v={name:"hard-drive",size:24,node:[["path",{d:"M10 16h.01",key:"1bzywj"}],["path",{d:"M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z",key:"18tbho"}],["path",{d:"M21.946 12.013H2.054",key:"zqlbp7"}],["path",{d:"M6 16h.01",key:"1pmjb7"}]]};v.node;const z=$(v);function V(r,i){const t=Number(i)||0;switch(r){case"tokens":return D(t);case"rank":return`#${Math.round(t)}`;case"multiplier":return`${(Math.round(t*10)/10).toString()}×`;default:return Math.round(t).toLocaleString()}}function F(r){if(!r)return 0;const i=Number(r.next_threshold),t=Number(r.metric_value??r.value);if(!Number.isFinite(i)||i<=0)return r.tier>=4?1:0;if(!Number.isFinite(t)||t<=0)return 0;const o=r.lower_is_better?i/t:t/i;return Math.max(0,Math.min(1,o))}function q(r){const i=r?.achieved||{},t=Object.values(i).map(o=>o?Date.parse(o):NaN).filter(o=>Number.isFinite(o));return t.length>0?Math.max(...t):null}function K({achievements:r,isOwn:i=!1,scope:t,onSelect:o,size:m="xl",columns:y="default",animateIn:k=!1,className:N=""}){const j=I(),u=k&&!j,p=new Map;for(const e of Array.isArray(r)?r:[])e&&e.id&&p.set(e.id,e);const g=t?x.filter(e=>e.scope===t):x;let c;if(i){const e=g.map(a=>({entry:a,record:p.get(a.id)||{id:a.id,tier:0}})),n=b(e.filter(a=>(a.record.tier||0)>=1).map(a=>({...a,id:a.entry.id,tier:a.record.tier}))),h=e.filter(a=>(a.record.tier||0)<1);c=[...n,...h]}else c=b(g.map(e=>({entry:e,record:p.get(e.id)})).filter(e=>e.record&&(e.record.tier||0)>=1).map(e=>({...e,id:e.entry.id,tier:e.record.tier}))).map(({entry:e,record:n})=>({entry:e,record:n}));if(c.length===0)return null;const w=y==="wide"?"grid-cols-[repeat(3,max-content)] sm:grid-cols-[repeat(4,max-content)] lg:grid-cols-[repeat(5,max-content)]":"grid-cols-[repeat(3,max-content)] sm:grid-cols-[repeat(4,max-content)]",M=m==="lg"?"mx-0 sm:-mx-2":"-mx-2 sm:-mx-4",A=m==="lg"?"px-0":"px-1";return s.jsx("div",{className:`${M} grid justify-between gap-y-7 ${w} ${N}`,children:c.map(({entry:e,record:n},h)=>{const a=(n.tier||0)>=1,f=l(T(e.id,"name")),d=a?B(n.tier):null,_=F(n);return s.jsxs(C.button,{type:"button",initial:u?{opacity:0,y:16,scale:.9}:!1,animate:u?{opacity:1,y:0,scale:1}:void 0,whileTap:u?{scale:.97}:void 0,transition:{delay:.05+h*.035,duration:.45,ease:[.16,1,.3,1]},onClick:o?()=>o({...n,id:e.id}):void 0,className:`group flex w-[6.75rem] flex-col items-center rounded-xl ${A} pb-3 pt-4 text-center transition-[background-color,transform] duration-200 ease-out hover:bg-oai-gray-50 active:scale-[0.97] dark:hover:bg-oai-gray-900/70 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-oai-brand/60 sm:w-[7.75rem]`,"aria-label":l("achievements.badge.aria",{name:f,tier:d?l(`achievements.tier.${d}`):l("achievements.modal.locked")}),children:[s.jsx(E,{badgeId:e.id,tier:n.tier,locked:!a,size:m,className:"transition-transform duration-200 ease-out group-hover:-translate-y-0.5 group-hover:scale-105"}),s.jsxs("span",{className:"mt-2.5 flex w-full items-center justify-center gap-1",children:[s.jsx("span",{title:f,className:"min-w-0 truncate text-xs font-medium leading-tight text-oai-gray-800 dark:text-oai-gray-200",children:f}),e.scope==="local"&&s.jsx("span",{title:l("achievements.page.local_note"),"aria-label":l("achievements.scope.local"),className:"inline-flex shrink-0 text-oai-gray-400 dark:text-oai-gray-500",children:s.jsx(z,{size:11,strokeWidth:2,"aria-hidden":!0})})]}),s.jsx("span",{className:"mt-1 flex h-4 w-full items-center justify-center",children:a?s.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-[0.08em]",style:{color:L[d]?.label},children:l(`achievements.tier.${d}`)}):i?s.jsx("span",{className:"h-[3px] w-14 overflow-hidden rounded-full bg-oai-gray-200 dark:bg-oai-gray-800",children:s.jsx("span",{className:"block h-full rounded-full bg-oai-brand/70",style:{width:`${Math.round(_*100)}%`}})}):null})]},e.id)})})}export{K as A,F as b,V as f,q as l};
1
+ import{m as $,j as s,c as l}from"./__vite-browser-external-BDugA6I0.js";import{m as C}from"./react-Ctoe8iLl.js";import{B as x,s as b,b as T,t as B,A as E,a as L}from"./AchievementBadge-dt_UDU_h.js";import{f as D}from"./format-tokens-DCZM5Nfn.js";import{u as I}from"./use-reduced-motion-CNpG-Yoi.js";const v={name:"hard-drive",size:24,node:[["path",{d:"M10 16h.01",key:"1bzywj"}],["path",{d:"M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z",key:"18tbho"}],["path",{d:"M21.946 12.013H2.054",key:"zqlbp7"}],["path",{d:"M6 16h.01",key:"1pmjb7"}]]};v.node;const z=$(v);function V(r,i){const t=Number(i)||0;switch(r){case"tokens":return D(t);case"rank":return`#${Math.round(t)}`;case"multiplier":return`${(Math.round(t*10)/10).toString()}×`;default:return Math.round(t).toLocaleString()}}function F(r){if(!r)return 0;const i=Number(r.next_threshold),t=Number(r.metric_value??r.value);if(!Number.isFinite(i)||i<=0)return r.tier>=4?1:0;if(!Number.isFinite(t)||t<=0)return 0;const o=r.lower_is_better?i/t:t/i;return Math.max(0,Math.min(1,o))}function q(r){const i=r?.achieved||{},t=Object.values(i).map(o=>o?Date.parse(o):NaN).filter(o=>Number.isFinite(o));return t.length>0?Math.max(...t):null}function K({achievements:r,isOwn:i=!1,scope:t,onSelect:o,size:m="xl",columns:y="default",animateIn:k=!1,className:N=""}){const j=I(),u=k&&!j,p=new Map;for(const e of Array.isArray(r)?r:[])e&&e.id&&p.set(e.id,e);const g=t?x.filter(e=>e.scope===t):x;let c;if(i){const e=g.map(a=>({entry:a,record:p.get(a.id)||{id:a.id,tier:0}})),n=b(e.filter(a=>(a.record.tier||0)>=1).map(a=>({...a,id:a.entry.id,tier:a.record.tier}))),h=e.filter(a=>(a.record.tier||0)<1);c=[...n,...h]}else c=b(g.map(e=>({entry:e,record:p.get(e.id)})).filter(e=>e.record&&(e.record.tier||0)>=1).map(e=>({...e,id:e.entry.id,tier:e.record.tier}))).map(({entry:e,record:n})=>({entry:e,record:n}));if(c.length===0)return null;const w=y==="wide"?"grid-cols-[repeat(3,max-content)] sm:grid-cols-[repeat(4,max-content)] lg:grid-cols-[repeat(5,max-content)]":"grid-cols-[repeat(3,max-content)] sm:grid-cols-[repeat(4,max-content)]",M=m==="lg"?"mx-0 sm:-mx-2":"-mx-2 sm:-mx-4",A=m==="lg"?"px-0":"px-1";return s.jsx("div",{className:`${M} grid justify-between gap-y-7 ${w} ${N}`,children:c.map(({entry:e,record:n},h)=>{const a=(n.tier||0)>=1,f=l(T(e.id,"name")),d=a?B(n.tier):null,_=F(n);return s.jsxs(C.button,{type:"button",initial:u?{opacity:0,y:16,scale:.9}:!1,animate:u?{opacity:1,y:0,scale:1}:void 0,whileTap:u?{scale:.97}:void 0,transition:{delay:.05+h*.035,duration:.45,ease:[.16,1,.3,1]},onClick:o?()=>o({...n,id:e.id}):void 0,className:`group flex w-[6.75rem] flex-col items-center rounded-xl ${A} pb-3 pt-4 text-center transition-[background-color,transform] duration-200 ease-out hover:bg-oai-gray-50 active:scale-[0.97] dark:hover:bg-oai-gray-900/70 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-oai-brand/60 sm:w-[7.75rem]`,"aria-label":l("achievements.badge.aria",{name:f,tier:d?l(`achievements.tier.${d}`):l("achievements.modal.locked")}),children:[s.jsx(E,{badgeId:e.id,tier:n.tier,locked:!a,size:m,className:"transition-transform duration-200 ease-out group-hover:-translate-y-0.5 group-hover:scale-105"}),s.jsxs("span",{className:"mt-2.5 flex w-full items-center justify-center gap-1",children:[s.jsx("span",{title:f,className:"min-w-0 truncate text-xs font-medium leading-tight text-oai-gray-800 dark:text-oai-gray-200",children:f}),e.scope==="local"&&s.jsx("span",{title:l("achievements.page.local_note"),"aria-label":l("achievements.scope.local"),className:"inline-flex shrink-0 text-oai-gray-400 dark:text-oai-gray-500",children:s.jsx(z,{size:11,strokeWidth:2,"aria-hidden":!0})})]}),s.jsx("span",{className:"mt-1 flex h-4 w-full items-center justify-center",children:a?s.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-[0.08em]",style:{color:L[d]?.label},children:l(`achievements.tier.${d}`)}):i?s.jsx("span",{className:"h-[3px] w-14 overflow-hidden rounded-full bg-oai-gray-200 dark:bg-oai-gray-800",children:s.jsx("span",{className:"block h-full rounded-full bg-oai-brand/70",style:{width:`${Math.round(_*100)}%`}})}):null})]},e.id)})})}export{K as A,F as b,V as f,q as l};
@@ -1 +1 @@
1
- import{r as L,j as a,b4 as De,c as h,e as ye,X as Ie}from"./__vite-browser-external-oFHfLR8i.js";import{k as _e,V as Me,l as Ve,r as Te,n as $e,o as be,q as ve,s as Oe,t as Re,v as Be,w as Pe,x as Ke,y as Ce,z as Fe,A as Le,B as Xe,S as Ge,H as We,C as G,D as ze,E as Ue,e as Ye,F as He,m as C}from"./react-C9Bg9RXS.js";import{c as je,A as Ze,p as qe,b as U,t as le,a as T,d as Je}from"./AchievementBadge-Dk6u95zc.js";import{u as Qe,a as z}from"./use-transform-DYM391E0.js";import{u as et}from"./use-reduced-motion-D_7LzLSe.js";import{l as ce,f as ue,b as tt}from"./AchievementsSection-DaVrpiJ4.js";import{D as nt,a as rt,b as at,c as st,d as it,e as ot}from"./DialogTitle-BhRP2R4n.js";import"./zap-D2E3JNcE.js";import"./flame-CltKUU4A.js";import"./format-tokens-BEIqtfnO.js";import"./composite-Bl68G4Qr.js";import"./store-npers9xW.js";const lt=(e,t,n)=>{const r=t-e;return((n-e)%r+r)%r+e};function Ne(e,t){return _e(e)?e[lt(0,e.length,t)]:e}class ct{constructor(t){this.stop=()=>this.runAll("stop"),this.animations=t.filter(Boolean)}get finished(){return Promise.all(this.animations.map(t=>t.finished))}getAll(t){return this.animations[0][t]}setAll(t,n){for(let r=0;r<this.animations.length;r++)this.animations[r][t]=n}attachTimeline(t){const n=this.animations.map(r=>r.attachTimeline(t));return()=>{n.forEach((r,s)=>{r&&r(),this.animations[s].stop()})}}get time(){return this.getAll("time")}set time(t){this.setAll("time",t)}get speed(){return this.getAll("speed")}set speed(t){this.setAll("speed",t)}get state(){return this.getAll("state")}get startTime(){return this.getAll("startTime")}get duration(){return de(this.animations,"duration")}get iterationDuration(){return de(this.animations,"iterationDuration")}runAll(t){this.animations.forEach(n=>n[t]())}play(){this.runAll("play")}pause(){this.runAll("pause")}cancel(){this.runAll("cancel")}complete(){this.runAll("complete")}}function de(e,t){let n=0;for(let r=0;r<e.length;r++){const s=e[r][t];s!==null&&s>n&&(n=s)}return n}class ut extends ct{then(t,n){return this.finished.finally(t).then(()=>{})}}function dt(e,t){return e in t}class mt extends Me{constructor(){super(...arguments),this.type="object"}readValueFromInstance(t,n){if(dt(n,t)){const r=t[n];if(typeof r=="string"||typeof r=="number")return r}}getBaseTargetFromProps(){}removeValueFromRenderState(t,n){delete n.output[t]}measureInstanceViewportBox(){return Ve()}build(t,n){Object.assign(t.output,n)}renderInstance(t,{output:n}){Object.assign(t,n)}sortInstanceNodePosition(){return 0}}function Y(e){return typeof e=="object"&&!Array.isArray(e)}function ke(e,t,n,r){return e==null?[]:typeof e=="string"&&Y(t)?Te(e,n,r):e instanceof NodeList?Array.from(e):Array.isArray(e)?e.filter(s=>s!=null):[e]}function ft(e,t,n){return e*(t+1)+n*t}function me(e,t,n,r){return typeof t=="number"?t:t.startsWith("-")||t.startsWith("+")?Math.max(0,e+parseFloat(t)):t==="<"?n:t.startsWith("<")?Math.max(0,n+parseFloat(t.slice(1))):r.get(t)??e}function pt(e,t,n){for(let r=0;r<e.length;r++){const s=e[r];s.at>t&&s.at<n&&(be(e,s),r--)}}function ht(e,t,n,r,s,c){pt(e,s,c);for(let i=0;i<t.length;i++)e.push({value:t[i],at:$e(s,c,r[i]),easing:Ne(n,i)})}function gt(e,t,n=0){const r=t+1+t*n;for(let s=0;s<e.length;s++)e[s]=e[s]/r}function xt(e,t){return e.at===t.at?e.value===null?1:t.value===null?-1:0:e.at-t.at}const yt="easeInOut",bt=20;function vt(e,{defaultTransition:t={},...n}={},r,s){const c=t.duration||.3,i=new Map,f=new Map,m={},p=new Map;let g=0,u=0,x=0;for(let N=0;N<e.length;N++){const k=e[N];if(typeof k=="string"){p.set(k,u);continue}else if(!Array.isArray(k)){p.set(k.name,me(u,k.at,g,p));continue}let[E,b,v={}]=k;v.at!==void 0&&(u=me(u,v.at,g,p));let j=0;const _=(w,M,A,o=0,l=0)=>{const d=jt(w),{delay:D=0,times:y=Oe(d),type:R=t.type||"keyframes",repeat:B,repeatType:W,repeatDelay:H=0,...Se}=M;let{ease:I=t.ease||"easeOut",duration:S}=M;const Z=typeof D=="function"?D(o,l):D,q=d.length,J=Ke(R)?R:s?.[R||"keyframes"];if(q<=2&&J){let $=100;if(q===2&&wt(d)){const P=d[1]-d[0];$=Math.abs(P)}const O={...t,...Se};S!==void 0&&(O.duration=Ce(S));const X=Re(O,$,J);I=X.ease,S=X.duration}S??(S=c);const Q=u+Z;y.length===1&&y[0]===0&&(y[1]=1);const ee=y.length-d.length;if(ee>0&&Be(y,ee),d.length===1&&d.unshift(null),B&&B<bt){const $=S>0?H/S:0;S=ft(S,B,H);const O=[...d],X=[...y];I=Array.isArray(I)?[...I]:[I];const P=[...I],ne=W==="reverse"||W==="mirror";let re=O,ae=P;ne&&(re=[...O].reverse(),W==="reverse"&&(ae=[...P].reverse().map(V=>typeof V=="function"?Pe(V):V)));for(let V=0;V<B;V++){const se=ne&&V%2===0,ie=se?re:O,Ee=se?ae:P,oe=(V+1)*(1+$);$>0&&(d.push(d[d.length-1]),y.push(oe),I.push("linear")),d.push(...ie);for(let K=0;K<ie.length;K++)y.push(X[K]+oe),I.push(K===0?"linear":Ne(Ee,K-1))}gt(y,B,$)}const te=Q+S;ht(A,d,I,y,Q,te),j=Math.max(Z+S,j),x=Math.max(te,x)};if(ve(E)){const w=fe(E,f);_(b,v,pe("default",w))}else{const w=ke(E,b,r,m),M=w.length;for(let A=0;A<M;A++){b=b,v=v;const o=w[A],l=fe(o,f);for(const d in b)_(b[d],Nt(v,d),pe(d,l),A,M)}}g=u,u+=j}return f.forEach((N,k)=>{for(const E in N){const b=N[E];b.sort(xt);const v=[],j=[],_=[];for(let o=0;o<b.length;o++){const{at:l,value:d,easing:D}=b[o];v.push(d),j.push(Fe(0,x,l)),_.push(D||"easeOut")}j[0]!==0&&(j.unshift(0),v.unshift(v[0]),_.unshift(yt)),j[j.length-1]!==1&&(j.push(1),v.push(null)),i.has(k)||i.set(k,{keyframes:{},transition:{}});const w=i.get(k);w.keyframes[E]=v;const{type:M,...A}=t;w.transition[E]={...A,duration:x,ease:_,times:j,...n}}}),i}function fe(e,t){return!t.has(e)&&t.set(e,{}),t.get(e)}function pe(e,t){return t[e]||(t[e]=[]),t[e]}function jt(e){return Array.isArray(e)?e:[e]}function Nt(e,t){return e&&e[t]?{...e,...e[t]}:{...e}}const kt=e=>typeof e=="number",wt=e=>e.every(kt);function At(e){const t={presenceContext:null,props:{},visualState:{renderState:{transform:{},transformOrigin:{},style:{},vars:{},attrs:{}},latestValues:{}}},n=Le(e)&&!Xe(e)?new Ge(t):new We(t);n.mount(e),G.set(e,n)}function St(e){const t={presenceContext:null,props:{},visualState:{renderState:{output:{}},latestValues:{}}},n=new mt(t);n.mount(e),G.set(e,n)}function Et(e,t){return ve(e)||typeof e=="number"||typeof e=="string"&&!Y(t)}function we(e,t,n,r){const s=[];if(Et(e,t))s.push(ze(e,Y(t)&&t.default||t,n&&(n.default||n)));else{if(e==null)return s;const c=ke(e,t,r),i=c.length;for(let f=0;f<i;f++){const m=c[f],p=m instanceof Element?At:St;G.has(m)||p(m);const g=G.get(m),u={...n};"delay"in u&&typeof u.delay=="function"&&(u.delay=u.delay(f,i)),s.push(...Ue(g,{...t,transition:u},{}))}}return s}function Dt(e,t,n){const r=[],s=e.map(i=>{if(Array.isArray(i)&&typeof i[0]=="function"){const f=i[0],m=Ye(0);return m.on("change",f),i.length===1?[m,[0,1]]:i.length===2?[m,[0,1],i[1]]:[m,i[1],i[2]]}return i});return vt(s,t,n,{spring:He}).forEach(({keyframes:i,transition:f},m)=>{r.push(...we(m,i,f))}),r}function It(e){return Array.isArray(e)&&e.some(Array.isArray)}function _t(e={}){const{scope:t,reduceMotion:n,skipAnimations:r}=e;function s(c,i,f){let m=[],p;const g={};if(n!==void 0&&(g.reduceMotion=n),r!==void 0&&(g.skipAnimations=r),It(c)){const{onComplete:x,...N}=i||{};typeof x=="function"&&(p=x),m=Dt(c,{...g,...N},t)}else{const{onComplete:x,...N}=f||{};typeof x=="function"&&(p=x),m=we(c,i,{...g,...N},t)}const u=new ut(m);return p&&u.finished.then(p),t&&(t.animations.push(u),u.finished.then(()=>{be(t.animations,u)})),u}return s}const F=_t(),he=8;function Mt({badgeId:e,tier:t,locked:n=!1,size:r=176,backLines:s=[],label:c}){const i=Qe(0),f=et(),m=L.useRef(null),p=L.useRef(null),g=L.useRef(!1),u=qe(t,n),x=je.get(e)?.icon||null,N=z(i,o=>`${(o%360+360)%360/360*160-80}%`),k=z(i,o=>`${80-(o%360+360)%360/360*160}%`),E=z(i,o=>{const l=Math.abs(Math.sin(o*Math.PI/180));return Math.max(0,(l-.35)/.65)*.3}),b=()=>{p.current?.stop?.(),p.current=null};L.useEffect(()=>{if(f||g.current)return;let o=!1;i.set(-360);const l=F(i,0,{duration:.9,ease:[.16,1,.3,1]});return p.current=l,l.then(()=>{o||g.current||(p.current=F(i,[0,-14,14,0],{duration:4.5,repeat:1/0,ease:"easeInOut"}))}),()=>{o=!0,b()}},[f,i]);const v=o=>{const l=i.get();if(f){const y=Math.round(l/180)*180;p.current=F(i,y,{duration:.2,ease:"easeOut"});return}const d=l+o*.35,D=Math.round(d/180)*180;p.current=F(i,D,{type:"spring",velocity:o,stiffness:58,damping:13.5,mass:1})},j=o=>{g.current=!0,b(),o.currentTarget.setPointerCapture?.(o.pointerId),m.current={pointerId:o.pointerId,startX:o.clientX,startRot:i.get(),samples:[{t:o.timeStamp,x:o.clientX}]}},_=o=>{const l=m.current;!l||l.pointerId!==o.pointerId||(i.set(l.startRot+(o.clientX-l.startX)*.55),l.samples.push({t:o.timeStamp,x:o.clientX}),l.samples.length>5&&l.samples.shift())},w=o=>{const l=m.current;if(!l||l.pointerId!==o.pointerId)return;m.current=null;const d=l.samples[0],D=l.samples[l.samples.length-1],y=D.t-d.t,R=y>0?(D.x-d.x)*.55*1e3/y:0;v(R)},M=o=>{if(o.key!=="ArrowLeft"&&o.key!=="ArrowRight")return;o.preventDefault(),g.current=!0,b();const l=o.key==="ArrowRight"?30:-30;p.current=F(i,i.get()+l,{duration:.15,ease:"easeOut"})},A={backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"};return a.jsx("div",{role:"img","aria-label":c,tabIndex:0,onPointerDown:j,onPointerMove:_,onPointerUp:w,onPointerCancel:w,onKeyDown:M,className:"inline-flex cursor-grab select-none items-center justify-center outline-none focus-visible:ring-2 focus-visible:ring-oai-brand/60 rounded-full active:cursor-grabbing",style:{perspective:900,touchAction:"pan-y"},children:a.jsxs("div",{className:"relative",style:{transform:"rotateX(-8deg)",transformStyle:"preserve-3d"},children:[a.jsxs(C.div,{className:"relative",style:{rotateY:i,transformStyle:"preserve-3d",width:r,height:r},children:[[-3,-1.5,0,1.5,3].map(o=>a.jsx("div",{"aria-hidden":!0,className:"absolute inset-0 rounded-full",style:{transform:`translateZ(${o}px)`,background:u.rim[1]}},o)),a.jsxs("div",{className:"absolute inset-0 overflow-hidden rounded-full",style:{...A,transform:`translateZ(${he/2}px)`},children:[a.jsx(Ze,{badgeId:e,tier:t,locked:n,size:"fill",className:"brightness-105 saturate-[1.08]"}),a.jsx("div",{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 rounded-full",style:{background:"radial-gradient(circle at 30% 20%, rgba(255,255,255,0.45), rgba(255,255,255,0) 42%), linear-gradient(172deg, rgba(255,255,255,0.14) 0%, rgba(255,255,255,0) 38%, rgba(0,0,0,0.08) 100%)",boxShadow:"inset 0 3px 7px rgba(255,255,255,0.5), inset 0 -3px 8px rgba(0,0,0,0.15)"}}),a.jsx(C.div,{"aria-hidden":!0,className:"pointer-events-none absolute inset-0",style:{x:N,background:"linear-gradient(105deg, transparent 34%, rgba(255,255,255,0.5) 50%, transparent 66%)"}}),a.jsx(C.div,{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 rounded-full",style:{opacity:E,background:"rgba(8, 12, 10, 0.9)"}})]}),a.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center gap-1 overflow-hidden rounded-full px-6 text-center",style:{...A,transform:`rotateY(180deg) translateZ(${he/2}px)`,background:`linear-gradient(145deg, ${u.face[0]}, ${u.face[1]})`,boxShadow:`inset 0 0 0 6px ${u.rim[1]}, inset 0 0 0 7.5px rgba(255,255,255,0.22), inset 0 3px 7px rgba(255,255,255,0.4), inset 0 -4px 12px rgba(0,0,0,0.22)`},children:[a.jsx("div",{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 rounded-full",style:{background:"repeating-radial-gradient(circle at 50% 50%, rgba(255,255,255,0.06) 0px, rgba(255,255,255,0.06) 1px, transparent 1px, transparent 4px)"}}),x?a.jsx(x,{"aria-hidden":!0,size:Math.round(r*.62),strokeWidth:1.1,color:u.glyph,className:"pointer-events-none absolute opacity-[0.13]",style:{filter:"drop-shadow(0 1px 0 rgba(255,255,255,0.3)) drop-shadow(0 -1px 0 rgba(0,0,0,0.35))"}}):null,a.jsx("div",{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 rounded-full",style:{background:"radial-gradient(circle at 70% 20%, rgba(255,255,255,0.4), rgba(255,255,255,0) 44%), linear-gradient(188deg, rgba(255,255,255,0.12) 0%, rgba(255,255,255,0) 38%, rgba(0,0,0,0.10) 100%)"}}),s.map((o,l)=>a.jsx("div",{className:`font-mono tabular-nums ${l===0?"text-[10px] uppercase tracking-[0.18em]":l===1?"text-lg font-bold":"text-[11px]"}`,style:{color:u.glyph,textShadow:"0 1px 0 rgba(255,255,255,0.28), 0 -1px 0 rgba(0,0,0,0.3)"},children:o},`${l}-${o}`)),a.jsx(C.div,{"aria-hidden":!0,className:"pointer-events-none absolute inset-0",style:{x:k,background:"linear-gradient(105deg, transparent 34%, rgba(255,255,255,0.45) 50%, transparent 66%)"}}),a.jsx(C.div,{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 rounded-full",style:{opacity:E,background:"rgba(8, 12, 10, 0.9)"}})]})]}),a.jsx("div",{"aria-hidden":!0,className:"absolute left-1/2 h-3 w-3/5 rounded-[100%] bg-black/20 blur-md dark:bg-black/45",style:{bottom:-20,transform:"translateX(-50%)"}})]})})}function Ae(e){if(!e)return null;const t=Date.parse(e);return Number.isFinite(t)?new Date(t).toLocaleDateString():null}function Vt(e){const t=Number(e);return!Number.isSafeInteger(t)||t<1?null:String(t).padStart(6,"0")}function Tt(e,t,n){if(t?.scope!=="cloud"||!n)return null;const r=Number(e?.serials?.[n]);return Number.isSafeInteger(r)&&r>=1?r:null}function $t({badge:e}){return a.jsx("div",{className:"flex items-center gap-1",children:Je.map((t,n)=>{const r=(e.tier||0)>=n+1,s=Ae(e.achieved?.[t]),c=T[t];return a.jsx("span",{title:s?`${h(`achievements.tier.${t}`)} · ${s}`:h(`achievements.tier.${t}`),className:"inline-flex h-2 w-8 rounded-full",style:r?{background:`linear-gradient(120deg, ${c.rim[0]} 0%, ${c.ring} 55%, ${c.rim[1]} 100%)`,boxShadow:"inset 0 1px 1px rgba(255,255,255,0.4), 0 0 0 1px rgba(10,15,12,0.05)"}:void 0,children:!r&&a.jsx("span",{className:"h-full w-full rounded-full bg-oai-gray-200 dark:bg-oai-gray-800"})},t)})})}function ge({badge:e,onClose:t}){const n=je.get(e.id),r=h(U(e.id,"name")),s=(e.tier||0)>=1,c=s?le(e.tier):null,i=Ae(s?e.achieved?.[c]||(ce(e)?new Date(ce(e)).toISOString():null):null),f=ue(n?.format,e.metric_value),m=tt(e),p=e.tier<4?le((e.tier||0)+1):null,g=Tt(e,n,c),u=Vt(g),x=u?[h("achievements.modal.achieved_label"),h("achievements.modal.issue_number",{number:u}),i||r]:[s?h("achievements.modal.achieved_label"):h("achievements.modal.locked"),s?f:"···",s&&i?i:r];return a.jsxs("div",{className:"flex flex-col items-center px-6 pb-6 pt-5 text-center",children:[a.jsxs("div",{className:"flex w-full items-start justify-between gap-3",children:[a.jsxs("div",{className:"min-w-0 flex-1 text-left",children:[a.jsx("h2",{className:"truncate text-lg font-semibold tracking-tight text-oai-black dark:text-white",children:r}),a.jsx("p",{className:"mt-0.5 text-xs text-oai-gray-500 dark:text-oai-gray-400",children:h(U(e.id,"desc"))})]}),a.jsx("button",{type:"button",onClick:t,"aria-label":h("achievements.modal.close"),className:"shrink-0 rounded-md p-1.5 text-oai-gray-400 transition-colors hover:bg-oai-gray-100 hover:text-oai-gray-700 dark:hover:bg-oai-gray-900 dark:hover:text-oai-gray-200",children:a.jsx(Ie,{size:16})})]}),a.jsx("div",{className:"mt-5 mb-7",children:a.jsx(Mt,{badgeId:e.id,tier:e.tier,locked:!s,backLines:x,label:h("achievements.modal.coin_aria",{name:r})})}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("span",{className:"rounded-full px-2.5 py-0.5 text-[11px] font-semibold uppercase tracking-wide",style:s?{background:`linear-gradient(120deg, ${T[c].rim[0]} 0%, ${T[c].ring} 55%, ${T[c].rim[1]} 100%)`,color:T[c].glyph,textShadow:"0 1px 0 rgba(255,255,255,0.35)",boxShadow:"inset 0 1px 1px rgba(255,255,255,0.4), 0 0 0 1px rgba(10,15,12,0.06)"}:{background:"rgba(128,134,130,0.75)",color:"rgba(250,250,250,0.95)"},children:s?h(`achievements.tier.${c}`):h("achievements.modal.locked")}),s&&i?a.jsx("span",{className:"text-xs tabular-nums text-oai-gray-500 dark:text-oai-gray-400",children:i}):null]}),a.jsxs("dl",{className:"mt-5 w-full space-y-3 border-t border-oai-gray-200/70 pt-4 text-left dark:border-oai-gray-800/60",children:[a.jsxs("div",{className:"flex items-baseline justify-between gap-3 text-sm",children:[a.jsx("dt",{className:"text-oai-gray-500 dark:text-oai-gray-400",children:h("achievements.modal.value_label")}),a.jsx("dd",{className:"font-mono font-semibold tabular-nums text-oai-black dark:text-white",children:f})]}),a.jsxs("div",{children:[a.jsxs("div",{className:"flex items-baseline justify-between gap-3 text-xs text-oai-gray-500 dark:text-oai-gray-400",children:[a.jsx("span",{children:e.tier>=4?h("achievements.modal.max_tier"):h("achievements.modal.progress_to_next",{tier:h(`achievements.tier.${p}`)})}),e.tier<4&&e.next_threshold!=null?a.jsxs("span",{className:"font-mono tabular-nums",children:[f," ",e.lower_is_better?"→":"/"," ",ue(n?.format,e.next_threshold)]}):null]}),a.jsx("div",{className:"mt-1.5 h-1.5 w-full overflow-hidden rounded-full bg-oai-gray-200 dark:bg-oai-gray-800",children:a.jsx("div",{className:"h-full rounded-full transition-[width] duration-500",style:{width:`${Math.round((e.tier>=4?1:m)*100)}%`,background:s?`linear-gradient(90deg, ${T[c].rim[0]} 0%, ${T[c].ring} 55%, ${T[c].rim[1]} 100%)`:"rgba(128,134,130,0.75)",boxShadow:s?"inset 0 1px 1px rgba(255,255,255,0.35)":void 0}})})]}),a.jsxs("div",{className:"flex items-center justify-between gap-3 text-xs text-oai-gray-500 dark:text-oai-gray-400",children:[a.jsx("span",{children:h("achievements.modal.tier_history")}),a.jsx($t,{badge:e})]})]})]})}const xe=ye("relative w-full max-w-[380px] flex flex-col","rounded-2xl bg-white dark:bg-oai-gray-950","shadow-[0_20px_60px_-20px_rgba(0,0,0,0.25)] dark:shadow-[0_20px_60px_-10px_rgba(0,0,0,0.65)]","ring-1 ring-oai-gray-200 dark:ring-oai-gray-800 overflow-hidden","dark:border-t dark:border-white/[0.08]");function Ut({badge:e,onClose:t}){const n=De(),r=!!e;return L.useEffect(()=>{if(!n||!r)return;const s=c=>{c.key==="Escape"&&(c.stopPropagation(),t?.())};return window.addEventListener("keydown",s,!0),()=>window.removeEventListener("keydown",s,!0)},[n,r,t]),r?n?a.jsxs("div",{className:"fixed inset-0 z-[120] flex items-center justify-center p-4",children:[a.jsx("div",{className:"absolute inset-0 bg-black/40 backdrop-blur-[2px]",onClick:t,"aria-hidden":!0}),a.jsx("div",{className:xe,children:a.jsx(ge,{badge:e,onClose:t})})]}):a.jsx(nt,{open:!0,onOpenChange:s=>{s||t?.()},children:a.jsxs(rt,{children:[a.jsx(at,{className:"cost-modal-backdrop z-[110]"}),a.jsx(st,{className:"fixed inset-0 z-[120] flex items-center justify-center p-4",children:a.jsxs(it,{className:ye("cost-modal-popup",xe),children:[a.jsx(ot,{render:a.jsx("h2",{className:"sr-only"}),children:h(U(e.id,"name"))}),a.jsx(ge,{badge:e,onClose:t})]})})]})}):null}export{Ut as BadgeDetailModal,Tt as currentBadgeIssueNumber,Ut as default,Vt as formatIssueNumber};
1
+ import{r as L,j as a,b5 as De,c as h,e as ye,X as Ie}from"./__vite-browser-external-BDugA6I0.js";import{k as _e,V as Me,l as Ve,r as Te,n as $e,o as be,q as ve,s as Oe,t as Re,v as Be,w as Pe,x as Ke,y as Ce,z as Fe,A as Le,B as Xe,S as Ge,H as We,C as G,D as ze,E as Ue,e as Ye,F as He,m as C}from"./react-Ctoe8iLl.js";import{c as je,A as Ze,p as qe,b as U,t as le,a as T,d as Je}from"./AchievementBadge-dt_UDU_h.js";import{u as Qe,a as z}from"./use-transform-D36BHcXk.js";import{u as et}from"./use-reduced-motion-CNpG-Yoi.js";import{l as ce,f as ue,b as tt}from"./AchievementsSection-CDxcyig2.js";import{D as nt,a as rt,b as at,c as st,d as it,e as ot}from"./DialogTitle-BJxpp2t-.js";import"./zap-BS7ZU76I.js";import"./flame-BMJTxjVg.js";import"./format-tokens-DCZM5Nfn.js";import"./composite--JllTpIX.js";import"./store-B2RplzvW.js";const lt=(e,t,n)=>{const r=t-e;return((n-e)%r+r)%r+e};function Ne(e,t){return _e(e)?e[lt(0,e.length,t)]:e}class ct{constructor(t){this.stop=()=>this.runAll("stop"),this.animations=t.filter(Boolean)}get finished(){return Promise.all(this.animations.map(t=>t.finished))}getAll(t){return this.animations[0][t]}setAll(t,n){for(let r=0;r<this.animations.length;r++)this.animations[r][t]=n}attachTimeline(t){const n=this.animations.map(r=>r.attachTimeline(t));return()=>{n.forEach((r,s)=>{r&&r(),this.animations[s].stop()})}}get time(){return this.getAll("time")}set time(t){this.setAll("time",t)}get speed(){return this.getAll("speed")}set speed(t){this.setAll("speed",t)}get state(){return this.getAll("state")}get startTime(){return this.getAll("startTime")}get duration(){return de(this.animations,"duration")}get iterationDuration(){return de(this.animations,"iterationDuration")}runAll(t){this.animations.forEach(n=>n[t]())}play(){this.runAll("play")}pause(){this.runAll("pause")}cancel(){this.runAll("cancel")}complete(){this.runAll("complete")}}function de(e,t){let n=0;for(let r=0;r<e.length;r++){const s=e[r][t];s!==null&&s>n&&(n=s)}return n}class ut extends ct{then(t,n){return this.finished.finally(t).then(()=>{})}}function dt(e,t){return e in t}class mt extends Me{constructor(){super(...arguments),this.type="object"}readValueFromInstance(t,n){if(dt(n,t)){const r=t[n];if(typeof r=="string"||typeof r=="number")return r}}getBaseTargetFromProps(){}removeValueFromRenderState(t,n){delete n.output[t]}measureInstanceViewportBox(){return Ve()}build(t,n){Object.assign(t.output,n)}renderInstance(t,{output:n}){Object.assign(t,n)}sortInstanceNodePosition(){return 0}}function Y(e){return typeof e=="object"&&!Array.isArray(e)}function ke(e,t,n,r){return e==null?[]:typeof e=="string"&&Y(t)?Te(e,n,r):e instanceof NodeList?Array.from(e):Array.isArray(e)?e.filter(s=>s!=null):[e]}function ft(e,t,n){return e*(t+1)+n*t}function me(e,t,n,r){return typeof t=="number"?t:t.startsWith("-")||t.startsWith("+")?Math.max(0,e+parseFloat(t)):t==="<"?n:t.startsWith("<")?Math.max(0,n+parseFloat(t.slice(1))):r.get(t)??e}function pt(e,t,n){for(let r=0;r<e.length;r++){const s=e[r];s.at>t&&s.at<n&&(be(e,s),r--)}}function ht(e,t,n,r,s,c){pt(e,s,c);for(let i=0;i<t.length;i++)e.push({value:t[i],at:$e(s,c,r[i]),easing:Ne(n,i)})}function gt(e,t,n=0){const r=t+1+t*n;for(let s=0;s<e.length;s++)e[s]=e[s]/r}function xt(e,t){return e.at===t.at?e.value===null?1:t.value===null?-1:0:e.at-t.at}const yt="easeInOut",bt=20;function vt(e,{defaultTransition:t={},...n}={},r,s){const c=t.duration||.3,i=new Map,f=new Map,m={},p=new Map;let g=0,u=0,x=0;for(let N=0;N<e.length;N++){const k=e[N];if(typeof k=="string"){p.set(k,u);continue}else if(!Array.isArray(k)){p.set(k.name,me(u,k.at,g,p));continue}let[E,b,v={}]=k;v.at!==void 0&&(u=me(u,v.at,g,p));let j=0;const _=(w,M,A,o=0,l=0)=>{const d=jt(w),{delay:D=0,times:y=Oe(d),type:R=t.type||"keyframes",repeat:B,repeatType:W,repeatDelay:H=0,...Se}=M;let{ease:I=t.ease||"easeOut",duration:S}=M;const Z=typeof D=="function"?D(o,l):D,q=d.length,J=Ke(R)?R:s?.[R||"keyframes"];if(q<=2&&J){let $=100;if(q===2&&wt(d)){const P=d[1]-d[0];$=Math.abs(P)}const O={...t,...Se};S!==void 0&&(O.duration=Ce(S));const X=Re(O,$,J);I=X.ease,S=X.duration}S??(S=c);const Q=u+Z;y.length===1&&y[0]===0&&(y[1]=1);const ee=y.length-d.length;if(ee>0&&Be(y,ee),d.length===1&&d.unshift(null),B&&B<bt){const $=S>0?H/S:0;S=ft(S,B,H);const O=[...d],X=[...y];I=Array.isArray(I)?[...I]:[I];const P=[...I],ne=W==="reverse"||W==="mirror";let re=O,ae=P;ne&&(re=[...O].reverse(),W==="reverse"&&(ae=[...P].reverse().map(V=>typeof V=="function"?Pe(V):V)));for(let V=0;V<B;V++){const se=ne&&V%2===0,ie=se?re:O,Ee=se?ae:P,oe=(V+1)*(1+$);$>0&&(d.push(d[d.length-1]),y.push(oe),I.push("linear")),d.push(...ie);for(let K=0;K<ie.length;K++)y.push(X[K]+oe),I.push(K===0?"linear":Ne(Ee,K-1))}gt(y,B,$)}const te=Q+S;ht(A,d,I,y,Q,te),j=Math.max(Z+S,j),x=Math.max(te,x)};if(ve(E)){const w=fe(E,f);_(b,v,pe("default",w))}else{const w=ke(E,b,r,m),M=w.length;for(let A=0;A<M;A++){b=b,v=v;const o=w[A],l=fe(o,f);for(const d in b)_(b[d],Nt(v,d),pe(d,l),A,M)}}g=u,u+=j}return f.forEach((N,k)=>{for(const E in N){const b=N[E];b.sort(xt);const v=[],j=[],_=[];for(let o=0;o<b.length;o++){const{at:l,value:d,easing:D}=b[o];v.push(d),j.push(Fe(0,x,l)),_.push(D||"easeOut")}j[0]!==0&&(j.unshift(0),v.unshift(v[0]),_.unshift(yt)),j[j.length-1]!==1&&(j.push(1),v.push(null)),i.has(k)||i.set(k,{keyframes:{},transition:{}});const w=i.get(k);w.keyframes[E]=v;const{type:M,...A}=t;w.transition[E]={...A,duration:x,ease:_,times:j,...n}}}),i}function fe(e,t){return!t.has(e)&&t.set(e,{}),t.get(e)}function pe(e,t){return t[e]||(t[e]=[]),t[e]}function jt(e){return Array.isArray(e)?e:[e]}function Nt(e,t){return e&&e[t]?{...e,...e[t]}:{...e}}const kt=e=>typeof e=="number",wt=e=>e.every(kt);function At(e){const t={presenceContext:null,props:{},visualState:{renderState:{transform:{},transformOrigin:{},style:{},vars:{},attrs:{}},latestValues:{}}},n=Le(e)&&!Xe(e)?new Ge(t):new We(t);n.mount(e),G.set(e,n)}function St(e){const t={presenceContext:null,props:{},visualState:{renderState:{output:{}},latestValues:{}}},n=new mt(t);n.mount(e),G.set(e,n)}function Et(e,t){return ve(e)||typeof e=="number"||typeof e=="string"&&!Y(t)}function we(e,t,n,r){const s=[];if(Et(e,t))s.push(ze(e,Y(t)&&t.default||t,n&&(n.default||n)));else{if(e==null)return s;const c=ke(e,t,r),i=c.length;for(let f=0;f<i;f++){const m=c[f],p=m instanceof Element?At:St;G.has(m)||p(m);const g=G.get(m),u={...n};"delay"in u&&typeof u.delay=="function"&&(u.delay=u.delay(f,i)),s.push(...Ue(g,{...t,transition:u},{}))}}return s}function Dt(e,t,n){const r=[],s=e.map(i=>{if(Array.isArray(i)&&typeof i[0]=="function"){const f=i[0],m=Ye(0);return m.on("change",f),i.length===1?[m,[0,1]]:i.length===2?[m,[0,1],i[1]]:[m,i[1],i[2]]}return i});return vt(s,t,n,{spring:He}).forEach(({keyframes:i,transition:f},m)=>{r.push(...we(m,i,f))}),r}function It(e){return Array.isArray(e)&&e.some(Array.isArray)}function _t(e={}){const{scope:t,reduceMotion:n,skipAnimations:r}=e;function s(c,i,f){let m=[],p;const g={};if(n!==void 0&&(g.reduceMotion=n),r!==void 0&&(g.skipAnimations=r),It(c)){const{onComplete:x,...N}=i||{};typeof x=="function"&&(p=x),m=Dt(c,{...g,...N},t)}else{const{onComplete:x,...N}=f||{};typeof x=="function"&&(p=x),m=we(c,i,{...g,...N},t)}const u=new ut(m);return p&&u.finished.then(p),t&&(t.animations.push(u),u.finished.then(()=>{be(t.animations,u)})),u}return s}const F=_t(),he=8;function Mt({badgeId:e,tier:t,locked:n=!1,size:r=176,backLines:s=[],label:c}){const i=Qe(0),f=et(),m=L.useRef(null),p=L.useRef(null),g=L.useRef(!1),u=qe(t,n),x=je.get(e)?.icon||null,N=z(i,o=>`${(o%360+360)%360/360*160-80}%`),k=z(i,o=>`${80-(o%360+360)%360/360*160}%`),E=z(i,o=>{const l=Math.abs(Math.sin(o*Math.PI/180));return Math.max(0,(l-.35)/.65)*.3}),b=()=>{p.current?.stop?.(),p.current=null};L.useEffect(()=>{if(f||g.current)return;let o=!1;i.set(-360);const l=F(i,0,{duration:.9,ease:[.16,1,.3,1]});return p.current=l,l.then(()=>{o||g.current||(p.current=F(i,[0,-14,14,0],{duration:4.5,repeat:1/0,ease:"easeInOut"}))}),()=>{o=!0,b()}},[f,i]);const v=o=>{const l=i.get();if(f){const y=Math.round(l/180)*180;p.current=F(i,y,{duration:.2,ease:"easeOut"});return}const d=l+o*.35,D=Math.round(d/180)*180;p.current=F(i,D,{type:"spring",velocity:o,stiffness:58,damping:13.5,mass:1})},j=o=>{g.current=!0,b(),o.currentTarget.setPointerCapture?.(o.pointerId),m.current={pointerId:o.pointerId,startX:o.clientX,startRot:i.get(),samples:[{t:o.timeStamp,x:o.clientX}]}},_=o=>{const l=m.current;!l||l.pointerId!==o.pointerId||(i.set(l.startRot+(o.clientX-l.startX)*.55),l.samples.push({t:o.timeStamp,x:o.clientX}),l.samples.length>5&&l.samples.shift())},w=o=>{const l=m.current;if(!l||l.pointerId!==o.pointerId)return;m.current=null;const d=l.samples[0],D=l.samples[l.samples.length-1],y=D.t-d.t,R=y>0?(D.x-d.x)*.55*1e3/y:0;v(R)},M=o=>{if(o.key!=="ArrowLeft"&&o.key!=="ArrowRight")return;o.preventDefault(),g.current=!0,b();const l=o.key==="ArrowRight"?30:-30;p.current=F(i,i.get()+l,{duration:.15,ease:"easeOut"})},A={backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"};return a.jsx("div",{role:"img","aria-label":c,tabIndex:0,onPointerDown:j,onPointerMove:_,onPointerUp:w,onPointerCancel:w,onKeyDown:M,className:"inline-flex cursor-grab select-none items-center justify-center outline-none focus-visible:ring-2 focus-visible:ring-oai-brand/60 rounded-full active:cursor-grabbing",style:{perspective:900,touchAction:"pan-y"},children:a.jsxs("div",{className:"relative",style:{transform:"rotateX(-8deg)",transformStyle:"preserve-3d"},children:[a.jsxs(C.div,{className:"relative",style:{rotateY:i,transformStyle:"preserve-3d",width:r,height:r},children:[[-3,-1.5,0,1.5,3].map(o=>a.jsx("div",{"aria-hidden":!0,className:"absolute inset-0 rounded-full",style:{transform:`translateZ(${o}px)`,background:u.rim[1]}},o)),a.jsxs("div",{className:"absolute inset-0 overflow-hidden rounded-full",style:{...A,transform:`translateZ(${he/2}px)`},children:[a.jsx(Ze,{badgeId:e,tier:t,locked:n,size:"fill",className:"brightness-105 saturate-[1.08]"}),a.jsx("div",{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 rounded-full",style:{background:"radial-gradient(circle at 30% 20%, rgba(255,255,255,0.45), rgba(255,255,255,0) 42%), linear-gradient(172deg, rgba(255,255,255,0.14) 0%, rgba(255,255,255,0) 38%, rgba(0,0,0,0.08) 100%)",boxShadow:"inset 0 3px 7px rgba(255,255,255,0.5), inset 0 -3px 8px rgba(0,0,0,0.15)"}}),a.jsx(C.div,{"aria-hidden":!0,className:"pointer-events-none absolute inset-0",style:{x:N,background:"linear-gradient(105deg, transparent 34%, rgba(255,255,255,0.5) 50%, transparent 66%)"}}),a.jsx(C.div,{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 rounded-full",style:{opacity:E,background:"rgba(8, 12, 10, 0.9)"}})]}),a.jsxs("div",{className:"absolute inset-0 flex flex-col items-center justify-center gap-1 overflow-hidden rounded-full px-6 text-center",style:{...A,transform:`rotateY(180deg) translateZ(${he/2}px)`,background:`linear-gradient(145deg, ${u.face[0]}, ${u.face[1]})`,boxShadow:`inset 0 0 0 6px ${u.rim[1]}, inset 0 0 0 7.5px rgba(255,255,255,0.22), inset 0 3px 7px rgba(255,255,255,0.4), inset 0 -4px 12px rgba(0,0,0,0.22)`},children:[a.jsx("div",{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 rounded-full",style:{background:"repeating-radial-gradient(circle at 50% 50%, rgba(255,255,255,0.06) 0px, rgba(255,255,255,0.06) 1px, transparent 1px, transparent 4px)"}}),x?a.jsx(x,{"aria-hidden":!0,size:Math.round(r*.62),strokeWidth:1.1,color:u.glyph,className:"pointer-events-none absolute opacity-[0.13]",style:{filter:"drop-shadow(0 1px 0 rgba(255,255,255,0.3)) drop-shadow(0 -1px 0 rgba(0,0,0,0.35))"}}):null,a.jsx("div",{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 rounded-full",style:{background:"radial-gradient(circle at 70% 20%, rgba(255,255,255,0.4), rgba(255,255,255,0) 44%), linear-gradient(188deg, rgba(255,255,255,0.12) 0%, rgba(255,255,255,0) 38%, rgba(0,0,0,0.10) 100%)"}}),s.map((o,l)=>a.jsx("div",{className:`font-mono tabular-nums ${l===0?"text-[10px] uppercase tracking-[0.18em]":l===1?"text-lg font-bold":"text-[11px]"}`,style:{color:u.glyph,textShadow:"0 1px 0 rgba(255,255,255,0.28), 0 -1px 0 rgba(0,0,0,0.3)"},children:o},`${l}-${o}`)),a.jsx(C.div,{"aria-hidden":!0,className:"pointer-events-none absolute inset-0",style:{x:k,background:"linear-gradient(105deg, transparent 34%, rgba(255,255,255,0.45) 50%, transparent 66%)"}}),a.jsx(C.div,{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 rounded-full",style:{opacity:E,background:"rgba(8, 12, 10, 0.9)"}})]})]}),a.jsx("div",{"aria-hidden":!0,className:"absolute left-1/2 h-3 w-3/5 rounded-[100%] bg-black/20 blur-md dark:bg-black/45",style:{bottom:-20,transform:"translateX(-50%)"}})]})})}function Ae(e){if(!e)return null;const t=Date.parse(e);return Number.isFinite(t)?new Date(t).toLocaleDateString():null}function Vt(e){const t=Number(e);return!Number.isSafeInteger(t)||t<1?null:String(t).padStart(6,"0")}function Tt(e,t,n){if(t?.scope!=="cloud"||!n)return null;const r=Number(e?.serials?.[n]);return Number.isSafeInteger(r)&&r>=1?r:null}function $t({badge:e}){return a.jsx("div",{className:"flex items-center gap-1",children:Je.map((t,n)=>{const r=(e.tier||0)>=n+1,s=Ae(e.achieved?.[t]),c=T[t];return a.jsx("span",{title:s?`${h(`achievements.tier.${t}`)} · ${s}`:h(`achievements.tier.${t}`),className:"inline-flex h-2 w-8 rounded-full",style:r?{background:`linear-gradient(120deg, ${c.rim[0]} 0%, ${c.ring} 55%, ${c.rim[1]} 100%)`,boxShadow:"inset 0 1px 1px rgba(255,255,255,0.4), 0 0 0 1px rgba(10,15,12,0.05)"}:void 0,children:!r&&a.jsx("span",{className:"h-full w-full rounded-full bg-oai-gray-200 dark:bg-oai-gray-800"})},t)})})}function ge({badge:e,onClose:t}){const n=je.get(e.id),r=h(U(e.id,"name")),s=(e.tier||0)>=1,c=s?le(e.tier):null,i=Ae(s?e.achieved?.[c]||(ce(e)?new Date(ce(e)).toISOString():null):null),f=ue(n?.format,e.metric_value),m=tt(e),p=e.tier<4?le((e.tier||0)+1):null,g=Tt(e,n,c),u=Vt(g),x=u?[h("achievements.modal.achieved_label"),h("achievements.modal.issue_number",{number:u}),i||r]:[s?h("achievements.modal.achieved_label"):h("achievements.modal.locked"),s?f:"···",s&&i?i:r];return a.jsxs("div",{className:"flex flex-col items-center px-6 pb-6 pt-5 text-center",children:[a.jsxs("div",{className:"flex w-full items-start justify-between gap-3",children:[a.jsxs("div",{className:"min-w-0 flex-1 text-left",children:[a.jsx("h2",{className:"truncate text-lg font-semibold tracking-tight text-oai-black dark:text-white",children:r}),a.jsx("p",{className:"mt-0.5 text-xs text-oai-gray-500 dark:text-oai-gray-400",children:h(U(e.id,"desc"))})]}),a.jsx("button",{type:"button",onClick:t,"aria-label":h("achievements.modal.close"),className:"shrink-0 rounded-md p-1.5 text-oai-gray-400 transition-colors hover:bg-oai-gray-100 hover:text-oai-gray-700 dark:hover:bg-oai-gray-900 dark:hover:text-oai-gray-200",children:a.jsx(Ie,{size:16})})]}),a.jsx("div",{className:"mt-5 mb-7",children:a.jsx(Mt,{badgeId:e.id,tier:e.tier,locked:!s,backLines:x,label:h("achievements.modal.coin_aria",{name:r})})}),a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("span",{className:"rounded-full px-2.5 py-0.5 text-[11px] font-semibold uppercase tracking-wide",style:s?{background:`linear-gradient(120deg, ${T[c].rim[0]} 0%, ${T[c].ring} 55%, ${T[c].rim[1]} 100%)`,color:T[c].glyph,textShadow:"0 1px 0 rgba(255,255,255,0.35)",boxShadow:"inset 0 1px 1px rgba(255,255,255,0.4), 0 0 0 1px rgba(10,15,12,0.06)"}:{background:"rgba(128,134,130,0.75)",color:"rgba(250,250,250,0.95)"},children:s?h(`achievements.tier.${c}`):h("achievements.modal.locked")}),s&&i?a.jsx("span",{className:"text-xs tabular-nums text-oai-gray-500 dark:text-oai-gray-400",children:i}):null]}),a.jsxs("dl",{className:"mt-5 w-full space-y-3 border-t border-oai-gray-200/70 pt-4 text-left dark:border-oai-gray-800/60",children:[a.jsxs("div",{className:"flex items-baseline justify-between gap-3 text-sm",children:[a.jsx("dt",{className:"text-oai-gray-500 dark:text-oai-gray-400",children:h("achievements.modal.value_label")}),a.jsx("dd",{className:"font-mono font-semibold tabular-nums text-oai-black dark:text-white",children:f})]}),a.jsxs("div",{children:[a.jsxs("div",{className:"flex items-baseline justify-between gap-3 text-xs text-oai-gray-500 dark:text-oai-gray-400",children:[a.jsx("span",{children:e.tier>=4?h("achievements.modal.max_tier"):h("achievements.modal.progress_to_next",{tier:h(`achievements.tier.${p}`)})}),e.tier<4&&e.next_threshold!=null?a.jsxs("span",{className:"font-mono tabular-nums",children:[f," ",e.lower_is_better?"→":"/"," ",ue(n?.format,e.next_threshold)]}):null]}),a.jsx("div",{className:"mt-1.5 h-1.5 w-full overflow-hidden rounded-full bg-oai-gray-200 dark:bg-oai-gray-800",children:a.jsx("div",{className:"h-full rounded-full transition-[width] duration-500",style:{width:`${Math.round((e.tier>=4?1:m)*100)}%`,background:s?`linear-gradient(90deg, ${T[c].rim[0]} 0%, ${T[c].ring} 55%, ${T[c].rim[1]} 100%)`:"rgba(128,134,130,0.75)",boxShadow:s?"inset 0 1px 1px rgba(255,255,255,0.35)":void 0}})})]}),a.jsxs("div",{className:"flex items-center justify-between gap-3 text-xs text-oai-gray-500 dark:text-oai-gray-400",children:[a.jsx("span",{children:h("achievements.modal.tier_history")}),a.jsx($t,{badge:e})]})]})]})}const xe=ye("relative w-full max-w-[380px] flex flex-col","rounded-2xl bg-white dark:bg-oai-gray-950","shadow-[0_20px_60px_-20px_rgba(0,0,0,0.25)] dark:shadow-[0_20px_60px_-10px_rgba(0,0,0,0.65)]","ring-1 ring-oai-gray-200 dark:ring-oai-gray-800 overflow-hidden","dark:border-t dark:border-white/[0.08]");function Ut({badge:e,onClose:t}){const n=De(),r=!!e;return L.useEffect(()=>{if(!n||!r)return;const s=c=>{c.key==="Escape"&&(c.stopPropagation(),t?.())};return window.addEventListener("keydown",s,!0),()=>window.removeEventListener("keydown",s,!0)},[n,r,t]),r?n?a.jsxs("div",{className:"fixed inset-0 z-[120] flex items-center justify-center p-4",children:[a.jsx("div",{className:"absolute inset-0 bg-black/40 backdrop-blur-[2px]",onClick:t,"aria-hidden":!0}),a.jsx("div",{className:xe,children:a.jsx(ge,{badge:e,onClose:t})})]}):a.jsx(nt,{open:!0,onOpenChange:s=>{s||t?.()},children:a.jsxs(rt,{children:[a.jsx(at,{className:"cost-modal-backdrop z-[110]"}),a.jsx(st,{className:"fixed inset-0 z-[120] flex items-center justify-center p-4",children:a.jsxs(it,{className:ye("cost-modal-popup",xe),children:[a.jsx(ot,{render:a.jsx("h2",{className:"sr-only"}),children:h(U(e.id,"name"))}),a.jsx(ge,{badge:e,onClose:t})]})})]})}):null}export{Ut as BadgeDetailModal,Tt as currentBadgeIssueNumber,Ut as default,Vt as formatIssueNumber};