KoeYe commited on
Commit
7d419bd
·
1 Parent(s): 5c0856a

Unify task examples, add chart tooltips and bound scene loading

Browse files
README.md CHANGED
@@ -29,3 +29,11 @@ Deployment remains this Hugging Face static Space: `index.html` and `cases.html`
29
  The Pareto renderer (`assets/pareto.js`) ports the reference toolkit's reversed logarithmic cost axis, connected frontier, provider palette and greedy collision-aware label placement. `data/pareto.json` combines unrounded scores from the existing `data/site.js` with exact mean costs from the original published tables; all three task views recompute non-dominance from those values. The table displays three decimals but sorts at source precision.
30
 
31
  Homepage scenes (`assets/scene-cards.js`) adapt BuildingBench's shared WebGL renderer and per-view canvas engine. Existing public packed models are decoded with the same adapter as `cases.html`; geometry and the full case explorer remain unchanged. Visible scenes load automatically; repeated scenes share decoded assets. Drag or arrow keys orbit, wheel or +/- zoom, and the pause control stops rotation. Both Image-to-Scene cards switch between the saved repair, corrupted input and ground truth using the reference camera.
 
 
 
 
 
 
 
 
 
29
  The Pareto renderer (`assets/pareto.js`) ports the reference toolkit's reversed logarithmic cost axis, connected frontier, provider palette and greedy collision-aware label placement. `data/pareto.json` combines unrounded scores from the existing `data/site.js` with exact mean costs from the original published tables; all three task views recompute non-dominance from those values. The table displays three decimals but sorts at source precision.
30
 
31
  Homepage scenes (`assets/scene-cards.js`) adapt BuildingBench's shared WebGL renderer and per-view canvas engine. Existing public packed models are decoded with the same adapter as `cases.html`; geometry and the full case explorer remain unchanged. Visible scenes load automatically; repeated scenes share decoded assets. Drag or arrow keys orbit, wheel or +/- zoom, and the pause control stops rotation. Both Image-to-Scene cards switch between the saved repair, corrupted input and ground truth using the reference camera.
