Frank 2 hafta önce
ebeveyn
işleme
7a881b6950

+ 541 - 0
packages/console/app/src/routes/rankings.css

@@ -0,0 +1,541 @@
+[data-page="zen"][data-route="rankings"] {
+  [data-component="hero"][data-variant="rankings"] {
+    padding-top: var(--vertical-padding);
+    padding-bottom: var(--vertical-padding);
+
+    [data-slot="hero-copy"] {
+      p {
+        margin-bottom: 0;
+        max-width: 44rem;
+      }
+    }
+  }
+
+  [data-component="container"] {
+    border: none;
+  }
+
+  [data-component="footer"] {
+    border-top: none;
+  }
+
+  [data-component="rankings-section"] {
+    padding: var(--vertical-padding) var(--padding);
+
+    h3 {
+      font-size: 16px;
+      font-weight: 700;
+      color: var(--color-text-strong);
+    }
+  }
+
+  [data-slot="chart"] {
+    margin-top: 1.5rem;
+    background: var(--color-background-weak);
+    border: 1px solid var(--color-border-weak);
+    border-radius: 0.5rem;
+    padding: 2rem 1.5rem 1.5rem;
+    overflow: visible;
+
+    @media (max-width: 40rem) {
+      padding: 1.5rem 1rem 1rem;
+    }
+  }
+
+  [data-slot="bars"] {
+    display: flex;
+    align-items: flex-end;
+    gap: 0.75rem;
+    height: 20rem;
+
+    @media (max-width: 40rem) {
+      height: 14rem;
+      gap: 0.5rem;
+    }
+  }
+
+  [data-slot="bar-group"] {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    gap: 0.5rem;
+    height: 100%;
+    justify-content: flex-end;
+    min-width: 2.5rem;
+    cursor: default;
+    transition: opacity 0.15s ease;
+
+    &[data-dimmed] {
+      opacity: 0.35;
+    }
+  }
+
+  [data-slot="bar-label"] {
+    color: var(--color-text-weak);
+    font-size: 0.75rem;
+    white-space: nowrap;
+  }
+
+  [data-slot="bar-wrap"] {
+    position: relative;
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    justify-content: flex-end;
+    align-items: center;
+  }
+
+  [data-slot="bar"] {
+    width: 100%;
+    max-width: 4rem;
+    border-radius: 0.25rem 0.25rem 0 0;
+    min-height: 2px;
+    display: flex;
+    flex-direction: column-reverse;
+    gap: 1px;
+    overflow: hidden;
+
+    span {
+      display: block;
+      min-height: 1px;
+    }
+
+    span:last-child {
+      border-radius: 0.25rem 0.25rem 0 0;
+    }
+  }
+
+  [data-slot="bar-week"] {
+    color: var(--color-text-weak);
+    font-size: 0.75rem;
+    white-space: nowrap;
+  }
+
+  [data-slot="tooltip"] {
+    position: fixed;
+    z-index: 100;
+    transform: translateY(-100%);
+    background: var(--color-background);
+    border: 1px solid var(--color-border);
+    border-radius: 0.375rem;
+    padding: 0.75rem;
+    min-width: 14rem;
+    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
+    pointer-events: none;
+
+    strong {
+      display: block;
+      color: var(--color-text-strong);
+      font-size: 0.8125rem;
+      font-weight: 600;
+      margin-bottom: 0.125rem;
+    }
+  }
+
+  [data-slot="tooltip-total"] {
+    display: block;
+    color: var(--color-text-weak);
+    font-size: 0.75rem;
+    margin-bottom: 0.5rem;
+    padding-bottom: 0.5rem;
+    border-bottom: 1px solid var(--color-border-weak);
+  }
+
+  [data-slot="tooltip-row"] {
+    display: grid;
+    grid-template-columns: auto 1fr auto;
+    align-items: center;
+    gap: 0.5rem;
+    font-size: 0.75rem;
+    color: var(--color-text);
+    padding: 0.175rem 0;
+
+    i {
+      width: 0.5rem;
+      height: 0.5rem;
+      border-radius: 2px;
+      flex: none;
+    }
+
+    span:last-child {
+      text-align: right;
+      color: var(--color-text-strong);
+      font-weight: 500;
+    }
+  }
+
+  [data-slot="legend"] {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 0.75rem 1.25rem;
+    margin-top: 1.5rem;
+    padding-top: 1rem;
+    border-top: 1px solid var(--color-border-weak);
+  }
+
+  [data-slot="legend-item"] {
+    display: inline-flex;
+    align-items: center;
+    gap: 0.5rem;
+    font-size: 0.8125rem;
+    color: var(--color-text);
+
+    i {
+      width: 0.75rem;
+      height: 0.75rem;
+      border-radius: 2px;
+      flex: none;
+    }
+  }
+
+  [data-slot="subtitle"] {
+    color: var(--color-text);
+    margin-top: 0.5rem;
+  }
+
+  [data-slot="lb-podium"] {
+    display: grid;
+    grid-template-columns: repeat(3, minmax(0, 1fr));
+    gap: 0.75rem;
+    margin-top: 1.5rem;
+
+    @media (max-width: 40rem) {
+      grid-template-columns: 1fr;
+    }
+  }
+
+  [data-slot="lb-podium-item"] {
+    display: flex;
+    flex-direction: column;
+    gap: 0.375rem;
+    padding: 1.25rem;
+    background: var(--color-background-weak);
+    border: 1px solid var(--color-border-weak);
+    border-radius: 0.5rem;
+
+    strong {
+      color: var(--color-text-strong);
+      font-size: 1.0625rem;
+      font-weight: 600;
+    }
+  }
+
+  [data-slot="lb-podium-rank"] {
+    display: inline-flex;
+    align-items: center;
+    justify-content: center;
+    width: 1.75rem;
+    height: 1.75rem;
+    border-radius: 999px;
+    font-size: 0.8125rem;
+    font-weight: 700;
+    margin-bottom: 0.25rem;
+  }
+
+  [data-slot="lb-podium-item"][data-rank="1"] [data-slot="lb-podium-rank"] {
+    background: hsl(45, 93%, 47%);
+    color: hsl(45, 100%, 10%);
+  }
+
+  [data-slot="lb-podium-item"][data-rank="2"] [data-slot="lb-podium-rank"] {
+    background: hsl(0, 0%, 75%);
+    color: hsl(0, 0%, 15%);
+  }
+
+  [data-slot="lb-podium-item"][data-rank="3"] [data-slot="lb-podium-rank"] {
+    background: hsl(30, 60%, 50%);
+    color: hsl(30, 60%, 10%);
+  }
+
+  [data-slot="lb-podium-tokens"] {
+    color: var(--color-text-weak);
+    font-size: 0.875rem;
+  }
+
+  [data-slot="leaderboard"] {
+    display: grid;
+    grid-template-columns: repeat(2, minmax(0, 1fr));
+    gap: 0 2rem;
+    margin-top: 1rem;
+
+    @media (max-width: 58rem) {
+      grid-template-columns: 1fr;
+    }
+  }
+
+  [data-slot="lb-col"] {
+    display: grid;
+    align-content: start;
+  }
+
+  [data-slot="lb-col"] [data-slot="lb-row"]:last-child {
+    border-bottom: none;
+  }
+
+  [data-slot="lb-row"] {
+    display: grid;
+    grid-template-columns: 2rem minmax(0, 1fr) auto;
+    align-items: center;
+    gap: 0.75rem;
+    padding: 0.75rem 0;
+    border-bottom: 1px solid var(--color-border-weak);
+  }
+
+  [data-slot="lb-row"]:last-child {
+    border-bottom: none;
+  }
+
+  [data-slot="lb-rank"] {
+    color: var(--color-text-weak);
+    font-size: 0.875rem;
+  }
+
+  [data-slot="lb-info"] {
+    min-width: 0;
+
+    strong {
+      display: block;
+      color: var(--color-text-strong);
+      font-size: 0.9375rem;
+      font-weight: 500;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+  }
+
+  [data-slot="lb-tokens"] {
+    white-space: nowrap;
+    color: var(--color-text);
+    font-size: 0.875rem;
+  }
+
+  [data-slot="lb-toggle"] {
+    display: block;
+    margin: 1rem auto 0;
+    padding: 0;
+    background: none;
+    border: none;
+    color: var(--color-text-weak);
+    font: inherit;
+    font-size: 0.875rem;
+    cursor: pointer;
+    text-decoration: underline;
+    text-underline-offset: 0.14em;
+    text-decoration-thickness: 1px;
+
+    &:hover {
+      color: var(--color-text-strong);
+    }
+  }
+
+  [data-slot="share-bars"] {
+    display: flex;
+    gap: 0.5rem;
+    height: 20rem;
+
+    @media (max-width: 40rem) {
+      height: 14rem;
+      gap: 0.375rem;
+    }
+  }
+
+  [data-slot="share-col"] {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    gap: 0.5rem;
+    min-width: 2.5rem;
+    cursor: default;
+    transition: opacity 0.15s ease;
+
+    &[data-dimmed] {
+      opacity: 0.35;
+    }
+  }
+
+  [data-slot="share-stack"] {
+    flex: 1;
+    display: flex;
+    flex-direction: column-reverse;
+    gap: 1px;
+    border-radius: 0.25rem;
+    overflow: hidden;
+
+    span {
+      display: block;
+      min-height: 1px;
+    }
+  }
+
+  [data-slot="share-week"] {
+    color: var(--color-text-weak);
+    font-size: 0.75rem;
+    text-align: center;
+    white-space: nowrap;
+  }
+
+  [data-slot="pricing-table"] {
+    margin-top: 1.5rem;
+    border: 1px solid var(--color-border-weak);
+    border-radius: 0.5rem;
+    overflow: hidden;
+  }
+
+  [data-slot="pricing-header"],
+  [data-slot="pricing-row"] {
+    display: grid;
+    grid-template-columns: minmax(0, 1.5fr) repeat(4, minmax(0, 1fr));
+    gap: 0.75rem;
+    padding: 0.75rem 1.25rem;
+
+    &[data-cols="4"] {
+      grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr));
+    }
+
+    &[data-cols="3"] {
+      grid-template-columns: minmax(0, 1.5fr) repeat(2, minmax(0, 1fr));
+    }
+
+    &[data-cols="2"] {
+      grid-template-columns: minmax(0, 1fr) auto;
+    }
+
+    @media (max-width: 40rem) {
+      padding: 0.625rem 0.75rem;
+      gap: 0.5rem;
+    }
+  }
+
+  [data-slot="pricing-header"] {
+    background: var(--color-background-weak);
+    border-bottom: 1px solid var(--color-border-weak);
+    font-size: 0.8125rem;
+    font-weight: 600;
+    color: var(--color-text-weak);
+  }
+
+  [data-slot="pricing-row"] {
+    border-bottom: 1px solid var(--color-border-weak);
+    font-size: 0.875rem;
+    color: var(--color-text);
+
+    &:last-child {
+      border-bottom: none;
+    }
+  }
+
+  [data-slot="cost-list"] {
+    margin-top: 1.5rem;
+  }
+
+  [data-slot="cost-group"] {
+    &:last-child {
+      margin-bottom: 0;
+      padding-bottom: 0;
+    }
+  }
+
+  [data-slot="cost-row"] {
+    padding: 0.5rem 0;
+  }
+
+  [data-slot="cost-main"] {
+    display: grid;
+    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1.2fr);
+    align-items: center;
+    gap: 0.75rem 2rem;
+  }
+
+  [data-slot="cost-detail"] {
+    display: flex;
+    gap: 1rem;
+    margin-top: 0.375rem;
+    font-size: 0.75rem;
+    color: var(--color-text-weak);
+  }
+
+  [data-slot="cost-bar-wrap"] {
+    height: 0.375rem;
+    background: var(--color-border-weak);
+    border-radius: 999px;
+  }
+
+  [data-slot="cost-bar"] {
+    display: block;
+    height: 100%;
+    background: var(--color-background-strong);
+    border-radius: 999px;
+    min-width: 2px;
+  }
+
+  [data-slot="pricing-model"] {
+    color: var(--color-text-strong);
+    font-weight: 500;
+    font-size: 0.9375rem;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
+
+  [data-slot="pricing-effective"] {
+    color: var(--color-text-strong);
+    font-weight: 600;
+  }
+
+  [data-slot="tps-cell"] {
+    position: relative;
+    display: flex;
+    align-items: center;
+    height: 0.5rem;
+    background: var(--color-border-weak);
+    border-radius: 999px;
+    cursor: default;
+
+    &:hover::after {
+      content: attr(title);
+      position: absolute;
+      bottom: calc(100% + 0.375rem);
+      left: 50%;
+      transform: translateX(-50%);
+      padding: 0.25rem 0.5rem;
+      background: var(--color-background);
+      border: 1px solid var(--color-border);
+      border-radius: 0.25rem;
+      font-size: 0.75rem;
+      color: var(--color-text-strong);
+      white-space: nowrap;
+      pointer-events: none;
+      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+      z-index: 10;
+    }
+  }
+
+  [data-slot="tps-bar"] {
+    height: 100%;
+    background: var(--color-background-strong);
+    border-radius: 999px 0 0 999px;
+    min-width: 2px;
+  }
+
+  [data-slot="map-wrap"] {
+    position: relative;
+    margin-top: 1.5rem;
+  }
+
+  [data-slot="world-map"] {
+    width: 100%;
+    height: auto;
+
+    path {
+      cursor: default;
+      transition: opacity 0.15s ease;
+
+      &:hover {
+        opacity: 0.8;
+      }
+    }
+  }
+}

