1const w=JSON.parse(document.getElementById("sb-data").textContent||"{}"),B=["Cloud","Local"],q={Cloud:"var(--teal)",Local:"var(--amber)"},Y={Cloud:"#42c6d4",Local:"#f2b263"},N=1,Q=25,R=40,l={cat:"overall",classes:new Set(B),split:!1,q:"",sort:"score",all:!1,open:new Set,axis:"cost"},f=s=>document.getElementById(s),u=s=>String(s??"").replace(/[&<>"]/g,t=>({"&":"&","<":"<",">":">",'"':"""})[t]),F=s=>s==="overall"?"Overall":w.categories.find(t=>t.key===s)?.label||s,p=(s,t=l.cat)=>t==="overall"?s.overall:s.categories[t]??null,D=s=>s==null?"":s===0?"free":s<.01?"$"+s.toFixed(4):"$"+s.toFixed(3),y=s=>!s.out_of_competition,G=s=>`<span class="sb-tag ${s.class.toLowerCase()}">${s.class}</span>${s.note?` <span class="sb-tag note">${u(s.note)}</span>`:""}`,U=()=>{const s=l.q.trim().toLowerCase();return w.models.filter(t=>l.classes.has(t.class)&&(!s||t.name.toLowerCase().includes(s)))},P=(s,t)=>s.filter(o=>p(o,t)!=null).sort((o,n)=>p(n,t)-p(o,t));function ct(){const s=P(w.models.filter(y),"overall");if(!s.length)return;const t=s[0].overall,o=s.filter(n=>t-n.overall<=N);f("sb-lead-note").textContent=o.length>3?`${o.length} within ${N} pt`:"",f("sb-leaders").innerHTML=s.slice(0,3).map((n,a)=>` 2 <li class="flex items-center gap-4"> 3 <span class="sb-rank ${a===0?"top":""}">${a+1}</span> 4 <div class="min-w-0 flex-1"> 5 <div class="flex items-center gap-2"><span class="truncate text-[17px] font-medium text-[var(--ink)]">${u(n.name)}</span>${G(n)}</div> 6 <div class="mt-2 h-1 rounded bg-white/5"><div class="sb-mini" style="width:${(n.overall-R)/(100-R)*100}%;background:${q[n.class]}"></div></div> 7 </div> 8 <span class="sb-num text-3xl text-[var(--ink)]">${n.overall.toFixed(1)}</span> 9 </li>`).join("")}function rt(){const s=["overall",...w.categories.map(t=>t.key)];f("sb-cats").innerHTML=s.map(t=>`<button class="sb-segbtn" role="tab" aria-selected="${l.cat===t}" data-cat="${t}">${u(F(t))}</button>`).join(""),f("sb-classes").innerHTML=B.map(t=>`<button class="sb-cls" aria-pressed="${l.classes.has(t)}" data-cls="${t}"><i class="sb-swatch" style="background:${q[t]}"></i>${t}</button>`).join("")}function Z(){const s=U().filter(y),t=["md:col-span-3","md:col-span-3","md:col-span-2","md:col-span-2","md:col-span-2"];f("sb-best").innerHTML=w.categories.map((o,n)=>{const a=P(s,o.key),b=`<p class="font-mono text-[12px] uppercase tracking-[0.16em] text-[var(--dim)]">${u(o.label)}</p>`;if(!a.length)return`<div class="sb-card p-6 ${t[n]}">${b}<p class="mt-4 text-[var(--faint)]">No model in this selection.</p></div>`;const h=p(a[0],o.key),i=a.filter(d=>h-p(d,o.key)<=N),g=a.slice(0,5),c=Math.min(...g.map(d=>p(d,o.key)))-2;return`<button class="sb-card sb-best p-6 ${t[n]}" data-cat="${o.key}" aria-label="Show the ${u(o.label)} ranking"> 10 <div class="flex items-start justify-between gap-4"> 11 <div class="min-w-0">${b} 12 <p class="mt-3 text-[19px] font-medium leading-snug text-[var(--ink)]">${i.slice(0,3).map(d=>u(d.name)).join(", ")}${i.length>3?` <span class="text-[var(--faint)]">+${i.length-3}</span>`:""}</p> 13 <p class="mt-1 font-mono text-[12px] text-[var(--faint)]">${i.length>1?`${i.length} models within ${N} pt`:"clear leader"}</p> 14 </div> 15 <span class="sb-num text-[40px] leading-none text-[var(--teal)]">${h.toFixed(1)}</span> 16 </div> 17 <ol class="mt-5 space-y-2">${g.map(d=>{const k=p(d,o.key);return`<li class="grid grid-cols-[minmax(0,1fr)_3rem] items-center gap-3"> 18 <div class="min-w-0"><div class="truncate text-[13px] text-[var(--dim)]">${u(d.name)}</div> 19 <div class="mt-1 h-1 rounded bg-white/5"><div class="sb-mini" style="width:${Math.max(3,(k-c)/(100-c)*100)}%;background:${q[d.class]}"></div></div></div> 20 <span class="sb-num text-right text-[13px] text-[var(--ink)]">${k.toFixed(1)}</span></li>`}).join("")}</ol> 21 </button>`}).join("")}const O=1e3,E=520,$={l:70,r:28,t:24,b:64};function J(){const s=f("sb-scatter"),t=l.cat,o=l.q.trim().toLowerCase(),n=l.axis==="cost",a=w.models.filter(e=>l.classes.has(e.class)&&p(e,t)!=null&&(n?e.cost_per_test!=null:e.tok_s!=null&&e.tok_s>0));f("sb-axis-word").textContent=n?"cost":"speed";const b=e=>{f("sb-chart-sub").textContent=n?`${F(t)} score against measured cost per task, cloud models.${e?" The dashed line joins the models nobody beats on both price and quality.":" Top left is cheap and good."}`:`${F(t)} score against median decode speed, in tokens per second. Top right is fast and good.`};if(b(!1),f("sb-legend-front").style.display="none",!a.length){s.innerHTML=`<text x="${O/2}" y="${E/2}" text-anchor="middle" fill="#9bb4bf" font-size="16">No model with this data in the selection.</text>`;return}const h=a.map(e=>p(e,t)),i=Math.max(0,Math.floor((Math.min(...h)-3)/5)*5),g=100,c=e=>n?Math.max(e.cost_per_test,5e-4):e.tok_s,d=e=>Math.log10(e),k=a.map(c);let _=d(Math.min(...k)),L=d(Math.max(...k));_=Math.floor(_),L=Math.ceil(L),L===_&&(L=_+1);const S=e=>$.l+(d(e)-_)/(L-_)*(O-$.l-$.r),T=e=>E-$.b-(e-i)/(g-i)*(E-$.t-$.b),X='font-family="JetBrains Mono, monospace"';let M="";for(let e=i;e<=g;e+=5)M+=`<line x1="${$.l}" x2="${O-$.r}" y1="${T(e)}" y2="${T(e)}" stroke="rgba(255,255,255,.06)"/>`,M+=`<text x="${$.l-12}" y="${T(e)+4}" text-anchor="end" fill="#7f9aa6" font-size="16" ${X}>${e}</text>`;const I=[];if(n)for(let e=_;e<=L;e++)I.push(Math.pow(10,e));else for(let e=_;e<=L;
21e++)[1,2,5].forEach(r=>{const x=r*Math.pow(10,e);d(x)>=_&&d(x)<=L&&I.push(x)});if(I.forEach(e=>{M+=`<line x1="${S(e)}" x2="${S(e)}" y1="${$.t}" y2="${E-$.b}" stroke="rgba(255,255,255,.04)"/>`,M+=`<text x="${S(e)}" y="${E-$.b+26}" text-anchor="middle" fill="#7f9aa6" font-size="16" ${X}>${n?"$"+e:e}</text>`}),M+=`<text x="${($.l+O-$.r)/2}" y="${E-10}" text-anchor="middle" fill="#9bb4bf" font-size="17">${n?"Cost per task, log scale (free models at the left edge)":"Median decode speed, tokens per second, log scale"}</text>`,n){const e=a.filter(y).sort((v,m)=>c(v)-c(m)||p(m,t)-p(v,t)),r=[];let x=-1;e.forEach(v=>{p(v,t)>x&&(r.push(v),x=p(v,t))}),r.length>1&&(f("sb-legend-front").style.display="",b(!0)),r.length>1&&(M+=`<polyline fill="none" stroke="#42c6d4" stroke-width="2" stroke-dasharray="6 6" opacity=".7" points="${r.map(v=>`${S(c(v))},${T(p(v,t))}`).join(" ")}"/>`)}const V=new Set(a.filter(y).sort((e,r)=>p(r,t)-p(e,t)).slice(0,6).map(e=>e.id)),W=[],nt=a.map(e=>({id:e.id,x:S(c(e)),y:T(p(e,t))})),at=(e,r,x,v)=>e>$.l&&e+x<O-4&&r-16>$.t&&r<E-$.b&&!W.some(m=>Math.abs(m.y-r)<22&&e<m.x+m.w+8&&m.x<e+x+8)&&!nt.some(m=>m.id!==v&&m.x>e-8&&m.x<e+x+8&&m.y>r-22&&m.y<r+8);[...a].sort((e,r)=>Number(y(e))-Number(y(r))).forEach(e=>{const r=S(c(e)),x=T(p(e,t)),v=o&&!e.name.toLowerCase().includes(o),m=!y(e),ot=n?`, ${D(e.cost_per_test)}`:`, ${Math.round(e.tok_s)} tokens per second`;if(M+=`<circle class="sb-pt" data-id="${u(e.id)}" tabindex="0" role="img" aria-label="${u(e.name)}, ${e.class}${m?", out of competition":""}, ${p(e,t).toFixed(1)}${ot}" 22 cx="${r}" cy="${x}" r="${V.has(e.id)?7:5.5}" fill="${m?"transparent":Y[e.class]}" stroke="${m?Y[e.class]:"#0c2535"}" stroke-width="${m?2:1.5}" opacity="${v?.18:.92}"/>`,V.has(e.id)&&!v){const C=e.name.length*9.4,H=[[r+12,x+6],[r-12-C,x+6],[r-C/2,x-14],[r-C/2,x+28],[r+12,x-16],[r-12-C,x-16],[r+12,x+26],[r-12-C,x+26]].find(([lt,it])=>at(lt,it,C,e.id));H&&(W.push({x:H[0],y:H[1],w:C}),M+=`<text x="${H[0]}" y="${H[1]}" fill="#e8f1f4" font-size="17">${u(e.name)}</text>`)}}),s.innerHTML=M}function tt(s){const t=w.models.find(b=>b.id===s.dataset.id);if(!t)return;const o=f("sb-tip"),n=s.closest(".sb-card").getBoundingClientRect(),a=s.getBoundingClientRect();o.innerHTML=`<div class="flex flex-wrap items-center gap-2"><strong class="font-medium">${u(t.name)}</strong>${G(t)}</div> 23 <div class="sb-num mt-2 text-[12px] text-[var(--dim)]">${u(F(l.cat))} <span class="text-[var(--ink)]">${p(t)?.toFixed(1)??"n/a"}</span> 24 ${t.cost_per_test!=null?`<br>Cost <span class="text-[var(--ink)]">${D(t.cost_per_test)}</span>`:""} 25 ${t.tok_s!=null?`<br>Speed <span class="text-[var(--ink)]">${Math.round(t.tok_s)} tok/s</span>`:""} 26 ${t.out_of_competition?'<br><span class="text-[var(--faint)]">Out of competition</span>':""}</div>`,o.style.left=`${Math.max(8,Math.min(a.left-n.left+14,n.width-210))}px`,o.style.top=`${Math.max(8,a.top-n.top-80)}px`,o.classList.add("on")}const st=()=>f("sb-tip").classList.remove("on");function dt(s){const t=[...s],o=(n,a)=>(p(a)??-1)-(p(n)??-1);return l.sort==="score"&&t.sort(o),l.sort==="cost"&&t.sort((n,a)=>(n.cost_per_test??1e9)-(a.cost_per_test??1e9)||o(n,a)),l.sort==="speed"&&t.sort((n,a)=>(a.tok_s??-1)-(n.tok_s??-1)||o(n,a)),l.sort==="name"&&t.sort((n,a)=>n.name.localeCompare(a.name)),t}function pt(s,t,o){const n=p(s),a=n==null?0:Math.max(2,(n-R)/(100-R)*100),b=n!=null&&o!=null&&t!=null?n-o:null,h=l.open.has(s.id),i=h?`<div class="sb-detail grid gap-5 md:grid-cols-5">${w.categories.map(c=>{const d=s.categories[c.key];return`<div><p class="font-mono text-[11px] uppercase tracking-[0.14em] text-[var(--faint)]">${u(c.label)}</p> 27 <p class="sb-num mt-1 text-xl text-[var(--ink)]">${d==null?"n/a":d.toFixed(1)}</p> 28 <ul class="mt-2 space-y-1">${c.axes.filter(k=>s.axes[k.key]!=null).map(k=>`<li class="flex justify-between gap-3 text-[13px] text-[var(--dim)]"><span>${u(k.label)}</span><span class="sb-num text-[var(--ink)]">${s.axes[k.key].toFixed(0)}</span></li>`).join("")||'<li class="text-[13px] text-[var(--faint)]">not tested</li>'}</ul></div>`}).join("")}
28<p class="font-mono text-[11px] text-[var(--faint)] md:col-span-5">${s.n_tests} graded tasks${s.cost_estimated?", cost estimated from token usage":""}${s.out_of_competition?", shown for context, out of competition":""}</p></div>`:"",g=t==null?'<span class="sb-rank none" title="Out of competition" aria-label="Out of competition">-</span>':`<span class="sb-rank ${t<=3&&l.sort==="score"?"top":""}">${t}</span>`;return`<div class="sb-row ${t==null?"out":""}" data-id="${u(s.id)}" role="button" tabindex="0" aria-expanded="${h}"> 29 ${g} 30 <span class="min-w-0"><span class="block truncate font-medium text-[var(--ink)]">${u(s.name)}</span><span class="mt-1 inline-flex flex-wrap gap-1">${G(s)}</span></span> 31 <span class="hidden md:block"><span class="block h-2 rounded bg-white/5"><span class="sb-bar block" style="width:${a}%;background:${q[s.class]};${t==null?"opacity:.55":""}"></span></span></span> 32 <span class="sb-num text-right text-lg text-[var(--ink)]">${n==null?'<span class="text-sm text-[var(--faint)]">n/a</span>':n.toFixed(1)}</span> 33 <span class="sb-num hidden text-right text-[13px] text-[var(--faint)] md:block">${b==null?"":b===0?"lead":b.toFixed(1)}</span> 34 <span class="sb-num hidden text-right text-[13px] text-[var(--dim)] md:block">${u(D(s.cost_per_test))}</span> 35 <span class="sb-num hidden text-right text-[13px] text-[var(--dim)] md:block">${s.tok_s==null?"":Math.round(s.tok_s)}</span> 36 ${i}</div>`}function K(s,t){const o=dt(s),n=P(s.filter(y),l.cat)[0],a=n?p(n):null,b=l.all?o:o.slice(0,Q);let h=0;const i=c=>l.sort===c?c==="cost"||c==="name"?"ascending":"descending":"none",g=(c,d,k="")=>`<button class="sb-sort ${k}" data-sort="${c}" aria-sort="${i(c)}">${d}</button>`;return`${t?`<h3 class="mb-2 mt-10 flex items-center gap-3 font-mono text-[12px] uppercase tracking-[0.16em] text-[var(--dim)]"><i class="sb-swatch" style="background:${q[t]}"></i>${u(t)} <span class="text-[var(--ink)]">${o.length}</span></h3>`:""} 37 <div class="sb-row sb-head" role="presentation"><span>#</span>${g("name","Model","text-left")}<span class="hidden md:block"></span>${g("score",u(F(l.cat)),"text-right")}<span class="hidden text-right md:block">Gap</span>${g("cost","Cost / task","hidden md:block text-right")}${g("speed","Tok/s","hidden md:block text-right")}</div> 38 ${b.map(c=>pt(c,y(c)?++h:null,a)).join("")||'<p class="px-3 py-10 text-[var(--faint)]">No model matches this selection.</p>'}`}function j(){const s=U();f("sb-rank-title").textContent=`Ranking: ${F(l.cat)}`,f("sb-count").textContent=`${s.filter(y).length} ranked, ${s.filter(n=>!y(n)).length} out of competition`,f("sb-tables").innerHTML=l.split?B.filter(n=>s.some(a=>a.class===n)).map(n=>K(s.filter(a=>a.class===n),n)).join(""):K(s);const t=l.split?Math.max(0,...B.map(n=>s.filter(a=>a.class===n).length)):s.length,o=f("sb-more");o.style.display=t>Q?"":"none",o.textContent=l.all?"Show top 25":`Show all ${s.length} models`}function A(){rt(),Z(),J(),j()}document.addEventListener("click",s=>{const t=s.target,o=t.closest("[data-cat]");if(o){l.cat=o.dataset.cat,l.sort="score",A(),o.classList.contains("sb-best")&&f("sb-rank-title").scrollIntoView({behavior:matchMedia("(prefers-reduced-motion: reduce)").matches?"auto":"smooth",block:"start"});return}const n=t.closest("[data-cls]");if(n){const i=n.dataset.cls;l.classes.has(i)&&l.classes.size>1?l.classes.delete(i):l.classes.add(i),A();return}const a=t.closest("[data-axis]");if(a){l.axis=a.dataset.axis,document.querySelectorAll("#sb-axis [data-axis]").forEach(i=>i.setAttribute("aria-selected",String(i===a))),J();return}const b=t.closest("[data-sort]");if(b){l.sort=b.dataset.sort,j();return}if(t.closest("#sb-more")){l.all=!l.all,j();return}const h=t.closest(".sb-row[data-id]");if(h&&!t.closest(".sb-detail")){const i=h.dataset.id;l.open.has(i)?l.open.delete(i):l.open.add(i),j()}});document.addEventListener("keydown",s=>{const t=s.target.closest?.(".sb-row[data-id]");t&&(s.key==="Enter"||s.key===" ")&&(s.preventDefault(),t.click())});const z=f("sb-scatter");z.addEventListener("pointerover",s=>{const t=s.target.closest(".sb-pt");t&&tt(t)});z.addEventListener("pointerout",s=>{s.target.closest(".sb-pt")&&st()});z.addEventListener("focusin",s=>{const t=s.target.closest(".sb-pt");t&&tt(t)});z.addEventListener("focusout",st);f("sb-split").addEventListener("change",s=>{l.split=s.target.checked,j()});f("sb-search").addEventListener("input",s=>{l.q=s.target.value,Z(),J(),j()});const et=s=>document.querySelectorAll(".sb-price-note").forEach(t=>t.textContent=s);et(w.prices_updated?`Cost at OpenRouter prices of ${w.prices_updated.slice(0,10)}`:"");
38async function xt(){const s=w.models.filter(t=>t.or_id&&t.tokens_per_task);if(s.length)try{const t=new AbortController,o=setTimeout(()=>t.abort(),6e3),n=await fetch("https://openrouter.ai/api/v1/models",{signal:t.signal});if(clearTimeout(o),!n.ok)return;const a=await n.json(),b=new Map((a.data||[]).map(i=>[i.id,i.pricing||{}]));let h=0;s.forEach(i=>{const g=b.get(i.or_id),c=parseFloat(g?.prompt??""),d=parseFloat(g?.completion??"");Number.isFinite(c)&&Number.isFinite(d)&&c>=0&&d>=0&&(i.cost_per_test=i.tokens_per_task.prompt*c+i.tokens_per_task.completion*d,i.cost_source="live",h++)}),h&&(et(`Cost at live OpenRouter prices, ${new Date().toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"})}`),A())}catch{}}ct();A();xt();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.