32
+
33
+ ## Interaction and loading reliability
34
+
35
+ Task Format switches the entire construction/editing example, including instructions, inputs, saved output and evaluator. Bar marks, labels and Pareto points share pointer, keyboard and tap tooltips with source-precision scores and costs in `data/leaderboard-details.json`. The ranking supports filtering and source-precision sorting.
36
+
37
+ Homepage model work uses a shared two-job download/decode queue. Hidden/offscreen views release their request; stale results cannot replace the selected state. Card textures are limited to 512px and render resolution is bounded, while original model files and the full case explorer stay intact. Idle decoded assets are evicted; the 128 MiB cache target is not a hard limit on currently visible geometry. Downloads show progress, abort after 20 seconds without data or 90 seconds total, retry once, then expose an explicit Retry button. Context loss pauses drawing and restoration rebuilds the environment; failures expose recovery instead of an indefinite loading overlay.
38
+
39
+ Queue tests: `node --test tests/scene-assets.test.mjs`. Browser QA includes public-model cold loads, quick scrolling, task/repair switching, desktop/mobile resize, forced HTTP failures, stalled downloads, retry and WebGL context loss.
assets/buildingbench.css CHANGED
@@ -31,3 +31,8 @@ section,section.alt,section.dark{padding:34px 0;background:transparent;color:var
31
  @media(max-width:650px){.case-grid{grid-template-columns:1fr}.tk figure>.live-scene{height:260px}}
32
  .pareto-card .figure-title{color:#1a1a1a!important}.pareto-card .figure-title span{color:#8d8d8d}
33
  .pareto-swipe{display:none}@media(max-width:650px){.pareto-swipe{display:block;font:10px Inter,sans-serif;color:#7d857f;margin:6px 0}}
 
 
 
 
 
 
31
  @media(max-width:650px){.case-grid{grid-template-columns:1fr}.tk figure>.live-scene{height:260px}}
32
  .pareto-card .figure-title{color:#1a1a1a!important}.pareto-card .figure-title span{color:#8d8d8d}
33
  .pareto-swipe{display:none}@media(max-width:650px){.pareto-swipe{display:block;font:10px Inter,sans-serif;color:#7d857f;margin:6px 0}}
34
+ /* Unified task format and reference-style chart interaction. */
35
+ [hidden]{display:none!important}.task-tabs{display:flex;gap:4px;padding:4px;background:#f0f3ef;border:1px solid #d7dbd5;border-radius:9px;width:max-content;max-width:100%;margin:0 0 22px}.task-tabs button{border:0;background:none;border-radius:6px;padding:10px 18px;font:600 12px Inter,sans-serif;color:#778178;cursor:pointer}.task-tabs [aria-selected=true]{background:white;color:#17201d;box-shadow:0 1px 4px #17201d15}.task-content>h3{font-size:22px;letter-spacing:-.6px;line-height:1.35;margin:0 0 5px}.task-content>h3 span{font-weight:500}.task-content .task-columns{align-items:stretch}.task-formula{font:11px/1.7 'IBM Plex Mono',monospace;color:#58665c;margin:12px 0 0}.input-panel .live-scene{height:255px;border-radius:12px}.task-reference{display:flex;align-items:center;gap:10px;margin-top:12px;font:11px/1.5 Inter,sans-serif;color:#35687e}.task-reference img{width:70px;height:48px;border-radius:5px;object-fit:cover}.task-content .scene-versions{padding:8px 3px;border:0;background:transparent}.scene-loading{display:flex;flex-direction:column;justify-content:center;align-items:center;gap:10px;font-size:12px;text-align:center;padding:16px;z-index:3;background:#e6edf0e8}.scene-retry{pointer-events:auto;cursor:pointer;border:1px solid #81998e;background:#fffefb;border-radius:7px;color:#294c41;padding:8px 14px;font:600 12px Inter,sans-serif}.live-scene[data-state-phase=error] .scene-loading{color:#684839}.chart-tooltip{position:fixed;z-index:1100;max-width:calc(100vw - 16px);padding:14px 17px;background:#fffefb;border:1px solid #d7dbd5;border-radius:11px;color:#4a544f;box-shadow:0 5px 24px #17201d24;opacity:0;pointer-events:none;font:12px/1.65 Inter,sans-serif}.chart-tooltip.on{opacity:1}.chart-tooltip strong{display:block;color:#17201d;font-size:13px}.tooltip-provider{display:block;font-size:10px;color:#7d857f;margin:1px 0 8px}.chart-tooltip dl{display:grid;grid-template-columns:auto auto;gap:4px 16px;margin:0}.chart-tooltip dd{font:11px/1.8 'IBM Plex Mono',monospace;text-align:right;margin:0;color:#17201d}.chart-node{cursor:pointer;transition:opacity .12s}.chart-node.dim{opacity:.23}.chart-node.hot .bar{filter:brightness(1.08)}.chart-node:focus{outline:none}.chart-node:focus .bar{stroke:#17201d;stroke-width:2}.bar-card,.pareto-card,.ranking-card{padding:24px!important;border-radius:20px}.bar-heading{padding:0!important}.bar-scroll{margin-top:14px}.bar-card .note{margin:0!important}.kit-bars{min-width:1000px}.pareto-svg{min-width:1100px}.figure-caption{margin-left:0!important;margin-right:0!important}.lb-tabs{position:static!important}.ranking-toolbar{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;margin:0 0 20px}.ranking-toolbar label{display:grid;gap:7px;font:500 11px Inter,sans-serif;color:#65756c}.ranking-toolbar input{width:260px;max-width:100%;border:1px solid #d7dbd5;border-radius:7px;padding:9px 11px;font:12px Inter,sans-serif;background:#fffefb;color:#17201d}.ranking-toolbar>span{font-size:11px;color:#7d857f;padding-bottom:9px}.ranking-card .board-wrap{margin-top:16px;border:1px solid #d7dbd5;border-radius:12px}.ranking-card .board{margin:0}.ranking-card .board tbody tr:last-child td{border-bottom:0}.ranking-card .board-note{margin:12px 0 0}.bar-card .note,.figure-caption{font-size:11px;line-height:1.7}
36
+ @media(max-width:650px){.task-tabs{width:100%;margin-bottom:18px}.task-tabs button{padding:9px 8px;flex:1;font-size:11px}.task-content>h3{font-size:19px}.task-content>h3 span{font-size:14px}.bar-card,.pareto-card,.ranking-card{padding:18px 14px!important;border-radius:18px}.bar-scroll,.pareto-scroll{margin-left:-14px;margin-right:-14px;padding:0 14px}.ranking-toolbar{gap:12px;align-items:flex-start}.ranking-toolbar label{flex:1;min-width:0}.ranking-toolbar input{width:100%;box-sizing:border-box}.ranking-toolbar>span{font-size:10px;max-width:90px;padding-top:24px}.chart-tooltip{padding:12px;font-size:11px}.chart-tooltip dl{gap:4px 10px}.chart-tooltip dd{font-size:10px}.chart-tooltip strong{font-size:12px}}
37
+
38
+ .chart-node{user-select:none;-webkit-user-select:none}.chart-tooltip dt{margin:0}
assets/chart-interactions.js ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // BuildingBench interaction: full model hit targets, a viewport tooltip, and quieting the other marks.
2
+ const detailPromise=fetch(new URL('../data/leaderboard-details.json?v=20261001c',import.meta.url)).then(r=>{if(!r.ok)throw new Error('Leaderboard details unavailable');return r.json();});
3
+ const tip=Object.assign(document.createElement('div'),{className:'chart-tooltip',id:'chart-tooltip'});tip.setAttribute('role','tooltip');document.body.append(tip);
4
+ let active=null,pinned=false;
5
+ function hide(){tip.classList.remove('on');active?.plot.querySelectorAll('.chart-node').forEach(n=>n.classList.remove('dim','hot'));active?.node.removeAttribute('aria-describedby');active=null;pinned=false;}
6
+ function show(node,plot,record,anchorSelector){
7
+ if(active?.node!==node)hide();active={node,plot,record,anchorSelector};tip.replaceChildren();
8
+ const title=document.createElement('strong');title.textContent=record.name;tip.append(title);
9
+ const provider=document.createElement('span');provider.className='tooltip-provider';provider.textContent=record.provider;tip.append(provider);
10
+ const dl=document.createElement('dl');for(const m of record.metrics){const dt=document.createElement('dt'),dd=document.createElement('dd');dt.textContent=m.label;dd.textContent=(m.currency?'$':'')+String(m.value);dl.append(dt,dd);}tip.append(dl);
11
+ tip.classList.add('on');node.setAttribute('aria-describedby','chart-tooltip');plot.querySelectorAll('.chart-node').forEach(n=>{n.classList.toggle('dim',n!==node);n.classList.toggle('hot',n===node);});
12
+ const r=(node.querySelector(anchorSelector)||node).getBoundingClientRect(),w=tip.offsetWidth,h=tip.offsetHeight;
13
+ tip.style.left=Math.max(8,Math.min(innerWidth-w-8,r.left+r.width/2-w/2))+'px';
14
+ tip.style.top=Math.max(8,Math.min(innerHeight-h-8,r.top>h+14?r.top-h-12:r.bottom+12))+'px';
15
+ }
16
+ export async function bindChartTooltip(node,plot,key,mode,anchorSelector='.bar,.chip'){
17
+ const data=await detailPromise,record=data[mode].find(d=>d.key===key||d.name===key);if(!record)return;
18
+ node.classList.add('chart-node');node.setAttribute('tabindex','0');node.setAttribute('role','button');node.setAttribute('aria-label',record.name+'; '+record.metrics.map(m=>m.label+' '+(m.currency?'$':'')+m.value).join('; '));
19
+ node.addEventListener('pointerenter',()=>{pinned=false;show(node,plot,record,anchorSelector);});
20
+ node.addEventListener('pointerleave',()=>{if(!pinned&&active?.node===node)hide();});
21
+ node.addEventListener('focus',()=>show(node,plot,record,anchorSelector));node.addEventListener('blur',()=>{if(active?.node===node)hide();});
22
+ node.addEventListener('click',event=>{event.stopPropagation();show(node,plot,record,anchorSelector);pinned=true;});
23
+ node.addEventListener('keydown',event=>{if(event.key==='Escape')hide();if(event.key==='Enter'||event.key===' '){event.preventDefault();show(node,plot,record,anchorSelector);pinned=true;}});
24
+ node.dataset.interactive='true';
25
+ }
26
+ window.addEventListener('scroll',()=>{if(active&&document.activeElement===active.node){const a=active;requestAnimationFrame(()=>{if(active===a)show(a.node,a.plot,a.record,a.anchorSelector);});}else hide();},{passive:true,capture:true});window.addEventListener('resize',hide);document.addEventListener('click',event=>{if(!event.target.closest('.chart-node'))hide();});document.addEventListener('keydown',event=>{if(event.key==='Escape')hide();});
assets/leaderboard-bars.js CHANGED
@@ -1,6 +1,7 @@
1
  // Bar layout and name wrapping adapted from BuildingBench figure-kit/bar-static/build.py.
2
  // Data is exclusively the existing Code4Scene data/site.js paper board; no reference benchmark scores.
3
  (async function(){
 
4
  await Promise.all([document.fonts.load('400 13px Inter'),document.fonts.load('700 13px Inter'),document.fonts.load('500 15.5px "IBM Plex Mono"')]);
5
  const ALL = {"overall": [{"name": "GPT-6 Astra (max)", "org": "OpenAI", "score": 0.6193352866666667, "colour": "#10A37F", "ink": "#ffffff", "label": "62", "new": false}, {"name": "Gemini 3.8 Flash (high)", "org": "Google", "score": 0.6189750266666667, "colour": "#7b1fa2", "ink": "#ffffff", "label": "62", "new": false}, {"name": "Claude Fable 5.1 (max)", "org": "Anthropic", "score": 0.60604898, "colour": "#D97757", "ink": "#ffffff", "label": "61", "new": false}, {"name": "Claude Opus 5 (max)", "org": "Anthropic", "score": 0.5931299933333334, "colour": "#D97757", "ink": "#ffffff", "label": "59", "new": false}, {"name": "GPT-5.6 Sol (high)", "org": "OpenAI", "score": 0.5499994666666667, "colour": "#10A37F", "ink": "#ffffff", "label": "55", "new": false}, {"name": "Muse Spark 1.3 (medium)", "org": "Meta", "score": 0.5022053666666666, "colour": "#42a5f5", "ink": "#111111", "label": "50", "new": false}, {"name": "GLM-5.3 Flash (max)", "org": "Z.ai", "score": 0.4147088666666666, "colour": "#96650b", "ink": "#ffffff", "label": "41", "new": false}, {"name": "Qwen 3.8 27B (thinking off)", "org": "Alibaba", "score": 0.37818169333333335, "colour": "#fe7016", "ink": "#111111", "label": "38", "new": false}, {"name": "Grok 4.6 (high)", "org": "xAI", "score": 0.37567506, "colour": "#111111", "ink": "#ffffff", "label": "38", "new": false}, {"name": "Qwen 3.8 27B (thinking on)", "org": "Alibaba", "score": 0.37094399333333333, "colour": "#fe7016", "ink": "#111111", "label": "37", "new": false}, {"name": "Inkling (high)", "org": "Thinking Machines", "score": 0.31150237333333336, "colour": "#686868", "ink": "#ffffff", "label": "31", "new": false}, {"name": "Gemma 4 31B (thinking on)", "org": "Google", "score": 0.29812257999999997, "colour": "#7b1fa2", "ink": "#ffffff", "label": "30", "new": false}, {"name": "Gemma 4 31B (thinking off)", "org": "Google", "score": 0.28498897333333334, "colour": "#7b1fa2", "ink": "#ffffff", "label": "28", "new": false}, {"name": "DeepSeek V4.1 Flash (high)", "org": "DeepSeek", "score": 0.22658958, "colour": "#3f51e0", "ink": "#ffffff", "label": "23", "new": false}], "t2s": [{"name": "Claude Fable 5.1 (max)", "org": "Anthropic", "score": 0.78775, "colour": "#D97757", "ink": "#ffffff", "label": "79", "new": false}, {"name": "GPT-6 Astra (max)", "org": "OpenAI", "score": 0.72382, "colour": "#10A37F", "ink": "#ffffff", "label": "72", "new": false}, {"name": "Claude Opus 5 (max)", "org": "Anthropic", "score": 0.7181599999999999, "colour": "#D97757", "ink": "#ffffff", "label": "72", "new": false}, {"name": "GPT-5.6 Sol (high)", "org": "OpenAI", "score": 0.70704, "colour": "#10A37F", "ink": "#ffffff", "label": "71", "new": false}, {"name": "Gemini 3.8 Flash (high)", "org": "Google", "score": 0.65689, "colour": "#7b1fa2", "ink": "#ffffff", "label": "66", "new": false}, {"name": "Muse Spark 1.3 (medium)", "org": "Meta", "score": 0.646195, "colour": "#42a5f5", "ink": "#111111", "label": "65", "new": false}, {"name": "Grok 4.6 (high)", "org": "xAI", "score": 0.56721, "colour": "#111111", "ink": "#ffffff", "label": "57", "new": false}, {"name": "Qwen 3.8 27B (thinking off)", "org": "Alibaba", "score": 0.55666, "colour": "#fe7016", "ink": "#111111", "label": "56", "new": false}, {"name": "Qwen 3.8 27B (thinking on)", "org": "Alibaba", "score": 0.51571, "colour": "#fe7016", "ink": "#111111", "label": "52", "new": false}, {"name": "GLM-5.3 Flash (max)", "org": "Z.ai", "score": 0.5094299999999999, "colour": "#96650b", "ink": "#ffffff", "label": "51", "new": false}, {"name": "Gemma 4 31B (thinking on)", "org": "Google", "score": 0.470705, "colour": "#7b1fa2", "ink": "#ffffff", "label": "47", "new": false}, {"name": "Gemma 4 31B (thinking off)", "org": "Google", "score": 0.45494, "colour": "#7b1fa2", "ink": "#ffffff", "label": "45", "new": false}, {"name": "Inkling (high)", "org": "Thinking Machines", "score": 0.42498500000000006, "colour": "#686868", "ink": "#ffffff", "label": "42", "new": false}, {"name": "DeepSeek V4.1 Flash (high)", "org": "DeepSeek", "score": 0.24269, "colour": "#3f51e0", "ink": "#ffffff", "label": "24", "new": false}], "i2s": [{"name": "Gemini 3.8 Flash (high)", "org": "Google", "score": 0.5810600533333334, "colour": "#7b1fa2", "ink": "#ffffff", "label": "58", "new": false}, {"name": "GPT-6 Astra (max)", "org": "OpenAI", "score": 0.5148505733333334, "colour": "#10A37F", "ink": "#ffffff", "label": "51", "new": false}, {"name": "Claude Opus 5 (max)", "org": "Anthropic", "score": 0.46809998666666675, "colour": "#D97757", "ink": "#ffffff", "label": "47", "new": false}, {"name": "Claude Fable 5.1 (max)", "org": "Anthropic", "score": 0.4243479600000001, "colour": "#D97757", "ink": "#ffffff", "label": "42", "new": false}, {"name": "GPT-5.6 Sol (high)", "org": "OpenAI", "score": 0.3929589333333333, "colour": "#10A37F", "ink": "#ffffff", "label": "39", "new": false}, {"name": "Muse Spark 1.3 (medium)", "org": "Meta", "score": 0.35821573333333334, "colour": "#42a5f5", "ink": "#111111", "label": "36", "new": false}, {"name": "GLM-5.3 Flash (max)", "org": "Z.ai", "score": 0.3199877333333333, "colour": "#96650b", "ink": "#ffffff", "label": "32", "new": false}, {"name": "Qwen 3.8 27B (thinking on)", "org": "Alibaba", "score": 0.2261779866666667, "colour": "#fe7016", "ink": "#111111", "label": "23", "new": false}, {"name": "DeepSeek V4.1 Flash (high)", "org": "DeepSeek", "score": 0.21048916, "colour": "#3f51e0", "ink": "#ffffff", "label": "21", "new": false}, {"name": "Qwen 3.8 27B (thinking off)", "org": "Alibaba", "score": 0.19970338666666668, "colour": "#fe7016", "ink": "#111111", "label": "20", "new": false}, {"name": "Inkling (high)", "org": "Thinking Machines", "score": 0.19801974666666666, "colour": "#686868", "ink": "#ffffff", "label": "20", "new": false}, {"name": "Grok 4.6 (high)", "org": "xAI", "score": 0.18414012, "colour": "#111111", "ink": "#ffffff", "label": "18", "new": false}, {"name": "Gemma 4 31B (thinking on)", "org": "Google", "score": 0.12554015999999998, "colour": "#7b1fa2", "ink": "#ffffff", "label": "13", "new": false}, {"name": "Gemma 4 31B (thinking off)", "org": "Google", "score": 0.11503794666666667, "colour": "#7b1fa2", "ink": "#ffffff", "label": "12", "new": false}]};
6
  const LOGOS = {"Anthropic": {"icon": "anthropic", "fill": "#141413", "viewBox": "0 0 24 24", "inner": "<path d=\"M13.827 3.52h3.603L24 20h-3.603l-6.57-16.48zm-7.258 0h3.767L16.906 20h-3.674l-1.343-3.461H5.017l-1.344 3.46H0L6.57 3.522zm4.132 9.959L8.453 7.687 6.205 13.48H10.7z\"></path>", "rule": "evenodd"}, "OpenAI": {"icon": "openai", "fill": "#141413", "viewBox": "0 0 24 24", "inner": "<path d=\"M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z\"></path>", "rule": "evenodd"}, "Meta": {"icon": "meta-color", "viewBox": "0 0 24 24", "inner": "<path d=\"M6.897 4h-.024l-.031 2.615h.022c1.715 0 3.046 1.357 5.94 6.246l.175.297.012.02 1.62-2.438-.012-.019a48.763 48.763 0 00-1.098-1.716 28.01 28.01 0 00-1.175-1.629C10.413 4.932 8.812 4 6.896 4z\" fill=\"url(#lobe-icons-meta-0-_R_0_)\"></path><path d=\"M6.873 4C4.95 4.01 3.247 5.258 2.02 7.17a4.352 4.352 0 00-.01.017l2.254 1.231.011-.017c.718-1.083 1.61-1.774 2.568-1.785h.021L6.896 4h-.023z\" fill=\"url(#lobe-icons-meta-1-_R_0_)\"></path><path d=\"M2.019 7.17l-.011.017C1.2 8.447.598 9.995.274 11.664l-.005.022 2.534.6.004-.022c.27-1.467.786-2.828 1.456-3.845l.011-.017L2.02 7.17z\" fill=\"url(#lobe-icons-meta-2-_R_0_)\"></path><path d=\"M2.807 12.264l-2.533-.6-.005.022c-.177.918-.267 1.851-.269 2.786v.023l2.598.233v-.023a12.591 12.591 0 01.21-2.44z\" fill=\"url(#lobe-icons-meta-3-_R_0_)\"></path><path d=\"M2.677 15.537a5.462 5.462 0 01-.079-.813v-.022L0 14.468v.024a8.89 8.89 0 00.146 1.652l2.535-.585a4.106 4.106 0 01-.004-.022z\" fill=\"url(#lobe-icons-meta-4-_R_0_)\"></path><path d=\"M3.27 16.89c-.284-.31-.484-.756-.589-1.328l-.004-.021-2.535.585.004.021c.192 1.01.568 1.85 1.106 2.487l.014.017 2.018-1.745a2.106 2.106 0 01-.015-.016z\" fill=\"url(#lobe-icons-meta-5-_R_0_)\"></path><path d=\"M10.78 9.654c-1.528 2.35-2.454 3.825-2.454 3.825-2.035 3.2-2.739 3.917-3.871 3.917a1.545 1.545 0 01-1.186-.508l-2.017 1.744.014.017C2.01 19.518 3.058 20 4.356 20c1.963 0 3.374-.928 5.884-5.33l1.766-3.13a41.283 41.283 0 00-1.227-1.886z\" fill=\"#0082FB\"></path><path d=\"M13.502 5.946l-.016.016c-.4.43-.786.908-1.16 1.416.378.483.768 1.024 1.175 1.63.48-.743.928-1.345 1.367-1.807l.016-.016-1.382-1.24z\" fill=\"url(#lobe-icons-meta-6-_R_0_)\"></path><path d=\"M20.918 5.713C19.853 4.633 18.583 4 17.225 4c-1.432 0-2.637.787-3.723 1.944l-.016.016 1.382 1.24.016-.017c.715-.747 1.408-1.12 2.176-1.12.826 0 1.6.39 2.27 1.075l.015.016 1.589-1.425-.016-.016z\" fill=\"#0082FB\"></path><path d=\"M23.998 14.125c-.06-3.467-1.27-6.566-3.064-8.396l-.016-.016-1.588 1.424.015.016c1.35 1.392 2.277 3.98 2.361 6.971v.023h2.292v-.022z\" fill=\"url(#lobe-icons-meta-7-_R_0_)\"></path><path d=\"M23.998 14.15v-.023h-2.292v.022c.004.14.006.282.006.424 0 .815-.121 1.474-.368 1.95l-.011.022 1.708 1.782.013-.02c.62-.96.946-2.293.946-3.91 0-.083 0-.165-.002-.247z\" fill=\"url(#lobe-icons-meta-8-_R_0_)\"></path><path d=\"M21.344 16.52l-.011.02c-.214.402-.519.67-.917.787l.778 2.462a3.493 3.493 0 00.438-.182 3.558 3.558 0 001.366-1.218l.044-.065.012-.02-1.71-1.784z\" fill=\"url(#lobe-icons-meta-9-_R_0_)\"></path><path d=\"M19.92 17.393c-.262 0-.492-.039-.718-.14l-.798 2.522c.449.153.927.222 1.46.222.492 0 .943-.073 1.352-.215l-.78-2.462c-.167.05-.341.075-.517.073z\" fill=\"url(#lobe-icons-meta-10-_R_0_)\"></path><path d=\"M18.323 16.534l-.014-.017-1.836 1.914.016.017c.637.682 1.246 1.105 1.937 1.337l.797-2.52c-.291-.125-.573-.353-.9-.731z\" fill=\"url(#lobe-icons-meta-11-_R_0_)\"></path><path d=\"M18.309 16.515c-.55-.642-1.232-1.712-2.303-3.44l-1.396-2.336-.011-.02-1.62 2.438.012.02.989 1.668c.959 1.61 1.74 2.774 2.493 3.585l.016.016 1.834-1.914a2.353 2.353 0 01-.014-.017z\" fill=\"url(#lobe-icons-meta-12-_R_0_)\"></path><defs><linearGradient id=\"lobe-icons-meta-0-_R_0_\" x1=\"75.897%\" x2=\"26.312%\" y1=\"89.199%\" y2=\"12.194%\"><stop offset=\".06%\" stop-color=\"#0867DF\"></stop><stop offset=\"45.39%\" stop-color=\"#0668E1\"></stop><stop offset=\"85.91%\" stop-color=\"#0064E0\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-1-_R_0_\" x1=\"21.67%\" x2=\"97.068%\" y1=\"75.874%\" y2=\"23.985%\"><stop offset=\"13.23%\" stop-color=\"#0064DF\"></stop><stop offset=\"99.88%\" stop-color=\"#0064E0\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-2-_R_0_\" x1=\"38.263%\" x2=\"60.895%\" y1=\"89.127%\" y2=\"16.131%\"><stop offset=\"1.47%\" stop-color=\"#0072EC\"></stop><stop offset=\"68.81%\" stop-color=\"#0064DF\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-3-_R_0_\" x1=\"47.032%\" x2=\"52.15%\" y1=\"90.19%\" y2=\"15.745%\"><stop offset=\"7.31%\" stop-color=\"#007CF6\"></stop><stop offset=\"99.43%\" stop-color=\"#0072EC\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-4-_R_0_\" x1=\"52.155%\" x2=\"47.591%\" y1=\"58.301%\" y2=\"37.004%\"><stop offset=\"7.31%\" stop-color=\"#007FF9\"></stop><stop offset=\"100%\" stop-color=\"#007CF6\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-5-_R_0_\" x1=\"37.689%\" x2=\"61.961%\" y1=\"12.502%\" y2=\"63.624%\"><stop offset=\"7.31%\" stop-color=\"#007FF9\"></stop><stop offset=\"100%\" stop-color=\"#0082FB\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-6-_R_0_\" x1=\"34.808%\" x2=\"62.313%\" y1=\"68.859%\" y2=\"23.174%\"><stop offset=\"27.99%\" stop-color=\"#007FF8\"></stop><stop offset=\"91.41%\" stop-color=\"#0082FB\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-7-_R_0_\" x1=\"43.762%\" x2=\"57.602%\" y1=\"6.235%\" y2=\"98.514%\"><stop offset=\"0%\" stop-color=\"#0082FB\"></stop><stop offset=\"99.95%\" stop-color=\"#0081FA\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-8-_R_0_\" x1=\"60.055%\" x2=\"39.88%\" y1=\"4.661%\" y2=\"69.077%\"><stop offset=\"6.19%\" stop-color=\"#0081FA\"></stop><stop offset=\"100%\" stop-color=\"#0080F9\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-9-_R_0_\" x1=\"30.282%\" x2=\"61.081%\" y1=\"59.32%\" y2=\"33.244%\"><stop offset=\"0%\" stop-color=\"#027AF3\"></stop><stop offset=\"100%\" stop-color=\"#0080F9\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-10-_R_0_\" x1=\"20.433%\" x2=\"82.112%\" y1=\"50.001%\" y2=\"50.001%\"><stop offset=\"0%\" stop-color=\"#0377EF\"></stop><stop offset=\"99.94%\" stop-color=\"#0279F1\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-11-_R_0_\" x1=\"40.303%\" x2=\"72.394%\" y1=\"35.298%\" y2=\"57.811%\"><stop offset=\".19%\" stop-color=\"#0471E9\"></stop><stop offset=\"100%\" stop-color=\"#0377EF\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-12-_R_0_\" x1=\"32.254%\" x2=\"68.003%\" y1=\"19.719%\" y2=\"84.908%\"><stop offset=\"27.65%\" stop-color=\"#0867DF\"></stop><stop offset=\"100%\" stop-color=\"#0471E9\"></stop></linearGradient></defs>", "rule": null}, "Google": {"icon": "google-color", "viewBox": "0 0 24 24", "inner": "<path d=\"M23 12.245c0-.905-.075-1.565-.236-2.25h-10.54v4.083h6.186c-.124 1.014-.797 2.542-2.294 3.569l-.021.136 3.332 2.53.23.022C21.779 18.417 23 15.593 23 12.245z\" fill=\"#4285F4\"></path><path d=\"M12.225 23c3.03 0 5.574-.978 7.433-2.665l-3.542-2.688c-.948.648-2.22 1.1-3.891 1.1a6.745 6.745 0 01-6.386-4.572l-.132.011-3.465 2.628-.045.124C4.043 20.531 7.835 23 12.225 23z\" fill=\"#34A853\"></path><path d=\"M5.84 14.175A6.65 6.65 0 015.463 12c0-.758.138-1.491.361-2.175l-.006-.147-3.508-2.67-.115.054A10.831 10.831 0 001 12c0 1.772.436 3.447 1.197 4.938l3.642-2.763z\" fill=\"#FBBC05\"></path><path d=\"M12.225 5.253c2.108 0 3.529.892 4.34 1.638l3.167-3.031C17.787 2.088 15.255 1 12.225 1 7.834 1 4.043 3.469 2.197 7.062l3.63 2.763a6.77 6.77 0 016.398-4.572z\" fill=\"#EB4335\"></path>", "rule": null}, "DeepSeek": {"icon": "deepseek-color", "viewBox": "0 0 24 24", "inner": "<path d=\"M23.748 4.482c-.254-.124-.364.113-.512.234-.051.039-.094.09-.137.136-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.156-.708-.311-.955-.65-.172-.241-.219-.51-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.093.172.187.129.323-.082.28-.18.552-.266.833-.055.179-.137.217-.329.14a5.526 5.526 0 01-1.736-1.18c-.857-.828-1.631-1.742-2.597-2.458a11.365 11.365 0 00-.689-.471c-.985-.957.13-1.743.388-1.836.27-.098.093-.432-.779-.428-.872.004-1.67.295-2.687.684a3.055 3.055 0 01-.465.137 9.597 9.597 0 00-2.883-.102c-1.885.21-3.39 1.102-4.497 2.623C.082 8.606-.231 10.684.152 12.85c.403 2.284 1.569 4.175 3.36 5.653 1.858 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.133-.284 4.994-1.86.47.234.962.327 1.78.397.63.059 1.236-.03 1.705-.128.735-.156.684-.837.419-.961-2.155-1.004-1.682-.595-2.113-.926 1.096-1.296 2.746-2.642 3.392-7.003.05-.347.007-.565 0-.845-.004-.17.035-.237.23-.256a4.173 4.173 0 001.545-.475c1.396-.763 1.96-2.015 2.093-3.517.02-.23-.004-.467-.247-.588zM11.581 18c-2.089-1.642-3.102-2.183-3.52-2.16-.392.024-.321.471-.235.763.09.288.207.486.371.739.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.167-1.361-.802-2.5-1.86-3.301-3.307-.774-1.393-1.224-2.887-1.298-4.482-.02-.386.093-.522.477-.592a4.696 4.696 0 011.529-.039c2.132.312 3.946 1.265 5.468 2.774.868.86 1.525 1.887 2.202 2.891.72 1.066 1.494 2.082 2.48 2.914.348.292.625.514.891.677-.802.09-2.14.11-3.054-.614zm1-6.44a.306.306 0 01.415-.287.302.302 0 01.2.288.306.306 0 01-.31.307.303.303 0 01-.304-.308zm3.11 1.596c-.2.081-.399.151-.59.16a1.245 1.245 0 01-.798-.254c-.274-.23-.47-.358-.552-.758a1.73 1.73 0 01.016-.588c.07-.327-.008-.537-.239-.727-.187-.156-.426-.199-.688-.199a.559.559 0 01-.254-.078c-.11-.054-.2-.19-.114-.358.028-.054.16-.186.192-.21.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.391.451.462.576.685.914.176.265.336.537.445.848.067.195-.019.354-.25.452z\" fill=\"#4D6BFE\"></path>", "rule": null}, "xAI": {"icon": "xai", "tile": "#111111", "shape": "square", "viewBox": "0 0 24 24", "inner": "<path d=\"M6.469 8.776L16.512 23h-4.464L2.005 8.776H6.47zm-.004 7.9l2.233 3.164L6.467 23H2l4.465-6.324zM22 2.582V23h-3.659V7.764L22 2.582zM22 1l-9.952 14.095-2.233-3.163L17.533 1H22z\"></path>", "rule": "evenodd"}, "Z.ai": {"icon": "zai", "tile": "#111111", "shape": "square", "viewBox": "0 0 24 24", "inner": "<path d=\"M12.105 2L9.927 4.953H.653L2.83 2h9.276zM23.254 19.048L21.078 22h-9.242l2.174-2.952h9.244zM24 2L9.264 22H0L14.736 2H24z\"></path>", "rule": "evenodd"}, "Moonshot": {"icon": "kimi", "tile": "#111111", "shape": "square", "viewBox": "0 0 24 24", "inner": "<path d=\"M21.846 0a1.923 1.923 0 110 3.846H20.15a.226.226 0 01-.227-.226V1.923C19.923.861 20.784 0 21.846 0z\"></path><path d=\"M11.065 11.199l7.257-7.2c.137-.136.06-.41-.116-.41H14.3a.164.164 0 00-.117.051l-7.82 7.756c-.122.12-.302.013-.302-.179V3.82c0-.127-.083-.23-.185-.23H3.186c-.103 0-.186.103-.186.23V19.77c0 .128.083.23.186.23h2.69c.103 0 .186-.102.186-.23v-3.25c0-.069.025-.135.069-.178l2.424-2.406a.158.158 0 01.205-.023l6.484 4.772a7.677 7.677 0 003.453 1.283c.108.012.2-.095.2-.23v-3.06c0-.117-.07-.212-.164-.227a5.028 5.028 0 01-2.027-.807l-5.613-4.064c-.117-.078-.132-.279-.028-.381z\"></path>", "rule": "evenodd"}, "StepFun": {"icon": "stepfun", "tile": "#01d9cf", "shape": "circle", "viewBox": "0 0 24 24", "inner": "<path d=\"M12 0C5.372 0 0 5.372 0 12s5.372 12 12 12 12-5.372 12-12S18.628 0 12 0zM8.762 19.614H4.376v-4.386h4.386v4.386zm5.423 0H9.798v-4.386h4.387v4.386zm0-5.42H9.798V9.81h4.387v4.386zm0-5.418H9.798V4.39h4.387v4.386zm5.422-.004h-4.386V4.386h4.386v4.386z\"></path>", "rule": "evenodd"}, "Undisclosed": {"icon": "unionalpha-color", "viewBox": "0 0 24 24", "inner": "<path d=\"M12.5709 13.3706C12.6556 13.4345 12.8442 13.7666 12.9123 13.875L13.4693 14.7624C13.7592 15.2257 14.0526 15.6895 14.3386 16.1555C14.4141 16.2951 14.4587 16.3467 14.3445 16.48C13.9818 16.9035 13.6097 17.321 13.2426 17.7406C12.6047 18.4698 11.5795 19.0999 10.6086 19.2277C10.5721 19.2324 10.5355 19.2366 10.4988 19.2405C10.3741 19.2219 10.2359 19.2226 10.1067 19.2077C9.62828 19.1531 9.13925 18.9833 8.73437 18.7229C8.58284 18.6255 8.20429 18.365 8.13135 18.2015C8.7166 18.0941 8.9971 17.6275 9.36375 17.2093C9.46647 17.0921 9.56558 16.9681 9.66524 16.8481C10.2482 16.1439 10.8249 15.4346 11.3952 14.7202C11.5532 14.5228 12.4352 13.3557 12.5709 13.3706Z\" fill=\"url(#lobe-icons-union-alpha-0-_R_0_)\"></path><path d=\"M23.9999 4.03711C23.9427 4.17731 23.8557 4.29083 23.7726 4.41626C23.5172 4.80162 23.2489 5.18017 22.9952 5.56645C21.7031 7.52279 20.3758 9.45572 19.0141 11.3643L18.2195 12.4575C18.0914 12.6376 17.8772 12.9025 17.8103 13.1017C17.5635 12.8289 17.3373 12.3638 17.1271 12.052C16.7507 11.4939 16.4007 10.8942 16.0072 10.3494C15.964 10.2787 15.9232 10.1649 15.8967 10.0866C15.9509 9.95674 16.2386 9.57362 16.3367 9.43732L17.184 8.26053L19.1886 5.47039C19.3731 5.21667 20.0937 4.17696 20.2819 4.03711H23.9999Z\" fill=\"url(#lobe-icons-union-alpha-1-_R_0_)\"></path><path d=\"M5.67537 4.61919C5.91433 4.59978 6.08153 4.64306 6.2388 4.65534C7.31097 4.73906 7.93546 5.78123 8.52073 6.55699C8.55486 6.60222 8.67307 6.77678 8.67756 6.81818C8.50211 6.78591 8.24062 6.87736 8.10425 6.98766C7.77451 7.25438 7.47306 7.60773 7.16738 7.90822C6.82713 8.24411 6.49119 8.58431 6.15964 8.92879C5.96629 9.12818 5.68162 9.40902 5.50821 9.61426C4.95769 10.264 4.58519 11.0455 4.42712 11.8823C4.38673 12.1047 4.33596 12.4789 4.34474 12.6979C4.38003 13.5788 4.68343 14.4541 5.20029 15.1681C5.44662 15.5083 5.69406 15.7534 5.97744 16.05C6.42647 16.5145 6.87971 16.9749 7.33712 17.4311C8.17604 18.2704 8.83084 19.0614 10.1068 19.2072C10.2359 19.2221 10.3741 19.2214 10.4989 19.24C10.4563 19.2438 10.4156 19.2437 10.3732 19.2456C9.63946 19.2779 8.9074 19.2593 8.17299 19.2571L6.81265 19.2561C6.34052 19.2551 5.82434 19.2555 5.36063 19.1766C4.33929 19.003 3.55816 18.5177 2.78058 17.8624C1.69732 16.9495 0.760791 15.9389 0.316835 14.5629C0.188539 14.1652 0.0845513 13.7688 0.0423572 13.352C0.0341296 13.2704 0.025306 13.1714 0 13.0938V12.1601C0.024482 12.0989 0.0539558 11.7751 0.0701206 11.682C0.118265 11.3996 0.185469 11.1208 0.271272 10.8475C0.464403 10.234 0.818387 9.53555 1.19037 9.01281C1.67633 8.32991 2.33983 7.69834 2.92227 7.09354L3.99839 5.99473C4.54749 5.44174 4.97245 4.98537 5.67537 4.61919Z\" fill=\"url(#lobe-icons-union-alpha-2-_R_0_)\"></path><path d=\"M16.0072 10.3494C16.4008 10.8942 16.7508 11.4939 17.1271 12.052C17.3373 12.3638 17.5635 12.8289 17.8104 13.1017C17.8351 13.1633 18.024 13.4562 18.0701 13.5307L18.6905 14.5371C19.1466 15.2881 19.6091 16.0351 20.078 16.7781C20.4399 17.3561 20.7699 17.9692 21.2574 18.4512C21.5622 18.7524 21.9167 18.9416 22.3073 19.1101C22.4041 19.1518 22.5241 19.1723 22.6131 19.2159L22.5999 19.2374C22.543 19.2593 22.4118 19.2355 22.3393 19.2386C21.4806 19.2765 20.6139 19.2542 19.7541 19.2467C19.2053 19.2419 18.6361 19.2653 18.0899 19.2461C17.9536 19.241 17.8182 19.2222 17.6855 19.1901C17.2306 19.0825 16.8145 18.8188 16.4914 18.4847C16.2155 18.1993 16.0406 17.8931 15.8347 17.558C15.6277 17.2199 15.423 16.8802 15.2208 16.5391L13.5134 13.7217C13.602 13.5224 14.0393 12.9594 14.2007 12.7419L16.0072 10.3494Z\" fill=\"url(#lobe-icons-union-alpha-3-_R_0_)\"></path><path d=\"M11.3662 4.03706C11.4355 4.04736 11.5279 4.0639 11.5825 4.11302C11.7409 4.25538 11.8717 4.45147 12.0009 4.62253C13.1498 6.14388 14.2121 7.73081 15.2749 9.31286C15.3244 9.38658 15.4528 9.56569 15.4748 9.646C15.3946 9.79571 15.0698 10.1847 14.9522 10.3329L13.8456 11.7243C13.647 11.9762 13.455 12.2345 13.2586 12.4878C13.1566 12.6194 13.0064 12.8305 12.8889 12.9425C12.6125 12.5563 12.3581 12.1531 12.0887 11.7623L9.66701 8.22137C9.43592 7.88192 9.20191 7.54448 8.96502 7.20905C8.92518 7.15337 8.69584 6.86111 8.67758 6.81865C8.67307 6.77723 8.55489 6.60269 8.52077 6.55747C7.9355 5.7817 7.311 4.73956 6.23883 4.65583C6.08162 4.64356 5.91434 4.61968 5.67542 4.61968C6.15935 4.35771 6.84659 4.17302 7.38673 4.09926C8.69114 3.92117 10.0523 4.03706 11.3662 4.03706Z\" fill=\"url(#lobe-icons-union-alpha-4-_R_0_)\"></path><path d=\"M15.3619 8.08232L15.874 8.87602L19.2024 4.16504L15.3619 8.08232Z\" fill=\"url(#lobe-icons-union-alpha-5-_R_0_)\"></path><defs><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-union-alpha-0-_R_0_\" x1=\"21.5578\" x2=\"21.5578\" y1=\"4.03711\" y2=\"12.691\"><stop stop-color=\"currentColor\" stop-opacity=\"0.39\"></stop><stop offset=\"1\" stop-color=\"currentColor\" stop-opacity=\"0.22\"></stop></linearGradient><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-union-alpha-1-_R_0_\" x1=\"21.5578\" x2=\"21.5578\" y1=\"4.03711\" y2=\"12.691\"><stop stop-color=\"currentColor\" stop-opacity=\"0.39\"></stop><stop offset=\"1\" stop-color=\"currentColor\" stop-opacity=\"0.22\"></stop></linearGradient><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-union-alpha-2-_R_0_\" x1=\"5.27425\" x2=\"5.24944\" y1=\"5.41908\" y2=\"14.0217\"><stop stop-color=\"currentColor\" stop-opacity=\"0.15\"></stop><stop offset=\"1\" stop-color=\"currentColor\" stop-opacity=\"0.87\"></stop></linearGradient><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-union-alpha-3-_R_0_\" x1=\"14.1443\" x2=\"14.1443\" y1=\"14.4319\" y2=\"19.26\"><stop stop-color=\"currentColor\" stop-opacity=\"0.93\"></stop><stop offset=\"1\" stop-color=\"currentColor\" stop-opacity=\"0.57\"></stop></linearGradient><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-union-alpha-4-_R_0_\" x1=\"14.1443\" x2=\"14.1443\" y1=\"14.4319\" y2=\"19.26\"><stop stop-color=\"currentColor\" stop-opacity=\"0.93\"></stop><stop offset=\"1\" stop-color=\"currentColor\" stop-opacity=\"0.57\"></stop></linearGradient><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-union-alpha-5-_R_0_\" x1=\"17.2822\" x2=\"17.2822\" y1=\"4.16504\" y2=\"8.87602\"><stop stop-color=\"#D72725\"></stop><stop offset=\"1\" stop-color=\"#CD2920\"></stop></linearGradient></defs>", "rule": null}, "Cognition": {"icon": "devin-color", "viewBox": "0 0 24 24", "inner": "<path d=\"M2.033 9.867l2.554 1.483a.589.589 0 00.592 0l2.554-1.483.01-.008a.608.608 0 00.11-.084l.013-.015a.631.631 0 00.076-.1c.003-.005.008-.01.01-.016a.558.558 0 00.052-.125l.007-.028a.611.611 0 00.019-.14V7.868c0-.572.307-1.105.8-1.392a1.595 1.595 0 011.598 0l1.277.742a.54.54 0 00.129.053l.028.01c.044.01.088.015.133.016h.006l.013-.002a.587.587 0 00.27-.074l.011-.004 2.554-1.483a.596.596 0 00.297-.516V2.253a.595.595 0 00-.297-.516L12.293.257a.587.587 0 00-.591 0L9.148 1.737l-.01.01a.609.609 0 00-.109.083l-.014.015a.632.632 0 00-.076.1c-.003.005-.008.01-.01.016a.57.57 0 00-.052.124l-.007.028a.612.612 0 00-.018.14v1.483c0 .572-.307 1.105-.8 1.393a1.597 1.597 0 01-1.599 0l-1.276-.742a.603.603 0 00-.13-.053l-.028-.008a.658.658 0 00-.133-.018h-.02a.57.57 0 00-.269.074c-.003.002-.008.002-.012.005L2.033 5.872a.596.596 0 00-.297.515v2.966c0 .213.113.41.297.515z\" fill=\"#3969CA\"></path><path d=\"M15.943 10.607a1.596 1.596 0 011.599 0l1.276.74c.041.025.085.04.13.055l.028.008c.043.01.088.016.133.018h.005c.005 0 .01-.002.014-.003a.474.474 0 00.122-.016l.021-.005a.616.616 0 00.126-.052c.004-.002.009-.002.013-.005l2.554-1.482a.597.597 0 00.297-.516V6.383a.596.596 0 00-.297-.515l-2.552-1.483a.587.587 0 00-.592 0l-2.553 1.482-.011.008a.61.61 0 00-.108.084l-.014.016a.637.637 0 00-.076.1c-.003.005-.008.01-.01.016a.57.57 0 00-.052.124l-.007.029a.612.612 0 00-.018.14v1.482c0 .572-.307 1.105-.8 1.393a1.597 1.597 0 01-1.599 0l-1.276-.742a.584.584 0 00-.13-.053l-.028-.008a.62.62 0 00-.133-.018h-.02a.587.587 0 00-.269.074l-.012.004L9.15 10a.596.596 0 00-.296.516v2.966c0 .212.112.409.296.515l2.554 1.483s.008.002.012.005c.04.022.082.04.126.052l.02.004a.57.57 0 00.123.017l.014.002h.006c.054 0 .108-.01.16-.025a.587.587 0 00.13-.054l1.277-.741a1.597 1.597 0 012.398 1.392v1.482c0 .049.007.095.019.14l.007.028a.619.619 0 00.051.125c.004.006.008.01.01.016a.6.6 0 00.076.1l.014.015c.033.032.069.06.108.084.004.002.006.006.011.008l2.554 1.483a.59.59 0 00.593 0l2.554-1.483a.597.597 0 00.296-.516v-2.965a.595.595 0 00-.296-.516l-2.554-1.483s-.008-.002-.012-.005a.54.54 0 00-.126-.051c-.007-.003-.013-.003-.02-.005a.635.635 0 00-.125-.017h-.018a.557.557 0 00-.16.026.588.588 0 00-.13.053l-1.276.742a1.595 1.595 0 01-1.598 0 1.615 1.615 0 010-2.785l-.005-.001z\" fill=\"#21C19A\"></path><path d=\"M14.848 18.265l-2.554-1.482-.012-.005a.526.526 0 00-.126-.052c-.007-.002-.014-.002-.02-.005a.64.64 0 00-.124-.017h-.02a.56.56 0 00-.16.026.588.588 0 00-.13.053l-1.276.742a1.594 1.594 0 01-1.598 0c-.493-.286-.8-.82-.8-1.393V14.65a.563.563 0 00-.018-.14l-.008-.028a.604.604 0 00-.051-.124l-.01-.017a.603.603 0 00-.076-.1l-.014-.015a.596.596 0 00-.109-.084c-.003-.002-.005-.006-.01-.008L5.178 12.65a.587.587 0 00-.591 0l-2.554 1.483a.596.596 0 00-.297.516v2.965c0 .213.113.41.297.516l2.554 1.483.012.004a.618.618 0 00.267.074l.016.002h.007a.55.55 0 00.16-.026.584.584 0 00.129-.053l1.277-.742a1.597 1.597 0 012.398 1.393v1.482c0 .05.007.095.019.14l.007.028c.013.044.03.085.051.125l.01.016c.022.036.047.07.076.1l.014.015c.032.032.069.06.109.084l.01.008 2.554 1.483a.587.587 0 00.593 0l2.554-1.483a.596.596 0 00.296-.515v-2.966a.596.596 0 00-.296-.516h-.002z\" fill=\"#0294DE\"></path>", "rule": null}, "Fireworks": {"icon": "fireworks-color", "viewBox": "0 0 24 24", "inner": "<path clip-rule=\"evenodd\" d=\"M14.8 5l-2.801 6.795L9.195 5H7.397l3.072 7.428a1.64 1.64 0 003.038.002L16.598 5H14.8zm1.196 10.352l5.124-5.244-.699-1.669-5.596 5.739a1.664 1.664 0 00-.343 1.807 1.642 1.642 0 001.516 1.012L16 17l8-.02-.699-1.669-7.303.041h-.002zM2.88 10.104l.699-1.669 5.596 5.739c.468.479.603 1.189.343 1.807a1.643 1.643 0 01-1.516 1.012l-8-.018-.002.002.699-1.669 7.303.042-5.122-5.246z\" fill=\"#5019C5\" fill-rule=\"evenodd\"></path>", "rule": null}, "Stealth": {"wordmark": ["STEALTH"]}, "Thinking Machines": {"wordmark": ["THINKING", "MACHINES"]}, "Alibaba": {"wordmark": ["QWEN"]}};
@@ -22,10 +23,11 @@ const G = { // geometry, CSS px
22
  nameTol: 12, // splits this close to the most balanced count as ties
23
  };
24
 
 
25
  function el(tag, attrs, parent) {
26
  const e = document.createElementNS(NS, tag);
27
  for (const k in attrs) e.setAttribute(k, attrs[k]);
28
- (parent || svg).appendChild(e);
29
  return e;
30
  }
31
  const ctx = document.createElement("canvas").getContext("2d");
@@ -87,9 +89,12 @@ function wrap2(name, font) {
87
  const cx = G.left + (i + 0.5) * pitch, x0 = cx - bwid / 2, x1 = cx + bwid / 2;
88
  const top = y(d.score * 100), r = Math.min(G.radius, bwid / 2);
89
  pos[d.name] = {cx, top, x0, x1};
90
- const bar = el("path", {tabindex: 0, role: "img", "aria-label": `${d.name}: ${d.score.toFixed(3)}`, d: `M${x0},${G.base} V${top + r} Q${x0},${top} ${x0 + r},${top} H${x1 - r} ` +
 
 
 
91
  `Q${x1},${top} ${x1},${top + r} V${G.base} Z`, fill: d.colour});
92
- el("title", {}, bar).textContent = `${d.name}: ${d.score.toFixed(3)}`;
93
  const v = el("text", {x: cx, y: (top + G.base) / 2 + 5.4, "text-anchor": "middle",
94
  "font-family": MONO, "font-weight": 500, "font-size": 15.5, fill: d.ink});
95
  v.textContent = d.label;
@@ -135,6 +140,6 @@ function wrap2(name, font) {
135
  });
136
 
137
 
138
- svg.dataset.ready='true';
139
  }
140
  })();
 
1
  // Bar layout and name wrapping adapted from BuildingBench figure-kit/bar-static/build.py.
2
  // Data is exclusively the existing Code4Scene data/site.js paper board; no reference benchmark scores.
3
  (async function(){
4
+ const {bindChartTooltip}=await import("./chart-interactions.js?v=20261001c");
5
  await Promise.all([document.fonts.load('400 13px Inter'),document.fonts.load('700 13px Inter'),document.fonts.load('500 15.5px "IBM Plex Mono"')]);
6
  const ALL = {"overall": [{"name": "GPT-6 Astra (max)", "org": "OpenAI", "score": 0.6193352866666667, "colour": "#10A37F", "ink": "#ffffff", "label": "62", "new": false}, {"name": "Gemini 3.8 Flash (high)", "org": "Google", "score": 0.6189750266666667, "colour": "#7b1fa2", "ink": "#ffffff", "label": "62", "new": false}, {"name": "Claude Fable 5.1 (max)", "org": "Anthropic", "score": 0.60604898, "colour": "#D97757", "ink": "#ffffff", "label": "61", "new": false}, {"name": "Claude Opus 5 (max)", "org": "Anthropic", "score": 0.5931299933333334, "colour": "#D97757", "ink": "#ffffff", "label": "59", "new": false}, {"name": "GPT-5.6 Sol (high)", "org": "OpenAI", "score": 0.5499994666666667, "colour": "#10A37F", "ink": "#ffffff", "label": "55", "new": false}, {"name": "Muse Spark 1.3 (medium)", "org": "Meta", "score": 0.5022053666666666, "colour": "#42a5f5", "ink": "#111111", "label": "50", "new": false}, {"name": "GLM-5.3 Flash (max)", "org": "Z.ai", "score": 0.4147088666666666, "colour": "#96650b", "ink": "#ffffff", "label": "41", "new": false}, {"name": "Qwen 3.8 27B (thinking off)", "org": "Alibaba", "score": 0.37818169333333335, "colour": "#fe7016", "ink": "#111111", "label": "38", "new": false}, {"name": "Grok 4.6 (high)", "org": "xAI", "score": 0.37567506, "colour": "#111111", "ink": "#ffffff", "label": "38", "new": false}, {"name": "Qwen 3.8 27B (thinking on)", "org": "Alibaba", "score": 0.37094399333333333, "colour": "#fe7016", "ink": "#111111", "label": "37", "new": false}, {"name": "Inkling (high)", "org": "Thinking Machines", "score": 0.31150237333333336, "colour": "#686868", "ink": "#ffffff", "label": "31", "new": false}, {"name": "Gemma 4 31B (thinking on)", "org": "Google", "score": 0.29812257999999997, "colour": "#7b1fa2", "ink": "#ffffff", "label": "30", "new": false}, {"name": "Gemma 4 31B (thinking off)", "org": "Google", "score": 0.28498897333333334, "colour": "#7b1fa2", "ink": "#ffffff", "label": "28", "new": false}, {"name": "DeepSeek V4.1 Flash (high)", "org": "DeepSeek", "score": 0.22658958, "colour": "#3f51e0", "ink": "#ffffff", "label": "23", "new": false}], "t2s": [{"name": "Claude Fable 5.1 (max)", "org": "Anthropic", "score": 0.78775, "colour": "#D97757", "ink": "#ffffff", "label": "79", "new": false}, {"name": "GPT-6 Astra (max)", "org": "OpenAI", "score": 0.72382, "colour": "#10A37F", "ink": "#ffffff", "label": "72", "new": false}, {"name": "Claude Opus 5 (max)", "org": "Anthropic", "score": 0.7181599999999999, "colour": "#D97757", "ink": "#ffffff", "label": "72", "new": false}, {"name": "GPT-5.6 Sol (high)", "org": "OpenAI", "score": 0.70704, "colour": "#10A37F", "ink": "#ffffff", "label": "71", "new": false}, {"name": "Gemini 3.8 Flash (high)", "org": "Google", "score": 0.65689, "colour": "#7b1fa2", "ink": "#ffffff", "label": "66", "new": false}, {"name": "Muse Spark 1.3 (medium)", "org": "Meta", "score": 0.646195, "colour": "#42a5f5", "ink": "#111111", "label": "65", "new": false}, {"name": "Grok 4.6 (high)", "org": "xAI", "score": 0.56721, "colour": "#111111", "ink": "#ffffff", "label": "57", "new": false}, {"name": "Qwen 3.8 27B (thinking off)", "org": "Alibaba", "score": 0.55666, "colour": "#fe7016", "ink": "#111111", "label": "56", "new": false}, {"name": "Qwen 3.8 27B (thinking on)", "org": "Alibaba", "score": 0.51571, "colour": "#fe7016", "ink": "#111111", "label": "52", "new": false}, {"name": "GLM-5.3 Flash (max)", "org": "Z.ai", "score": 0.5094299999999999, "colour": "#96650b", "ink": "#ffffff", "label": "51", "new": false}, {"name": "Gemma 4 31B (thinking on)", "org": "Google", "score": 0.470705, "colour": "#7b1fa2", "ink": "#ffffff", "label": "47", "new": false}, {"name": "Gemma 4 31B (thinking off)", "org": "Google", "score": 0.45494, "colour": "#7b1fa2", "ink": "#ffffff", "label": "45", "new": false}, {"name": "Inkling (high)", "org": "Thinking Machines", "score": 0.42498500000000006, "colour": "#686868", "ink": "#ffffff", "label": "42", "new": false}, {"name": "DeepSeek V4.1 Flash (high)", "org": "DeepSeek", "score": 0.24269, "colour": "#3f51e0", "ink": "#ffffff", "label": "24", "new": false}], "i2s": [{"name": "Gemini 3.8 Flash (high)", "org": "Google", "score": 0.5810600533333334, "colour": "#7b1fa2", "ink": "#ffffff", "label": "58", "new": false}, {"name": "GPT-6 Astra (max)", "org": "OpenAI", "score": 0.5148505733333334, "colour": "#10A37F", "ink": "#ffffff", "label": "51", "new": false}, {"name": "Claude Opus 5 (max)", "org": "Anthropic", "score": 0.46809998666666675, "colour": "#D97757", "ink": "#ffffff", "label": "47", "new": false}, {"name": "Claude Fable 5.1 (max)", "org": "Anthropic", "score": 0.4243479600000001, "colour": "#D97757", "ink": "#ffffff", "label": "42", "new": false}, {"name": "GPT-5.6 Sol (high)", "org": "OpenAI", "score": 0.3929589333333333, "colour": "#10A37F", "ink": "#ffffff", "label": "39", "new": false}, {"name": "Muse Spark 1.3 (medium)", "org": "Meta", "score": 0.35821573333333334, "colour": "#42a5f5", "ink": "#111111", "label": "36", "new": false}, {"name": "GLM-5.3 Flash (max)", "org": "Z.ai", "score": 0.3199877333333333, "colour": "#96650b", "ink": "#ffffff", "label": "32", "new": false}, {"name": "Qwen 3.8 27B (thinking on)", "org": "Alibaba", "score": 0.2261779866666667, "colour": "#fe7016", "ink": "#111111", "label": "23", "new": false}, {"name": "DeepSeek V4.1 Flash (high)", "org": "DeepSeek", "score": 0.21048916, "colour": "#3f51e0", "ink": "#ffffff", "label": "21", "new": false}, {"name": "Qwen 3.8 27B (thinking off)", "org": "Alibaba", "score": 0.19970338666666668, "colour": "#fe7016", "ink": "#111111", "label": "20", "new": false}, {"name": "Inkling (high)", "org": "Thinking Machines", "score": 0.19801974666666666, "colour": "#686868", "ink": "#ffffff", "label": "20", "new": false}, {"name": "Grok 4.6 (high)", "org": "xAI", "score": 0.18414012, "colour": "#111111", "ink": "#ffffff", "label": "18", "new": false}, {"name": "Gemma 4 31B (thinking on)", "org": "Google", "score": 0.12554015999999998, "colour": "#7b1fa2", "ink": "#ffffff", "label": "13", "new": false}, {"name": "Gemma 4 31B (thinking off)", "org": "Google", "score": 0.11503794666666667, "colour": "#7b1fa2", "ink": "#ffffff", "label": "12", "new": false}]};
7
  const LOGOS = {"Anthropic": {"icon": "anthropic", "fill": "#141413", "viewBox": "0 0 24 24", "inner": "<path d=\"M13.827 3.52h3.603L24 20h-3.603l-6.57-16.48zm-7.258 0h3.767L16.906 20h-3.674l-1.343-3.461H5.017l-1.344 3.46H0L6.57 3.522zm4.132 9.959L8.453 7.687 6.205 13.48H10.7z\"></path>", "rule": "evenodd"}, "OpenAI": {"icon": "openai", "fill": "#141413", "viewBox": "0 0 24 24", "inner": "<path d=\"M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z\"></path>", "rule": "evenodd"}, "Meta": {"icon": "meta-color", "viewBox": "0 0 24 24", "inner": "<path d=\"M6.897 4h-.024l-.031 2.615h.022c1.715 0 3.046 1.357 5.94 6.246l.175.297.012.02 1.62-2.438-.012-.019a48.763 48.763 0 00-1.098-1.716 28.01 28.01 0 00-1.175-1.629C10.413 4.932 8.812 4 6.896 4z\" fill=\"url(#lobe-icons-meta-0-_R_0_)\"></path><path d=\"M6.873 4C4.95 4.01 3.247 5.258 2.02 7.17a4.352 4.352 0 00-.01.017l2.254 1.231.011-.017c.718-1.083 1.61-1.774 2.568-1.785h.021L6.896 4h-.023z\" fill=\"url(#lobe-icons-meta-1-_R_0_)\"></path><path d=\"M2.019 7.17l-.011.017C1.2 8.447.598 9.995.274 11.664l-.005.022 2.534.6.004-.022c.27-1.467.786-2.828 1.456-3.845l.011-.017L2.02 7.17z\" fill=\"url(#lobe-icons-meta-2-_R_0_)\"></path><path d=\"M2.807 12.264l-2.533-.6-.005.022c-.177.918-.267 1.851-.269 2.786v.023l2.598.233v-.023a12.591 12.591 0 01.21-2.44z\" fill=\"url(#lobe-icons-meta-3-_R_0_)\"></path><path d=\"M2.677 15.537a5.462 5.462 0 01-.079-.813v-.022L0 14.468v.024a8.89 8.89 0 00.146 1.652l2.535-.585a4.106 4.106 0 01-.004-.022z\" fill=\"url(#lobe-icons-meta-4-_R_0_)\"></path><path d=\"M3.27 16.89c-.284-.31-.484-.756-.589-1.328l-.004-.021-2.535.585.004.021c.192 1.01.568 1.85 1.106 2.487l.014.017 2.018-1.745a2.106 2.106 0 01-.015-.016z\" fill=\"url(#lobe-icons-meta-5-_R_0_)\"></path><path d=\"M10.78 9.654c-1.528 2.35-2.454 3.825-2.454 3.825-2.035 3.2-2.739 3.917-3.871 3.917a1.545 1.545 0 01-1.186-.508l-2.017 1.744.014.017C2.01 19.518 3.058 20 4.356 20c1.963 0 3.374-.928 5.884-5.33l1.766-3.13a41.283 41.283 0 00-1.227-1.886z\" fill=\"#0082FB\"></path><path d=\"M13.502 5.946l-.016.016c-.4.43-.786.908-1.16 1.416.378.483.768 1.024 1.175 1.63.48-.743.928-1.345 1.367-1.807l.016-.016-1.382-1.24z\" fill=\"url(#lobe-icons-meta-6-_R_0_)\"></path><path d=\"M20.918 5.713C19.853 4.633 18.583 4 17.225 4c-1.432 0-2.637.787-3.723 1.944l-.016.016 1.382 1.24.016-.017c.715-.747 1.408-1.12 2.176-1.12.826 0 1.6.39 2.27 1.075l.015.016 1.589-1.425-.016-.016z\" fill=\"#0082FB\"></path><path d=\"M23.998 14.125c-.06-3.467-1.27-6.566-3.064-8.396l-.016-.016-1.588 1.424.015.016c1.35 1.392 2.277 3.98 2.361 6.971v.023h2.292v-.022z\" fill=\"url(#lobe-icons-meta-7-_R_0_)\"></path><path d=\"M23.998 14.15v-.023h-2.292v.022c.004.14.006.282.006.424 0 .815-.121 1.474-.368 1.95l-.011.022 1.708 1.782.013-.02c.62-.96.946-2.293.946-3.91 0-.083 0-.165-.002-.247z\" fill=\"url(#lobe-icons-meta-8-_R_0_)\"></path><path d=\"M21.344 16.52l-.011.02c-.214.402-.519.67-.917.787l.778 2.462a3.493 3.493 0 00.438-.182 3.558 3.558 0 001.366-1.218l.044-.065.012-.02-1.71-1.784z\" fill=\"url(#lobe-icons-meta-9-_R_0_)\"></path><path d=\"M19.92 17.393c-.262 0-.492-.039-.718-.14l-.798 2.522c.449.153.927.222 1.46.222.492 0 .943-.073 1.352-.215l-.78-2.462c-.167.05-.341.075-.517.073z\" fill=\"url(#lobe-icons-meta-10-_R_0_)\"></path><path d=\"M18.323 16.534l-.014-.017-1.836 1.914.016.017c.637.682 1.246 1.105 1.937 1.337l.797-2.52c-.291-.125-.573-.353-.9-.731z\" fill=\"url(#lobe-icons-meta-11-_R_0_)\"></path><path d=\"M18.309 16.515c-.55-.642-1.232-1.712-2.303-3.44l-1.396-2.336-.011-.02-1.62 2.438.012.02.989 1.668c.959 1.61 1.74 2.774 2.493 3.585l.016.016 1.834-1.914a2.353 2.353 0 01-.014-.017z\" fill=\"url(#lobe-icons-meta-12-_R_0_)\"></path><defs><linearGradient id=\"lobe-icons-meta-0-_R_0_\" x1=\"75.897%\" x2=\"26.312%\" y1=\"89.199%\" y2=\"12.194%\"><stop offset=\".06%\" stop-color=\"#0867DF\"></stop><stop offset=\"45.39%\" stop-color=\"#0668E1\"></stop><stop offset=\"85.91%\" stop-color=\"#0064E0\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-1-_R_0_\" x1=\"21.67%\" x2=\"97.068%\" y1=\"75.874%\" y2=\"23.985%\"><stop offset=\"13.23%\" stop-color=\"#0064DF\"></stop><stop offset=\"99.88%\" stop-color=\"#0064E0\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-2-_R_0_\" x1=\"38.263%\" x2=\"60.895%\" y1=\"89.127%\" y2=\"16.131%\"><stop offset=\"1.47%\" stop-color=\"#0072EC\"></stop><stop offset=\"68.81%\" stop-color=\"#0064DF\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-3-_R_0_\" x1=\"47.032%\" x2=\"52.15%\" y1=\"90.19%\" y2=\"15.745%\"><stop offset=\"7.31%\" stop-color=\"#007CF6\"></stop><stop offset=\"99.43%\" stop-color=\"#0072EC\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-4-_R_0_\" x1=\"52.155%\" x2=\"47.591%\" y1=\"58.301%\" y2=\"37.004%\"><stop offset=\"7.31%\" stop-color=\"#007FF9\"></stop><stop offset=\"100%\" stop-color=\"#007CF6\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-5-_R_0_\" x1=\"37.689%\" x2=\"61.961%\" y1=\"12.502%\" y2=\"63.624%\"><stop offset=\"7.31%\" stop-color=\"#007FF9\"></stop><stop offset=\"100%\" stop-color=\"#0082FB\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-6-_R_0_\" x1=\"34.808%\" x2=\"62.313%\" y1=\"68.859%\" y2=\"23.174%\"><stop offset=\"27.99%\" stop-color=\"#007FF8\"></stop><stop offset=\"91.41%\" stop-color=\"#0082FB\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-7-_R_0_\" x1=\"43.762%\" x2=\"57.602%\" y1=\"6.235%\" y2=\"98.514%\"><stop offset=\"0%\" stop-color=\"#0082FB\"></stop><stop offset=\"99.95%\" stop-color=\"#0081FA\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-8-_R_0_\" x1=\"60.055%\" x2=\"39.88%\" y1=\"4.661%\" y2=\"69.077%\"><stop offset=\"6.19%\" stop-color=\"#0081FA\"></stop><stop offset=\"100%\" stop-color=\"#0080F9\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-9-_R_0_\" x1=\"30.282%\" x2=\"61.081%\" y1=\"59.32%\" y2=\"33.244%\"><stop offset=\"0%\" stop-color=\"#027AF3\"></stop><stop offset=\"100%\" stop-color=\"#0080F9\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-10-_R_0_\" x1=\"20.433%\" x2=\"82.112%\" y1=\"50.001%\" y2=\"50.001%\"><stop offset=\"0%\" stop-color=\"#0377EF\"></stop><stop offset=\"99.94%\" stop-color=\"#0279F1\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-11-_R_0_\" x1=\"40.303%\" x2=\"72.394%\" y1=\"35.298%\" y2=\"57.811%\"><stop offset=\".19%\" stop-color=\"#0471E9\"></stop><stop offset=\"100%\" stop-color=\"#0377EF\"></stop></linearGradient><linearGradient id=\"lobe-icons-meta-12-_R_0_\" x1=\"32.254%\" x2=\"68.003%\" y1=\"19.719%\" y2=\"84.908%\"><stop offset=\"27.65%\" stop-color=\"#0867DF\"></stop><stop offset=\"100%\" stop-color=\"#0471E9\"></stop></linearGradient></defs>", "rule": null}, "Google": {"icon": "google-color", "viewBox": "0 0 24 24", "inner": "<path d=\"M23 12.245c0-.905-.075-1.565-.236-2.25h-10.54v4.083h6.186c-.124 1.014-.797 2.542-2.294 3.569l-.021.136 3.332 2.53.23.022C21.779 18.417 23 15.593 23 12.245z\" fill=\"#4285F4\"></path><path d=\"M12.225 23c3.03 0 5.574-.978 7.433-2.665l-3.542-2.688c-.948.648-2.22 1.1-3.891 1.1a6.745 6.745 0 01-6.386-4.572l-.132.011-3.465 2.628-.045.124C4.043 20.531 7.835 23 12.225 23z\" fill=\"#34A853\"></path><path d=\"M5.84 14.175A6.65 6.65 0 015.463 12c0-.758.138-1.491.361-2.175l-.006-.147-3.508-2.67-.115.054A10.831 10.831 0 001 12c0 1.772.436 3.447 1.197 4.938l3.642-2.763z\" fill=\"#FBBC05\"></path><path d=\"M12.225 5.253c2.108 0 3.529.892 4.34 1.638l3.167-3.031C17.787 2.088 15.255 1 12.225 1 7.834 1 4.043 3.469 2.197 7.062l3.63 2.763a6.77 6.77 0 016.398-4.572z\" fill=\"#EB4335\"></path>", "rule": null}, "DeepSeek": {"icon": "deepseek-color", "viewBox": "0 0 24 24", "inner": "<path d=\"M23.748 4.482c-.254-.124-.364.113-.512.234-.051.039-.094.09-.137.136-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.156-.708-.311-.955-.65-.172-.241-.219-.51-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.093.172.187.129.323-.082.28-.18.552-.266.833-.055.179-.137.217-.329.14a5.526 5.526 0 01-1.736-1.18c-.857-.828-1.631-1.742-2.597-2.458a11.365 11.365 0 00-.689-.471c-.985-.957.13-1.743.388-1.836.27-.098.093-.432-.779-.428-.872.004-1.67.295-2.687.684a3.055 3.055 0 01-.465.137 9.597 9.597 0 00-2.883-.102c-1.885.21-3.39 1.102-4.497 2.623C.082 8.606-.231 10.684.152 12.85c.403 2.284 1.569 4.175 3.36 5.653 1.858 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.133-.284 4.994-1.86.47.234.962.327 1.78.397.63.059 1.236-.03 1.705-.128.735-.156.684-.837.419-.961-2.155-1.004-1.682-.595-2.113-.926 1.096-1.296 2.746-2.642 3.392-7.003.05-.347.007-.565 0-.845-.004-.17.035-.237.23-.256a4.173 4.173 0 001.545-.475c1.396-.763 1.96-2.015 2.093-3.517.02-.23-.004-.467-.247-.588zM11.581 18c-2.089-1.642-3.102-2.183-3.52-2.16-.392.024-.321.471-.235.763.09.288.207.486.371.739.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.167-1.361-.802-2.5-1.86-3.301-3.307-.774-1.393-1.224-2.887-1.298-4.482-.02-.386.093-.522.477-.592a4.696 4.696 0 011.529-.039c2.132.312 3.946 1.265 5.468 2.774.868.86 1.525 1.887 2.202 2.891.72 1.066 1.494 2.082 2.48 2.914.348.292.625.514.891.677-.802.09-2.14.11-3.054-.614zm1-6.44a.306.306 0 01.415-.287.302.302 0 01.2.288.306.306 0 01-.31.307.303.303 0 01-.304-.308zm3.11 1.596c-.2.081-.399.151-.59.16a1.245 1.245 0 01-.798-.254c-.274-.23-.47-.358-.552-.758a1.73 1.73 0 01.016-.588c.07-.327-.008-.537-.239-.727-.187-.156-.426-.199-.688-.199a.559.559 0 01-.254-.078c-.11-.054-.2-.19-.114-.358.028-.054.16-.186.192-.21.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.391.451.462.576.685.914.176.265.336.537.445.848.067.195-.019.354-.25.452z\" fill=\"#4D6BFE\"></path>", "rule": null}, "xAI": {"icon": "xai", "tile": "#111111", "shape": "square", "viewBox": "0 0 24 24", "inner": "<path d=\"M6.469 8.776L16.512 23h-4.464L2.005 8.776H6.47zm-.004 7.9l2.233 3.164L6.467 23H2l4.465-6.324zM22 2.582V23h-3.659V7.764L22 2.582zM22 1l-9.952 14.095-2.233-3.163L17.533 1H22z\"></path>", "rule": "evenodd"}, "Z.ai": {"icon": "zai", "tile": "#111111", "shape": "square", "viewBox": "0 0 24 24", "inner": "<path d=\"M12.105 2L9.927 4.953H.653L2.83 2h9.276zM23.254 19.048L21.078 22h-9.242l2.174-2.952h9.244zM24 2L9.264 22H0L14.736 2H24z\"></path>", "rule": "evenodd"}, "Moonshot": {"icon": "kimi", "tile": "#111111", "shape": "square", "viewBox": "0 0 24 24", "inner": "<path d=\"M21.846 0a1.923 1.923 0 110 3.846H20.15a.226.226 0 01-.227-.226V1.923C19.923.861 20.784 0 21.846 0z\"></path><path d=\"M11.065 11.199l7.257-7.2c.137-.136.06-.41-.116-.41H14.3a.164.164 0 00-.117.051l-7.82 7.756c-.122.12-.302.013-.302-.179V3.82c0-.127-.083-.23-.185-.23H3.186c-.103 0-.186.103-.186.23V19.77c0 .128.083.23.186.23h2.69c.103 0 .186-.102.186-.23v-3.25c0-.069.025-.135.069-.178l2.424-2.406a.158.158 0 01.205-.023l6.484 4.772a7.677 7.677 0 003.453 1.283c.108.012.2-.095.2-.23v-3.06c0-.117-.07-.212-.164-.227a5.028 5.028 0 01-2.027-.807l-5.613-4.064c-.117-.078-.132-.279-.028-.381z\"></path>", "rule": "evenodd"}, "StepFun": {"icon": "stepfun", "tile": "#01d9cf", "shape": "circle", "viewBox": "0 0 24 24", "inner": "<path d=\"M12 0C5.372 0 0 5.372 0 12s5.372 12 12 12 12-5.372 12-12S18.628 0 12 0zM8.762 19.614H4.376v-4.386h4.386v4.386zm5.423 0H9.798v-4.386h4.387v4.386zm0-5.42H9.798V9.81h4.387v4.386zm0-5.418H9.798V4.39h4.387v4.386zm5.422-.004h-4.386V4.386h4.386v4.386z\"></path>", "rule": "evenodd"}, "Undisclosed": {"icon": "unionalpha-color", "viewBox": "0 0 24 24", "inner": "<path d=\"M12.5709 13.3706C12.6556 13.4345 12.8442 13.7666 12.9123 13.875L13.4693 14.7624C13.7592 15.2257 14.0526 15.6895 14.3386 16.1555C14.4141 16.2951 14.4587 16.3467 14.3445 16.48C13.9818 16.9035 13.6097 17.321 13.2426 17.7406C12.6047 18.4698 11.5795 19.0999 10.6086 19.2277C10.5721 19.2324 10.5355 19.2366 10.4988 19.2405C10.3741 19.2219 10.2359 19.2226 10.1067 19.2077C9.62828 19.1531 9.13925 18.9833 8.73437 18.7229C8.58284 18.6255 8.20429 18.365 8.13135 18.2015C8.7166 18.0941 8.9971 17.6275 9.36375 17.2093C9.46647 17.0921 9.56558 16.9681 9.66524 16.8481C10.2482 16.1439 10.8249 15.4346 11.3952 14.7202C11.5532 14.5228 12.4352 13.3557 12.5709 13.3706Z\" fill=\"url(#lobe-icons-union-alpha-0-_R_0_)\"></path><path d=\"M23.9999 4.03711C23.9427 4.17731 23.8557 4.29083 23.7726 4.41626C23.5172 4.80162 23.2489 5.18017 22.9952 5.56645C21.7031 7.52279 20.3758 9.45572 19.0141 11.3643L18.2195 12.4575C18.0914 12.6376 17.8772 12.9025 17.8103 13.1017C17.5635 12.8289 17.3373 12.3638 17.1271 12.052C16.7507 11.4939 16.4007 10.8942 16.0072 10.3494C15.964 10.2787 15.9232 10.1649 15.8967 10.0866C15.9509 9.95674 16.2386 9.57362 16.3367 9.43732L17.184 8.26053L19.1886 5.47039C19.3731 5.21667 20.0937 4.17696 20.2819 4.03711H23.9999Z\" fill=\"url(#lobe-icons-union-alpha-1-_R_0_)\"></path><path d=\"M5.67537 4.61919C5.91433 4.59978 6.08153 4.64306 6.2388 4.65534C7.31097 4.73906 7.93546 5.78123 8.52073 6.55699C8.55486 6.60222 8.67307 6.77678 8.67756 6.81818C8.50211 6.78591 8.24062 6.87736 8.10425 6.98766C7.77451 7.25438 7.47306 7.60773 7.16738 7.90822C6.82713 8.24411 6.49119 8.58431 6.15964 8.92879C5.96629 9.12818 5.68162 9.40902 5.50821 9.61426C4.95769 10.264 4.58519 11.0455 4.42712 11.8823C4.38673 12.1047 4.33596 12.4789 4.34474 12.6979C4.38003 13.5788 4.68343 14.4541 5.20029 15.1681C5.44662 15.5083 5.69406 15.7534 5.97744 16.05C6.42647 16.5145 6.87971 16.9749 7.33712 17.4311C8.17604 18.2704 8.83084 19.0614 10.1068 19.2072C10.2359 19.2221 10.3741 19.2214 10.4989 19.24C10.4563 19.2438 10.4156 19.2437 10.3732 19.2456C9.63946 19.2779 8.9074 19.2593 8.17299 19.2571L6.81265 19.2561C6.34052 19.2551 5.82434 19.2555 5.36063 19.1766C4.33929 19.003 3.55816 18.5177 2.78058 17.8624C1.69732 16.9495 0.760791 15.9389 0.316835 14.5629C0.188539 14.1652 0.0845513 13.7688 0.0423572 13.352C0.0341296 13.2704 0.025306 13.1714 0 13.0938V12.1601C0.024482 12.0989 0.0539558 11.7751 0.0701206 11.682C0.118265 11.3996 0.185469 11.1208 0.271272 10.8475C0.464403 10.234 0.818387 9.53555 1.19037 9.01281C1.67633 8.32991 2.33983 7.69834 2.92227 7.09354L3.99839 5.99473C4.54749 5.44174 4.97245 4.98537 5.67537 4.61919Z\" fill=\"url(#lobe-icons-union-alpha-2-_R_0_)\"></path><path d=\"M16.0072 10.3494C16.4008 10.8942 16.7508 11.4939 17.1271 12.052C17.3373 12.3638 17.5635 12.8289 17.8104 13.1017C17.8351 13.1633 18.024 13.4562 18.0701 13.5307L18.6905 14.5371C19.1466 15.2881 19.6091 16.0351 20.078 16.7781C20.4399 17.3561 20.7699 17.9692 21.2574 18.4512C21.5622 18.7524 21.9167 18.9416 22.3073 19.1101C22.4041 19.1518 22.5241 19.1723 22.6131 19.2159L22.5999 19.2374C22.543 19.2593 22.4118 19.2355 22.3393 19.2386C21.4806 19.2765 20.6139 19.2542 19.7541 19.2467C19.2053 19.2419 18.6361 19.2653 18.0899 19.2461C17.9536 19.241 17.8182 19.2222 17.6855 19.1901C17.2306 19.0825 16.8145 18.8188 16.4914 18.4847C16.2155 18.1993 16.0406 17.8931 15.8347 17.558C15.6277 17.2199 15.423 16.8802 15.2208 16.5391L13.5134 13.7217C13.602 13.5224 14.0393 12.9594 14.2007 12.7419L16.0072 10.3494Z\" fill=\"url(#lobe-icons-union-alpha-3-_R_0_)\"></path><path d=\"M11.3662 4.03706C11.4355 4.04736 11.5279 4.0639 11.5825 4.11302C11.7409 4.25538 11.8717 4.45147 12.0009 4.62253C13.1498 6.14388 14.2121 7.73081 15.2749 9.31286C15.3244 9.38658 15.4528 9.56569 15.4748 9.646C15.3946 9.79571 15.0698 10.1847 14.9522 10.3329L13.8456 11.7243C13.647 11.9762 13.455 12.2345 13.2586 12.4878C13.1566 12.6194 13.0064 12.8305 12.8889 12.9425C12.6125 12.5563 12.3581 12.1531 12.0887 11.7623L9.66701 8.22137C9.43592 7.88192 9.20191 7.54448 8.96502 7.20905C8.92518 7.15337 8.69584 6.86111 8.67758 6.81865C8.67307 6.77723 8.55489 6.60269 8.52077 6.55747C7.9355 5.7817 7.311 4.73956 6.23883 4.65583C6.08162 4.64356 5.91434 4.61968 5.67542 4.61968C6.15935 4.35771 6.84659 4.17302 7.38673 4.09926C8.69114 3.92117 10.0523 4.03706 11.3662 4.03706Z\" fill=\"url(#lobe-icons-union-alpha-4-_R_0_)\"></path><path d=\"M15.3619 8.08232L15.874 8.87602L19.2024 4.16504L15.3619 8.08232Z\" fill=\"url(#lobe-icons-union-alpha-5-_R_0_)\"></path><defs><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-union-alpha-0-_R_0_\" x1=\"21.5578\" x2=\"21.5578\" y1=\"4.03711\" y2=\"12.691\"><stop stop-color=\"currentColor\" stop-opacity=\"0.39\"></stop><stop offset=\"1\" stop-color=\"currentColor\" stop-opacity=\"0.22\"></stop></linearGradient><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-union-alpha-1-_R_0_\" x1=\"21.5578\" x2=\"21.5578\" y1=\"4.03711\" y2=\"12.691\"><stop stop-color=\"currentColor\" stop-opacity=\"0.39\"></stop><stop offset=\"1\" stop-color=\"currentColor\" stop-opacity=\"0.22\"></stop></linearGradient><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-union-alpha-2-_R_0_\" x1=\"5.27425\" x2=\"5.24944\" y1=\"5.41908\" y2=\"14.0217\"><stop stop-color=\"currentColor\" stop-opacity=\"0.15\"></stop><stop offset=\"1\" stop-color=\"currentColor\" stop-opacity=\"0.87\"></stop></linearGradient><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-union-alpha-3-_R_0_\" x1=\"14.1443\" x2=\"14.1443\" y1=\"14.4319\" y2=\"19.26\"><stop stop-color=\"currentColor\" stop-opacity=\"0.93\"></stop><stop offset=\"1\" stop-color=\"currentColor\" stop-opacity=\"0.57\"></stop></linearGradient><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-union-alpha-4-_R_0_\" x1=\"14.1443\" x2=\"14.1443\" y1=\"14.4319\" y2=\"19.26\"><stop stop-color=\"currentColor\" stop-opacity=\"0.93\"></stop><stop offset=\"1\" stop-color=\"currentColor\" stop-opacity=\"0.57\"></stop></linearGradient><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-union-alpha-5-_R_0_\" x1=\"17.2822\" x2=\"17.2822\" y1=\"4.16504\" y2=\"8.87602\"><stop stop-color=\"#D72725\"></stop><stop offset=\"1\" stop-color=\"#CD2920\"></stop></linearGradient></defs>", "rule": null}, "Cognition": {"icon": "devin-color", "viewBox": "0 0 24 24", "inner": "<path d=\"M2.033 9.867l2.554 1.483a.589.589 0 00.592 0l2.554-1.483.01-.008a.608.608 0 00.11-.084l.013-.015a.631.631 0 00.076-.1c.003-.005.008-.01.01-.016a.558.558 0 00.052-.125l.007-.028a.611.611 0 00.019-.14V7.868c0-.572.307-1.105.8-1.392a1.595 1.595 0 011.598 0l1.277.742a.54.54 0 00.129.053l.028.01c.044.01.088.015.133.016h.006l.013-.002a.587.587 0 00.27-.074l.011-.004 2.554-1.483a.596.596 0 00.297-.516V2.253a.595.595 0 00-.297-.516L12.293.257a.587.587 0 00-.591 0L9.148 1.737l-.01.01a.609.609 0 00-.109.083l-.014.015a.632.632 0 00-.076.1c-.003.005-.008.01-.01.016a.57.57 0 00-.052.124l-.007.028a.612.612 0 00-.018.14v1.483c0 .572-.307 1.105-.8 1.393a1.597 1.597 0 01-1.599 0l-1.276-.742a.603.603 0 00-.13-.053l-.028-.008a.658.658 0 00-.133-.018h-.02a.57.57 0 00-.269.074c-.003.002-.008.002-.012.005L2.033 5.872a.596.596 0 00-.297.515v2.966c0 .213.113.41.297.515z\" fill=\"#3969CA\"></path><path d=\"M15.943 10.607a1.596 1.596 0 011.599 0l1.276.74c.041.025.085.04.13.055l.028.008c.043.01.088.016.133.018h.005c.005 0 .01-.002.014-.003a.474.474 0 00.122-.016l.021-.005a.616.616 0 00.126-.052c.004-.002.009-.002.013-.005l2.554-1.482a.597.597 0 00.297-.516V6.383a.596.596 0 00-.297-.515l-2.552-1.483a.587.587 0 00-.592 0l-2.553 1.482-.011.008a.61.61 0 00-.108.084l-.014.016a.637.637 0 00-.076.1c-.003.005-.008.01-.01.016a.57.57 0 00-.052.124l-.007.029a.612.612 0 00-.018.14v1.482c0 .572-.307 1.105-.8 1.393a1.597 1.597 0 01-1.599 0l-1.276-.742a.584.584 0 00-.13-.053l-.028-.008a.62.62 0 00-.133-.018h-.02a.587.587 0 00-.269.074l-.012.004L9.15 10a.596.596 0 00-.296.516v2.966c0 .212.112.409.296.515l2.554 1.483s.008.002.012.005c.04.022.082.04.126.052l.02.004a.57.57 0 00.123.017l.014.002h.006c.054 0 .108-.01.16-.025a.587.587 0 00.13-.054l1.277-.741a1.597 1.597 0 012.398 1.392v1.482c0 .049.007.095.019.14l.007.028a.619.619 0 00.051.125c.004.006.008.01.01.016a.6.6 0 00.076.1l.014.015c.033.032.069.06.108.084.004.002.006.006.011.008l2.554 1.483a.59.59 0 00.593 0l2.554-1.483a.597.597 0 00.296-.516v-2.965a.595.595 0 00-.296-.516l-2.554-1.483s-.008-.002-.012-.005a.54.54 0 00-.126-.051c-.007-.003-.013-.003-.02-.005a.635.635 0 00-.125-.017h-.018a.557.557 0 00-.16.026.588.588 0 00-.13.053l-1.276.742a1.595 1.595 0 01-1.598 0 1.615 1.615 0 010-2.785l-.005-.001z\" fill=\"#21C19A\"></path><path d=\"M14.848 18.265l-2.554-1.482-.012-.005a.526.526 0 00-.126-.052c-.007-.002-.014-.002-.02-.005a.64.64 0 00-.124-.017h-.02a.56.56 0 00-.16.026.588.588 0 00-.13.053l-1.276.742a1.594 1.594 0 01-1.598 0c-.493-.286-.8-.82-.8-1.393V14.65a.563.563 0 00-.018-.14l-.008-.028a.604.604 0 00-.051-.124l-.01-.017a.603.603 0 00-.076-.1l-.014-.015a.596.596 0 00-.109-.084c-.003-.002-.005-.006-.01-.008L5.178 12.65a.587.587 0 00-.591 0l-2.554 1.483a.596.596 0 00-.297.516v2.965c0 .213.113.41.297.516l2.554 1.483.012.004a.618.618 0 00.267.074l.016.002h.007a.55.55 0 00.16-.026.584.584 0 00.129-.053l1.277-.742a1.597 1.597 0 012.398 1.393v1.482c0 .05.007.095.019.14l.007.028c.013.044.03.085.051.125l.01.016c.022.036.047.07.076.1l.014.015c.032.032.069.06.109.084l.01.008 2.554 1.483a.587.587 0 00.593 0l2.554-1.483a.596.596 0 00.296-.515v-2.966a.596.596 0 00-.296-.516h-.002z\" fill=\"#0294DE\"></path>", "rule": null}, "Fireworks": {"icon": "fireworks-color", "viewBox": "0 0 24 24", "inner": "<path clip-rule=\"evenodd\" d=\"M14.8 5l-2.801 6.795L9.195 5H7.397l3.072 7.428a1.64 1.64 0 003.038.002L16.598 5H14.8zm1.196 10.352l5.124-5.244-.699-1.669-5.596 5.739a1.664 1.664 0 00-.343 1.807 1.642 1.642 0 001.516 1.012L16 17l8-.02-.699-1.669-7.303.041h-.002zM2.88 10.104l.699-1.669 5.596 5.739c.468.479.603 1.189.343 1.807a1.643 1.643 0 01-1.516 1.012l-8-.018-.002.002.699-1.669 7.303.042-5.122-5.246z\" fill=\"#5019C5\" fill-rule=\"evenodd\"></path>", "rule": null}, "Stealth": {"wordmark": ["STEALTH"]}, "Thinking Machines": {"wordmark": ["THINKING", "MACHINES"]}, "Alibaba": {"wordmark": ["QWEN"]}};
 
23
  nameTol: 12, // splits this close to the most balanced count as ties
24
  };
25
 
26
+ let current=null;
27
  function el(tag, attrs, parent) {
28
  const e = document.createElementNS(NS, tag);
29
  for (const k in attrs) e.setAttribute(k, attrs[k]);
30
+ (parent || current || svg).appendChild(e);
31
  return e;
32
  }
33
  const ctx = document.createElement("canvas").getContext("2d");
 
89
  const cx = G.left + (i + 0.5) * pitch, x0 = cx - bwid / 2, x1 = cx + bwid / 2;
90
  const top = y(d.score * 100), r = Math.min(G.radius, bwid / 2);
91
  pos[d.name] = {cx, top, x0, x1};
92
+ current=el('g',{'class':'bar-node'},svg);
93
+ el('rect',{x:G.left+i*pitch,y:G.top,width:pitch,height:H-G.top,fill:'transparent','class':'bar-hit'});
94
+ bindChartTooltip(current,svg,d.name,key,'.bar');
95
+ const bar = el("path", {class:"bar", d: `M${x0},${G.base} V${top + r} Q${x0},${top} ${x0 + r},${top} H${x1 - r} ` +
96
  `Q${x1},${top} ${x1},${top + r} V${G.base} Z`, fill: d.colour});
97
+
98
  const v = el("text", {x: cx, y: (top + G.base) / 2 + 5.4, "text-anchor": "middle",
99
  "font-family": MONO, "font-weight": 500, "font-size": 15.5, fill: d.ink});
100
  v.textContent = d.label;
 
140
  });
141
 
142
 
143
+ current=null;svg.dataset.ready='true';
144
  }
145
  })();
assets/leaderboard-controls.js ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ const input=document.getElementById('model-search'),tables=[...document.querySelectorAll('table.board')];
2
+ function filter(){let shown=0;for(const table of tables){let rank=0;for(const row of table.tBodies[0].rows){row.hidden=!row.dataset.search.includes(input.value.trim().toLowerCase());if(!row.hidden)row.cells[0].textContent=++rank;}shown=rank;}document.getElementById('ranking-count').textContent=shown+' of 14 configurations';}
3
+ input.addEventListener('input',filter);tables.forEach(t=>t.querySelectorAll('th[data-k]').forEach(th=>th.addEventListener('click',filter)));
assets/pareto.js CHANGED
@@ -1,3 +1,4 @@
 
1
  // Adapted from BuildingBench's figure-kit/pareto-frontier/render.py and live SVG.
2
  // Domain, costs and scores are exclusively Code4Scene's historical paper evaluation.
3
  const NS='http://www.w3.org/2000/svg';
@@ -35,10 +36,7 @@ for(const svg of document.querySelectorAll('.pareto-svg')){
35
  g.append(node('rect',{x:cx-5,y:cy-5,width:10,height:10,rx:1,fill:color,stroke:'#fffefb','stroke-width':1.7,class:'chip'}));
36
  g.append(node('text',{x:cx+best.dx,y:cy+best.dy,'text-anchor':best.anchor,fill:label,'font-size':font,'font-weight':isFront?700:400,class:'model-label'},name));
37
  g.append(node('circle',{cx,cy,r:14,fill:'transparent'}));
38
- const tip=document.querySelector('#pareto-tooltip')||Object.assign(document.body.appendChild(document.createElement('div')),{id:'pareto-tooltip',className:'pareto-tooltip'});
39
- const show=()=>{tip.replaceChildren();const title=document.createElement('strong');title.textContent=d.name;tip.append(title);for(const text of [`Score: ${d.score.toFixed(6)}`,`Mean cost / case: $${d.cost.toFixed(6)}`,isFront?'Pareto frontier':'Dominated configuration']){const p=document.createElement('div');p.textContent=text;tip.append(p);}const rect=g.querySelector('.chip').getBoundingClientRect();tip.classList.add('on');tip.style.left=Math.max(8,Math.min(innerWidth-tip.offsetWidth-8,rect.x+rect.width/2-tip.offsetWidth/2))+'px';tip.style.top=(rect.y<tip.offsetHeight+16?rect.bottom+12:rect.y-tip.offsetHeight-12)+'px';svg.querySelectorAll('.pareto-node').forEach(n=>n.classList.toggle('dim',n!==g));};
40
- const hide=()=>{tip.classList.remove('on');svg.querySelectorAll('.pareto-node').forEach(n=>n.classList.remove('dim'));};
41
- g.addEventListener('mouseenter',show);g.addEventListener('focus',show);g.addEventListener('click',show);g.addEventListener('mouseleave',hide);g.addEventListener('blur',hide);window.addEventListener('scroll',hide,{passive:true});
42
  }
43
  svg.dataset.ready='true';
44
  }
 
1
+ import {bindChartTooltip} from "./chart-interactions.js?v=20261001c";
2
  // Adapted from BuildingBench's figure-kit/pareto-frontier/render.py and live SVG.
3
  // Domain, costs and scores are exclusively Code4Scene's historical paper evaluation.
4
  const NS='http://www.w3.org/2000/svg';
 
36
  g.append(node('rect',{x:cx-5,y:cy-5,width:10,height:10,rx:1,fill:color,stroke:'#fffefb','stroke-width':1.7,class:'chip'}));
37
  g.append(node('text',{x:cx+best.dx,y:cy+best.dy,'text-anchor':best.anchor,fill:label,'font-size':font,'font-weight':isFront?700:400,class:'model-label'},name));
38
  g.append(node('circle',{cx,cy,r:14,fill:'transparent'}));
39
+ bindChartTooltip(g,svg,d.key,svg.dataset.mode,'.chip');
 
 
 
40
  }
41
  svg.dataset.ready='true';
42
  }
assets/scene-assets.js ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // A bounded, reference-counted queue. A shared scene has one job regardless of how many cards display it.
2
+ export class AssetQueue {
3
+ constructor({load,dispose,maxConcurrent=2,maxIdle=1,maxBytes=128*1024*1024,onChange=()=>{}}){Object.assign(this,{load,dispose,maxConcurrent,maxIdle,maxBytes,onChange});this.entries=new Map();this.running=0;this.peakRunning=0;}
4
+ retain(key,listener,priority=()=>0){
5
+ let e=this.entries.get(key);
6
+ if(!e||e.state==='error'||e.state==='cancelled'){
7
+ e={key,users:new Set(),state:'queued',asset:null,controller:new AbortController(),last:Date.now(),bytes:0};this.entries.set(key,e);
8
+ }
9
+ const user={listener,priority};e.users.add(user);e.last=Date.now();queueMicrotask(()=>{if(e.users.has(user))listener(e);this.pump();});this.changed();
10
+ let released=false;
11
+ return {entry:e,release:()=>{if(released)return;released=true;e.users.delete(user);e.last=Date.now();if(!e.users.size&&!e.asset){e.state='cancelled';e.controller.abort();if(this.entries.get(key)===e)this.entries.delete(key);}this.evict();this.pump();this.changed();}};
12
+ }
13
+ notify(e,state,detail={}){if(e.controller.signal.aborted)return;Object.assign(e,detail,{state});for(const u of e.users)u.listener(e);this.changed();}
14
+ pump(){
15
+ while(this.running<this.maxConcurrent){const queued=[...this.entries.values()].filter(e=>e.state==='queued'&&e.users.size).sort((a,b)=>Math.min(...[...a.users].map(u=>u.priority()))-Math.min(...[...b.users].map(u=>u.priority())));if(!queued.length)break;const e=queued[0];e.state='loading';this.running++;this.peakRunning=Math.max(this.peakRunning,this.running);this.run(e);}
16
+ }
17
+ async run(e){
18
+ try{
19
+ let asset;
20
+ for(let attempt=0;attempt<2;attempt++){
21
+ try{asset=await this.load(e.key,e.controller.signal,(state,detail)=>this.notify(e,state,detail));break;}
22
+ catch(error){if(e.controller.signal.aborted)throw error;if(attempt===1)throw error;this.notify(e,'retrying');await new Promise(r=>setTimeout(r,800));}
23
+ }
24
+ if(e.controller.signal.aborted||!e.users.size){this.dispose(asset);return;}
25
+ e.asset=asset;e.bytes=asset.bytes||0;this.notify(e,'ready');
26
+ }catch(error){if(!e.controller.signal.aborted)this.notify(e,'error',{error});}
27
+ finally{this.running--;this.evict();this.pump();this.changed();}
28
+ }
29
+ evict(){
30
+ const idle=[...this.entries.values()].filter(e=>!e.users.size&&e.asset).sort((a,b)=>a.last-b.last);let total=[...this.entries.values()].reduce((n,e)=>n+e.bytes,0);
31
+ while(idle.length&&(idle.length>this.maxIdle||total>this.maxBytes)){const e=idle.shift();total-=e.bytes;this.dispose(e.asset);e.asset=null;if(this.entries.get(e.key)===e)this.entries.delete(e.key);}
32
+ }
33
+ changed(){this.onChange({running:this.running,peak:this.peakRunning,queued:[...this.entries.values()].filter(e=>e.state==='queued').length,cached:[...this.entries.values()].filter(e=>e.asset).length,bytes:[...this.entries.values()].reduce((n,e)=>n+e.bytes,0)});}
34
+ }
35
+
36
+ // A stalled body must not leave a loading card forever. Idle and total limits cover headers and streamed bytes.
37
+ export async function fetchSceneBytes(url,signal,progress,{idleMs=20000,totalMs=90000,fetcher=fetch}={}){
38
+ const abort=new AbortController();let idle,total,reason='';
39
+ const stop=()=>abort.abort();signal.addEventListener('abort',stop,{once:true});if(signal.aborted)stop();
40
+ const reset=()=>{clearTimeout(idle);idle=setTimeout(()=>{reason='The scene download stopped responding.';abort.abort();},idleMs);};
41
+ reset();total=setTimeout(()=>{reason='The scene download took too long.';abort.abort();},totalMs);
42
+ try{
43
+ const response=await fetcher(url,{signal:abort.signal});if(!response.ok)throw new Error('Scene request failed (HTTP '+response.status+').');
44
+ const size=Number(response.headers.get('content-length'))||0,reader=response.body.getReader(),chunks=[];let received=0,last=0;
45
+ for(;;){const {done,value}=await reader.read();if(done)break;reset();chunks.push(value);received+=value.length;if(Date.now()-last>120){progress({received,total:size});last=Date.now();}}
46
+ if(!received||size&&received!==size)throw new Error('The scene download was incomplete.');
47
+ progress({received,total:size});const bytes=new Uint8Array(received);let at=0;for(const c of chunks){bytes.set(c,at);at+=c.length;}return bytes;
48
+ }catch(error){if(reason)throw new Error(reason);throw error;}
49
+ finally{clearTimeout(idle);clearTimeout(total);signal.removeEventListener('abort',stop);}
50
+ }
assets/scene-cards.js CHANGED
@@ -1,4 +1,5 @@
1
  import * as THREE from "three";
 