+ 920 - 0
packages/console/app/src/routes/rankings.tsx

@@ -0,0 +1,920 @@
+import "./zen/index.css"
+import "./rankings.css"
+import { Title } from "@solidjs/meta"
+import { createSignal, For, Show } from "solid-js"
+import { Footer } from "~/component/footer"
+import { Header } from "~/component/header"
+import { Legal } from "~/component/legal"
+import { LocaleLinks } from "~/component/locale-links"
+import { paths as worldPaths } from "./world-paths"
+
+const models = [
+  { name: "minimax-m2.5-free", color: "#f25bb2" },
+  { name: "big-pickle", color: "#8b5cf6" },
+  { name: "mimo-v2-pro-free", color: "#18a57b" },
+  { name: "kimi-k2.5-free", color: "#3481cf" },
+  { name: "kimi-k2.5", color: "#e4ad27" },
+  { name: "minimax-m2.1-free", color: "#ff5a1f" },
+  { name: "glm-5-free", color: "#46b786" },
+  { name: "gpt-5-nano", color: "#84cc16" },
+  { name: "nemotron-3-super-free", color: "#14c2a3" },
+  { name: "claude-opus-4-6", color: "#ff7b3d" },
+] as const
+
+type Week = {
+  week: string
+  segments: { model: string; color: string; tokens: number }[]
+  total: number
+}
+
+const raw: Record<string, Record<string, number>> = {
+  "jan-27": {
+    "big-pickle": 368743864804,
+    "kimi-k2.5-free": 915886375887,
+    "kimi-k2.5": 39168495089,
+    "minimax-m2.1-free": 270764664177,
+    "gpt-5-nano": 41276213376,
+  },
+  "feb-3": {
+    "big-pickle": 520618971808,
+    "kimi-k2.5-free": 980317788887,
+    "kimi-k2.5": 92823557285,
+    "minimax-m2.1-free": 721380871693,
+    "gpt-5-nano": 74420810088,
+    "claude-opus-4-6": 49826050233,
+  },
+  "feb-10": {
+    "minimax-m2.5-free": 905276977685,
+    "big-pickle": 775593605696,
+    "kimi-k2.5-free": 546100624556,
+    "kimi-k2.5": 106869700825,
+    "minimax-m2.1-free": 273479063739,
+    "glm-5-free": 21944995438,
+    "gpt-5-nano": 86562724981,
+    "claude-opus-4-6": 71785580030,
+  },
+  "feb-17": {
+    "minimax-m2.5-free": 1313909105944,
+    "big-pickle": 1017431400927,
+    "kimi-k2.5-free": 350112011799,
+    "kimi-k2.5": 100616295719,
+    "minimax-m2.1-free": 11269742719,
+    "glm-5-free": 735726749938,
+    "gpt-5-nano": 79036772388,
+    "claude-opus-4-6": 66789922519,
+  },
+  "feb-24": {
+    "minimax-m2.5-free": 1988229542028,
+    "big-pickle": 1332574843957,
+    "kimi-k2.5-free": 17964822381,
+    "kimi-k2.5": 152009783828,
+    "minimax-m2.1-free": 10376282858,
+    "glm-5-free": 3848233361,
+    "gpt-5-nano": 94195723658,
+    "claude-opus-4-6": 72579249230,
+  },
+  "mar-3": {
+    "minimax-m2.5-free": 1103526073812,
+    "big-pickle": 864075264151,
+    "kimi-k2.5": 236732504356,
+    "gpt-5-nano": 62076480967,
+    "claude-opus-4-6": 75122544903,
+  },
+  "mar-10": {
+    "minimax-m2.5-free": 1765538911999,
+    "big-pickle": 1456821813321,
+    "kimi-k2.5": 270005019814,
+    "gpt-5-nano": 80064940458,
+    "nemotron-3-super-free": 226767628611,
+    "claude-opus-4-6": 121826865344,
+  },
+  "mar-17": {
+    "minimax-m2.5-free": 2258964526070,
+    "big-pickle": 2157757939980,
+    "mimo-v2-pro-free": 1393092895745,
+    "kimi-k2.5": 253277628360,
+    "gpt-5-nano": 91075743861,
+    "nemotron-3-super-free": 257336931857,
+    "claude-opus-4-6": 107180831444,
+  },
+  "mar-24": {
+    "minimax-m2.5-free": 2256417941175,
+    "big-pickle": 2596072141208,
+    "mimo-v2-pro-free": 1612680626347,
+    "kimi-k2.5": 263140655381,
+    "gpt-5-nano": 130043140955,
+    "nemotron-3-super-free": 254171104198,
+    "claude-opus-4-6": 107813898809,
+  },
+}
+
+const totals: Record<string, number> = {
+  "jan-27": 1954431878631,
+  "feb-3": 2782873471532,
+  "feb-10": 2982021636344,
+  "feb-17": 3898395901667,
+  "feb-24": 3980255846812,
+  "mar-3": 2789862168396,
+  "mar-10": 4672779512356,
+  "mar-17": 7453410720062,
+  "mar-24": 8434615944207,
+}
+
+const weeks = ["jan-27", "feb-3", "feb-10", "feb-17", "feb-24", "mar-3", "mar-10", "mar-17", "mar-24"]
+const labels: Record<string, string> = {
+  "jan-27": "Jan 27",
+  "feb-3": "Feb 3",
+  "feb-10": "Feb 10",
+  "feb-17": "Feb 17",
+  "feb-24": "Feb 24",
+  "mar-3": "Mar 3",
+  "mar-10": "Mar 10",
+  "mar-17": "Mar 17",
+  "mar-24": "Mar 24",
+}
+
+const usage: Week[] = weeks.map((key) => {
+  const data = raw[key]
+  const total = totals[key]
+  const named = models.filter((m) => data[m.name]).map((m) => ({ model: m.name, color: m.color, tokens: data[m.name] }))
+  const rest = total - named.reduce((sum, s) => sum + s.tokens, 0)
+  return {
+    week: labels[key],
+    total,
+    segments: [...named, { model: "Other", color: "rgba(148, 163, 184, 0.35)", tokens: rest }],
+  }
+})
+
+const max = Math.max(...usage.map((w) => w.total))
+
+const fmt = (n: number) => {
+  if (n >= 1e12) return `${(n / 1e12).toFixed(1)}T`
+  return `${(n / 1e9).toFixed(0)}B`
+}
+
+const leaderboard = [
+  { rank: 1, model: "big-pickle", tokens: 2_596_072_141_208 },
+  { rank: 2, model: "minimax-m2.5-free", tokens: 2_256_417_941_175 },
+  { rank: 3, model: "mimo-v2-pro-free", tokens: 1_612_680_626_347 },
+  { rank: 4, model: "mimo-v2-omni-free", tokens: 313_963_070_777 },
+  { rank: 5, model: "kimi-k2.5", tokens: 263_140_655_381 },
+  { rank: 6, model: "nemotron-3-super-free", tokens: 254_171_104_198 },
+  { rank: 7, model: "minimax-m2.7", tokens: 235_471_532_073 },
+  { rank: 8, model: "qwen3.6-plus-free", tokens: 211_645_852_696 },
+  { rank: 9, model: "glm-5", tokens: 149_968_059_435 },
+  { rank: 10, model: "gpt-5-nano", tokens: 130_043_140_955 },
+  { rank: 11, model: "claude-opus-4-6", tokens: 107_813_898_809 },
+  { rank: 12, model: "minimax-m2.5", tokens: 91_477_876_330 },
+  { rank: 13, model: "gpt-5.4", tokens: 64_216_544_736 },
+  { rank: 14, model: "claude-sonnet-4-6", tokens: 53_638_240_479 },
+  { rank: 15, model: "gpt-5.3-codex", tokens: 31_928_019_743 },
+  { rank: 16, model: "gemini-3-flash", tokens: 14_528_488_448 },
+  { rank: 17, model: "claude-haiku-4-5", tokens: 8_921_076_835 },
+  { rank: 18, model: "gemini-3.1-pro", tokens: 7_676_935_166 },
+  { rank: 19, model: "claude-sonnet-4-5", tokens: 5_051_555_617 },
+  { rank: 20, model: "gpt-5.4-mini", tokens: 4_751_125_737 },
+]
+
+const providers = [
+  { name: "opencode", color: "#8b5cf6" },
+  { name: "minimax", color: "#f25bb2" },
+  { name: "xiaomi", color: "#ff5a1f" },
+  { name: "moonshot", color: "#3481cf" },
+  { name: "nvidia", color: "#14c2a3" },
+  { name: "openai", color: "#84cc16" },
+  { name: "anthropic", color: "#ff7b3d" },
+  { name: "zhipu", color: "#46b786" },
+  { name: "google", color: "#e4ad27" },
+  { name: "alibaba", color: "#ef5db1" },
+  { name: "arcee", color: "#2085ec" },
+] as const
+
+const shareRaw: Record<string, Record<string, number>> = {
+  "jan-27": {
+    moonshot: 957101046076,
+    opencode: 368743864804,
+    minimax: 273789245099,
+    zhipu: 175220173052,
+    openai: 71428726197,
+    anthropic: 63795092028,
+    arcee: 22900709163,
+    google: 21116481943,
+    alibaba: 336540269,
+  },
+  "feb-3": {
+    moonshot: 1075728836899,
+    minimax: 727777460147,
+    opencode: 520618971808,
+    anthropic: 126083048915,
+    openai: 119992167519,
+    zhipu: 106315324243,
+    arcee: 70511760645,
+    google: 35345191581,
+    alibaba: 500567954,
+  },
+  "feb-10": {
+    minimax: 1195064506114,
+    opencode: 775593605696,
+    moonshot: 655693064959,
+    openai: 126021773769,
+    anthropic: 114969689993,
+    zhipu: 66447874989,
+    google: 27728156767,
+    arcee: 20502880487,
+  },
+  "feb-17": {
+    minimax: 1340689075939,
+    opencode: 1017431400927,
+    zhipu: 753486920157,
+    moonshot: 453006079914,
+    anthropic: 136280713749,
+    openai: 117036878336,
+    google: 44709966980,
+    arcee: 35460739820,
+  },
+  "feb-24": {
+    minimax: 2037390464296,
+    opencode: 1332574843957,
+    moonshot: 172345287072,
+    openai: 165404921924,
+    anthropic: 137007019288,
+    arcee: 65348467867,
+    zhipu: 36192647725,
+    google: 32632757942,
+  },
+  "mar-3": {
+    minimax: 1236589693899,
+    opencode: 864075264151,
+    moonshot: 236940261927,
+    openai: 144296631970,
+    anthropic: 143388311109,
+    zhipu: 89420861866,
+    google: 35499950281,
+    xiaomi: 24396507662,
+    arcee: 14674544044,
+  },
+  "mar-10": {
+    minimax: 1919467888084,
+    opencode: 1456821813321,
+    xiaomi: 302031698856,
+    moonshot: 270021430246,
+    nvidia: 226767628611,
+    anthropic: 181566633371,
+    openai: 171713393912,
+    zhipu: 113460952065,
+    google: 30109971757,
+    arcee: 818102133,
+  },
+  "mar-17": {
+    minimax: 2536581988215,
+    opencode: 2157757939980,
+    xiaomi: 1708313298084,
+    nvidia: 257336931857,
+    moonshot: 253304780525,
+    openai: 196305815207,
+    anthropic: 188087354693,
+    zhipu: 127277270842,
+    google: 28180238053,
+    arcee: 265058488,
+  },
+  "mar-24": {
+    opencode: 2596072141208,
+    minimax: 2583441903425,
+    xiaomi: 1930671539776,
+    moonshot: 263142158847,
+    nvidia: 254171104198,
+    openai: 242821016755,
+    alibaba: 211645852696,
+    anthropic: 179934787304,
+    zhipu: 150050493012,
+    google: 22325363704,
+    arcee: 336333746,
+  },
+}
+
+const share = weeks.map((key) => {
+  const data = shareRaw[key]
+  const total = totals[key]
+  const segs = providers
+    .filter((p) => data[p.name])
+    .map((p) => ({
+      provider: p.name,
+      color: p.color,
+      tokens: data[p.name],
+      pct: (data[p.name] / total) * 100,
+    }))
+  return { week: labels[key], total, segments: segs }
+})
+
+const pricing: Record<string, { input: number; output: number; cached: number }> = {
+  "kimi-k2.5": { input: 0.6, output: 3.0, cached: 0.1 },
+  "minimax-m2.7": { input: 0.3, output: 1.2, cached: 0.06 },
+  "glm-5": { input: 1.0, output: 3.2, cached: 0.2 },
+  "claude-opus-4-6": { input: 5.0, output: 25.0, cached: 0.5 },
+  "minimax-m2.5": { input: 0.3, output: 1.2, cached: 0.03 },
+  "gpt-5.4": { input: 2.5, output: 15.0, cached: 0.25 },
+  "claude-sonnet-4-6": { input: 3.0, output: 15.0, cached: 0.3 },
+  "gpt-5.3-codex": { input: 1.75, output: 14.0, cached: 0.175 },
+  "gemini-3-flash": { input: 0.5, output: 3.0, cached: 0.05 },
+  "claude-haiku-4-5": { input: 1.0, output: 5.0, cached: 0.1 },
+  "gemini-3.1-pro": { input: 2.0, output: 12.0, cached: 0.2 },
+  "claude-sonnet-4-5": { input: 3.0, output: 15.0, cached: 0.3 },
+  "gpt-5.4-mini": { input: 0.75, output: 4.5, cached: 0.075 },
+}
+
+const effective = (p: { input: number; output: number; cached: number }) =>
+  p.cached * 0.94 + p.input * 0.06 + p.output * 0.01
+
+const price = (n: number) => (n === 0 ? "Free" : `$${n.toFixed(2)}`)
+
+const modelGroup: Record<string, string> = {
+  "kimi-k2.5": "moonshot",
+  "minimax-m2.7": "minimax",
+  "minimax-m2.5": "minimax",
+  "glm-5": "zhipu",
+  "claude-opus-4-6": "anthropic",
+  "claude-sonnet-4-6": "anthropic",
+  "claude-sonnet-4-5": "anthropic",
+  "claude-haiku-4-5": "anthropic",
+  "gpt-5.4": "openai",
+  "gpt-5.3-codex": "openai",
+  "gpt-5.4-mini": "openai",
+  "gemini-3-flash": "google",
+  "gemini-3.1-pro": "google",
+}
+
+const pricedModels = leaderboard
+  .filter((r) => !r.model.endsWith("-free") && pricing[r.model])
+  .sort((a, b) => effective(pricing[a.model]) - effective(pricing[b.model]))
+
+const maxEffective = Math.max(...pricedModels.map((r) => effective(pricing[r.model])))
+
+const grouped = (() => {
+  const groups: { provider: string; models: typeof pricedModels }[] = []
+  const seen = new Set<string>()
+  for (const row of pricedModels) {
+    const g = modelGroup[row.model] || row.model
+    if (seen.has(g)) continue
+    seen.add(g)
+    const items = pricedModels.filter((r) => (modelGroup[r.model] || r.model) === g)
+    groups.push({ provider: g, models: items })
+  }
+  return groups
+})()
+
+const sessions = [
+  { model: "gpt-5.4-nano", spend: 56.19, sessions: 2469, tokens: 2_058_320_992 },
+  { model: "gpt-5.1-codex-mini", spend: 46.49, sessions: 649, tokens: 1_114_706_819 },
+  { model: "minimax-m2.5", spend: 10774.93, sessions: 101862, tokens: 91_512_287_752 },
+  { model: "claude-haiku-4-5", spend: 2169.56, sessions: 14896, tokens: 8_965_515_678 },
+  { model: "gpt-5.4-mini", spend: 858.63, sessions: 4726, tokens: 4_759_454_622 },
+  { model: "minimax-m2.7", spend: 24120.99, sessions: 118523, tokens: 235_267_498_689 },
+  { model: "gpt-5.4", spend: 31834.9, sessions: 142909, tokens: 64_146_279_556 },
+  { model: "kimi-k2.5", spend: 39724.09, sessions: 150135, tokens: 263_660_128_320 },
+  { model: "gemini-3-flash", spend: 2294.28, sessions: 8405, tokens: 14_752_884_651 },
+  { model: "glm-5", spend: 37814.87, sessions: 105292, tokens: 150_626_981_063 },
+  { model: "claude-sonnet-4-6", spend: 32133.34, sessions: 42237, tokens: 53_550_067_871 },
+  { model: "gpt-5.3-codex", spend: 10809.82, sessions: 13888, tokens: 31_907_600_634 },
+  { model: "claude-sonnet-4-5", spend: 4061.09, sessions: 4057, tokens: 5_157_076_730 },
+  { model: "gemini-3.1-pro", spend: 6257.1, sessions: 5777, tokens: 7_569_358_077 },
+  { model: "claude-opus-4-6", spend: 114219.22, sessions: 42550, tokens: 106_575_958_684 },
+  { model: "claude-opus-4-5", spend: 3582.53, sessions: 1576, tokens: 3_219_688_476 },
+  { model: "gpt-5.4-pro", spend: 6555.13, sessions: 1264, tokens: 200_314_429 },
+]
+
+const avg = (r: (typeof sessions)[number]) => r.spend / r.sessions
+const avgTokens = (r: (typeof sessions)[number]) => Math.round(r.tokens / r.sessions)
+
+const fmtTokens = (n: number) => {
+  if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`
+  if (n >= 1e3) return `${(n / 1e3).toFixed(0)}K`
+  return String(n)
+}
+
+const maxTps = Math.max(...sessions.map((r) => avgTokens(r)))
+
+const countries: Record<string, number> = {
+  CN: 1_954_638_555_964,
+  US: 893_134_696_046,
+  IN: 535_643_693_640,
+  BR: 382_163_396_828,
+  DE: 311_242_520_442,
+  ES: 209_329_692_495,
+  RU: 201_527_328_150,
+  HK: 196_512_051_704,
+  GB: 166_553_586_780,
+  AR: 162_194_105_984,
+  SG: 158_456_781_083,
+  FR: 156_789_513_531,
+  JP: 152_176_549_930,
+  NL: 142_283_579_531,
+  ID: 133_099_866_730,
+  CA: 130_175_404_155,
+  IT: 104_164_651_206,
+  MX: 103_470_313_882,
+  TW: 99_750_103_092,
+  CO: 96_782_169_230,
+  VN: 89_760_456_363,
+  PL: 87_055_503_038,
+  TR: 83_380_620_873,
+  KR: 82_692_257_401,
+  AU: 82_626_936_402,
+  PH: 63_600_637_182,
+  EG: 61_672_925_246,
+  PT: 55_231_430_725,
+  BD: 54_398_663_664,
+  SE: 53_569_291_560,
+  CL: 52_319_761_865,
+  TH: 50_343_490_695,
+  NG: 50_159_406_105,
+  PK: 49_490_412_870,
+  FI: 45_825_535_387,
+  PE: 43_961_712_555,
+  CH: 43_300_038_112,
+  MY: 41_561_444_011,
+  RO: 40_383_208_346,
+  BE: 38_322_022_514,
+  MA: 38_272_211_062,
+  ZA: 38_180_939_069,
+  UA: 36_032_426_930,
+  VE: 34_807_973_969,
+  KE: 34_239_081_597,
+  IL: 32_705_941_531,
+  AT: 31_995_376_039,
+  DZ: 29_533_977_612,
+  CZ: 28_976_529_740,
+  NP: 25_623_967_353,
+  DO: 23_957_780_174,
+  DK: 22_736_971_721,
+  EC: 21_934_976_342,
+  AE: 21_823_728_235,
+  TN: 21_412_135_454,
+  NO: 20_735_253_026,
+  SA: 20_234_711_215,
+  BY: 18_939_368_533,
+  GH: 16_936_621_597,
+  RS: 16_778_051_855,
+  NZ: 16_319_979_678,
+  ET: 15_465_960_765,
+  IE: 14_978_507_068,
+  BO: 14_833_821_684,
+  GR: 14_785_265_286,
+  HU: 14_540_890_452,
+  UY: 13_804_790_917,
+  UZ: 13_008_621_109,
+  LK: 12_735_597_659,
+  BG: 12_045_851_521,
+  CR: 11_261_069_513,
+  PY: 10_614_168_600,
+  KH: 10_555_315_979,
+  KZ: 10_159_168_104,
+  LT: 9_815_793_110,
+  EE: 9_417_177_100,
+  UG: 9_165_111_455,
+  SK: 9_070_826_870,
+  LV: 8_198_013_338,
+  IQ: 8_187_011_695,
+  HR: 7_605_019_662,
+  CM: 7_377_050_916,
+  ZW: 7_314_742_432,
+  YE: 6_747_216_591,
+  JO: 6_211_747_207,
+  PA: 6_092_366_683,
+  QA: 5_955_042_936,
+  MD: 5_773_585_201,
+  TZ: 5_625_754_397,
+  NI: 5_228_293_282,
+  GE: 5_165_628_063,
+  SI: 4_955_336_900,
+  SN: 4_688_066_204,
+  BA: 4_549_605_753,
+  BJ: 4_543_143_957,
+  GT: 4_424_503_835,
+  HN: 4_405_852_608,
+  OM: 4_395_319_849,
+}
+
+const maxCountry = Math.max(...Object.values(countries))
+
+const names: Record<string, string> = {
+  CN: "China",
+  US: "United States",
+  IN: "India",
+  BR: "Brazil",
+  DE: "Germany",
+  ES: "Spain",
+  RU: "Russia",
+  HK: "Hong Kong",
+  GB: "United Kingdom",
+  AR: "Argentina",
+  SG: "Singapore",
+  FR: "France",
+  JP: "Japan",
+  NL: "Netherlands",
+  ID: "Indonesia",
+  CA: "Canada",
+  IT: "Italy",
+  MX: "Mexico",
+  TW: "Taiwan",
+  CO: "Colombia",
+  VN: "Vietnam",
+  PL: "Poland",
+  TR: "Turkey",
+  KR: "South Korea",
+  AU: "Australia",
+  PH: "Philippines",
+  EG: "Egypt",
+  PT: "Portugal",
+  BD: "Bangladesh",
+  SE: "Sweden",
+  CL: "Chile",
+  TH: "Thailand",
+  NG: "Nigeria",
+  PK: "Pakistan",
+  FI: "Finland",
+  PE: "Peru",
+  CH: "Switzerland",
+  MY: "Malaysia",
+  RO: "Romania",
+  BE: "Belgium",
+  MA: "Morocco",
+  ZA: "South Africa",
+  UA: "Ukraine",
+  VE: "Venezuela",
+  KE: "Kenya",
+  IL: "Israel",
+  AT: "Austria",
+  DZ: "Algeria",
+  CZ: "Czechia",
+  NP: "Nepal",
+  DO: "Dominican Republic",
+  DK: "Denmark",
+  EC: "Ecuador",
+  AE: "UAE",
+  TN: "Tunisia",
+  NO: "Norway",
+  SA: "Saudi Arabia",
+  BY: "Belarus",
+  GH: "Ghana",
+  RS: "Serbia",
+  NZ: "New Zealand",
+  ET: "Ethiopia",
+  IE: "Ireland",
+  BO: "Bolivia",
+  GR: "Greece",
+  HU: "Hungary",
+  UY: "Uruguay",
+  UZ: "Uzbekistan",
+  LK: "Sri Lanka",
+  BG: "Bulgaria",
+  CR: "Costa Rica",
+  PY: "Paraguay",
+  KH: "Cambodia",
+  KZ: "Kazakhstan",
+  LT: "Lithuania",
+  EE: "Estonia",
+  UG: "Uganda",
+  SK: "Slovakia",
+  LV: "Latvia",
+  IQ: "Iraq",
+  HR: "Croatia",
+  CM: "Cameroon",
+  ZW: "Zimbabwe",
+  YE: "Yemen",
+  JO: "Jordan",
+  PA: "Panama",
+  QA: "Qatar",
+  MD: "Moldova",
+  TZ: "Tanzania",
+  NI: "Nicaragua",
+  GE: "Georgia",
+  SI: "Slovenia",
+  SN: "Senegal",
+  BA: "Bosnia",
+  BJ: "Benin",
+  GT: "Guatemala",
+  HN: "Honduras",
+  OM: "Oman",
+}
+
+const flag = (code: string) => String.fromCodePoint(...[...code].map((c) => 0x1f1e6 + c.charCodeAt(0) - 65))
+
+const fill = (code: string) => {
+  const val = countries[code]
+  if (!val) return "var(--color-border-weak)"
+  const t = Math.pow(Math.log(val) / Math.log(maxCountry), 1.5)
+  const s = 50 + t * 40
+  const l = 92 - t * 60
+  return `hsl(220, ${s}%, ${l}%)`
+}
+
+export default function Rankings() {
+  const [active, setActive] = createSignal<number | null>(null)
+  const [pos, setPos] = createSignal({ x: 0, y: 0 })
+  const [expanded, setExpanded] = createSignal(false)
+  const [shareActive, setShareActive] = createSignal<number | null>(null)
+  const [sharePos, setSharePos] = createSignal({ x: 0, y: 0 })
+  const [mapHover, setMapHover] = createSignal<string | null>(null)
+  const [mapPos, setMapPos] = createSignal({ x: 0, y: 0 })
+
+  return (
+    <main data-page="zen" data-route="rankings">
+      <Title>Model Rankings</Title>
+      <LocaleLinks path="/rankings" />
+
+      <div data-component="container">
+        <Header zen hideGetStarted />
+
+        <div data-component="content">
+          <section data-component="hero" data-variant="rankings">
+            <div data-slot="hero-copy">
+              <h1>Model Rankings</h1>
+              <p>
+                See which models are winning real usage, how the mix shifts over time, and where momentum is moving each
+                week.
+              </p>
+            </div>
+          </section>
+
+          <section data-component="rankings-section">
+            <h3>Usage</h3>
+            <div data-slot="chart">
+              <div
+                data-slot="bars"
+                onMouseLeave={() => setActive(null)}
+                onMouseMove={(e) => setPos({ x: e.clientX, y: e.clientY })}
+              >
+                <For each={usage}>
+                  {(week, i) => (
+                    <div
+                      data-slot="bar-group"
+                      data-active={active() === i() ? "" : undefined}
+                      data-dimmed={active() !== null && active() !== i() ? "" : undefined}
+                      onMouseEnter={() => setActive(i())}
+                    >
+                      <span data-slot="bar-label">{fmt(week.total)}</span>
+                      <div data-slot="bar-wrap">
+                        <div data-slot="bar" style={{ height: `${(week.total / max) * 100}%` }}>
+                          <For each={week.segments}>
+                            {(seg) => (
+                              <span
+                                style={{
+                                  flex: String(seg.tokens),
+                                  background: seg.color,
+                                }}
+                              />
+                            )}
+                          </For>
+                        </div>
+                      </div>
+                      <span data-slot="bar-week">{week.week}</span>
+                    </div>
+                  )}
+                </For>
+              </div>
+              <Show when={active() !== null}>
+                <div
+                  data-slot="tooltip"
+                  style={{
+                    left: `${pos().x + 16}px`,
+                    top: `${pos().y - 16}px`,
+                  }}
+                >
+                  <strong>{usage[active()!].week}</strong>
+                  <span data-slot="tooltip-total">{fmt(usage[active()!].total)} total</span>
+                  <For each={usage[active()!].segments.filter((s) => s.tokens > 0)}>
+                    {(seg) => (
+                      <span data-slot="tooltip-row">
+                        <i style={{ background: seg.color }} />
+                        <span>{seg.model}</span>
+                        <span>{fmt(seg.tokens)}</span>
+                      </span>
+                    )}
+                  </For>
+                </div>
+              </Show>
+              <div data-slot="legend">
+                <For each={models}>
+                  {(m) => (
+                    <span data-slot="legend-item">
+                      <i style={{ background: m.color }} />
+                      {m.name}
+                    </span>
+                  )}
+                </For>
+                <span data-slot="legend-item">
+                  <i style={{ background: "rgba(148, 163, 184, 0.35)" }} />
+                  Other
+                </span>
+              </div>
+            </div>
+          </section>
+
+          <section data-component="rankings-section">
+            <h3>Leaderboard</h3>
+            <p data-slot="subtitle">Week of Mar 24 — top models by token usage.</p>
+            <div data-slot="lb-podium">
+              <For each={leaderboard.slice(0, 3)}>
+                {(row) => (
+                  <div data-slot="lb-podium-item" data-rank={row.rank}>
+                    <span data-slot="lb-podium-rank">{row.rank}</span>
+                    <strong>{row.model}</strong>
+                    <span data-slot="lb-podium-tokens">{fmt(row.tokens)}</span>
+                  </div>
+                )}
+              </For>
+            </div>
+            <div data-slot="leaderboard">
+              <For
+                each={[
+                  leaderboard.slice(3, expanded() ? 13 : 8),
+                  leaderboard.slice(expanded() ? 13 : 8, expanded() ? leaderboard.length : 13),
+                ]}
+              >
+                {(col) => (
+                  <div data-slot="lb-col">
+                    <For each={col}>
+                      {(row) => (
+                        <article data-slot="lb-row">
+                          <span data-slot="lb-rank">{row.rank}.</span>
+                          <div data-slot="lb-info">
+                            <strong>{row.model}</strong>
+                          </div>
+                          <span data-slot="lb-tokens">{fmt(row.tokens)}</span>
+                        </article>
+                      )}
+                    </For>
+                  </div>
+                )}
+              </For>
+            </div>
+            <Show when={leaderboard.length > 13}>
+              <button data-slot="lb-toggle" onClick={() => setExpanded(!expanded())}>
+                {expanded() ? "Show less" : "Show all"}
+              </button>
+            </Show>
+          </section>
+
+          <section data-component="rankings-section">
+            <h3>Market Share</h3>
+            <div data-slot="chart">
+              <div
+                data-slot="share-bars"
+                onMouseLeave={() => setShareActive(null)}
+                onMouseMove={(e) => setSharePos({ x: e.clientX, y: e.clientY })}
+              >
+                <For each={share}>
+                  {(week, i) => (
+                    <div
+                      data-slot="share-col"
+                      data-dimmed={shareActive() !== null && shareActive() !== i() ? "" : undefined}
+                      onMouseEnter={() => setShareActive(i())}
+                    >
+                      <div data-slot="share-stack">
+                        <For each={week.segments}>
+                          {(seg) => <span style={{ flex: String(seg.pct), background: seg.color }} />}
+                        </For>
+                      </div>
+                      <span data-slot="share-week">{week.week}</span>
+                    </div>
+                  )}
+                </For>
+              </div>
+              <Show when={shareActive() !== null}>
+                <div
+                  data-slot="tooltip"
+                  style={{
+                    left: `${sharePos().x + 16}px`,
+                    top: `${sharePos().y - 16}px`,
+                  }}
+                >
+                  <strong>{share[shareActive()!].week}</strong>
+                  <span data-slot="tooltip-total">{fmt(share[shareActive()!].total)} total</span>
+                  <For each={share[shareActive()!].segments.filter((s) => s.tokens > 0)}>
+                    {(seg) => (
+                      <span data-slot="tooltip-row">
+                        <i style={{ background: seg.color }} />
+                        <span>{seg.provider}</span>
+                        <span>{seg.pct.toFixed(1)}%</span>
+                      </span>
+                    )}
+                  </For>
+                </div>
+              </Show>
+              <div data-slot="legend">
+                <For each={providers}>
+                  {(p) => (
+                    <span data-slot="legend-item">
+                      <i style={{ background: p.color }} />
+                      {p.name}
+                    </span>
+                  )}
+                </For>
+              </div>
+            </div>
+          </section>
+
+          <section data-component="rankings-section">
+            <h3>Token Cost</h3>
+            <p data-slot="subtitle">Price per 1M tokens on OpenCode Zen.</p>
+            <div data-slot="cost-list">
+              <For each={grouped}>
+                {(group) => (
+                  <div data-slot="cost-group">
+                    <For each={group.models}>
+                      {(row) => {
+                        const p = pricing[row.model]
+                        const eff = effective(p)
+                        return (
+                          <div data-slot="cost-row">
+                            <div data-slot="cost-main">
+                              <span data-slot="pricing-model">{row.model}</span>
+                              <span data-slot="pricing-effective">{price(eff)}</span>
+                              <span data-slot="cost-bar-wrap">
+                                <span data-slot="cost-bar" style={{ width: `${(eff / maxEffective) * 100}%` }} />
+                              </span>
+                            </div>
+                            <div data-slot="cost-detail">
+                              <span>Input {price(p.input)}</span>
+                              <span>Output {price(p.output)}</span>
+                              <span>Cached {price(p.cached)}</span>
+                            </div>
+                          </div>
+                        )
+                      }}
+                    </For>
+                  </div>
+                )}
+              </For>
+            </div>
+          </section>
+
+          <section data-component="rankings-section">
+            <h3>Session Cost</h3>
+            <p data-slot="subtitle">Average cost per session on OpenCode Zen.</p>
+            <div data-slot="pricing-table">
+              <div data-slot="pricing-header" data-cols="3">
+                <span>Model</span>
+                <span>Cost / Session</span>
+                <span>Tokens / Session</span>
+              </div>
+              <For each={sessions}>
+                {(row) => (
+                  <div data-slot="pricing-row" data-cols="3">
+                    <span data-slot="pricing-model">{row.model}</span>
+                    <span data-slot="pricing-effective">${avg(row).toFixed(4)}</span>
+                    <span data-slot="tps-cell" title={fmtTokens(avgTokens(row))}>
+                      <span data-slot="tps-bar" style={{ width: `${(avgTokens(row) / maxTps) * 100}%` }} />
+                    </span>
+                  </div>
+                )}
+              </For>
+            </div>
+          </section>
+
+          <section data-component="rankings-section">
+            <h3>Token by Country</h3>
+            <div data-slot="map-wrap" onMouseLeave={() => setMapHover(null)}>
+              <svg
+                data-slot="world-map"
+                viewBox="30.767 241.591 784.077 458.627"
+                onMouseMove={(e) => setMapPos({ x: e.clientX, y: e.clientY })}
+              >
+                <For each={Object.entries(worldPaths)}>
+                  {([code, d]) => (
+                    <path
+                      d={d}
+                      fill={fill(code)}
+                      stroke="var(--color-background)"
+                      stroke-width="0.5"
+                      onMouseEnter={() => setMapHover(code)}
+                      onMouseLeave={() => setMapHover(null)}
+                    />
+                  )}
+                </For>
+              </svg>
+              <Show when={mapHover() && countries[mapHover()!]}>
+                <div
+                  data-slot="tooltip"
+                  style={{
+                    left: `${mapPos().x + 16}px`,
+                    top: `${mapPos().y - 16}px`,
+                  }}
+                >
+                  <strong>
+                    {flag(mapHover()!)} {names[mapHover()!] || mapHover()}
+                  </strong>
+                  <span data-slot="tooltip-total">{fmt(countries[mapHover()!])}</span>
+                </div>
+              </Show>
+            </div>
+          </section>
+
+          <Footer />
+        </div>
+      </div>
+
+      <Legal />
+    </main>
+  )
+}

Dosya farkı çok büyük olduğundan ihmal edildi
+ 25 - 0
packages/console/app/src/routes/world-paths.ts


Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor