1import{r as w,j as de}from"./chunk-6CSD65Y2-C0TiM0T8.js";import{a as E,c as _e,b as J}from"./brand-palette-CrTJb4HX.js";import{u as Ne}from"./use-in-view-9xR4HxK7.js";import{u as Be}from"./use-reduced-motion-_rAsVjG9.js";import{f as oe,c as fe}from"./frame-BT3eX1Ww.js";const k=40,F=24,K=4,ve=k*F*K,Ye=48,Xe=1e3/60,X=.16;function De(){return{read:new Float32Array(ve),write:new Float32Array(ve)}}function O(r,a,c){return Math.min(c,Math.max(a,r))}function Ue(r,a){return Math.min(1,Math.hypot(r,a)*Ye)}function b(r,a,c,f){const m=O(a,0,k-1),v=O(c,0,F-1),l=Math.floor(m),n=Math.floor(v),g=Math.min(k-1,l+1),e=Math.min(F-1,n+1),t=m-l,x=v-n,N=r[(n*k+l)*K+f],P=r[(n*k+g)*K+f],R=r[(e*k+l)*K+f],L=r[(e*k+g)*K+f],C=N+(P-N)*t,I=R+(L-R)*t;return C+(I-C)*x}function We(r,a,c,f,m,v){const l=O(a,0,1)*(k-1),n=O(c,0,1)*(F-1),g=O(v,0,1),e=1.2+g*1.25,t=Math.ceil(e*2),x=Math.max(0,Math.floor(l)-t),N=Math.min(k-1,Math.ceil(l)+t),P=Math.max(0,Math.floor(n)-t),R=Math.min(F-1,Math.ceil(n)+t),L=e*e;for(let C=P;C<=R;C++)for(let I=x;I<=N;I++){const T=I-l,D=C-n,y=Math.exp(-(T*T+D*D)/(L*.72));if(y<.01)continue;const p=(C*k+I)*K;r.read[p]=O(r.read[p]+f*y*.48,-X,X),r.read[p+1]=O(r.read[p+1]+m*y*.48,-X,X),r.read[p+2]=Math.min(1.2,r.read[p+2]+y*g*.72)}}function Ve(r,a,c,f,m,v,l,n){const g=Math.hypot((f-a)*k,(m-c)*F),e=Math.max(1,Math.ceil(g*.75));for(let t=1;t<=e;t++){const x=t/e;We(r,a+(f-a)*x,c+(m-c)*x,v,l,n)}}function ze(r,a){const c=O(a/Xe,0,4),f=Math.pow(.935,c),m=Math.pow(.985,c),v=Math.min(.08,c*.08),l=c*.62,n=r.read,g=r.write;for(let e=0;e<F;e++)for(let t=0;t<k;t++){const x=(e*k+t)*K,N=n[x],P=n[x+1],R=t-N*k*l,L=e-P*F*l,C=b(n,R,L,0),I=b(n,R,L,1),T=b(n,R,L,2),D=(b(n,t-1,e,0)+b(n,t+1,e,0)+b(n,t,e-1,0)+b(n,t,e+1,0))*.25,y=(b(n,t-1,e,1)+b(n,t+1,e,1)+b(n,t,e-1,1)+b(n,t,e+1,1))*.25,p=(b(n,t-1,e,2)+b(n,t+1,e,2)+b(n,t,e-1,2)+b(n,t,e+1,2))*.25;g[x]=O((C+(D-C)*v)*f,-X,X),g[x+1]=O((I+(y-I)*v)*f,-X,X),g[x+2]=Math.max(0,T+(p-T)*v*.65)*m,g[x+3]=0}r.read=g,r.write=n}function qe(r){r.read.fill(0),r.write.fill(0)}const Ge=18,pe=.8,he=9,le=64,Pe=32,Le=le*Pe;let ue=null;function He(r){return ue||(ue=r.requestAdapter().then(a=>(a==null?void 0:a.requestDevice())??null).catch(()=>(ue=null,null))),ue}const A={durationMs:2600,wordmarkWindow:.52,fieldStart:.5,wordRows:6,wordStagger:.12,wipeDuration:.52,rowStagger:.008,noise:.08,feather:.08},H={velocityBlend:.68,maxVelocity:.14,dampingPerFrame:.975,referenceFrameMs:1e3/60};function u(r){return`vec3f(${r.join(", ")})`}function Ke(r){const a=new Float32Array(Le);if(!r)return{data:a,width:0,height:0};const c=r.split(` 2`).slice(0,Pe);let f=0;return c.forEach((m,v)=>{f=Math.max(f,Math.min(m.length,le));for(let l=0;l<Math.min(m.length,le);l++)m[l]==="#"&&(a[v*le+l]=1)}),{data:a,width:f,height:c.length}}const je=` 3struct Uniforms { 4 viewport: vec4f, 5 controls: vec4f, 6 edgeTreatment: vec4f, 7 pointer: vec4f, 8 maskPlacement: vec4f, 9 maskColour: vec4f, 10} 11 12@group(0) @binding(0) var<uniform> uniforms: Uniforms; 13@group(0) @binding(1) var<storage, read> pointerFlow: array<vec4f>; 14@group(0) @binding(2) var<storage, read> glyphMaskData: array<f32>; 15 16const FLOW_COLUMNS: i32 = ${k}; 17const FLOW_ROWS: i32 = ${F}; 18const MASK_COLUMNS: i32 = ${le}; 19 20fn flowCell(x: i32, y: i32) -> vec4f { 21 let safeX = clamp(x, 0, FLOW_COLUMNS - 1); 22 let safeY = clamp(y, 0, FLOW_ROWS - 1); 23 return pointerFlow[u32(safeY * FLOW_COLUMNS + safeX)]; 24} 25 26fn samplePointerFlow(uv: vec2f) -> vec4f { 27 let coordinate = clamp(uv, vec2f(0.0), vec2f(1.0)) 28 * vec2f(f32(FLOW_COLUMNS - 1), f32(FLOW_ROWS - 1)); 29 let lower = vec2i(floor(coordinate)); 30 let upper = min(lower + vec2i(1), vec2i(FLOW_COLUMNS - 1, FLOW_ROWS - 1)); 31 let blend = fract(coordinate); 32 let top = mix( 33 flowCell(lower.x, lower.y), 34 flowCell(upper.x, lower.y), 35 blend.x 36 ); 37 let bottom = mix( 38 flowCell(lower.x, upper.y), 39 flowCell(upper.x, upper.y), 40 blend.x 41 ); 42 return mix(top, bottom, blend.y); 43} 44 45fn field(uv: vec2f, time: f32) -> f32 { 46 let aspect = uniforms.viewport.x / max(uniforms.viewport.y, 1.0); 47 var p = vec2f((uv.x - 0.56) * aspect, uv.y - 0.52); 48 let warpAmount = uniforms.controls.z; 49 let warp = vec2f( 50 sin(p.y * 5.2 + time * 0.34 + uniforms.viewport.w) * 0.13, 51 sin(p.x * 4.1 - time * 0.27) * 0.1 52 ) * warpAmount; 53 p += warp; 54 55 let foldA = sin(p.x * 7.0 + p.y * 3.1 + time * 0.42); 56 let foldB = cos(p.y * 8.2 - p.x * 2.7 - time * 0.31); 57 let ribbon = abs(p.y + foldA * 0.16 + foldB * 0.07); 58 let body = 1.0 - smoothstep(0.18, 0.72, length(p * vec2f(0.84, 1.12))); 59 let wave = 1.0 - smoothstep(0.06, 0.42, ribbon); 60 let lobe = 1.0 - smoothstep( 61 0.16, 62 0.68, 63 length(p - vec2f(0.3 + sin(time * 0.21) * 0.07, -0.08)) 64 ); 65 66 return clamp(max(body * 0.82 + wave * 0.48, lobe * 0.72), 0.0, 1.0); 67} 68 69fn gradient3(t: f32, start: vec3f, middle: vec3f, end: vec3f) -> vec3f { 70 if (t < 0.5) { 71 return mix(start, middle, t * 2.0); 72 } 73 return mix(middle, end, (t - 0.5) * 2.0); 74} 75 76fn palette(t: f32, paletteIndex: f32) -> vec3f { 77 let lemon = ${u(E[0].rgb)}; 78 let rind = ${u(E[1].rgb)}; 79 let blueberry = ${u(E[2].rgb)}; 80 let blackcurrant = ${u(E[3].rgb)}; 81 let dragonfruit = ${u(E[4].rgb)}; 82 let watermelon = ${u(E[5].rgb)}; 83 let tangerine = ${u(_e.rgb)}; 84 let paper = ${u(J.paper.rgb)}; 85 let ink = ${u(J.ink.rgb)}; 86 let uiPaper = ${u(J.uiPaper.rgb)}; 87 let preset = i32(round(paletteIndex)); 88 89 if (preset == 1) { 90 return gradient3(t, lemon, mix(lemon, paper, 0.28), rind); 91 } 92 if (preset == 2) { 93 return gradient3(t, lemon, rind, mix(rind, blueberry, 0.28)); 94 } 95 if (preset == 3) { 96 return gradient3(t, rind, blueberry, blackcurrant); 97 } 98 if (preset == 4) { 99 return gradient3(t, blueberry, blackcurrant, dragonfruit); 100 } 101 if (preset == 5) { 102 return gradient3(t, lemon, dragonfruit, watermelon); 103 } 104 if (preset == 6) { 105 return gradient3(t, rind, mix(rind, ink, 0.72), watermelon); 106 } 107 if (preset == 7) { 108 return gradient3(t, uiPaper, mix(uiPaper, blueberry, 0.2), blueberry); 109 } 110 if (preset == 8) { 111 return gradient3(t, mix(dragonfruit, blackcurrant, 0.3), dragonfruit, mix(dragonfruit, paper, 0.24)); 112 } 113 if (preset == ${he}) { 114 return gradient3(t, ink, mix(ink, paper, 0.09), mix(ink, paper, 0.24)); 115 } 116 if (preset == 10) { 117 return gradient3(t, mix(tangerine, lemon, 0.35), tangerine, mix(tangerine, watermelon, 0.4)); 118 } 119 if (t < 0.2) { 120 return mix(lemon, rind, t / 0.2); 121 } 122 if (t < 0.4) { 123 return mix(rind, blueberry, (t - 0.2) / 0.2); 124 } 125 if (t < 0.6) { 126 return mix(blueberry, blackcurrant, (t - 0.4) / 0.2); 127 } 128 if (t < 0.8) { 129 return mix(blackcurrant, dragonfruit, (t - 0.6) / 0.2); 130 } 131 return mix(dragonfruit, watermelon, (t - 0.8) / 0.2); 132} 133 134fn paletteSolid(paletteIndex: f32) -> vec3f { 135 let preset = i32(round(paletteIndex)); 136 if (preset == 2 || preset == 6) { 137 return ${u(E[1].rgb)}; 138 } 139 if (preset == 3) { 140 return ${u(E[2].rgb)}; 141 } 142 if (preset == 4) { 143 return ${u(E[3].rgb)}; 144 } 145 if (preset == 5) { 146 return ${u(E[5].rgb)}; 147 } 148 if (preset == 7) { 149 return ${u(J.uiPaper.rgb)}; 150 } 151 if (preset == 8) { 152 return ${u(E[4].rgb)}; 153 } 154 if (preset == ${he}) { 155 return mix( 156 ${u(J.ink.rgb)}, 157 ${u(J.paper.rgb)}, 158 0.12 159 ); 160 } 161 if (preset == 10) { 162 return ${u(_e.rgb)}; 163 } 164 return ${u(E[0].rgb)}; 165} 166 167fn pointerHead(uv: vec2f) -> f32 { 168 let velocity = uniforms.pointer.zw; 169 let movement = length(velocity); 170 let sizeSpeed = clamp(movement * 10.0, 0.0, 1.0); 171 let movementVisibility = smoothstep(0.002, 0.006, movement); 172 if ( 173 uniforms.pointer.x < 0.0 || uniforms.pointer.x > 1.0 174 || uniforms.pointer.y < 0.0 || uniforms.pointer.y > 1.0 175 ) { 176 return 0.0; 177 } 178 179 let aspect = uniforms.viewport.x / max(uniforms.viewport.y, 1.0); 180 let relative = (uv - uniforms.pointer.xy) * vec2f(aspect, 1.0); 181 let headRadius = (0.035 + sizeSpeed * 0.035) * 0.75; 182 let head = 1.0 - smoothstep(headRadius, headRadius * 1.7, length(relative)); 183 return head * movementVisibility; 184} 185 186fn lineMask(p: vec2f, halfLength: f32, width: f32) -> f32 { 187 let body = 1.0 - smoothstep(width, width + 0.08, abs(p.y)); 188 let ends = 1.0 - smoothstep(halfLength, halfLength + 0.08, abs(p.x)); 189 return body * ends; 190} 191 192fn hashGlyph(local: vec2f) -> f32 { 193 let vertical = max( 194 lineMask(vec2f(local.y, local.x - 0.25), 0.72, 0.075), 195 lineMask(vec2f(local.y, local.x + 0.25), 0.72, 0.075) 196 ); 197 let horizontal = max( 198 lineMask(vec2f(local.x, local.y - 0.24), 0.68, 0.075), 199 lineMask(vec2f(local.x, local.y + 0.24), 0.68, 0.075) 200 ); 201 return max(vertical, horizontal); 202} 203 204fn glyphMaskValue(cell: vec2f) -> f32 { 205 if (uniforms.maskColour.w < 0.5) { 206 return 0.0; 207 } 208 209 let local = vec2i(cell) - vec2i(round(uniforms.maskPlacement.xy)); 210 let width = i32(round(uniforms.maskPlacement.z)); 211 let height = i32(round(uniforms.maskPlacement.w)); 212 if (local.x < 0 || local.y < 0 || local.x >= width || local.y >= height) { 213 return 0.0; 214 } 215 216 return glyphMaskData[u32(local.y * MASK_COLUMNS + local.x)]; 217} 218 219fn glyphMaskReveal(cell: vec2f, revealTime: f32, noise: f32) -> f32 { 220 if (uniforms.maskColour.w < 0.5) { 221 return 0.0; 222 } 223 224 let local = vec2i(cell) - vec2i(round(uniforms.maskPlacement.xy)); 225 let width = i32(round(uniforms.maskPlacement.z)); 226 let height = i32(round(uniforms.maskPlacement.w)); 227 if (local.x < 0 || local.y < 0 || local.x >= width || local.y >= height) { 228 return 0.0; 229 } 230 231 let wordmarkTime = clamp( 232 revealTime / ${A.wordmarkWindow}, 233 0.0, 234 1.0 235 ); 236 let wordIndex = floor(f32(local.y) / ${A.wordRows}.0); 237 let rowIndex = f32(local.y % ${A.wordRows}); 238 let columnProgress = (f32(local.x) + 0.5) / max(f32(width), 1.0); 239 let threshold = wordIndex * ${A.wordStagger} 240 + columnProgress * ${A.wipeDuration} 241 + rowIndex * ${A.rowStagger} 242 + (noise - 0.5) * ${A.noise}; 243 return smoothstep( 244 -${A.feather}, 245 ${A.feather}, 246 wordmarkTime - threshold 247 ); 248} 249 250fn glyph(local: vec2f, tangent: vec2f, value: f32, edge: f32) -> f32 { 251 let normal = vec2f(-tangent.y, tangent.x); 252 let p = vec2f(dot(local, tangent), dot(local, normal)); 253 let dotMark = 1.0 - smoothstep(0.12, 0.22, length(local)); 254 let contour = lineMask(p, 0.72, 0.08); 255 let crossMark = max( 256 lineMask(local, 0.56, 0.075), 257 lineMask(vec2f(local.y, local.x), 0.48, 0.075) 258 ); 259 let doubleMark = max(
260 lineMask(p + vec2f(0.0, 0.22), 0.64, 0.065), 261 lineMask(p - vec2f(0.0, 0.22), 0.64, 0.065) 262 ); 263 let corner = max( 264 lineMask(vec2f(local.x + 0.18, local.y - 0.28), 0.45, 0.07), 265 lineMask(vec2f(local.y + 0.25, local.x + 0.25), 0.34, 0.07) 266 ); 267 268 if (edge > 0.06) { 269 return contour; 270 } 271 if (value < 0.22) { 272 return dotMark; 273 } 274 if (value < 0.46) { 275 return corner; 276 } 277 if (value < 0.72) { 278 return crossMark; 279 } 280 return doubleMark; 281} 282 283@vertex 284fn vertexMain(@builtin(vertex_index) index: u32) -> @builtin(position) vec4f { 285 var positions = array<vec2f, 3>( 286 vec2f(-1.0, -1.0), 287 vec2f(3.0, -1.0), 288 vec2f(-1.0, 3.0) 289 ); 290 return vec4f(positions[index], 0.0, 1.0); 291} 292 293@fragment 294fn fragmentMain(@builtin(position) position: vec4f) -> @location(0) vec4f { 295 let cellHeight = uniforms.controls.x; 296 let cellSize = vec2f(cellHeight * 0.6667, cellHeight); 297 let cell = floor(position.xy / cellSize); 298 let cellCenter = (cell + 0.5) * cellSize; 299 let uv = cellCenter / uniforms.viewport.xy; 300 let local = fract(position.xy / cellSize) * 2.0 - 1.0; 301 let time = uniforms.viewport.z; 302 let flow = samplePointerFlow(uv); 303 let flowStrength = clamp(flow.z, 0.0, 1.0); 304 let head = pointerHead(uv); 305 let swish = clamp(max(flowStrength * 1.05, head * 0.9), 0.0, 1.0); 306 let flowSpeed = length(flow.xy); 307 let pointerDirection = normalize(uniforms.pointer.zw + vec2f(0.00001, 0.0)); 308 let flowDirection = normalize(flow.xy + vec2f(0.00001, 0.0)); 309 let swishDirection = normalize( 310 mix(pointerDirection, flowDirection, smoothstep(0.002, 0.025, flowSpeed)) 311 + vec2f(0.00001, 0.0) 312 ); 313 let sampleUv = uv 314 - flow.xy * flowStrength * 0.26 315 - pointerDirection * head * 0.015; 316 let value = field(sampleUv, time); 317 let sampleStep = cellSize / uniforms.viewport.xy; 318 let dx = field(sampleUv + vec2f(sampleStep.x, 0.0), time) 319 - field(sampleUv - vec2f(sampleStep.x, 0.0), time); 320 let dy = field(sampleUv + vec2f(0.0, sampleStep.y), time) 321 - field(sampleUv - vec2f(0.0, sampleStep.y), time); 322 let edge = length(vec2f(dx, dy)); 323 let fieldGradient = vec2f(dx, dy); 324 let interiorNormal = normalize(fieldGradient + vec2f(0.0001, 0.0)); 325 let tangent = vec2f(-interiorNormal.y, interiorNormal.x); 326 let glyphTangent = normalize( 327 mix(tangent, swishDirection, smoothstep(0.04, 0.52, swish) * 0.42) 328 + vec2f(0.0001, 0.0) 329 ); 330 331 let drift = sin(uv.y * 5.0 + time * 0.12) * 0.08; 332 let paletteIndex = uniforms.edgeTreatment.z; 333 let colour = palette(clamp(uv.x + drift, 0.0, 1.0), paletteIndex); 334 let contrast = max(uniforms.controls.w, 0.1); 335 let sourceAlpha = smoothstep(0.04, 0.42 / contrast, value) * 0.9; 336 let solidColour = paletteSolid(paletteIndex); 337 let mappedColour = mix(solidColour, colour, sourceAlpha); 338 let cellNoise = fract( 339 sin(dot(cell + vec2f(uniforms.viewport.w * 7.1, 0.0), vec2f(12.9898, 78.233))) 340 * 43758.5453 341 ); 342 let revealTime = smoothstep(0.0, 1.0, uniforms.edgeTreatment.y); 343 var fieldRevealTime = revealTime; 344 if (uniforms.maskColour.w >= 0.5) { 345 fieldRevealTime = clamp( 346 (revealTime - ${A.fieldStart}) 347 / ${1-A.fieldStart}, 348 0.0, 349 1.0 350 ); 351 } 352 let wavefront = fieldRevealTime * 1.78 - 0.34; 353 let cellThreshold = uv.x + (cellNoise - 0.5) * 0.14; 354 let reveal = smoothstep(-0.03, 0.42, wavefront - cellThreshold); 355 let glyphReveal = smoothstep(0.08, 0.9, reveal); 356 var result = mix(solidColour, mappedColour, reveal); 357 let pointerCut = clamp(flowStrength * 0.28 + head * 0.18, 0.0, 0.34); 358 result = mix(result, solidColour, pointerCut); 359 360 let reactiveValue = value; 361 let reactiveEdge = edge; 362 let glyphMask = glyph(local, glyphTangent, reactiveValue, reactiveEdge); 363 let wordmarkCell = glyphMaskValue(cell); 364 let wordmarkReveal = glyphMaskReveal(cell, revealTime, cellNoise); 365 let wordmarkInk = hashGlyph(local) * wordmarkCell * wordmarkReveal; 366 let visibility = smoothstep( 367 0.035, 368 0.18 / contrast, 369 reactiveValue + reactiveEdge * 1.8 370 ); 371 let boundaryBand = smoothstep(0.035, 0.16, edge) 372 * (1.0 - smoothstep(0.68, 0.94, value)); 373 let interiorSide = smoothstep(-0.42, 0.58, dot(local, interiorNormal)); 374 let directionalLift = boundaryBand * interiorSide * uniforms.edgeTreatment.x; 375 var dormantInk = 0.015; 376 if (uniforms.maskColour.w >= 0.5) { 377 dormantInk = 0.0; 378 } 379 let whiteInk = glyphMask 380 * visibility 381 * (0.62 + edge * 2.8) 382 * contrast 383 * (1.0 + directionalLift * 0.45) 384 * mix(dormantInk, 1.0, glyphReveal); 385 let palettePreset = i32(round(paletteIndex)); 386 var glyphInk = vec3f(1.0); 387 if (palettePreset == 7) { 388 glyphInk = vec3f(0.25, 0.46, 0.94); 389 } 390 let glyphColour = mix( 391 mappedColour, 392 glyphInk, 393 glyphReveal * (0.94 + directionalLift * 0.06) 394 ); 395 result = mix(result, glyphColour, clamp(whiteInk, 0.0, 0.96)); 396 if (palettePreset == ${he}) { 397 let monoAlpha = clamp(whiteInk, 0.0, 0.25); 398 let outputAlpha = monoAlpha * (1.0 - wordmarkInk) + wordmarkInk; 399 let outputColour = vec3f(monoAlpha) * (1.0 - wordmarkInk) 400 + uniforms.maskColour.rgb * wordmarkInk; 401 return vec4f(outputColour, outputAlpha); 402 } 403 404 result = mix(result, uniforms.maskColour.rgb, wordmarkInk); 405 return vec4f(result, 1.0); 406} 407`;function rt({className:r,label:a="Animated summer-fruit ASCII field",phase:c=0,speed:f=1,contrast:m=1,edgeEmphasis:v=.35,cellSize:l=Ge,paletteIndex:n=0,solidColour:g="var(--lab-yellow)",staticFrame:e=!1,pointerSwish:t=!0,renderWidth:x,renderHeight:N,glyphMask:P,glyphMaskColour:R=E[1].rgb,fitGlyphMask:L=!1,glyphMaskInset:C,deferUntilVisible:I=!1}){const T=w.useRef(null),D=w.useRef(null),y=Ne(T),p=!!Be(),ie=w.useRef(y),j=w.useRef(p),ge=w.useRef({cellSize:l,speed:f,warp:pe,contrast:m,edgeEmphasis:v,paletteIndex:n}),B=w.useRef(null),U=w.useRef({x:-2,y:-2,velocityX:0,velocityY:0,lastX:0,lastY:0,lastEventAt:0,lastFrameAt:0,flow:De()}),[we,W]=w.useState("loading"),[xe,V]=w.useState(!1),[ye,Oe]=w.useState(!I);w.useEffect(()=>{y&&Oe(!0)},[y]);const Te=s=>{if(!t||p||e||s.pointerType==="touch")return;const z=s.currentTarget.getBoundingClientRect(),h=Math.min(1,Math.max(0,(s.clientX-z.left)/z.width)),q=Math.min(1,Math.max(0,(s.clientY-z.top)/z.height)),o=U.current,Y=performance.now();if(o.lastEventAt>0){const ae=Math.min(50,Math.max(8,Y-o.lastEventAt)),ee=H.referenceFrameMs/ae,me=(h-o.lastX)*ee,d=(q-o.lastY)*ee,Q=H.velocityBlend;o.velocityX+=(me-o.velocityX)*Q,o.velocityY+=(d-o.velocityY)*Q,o.velocityX=Math.min(H.maxVelocity,Math.max(-.14,o.velocityX)),o.velocityY=Math.min(H.maxVelocity,Math.max(-.14,o.velocityY))}const M=Ue(o.velocityX,o.velocityY);o.lastEventAt>0&&M>.01&&Ve(o.flow,o.lastX,o.lastY,h,q,o.velocityX,o.velocityY,M),o.x=h,o.y=q,o.lastX=h,o.lastY=q,o.lastEventAt=Y},$e=()=>{const s=U.current;s.x=-2,s.y=-2,s.velocityX=0,s.velocityY=0,s.lastEventAt=0};return w.useEffect(()=>{ie.current=y},[y]),w.useEffect(()=>{j.current=p},[p]),w.useEffect(()=>{ge.current={cellSize:l,speed:f,warp:pe,contrast:m,edgeEmphasis:v,paletteIndex:n},ie.current&&B.current&&oe.render(()=>{var s;return(s=B.current)==null?void 0:s.call(B,{timestamp:performance.now()})})},[l,m,v,n,f]),w.useEffect(()=>{if(!ye)return;const s=T.current;if(!s)return;const z=navigator.gpu;if(!z){V(!1),W("static");return}const h=s,q=z;let o=!1,Y=null,M=null,ae=!1,ee=null;V(!1),W("loading");async function me(){try{const d=await He(q);if(o)return;if(!d){V(!1),W("static");return}const Q=h.getContext("webgpu");if(!Q){V(!1),W("static");return}
407const Me=q.getPreferredCanvasFormat();Q.configure({device:d,format:Me,alphaMode:"premultiplied"});const be=d.createShaderModule({code:je}),Z=Ke(P),ke=d.createRenderPipeline({layout:"auto",vertex:{module:be,entryPoint:"vertexMain"},fragment:{module:be,entryPoint:"fragmentMain",targets:[{format:Me}]},primitive:{topology:"triangle-list"}}),i=new Float32Array(24),Se=d.createBuffer({size:i.byteLength,usage:72}),Re=d.createBuffer({size:ve*Float32Array.BYTES_PER_ELEMENT,usage:136}),Ce=d.createBuffer({size:Le*Float32Array.BYTES_PER_ELEMENT,usage:136});d.queue.writeBuffer(Ce,0,Z.data);const Fe=d.createBindGroup({layout:ke.getBindGroupLayout(0),entries:[{binding:0,resource:{buffer:Se}},{binding:1,resource:{buffer:Re}},{binding:2,resource:{buffer:Ce}}]});let Ee=0,Ae=0,se=l;const Ie=()=>{var G;const $=h.getBoundingClientRect(),_=Math.min(window.devicePixelRatio||1,1.5),S=Math.max(1,Math.round($.width*_)),te=Math.max(1,Math.round($.height*_));(h.width!==S||h.height!==te)&&(h.width=S,h.height=te);const re=(G=D.current)==null?void 0:G.getBoundingClientRect(),ne=re?Math.max(0,re.left-$.left):0;se=L?Math.min(l,(h.width-ne*_*2)/Math.max(1,Z.width*.6667),h.height/Math.max(1,Z.height)):l;const ce=se*.6667;Ee=Math.round(ne*_/ce),Ae=Math.max(0,Math.floor((h.height/se-Z.height)/2))};M=({timestamp:$})=>{if(o||!ie.current)return;const _=ge.current,S=U.current,te=S.lastFrameAt?Math.min(64,Math.max(0,$-S.lastFrameAt)):H.referenceFrameMs,re=Math.pow(H.dampingPerFrame,te/H.referenceFrameMs);S.velocityX*=re,S.velocityY*=re,t&&!j.current&&!e&&ze(S.flow,te),S.lastFrameAt=$;let ne=1;!j.current&&!e&&(ee??(ee=$),ne=Math.min(1,Math.max(0,($-ee)/A.durationMs))),i[0]=h.width,i[1]=h.height,i[2]=j.current||e?c:$/1e3*_.speed,i[3]=c,i[4]=se,i[5]=_.speed,i[6]=_.warp,i[7]=_.contrast,i[8]=_.edgeEmphasis,i[9]=ne,i[10]=_.paletteIndex,i[11]=0,i[12]=S.x,i[13]=S.y,i[14]=t&&!j.current&&!e?S.velocityX:0,i[15]=t&&!j.current&&!e?S.velocityY:0,i[16]=Ee,i[17]=Ae,i[18]=Z.width,i[19]=Z.height,i[20]=R[0],i[21]=R[1],i[22]=R[2],i[23]=P?1:0,d.queue.writeBuffer(Se,0,i),d.queue.writeBuffer(Re,0,S.flow.read);const ce=d.createCommandEncoder(),G=ce.beginRenderPass({colorAttachments:[{view:Q.getCurrentTexture().createView(),clearValue:{r:.985,g:.81,b:.07,a:1},loadOp:"clear",storeOp:"store"}]});G.setPipeline(ke),G.setBindGroup(0,Fe),G.draw(3),G.end(),d.queue.submit([ce.finish()]),ae||(ae=!0,W("live"))},B.current=M,Ie(),M({timestamp:performance.now()}),Y=new ResizeObserver(()=>{oe.read(Ie),ie.current&&M&&oe.render(()=>M==null?void 0:M({timestamp:performance.now()}))}),Y.observe(h),V(!0),d.lost.then(()=>{o||(M&&fe(M),V(!1),W("static"))})}catch(d){console.error("Brand ASCII renderer failed to start",d),o||(V(!1),W("static"))}}return me(),()=>{o=!0,M&&fe(M),B.current===M&&(B.current=null),Y==null||Y.disconnect()}},[P,R,C,L,ye,l,c,t,e]),w.useEffect(()=>{const s=B.current;if(!(!xe||!s)){if(fe(s),!y){U.current.velocityX=0,U.current.velocityY=0,U.current.lastFrameAt=0,qe(U.current.flow);return}if(p||e){oe.render(()=>s({timestamp:0}));return}return oe.render(s,!0),()=>fe(s)}},[y,p,xe,e]),de.jsxs("div",{className:r,"data-ascii-status":we,"data-ascii-active":we==="live"&&y&&!p&&!e?"true":"false","data-ascii-reduced-motion":p?"true":"false","data-ascii-palette":n,"data-ascii-pointer-swish":t?"true":"false","data-ascii-static":e?"true":"false",role:a?"img":void 0,"aria-label":a||void 0,"aria-hidden":a?void 0:!0,onPointerMove:Te,onPointerLeave:$e,style:{"--ascii-cell-size":`${l}px`,"--ascii-contrast":m,"--ascii-warp":pe,"--ascii-solid":g,background:g},children:[de.jsx("canvas",{ref:T,className:"brand-ascii-canvas",width:x,height:N,"aria-hidden":"true"}),P?de.jsx("span",{ref:D,"aria-hidden":"true",style:{position:"absolute",insetBlockStart:0,insetInlineStart:C??0,width:0,height:0,visibility:"hidden",pointerEvents:"none"}}):null]})}export{he as A,rt as B,Ge as a,pe as b};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.