2
  import {GLTFLoader} from "three/addons/loaders/GLTFLoader.js";
3
  import {MeshoptDecoder} from "three/addons/libs/meshopt_decoder.module.js";
4
  import {Sky} from "three/addons/objects/Sky.js";
@@ -9,9 +10,7 @@ import {Sky} from "three/addons/objects/Sky.js";
9
  // procedural viewer had (rotationX / rotationY / zoom / paused / group /
10
  // draw(dt) / destroy()), so the page code above it did not have to change.
11
  //
12
- // Every mesh drawn here is the building.glb an agent handed in to the
13
- // benchmark, re-encoded for the page (textures at most 512 px, JPEG for
14
- // opaque maps) and gzipped. Geometry is untouched.
15
  (function () {
16
  const ADD = {GLTFLoader};
17
  const activeViewers = new Set();
@@ -19,20 +18,40 @@ import {Sky} from "three/addons/objects/Sky.js";
19
  let lastFrame = performance.now();
20
 
21
  /* ------------------------------------------------------------ renderer */
22
- let gl = null, ENV = null;
23
  function renderer() {
24
  if (gl) return gl;
25
  gl = new THREE.WebGLRenderer({ antialias: true, alpha: true, premultipliedAlpha: true, powerPreference: "high-performance" });
26
  gl.setPixelRatio(1);
 
 
 
 
 
 
 
 
 
 
27
  gl.outputColorSpace = THREE.SRGBColorSpace;
28
  gl.toneMapping = THREE.ACESFilmicToneMapping; gl.toneMappingExposure = 1.0;
29
  gl.shadowMap.enabled = true;
30
  gl.shadowMap.type = THREE.PCFSoftShadowMap;
31
  gl.setClearColor(0x000000, 0);
32
- const sky=new Sky();sky.scale.setScalar(1000);const u=sky.material.uniforms;u.turbidity.value=4;u.rayleigh.value=1.4;u.mieCoefficient.value=.004;u.mieDirectionalG.value=.8;u.sunPosition.value.setFromSphericalCoords(1,THREE.MathUtils.degToRad(52),THREE.MathUtils.degToRad(215));const skyScene=new THREE.Scene();skyScene.add(sky);ENV=new THREE.PMREMGenerator(gl).fromScene(skyScene,0,.1,2000).texture;
33
  return gl;
34
  }
35
 
 
 
 
 
 
 
 
 
 
 
36
  // The benchmark's own light rig (city_bench.building_light/1), the numbers
37
  // the board's renders use: sun in the south-east at 50 degrees, a pale sky,
38
  // and a muted environment. One rig for the page, moved into whichever scene
@@ -68,30 +87,42 @@ import {Sky} from "three/addons/objects/Sky.js";
68
  asset.scene.add(RIG_GROUP);
69
  }
70
 
71
- /* -------------------------------------------------------------- assets */
72
- // BB_ASSETS maps a key to either a gzipped-base64 glb (the self-contained
73
- // page) or an assets/… path (the split copy for hosting). Same bytes, one
74
- // fetch earlier.
75
- const ASSETS = window.BB_ASSETS || {};
76
- const cache = new Map(); // key -> {promise, asset, refs, last}
77
- const loader = new ADD.GLTFLoader().setMeshoptDecoder(MeshoptDecoder);
78
- const gunzip = buf => new Response(new Blob([buf]).stream().pipeThrough(new DecompressionStream("gzip"))).arrayBuffer();
79
- const PACK_KEY = Uint8Array.from("5c2f9e71d3a84b06e1f7c29a38d05b64a7193ce8f2046db95e81c73a2df6904b".match(/../g), h => parseInt(h,16));
80
- async function bytesFor(key) {
81
- const r = await fetch(key); if (!r.ok) throw new Error("HTTP " + r.status);
82
- const a = new Uint8Array(await r.arrayBuffer());
83
- for (let i=0;i<a.length;i++) a[i] ^= PACK_KEY[i&31] ^ (((i>>>5)*131)&255);
84
- return a.buffer;
 
 
 
 
 
 
 
 
85
  }
86
- function parse(buf) { return new Promise((resolve, reject) => loader.parse(buf, "", resolve, reject)); }
87
- function acquire(key) {
88
- let entry = cache.get(key);
89
- if (!entry) {
90
- entry = { refs: 0, last: performance.now(), asset: null };
91
- // A dropped connection is not a bad file: one retry, and a failure leaves
92
- // the cache so the next mount can try again.
93
- const attempt = () => bytesFor(key).then(parse);
94
- entry.promise = attempt().catch(() => new Promise(r => setTimeout(r, 1500)).then(attempt)).then(gltf => {
 
 
 
 
95
  const root = gltf.scene;
96
  root.traverse(node => { if (node.isMesh) { node.castShadow = true; node.receiveShadow = true; } });
97
  const box = new THREE.Box3(), pts=[];
@@ -108,38 +139,16 @@ import {Sky} from "three/addons/objects/Sky.js";
108
  scene.background = new THREE.Color(0xe6edf0); scene.add(root);
109
  const task=window.SITE.cases.find(c=>c.track==='i2s'&&(c.input_glb===key||c.gt_glb===key||c.agents.some(a=>a.glb===key)));
110
  if(task){root.updateMatrixWorld(true);root.traverse(o=>{const duplicate=(task.duplicates||[]).includes(o.name);if(!duplicate&&!(task.targets||[]).includes(o.name))return;const b=new THREE.Box3().setFromObject(o);if(b.isEmpty())return;const h=new THREE.Box3Helper(b.expandByScalar(.08),duplicate?0xff6b5e:0x5ee08a);h.material.depthTest=false;h.material.transparent=true;h.renderOrder=999;scene.add(h);});}
111
- entry.asset = { key, root, scene, box, centre, corners, radius: Math.max(size.length() / 2, 1), floor: box.min.y };
112
- return entry.asset;
113
- });
114
- entry.promise.catch(() => { if (cache.get(key) === entry) cache.delete(key); });
115
- cache.set(key, entry);
116
  }
117
- entry.refs++; entry.last = performance.now();
118
- return entry;
119
- }
120
- function release(entry) { if (!entry) return; entry.refs = Math.max(0, entry.refs - 1); entry.last = performance.now(); evict(); }
121
- const KEEP = 40;
122
- function evict() {
123
- const idle = [...cache.values()].filter(e => e.refs === 0 && e.asset);
124
- if (cache.size <= KEEP) return;
125
- idle.sort((a, b) => a.last - b.last);
126
- for (const e of idle) {
127
- if (cache.size <= KEEP) break;
128
- e.asset.root.traverse(n => {
129
- if (!n.isMesh) return;
130
- n.geometry?.dispose();
131
- for (const m of [].concat(n.material || [])) { for (const s of ["map", "normalMap", "roughnessMap", "metalnessMap", "emissiveMap", "aoMap", "alphaMap"]) m[s]?.dispose(); m.dispose(); }
132
- });
133
- cache.delete(e.asset.key);
134
- }
135
- }
136
 
137
  /* -------------------------------------------------------------- viewer */
138
  const clamp = (v, a, b) => Math.min(b, Math.max(a, v));
139
  const reduced = () => window.matchMedia("(prefers-reduced-motion: reduce)").matches;
140
  class Viewer {
141
  constructor(canvas, options = {}) {
142
- this.canvas = canvas;
143
  this.ctx = canvas.getContext("2d", { alpha: true });
144
  this.rotationY = options.rotationY ?? -0.65;
145
  this.rotationX = options.rotationX ?? 0.35;
@@ -154,30 +163,50 @@ import {Sky} from "three/addons/objects/Sky.js";
154
  this.entry = null; this.asset = null;
155
  this.bind();
156
  activeViewers.add(this);
157
- if (options.assetKey) this.load(options.assetKey);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  }
159
- load(key) {
160
- release(this.entry);
161
- this.entry = acquire(key); this.asset = null; this.failed = null;
162
- const entry = this.entry;
163
- entry.promise.then(asset => { if (this.entry === entry && !this.destroyed) { this.asset = asset; this.hasDrawn = false; } },
164
- err => { if (this.entry === entry) { this.failed = err; console.error("Code4Scene: submission failed to load", key, err); } });
165
- return entry.promise;
166
  }
167
  bind() {
168
  this.onDown = e => { this.paused = true; this.dragging = true; this.lastPointer = [e.clientX, e.clientY]; this.canvas.setPointerCapture?.(e.pointerId); };
169
- this.onMove = e => { if (!this.dragging) return; const dx = e.clientX - this.lastPointer[0], dy = e.clientY - this.lastPointer[1]; this.rotationY += dx * .012; this.rotationX = clamp(this.rotationX + dy * .008, -.05, 1.3); this.lastPointer = [e.clientX, e.clientY]; if (this.group) { this.group.rotationX = this.rotationX; this.group.rotationY = this.rotationY; } };
170
  this.onUp = () => { this.dragging = false; this.lastPointer = null; };
171
- this.onWheel = e => { e.preventDefault(); this.zoom = clamp(this.zoom - e.deltaY * .0007, .6, 2.2); if (this.group) this.group.zoom = this.zoom; };
172
- this.onKey = e => { const keys = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "+", "=", "-"]; if (!keys.includes(e.key)) return; e.preventDefault(); this.paused = true; if (e.key === "ArrowLeft") this.rotationY -= .12; if (e.key === "ArrowRight") this.rotationY += .12; if (e.key === "ArrowUp") this.rotationX = clamp(this.rotationX + .1, -.05, 1.3); if (e.key === "ArrowDown") this.rotationX = clamp(this.rotationX - .1, -.05, 1.3); if (e.key === "+" || e.key === "=") this.zoom = clamp(this.zoom + .08, .6, 2.2); if (e.key === "-") this.zoom = clamp(this.zoom - .08, .6, 2.2); if (this.group) Object.assign(this.group, { rotationX: this.rotationX, rotationY: this.rotationY, zoom: this.zoom, paused: true }); };
173
  this.canvas.addEventListener("wheel", this.onWheel, { passive: false }); this.canvas.addEventListener("keydown", this.onKey);
174
  this.canvas.addEventListener("pointerdown", this.onDown); this.canvas.addEventListener("pointermove", this.onMove); this.canvas.addEventListener("pointerup", this.onUp); this.canvas.addEventListener("pointercancel", this.onUp);
175
  }
176
  resize() {
177
  const rect = this.canvas.getBoundingClientRect();
178
- const dpr = Math.min(window.devicePixelRatio || 1, 2);
179
  const w = Math.max(1, Math.round(rect.width * dpr)), h = Math.max(1, Math.round(rect.height * dpr));
180
- if (this.canvas.width !== w || this.canvas.height !== h) { this.canvas.width = w; this.canvas.height = h; }
181
  this.w = rect.width; this.h = rect.height; this.dpr = dpr;
182
  }
183
  // Orbit the model's centre. The distance is fitted to the bounding box
@@ -210,11 +239,12 @@ import {Sky} from "three/addons/objects/Sky.js";
210
  cam.up.set(0, 1, 0); cam.lookAt(target); cam.updateProjectionMatrix();
211
  }
