11import { For , createSignal , onCleanup , onMount } from "solid-js"
22import { useI18n } from "~/context/i18n"
3- import { RollingNumber } from "./rolling-number"
43
54export function LimitsGraph ( props : { href : string } ) {
65 let root ! : HTMLElement
76 const [ visible , setVisible ] = createSignal ( false )
8- const [ boosted , setBoosted ] = createSignal ( false )
9- const [ promoted , setPromoted ] = createSignal < string [ ] > ( [ ] )
10- let timer : ReturnType < typeof setTimeout > | undefined
117
128 const i18n = useI18n ( )
139
1410 onMount ( ( ) => {
1511 const motion = window . matchMedia ( "(prefers-reduced-motion: reduce)" )
1612 const finish = ( ) => {
1713 if ( ! motion . matches ) return
18- clearTimeout ( timer )
1914 setVisible ( true )
20- setBoosted ( true )
21- setPromoted ( bonuses . map ( ( model ) => model . id ) )
2215 }
2316 motion . addEventListener ( "change" , finish )
2417 onCleanup ( ( ) => {
25- clearTimeout ( timer )
2618 motion . removeEventListener ( "change" , finish )
2719 } )
2820 if ( motion . matches ) return finish ( )
@@ -46,18 +38,17 @@ export function LimitsGraph(props: { href: string }) {
4638 { id : "grok-4.6" , name : "Grok 4.6" , req : 169 } ,
4739 { id : "hy4-preview" , name : "Hy4 preview" , req : 1350 } ,
4840 { id : "gpt-5.6-luna" , name : "GPT 5.6 Luna" , req : 2050 } ,
49- { id : "glm-5.3-flash" , name : "GLM-5.3-Flash" , req : 3160 , baseReq : 1580 , bonus : "2x usage" } ,
5041 { id : "minimax-m3" , name : "MiniMax M3" , req : 3200 } ,
5142 { id : "qwen3.7-plus" , name : "Qwen3.7 Plus" , req : 4300 } ,
5243 { id : "hy3" , name : "Hy3" , req : 4300 } ,
5344 { id : "qwen3.8-flash" , name : "Qwen3.8 Flash" , req : 5400 } ,
45+ { id : "glm-5.3-flash" , name : "GLM-5.3-Flash" , req : 6320 } ,
5446 { id : "deepseek-v4-flash" , name : "DeepSeek V4 Flash" , req : 7600 } ,
5547 { id : "longcat-2.0" , name : "LongCat-2.0" , req : 11400 } ,
5648 { id : "omen-alpha" , name : "Omen Alpha" , req : 11600 } ,
5749 { id : "mimo-v2.5" , name : "MiMo-V2.5" , req : 30100 } ,
5850 { id : "muse-spark-1.3-contributor" , name : "Muse Spark 1.3 Contributor" , req : 45300 , edge : true } ,
5951 ] . map ( ( model , index ) => ( { ...model , d : `${ 50 + index * 25 } ms` } ) )
60- const bonuses = graph . filter ( ( model ) => model . baseReq )
6152
6253 const w = 1040
6354 const chartW = 720
@@ -102,34 +93,13 @@ export function LimitsGraph(props: { href: string }) {
10293 const py = ( n : number ) => `${ ( n / h ) * 100 } %`
10394 const lx = px ( left - 16 )
10495 const ty = py ( h - 18 )
105- const timing = ( ) => {
106- const style = getComputedStyle ( root )
107- return {
108- duration : Number . parseFloat ( style . getPropertyValue ( "--bonus-duration" ) ) ,
109- easing : style . getPropertyValue ( "--spring-easing" ) . trim ( ) ,
110- spinEasing : style . getPropertyValue ( "--digit-easing" ) . trim ( ) ,
111- }
112- }
11396
11497 return (
11598 < figure
11699 data-component = "limit-graph"
117100 aria-label = { i18n . t ( "go.graph.label" ) }
118101 data-visible = { visible ( ) ? "" : undefined }
119- data-boosted = { boosted ( ) ? "" : undefined }
120102 ref = { root }
121- onAnimationStart = { ( event ) => {
122- if ( ! ( event . target instanceof SVGElement ) || event . animationName !== "go-graph-reveal" ) return
123- if ( event . target . hasAttribute ( "data-stage-end" ) && ! boosted ( ) ) {
124- const duration = Number . parseFloat ( getComputedStyle ( root ) . getPropertyValue ( "--reveal-duration" ) )
125- timer = setTimeout ( ( ) => setBoosted ( true ) , duration * 0.6 )
126- return
127- }
128- if ( event . target . dataset . animate !== "bonus" ) return
129- const model = event . target . dataset . model
130- if ( ! model ) return
131- setPromoted ( ( current ) => [ ...current , model ] )
132- } }
133103 >
134104 < div data-slot = "plot" >
135105 < svg
@@ -152,33 +122,17 @@ export function LimitsGraph(props: { href: string }) {
152122 < g data-slot = "bars" >
153123 < For each = { graph } >
154124 { ( m , i ) => (
155- < >
156- < rect
157- data-animate = "bar"
158- data-model = { m . id }
159- data-stage-end = { i ( ) === graph . length - 1 ? "" : undefined }
160- style = { { "--d" : m . d } }
161- x = { left }
162- y = { gy ( i ( ) ) - bh / 2 }
163- width = { Math . max ( 0 , ( "infinite" in m ? infiniteX : x ( ratio ( m . baseReq ?? m . req ) ) ) - left ) }
164- height = { bh }
165- data-bar
166- data-kind = { "infinite" in m ? "infinite" : "go" }
167- />
168- { m . baseReq && (
169- < rect
170- data-animate = "bonus"
171- data-model = { m . id }
172- style = { { "--bonus-delay" : `${ bonuses . indexOf ( m ) * 60 } ms` } }
173- x = { x ( ratio ( m . baseReq ) ) + 2 }
174- y = { gy ( i ( ) ) - bh / 2 }
175- width = { Math . max ( 0 , x ( ratio ( m . req ) ) - x ( ratio ( m . baseReq ) ) - 2 ) }
176- height = { bh }
177- data-bar
178- data-kind = "promo"
179- />
180- ) }
181- </ >
125+ < rect
126+ data-animate = "bar"
127+ data-model = { m . id }
128+ style = { { "--d" : m . d } }
129+ x = { left }
130+ y = { gy ( i ( ) ) - bh / 2 }
131+ width = { Math . max ( 0 , ( "infinite" in m ? infiniteX : x ( ratio ( m . req ) ) ) - left ) }
132+ height = { bh }
133+ data-bar
134+ data-kind = { "infinite" in m ? "infinite" : "go" }
135+ />
182136 ) }
183137 </ For >
184138 </ g >
@@ -213,25 +167,14 @@ export function LimitsGraph(props: { href: string }) {
213167 data-model = { m . id }
214168 data-edge = { "edge" in m ? "" : undefined }
215169 data-infinite = { "infinite" in m ? "" : undefined }
216- data-promo = { m . baseReq ? "" : undefined }
217170 style = { {
218- "--x" : px ( "infinite" in m ? infiniteX : x ( ratio ( m . baseReq ?? m . req ) ) ) ,
171+ "--x" : px ( "infinite" in m ? infiniteX : x ( ratio ( m . req ) ) ) ,
219172 "--y" : py ( gy ( i ( ) ) ) ,
220173 "--d" : m . d ,
221- "--bonus-delay" : `${ Math . max ( 0 , bonuses . indexOf ( m ) ) * 60 } ms` ,
222- "--travel" : `${ "infinite" in m ? 0 : ( ( x ( ratio ( m . req ) ) - x ( ratio ( m . baseReq ?? m . req ) ) ) / w ) * 100 } cqw` ,
223174 } }
224175 >
225176 < span data-label >
226- { ! ( "infinite" in m ) && m . baseReq ? (
227- < RollingNumber
228- value = { promoted ( ) . includes ( m . id ) ? m . req : m . baseReq }
229- target = { m . req }
230- timing = { timing }
231- />
232- ) : (
233- < span data-value > { "infinite" in m ? "\u221e" : m . req . toLocaleString ( ) } </ span >
234- ) }
177+ < span data-value > { "infinite" in m ? "\u221e" : m . req . toLocaleString ( ) } </ span >
235178 < span data-name > { m . name } </ span >
236179 { m . id === "muse-spark-1.3-contributor" && (
237180 < span data-regions >
@@ -244,7 +187,6 @@ export function LimitsGraph(props: { href: string }) {
244187 ) }
245188 { "infinite" in m && < span data-limited > ({ i18n . t ( "go.graph.limitedTime" ) } )</ span > }
246189 </ span >
247- { "bonus" in m && < span data-bonus > { m . bonus } </ span > }
248190 </ span >
249191 ) }
250192 </ For >
0 commit comments