212
  draw(dt) {
213
- if (this.destroyed || !this.canvas.isConnected) return;
214
  const rect = this.canvas.getBoundingClientRect();
215
  if (rect.width < 2 || rect.height < 2 || document.hidden) return;
216
  if (rect.bottom < 0 || rect.top > window.innerHeight) return;
217
  this.resize();
 
218
  if (this.group) { this.rotationX = this.group.rotationX; this.rotationY = this.group.rotationY; this.zoom = this.group.zoom; }
219
  if (!this.group && !this.paused && !this.dragging && !reduced()) this.rotationY += this.speed * dt;
220
  const ctx = this.ctx, W = this.canvas.width, H = this.canvas.height;
@@ -225,23 +255,23 @@ import {Sky} from "three/addons/objects/Sky.js";
225
  return;
226
  }
227
  const g = renderer();
228
- g.setSize(W, H, false);
229
  this.aim();
230
  rigFor(this.asset);
231
  g.render(this.asset.scene, this.camera);
232
  ctx.clearRect(0, 0, W, H);
233
  ctx.drawImage(g.domElement, 0, 0, W, H, 0, 0, W, H);
234
- this.hasDrawn = true; this.canvas.dataset.rendered="true"; this.canvas.parentElement.querySelector(".scene-loading")?.remove();
235
  }
236
  destroy() {
237
  this.destroyed = true; activeViewers.delete(this);
238
- release(this.entry); this.entry = null; this.asset = null;
239
  this.canvas.removeEventListener("pointerdown", this.onDown); this.canvas.removeEventListener("pointermove", this.onMove); this.canvas.removeEventListener("pointerup", this.onUp); this.canvas.removeEventListener("pointercancel", this.onUp); this.canvas.removeEventListener("wheel", this.onWheel); this.canvas.removeEventListener("keydown", this.onKey);
240
  }
241
  }
242
  window.GLBViewer = Viewer;
243
  window.destroyViewersWithin = root => { activeViewers.forEach(v => { if (root.contains(v.canvas)) v.destroy(); }); };
244
- window.BB_ENGINE = { cache, renderer, preload: key => acquire(key).promise.then(a => (release(cache.get(key)), a)) };
245
 
246
  /* ------------------------------------------------------------- the clock */
247
  function loop(now) {
@@ -250,27 +280,26 @@ import {Sky} from "three/addons/objects/Sky.js";
250
  const dt = Math.min(.05, (now - lastFrame) / 1000); lastFrame = now;
251
  const groups = new Set([...activeViewers].filter(v => v.group && !v.destroyed).map(v => v.group));
252
  if (!document.hidden && !reduced()) groups.forEach(g => { if (!g.paused && ![...activeViewers].some(v => v.group === g && v.dragging)) g.rotationY += dt * .14; });
253
- activeViewers.forEach(v => { try { v.draw(dt); } catch (err) { v.failed = err; v.asset = null; console.error('Code4Scene: viewer draw failed', err); } });
254
  }
255
  requestAnimationFrame(loop);
256
  })();
257
 
258
 
259
- // Mount only near the viewport; repeated appearances share one decoded asset and WebGL renderer.
260
- const observer=new IntersectionObserver(entries=>entries.forEach(entry=>{
261
- if(!entry.isIntersecting)return;observer.unobserve(entry.target);
262
- const el=entry.target,c=window.SITE.cases.find(c=>c.id===el.dataset.case),a=c.agents.find(a=>a.key===el.dataset.agent);
263
- const viewer=new window.GLBViewer(el.querySelector('canvas'),{assetKey:a.glb,refCam:c.ref_cam,rotationX:.55,rotationY:-.62,speed:.1});
264
- const loading=el.querySelector('.scene-loading');viewer.entry.promise.catch(()=>{if(loading)loading.textContent='Scene unavailable — open the case to retry.';});
265
- const pause=el.querySelector('.scene-motion');if(c.ref_cam){pause.textContent='▶';pause.setAttribute('aria-label','Resume scene rotation');}
266
- pause.addEventListener('click',()=>{viewer.paused=!viewer.paused;pause.textContent=viewer.paused?'▶':'Ⅱ';pause.setAttribute('aria-label',viewer.paused?'Resume scene rotation':'Pause scene rotation');});
267
- el.querySelector('canvas').addEventListener('pointerdown',()=>{pause.textContent='▶';pause.setAttribute('aria-label','Resume scene rotation');});
268
- el.parentElement.querySelectorAll('.scene-versions button').forEach(b=>b.addEventListener('click',()=>{
269
- const url=b.dataset.state==='input'?c.input_glb:b.dataset.state==='gt'?c.gt_glb:a.glb;
270
- el.parentElement.querySelectorAll('.scene-versions button').forEach(x=>x.classList.toggle('on',x===b));
271
- const status=document.createElement('span');status.className='scene-loading';status.setAttribute('role','status');status.textContent='Loading '+b.textContent.toLowerCase()+'…';el.querySelector('.scene-loading')?.remove();el.append(status);
272
- el.querySelector('canvas').dataset.rendered='false';el.querySelector('.scene-hint').textContent=b.textContent+' · Drag to orbit';
273
- viewer.load(url).catch(()=>status.textContent='Scene unavailable — open the case to retry.');el.dataset.state=b.dataset.state;
274
- }));
275
- }),{rootMargin:'180px'});
276
  document.querySelectorAll('.live-scene').forEach(el=>observer.observe(el));
 
 
1
  import * as THREE from "three";
2
+ import {AssetQueue,fetchSceneBytes} from "./scene-assets.js?v=20261001c";
3
  import {GLTFLoader} from "three/addons/loaders/GLTFLoader.js";
4
  import {MeshoptDecoder} from "three/addons/libs/meshopt_decoder.module.js";
5
  import {Sky} from "three/addons/objects/Sky.js";
 
10
  // procedural viewer had (rotationX / rotationY / zoom / paused / group /
11
  // draw(dt) / destroy()), so the page code above it did not have to change.
12
  //
13
+ // Existing public Code4Scene packed GLBs. The decoder preserves their original geometry and textures.
 
 
14
  (function () {
15
  const ADD = {GLTFLoader};
16
  const activeViewers = new Set();
 
18
  let lastFrame = performance.now();
19
 
20
  /* ------------------------------------------------------------ renderer */
21
+ let gl = null, ENV = null, contextLost = false, restoreTimer = null;
22
  function renderer() {
23
  if (gl) return gl;
24
  gl = new THREE.WebGLRenderer({ antialias: true, alpha: true, premultipliedAlpha: true, powerPreference: "high-performance" });
25
  gl.setPixelRatio(1);
26
+ gl.domElement.addEventListener('webglcontextlost',event=>{
27
+ event.preventDefault();contextLost=true;
28
+ activeViewers.forEach(v=>{if(v.visible)v.status('Restoring 3D graphics…','restoring');});
29
+ clearTimeout(restoreTimer);restoreTimer=setTimeout(()=>activeViewers.forEach(v=>{if(v.visible)v.fail(new Error('3D graphics were interrupted.'),'graphics');}),10000);
30
+ });
31
+ gl.domElement.addEventListener('webglcontextrestored',()=>{
32
+ clearTimeout(restoreTimer);contextLost=false;
33
+ try{makeEnvironment();for(const e of assets.entries.values())if(e.asset)e.asset.scene.environment=ENV;activeViewers.forEach(v=>{v.dirty=true;v.hasDrawn=false;});}
34
+ catch(error){activeViewers.forEach(v=>v.fail(error,'graphics'));}
35
+ });
36
  gl.outputColorSpace = THREE.SRGBColorSpace;
37
  gl.toneMapping = THREE.ACESFilmicToneMapping; gl.toneMappingExposure = 1.0;
38
  gl.shadowMap.enabled = true;
39
  gl.shadowMap.type = THREE.PCFSoftShadowMap;
40
  gl.setClearColor(0x000000, 0);
41
+ makeEnvironment();
42
  return gl;
43
  }
44
 
45
+ function makeEnvironment(){
46
+ ENV?.dispose();
47
+ const sky=new Sky();sky.scale.setScalar(1000);const u=sky.material.uniforms;u.turbidity.value=4;u.rayleigh.value=1.4;u.mieCoefficient.value=.004;u.mieDirectionalG.value=.8;u.sunPosition.value.setFromSphericalCoords(1,THREE.MathUtils.degToRad(52),THREE.MathUtils.degToRad(215));const skyScene=new THREE.Scene();skyScene.add(sky);const pmrem=new THREE.PMREMGenerator(gl);ENV=pmrem.fromScene(skyScene,0,.1,2000).texture;pmrem.dispose();sky.geometry.dispose();sky.material.dispose();
48
+ }
49
+ function recoverRenderer(){
50
+ clearTimeout(restoreTimer);contextLost=false;
51
+ if(gl){gl.dispose();gl=null;}ENV?.dispose();ENV=null;renderer();
52
+ for(const e of assets.entries.values())if(e.asset)e.asset.scene.environment=ENV;
53
+ activeViewers.forEach(v=>{v.dirty=true;v.hasDrawn=false;v.failed=null;});
54
+ }
55
  // The benchmark's own light rig (city_bench.building_light/1), the numbers
56
  // the board's renders use: sun in the south-east at 50 degrees, a pale sky,
57
  // and a muted environment. One rig for the page, moved into whichever scene
 
87
  asset.scene.add(RIG_GROUP);
88
  }
89
 
90
+ const PACK_KEY=Uint8Array.from("5c2f9e71d3a84b06e1f7c29a38d05b64a7193ce8f2046db95e81c73a2df6904b".match(/../g),h=>parseInt(h,16));
91
+ function disposeAsset(asset){
92
+ if(!asset)return;asset.scene.remove(RIG_GROUP);const geometries=new Set(),materials=new Set(),textures=new Set();
93
+ asset.scene.traverse(n=>{if(n.geometry)geometries.add(n.geometry);for(const m of [].concat(n.material||[])){materials.add(m);for(const v of Object.values(m))if(v?.isTexture)textures.add(v);}});
94
+ geometries.forEach(g=>g.dispose());textures.forEach(t=>{t.dispose();t.source?.data?.close?.();});materials.forEach(m=>m.dispose());
95
+ }
96
+ function assetProfile(root){
97
+ const buffers=new Set(),images=new Set();let geometry=0,textures=0,maxTexture=0;
98
+ root.traverse(n=>{if(n.geometry){for(const a of [...Object.values(n.geometry.attributes),n.geometry.index].filter(Boolean)){const buffer=(a.array||a.data?.array)?.buffer;if(buffer&&!buffers.has(buffer)){buffers.add(buffer);geometry+=buffer.byteLength;}}}for(const m of [].concat(n.material||[]))for(const t of Object.values(m))if(t?.isTexture){const image=t.source?.data;if(image&&!images.has(image)){images.add(image);textures+=(image.width||0)*(image.height||0)*4*1.34;maxTexture=Math.max(maxTexture,image.width||0,image.height||0);}}});
99
+ return {geometry,textures,maxTexture,bytes:geometry+textures};
100
+ }
101
+
102
+ // Cards never need full-resolution scene textures. Bound their decoded/GPU footprint,
103
+ // while the original public files and full case inspector retain their original texture resolution.
104
+ async function cardTextures(root,signal){
105
+ const images=new Map(),textures=new Set();root.traverse(n=>{for(const m of [].concat(n.material||[]))for(const t of Object.values(m))if(t?.isTexture)textures.add(t);});
106
+ for(const t of textures){const image=t.source?.data;if(!image||Math.max(image.width||0,image.height||0)<=512)continue;
107
+ if(signal.aborted)throw new DOMException('Scene no longer visible','AbortError');
108
+ if(!images.has(image)){const scale=512/Math.max(image.width,image.height);images.set(image,await createImageBitmap(image,{resizeWidth:Math.max(1,Math.round(image.width*scale)),resizeHeight:Math.max(1,Math.round(image.height*scale)),resizeQuality:'high',colorSpaceConversion:'none',premultiplyAlpha:'none'}));}
109
+ t.image=images.get(image);t.needsUpdate=true;
110
+ }
111
+ for(const original of images.keys())original.close?.();
112
  }
113
+ const assets=new AssetQueue({
114
+ maxConcurrent:2,maxIdle:1,maxBytes:128*1024*1024,dispose:disposeAsset,
115
+ onChange:s=>{document.documentElement.dataset.sceneJobs=String(s.running);document.documentElement.dataset.scenePeakJobs=String(s.peak);document.documentElement.dataset.sceneCached=String(s.cached);document.documentElement.dataset.sceneBytes=String(Math.round(s.bytes));},
116
+ load:async(key,signal,progress)=>{
117
+ progress('downloading',{received:0,total:0});const bytes=await fetchSceneBytes(key,signal,p=>progress('downloading',p));
118
+ for(let i=0;i<bytes.length;i++)bytes[i]^=PACK_KEY[i&31]^(((i>>>5)*131)&255);
119
+ if(new DataView(bytes.buffer).getUint32(0,true)!==0x46546c67)throw new Error('The scene file is invalid.');
120
+ if(signal.aborted)throw new DOMException('Scene no longer visible','AbortError');
121
+ progress('decoding');const gltf=await new Promise((resolve,reject)=>{
122
+ let done=false;const timer=setTimeout(()=>{done=true;reject(new Error('The scene could not be decoded in time.'));},30000);
123
+ new GLTFLoader().setMeshoptDecoder(MeshoptDecoder).parse(bytes.buffer,'',g=>{clearTimeout(timer);if(done||signal.aborted){const fake={scene:g.scene,root:g.scene};disposeAsset(fake);if(!done)reject(new DOMException('Scene no longer visible','AbortError'));return;}done=true;resolve(g);},error=>{clearTimeout(timer);if(!done){done=true;reject(error);}});
124
+ });
125
+ try{await cardTextures(gltf.scene,signal);}catch(error){disposeAsset({scene:gltf.scene,root:gltf.scene});throw error;}
126
  const root = gltf.scene;
127
  root.traverse(node => { if (node.isMesh) { node.castShadow = true; node.receiveShadow = true; } });
128
  const box = new THREE.Box3(), pts=[];
 
139
  scene.background = new THREE.Color(0xe6edf0); scene.add(root);
140
  const task=window.SITE.cases.find(c=>c.track==='i2s'&&(c.input_glb===key||c.gt_glb===key||c.agents.some(a=>a.glb===key)));
141
  if(task){root.updateMatrixWorld(true);root.traverse(o=>{const duplicate=(task.duplicates||[]).includes(o.name);if(!duplicate&&!(task.targets||[]).includes(o.name))return;const b=new THREE.Box3().setFromObject(o);if(b.isEmpty())return;const h=new THREE.Box3Helper(b.expandByScalar(.08),duplicate?0xff6b5e:0x5ee08a);h.material.depthTest=false;h.material.transparent=true;h.renderOrder=999;scene.add(h);});}
142
+ return {key,root,scene,box,centre,corners,radius:Math.max(size.length()/2,1),floor:box.min.y,...assetProfile(root)};
 
 
 
 
143
  }
144
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
 
146
  /* -------------------------------------------------------------- viewer */
147
  const clamp = (v, a, b) => Math.min(b, Math.max(a, v));
148
  const reduced = () => window.matchMedia("(prefers-reduced-motion: reduce)").matches;
149
  class Viewer {
150
  constructor(canvas, options = {}) {
151
+ this.canvas = canvas; this.element=canvas.closest(".live-scene");this.visible=false;this.dirty=true;this.handle=null;this.key=null;this.generation=0;
152
  this.ctx = canvas.getContext("2d", { alpha: true });
153
  this.rotationY = options.rotationY ?? -0.65;
154
  this.rotationX = options.rotationX ?? 0.35;
 
163
  this.entry = null; this.asset = null;
164
  this.bind();
165
  activeViewers.add(this);
166
+ if (options.assetKey) this.key=options.assetKey;
167
+ }
168
+ status(text,state){
169
+ this.element.dataset.statePhase=state;this.canvas.dataset.rendered='false';
170
+ let box=this.element.querySelector('.scene-loading');if(!box){box=document.createElement('div');box.className='scene-loading';box.setAttribute('role','status');this.element.append(box);}
171
+ if(box.textContent!==text)box.textContent=text;
172
+ }
173
+ fail(error,kind='asset'){
174
+ if(!this.visible)return;this.failed=error;this.failureKind=kind;this.status(kind==='graphics'?'3D graphics were interrupted.':'Could not load this scene.','error');
175
+ const box=this.element.querySelector('.scene-loading');box.title=error?.message||'';
176
+ const retry=document.createElement('button');retry.className='scene-retry';retry.textContent='Retry scene';retry.onclick=()=>{this.failed=null;if(this.failureKind==='graphics'){try{recoverRenderer();this.status('Preparing 3D scene…','decoding');}catch(e){this.fail(e,'graphics');}}else this.load(this.key);};box.append(retry);
177
+ }
178
+ load(key){
179
+ this.key=key;this.generation++;this.handle?.release();this.handle=null;this.asset=null;this.failed=null;this.hasDrawn=false;this.dirty=true;
180
+ if(!this.visible)return;
181
+ const generation=this.generation;this.status('Waiting for a download slot…','queued');
182
+ this.handle=assets.retain(key,entry=>{
183
+ if(this.destroyed||!this.visible||generation!==this.generation)return;
184
+ if(entry.state==='ready'){this.asset=entry.asset;this.element.dataset.sceneMb=(entry.bytes/1048576).toFixed(1);this.element.dataset.sceneGeometryMb=(entry.asset.geometry/1048576).toFixed(1);this.element.dataset.sceneTextureMb=(entry.asset.textures/1048576).toFixed(1);this.element.dataset.sceneMaxTexture=String(entry.asset.maxTexture);this.hasDrawn=false;this.dirty=true;this.status('Preparing 3D scene…','rendering');}
185
+ else if(entry.state==='error')this.fail(entry.error);
186
+ else if(entry.state==='downloading'){const text=entry.total?Math.min(100,Math.round(entry.received/entry.total*100))+'%':(entry.received/1048576).toFixed(1)+' MB';this.status('Downloading scene · '+text,'downloading');}
187
+ else if(entry.state==='decoding')this.status('Preparing scene geometry…','decoding');
188
+ else if(entry.state==='retrying')this.status('Connection interrupted · retrying…','retrying');
189
+ },()=>Math.abs(this.canvas.getBoundingClientRect().top));
190
  }
191
+ setVisible(visible){
192
+ if(this.visible===visible)return;this.visible=visible;
193
+ if(visible){this.load(this.key);}
194
+ else{this.generation++;this.handle?.release();this.handle=null;this.asset=null;this.element.dataset.statePhase='paused';}
 
 
 
195
  }
196
  bind() {
197
  this.onDown = e => { this.paused = true; this.dragging = true; this.lastPointer = [e.clientX, e.clientY]; this.canvas.setPointerCapture?.(e.pointerId); };
198
+ this.onMove = e => { if (!this.dragging) return; this.dirty=true; const dx = e.clientX - this.lastPointer[0], dy = e.clientY - this.lastPointer[1]; this.rotationY += dx * .012; this.rotationX = clamp(this.rotationX + dy * .008, -.05, 1.3); this.lastPointer = [e.clientX, e.clientY]; if (this.group) { this.group.rotationX = this.rotationX; this.group.rotationY = this.rotationY; } };
199
  this.onUp = () => { this.dragging = false; this.lastPointer = null; };
200
+ this.onWheel = e => { e.preventDefault();this.dirty=true; this.zoom = clamp(this.zoom - e.deltaY * .0007, .6, 2.2); if (this.group) this.group.zoom = this.zoom; };
201
+ this.onKey = e => { const keys = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "+", "=", "-"]; if (!keys.includes(e.key)) return; e.preventDefault(); this.dirty=true; this.paused = true; if (e.key === "ArrowLeft") this.rotationY -= .12; if (e.key === "ArrowRight") this.rotationY += .12; if (e.key === "ArrowUp") this.rotationX = clamp(this.rotationX + .1, -.05, 1.3); if (e.key === "ArrowDown") this.rotationX = clamp(this.rotationX - .1, -.05, 1.3); if (e.key === "+" || e.key === "=") this.zoom = clamp(this.zoom + .08, .6, 2.2); if (e.key === "-") this.zoom = clamp(this.zoom - .08, .6, 2.2); if (this.group) Object.assign(this.group, { rotationX: this.rotationX, rotationY: this.rotationY, zoom: this.zoom, paused: true }); };
202
  this.canvas.addEventListener("wheel", this.onWheel, { passive: false }); this.canvas.addEventListener("keydown", this.onKey);
203
  this.canvas.addEventListener("pointerdown", this.onDown); this.canvas.addEventListener("pointermove", this.onMove); this.canvas.addEventListener("pointerup", this.onUp); this.canvas.addEventListener("pointercancel", this.onUp);
204
  }
205
  resize() {
206
  const rect = this.canvas.getBoundingClientRect();
207
+ const dpr = Math.min(window.devicePixelRatio || 1, 1.5, 960/Math.max(1,rect.width),600/Math.max(1,rect.height));
208
  const w = Math.max(1, Math.round(rect.width * dpr)), h = Math.max(1, Math.round(rect.height * dpr));
209
+ if (this.canvas.width !== w || this.canvas.height !== h) { this.canvas.width = w; this.canvas.height = h;this.dirty=true; }
210
  this.w = rect.width; this.h = rect.height; this.dpr = dpr;
211
  }
212
  // Orbit the model's centre. The distance is fitted to the bounding box
 
239
  cam.up.set(0, 1, 0); cam.lookAt(target); cam.updateProjectionMatrix();
240
  }
241
  draw(dt) {
242
+ if (this.destroyed || !this.visible || !this.canvas.isConnected || contextLost || this.failed) return;
243
  const rect = this.canvas.getBoundingClientRect();
244
  if (rect.width < 2 || rect.height < 2 || document.hidden) return;
245
  if (rect.bottom < 0 || rect.top > window.innerHeight) return;
246
  this.resize();
247
+ if(this.hasDrawn&&!this.dirty&&(this.paused||reduced()))return;
248
  if (this.group) { this.rotationX = this.group.rotationX; this.rotationY = this.group.rotationY; this.zoom = this.group.zoom; }
249
  if (!this.group && !this.paused && !this.dragging && !reduced()) this.rotationY += this.speed * dt;
250
  const ctx = this.ctx, W = this.canvas.width, H = this.canvas.height;
 
255
  return;
256
  }
257
  const g = renderer();
258
+ if(g.domElement.width!==W||g.domElement.height!==H)g.setSize(W,H,false);
259
  this.aim();
260
  rigFor(this.asset);
261
  g.render(this.asset.scene, this.camera);
262
  ctx.clearRect(0, 0, W, H);
263
  ctx.drawImage(g.domElement, 0, 0, W, H, 0, 0, W, H);
264
+ this.hasDrawn = true; this.dirty=false;this.element.dataset.statePhase="ready"; this.canvas.dataset.rendered="true"; this.canvas.parentElement.querySelector(".scene-loading")?.remove();
265
  }
266
  destroy() {
267
  this.destroyed = true; activeViewers.delete(this);
268
+ this.handle?.release(); this.handle=null;this.asset=null;
269
  this.canvas.removeEventListener("pointerdown", this.onDown); this.canvas.removeEventListener("pointermove", this.onMove); this.canvas.removeEventListener("pointerup", this.onUp); this.canvas.removeEventListener("pointercancel", this.onUp); this.canvas.removeEventListener("wheel", this.onWheel); this.canvas.removeEventListener("keydown", this.onKey);
270
  }
271
  }
272
  window.GLBViewer = Viewer;
273
  window.destroyViewersWithin = root => { activeViewers.forEach(v => { if (root.contains(v.canvas)) v.destroy(); }); };
274
+ window.BB_ENGINE = { renderer };
275
 
276
  /* ------------------------------------------------------------- the clock */
277
  function loop(now) {
 
280
  const dt = Math.min(.05, (now - lastFrame) / 1000); lastFrame = now;
281
  const groups = new Set([...activeViewers].filter(v => v.group && !v.destroyed).map(v => v.group));
282
  if (!document.hidden && !reduced()) groups.forEach(g => { if (!g.paused && ![...activeViewers].some(v => v.group === g && v.dragging)) g.rotationY += dt * .14; });
283
+ activeViewers.forEach(v => { try { v.draw(dt); } catch (err) { v.fail(err,'graphics');console.error('Code4Scene: viewer draw failed',err); } });
284
  }
285
  requestAnimationFrame(loop);
286
  })();
287
 
288
 
289
+ // Visibility owns the asset subscription; hidden task panels and offscreen cards release resources.
290
+ const viewers=new Map();
291
+ function syncMotion(viewer,button){button.textContent=viewer.paused?'▶':'Ⅱ';button.setAttribute('aria-label',viewer.paused?'Resume scene rotation':'Pause scene rotation');}
292
+ function mount(el){
293
+ const c=window.SITE.cases.find(c=>c.id===el.dataset.case),a=c.agents.find(a=>a.key===el.dataset.agent);
294
+ const url=state=>state==='input'?c.input_glb:state==='gt'?c.gt_glb:a.glb;
295
+ const viewer=new window.GLBViewer(el.querySelector('canvas'),{assetKey:url(el.dataset.state||'repair'),refCam:c.ref_cam,rotationX:.55,rotationY:-.62,speed:.1});viewers.set(el,viewer);
296
+ const pause=el.querySelector('.scene-motion');syncMotion(viewer,pause);pause.addEventListener('click',()=>{viewer.paused=!viewer.paused;viewer.dirty=true;syncMotion(viewer,pause);});
297
+ el.querySelector('canvas').addEventListener('pointerdown',()=>syncMotion(viewer,pause));
298
+ el.parentElement.querySelectorAll(':scope > .scene-versions button').forEach(b=>b.addEventListener('click',()=>{
299
+ const state=b.dataset.state;el.dataset.state=state;el.parentElement.querySelectorAll(':scope > .scene-versions button').forEach(x=>{x.classList.toggle('on',x===b);x.setAttribute('aria-pressed',String(x===b));});
300
+ el.querySelector('.scene-hint').textContent=b.textContent+' · Drag to orbit';viewer.load(url(state));
301
+ }));return viewer;
302
+ }
303
+ const observer=new IntersectionObserver(entries=>entries.forEach(({target,isIntersecting})=>{const viewer=viewers.get(target)||mount(target);viewer.setVisible(isIntersecting&&!target.closest('[hidden]'));}),{rootMargin:'40px',threshold:0});
 
 
304
  document.querySelectorAll('.live-scene').forEach(el=>observer.observe(el));
305
+ document.addEventListener('taskchange',()=>{for(const[el,v]of viewers){if(el.closest('[hidden]'))v.setVisible(false);else{const r=el.getBoundingClientRect();v.setVisible(r.width>0&&r.bottom>0&&r.top<innerHeight+40);}}});
assets/task-tabs.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ const tabs=[...document.querySelectorAll('.task-tabs [role=tab]')];
2
+ function select(tab){
3
+ for(const b of tabs){const on=b===tab;b.setAttribute('aria-selected',String(on));b.tabIndex=on?0:-1;document.getElementById(b.getAttribute('aria-controls')).hidden=!on;}
4
+ document.dispatchEvent(new CustomEvent('taskchange'));
5
+ }
6
+ tabs.forEach((b,i)=>{b.addEventListener('click',()=>select(b));b.addEventListener('keydown',e=>{if(!['ArrowLeft','ArrowRight','Home','End'].includes(e.key))return;e.preventDefault();const j=e.key==='Home'?0:e.key==='End'?tabs.length-1:(i+(e.key==='ArrowRight'?1:-1)+tabs.length)%tabs.length;select(tabs[j]);tabs[j].focus();});});
data/leaderboard-details.json ADDED
@@ -0,0 +1,1352 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "overall": [
3
+ {
4
+ "key": "astra",
5
+ "name": "GPT-6 Astra (max)",
6
+ "provider": "OpenAI",
7
+ "metrics": [
8
+ {
9
+ "label": "Overall",
10
+ "value": 0.6193352866666667,
11
+ "currency": false
12
+ },
13
+ {
14
+ "label": "Text-to-Scene",
15
+ "value": 0.72382,
16
+ "currency": false
17
+ },
18
+ {
19
+ "label": "Image-to-Scene",
20
+ "value": 0.5148505733333334,
21
+ "currency": false
22
+ },
23
+ {
24
+ "label": "Mean cost / case",
25
+ "value": 12.896991822966507,
26
+ "currency": true
27
+ }
28
+ ]
29
+ },
30
+ {
31
+ "key": "gemini",
32
+ "name": "Gemini 3.8 Flash (high)",
33
+ "provider": "Google",
34
+ "metrics": [
35
+ {
36
+ "label": "Overall",
37
+ "value": 0.6189750266666667,
38
+ "currency": false
39
+ },
40
+ {
41
+ "label": "Text-to-Scene",
42
+ "value": 0.65689,
43
+ "currency": false
44
+ },
45
+ {
46
+ "label": "Image-to-Scene",
47
+ "value": 0.5810600533333334,
48
+ "currency": false
49
+ },
50
+ {
51
+ "label": "Mean cost / case",
52
+ "value": 1.9235185771258503,
53
+ "currency": true
54
+ }
55
+ ]
56
+ },
57
+ {
58
+ "key": "fable",
59
+ "name": "Claude Fable 5.1 (max)",
60
+ "provider": "Anthropic",
61
+ "metrics": [
62
+ {
63
+ "label": "Overall",
64
+ "value": 0.60604898,
65
+ "currency": false
66
+ },
67
+ {
68
+ "label": "Text-to-Scene",
69
+ "value": 0.78775,
70
+ "currency": false
71
+ },
72
+ {
73
+ "label": "Image-to-Scene",
74
+ "value": 0.4243479600000001,
75
+ "currency": false
76
+ },
77
+ {
78
+ "label": "Mean cost / case",
79
+ "value": 10.623258766403161,
80
+ "currency": true
81
+ }
82
+ ]
83
+ },
84
+ {
85
+ "key": "opus",
86
+ "name": "Claude Opus 5 (max)",
87
+ "provider": "Anthropic",
88
+ "metrics": [
89
+ {
90
+ "label": "Overall",
91
+ "value": 0.5931299933333334,
92
+ "currency": false
93
+ },
94
+ {
95
+ "label": "Text-to-Scene",
96
+ "value": 0.7181599999999999,
97
+ "currency": false
98
+ },
99
+ {
100
+ "label": "Image-to-Scene",
101
+ "value": 0.46809998666666675,
102
+ "currency": false
103
+ },
104
+ {
105
+ "label": "Mean cost / case",
106
+ "value": 19.47789116793412,
107
+ "currency": true
108
+ }
109
+ ]
110
+ },
111
+ {
112
+ "key": "sol",
113
+ "name": "GPT-5.6 Sol (high)",
114
+ "provider": "OpenAI",
115
+ "metrics": [
116
+ {
117
+ "label": "Overall",
118
+ "value": 0.5499994666666667,
119
+ "currency": false
120
+ },
121
+ {
122
+ "label": "Text-to-Scene",
123
+ "value": 0.70704,
124
+ "currency": false
125
+ },
126
+ {
127
+ "label": "Image-to-Scene",
128
+ "value": 0.3929589333333333,
129
+ "currency": false
130
+ },
131
+ {
132
+ "label": "Mean cost / case",
133
+ "value": 2.9749956842592593,
134
+ "currency": true
135
+ }
136
+ ]
137
+ },
138
+ {
139
+ "key": "muse",
140
+ "name": "Muse Spark 1.3 (medium)",
141
+ "provider": "Meta",
142
+ "metrics": [
143
+ {
144
+ "label": "Overall",
145
+ "value": 0.5022053666666666,
146
+ "currency": false
147
+ },
148
+ {
149
+ "label": "Text-to-Scene",
150
+ "value": 0.646195,
151
+ "currency": false
152
+ },
153
+ {
154
+ "label": "Image-to-Scene",
155
+ "value": 0.35821573333333334,
156
+ "currency": false
157
+ },
158
+ {
159
+ "label": "Mean cost / case",
160
+ "value": 0.0861066423076923,
161
+ "currency": true
162
+ }
163
+ ]
164
+ },
165
+ {
166
+ "key": "glm",
167
+ "name": "GLM-5.3 Flash (max)",
168
+ "provider": "Z.ai",
169
+ "metrics": [
170
+ {
171
+ "label": "Overall",
172
+ "value": 0.4147088666666666,
173
+ "currency": false
174
+ },
175
+ {
176
+ "label": "Text-to-Scene",
177
+ "value": 0.5094299999999999,
178
+ "currency": false
179
+ },
180
+ {
181
+ "label": "Image-to-Scene",
182
+ "value": 0.3199877333333333,
183
+ "currency": false
184
+ },
185
+ {
186
+ "label": "Mean cost / case",
187
+ "value": 0.40130584861111107,
188
+ "currency": true
189
+ }
190
+ ]
191
+ },
192
+ {
193
+ "key": "qwen-off",
194
+ "name": "Qwen 3.8 27B (thinking off)",
195
+ "provider": "Alibaba",
196
+ "metrics": [
197
+ {
198
+ "label": "Overall",
199
+ "value": 0.37818169333333335,
200
+ "currency": false
201
+ },
202
+ {
203
+ "label": "Text-to-Scene",
204
+ "value": 0.55666,
205
+ "currency": false
206
+ },
207
+ {
208
+ "label": "Image-to-Scene",
209
+ "value": 0.19970338666666668,
210
+ "currency": false
211
+ },
212
+ {
213
+ "label": "Mean cost / case",
214
+ "value": 0.38413493183103564,
215
+ "currency": true
216
+ }
217
+ ]
218
+ },
219
+ {
220
+ "key": "grok",
221
+ "name": "Grok 4.6 (high)",
222
+ "provider": "xAI",
223
+ "metrics": [
224
+ {
225
+ "label": "Overall",
226
+ "value": 0.37567506,
227
+ "currency": false
228
+ },
229
+ {
230
+ "label": "Text-to-Scene",
231
+ "value": 0.56721,
232
+ "currency": false
233
+ },
234
+ {
235
+ "label": "Image-to-Scene",
236
+ "value": 0.18414012,
237
+ "currency": false
238
+ },
239
+ {
240
+ "label": "Mean cost / case",
241
+ "value": 2.2948689296296294,
242
+ "currency": true
243
+ }
244
+ ]
245
+ },
246
+ {
247
+ "key": "qwen-on",
248
+ "name": "Qwen 3.8 27B (thinking on)",
249
+ "provider": "Alibaba",
250
+ "metrics": [
251
+ {
252
+ "label": "Overall",
253
+ "value": 0.37094399333333333,
254
+ "currency": false
255
+ },
256
+ {
257
+ "label": "Text-to-Scene",
258
+ "value": 0.51571,
259
+ "currency": false
260
+ },
261
+ {
262
+ "label": "Image-to-Scene",
263
+ "value": 0.2261779866666667,
264
+ "currency": false
265
+ },
266
+ {
267
+ "label": "Mean cost / case",
268
+ "value": 0.29748765575757574,
269
+ "currency": true
270
+ }
271
+ ]
272
+ },
273
+ {
274
+ "key": "inkling",
275
+ "name": "Inkling (high)",
276
+ "provider": "Thinking Machines",
277
+ "metrics": [
278
+ {
279
+ "label": "Overall",
280
+ "value": 0.31150237333333336,
281
+ "currency": false
282
+ },
283
+ {
284
+ "label": "Text-to-Scene",
285
+ "value": 0.42498500000000006,
286
+ "currency": false
287
+ },
288
+ {
289
+ "label": "Image-to-Scene",
290
+ "value": 0.19801974666666666,
291
+ "currency": false
292
+ },
293
+ {
294
+ "label": "Mean cost / case",
295
+ "value": 0.4783280191269841,
296
+ "currency": true
297
+ }
298
+ ]
299
+ },
300
+ {
301
+ "key": "gemma-on",
302
+ "name": "Gemma 4 31B (thinking on)",
303
+ "provider": "Google",
304
+ "metrics": [
305
+ {
306
+ "label": "Overall",
307
+ "value": 0.29812257999999997,
308
+ "currency": false
309
+ },
310
+ {
311
+ "label": "Text-to-Scene",
312
+ "value": 0.470705,
313
+ "currency": false
314
+ },
315
+ {
316
+ "label": "Image-to-Scene",
317
+ "value": 0.12554015999999998,
318
+ "currency": false
319
+ },
320
+ {
321
+ "label": "Mean cost / case",
322
+ "value": 0.026867125396825398,
323
+ "currency": true
324
+ }
325
+ ]
326
+ },
327
+ {
328
+ "key": "gemma-off",
329
+ "name": "Gemma 4 31B (thinking off)",
330
+ "provider": "Google",
331
+ "metrics": [
332
+ {
333
+ "label": "Overall",
334
+ "value": 0.28498897333333334,
335
+ "currency": false
336
+ },
337
+ {
338
+ "label": "Text-to-Scene",
339
+ "value": 0.45494,
340
+ "currency": false
341
+ },
342
+ {
343
+ "label": "Image-to-Scene",
344
+ "value": 0.11503794666666667,
345
+ "currency": false
346
+ },
347
+ {
348
+ "label": "Mean cost / case",
349
+ "value": 0.017148714965986397,
350
+ "currency": true
351
+ }
352
+ ]
353
+ },
354
+ {
355
+ "key": "deepseek",
356
+ "name": "DeepSeek V4.1 Flash (high)",
357
+ "provider": "DeepSeek",
358
+ "metrics": [
359
+ {
360
+ "label": "Overall",
361
+ "value": 0.22658958,
362
+ "currency": false
363
+ },
364
+ {
365
+ "label": "Text-to-Scene",
366
+ "value": 0.24269,
367
+ "currency": false
368
+ },
369
+ {
370
+ "label": "Image-to-Scene",
371
+ "value": 0.21048916,
372
+ "currency": false
373
+ },
374
+ {
375
+ "label": "Mean cost / case",
376
+ "value": 0.1240297601010101,
377
+ "currency": true
378
+ }
379
+ ]
380
+ }
381
+ ],
382
+ "t2s": [
383
+ {
384
+ "key": "fable",
385
+ "name": "Claude Fable 5.1 (max)",
386
+ "provider": "Anthropic",
387
+ "metrics": [
388
+ {
389
+ "label": "Text-to-Scene",
390
+ "value": 0.78775,
391
+ "currency": false
392
+ },
393
+ {
394
+ "label": "Detailed Alignment",
395
+ "value": 0.7253149999999999,
396
+ "currency": false
397
+ },
398
+ {
399
+ "label": "Overview Alignment",
400
+ "value": 0.7717050000000001,
401
+ "currency": false
402
+ },
403
+ {
404
+ "label": "Physical Safety",
405
+ "value": 0.898,
406
+ "currency": false
407
+ },
408
+ {
409
+ "label": "Mean cost / case",
410
+ "value": 18.1576316,
411
+ "currency": true
412
+ }
413
+ ]
414
+ },
415
+ {
416
+ "key": "astra",
417
+ "name": "GPT-6 Astra (max)",
418
+ "provider": "OpenAI",
419
+ "metrics": [
420
+ {
421
+ "label": "Text-to-Scene",
422
+ "value": 0.72382,
423
+ "currency": false
424
+ },
425
+ {
426
+ "label": "Detailed Alignment",
427
+ "value": 0.707165,
428
+ "currency": false
429
+ },
430
+ {
431
+ "label": "Overview Alignment",
432
+ "value": 0.733235,
433
+ "currency": false
434
+ },
435
+ {
436
+ "label": "Physical Safety",
437
+ "value": 0.712,
438
+ "currency": false
439
+ },
440
+ {
441
+ "label": "Mean cost / case",
442
+ "value": 22.472260736842106,
443
+ "currency": true
444
+ }
445
+ ]
446
+ },
447
+ {
448
+ "key": "opus",
449
+ "name": "Claude Opus 5 (max)",
450
+ "provider": "Anthropic",
451
+ "metrics": [
452
+ {
453
+ "label": "Text-to-Scene",
454
+ "value": 0.7181599999999999,
455
+ "currency": false
456
+ },
457
+ {
458
+ "label": "Detailed Alignment",
459
+ "value": 0.63106,
460
+ "currency": false
461
+ },
462
+ {
463
+ "label": "Overview Alignment",
464
+ "value": 0.71617,
465
+ "currency": false
466
+ },
467
+ {
468
+ "label": "Physical Safety",
469
+ "value": 0.811,
470
+ "currency": false
471
+ },
472
+ {
473
+ "label": "Mean cost / case",
474
+ "value": 34.49611078947368,
475
+ "currency": true
476
+ }
477
+ ]
478
+ },
479
+ {
480
+ "key": "sol",
481
+ "name": "GPT-5.6 Sol (high)",
482
+ "provider": "OpenAI",
483
+ "metrics": [
484
+ {
485
+ "label": "Text-to-Scene",
486
+ "value": 0.70704,
487
+ "currency": false
488
+ },
489
+ {
490
+ "label": "Detailed Alignment",
491
+ "value": 0.63186,
492
+ "currency": false
493
+ },
494
+ {
495
+ "label": "Overview Alignment",
496
+ "value": 0.710485,
497
+ "currency": false
498
+ },
499
+ {
500
+ "label": "Physical Safety",
501
+ "value": 0.772,
502
+ "currency": false
503
+ },
504
+ {
505
+ "label": "Mean cost / case",
506
+ "value": 4.07260365,
507
+ "currency": true
508
+ }
509
+ ]
510
+ },
511
+ {
512
+ "key": "gemini",
513
+ "name": "Gemini 3.8 Flash (high)",
514
+ "provider": "Google",
515
+ "metrics": [
516
+ {
517
+ "label": "Text-to-Scene",
518
+ "value": 0.65689,
519
+ "currency": false
520
+ },
521
+ {
522
+ "label": "Detailed Alignment",
523
+ "value": 0.6369100000000001,
524
+ "currency": false
525
+ },
526
+ {
527
+ "label": "Overview Alignment",
528
+ "value": 0.66406,
529
+ "currency": false
530
+ },
531
+ {
532
+ "label": "Physical Safety",
533
+ "value": 0.655,
534
+ "currency": false
535
+ },
536
+ {
537
+ "label": "Mean cost / case",
538
+ "value": 2.49471265,
539
+ "currency": true
540
+ }
541
+ ]
542
+ },
543
+ {
544
+ "key": "muse",
545
+ "name": "Muse Spark 1.3 (medium)",
546
+ "provider": "Meta",
547
+ "metrics": [
548
+ {
549
+ "label": "Text-to-Scene",
550
+ "value": 0.646195,
551
+ "currency": false
552
+ },
553
+ {
554
+ "label": "Detailed Alignment",
555
+ "value": 0.5981099999999999,
556
+ "currency": false
557
+ },
558
+ {
559
+ "label": "Overview Alignment",
560
+ "value": 0.660675,
561
+ "currency": false
562
+ },
563
+ {
564
+ "label": "Physical Safety",
565
+ "value": 0.651,
566
+ "currency": false
567
+ },
568
+ {
569
+ "label": "Mean cost / case",
570
+ "value": 0.10048539999999999,
571
+ "currency": true
572
+ }
573
+ ]
574
+ },
575
+ {
576
+ "key": "grok",
577
+ "name": "Grok 4.6 (high)",
578
+ "provider": "xAI",
579
+ "metrics": [
580
+ {
581
+ "label": "Text-to-Scene",
582
+ "value": 0.56721,
583
+ "currency": false
584
+ },
585
+ {
586
+ "label": "Detailed Alignment",
587
+ "value": 0.52211,
588
+ "currency": false
589
+ },
590
+ {
591
+ "label": "Overview Alignment",
592
+ "value": 0.5764199999999999,
593
+ "currency": false
594
+ },
595
+ {
596
+ "label": "Physical Safety",
597
+ "value": 0.585,
598
+ "currency": false
599
+ },
600
+ {
601
+ "label": "Mean cost / case",
602
+ "value": 4.326270533333333,
603
+ "currency": true
604
+ }
605
+ ]
606
+ },
607
+ {
608
+ "key": "qwen-off",
609
+ "name": "Qwen 3.8 27B (thinking off)",
610
+ "provider": "Alibaba",
611
+ "metrics": [
612
+ {
613
+ "label": "Text-to-Scene",
614
+ "value": 0.55666,
615
+ "currency": false
616
+ },
617
+ {
618
+ "label": "Detailed Alignment",
619
+ "value": 0.506755,
620
+ "currency": false
621
+ },
622
+ {
623
+ "label": "Overview Alignment",
624
+ "value": 0.529525,
625
+ "currency": false
626
+ },
627
+ {
628
+ "label": "Physical Safety",
629
+ "value": 0.688,
630
+ "currency": false
631
+ },
632
+ {
633
+ "label": "Mean cost / case",
634
+ "value": 0.49154169999999997,
635
+ "currency": true
636
+ }
637
+ ]
638
+ },
639
+ {
640
+ "key": "qwen-on",
641
+ "name": "Qwen 3.8 27B (thinking on)",
642
+ "provider": "Alibaba",
643
+ "metrics": [
644
+ {
645
+ "label": "Text-to-Scene",
646
+ "value": 0.51571,
647
+ "currency": false
648
+ },
649
+ {
650
+ "label": "Detailed Alignment",
651
+ "value": 0.50522,
652
+ "currency": false
653
+ },
654
+ {
655
+ "label": "Overview Alignment",
656
+ "value": 0.45978,
657
+ "currency": false
658
+ },
659
+ {
660
+ "label": "Physical Safety",
661
+ "value": 0.694,
662
+ "currency": false
663
+ },
664
+ {
665
+ "label": "Mean cost / case",
666
+ "value": 0.3344125,
667
+ "currency": true
668
+ }
669
+ ]
670
+ },
671
+ {
672
+ "key": "glm",
673
+ "name": "GLM-5.3 Flash (max)",
674
+ "provider": "Z.ai",
675
+ "metrics": [
676
+ {
677
+ "label": "Text-to-Scene",
678
+ "value": 0.5094299999999999,
679
+ "currency": false
680
+ },
681
+ {
682
+ "label": "Detailed Alignment",
683
+ "value": 0.403365,
684
+ "currency": false
685
+ },
686
+ {
687
+ "label": "Overview Alignment",
688
+ "value": 0.537015,
689
+ "currency": false
690
+ },
691
+ {
692
+ "label": "Physical Safety",
693
+ "value": 0.533,
694
+ "currency": false
695
+ },
696
+ {
697
+ "label": "Mean cost / case",
698
+ "value": 0.710521125,
699
+ "currency": true
700
+ }
701
+ ]
702
+ },
703
+ {
704
+ "key": "gemma-on",
705
+ "name": "Gemma 4 31B (thinking on)",
706
+ "provider": "Google",
707
+ "metrics": [
708
+ {
709
+ "label": "Text-to-Scene",
710
+ "value": 0.470705,
711
+ "currency": false
712
+ },
713
+ {
714
+ "label": "Detailed Alignment",
715
+ "value": 0.4117,
716
+ "currency": false
717
+ },
718
+ {
719
+ "label": "Overview Alignment",
720
+ "value": 0.41593,
721
+ "currency": false
722
+ },
723
+ {
724
+ "label": "Physical Safety",
725
+ "value": 0.694,
726
+ "currency": false
727
+ },
728
+ {
729
+ "label": "Mean cost / case",
730
+ "value": 0.0253001,
731
+ "currency": true
732
+ }
733
+ ]
734
+ },
735
+ {
736
+ "key": "gemma-off",
737
+ "name": "Gemma 4 31B (thinking off)",
738
+ "provider": "Google",
739
+ "metrics": [
740
+ {
741
+ "label": "Text-to-Scene",
742
+ "value": 0.45494,
743
+ "currency": false
744
+ },
745
+ {
746
+ "label": "Detailed Alignment",
747
+ "value": 0.43810000000000004,
748
+ "currency": false
749
+ },
750
+ {
751
+ "label": "Overview Alignment",
752
+ "value": 0.370465,
753
+ "currency": false
754
+ },
755
+ {
756
+ "label": "Physical Safety",
757
+ "value": 0.725,
758
+ "currency": false
759
+ },
760
+ {
761
+ "label": "Mean cost / case",
762
+ "value": 0.0151612,
763
+ "currency": true
764
+ }
765
+ ]
766
+ },
767
+ {
768
+ "key": "inkling",
769
+ "name": "Inkling (high)",
770
+ "provider": "Thinking Machines",
771
+ "metrics": [
772
+ {
773
+ "label": "Text-to-Scene",
774
+ "value": 0.42498500000000006,
775
+ "currency": false
776
+ },
777
+ {
778
+ "label": "Detailed Alignment",
779
+ "value": 0.392605,
780
+ "currency": false
781
+ },
782
+ {
783
+ "label": "Overview Alignment",
784
+ "value": 0.336705,
785
+ "currency": false
786
+ },
787
+ {
788
+ "label": "Physical Safety",
789
+ "value": 0.722,
790
+ "currency": false
791
+ },
792
+ {
793
+ "label": "Mean cost / case",
794
+ "value": 0.20252835,
795
+ "currency": true
796
+ }
797
+ ]
798
+ },
799
+ {
800
+ "key": "deepseek",
801
+ "name": "DeepSeek V4.1 Flash (high)",
802
+ "provider": "DeepSeek",
803
+ "metrics": [
804
+ {
805
+ "label": "Text-to-Scene",
806
+ "value": 0.24269,
807
+ "currency": false
808
+ },
809
+ {
810
+ "label": "Detailed Alignment",
811
+ "value": 0.216595,
812
+ "currency": false
813
+ },
814
+ {
815
+ "label": "Overview Alignment",
816
+ "value": 0.16134500000000002,
817
+ "currency": false
818
+ },
819
+ {
820
+ "label": "Physical Safety",
821
+ "value": 0.513,
822
+ "currency": false
823
+ },
824
+ {
825
+ "label": "Mean cost / case",
826
+ "value": 0.193865,
827
+ "currency": true
828
+ }
829
+ ]
830
+ }
831
+ ],
832
+ "i2s": [
833
+ {
834
+ "key": "gemini",
835
+ "name": "Gemini 3.8 Flash (high)",
836
+ "provider": "Google",
837
+ "metrics": [
838
+ {
839
+ "label": "Image-to-Scene",
840
+ "value": 0.5810600533333334,
841
+ "currency": false
842
+ },
843
+ {
844
+ "label": "Repair F1",
845
+ "value": 0.527,
846
+ "currency": false
847
+ },
848
+ {
849
+ "label": "Physical Safety",
850
+ "value": 0.796,
851
+ "currency": false
852
+ },
853
+ {
854
+ "label": "Indoor",
855
+ "value": 0.71653332,
856
+ "currency": false
857
+ },
858
+ {
859
+ "label": "Outdoor",
860
+ "value": 0.5133234200000001,
861
+ "currency": false
862
+ },
863
+ {
864
+ "label": "Mean cost / case",
865
+ "value": 1.3523245042517007,
866
+ "currency": true
867
+ }
868
+ ]
869
+ },
870
+ {
871
+ "key": "astra",
872
+ "name": "GPT-6 Astra (max)",
873
+ "provider": "OpenAI",
874
+ "metrics": [
875
+ {
876
+ "label": "Image-to-Scene",
877
+ "value": 0.5148505733333334,
878
+ "currency": false
879
+ },
880
+ {
881
+ "label": "Repair F1",
882
+ "value": 0.445,
883
+ "currency": false
884
+ },
885
+ {
886
+ "label": "Physical Safety",
887
+ "value": 0.796,
888
+ "currency": false
889
+ },
890
+ {
891
+ "label": "Indoor",
892
+ "value": 0.78546656,
893
+ "currency": false
894
+ },
895
+ {
896
+ "label": "Outdoor",
897
+ "value": 0.37954258,
898
+ "currency": false
899
+ },
900
+ {
901
+ "label": "Mean cost / case",
902
+ "value": 3.3217229090909095,
903
+ "currency": true
904
+ }
905
+ ]
906
+ },
907
+ {
908
+ "key": "opus",
909
+ "name": "Claude Opus 5 (max)",
910
+ "provider": "Anthropic",
911
+ "metrics": [
912
+ {
913
+ "label": "Image-to-Scene",
914
+ "value": 0.46809998666666675,
915
+ "currency": false
916
+ },
917
+ {
918
+ "label": "Repair F1",
919
+ "value": 0.389,
920
+ "currency": false
921
+ },
922
+ {
923
+ "label": "Physical Safety",
924
+ "value": 0.786,
925
+ "currency": false
926
+ },
927
+ {
928
+ "label": "Indoor",
929
+ "value": 0.61843384,
930
+ "currency": false
931
+ },
932
+ {
933
+ "label": "Outdoor",
934
+ "value": 0.39293306,
935
+ "currency": false
936
+ },
937
+ {
938
+ "label": "Mean cost / case",
939
+ "value": 4.459671546394558,
940
+ "currency": true
941
+ }
942
+ ]
943
+ },
944
+ {
945
+ "key": "fable",
946
+ "name": "Claude Fable 5.1 (max)",
947
+ "provider": "Anthropic",
948
+ "metrics": [
949
+ {
950
+ "label": "Image-to-Scene",
951
+ "value": 0.4243479600000001,
952
+ "currency": false
953
+ },
954
+ {
955
+ "label": "Repair F1",
956
+ "value": 0.332,
957
+ "currency": false
958
+ },
959
+ {
960
+ "label": "Physical Safety",
961
+ "value": 0.795,
962
+ "currency": false
963
+ },
964
+ {
965
+ "label": "Indoor",
966
+ "value": 0.53523332,
967
+ "currency": false
968
+ },
969
+ {
970
+ "label": "Outdoor",
971
+ "value": 0.36890528000000006,
972
+ "currency": false
973
+ },
974
+ {
975
+ "label": "Mean cost / case",
976
+ "value": 3.0888859328063245,
977
+ "currency": true
978
+ }
979
+ ]
980
+ },
981
+ {
982
+ "key": "sol",
983
+ "name": "GPT-5.6 Sol (high)",
984
+ "provider": "OpenAI",
985
+ "metrics": [
986
+ {
987
+ "label": "Image-to-Scene",
988
+ "value": 0.3929589333333333,
989
+ "currency": false
990
+ },
991
+ {
992
+ "label": "Repair F1",
993
+ "value": 0.319,
994
+ "currency": false
995
+ },
996
+ {
997
+ "label": "Physical Safety",
998
+ "value": 0.689,
999
+ "currency": false
1000
+ },
1001
+ {
1002
+ "label": "Indoor",
1003
+ "value": 0.49742972,
1004
+ "currency": false
1005
+ },
1006
+ {
1007
+ "label": "Outdoor",
1008
+ "value": 0.34072354,
1009
+ "currency": false
1010
+ },
1011
+ {
1012
+ "label": "Mean cost / case",
1013
+ "value": 1.8773877185185188,
1014
+ "currency": true
1015
+ }
1016
+ ]
1017
+ },
1018
+ {
1019
+ "key": "muse",
1020
+ "name": "Muse Spark 1.3 (medium)",
1021
+ "provider": "Meta",
1022
+ "metrics": [
1023
+ {
1024
+ "label": "Image-to-Scene",
1025
+ "value": 0.35821573333333334,
1026
+ "currency": false
1027
+ },
1028
+ {
1029
+ "label": "Repair F1",
1030
+ "value": 0.246,
1031
+ "currency": false
1032
+ },
1033
+ {
1034
+ "label": "Physical Safety",
1035
+ "value": 0.807,
1036
+ "currency": false
1037
+ },
1038
+ {
1039
+ "label": "Indoor",
1040
+ "value": 0.63253332,
1041
+ "currency": false
1042
+ },
1043
+ {
1044
+ "label": "Outdoor",
1045
+ "value": 0.22105694,
1046
+ "currency": false
1047
+ },
1048
+ {
1049
+ "label": "Mean cost / case",
1050
+ "value": 0.07172788461538461,
1051
+ "currency": true
1052
+ }
1053
+ ]
1054
+ },
1055
+ {
1056
+ "key": "glm",
1057
+ "name": "GLM-5.3 Flash (max)",
1058
+ "provider": "Z.ai",
1059
+ "metrics": [
1060
+ {
1061
+ "label": "Image-to-Scene",
1062
+ "value": 0.3199877333333333,
1063
+ "currency": false
1064
+ },
1065
+ {
1066
+ "label": "Repair F1",
1067
+ "value": 0.188,
1068
+ "currency": false
1069
+ },
1070
+ {
1071
+ "label": "Physical Safety",
1072
+ "value": 0.848,
1073
+ "currency": false
1074
+ },
1075
+ {
1076
+ "label": "Indoor",
1077
+ "value": 0.46533411999999996,
1078
+ "currency": false
1079
+ },
1080
+ {
1081
+ "label": "Outdoor",
1082
+ "value": 0.24731454,
1083
+ "currency": false
1084
+ },
1085
+ {
1086
+ "label": "Mean cost / case",
1087
+ "value": 0.09209057222222222,
1088
+ "currency": true
1089
+ }
1090
+ ]
1091
+ },
1092
+ {
1093
+ "key": "qwen-on",
1094
+ "name": "Qwen 3.8 27B (thinking on)",
1095
+ "provider": "Alibaba",
1096
+ "metrics": [
1097
+ {
1098
+ "label": "Image-to-Scene",
1099
+ "value": 0.2261779866666667,
1100
+ "currency": false
1101
+ },
1102
+ {
1103
+ "label": "Repair F1",
1104
+ "value": 0.118,
1105
+ "currency": false
1106
+ },
1107
+ {
1108
+ "label": "Physical Safety",
1109
+ "value": 0.66,
1110
+ "currency": false
1111
+ },
1112
+ {
1113
+ "label": "Indoor",
1114
+ "value": 0.29651112,
1115
+ "currency": false
1116
+ },
1117
+ {
1118
+ "label": "Outdoor",
1119
+ "value": 0.19101142,
1120
+ "currency": false
1121
+ },
1122
+ {
1123
+ "label": "Mean cost / case",
1124
+ "value": 0.2605628115151515,
1125
+ "currency": true
1126
+ }
1127
+ ]
1128
+ },
1129
+ {
1130
+ "key": "deepseek",
1131
+ "name": "DeepSeek V4.1 Flash (high)",
1132
+ "provider": "DeepSeek",
1133
+ "metrics": [
1134
+ {
1135
+ "label": "Image-to-Scene",
1136
+ "value": 0.21048916,
1137
+ "currency": false
1138
+ },
1139
+ {
1140
+ "label": "Repair F1",
1141
+ "value": 0.066,
1142
+ "currency": false
1143
+ },
1144
+ {
1145
+ "label": "Physical Safety",
1146
+ "value": 0.787,
1147
+ "currency": false
1148
+ },
1149
+ {
1150
+ "label": "Indoor",
1151
+ "value": 0.18933412,
1152
+ "currency": false
1153
+ },
1154
+ {
1155
+ "label": "Outdoor",
1156
+ "value": 0.22106668,
1157
+ "currency": false
1158
+ },
1159
+ {
1160
+ "label": "Mean cost / case",
1161
+ "value": 0.054194520202020195,
1162
+ "currency": true
1163
+ }
1164
+ ]
1165
+ },
1166
+ {
1167
+ "key": "qwen-off",
1168
+ "name": "Qwen 3.8 27B (thinking off)",
1169
+ "provider": "Alibaba",
1170
+ "metrics": [
1171
+ {
1172
+ "label": "Image-to-Scene",
1173
+ "value": 0.19970338666666668,
1174
+ "currency": false
1175
+ },
1176
+ {
1177
+ "label": "Repair F1",
1178
+ "value": 0.083,
1179
+ "currency": false
1180
+ },
1181
+ {
1182
+ "label": "Physical Safety",
1183
+ "value": 0.667,
1184
+ "currency": false
1185
+ },
1186
+ {
1187
+ "label": "Indoor",
1188
+ "value": 0.26629816,
1189
+ "currency": false
1190
+ },
1191
+ {
1192
+ "label": "Outdoor",
1193
+ "value": 0.166406,
1194
+ "currency": false
1195
+ },
1196
+ {
1197
+ "label": "Mean cost / case",
1198
+ "value": 0.27672816366207137,
1199
+ "currency": true
1200
+ }
1201
+ ]
1202
+ },
1203
+ {
1204
+ "key": "inkling",
1205
+ "name": "Inkling (high)",
1206
+ "provider": "Thinking Machines",
1207
+ "metrics": [
1208
+ {
1209
+ "label": "Image-to-Scene",
1210
+ "value": 0.19801974666666666,
1211
+ "currency": false
1212
+ },
1213
+ {
1214
+ "label": "Repair F1",
1215
+ "value": 0.095,
1216
+ "currency": false
1217
+ },
1218
+ {
1219
+ "label": "Physical Safety",
1220
+ "value": 0.609,
1221
+ "currency": false
1222
+ },
1223
+ {
1224
+ "label": "Indoor",
1225
+ "value": 0.1690288,
1226
+ "currency": false
1227
+ },
1228
+ {
1229
+ "label": "Outdoor",
1230
+ "value": 0.21251522,
1231
+ "currency": false
1232
+ },
1233
+ {
1234
+ "label": "Mean cost / case",
1235
+ "value": 0.7541276882539681,
1236
+ "currency": true
1237
+ }
1238
+ ]
1239
+ },
1240
+ {
1241
+ "key": "grok",
1242
+ "name": "Grok 4.6 (high)",
1243
+ "provider": "xAI",
1244
+ "metrics": [
1245
+ {
1246
+ "label": "Image-to-Scene",
1247
+ "value": 0.18414012,
1248
+ "currency": false
1249
+ },
1250
+ {
1251
+ "label": "Repair F1",
1252
+ "value": 0.044,
1253
+ "currency": false
1254
+ },
1255
+ {
1256
+ "label": "Physical Safety",
1257
+ "value": 0.744,
1258
+ "currency": false
1259
+ },
1260
+ {
1261
+ "label": "Indoor",
1262
+ "value": 0.1968008,
1263
+ "currency": false
1264
+ },
1265
+ {
1266
+ "label": "Outdoor",
1267
+ "value": 0.17780978,
1268
+ "currency": false
1269
+ },
1270
+ {
1271
+ "label": "Mean cost / case",
1272
+ "value": 0.2634673259259259,
1273
+ "currency": true
1274
+ }
1275
+ ]
1276
+ },
1277
+ {
1278
+ "key": "gemma-on",
1279
+ "name": "Gemma 4 31B (thinking on)",
1280
+ "provider": "Google",
1281
+ "metrics": [
1282
+ {
1283
+ "label": "Image-to-Scene",
1284
+ "value": 0.12554015999999998,
1285
+ "currency": false
1286
+ },
1287
+ {
1288
+ "label": "Repair F1",
1289
+ "value": 0.003,
1290
+ "currency": false
1291
+ },
1292
+ {
1293
+ "label": "Physical Safety",
1294
+ "value": 0.615,
1295
+ "currency": false
1296
+ },
1297
+ {
1298
+ "label": "Indoor",
1299
+ "value": 0.12704028,
1300
+ "currency": false
1301
+ },
1302
+ {
1303
+ "label": "Outdoor",
1304
+ "value": 0.1247901,
1305
+ "currency": false
1306
+ },
1307
+ {
1308
+ "label": "Mean cost / case",
1309
+ "value": 0.028434150793650796,
1310
+ "currency": true
1311
+ }
1312
+ ]
1313
+ },
1314
+ {
1315
+ "key": "gemma-off",
1316
+ "name": "Gemma 4 31B (thinking off)",
1317
+ "provider": "Google",
1318
+ "metrics": [
1319
+ {
1320
+ "label": "Image-to-Scene",
1321
+ "value": 0.11503794666666667,
1322
+ "currency": false
1323
+ },
1324
+ {
1325
+ "label": "Repair F1",
1326
+ "value": 0.001,
1327
+ "currency": false
1328
+ },
1329
+ {
1330
+ "label": "Physical Safety",
1331
+ "value": 0.572,
1332
+ "currency": false
1333
+ },
1334
+ {
1335
+ "label": "Indoor",
1336
+ "value": 0.11239600000000001,
1337
+ "currency": false
1338
+ },
1339
+ {
1340
+ "label": "Outdoor",
1341
+ "value": 0.11635892,
1342
+ "currency": false
1343
+ },
1344
+ {
1345
+ "label": "Mean cost / case",
1346
+ "value": 0.01913622993197279,
1347
+ "currency": true
1348
+ }
1349
+ ]
1350
+ }
1351
+ ]
1352
+ }
index.html CHANGED
The diff for this file is too large to render. See raw diff
 
tests/scene-assets.test.mjs ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import test from 'node:test';import assert from 'node:assert/strict';import {AssetQueue,fetchSceneBytes} from '../assets/scene-assets.js';
2
+ const tick=()=>new Promise(r=>setTimeout(r,0));
3
+ test('shared requests deduplicate, concurrency is capped, and releasing the last viewer cancels stale work',async()=>{
4
+ let started=[],resolve={},aborted=[],disposed=[];
5
+ const q=new AssetQueue({maxConcurrent:2,maxIdle:0,dispose:a=>disposed.push(a.key),load:(key,signal)=>new Promise((r,j)=>{started.push(key);resolve[key]=()=>r({key,bytes:1});signal.addEventListener('abort',()=>{aborted.push(key);j(new DOMException('Aborted','AbortError'));});})});
6
+ const a=q.retain('A',()=>{}),a2=q.retain('A',()=>{}),b=q.retain('B',()=>{}),c=q.retain('C',()=>{});await tick();assert.deepEqual(started,['A','B']);assert.equal(q.peakRunning,2);
7
+ a.release();assert.equal(aborted.length,0);a2.release();await tick();assert.deepEqual(aborted,['A']);assert.deepEqual(started,['A','B','C']);
8
+ resolve.B();resolve.C();await tick();b.release();c.release();assert.equal(q.running,0);assert.equal(q.entries.size,0);assert.deepEqual(disposed.sort(),['B','C']);
9
+ });
10
+ test('a transient error retries and a later subscriber reuses the asset',async()=>{
11
+ let attempts=0;const states=[];const q=new AssetQueue({load:async key=>{if(++attempts===1)throw Error('503');return {key,bytes:2};},dispose:()=>{}});
12
+ const a=q.retain('A',e=>states.push(e.state));await new Promise(r=>setTimeout(r,850));assert.equal(attempts,2);assert.ok(states.includes('retrying'));assert.equal(states.at(-1),'ready');
13
+ const b=q.retain('A',()=>{});await tick();assert.equal(attempts,2);a.release();b.release();
14
+ });
15
+ test('a stalled fetch reaches a bounded error, and partial responses are rejected',async()=>{
16
+ const stalled=(_url,{signal})=>new Promise((resolve,reject)=>signal.addEventListener('abort',()=>reject(new DOMException('Abort','AbortError'))));
17
+ await assert.rejects(fetchSceneBytes('test',new AbortController().signal,()=>{},{idleMs:15,totalMs:100,fetcher:stalled}),/stopped responding/);
18
+ await assert.rejects(fetchSceneBytes('test',new AbortController().signal,()=>{},{fetcher:async()=>new Response(new Uint8Array([1,2]),{headers:{'content-length':'4'}})}),/incomplete/);
19
+ });
20
+ test('download progress retains every byte and aborts propagate',async()=>{
21
+ const p=[];const b=await fetchSceneBytes('test',new AbortController().signal,x=>p.push(x),{fetcher:async()=>new Response(new Uint8Array([1,2,3]),{headers:{'content-length':'3'}})});assert.deepEqual([...b],[1,2,3]);assert.equal(p.at(-1).received,3);
22
+ const c=new AbortController();c.abort();await assert.rejects(fetchSceneBytes('test',c.signal,()=>{},{fetcher:async(_,{signal})=>{signal.throwIfAborted();}}),{name:'AbortError'});
23
+ });