asciify-engine 1.0.118 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -1
- package/dist/backgrounds.cjs +1 -0
- package/dist/backgrounds.d.cts +401 -0
- package/dist/backgrounds.d.ts +401 -0
- package/dist/backgrounds.js +1 -0
- package/dist/core.cjs +1 -0
- package/dist/core.d.cts +680 -0
- package/dist/core.d.ts +680 -0
- package/dist/core.js +1 -0
- package/dist/hover.cjs +1 -0
- package/dist/hover.d.cts +45 -0
- package/dist/hover.d.ts +45 -0
- package/dist/hover.js +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -1668
- package/dist/index.d.ts +3 -1668
- package/dist/index.js +1 -1
- package/dist/types-w2CRgyk6.d.cts +589 -0
- package/dist/types-w2CRgyk6.d.ts +589 -0
- package/examples/media-background.ts +22 -0
- package/package.json +37 -3
- package/skills/asciify-engine/SKILL.md +76 -749
- package/skills/asciify-engine/agents/openai.yaml +2 -2
- package/skills/asciify-engine/examples/layered-hero.css +30 -0
- package/skills/asciify-engine/examples/layered-hero.html +31 -0
- package/skills/asciify-engine/examples/layered-hero.js +78 -0
- package/skills/asciify-engine/references/layered-hero.md +45 -0
- package/skills/asciify-engine/references/media-api.md +109 -0
- package/skills/asciify-engine/references/studio-effects.md +57 -0
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
package/dist/core.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var t={dracula:{name:"Dracula",accent:"#bd93f9",bg:"#282a36",fg:"#f8f8f2"},monokai:{name:"Monokai",accent:"#a6e22e",bg:"#272822",fg:"#f8f8f2"},nord:{name:"Nord",accent:"#88c0d0",bg:"#2e3440",fg:"#eceff4"},catppuccin:{name:"Catppuccin",accent:"#cba6f7",bg:"#1e1e2e",fg:"#cdd6f4"},solarized:{name:"Solarized",accent:"#268bd2",bg:"#002b36",fg:"#839496"},gruvbox:{name:"Gruvbox",accent:"#b8bb26",bg:"#282828",fg:"#ebdbb2"}},e={standard:" .:-=+*#%@",blocks:" ░▒▓█",minimal:" .:+",dense:" .'`^\",:;Il!i><~+_-?][}{1)(|/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$",binary:"01",dots:" ⠁⠃⠇⡇⣇⣧⣷⣿",letters:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",claudeCode:" ╔╗╚╝║═╠╣╦╩╬░▒▓█│─┌┐└┘├┤┬┴┼",box:" ▪◾◼■█",lines:" ˗‐–—―━",braille:" ⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿⡀⡁⡂⡃⡄⡅⡆⡇⣀⣁⣂⣃⣄⣅⣆⣇⣈⣉⣊⣋⣌⣍⣎⣏⣐⣑⣒⣓⣔⣕⣖⣗⣘⣙⣚⣛⣜⣝⣞⣟⣠⣡⣢⣣⣤⣥⣦⣧⣨⣩⣪⣫⣬⣭⣮⣯⣰⣱⣲⣳⣴⣵⣶⣷⣸⣹⣺⣻⣼⣽⣾⣿",katakana:" ヲァィゥェォャュョッアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン",musical:" ♩♪♫♬♭♮♯",emoji:" ⬛🟫🟥🟧🟨🟩🟦🟪⬜",circles:" .·:∘○◦°•∙",shadows:" ·∘◦○◎⊙●◉",starfield:" ˙·∘∗✦✧★◆●",geometric:" ·△▷◇◈◆▣■█",pipes:" ╶─┐└├┤┬┴┼╬▒▓█",waves:" ˜∼≈〰≋∿∾∭∫",shards:" ╱╲╳◤◥◣◢△▲◆◼█",smoke:" ·˙⁚⁖∶∷⋮⋰⋱∴∵",ascii:" .'`^\",:;~-_+<>i!lI?/\\|()[]{}1tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$",interface:" ·•-–—+=:;<>[]{}()⌘⌥⇧⌃↵↗↘◇◆◈□■",prompt:" .:;>_`/\\|{}[]()=+*#@$",data:" ·∙•◦○●◇◆◈▱▰▣█",humanist:" ·˙,:;∴∵∷∶⁚⋮⋯∼≈≋∞",mesh:" ·╶╴╷╵─│┌┐└┘├┤┬┴┼╬░▒▓█"},n={cosmic:[e.starfield,e.circles,e.shadows],rain:[e.katakana,e.braille,e.binary],terminal:[e.pipes,e.claudeCode,e.standard],crystal:[e.shards,e.geometric,e.blocks],fluid:[e.waves,e.smoke,e.circles],pulse:[e.dense,e.standard,e.blocks],dream:[e.braille,e.shadows,e.smoke],angular:[e.geometric,e.shards,e.starfield],assistant:[e.interface,e.prompt,e.data],signal:[e.mesh,e.data,e.ascii],editorial:[e.humanist,e.waves,e.smoke]},o={classic:{renderMode:"ascii",charset:e.standard,colorMode:"grayscale"},particles:{renderMode:"dots",colorMode:"fullcolor",dotSizeRatio:.8},letters:{renderMode:"ascii",charset:e.letters,colorMode:"fullcolor"},claudeCode:{renderMode:"ascii",charset:e.claudeCode,colorMode:"accent",accentColor:"#f97316"},art:{renderMode:"ascii",charset:e.dense,colorMode:"fullcolor"},terminal:{renderMode:"ascii",charset:e.standard,colorMode:"matrix"},box:{renderMode:"ascii",charset:e.box,colorMode:"grayscale"},lines:{renderMode:"ascii",charset:e.lines,colorMode:"fullcolor"},braille:{renderMode:"ascii",charset:e.braille,colorMode:"fullcolor"},katakana:{renderMode:"ascii",charset:e.katakana,colorMode:"matrix"},musical:{renderMode:"ascii",charset:e.musical,colorMode:"accent",accentColor:"#e040fb"},emoji:{renderMode:"ascii",charset:e.emoji,colorMode:"fullcolor"},circles:{renderMode:"ascii",charset:e.circles,colorMode:"accent",accentColor:"#d4ff00"},shadows:{renderMode:"ascii",charset:e.shadows,colorMode:"accent",accentColor:"#50a0ff"},starfield:{renderMode:"ascii",charset:e.starfield,colorMode:"fullcolor"},geometric:{renderMode:"ascii",charset:e.geometric,colorMode:"grayscale"},pipes:{renderMode:"ascii",charset:e.pipes,colorMode:"accent",accentColor:"#00ff88"},waves:{renderMode:"ascii",charset:e.waves,colorMode:"fullcolor"},shards:{renderMode:"ascii",charset:e.shards,colorMode:"grayscale"},smoke:{renderMode:"ascii",charset:e.smoke,colorMode:"accent",accentColor:"#c850ff"},ascii:{renderMode:"ascii",charset:e.ascii,colorMode:"grayscale"},interface:{renderMode:"ascii",charset:e.interface,colorMode:"accent",accentColor:"#f4f1ea"},prompt:{renderMode:"ascii",charset:e.prompt,colorMode:"matrix"},data:{renderMode:"ascii",charset:e.data,colorMode:"fullcolor"},humanist:{renderMode:"ascii",charset:e.humanist,colorMode:"accent",accentColor:"#d6ccc2"},mesh:{renderMode:"ascii",charset:e.mesh,colorMode:"accent",accentColor:"#8fd3ff"}},r={agentField:{...o.interface,charsetFrames:n.assistant,charsetFps:1.6,animationStyle:"breathe",animationSpeed:.75,ditherStrength:.12,hoverEffect:"glow",hoverStrength:.42,hoverRadius:.18,hoverColor:"#f4f1ea",normalize:!0},liquidSignal:{...o.data,charsetFrames:n.signal,charsetFps:2.4,animationStyle:"melt",animationSpeed:.65,ditherStrength:.45,hoverEffect:"repel",hoverStrength:.55,hoverRadius:.22,hoverColor:"#8fd3ff",normalize:!0},cursorGravity:{...o.mesh,charsetFrames:n.angular,charsetFps:1.2,animationStyle:"orbit",animationSpeed:.9,ditherStrength:.2,hoverEffect:"attract",hoverStrength:.82,hoverRadius:.24,hoverColor:"#ffffff",normalize:!0},editorialPulse:{...o.humanist,charsetFrames:n.editorial,charsetFps:.9,animationStyle:"ripple",animationSpeed:.55,ditherStrength:.18,hoverEffect:"spotlight",hoverStrength:.35,hoverRadius:.2,hoverColor:"#fff8ea",normalize:!0},terminalFlow:{...o.prompt,charsetFrames:n.terminal,charsetFps:3,animationStyle:"rain",animationSpeed:1.1,ditherStrength:.22,hoverEffect:"glitchText",hoverStrength:.65,hoverRadius:.16,hoverColor:"#d4ff00",hoverText:["BUILD","SHIP","RUN","ASK","MODEL"],normalize:!0}},a={fontSize:7,charSpacing:1,brightness:0,contrast:0,charset:e.standard,colorMode:"grayscale",accentColor:"#d4ff00",invert:!1,renderMode:"ascii",animationStyle:"none",animationSpeed:1,dotSizeRatio:.8,ditherStrength:0,charAspect:.55,normalize:!1,hoverStrength:0,hoverRadius:.2,hoverEffect:"spotlight",hoverColor:"#ffffff",hoverShape:"circle",hoverText:"ASCIIFY",artStyle:"classic",customText:"",chromaKey:null,chromaKeyTolerance:60,chromaKeyTrimPadding:.002,chromaKeyTrimLuminanceThreshold:0,chromaKeyTrimMode:"range"},i={none:{label:"Off",options:{hoverStrength:0,hoverEffect:"spotlight",hoverRadius:.2,hoverColor:"#ffffff"}},subtle:{label:"Subtle",options:{hoverStrength:.25,hoverEffect:"glow",hoverRadius:.12,hoverColor:"#ffffff"}},flashlight:{label:"Flashlight",options:{hoverStrength:.6,hoverEffect:"spotlight",hoverRadius:.15,hoverColor:"#fffbe6"}},magnifier:{label:"Magnifier",options:{hoverStrength:.7,hoverEffect:"magnify",hoverRadius:.12,hoverColor:"#ffffff"}},forceField:{label:"Force Field",options:{hoverStrength:.7,hoverEffect:"repel",hoverRadius:.15,hoverColor:"#a0e8ff"}},neon:{label:"Neon",options:{hoverStrength:.6,hoverEffect:"colorShift",hoverRadius:.15,hoverColor:"#d946ef"}},fire:{label:"Fire",options:{hoverStrength:.7,hoverEffect:"spotlight",hoverRadius:.15,hoverColor:"#ff6b2b"}},ice:{label:"Ice",options:{hoverStrength:.5,hoverEffect:"glow",hoverRadius:.15,hoverColor:"#60d5f7"}},gravity:{label:"Gravity",options:{hoverStrength:.7,hoverEffect:"attract",hoverRadius:.18,hoverColor:"#a5d6ff"}},shatter:{label:"Shatter",options:{hoverStrength:.8,hoverEffect:"shatter",hoverRadius:.14,hoverColor:"#ff6090"}},ghost:{label:"Fluid trail",options:{hoverStrength:.55,hoverEffect:"trail",hoverRadius:.2,hoverColor:"#b39ddb"}},glitchReveal:{label:"Glitch Reveal",options:{hoverStrength:.8,hoverEffect:"glitchText",hoverRadius:.18,hoverColor:"#a3e635"}}};function s(t,e){const n=document.createElement("canvas");n.width=t,n.height=e;const o=n.getContext("2d",{willReadFrequently:!0});return{canvas:n,ctx:o}}function c(t,e,n){let o=t+255*e;return o=259*(255*n+255)/(255*(259-255*n))*(o-128)+128,Math.max(0,Math.min(255,o))}function l(t,e,n,o,r,a){if((a?1-t/255:t/255)<.12)return" ";const i=[...e];return i[(o*r+n)%i.length]}var h=[[0,8,2,10],[12,4,14,6],[3,11,1,9],[15,7,13,5]];function d(t,e,n,o){if(o<=0)return t;const r=(h[n%4][e%4]/16-.5)*o*128;return Math.max(0,Math.min(255,t+r))}var f=new Array(256),m=new Array(256);for(let t=0;t<256;t++)f[t]=`rgb(${t},${t},${t})`,m[t]=`rgb(0,${t},0)`;function u(t,e,n,o,r,a=!1){switch(e){case"fullcolor":return`rgb(${t.r},${t.g},${t.b})`;case"matrix":return m[.299*t.r+.587*t.g+.114*t.b|0];case"accent":return`rgb(${n},${o},${r})`;default:{const e=.299*t.r+.587*t.g+.114*t.b|0;return f[e]}}}var g=[0,0,0];function M(t,e,n,o,r,a=!1){switch(e){case"fullcolor":g[0]=t.r,g[1]=t.g,g[2]=t.b;break;case"matrix":{const e=.299*t.r+.587*t.g+.114*t.b|0;g[0]=0,g[1]=e,g[2]=0;break}case"accent":g[0]=n,g[1]=o,g[2]=r;break;default:{const e=.299*t.r+.587*t.g+.114*t.b|0;g[0]=e,g[1]=e,g[2]=e;break}}return g}function p(t){const e=t.match(/rgba?\(\s*(\d+)\s*[,\s]\s*(\d+)\s*[,\s]\s*(\d+)(?:\s*[,/]\s*([\d.]+))?\s*\)/);return e?{r:+e[1],g:+e[2],b:+e[3],a:void 0!==e[4]?+e[4]:1}:null}function v(t){let e=t;for(;e&&e!==document.documentElement.parentElement;){const t=getComputedStyle(e).backgroundColor;if(t&&"transparent"!==t&&"rgba(0, 0, 0, 0)"!==t){const e=p(t);if(e&&e.a>.1)return e}e=e.parentElement}return null}function w(t){if(t){const e=v(t);if(e){return(.299*e.r+.587*e.g+.114*e.b)/255<.4}}if("undefined"!=typeof document){const t=document.documentElement,e=(t.getAttribute("data-theme")||"").toLowerCase();if("dark"===e)return!0;if("light"===e)return!1;if(t.classList.contains("dark"))return!0;if(document.body){const t=v(document.body);if(t){return(.299*t.r+.587*t.g+.114*t.b)/255<.4}}}return"undefined"!=typeof window&&window.matchMedia("(prefers-color-scheme: dark)").matches}function y(t){if("string"!=typeof t)return t;const e=document.createElement("canvas");e.width=1,e.height=1;const n=e.getContext("2d");n.fillStyle=t,n.fillRect(0,0,1,1);const o=n.getImageData(0,0,1,1).data;return{r:o[0],g:o[1],b:o[2]}}function x(t){return t*t*(3-2*t)}function b(t,e,n,o,r,a,i){if("none"===a)return 1;const s=r*i;switch(a){case"wave":return.3+.7*(.6*(.5*Math.sin(t/n*Math.PI*4+3*s)+.5)+.4*(.5*Math.sin(e/o*Math.PI*3+2*s)+.5));case"pulse":{const r=n/2,a=o/2,i=Math.sqrt((t-r)**2+(e-a)**2),c=Math.sqrt(r**2+a**2);return.2+.8*(.5*Math.sin(i/c*Math.PI*6-4*s)+.5)}case"rain":return.1+.9*(.5*Math.sin(e/o*Math.PI*8-5*s+.3*t)+.5)*(.3*Math.sin(t/n*Math.PI*2+s)+.7);case"breathe":{const n=.3*Math.sin(2*s)+.7,o=.1*Math.sin(.1*(t+e)+s);return Math.max(.1,Math.min(1,n+o))}case"sparkle":{const n=43758.5453*Math.sin(127.1*t+311.7*e+43758.5453*Math.floor(8*s)),o=n-Math.floor(n);return o>.7?1:.15+.4*o}case"glitch":{const t=Math.floor(e/(.05*o)),n=43758.5453*Math.sin(43.23*t+17.89*Math.floor(6*s));if(n-Math.floor(n)>.85){const e=.5*Math.sin(30*s+t)+.5;return e<.3?0:e}return 1}case"spiral":{const r=n/2,a=o/2,i=t-r,c=e-a,l=Math.atan2(c,i),h=Math.sqrt(i*i+c*c),d=Math.sqrt(r*r+a*a);return.15+.85*(.5*Math.sin(3*l+h/d*Math.PI*8-3*s)+.5)}case"typewriter":{const r=n*o,a=e*n+t-.5*s%1*r*1.3;if(a>0)return 0;const i=Math.max(0,1+a/(.15*r));return Math.min(1,i)}case"scatter":{const r=n/2,a=o/2,i=t-r,c=e-a,l=Math.sqrt(i*i+c*c)/Math.sqrt(r*r+a*a),h=.5*Math.sin(1.5*s)+.5;return l>h?Math.max(0,1-3*(l-h)):.7+.3*Math.sin(10*l-2*s)}case"waveField":return.55+.45*Math.sin(t/n*9+2*Math.sin(e/o*6-s)+1.5*s);case"ripple":{const r=n/2,a=o/2,i=t-r,c=e-a,l=Math.sqrt(i*i+c*c),h=Math.sqrt(r*r+a*a);return.1+.9*(.5*Math.sin(l/h*Math.PI*10-5*s)+.5)*(.4+.6*(1-Math.min(1,l/(1.1*h))))}case"melt":{const n=e/o*Math.PI;return.05+(.5*Math.sin(n-1.8*s+.15*t)+.5)*(1-.6*(Math.max(0,e/o-.1)/.9))*.95}case"orbit":{const r=n/2,a=o/2,i=t-r,c=e-a,l=Math.atan2(c,i),h=Math.sqrt(i*i+c*c)/Math.sqrt(r*r+a*a);return.1+.9*(.5*Math.sin(2*l+6*h-2.5*s)+.5)}case"cellular":{const n=Math.floor(4*s),o=(t,e)=>{const o=43758.5453*Math.sin(127.1*t+311.7*e+43758.5453*n);return o-Math.floor(o)>.38?1:0},r=o(t,e),a=o(t-1,e)+o(t+1,e)+o(t,e-1)+o(t,e+1)+o(t-1,e-1)+o(t+1,e-1)+o(t-1,e+1)+o(t+1,e+1);return 1===(1===r?2===a||3===a?1:0:3===a?1:0)?1:.05}default:return 1}}var S={scale:1,offsetX:0,offsetY:0,glow:0,colorBlend:0,proximity:0};function E(t,e,n,o,r,a,i,s,c="spotlight",l=.5,h="circle",d=[],f=1){const m=(t-n)*Math.max(1,f),u=(e-o)*Math.max(1,1/f),g=.08+.35*l+.04*a;let M,p;if("box"===h){const t=Math.abs(m),e=Math.abs(u);M=Math.max(t,e),p=g}else M=Math.sqrt(m*m+u*u),p=g;if(M>=p&&("trail"!==c||0===d.length))return S.scale=1,S.offsetX=0,S.offsetY=0,S.glow=0,S.colorBlend=0,S.proximity=0,S;const v=x(Math.max(0,1-M/p))*r;let w=1,y=0,b=0,E=0,C=0;switch(c){case"spotlight":{w=1+v*a*1.8;const t=Math.atan2(u,m),e=v*v*a*.6;y=Math.cos(t)*e*i,b=Math.sin(t)*e*s,E=v*a*.4,C=v*v*a*.25;break}case"magnify":w=1+v*a*.85,E=v*a*.15;break;case"repel":{w=1;const t=Math.atan2(u,m),e=v*v*a*1.8;y=Math.cos(t)*e*i,b=Math.sin(t)*e*s;break}case"glow":E=v*a*.8,C=v*a*.4;break;case"colorShift":w=1,E=v*a*.12,C=v*a;break;case"attract":{const t=Math.atan2(u,m),e=v*v*a*1;y=(.45*-Math.cos(t)-1.6*Math.sin(t))*e*i,b=(.45*-Math.sin(t)+1.6*Math.cos(t))*e*s,E=v*a*.3;break}case"shatter":{const t=Math.atan2(u,m),e=.5*Math.sin(43.7*m+29.3*u),n=v*a*1.4*(.7+.3*e);y=Math.cos(t+e)*n*i,b=Math.sin(t+e)*n*s,w=Math.max(.1,1-v*a*.6),E=v*a*.25;break}case"trail":{let n=v,o=-u*v,r=m*v;for(const a of d){const i=(t-a.x)*Math.max(1,f),s=(e-a.y)*Math.max(1,1/f),c=Math.hypot(i,s)/g;if(c>=1)continue;const l=x(1-c)*a.intensity;n=Math.max(n,l),o+=(.35*a.vx-2*s)*l*.35,r+=(.35*a.vy+2*i)*l*.35}y=Math.tanh(2*o)*a*i*3,b=Math.tanh(2*r)*a*s*3,C=n*a*.65,E=n*a*.35,w=1+n*a*.08,S.proximity=n;break}case"glitchText":w=1,E=v*a*.5,C=v*a*.6}return S.scale=w,S.offsetX=y,S.offsetY=b,S.glow=E,S.colorBlend=C,"trail"!==c&&(S.proximity=v),S}function C(t,e,{continuous:n=!1,interactive:o=!1}={}){const r=t.parentElement??t;let a=null,i=0,s=!1,c=!0,l=!0,h=-1/0;const d=window.matchMedia("(prefers-reduced-motion: reduce)"),f=()=>{l=!0,s||!c||document.hidden||i||(i=requestAnimationFrame(m))},m=t=>{if(i=0,s||!c||document.hidden)return;const o=!d.matches&&(n||t-h<1500);(l||o)&&(e(t,d.matches?null:a),l=!1),o&&(i=requestAnimationFrame(m))},u=e=>{if("touch"===e.pointerType)return;const n=t.getBoundingClientRect();if(!n.width||!n.height)return;const o=(e.clientX-n.left)/n.width,r=(e.clientY-n.top)/n.height;a=o>=0&&o<=1&&r>=0&&r<=1?{x:o,y:r}:null,h=performance.now(),f()},g=()=>{a=null,h=performance.now(),f()},M=()=>{document.hidden&&i?(cancelAnimationFrame(i),i=0):f()},p="undefined"==typeof IntersectionObserver?null:new IntersectionObserver(([t])=>{c=t.isIntersecting,c?f():i&&(cancelAnimationFrame(i),i=0)});return p?.observe(t),o&&(r.addEventListener("pointermove",u),r.addEventListener("pointerleave",g)),document.addEventListener("visibilitychange",M),d.addEventListener("change",f),f(),{wake:f,stop:()=>{s=!0,cancelAnimationFrame(i),p?.disconnect(),r.removeEventListener("pointermove",u),r.removeEventListener("pointerleave",g),document.removeEventListener("visibilitychange",M),d.removeEventListener("change",f)}}}var T=null,F=null;function A(t,e){if(!T||!F){const n=s(t,e);T=n.canvas,F=n.ctx}return T.width!==t&&(T.width=t),T.height!==e&&(T.height=e),F}var k=new Map,I=new Map,R=new WeakMap;function L(t){const e=Intl.Segmenter;return e?Array.from(new e(void 0,{granularity:"grapheme"}).segment(t),({segment:t})=>t):[...t]}function H(t){let e=k.get(t);return e||(e=L(t),k.set(t,e)),e}function W(t){return L(t)}function $(t,e,n){const o=n?1-t/255:t/255,r=Math.floor(o*(e.length-1));return e[Math.max(0,Math.min(e.length-1,r))]??" "}function P(t,e,n,o){const r=`${t}\0${e?1:0}\0${n}\0${o}`;let a=I.get(r);if(!a){const i=H(t);a=new Array(256);for(let t=0;t<256;t++)a[t]=$(c(t,n,o),i,e);I.set(r,a)}return a}function j(){k.clear(),I.clear(),J=new WeakMap,Q=new WeakMap,_=new WeakMap,T=null,F=null}function z(t,e){return"auto"!==t?t:!w(e)}function q(t){const e=t.match(/^#([0-9a-fA-F]{3,6})$/);if(e){let t=e[1];if(3===t.length&&(t=t[0]+t[0]+t[1]+t[1]+t[2]+t[2]),6===t.length)return t}const n=t.match(/rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);return n?[n[1],n[2],n[3]].map(t=>parseInt(t).toString(16).padStart(2,"0")).join(""):null}function O(t){const e=t||"auto";if("auto"!==e)return q(e)??"ffffff";if("undefined"!=typeof document){const t=getComputedStyle(document.documentElement);for(const e of["--accent-color","--color-accent","--accent","--color-primary","--primary","--brand-color"]){const n=q(t.getPropertyValue(e).trim());if(n)return n}const e=q(getComputedStyle(document.body).accentColor??"");if(e)return e}return w("undefined"!=typeof document?document.body:null)?"faf9f7":"0d0d0d"}function B(t,e,n){return Math.max(e,Math.min(n,t))}function U(t,e,n){if(!t)return{x:0,y:0,width:e,height:n};const o=t.unit??"percent",r=!1!==t.preserveAspect,a=t=>void 0===t?void 0:"percent"===o?t*e:t,i=t=>void 0===t?void 0:"percent"===o?t*n:t,s=B(a(t.left)??0,0,e-1),c=B(a(t.right)??0,0,e-s-1),l=B(i(t.top)??0,0,n-1),h=B(i(t.bottom)??0,0,n-l-1),d=void 0!==t.left||void 0!==t.right||void 0!==t.top||void 0!==t.bottom,f=Math.max(1,e-s-c),m=Math.max(1,n-l-h),u=d?f:a(t.width),g=d?m:i(t.height);let M=u??e,p=g??n;if(r&&!d){const t=M/e,o=p/n,r=Math.min(t,o),a=void 0===u?o:void 0===g?t:r;M=e*a,p=n*a}M=B(M,1,d?f:e),p=B(p,1,d?m:n);const v=t.anchor??"center",w=a(t.x),y=i(t.y),x=d?s:0,b=d?l:0,S=d?f:e,E=d?m:n,C=v.endsWith("left")||"left"===v?0:v.endsWith("right")||"right"===v?S-M:(S-M)/2,T=v.startsWith("top")||"top"===v?0:v.startsWith("bottom")||"bottom"===v?E-p:(E-p)/2;return{x:B(w??x+C,0,Math.max(0,e-M)),y:B(y??b+T,0,Math.max(0,n-p)),width:M,height:p}}function V(t,e,n,o){const r=t instanceof HTMLVideoElement?t.videoWidth:t.width,a=t instanceof HTMLVideoElement?t.videoHeight:t.height;if(0===r||0===a)return{frame:[],cols:0,rows:0};const i=e.charAspect,s=e.fontSize*e.charSpacing,h=e.fontSize/i*e.charSpacing,f=n||r,m=o||a,u=Math.floor(f/s),g=Math.floor(m/h);if(u<=0||g<=0)return{frame:[],cols:0,rows:0};const M=U(e.sourceCrop,r,a),p=Math.max(1,Math.min(Math.floor(2048/u),Math.floor(M.width/u))),v=Math.max(1,Math.min(Math.floor(2048/g),Math.floor(M.height/g))),w=u*p,x=g*v,b=A(w,x),S=b.globalCompositeOperation;b.globalCompositeOperation="copy";try{b.drawImage(t,M.x,M.y,M.width,M.height,0,0,w,x)}finally{b.globalCompositeOperation=S}const E=b.getImageData(0,0,w,x).data,C=e.chromaKey,T=null!=C&&!1!==C,F=!0===C,k="blue-screen"===C;let I=null,R=0;!T||F||k||(I=y(C),R=(e.chromaKeyTolerance??60)**2);let L=0,W=255;if(e.normalize){let t=255,e=0;for(let n=0;n<E.length;n+=4){if(T){const t=E[n],e=E[n+1],o=E[n+2];let r=!1;if(F)r=e>1.4*t&&e>1.4*o&&e>80;else if(k)r=o>1.4*t&&o>1.4*e&&o>80;else if(null!==I){const n=t-I.r,a=e-I.g,i=o-I.b;r=n*n+a*a+i*i<=R}if(r)continue}const o=.299*E[n]+.587*E[n+1]+.114*E[n+2];o<t&&(t=o),o>e&&(e=o)}L=t,W=e>t?e-t:255}const j=[],q=z(e.invert),O=T&&e.charset.replace(/ /g,"")||e.charset,B=H(O),V=e.customText?null:P(O,q,e.brightness,e.contrast),N=p*v;for(let t=0;t<g;t++){const n=[];for(let o=0;o<u;o++){let r=0,a=0,i=0,s=0,h=0;for(let e=0;e<v;e++){const n=(t*v+e)*w;for(let t=0;t<p;t++){const e=4*(n+o*p+t),c=E[e],l=E[e+1],d=E[e+2],f=E[e+3];if(T){let t=!1;if(F)t=l>1.4*c&&l>1.4*d&&l>80;else if(k)t=d>1.4*c&&d>1.4*l&&d>80;else if(null!==I){const e=c-I.r,n=l-I.g,o=d-I.b;t=e*e+n*n+o*o<=R}if(t){h++;continue}}r+=c,a+=l,i+=d,s+=f}}if(T&&h>N/2){n.push({char:" ",r:0,g:0,b:0,a:0});continue}const f=N-h,m=f>0?r/f:0,g=f>0?a/f:0,M=f>0?i/f:0,y=f>0?s/f:0,x=.299*m+.587*g+.114*M,b=e.normalize?(x-L)/W*255:x,S=c(b,e.brightness,e.contrast),C=e.ditherStrength>0?d(S,o,t,e.ditherStrength):S,A=e.customText?l(C,e.customText,o,t,u,q):e.ditherStrength>0?$(C,B,q):V[Math.max(0,Math.min(255,0|b))];n.push({char:A,r:m,g:g,b:M,a:y,lum:C})}j.push(n)}return{frame:j,cols:u,rows:g}}function N(t,e,n,o){const r=t instanceof HTMLVideoElement?t.videoWidth:t.width,a=t instanceof HTMLVideoElement?t.videoHeight:t.height;if(0===r||0===a)return{rows:[],cols:0,rowCount:0};const i=e.charAspect,s=e.fontSize*e.charSpacing,l=e.fontSize/i*e.charSpacing,h=n||r,f=o||a,m=Math.floor(h/s),u=Math.floor(f/l);if(m<=0||u<=0)return{rows:[],cols:0,rowCount:0};const g=m,M=u,p=A(g,M),v=U(e.sourceCrop,r,a),w=p.globalCompositeOperation;p.globalCompositeOperation="copy";try{p.drawImage(t,v.x,v.y,v.width,v.height,0,0,g,M)}finally{p.globalCompositeOperation=w}const x=p.getImageData(0,0,g,M).data,b=e.chromaKey,S=null!=b&&!1!==b,E=!0===b,C="blue-screen"===b;let T=null,F=0;!S||E||C||(T=y(b),F=(e.chromaKeyTolerance??60)**2);let k=0,I=255;if(e.normalize){let t=255,e=0;for(let n=0;n<x.length;n+=4){if(S){const t=x[n],e=x[n+1],o=x[n+2];let r=!1;if(E)r=e>1.4*t&&e>1.4*o&&e>80;else if(C)r=o>1.4*t&&o>1.4*e&&o>80;else if(null!==T){const n=t-T.r,a=e-T.g,i=o-T.b;r=n*n+a*a+i*i<=F}if(r)continue}const o=.299*x[n]+.587*x[n+1]+.114*x[n+2];o<t&&(t=o),o>e&&(e=o)}k=t,I=e>t?e-t:255}const R=z(e.invert),L=S&&e.charset.replace(/ /g,"")||e.charset,W=H(L),j=e.customText?null:P(L,R,e.brightness,e.contrast),q=e.customText?H(e.customText):null,O="fullcolor"===e.colorMode?new Uint8ClampedArray(m*u*4):void 0,B=[];for(let t=0;t<u;t++){let n="";for(let o=0;o<m;o++){const r=4*(t*g+o),a=r,i=x[r],s=x[r+1],l=x[r+2],h=x[r+3];if(S){let t=!1;if(E)t=s>1.4*i&&s>1.4*l&&s>80;else if(C)t=l>1.4*i&&l>1.4*s&&l>80;else if(null!==T){const e=i-T.r,n=s-T.g,o=l-T.b;t=e*e+n*n+o*o<=F}if(t){n+=" ",O&&(O[a]=0,O[a+1]=0,O[a+2]=0,O[a+3]=0);continue}}O&&(O[a]=i,O[a+1]=s,O[a+2]=l,O[a+3]=h);const f=.299*i+.587*s+.114*l,u=e.normalize?(f-k)/I*255:f,M=e.ditherStrength>0||q?c(u,e.brightness,e.contrast):u,p=e.ditherStrength>0?d(M,o,t,e.ditherStrength):M;if(q){n+=(R?1-p/255:p/255)<.12?" ":q[(t*m+o)%q.length]}else e.ditherStrength<=0?n+=j[Math.max(0,Math.min(255,0|u))]:n+=$(p,W,R)}B.push(n)}return{rows:B,cols:m,rowCount:u,colors:O}}function D(t,e,n,o,r){if(0===e.rows.length)return;const a=t.canvas,i=Boolean(n.chromaKey)||e.rows.some(t=>t.includes(" "));i||(R.delete(t),t.clearRect(0,0,o,r),t.fillStyle=w(a)?"#0a0a0a":"#faf9f7",t.fillRect(0,0,o,r));const s=O(n.accentColor),c=parseInt(s.substring(0,2),16),l=parseInt(s.substring(2,4),16),h=parseInt(s.substring(4,6),16),d=o/e.cols,f=r/e.rowCount,m=.9*Math.min(d/.55,f),u=e.colors;if("fullcolor"===n.colorMode&&u){R.delete(t),t.clearRect(0,0,o,r),t.font=`${m}px "JetBrains Mono", monospace`,t.textAlign="left",t.textBaseline="middle",t.globalAlpha=1;let n="";for(let o=0;o<e.rows.length;o++){const r=W(e.rows[o]);let a=0;for(;a<e.cols;){for(;a<e.cols&&" "===r[a];)a++;if(a>=e.cols)break;const i=a,s=4*(o*e.cols+a),c=240&u[s],l=240&u[s+1],h=240&u[s+2];for(a++;a<e.cols&&" "!==r[a];){const t=4*(o*e.cols+a);if((240&u[t])!==c||(240&u[t+1])!==l||(240&u[t+2])!==h)break;a++}const m=`rgb(${c},${l},${h})`;m!==n&&(t.fillStyle=m,n=m),t.fillText(r.slice(i,a).join(""),i*d+.5*d,o*f+.5*f)}}return void(t.globalAlpha=1)}t.font=`${m}px "JetBrains Mono", monospace`,t.textAlign="left",t.textBaseline="middle";const g="matrix"===n.colorMode?"rgb(0,255,0)":"grayscale"===n.colorMode?w(a)?"rgb(230,230,230)":"rgb(24,24,24)":`rgb(${c},${l},${h})`;t.fillStyle=g,t.globalAlpha=1;const M=R.get(t),p=i&&M&&M.cols===e.cols&&M.rowCount===e.rowCount&&M.canvasWidth===o&&M.canvasHeight===r&&M.fillStyle===g;p||t.clearRect(0,0,o,r);for(let n=0;n<e.rows.length;n++){const r=e.rows[n];p&&M.rows[n]===r||(p&&t.clearRect(0,n*f,o,f+1),0!==r.trim().length&&t.fillText(r,.5*d,n*f+.5*f))}R.set(t,{rows:e.rows.slice(),cols:e.cols,rowCount:e.rowCount,canvasWidth:o,canvasHeight:r,fillStyle:g}),t.globalAlpha=1}async function K(t,e,n,o,r=12,a=10,i,s=0){const c=Math.min(t.duration-s,a),l=Math.ceil(c*r),h=[];let d=0,f=0;for(let a=0;a<l;a++){const m=s+a/r;if(m>s+c)break;t.currentTime=m,await new Promise(e=>{const n=()=>{t.removeEventListener("seeked",n),e()};t.addEventListener("seeked",n)});const u=V(t,e,n,o);h.push(u.frame),d=u.cols,f=u.rows,i?.((a+1)/l)}return{frames:h,cols:d,rows:f,fps:r}}async function Y(t,e,n,o,r=12,a=10,i,s=0){const c=Math.min(t.duration-s,a),l=Math.ceil(c*r),h=[];let d=0,f=0;for(let a=0;a<l;a++){const m=s+a/r;if(m>s+c)break;t.currentTime=m,await new Promise(e=>{const n=()=>{t.removeEventListener("seeked",n),e()};t.addEventListener("seeked",n)});const u=N(t,e,n,o);h.push(u),d=u.cols,f=u.rowCount,i?.((a+1)/l)}return{frames:h,cols:d,rows:f,fps:r}}async function X(t,e,n,o,r){const{parseGIF:a,decompressFrames:i}=await import("gifuct-js"),s=a(t),c=i(s,!0);if(0===c.length)return{frames:[],cols:0,rows:0,fps:10};const l=c[0].dims.width,h=c[0].dims.height,d=s.lsd?.width||l,f=s.lsd?.height||h,m=document.createElement("canvas");m.width=d,m.height=f;const u=m.getContext("2d"),g=document.createElement("canvas");g.width=d,g.height=f;const M=g.getContext("2d"),p=document.createElement("canvas"),v=p.getContext("2d"),w=[];let y=0,x=0,b=0;for(const t of c)b+=t.delay||100;const S=b/c.length,E=Math.round(Math.min(30,Math.max(5,1e3/S))),C=Math.min(c.length,300);for(let t=0;t<C;t++){const a=c[t],{dims:i,patch:s,disposalType:l}=a;3===l&&(M.clearRect(0,0,d,f),M.drawImage(m,0,0)),p.width!==i.width&&(p.width=i.width),p.height!==i.height&&(p.height=i.height);const h=new ImageData(new Uint8ClampedArray(s.buffer),i.width,i.height);v.putImageData(h,0,0),u.drawImage(p,i.left||0,i.top||0);const b=V(m,e,n,o);w.push(b.frame),y=b.cols,x=b.rows,2===l?u.clearRect(i.left||0,i.top||0,i.width,i.height):3===l&&(u.clearRect(0,0,d,f),u.drawImage(g,0,0)),r?.((t+1)/C)}return{frames:w,cols:y,rows:x,fps:E}}async function G(t,e,n,o,r){const{parseGIF:a,decompressFrames:i}=await import("gifuct-js"),s=a(t),c=i(s,!0);if(0===c.length)return{frames:[],cols:0,rows:0,fps:10};const l=c[0].dims.width,h=c[0].dims.height,d=s.lsd?.width||l,f=s.lsd?.height||h,m=document.createElement("canvas");m.width=d,m.height=f;const u=m.getContext("2d"),g=document.createElement("canvas");g.width=d,g.height=f;const M=g.getContext("2d"),p=document.createElement("canvas"),v=p.getContext("2d"),w=[];let y=0,x=0,b=0;for(const t of c)b+=t.delay||100;const S=b/c.length,E=Math.round(Math.min(30,Math.max(5,1e3/S))),C=Math.min(c.length,300);for(let t=0;t<C;t++){const a=c[t],{dims:i,patch:s,disposalType:l}=a;3===l&&(M.clearRect(0,0,d,f),M.drawImage(m,0,0)),p.width!==i.width&&(p.width=i.width),p.height!==i.height&&(p.height=i.height);const h=new ImageData(new Uint8ClampedArray(s.buffer),i.width,i.height);v.putImageData(h,0,0),u.drawImage(p,i.left||0,i.top||0);const b=N(m,e,n,o);w.push(b),y=b.cols,x=b.rowCount,2===l?u.clearRect(i.left||0,i.top||0,i.width,i.height):3===l&&(u.clearRect(0,0,d,f),u.drawImage(g,0,0)),r?.((t+1)/C)}return{frames:w,cols:y,rows:x,fps:E}}var J=new WeakMap,_=new WeakMap,Q=new WeakMap;function Z(t,e,n,o,r,a=0,i){if(!e.length||!e[0].length||o<=0||r<=0)return;let s=null;if(n.hoverStrength>0){let e=J.get(t);e||(e={x:.5,y:.5,intensity:0,time:-1,emittedAt:-1,points:[]},J.set(t,e)),s=function(t,e,n){const o=t.time<0?1/60:Math.max(0,Math.min(.1,(n-t.time)/1e3));t.time=n;const r=t.intensity<.003,a=t.x,i=t.y;if(e){r&&(t.x=e.x,t.y=e.y);const n=1-Math.exp(-o/.055);t.x+=(e.x-t.x)*n,t.y+=(e.y-t.y)*n}t.intensity+=((e?.intensity??(e?1:0))-t.intensity)*(1-Math.exp(-o/(e?.09:.18)));const s=Math.exp(-o/.22);for(const e of t.points)e.intensity*=s;for(;t.points.length&&t.points[0].intensity<.01;)t.points.shift();return e&&!r&&n-t.emittedAt>=24&&Math.hypot(t.x-a,t.y-i)>5e-4&&(t.points.push({x:t.x,y:t.y,intensity:t.intensity,vx:Math.max(-1,Math.min(1,(t.x-a)/Math.max(o,.001))),vy:Math.max(-1,Math.min(1,(t.y-i)/Math.max(o,.001)))}),t.points.length>12&&t.points.shift(),t.emittedAt=n),!e&&t.intensity<.003&&!t.points.length?(t.intensity=0,null):{x:t.x,y:t.y,intensity:t.intensity,trail:t.points}}(e,i??null,performance.now())}else J.delete(t);if("none"!==n.animationStyle||n.charsetFrames?.length||n.hoverStrength<=0)return Q.delete(t),void tt(t,e,n,o,r,a,s);const c=_.get(t);if(c?.frame!==e)return _.set(t,{frame:e,since:performance.now()}),Q.delete(t),void tt(t,e,n,o,r,a,s);if(performance.now()-c.since<100)return void tt(t,e,n,o,r,a,s);const l=t.getTransform();if(l.b||l.c||l.a<=0||l.d<=0)return void tt(t,e,n,o,r,a,s);if(!s||(s.intensity??0)<.003)return void tt(t,e,n,o,r,a,null);const h=w(t.canvas),d={...n,accentColor:"#"+O(n.accentColor)},f=JSON.stringify([d,o,r,l.a,l.d,h,void 0!==document.fonts?document.fonts.status:"loaded"]);let m=Q.get(t);if(!m||m.frame!==e||m.key!==f){const n=m?.canvas??document.createElement("canvas");n.width=Math.ceil(o*l.a),n.height=Math.ceil(r*l.d);const a=n.getContext("2d");a.setTransform(l.a,0,0,l.d,0,0),tt(a,e,d,o,r,0,null,void 0,h),m={frame:e,key:f,canvas:n},Q.set(t,m)}if(t.clearRect(0,0,o,r),t.drawImage(m.canvas,0,0,o,r),!s||(s.intensity??0)<.003)return;const u=e.length,g=e[0].length,M=.08+.35*n.hoverRadius+.04*n.hoverStrength,p="trail"===n.hoverEffect?[s,...s.trail??[]]:[s];let v=1,y=1,x=0,b=0;for(const t of p)v=Math.min(v,t.x-M),x=Math.max(x,t.x+M),y=Math.min(y,t.y-M),b=Math.max(b,t.y+M);if("glitchText"===n.hoverEffect){const t=n.hoverText,e=Math.max(1,...(Array.isArray(t)?t:[t]).map(t=>t.length));v=Math.min(v,s.x-e/g),x=Math.max(x,s.x+e/g)}const S=Math.ceil(5+4*n.hoverStrength),E={x:Math.max(0,Math.floor(v*g)-S),y:Math.max(0,Math.floor(y*u)-S),right:Math.min(g,Math.ceil(x*g)+S),bottom:Math.min(u,Math.ceil(b*u)+S)};t.save(),t.beginPath(),t.rect(E.x*o/g,E.y*r/u,(E.right-E.x)*o/g,(E.bottom-E.y)*r/u),t.clip(),tt(t,e,d,o,r,a,s,E,h),t.restore()}function tt(t,e,n,o,r,a=0,i,s,c){const l=e.length;if(0===l)return;const h=e[0].length;t.clearRect(0,0,o,r);let d=!1;const f=Math.max(1,l>>2),m=Math.max(1,h>>2);t:for(let t=0;t<l;t+=f){const n=e[t];for(let t=0;t<h;t+=m)if(n[t].a<200){d=!0;break t}}const g=t.canvas,p=c??w(g);d||(t.fillStyle=p?"#0a0a0a":"#faf9f7",t.fillRect(0,0,o,r));const v=o/h,y=r/l,x=i?.intensity??1,S=!!(i&&n.hoverStrength>0&&x>.005),C="#"+(q(n.hoverColor||"#ffffff")??"ffffff"),T=parseInt(C.slice(1,3),16),F=parseInt(C.slice(3,5),16),A=parseInt(C.slice(5,7),16),k=O(n.accentColor),I=parseInt(k.substring(0,2),16),R=parseInt(k.substring(2,4),16),L=parseInt(k.substring(4,6),16),W=n.hoverRadius;let P=0,j=h,B=0,U=l,V=0,N=0;if(S&&i){V=i.x,N=i.y;const t=.08+.35*W+.04*n.hoverStrength;P=Math.max(0,Math.floor((V-t)*h)-1),j=Math.min(h,Math.ceil((V+t)*h)+1),B=Math.max(0,Math.floor((N-t)*l)-1),U=Math.min(l,Math.ceil((N+t)*l)+1)}if(S&&"trail"===n.hoverEffect)for(const t of i?.trail??[]){const e=.08+.35*W+.04*n.hoverStrength;P=Math.min(P,Math.max(0,Math.floor((t.x-e)*h)-1)),j=Math.max(j,Math.min(h,Math.ceil((t.x+e)*h)+1)),B=Math.min(B,Math.max(0,Math.floor((t.y-e)*l)-1)),U=Math.max(U,Math.min(l,Math.ceil((t.y+e)*l)+1))}const D=n.animationStyle,K=n.animationSpeed,Y="none"===D,X=n.hoverStrength,G=n.hoverEffect,J=W,_=n.hoverShape||"circle",Q=z(n.invert,g),Z=n.colorMode,tt=2*Math.PI,et=1/h,nt=1/l;let ot="",rt=-1;if("dots"===n.renderMode){const c=.5*Math.min(v,y)*n.dotSizeRatio;for(let n=s?.y??0;n<(s?.bottom??l);n++){const d=e[n];for(let e=s?.x??0;e<(s?.right??h);e++){const s=d[e];if(s.a<10)continue;const f=.00392156863*(.299*s.r+.587*s.g+.114*s.b),m=Q?1-f:f;if(m<.02)continue;const g=Y?1:b(e,n,h,l,a,D,K);let p=1,w=0,C=0,k=0,H=0;if(S&&e>=P&&e<=j&&n>=B&&n<=U){const t=E(e*et,n*nt,V,N,x,X,v,y,G,J,_,i?.trail,o/r);p=t.scale,w=t.offsetX,C=t.offsetY,k=t.glow,H=t.colorBlend}const W=c*m*g*p;if(W<.3)continue;const $=e*v+.5*v+w,z=n*y+.5*y+C;let q;if(H>0){const t=M(s,Z,I,R,L,Q);q=`rgb(${Math.min(255,t[0]+(T-t[0])*H|0)},${Math.min(255,t[1]+(F-t[1])*H|0)},${Math.min(255,t[2]+(A-t[2])*H|0)})`}else q=u(s,Z,I,R,L,Q);const O=Math.min(1,.00392156863*s.a*g*(1+k));if(O!==rt&&(t.globalAlpha=O,rt=O),q!==ot&&(t.fillStyle=q,ot=q),W<=3){const e=2*W;t.fillRect($-W,z-W,e,e)}else t.beginPath(),t.arc($,z,W,0,tt),t.fill()}}}else{const c=.55,d=.9*Math.min(v/c,y);{const e="emoji"===n.artStyle;t.font=e?`${d}px "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Twemoji Mozilla", sans-serif`:`${d}px "JetBrains Mono", monospace`,t.textAlign="center",t.textBaseline="middle"}const f=n.charsetFrames,m=!!f?.length,g=m?f[Math.floor(Math.max(0,a)*(n.charsetFps??2))%f.length]:n.charset,p=t.getTransform();if(!S&&Y&&!m&&"accent"===Z&&!s&&n.hoverStrength<=0&&"emoji"!==n.artStyle&&"letterSpacing"in t&&/^[\x20-\x7e]*$/.test(n.customText||n.charset)&&e.every(t=>t.every(t=>t.a<10||255===t.a&&1===t.char.length&&/^[\x20-\x7e]$/.test(t.char)))){const n=t.letterSpacing;t.letterSpacing="0px";const o=t.measureText("M").width;t.letterSpacing=v-o+"px",t.fillStyle=`rgb(${I},${R},${L})`,t.globalAlpha=1,t.textAlign="left";for(let n=0;n<l;n++){const r=e[n];let a="";for(let t=0;t<h;t++){const e=r[t];a+=e.a<10?" ":e.char}0!==a.trim().length&&t.fillText(a,.5*(v-o),n*y+.5*y)}return t.letterSpacing=n,t.textAlign="center",void(t.globalAlpha=1)}const w="glitchText"===G&&S,C="!@#$%^&*<>{}[]|/\\~`0123456789",k=C.length;let z="",q=0,O=0,tt=0,at=0,it=0,st=0;if(w){const t=n.hoverText??"ASCIIFY";if(O=Math.round(V*h),tt=Math.round(N*l),Array.isArray(t)){const e=t.filter(t=>t.length>0);0===e.length&&e.push("ASCIIFY");z=e[((7*Math.floor(O/Math.max(1,Math.ceil(h/5)))+13*Math.floor(tt/Math.max(1,Math.ceil(l/3))))%e.length+e.length)%e.length]}else z=t||"ASCIIFY";q=z.length,at=Math.max(3,Math.min(12,Math.round(l*W*.6)));const e=Math.floor(at/2);it=Math.max(0,tt-e),it+at>l&&(it=Math.max(0,l-at)),st=O-Math.floor(q/2)}for(let n=s?.y??0;n<(s?.bottom??l);n++){const c=e[n];for(let d=s?.x??0;d<(s?.right??h);d++){const s=c[d];if(s.a<10)continue;let f=m&&null!=s.lum?$(s.lum,H(g),Q):s.char;if(" "===f)continue;const W=Y?1:b(d,n,h,l,a,D,K);if(W<.05)continue;let ct=1,lt=0,ht=0,dt=0,ft=0;if(S&&!w&&d>=P&&d<=j&&n>=B&&n<=U){const t=E(d*et,n*nt,V,N,x,X,v,y,G,J,_,i?.trail,o/r);if(ct=t.scale,lt=t.offsetX,ht=t.offsetY,dt=t.glow,ft=t.colorBlend,"trail"===G&&t.proximity>0){const o=Math.max(0,Math.min(h-1,Math.round(d-t.offsetX/v))),r=e[Math.max(0,Math.min(l-1,Math.round(n-t.offsetY/y)))][o],a=r.lum??.299*r.r+.587*r.g+.114*r.b;f=$(Math.min(255,a+t.proximity*X*65),H(g),Q)}}if(w&&n>=it&&n<it+at){const t=d-st;if(t>=0&&t<q){const e=z[t],o=Math.abs(n-tt)/Math.max(1,.5*at),r=Math.abs(d-O)/Math.max(1,q),i=Math.max(o,r),s=Math.max(0,Math.min(1,1-.9*i)),c=43758.5453*Math.sin(127.1*d+311.7*n+43758.5453*Math.floor(12*a));f=Math.abs(c-Math.floor(c))<s?e:C[Math.abs(Math.floor(97*c))%k],dt=.3+.7*s,ft=.3+.65*s}}const mt=d*v+.5*v+lt,ut=n*y+.5*y+ht;let gt;if(ft>0){const t=M(s,Z,I,R,L,Q);gt=`rgb(${Math.min(255,t[0]+(T-t[0])*ft|0)},${Math.min(255,t[1]+(F-t[1])*ft|0)},${Math.min(255,t[2]+(A-t[2])*ft|0)})`}else gt=u(s,Z,I,R,L,Q);const Mt=Math.min(1,.00392156863*s.a*W*(1+dt));Mt!==rt&&(t.globalAlpha=Mt,rt=Mt),gt!==ot&&(t.fillStyle=gt,ot=gt),1!==ct?(t.translate(mt,ut),t.scale(ct,ct),t.fillText(f,0,0),t.setTransform(p)):t.fillText(f,mt,ut)}}}t.globalAlpha=1}function et(t){return Math.max(0,Math.min(1,t))}function nt(t){return"string"==typeof t?document.querySelector(t):t instanceof HTMLElement?t:null}function ot(t){return"ascii"===t.renderMode&&"none"===t.animationStyle&&t.hoverStrength<=0&&!t.charsetFrames?.length}function rt(t,e={}){const n=et(t),o=et(n*(void 0===e.speed?1:Math.max(.001,e.speed)));return et(e.ease?e.ease(o):o)}function at(t,e,n={}){if(!Number.isFinite(t.duration)||t.duration<=0)return;const o=n.from??0,r=n.to??t.duration,a=Math.max(o,Math.min(r,t.duration)),i=rt(e,n),s=o+(a-o)*i;t.currentTime=Math.min(Math.max(o,s),Math.max(o,a-.04)),n.onUpdate?.(i,t)}function it(t,e){return Math.abs(t.currentTime-e)<1/240?st(t):new Promise(n=>{const o=()=>{t.removeEventListener("seeked",o),n()};t.addEventListener("seeked",o,{once:!0});const r=t.fastSeek;r?r.call(t,e):t.currentTime=e})}function st(t){const e=t.requestVideoFrameCallback;return new Promise(e?n=>{let o=!1;const r=()=>{o||(o=!0,n())};e.call(t,r),window.setTimeout(r,32)}:t=>requestAnimationFrame(()=>t()))}function ct(t,e={}){const n=nt(e.trigger)??t;t.pause();const o=e.gsap,r=e.ScrollTrigger??o?.ScrollTrigger;if(o&&r?.create){o.registerPlugin?.(r);const a=r.create({trigger:n,start:e.start??"top bottom",end:e.end??"bottom top",scrub:e.scrub??!0,onUpdate:n=>at(t,n.progress,e)});return()=>a.kill?.()}return function(t,e,n){let o=0;const r=()=>{o=0;const r=e.getBoundingClientRect(),a=window.innerHeight||document.documentElement.clientHeight,i=r.height+a,s=i>0?et((a-r.top)/i):0;at(t,s,n)},a=()=>{o||(o=requestAnimationFrame(r))};return window.addEventListener("scroll",a,{passive:!0}),window.addEventListener("resize",a),a(),()=>{window.removeEventListener("scroll",a),window.removeEventListener("resize",a),o&&cancelAnimationFrame(o)}}(t,n,e)}function lt(t,e,n){const o=e.gsap,r=e.ScrollTrigger??o?.ScrollTrigger;if(o&&r?.create){o.registerPlugin?.(r);const a=r.create({trigger:t,start:e.start??"top bottom",end:e.end??"bottom top",scrub:e.scrub??!0,onUpdate:t=>n(t.progress)});return()=>a.kill?.()}return function(t,e){let n=0;const o=()=>{n=0;const o=t.getBoundingClientRect(),r=window.innerHeight||document.documentElement.clientHeight,a=o.height+r,i=a>0?et((r-o.top)/a):0;e(i)},r=()=>{n||(n=requestAnimationFrame(o))};return window.addEventListener("scroll",r,{passive:!0}),window.addEventListener("resize",r),r(),()=>{window.removeEventListener("scroll",r),window.removeEventListener("resize",r),n&&cancelAnimationFrame(n)}}(t,n)}function ht(t,e,n){if(!t||!e||!n.sourceCrop)return{w:t,h:e};const o=U(n.sourceCrop,t,e);return{w:Math.max(1,Math.round(o.width)),h:Math.max(1,Math.round(o.height))}}function dt(t,e,n,o){const r=o.chromaKey;if(null==r||!1===r)return!1;if(!0===r)return e>1.4*t&&e>1.4*n&&e>80;if("blue-screen"===r)return n>1.4*t&&n>1.4*e&&n>80;const a=y(r),i=(o.chromaKeyTolerance??60)**2,s=t-a.r,c=e-a.g,l=n-a.b;return s*s+c*c+l*l<=i}function ft(t,e,n){if(!e.chromaKey||!e.sourceCrop||"off"===e.chromaKeyTrimMode)return e;const o=t instanceof HTMLVideoElement?t.videoWidth:t.width,r=t instanceof HTMLVideoElement?t.videoHeight:t.height;if(!o||!r)return e;const a=U(e.sourceCrop,o,r),i=Math.min(360,Math.max(1,Math.round(a.width))),c=Math.max(1,Math.round(i*(a.height/a.width))),{ctx:l}=s(i,c);l.drawImage(t,a.x,a.y,a.width,a.height,0,0,i,c);const h=l.getImageData(0,0,i,c).data,d=Math.max(0,Math.min(255,e.chromaKeyTrimLuminanceThreshold??0));let f=i,m=c,u=-1,g=-1;for(let t=0;t<c;t++)for(let n=0;n<i;n++){const o=4*(t*i+n),r=h[o+3],a=h[o],s=h[o+1],c=h[o+2];r<=8||.2126*a+.7152*s+.0722*c<=d||dt(a,s,c,e)||(n<f&&(f=n),t<m&&(m=t),n>u&&(u=n),t>g&&(g=t))}if(u<f||g<m)return e;const M=Math.max(0,Math.min(.25,e.chromaKeyTrimPadding??.002)),p=Math.round(i*M),v=Math.round(c*M);f=Math.max(0,f-p),m=Math.max(0,m-v),u=Math.min(i-1,u+p),g=Math.min(c-1,g+v);const w=function(t,e,n,o,r){const a=r&&Number.isFinite(r)&&r>0?r:null;if(!a)return t;const i=e.x,s=e.y,c=e.x+e.width,l=e.y+e.height,h=Math.max(i,t.left),d=Math.max(s,t.top),f=Math.min(c,n-t.right),m=Math.min(l,o-t.bottom),u=Math.max(1,f-h),g=Math.max(1,m-d),M=h+u/2,p=d+g/2;let v=u,w=g;v/w<a?v=w*a:w=v/a;v>e.width&&(v=e.width,w=Math.max(g,Math.min(e.height,v/a)));w>e.height&&(w=e.height,v=Math.max(u,Math.min(e.width,w*a)));let y=M-v/2,x=p-w/2;return y=Math.max(i,Math.min(c-v,y)),x=Math.max(s,Math.min(l-w,x)),{left:y,top:x,right:n-(y+v),bottom:o-(x+w)}}({left:a.x+f/i*a.width,top:a.y+m/c*a.height,right:o-(a.x+(u+1)/i*a.width),bottom:r-(a.y+(g+1)/c*a.height)},{x:a.x,y:a.y,width:a.width,height:a.height},o,r,n);return{...e,sourceCrop:{unit:"pixel",...w,preserveAspect:!1}}}function mt(t){const e=t.sourceCrop;return e&&"pixel"===e.unit?void 0===e.left||void 0===e.top||void 0===e.right||void 0===e.bottom?null:{left:e.left,top:e.top,right:e.right,bottom:e.bottom}:null}async function ut(t,e,n,o,r){if(!e.chromaKey||!e.sourceCrop||"range"!==e.chromaKeyTrimMode)return e;const a=t.currentTime,i=function(t,e,n,o){const r=!0===o?{}:o||{},a=Math.max(0,r.from??e),i=r.to??n??(Number.isFinite(t.duration)?t.duration:a),s=Math.max(a,i-.04),c=Math.max(0,s-a),l=c>.1?[a,a+.25*c,a+.5*c,a+.75*c,s]:[a];return Array.from(new Set(l.map(t=>Math.max(0,Number(t.toFixed(3))))))}(t,n,o,r);let s=null;for(const n of i){await it(t,n),await st(t);const o=mt(ft(t,e));o&&(s=s?{left:Math.min(s.left,o.left),top:Math.min(s.top,o.top),right:Math.min(s.right,o.right),bottom:Math.min(s.bottom,o.bottom)}:o)}return await it(t,a),await st(t),s?{...e,sourceCrop:{unit:"pixel",...s,preserveAspect:!0}}:e}function gt(t,e,n=2048){return Mt({sourceWidth:t,sourceHeight:e,maxRenderDimension:n})}function Mt({sourceWidth:t,sourceHeight:e,cssWidth:n=0,cssHeight:o=0,maxRenderDimension:r=2048}){const a=Math.max(1,t),i=Math.max(1,e),s=a/i,c=Math.max(1,r),l=Math.min(1,c/Math.max(a,i)),h=Math.max(a,i)*l,d=Math.max(0,n,o),f=Math.min(c,Math.max(h,d));return s>=1?{renderW:Math.round(f),renderH:Math.round(f/s)}:{renderW:Math.round(f*s),renderH:Math.round(f)}}function pt(t,e,n,o){if(void 0===t)return;if("number"==typeof t)return t;const r=t.trim();if(r.endsWith("%")){const t=Number.parseFloat(r)/100;return Number.isFinite(t)?e*t:void 0}if(r.endsWith("px")){const t=Number.parseFloat(r);return Number.isFinite(t)?t:void 0}if(r.endsWith("vw")){const t=Number.parseFloat(r)/100;return Number.isFinite(t)?n*t:void 0}if(r.endsWith("vh")){const t=Number.parseFloat(r)/100;return Number.isFinite(t)?o*t:void 0}}function vt(t,e,n,o,r,a=2048,i={}){const{width:s,height:c}=e.getBoundingClientRect();if(!s||!c)return{renderW:0,renderH:0,dpr:1};const l="undefined"!=typeof window?window.innerWidth:s,h="undefined"!=typeof window?window.innerHeight:c,d=pt(i.width,s,l,h)??s,f=pt(i.height,c,l,h)??c,m=function(t,e,n,o,r){const a=t=>{const n=pt(t,e,o,r);return n&&n>0?n:0},i=t=>{const e=pt(t,n,o,r);return e&&e>0?e:0};return void 0===t?{x:0,y:0}:"number"==typeof t||"string"==typeof t?{x:a(t),y:i(t)}:{x:a(t.x),y:i(t.y)}}(i.bleed,s,c,l,h),u=d+2*m.x,g=f+2*m.y,{cssW:M,cssH:p}=function(t,e,n,o="contain"){if("fill"===o)return{cssW:t,cssH:e};let r=t,a=r/n;const i="cover"===o,s=a>e;return(i&&!s||!i&&s)&&(a=e,r=a*n),"scale-down"===o&&(r=Math.min(r,t),a=Math.min(a,e)),{cssW:Math.round(r),cssH:Math.round(a)}}(u,g,n,i.objectFit??"contain"),v="undefined"!=typeof window&&window.devicePixelRatio||1;let w,y;o&&r?({renderW:w,renderH:y}=Mt({sourceWidth:o,sourceHeight:r,cssWidth:M,cssHeight:p,maxRenderDimension:a})):(w=M,y=p);const x=8e6,b=w*v*y*v>x?Math.sqrt(x/(w*y)):v;return t.width=Math.round(w*b),t.height=Math.round(y*b),t.style.width=`${M}px`,t.style.height=`${p}px`,{renderW:w,renderH:y,dpr:b}}async function wt(t,e,{fontSize:n,artStyle:r="classic",options:i={}}={}){let s;if("string"==typeof t){const e=new Image;e.crossOrigin="anonymous",await new Promise((n,o)=>{e.onload=()=>n(),e.onerror=()=>o(new Error(`Failed to load image: ${t}`)),e.src=t}),s=e}else t instanceof HTMLImageElement&&!t.complete?(await new Promise((e,n)=>{t.onload=()=>e(),t.onerror=()=>n(new Error("Image failed to load"))}),s=t):s=t;const c=o[r],l=n??i.fontSize??10,h={...a,...c,artStyle:r,...i,fontSize:l},d=e.getContext("2d");if(!d)throw new Error("Could not get 2d context from canvas");const{w:f,h:m}=function(t){return t instanceof HTMLVideoElement?{w:t.videoWidth,h:t.videoHeight}:t instanceof HTMLImageElement?{w:t.naturalWidth||t.width,h:t.naturalHeight||t.height}:{w:t.width,h:t.height}}(s),{renderW:u,renderH:g}=gt(f,m),M="undefined"!=typeof window&&window.devicePixelRatio||1,p=8e6,v=u*M*g*M>p?Math.sqrt(p/(u*g)):M;e.width===Math.round(u*v)&&e.height===Math.round(g*v)||(e.width=Math.round(u*v),e.height=Math.round(g*v));const{frame:w}=V(s,h,u,g),y=(t,e)=>{d.save(),d.setTransform(v,0,0,v,0,0),Z(d,w,h,u,g,t/1e3,e),d.restore()};y(0,null);return C(e,y,{continuous:"none"!==h.animationStyle||!!h.charsetFrames?.length,interactive:h.hoverStrength>0}).stop}async function yt(t,e,{fontSize:n,artStyle:r="classic",options:i={}}={}){const s="string"==typeof t?await fetch(t).then(t=>t.arrayBuffer()):t,c=n??i.fontSize??10;let l={...a,...o[r],artStyle:r,...i,fontSize:c};const h=e.getContext("2d");if(!h)throw new Error("Could not get 2d context from canvas");const{frames:d,fps:f}=await X(s,l,e.width,e.height);if(!d.length)throw new Error("asciifyGif: the GIF contains no renderable frames.");const m=performance.now();let u=-1;return C(e,(t,n)=>{const o=Math.floor((t-m)*f/1e3)%d.length;o===u&&!n&&l.hoverStrength<=0&&"none"===l.animationStyle&&!l.charsetFrames?.length||(Z(h,d[o],l,e.width,e.height,(t-m)/1e3,n),u=o)},{continuous:!0,interactive:l.hoverStrength>0}).stop}async function xt(t,e,{fontSize:n,artStyle:r="classic",options:i={},fitTo:s,objectFit:c,objectPosition:l,scale:h,width:d,height:f,bleed:m,preExtract:u=!1,fps:g,maxRenderDimension:M=2048,trim:p,scroll:v,maxCachedFrames:w=90,onReady:y,onFrame:x}={}){const b=p?.start??0,S=p?.end,E=n??i.fontSize??10;let T={...a,...o[r],artStyle:r,...i,fontSize:E};const F=e.getContext("2d");if(!F)throw new Error("asciifyVideo: could not get 2d context from canvas.");const A="string"==typeof s?document.querySelector(s):s instanceof HTMLElement?s:null,k={objectFit:c,objectPosition:l,scale:h,width:d,height:f,bleed:m},I=function(t,e){var n;if(!function(t){return void 0!==t.objectFit||void 0!==t.objectPosition||void 0!==t.scale||void 0!==t.width||void 0!==t.height||void 0!==t.bleed}(e))return()=>{};const o={width:t.style.width,height:t.style.height,objectFit:t.style.objectFit,objectPosition:t.style.objectPosition,maxWidth:t.style.maxWidth,maxHeight:t.style.maxHeight,transformOrigin:t.style.transformOrigin,scale:t.style.getPropertyValue("scale")};if(e.objectFit&&(t.style.objectFit=e.objectFit),e.objectPosition&&(t.style.objectPosition=e.objectPosition,t.style.transformOrigin=e.objectPosition),void 0===e.scale&&void 0===e.bleed||(t.style.maxWidth="none",t.style.maxHeight="none"),void 0!==e.scale){const o=Number.isFinite(e.scale)&&e.scale>0?e.scale:1;t.style.setProperty("scale",String(o)),(n=t.style).transformOrigin||(n.transformOrigin=e.objectPosition??"center center")}return()=>{t.style.width=o.width,t.style.height=o.height,t.style.objectFit=o.objectFit,t.style.objectPosition=o.objectPosition,t.style.maxWidth=o.maxWidth,t.style.maxHeight=o.maxHeight,t.style.transformOrigin=o.transformOrigin,o.scale?t.style.setProperty("scale",o.scale):t.style.removeProperty("scale")}}(e,k),R=t=>()=>{t(),I()};if(u){let n;"string"==typeof t?(n=document.createElement("video"),n.crossOrigin="anonymous",n.src=t,n.readyState<2&&await new Promise((e,o)=>{n.onloadeddata=()=>e(),n.onerror=()=>o(new Error(`asciifyVideo: failed to load "${t}"`))})):n=t,T=await ut(n,T,b,S,v);const o=ht(n.videoWidth,n.videoHeight,T);A&&vt(e,A,o.w/o.h,o.w,o.h,M,k);const{renderW:r,renderH:a}=gt(o.w,o.h,M),i="undefined"!=typeof window&&window.devicePixelRatio||1,s=8e6,c=r*i*a*i>s?Math.sqrt(s/(r*a)):i;e.width===Math.round(r*c)&&e.height===Math.round(a*c)||(e.width=Math.round(r*c),e.height=Math.round(a*c));const l=void 0!==S?S-b:10,h=g??(v?18:void 0);if(ot(T)){const{frames:t,fps:o}=await Y(n,T,r,a,h,l,void 0,b),i=e=>{const n=t[e];n&&(F.save(),F.setTransform(c,0,0,c,0,0),D(F,n,T,r,a),F.restore(),x?.())};if(v){let o=!1,r=-1;const a=!0===v?{}:v,s=lt(nt(a.trigger)??A??e,a,e=>{const s=rt(e,a),c=Math.max(0,Math.min(t.length-1,Math.round(s*(t.length-1))));c!==r&&(r=c,i(c),o||(o=!0,y?.(n)),a.onUpdate?.(s,n))});return i(0),o=!0,y?.(n),R(s)}let s,d=!1,f=0,m=performance.now(),u=!0;const g=1e3/o,M=e=>{d||(e-m>=g&&(i(f),f=(f+1)%t.length,m=e,u&&(u=!1,y?.(n))),s=requestAnimationFrame(M))};return s=requestAnimationFrame(M),R(()=>{d=!0,cancelAnimationFrame(s)})}const{frames:d,fps:f}=await K(n,T,r,a,h,l,void 0,b);if(!d.length)throw new Error("asciifyVideo: no frames were decoded.");let m=0;const u=performance.now(),p=C(e,(t,e)=>{v||(m=Math.floor((t-u)*f/1e3)%d.length),F.save(),F.setTransform(c,0,0,c,0,0),Z(F,d[m],T,r,a,(t-u)/1e3,e),F.restore(),x?.()},{continuous:!v||"none"!==T.animationStyle||!!T.charsetFrames?.length,interactive:T.hoverStrength>0});let w;if(v){const t=!0===v?{}:v;w=lt(nt(t.trigger)??A??e,t,e=>{m=Math.max(0,Math.min(d.length-1,Math.round(rt(e,t)*(d.length-1)))),p.wake(),t.onUpdate?.(e,n)})}return y?.(n),R(()=>{p.stop(),w?.()})}let L,H=!1;"string"==typeof t?(L=document.createElement("video"),L.crossOrigin="anonymous",L.src=t,L.muted=!0,L.loop=!0,L.playsInline=!0,L.setAttribute("playsinline",""),Object.assign(L.style,{position:"fixed",top:"0",left:"0",width:"1px",height:"1px",opacity:"0",pointerEvents:"none",zIndex:"-1"}),document.body.appendChild(L),H=!0,await new Promise((e,n)=>{L.onloadedmetadata=()=>e(),L.onerror=()=>n(new Error(`asciifyVideo: failed to load "${t}"`))}),await L.play().catch(()=>{})):(L=t,L.readyState<HTMLMediaElement.HAVE_METADATA&&await new Promise((t,e)=>{const n=()=>{L.removeEventListener("loadedmetadata",o),L.removeEventListener("error",r)},o=()=>{n(),t()},r=()=>{n(),e(new Error("asciifyVideo: provided video element failed to load metadata."))};L.addEventListener("loadedmetadata",o),L.addEventListener("error",r),L.load()}),L.paused&&await L.play().catch(()=>{})),b>0&&(L.currentTime=b,await new Promise(t=>{const e=()=>{L.removeEventListener("seeked",e),t()};L.addEventListener("seeked",e)}),await st(L));let W=null;(b>0||void 0!==S)&&(W=()=>{(void 0!==S&&L.currentTime>=S||b>0&&L.currentTime<b)&&(L.currentTime=b)},L.addEventListener("timeupdate",W)),T=await ut(L,T,b,S,v);let $=null;const P=ht(L.videoWidth,L.videoHeight,T);let{renderW:j,renderH:z}=gt(P.w,P.h,M);const q=t=>"frame"===T.chromaKeyTrimMode?ft(t,T,j/z):T;if(A){const t=P.w/P.h,n=P.w,o=P.h,r=vt(e,A,t,n,o,M,k);j=r.renderW,z=r.renderH;const a=e.getContext("2d");a&&a.setTransform(r.dpr,0,0,r.dpr,0,0),$=new ResizeObserver(()=>{const r=vt(e,A,t,n,o,M,k);j=r.renderW,z=r.renderH;const a=e.getContext("2d");a&&a.setTransform(r.dpr,0,0,r.dpr,0,0)}),$.observe(A)}else{const t="undefined"!=typeof window&&window.devicePixelRatio||1,n=8e6,o=j*t*z*t>n?Math.sqrt(n/(j*z)):t;e.width===Math.round(j*o)&&e.height===Math.round(z*o)||(e.width=Math.round(j*o),e.height=Math.round(z*o)),F.setTransform(o,0,0,o,0,0)}let O=!0,B=null;const U=v&&!u,X=g&&g>0?1e3/g:0;let G=0;const J=!U&&ot(T);if(U&&"ascii"===T.renderMode&&"none"===T.animationStyle&&T.hoverStrength<=0&&!T.charsetFrames?.length){const t=!0===v?{}:v,n=nt(t.trigger)??A??e,o=t.from??b,r=t.to??S??L.duration,a=Math.max(o,Math.min(r,L.duration)),i=Math.max(.001,a-o),s=Math.min(60,Math.max(12,g??30)),c=Math.max(2,Math.ceil(i*s)+1),l=new Array(c),h=[],d=Math.max(2,Math.min(c,Math.floor(w))),f=()=>{for(;h.length>d;){const t=h.findIndex(t=>t!==u&&Math.abs(t-u)>2),e=t>=0?t:0,n=h.splice(e,1)[0];void 0!==n&&(l[n]=void 0)}},m=t=>{const e=h.indexOf(t);e>=0&&h.splice(e,1),h.push(t),f()};let u=0,M=0,p=-1,E=0,C=!1,k=!1,I=!1;const P=new Set,O=document.createElement("video");O.muted=!0,O.playsInline=!0,O.preload="auto",O.crossOrigin=L.crossOrigin||"anonymous",O.src=L.currentSrc||L.src,Object.assign(O.style,{position:"fixed",top:"0",left:"0",width:"1px",height:"1px",opacity:"0",pointerEvents:"none",zIndex:"-1"}),document.body.appendChild(O),O.readyState<HTMLMediaElement.HAVE_METADATA&&await new Promise((t,e)=>{const n=()=>{O.removeEventListener("loadedmetadata",o),O.removeEventListener("error",r)},o=()=>{n(),t()},r=()=>{n(),e(new Error("asciifyVideo: cache video failed to load metadata."))};O.addEventListener("loadedmetadata",o),O.addEventListener("error",r),O.load()}),O.pause(),L.paused&&await L.play().catch(()=>{});const U=t=>o+i*t/Math.max(1,c-1),V=t=>Math.max(0,Math.min(c-1,Math.round(t*(c-1)))),K=q(L),Y=N(L,K,j,z);Y.rows.length>0&&(l[0]=Y,m(0),D(F,Y,K,j,z),I=!0,y?.(L),x?.());const J=t=>{if(l[t])return t;for(let e=1;e<c;e++){const n=t-e,o=t+e;if(n>=0&&l[n])return n;if(o<c&&l[o])return o}return-1},_=()=>{if(!l[u])return u;for(const t of P)if(!l[t])return t;for(let t=1;t<c;t++){const e=u-t,n=u+t;if(e>=0&&!l[e])return e;if(n<c&&!l[n])return n}return-1},Q=t=>{t<0||t>=c||l[t]||(P.add(t),Z())},Z=async()=>{if(C||k)return;const t=_();if(!(t<0)){P.delete(t),k=!0;try{if(await it(O,U(t)),!C){const e=q(O),n=N(O,e,j,z);n.rows.length>0&&(l[t]=n,m(t))}}finally{k=!1,C||requestAnimationFrame(()=>{Z()})}}},tt=()=>{if(C)return;const t=J(u);if(t>=0&&t!==p){const e=l[t];e&&(D(F,e,T,j,z),p=t,I||(I=!0,y?.(L)),x?.())}else if(t<0||p<0){const t=performance.now();if(X<=0||t-G>=X){const e=q(L),n=N(L,e,j,z);n.rows.length>0&&(D(F,n,e,j,z),G=t,I||(I=!0,y?.(L)),x?.())}}Q(u),E=requestAnimationFrame(tt)};return B=lt(n,t,e=>{const n=function(t,e,n={}){if(!Number.isFinite(t.duration)||t.duration<=0)return null;const o=n.from??0,r=n.to??t.duration,a=Math.max(o,Math.min(r,t.duration)),i=rt(e,n),s=o+(a-o)*i;return{progress:i,time:Math.min(Math.max(o,s),Math.max(o,a-.04))}}(L,e,{...t,from:o,to:a});M=n?.progress??et(e),u=V(M),Q(u),Q(u-1),Q(u+1),Q(u-2),Q(u+2),Q(u-3),Q(u+3),t.onUpdate?.(M,L)}),Q(0),Q(1),E=requestAnimationFrame(tt),R(()=>{C=!0,cancelAnimationFrame(E),B?.(),$?.disconnect(),P.clear(),h.length=0,l.fill(void 0),O.pause(),O.src="",O.removeAttribute("src"),O.load(),O.isConnected&&O.remove(),W&&L.removeEventListener("timeupdate",W),H&&(L.pause(),L.src="",L.removeAttribute("src"),L.load(),L.isConnected&&L.remove())})}if(U){const t=!0===v?{}:v;B=ct(L,{...t,trigger:t.trigger??A??e,from:t.from??b,to:t.to??S})}let _=-1,Q=0,tt=-1,at=0;const dt="function"==typeof L.requestVideoFrameCallback,mt=()=>{at=L.requestVideoFrameCallback(()=>{Q++,mt()})};dt&&mt();let Mt=0,pt=0,wt=null;const yt=C(e,(t,n)=>{if(L.readyState<2||0===e.width||0===e.height)return;if(X>0&&t-G<X&&!n)return;if(b>0&&L.currentTime<b)return;if(void 0!==S&&L.currentTime>=S)return;const o=(dt?Q!==tt:L.currentTime!==_)||Mt!==j||pt!==z;if(o||!(T.hoverStrength<=0)||"none"!==T.animationStyle||T.charsetFrames?.length){if(J){const t=q(L),e=N(L,t,j,z);D(F,e,t,j,z)}else!o&&wt||(wt=V(L,q(L),j,z).frame),Z(F,wt,T,j,z,t/1e3,n);_=L.currentTime,tt=Q,Mt=j,pt=z,G=t,O&&(O=!1,y?.(L)),x?.()}},{continuous:!0,interactive:T.hoverStrength>0});return R(()=>{yt.stop(),at&&L.cancelVideoFrameCallback(at),B?.(),$?.disconnect(),W&&L.removeEventListener("timeupdate",W),H&&(L.pause(),L.src="",L.removeAttribute("src"),L.load(),L.isConnected&&L.remove())})}function bt(t,e,n){return xt(t,e,n)}function St(t,e={},n,o){const r={...a,...e},{frame:i,cols:s}=V(t,r,n,o);if(!i.length||0===s)return"";const c=[];for(const t of i)c.push(t.map(t=>t.char).join(""));return c.join("\n")}function Et(t,e={},n,o){const r={...a,...e},{frame:i,cols:s}=V(t,r,n,o);if(!i.length||0===s)return"";const c=[];for(const t of i){let e="";for(const n of t)" "===n.char||n.a<10?e+=" ":e+=`[38;2;${n.r};${n.g};${n.b}m${n.char}[0m`;c.push(e)}return c.join("\n")}function Ct(t,e,n,o="#505050",r=100){if(!t||e<=0||n<=0)return[];const a=function(t){const e=t.match(/^#([0-9a-f]{3,8})$/i)?.[1];if(e){const t=e.length<=4?e.split("").map(t=>parseInt(t+t,16)):[parseInt(e.slice(0,2),16),parseInt(e.slice(2,4),16),parseInt(e.slice(4,6),16)];return{r:t[0],g:t[1],b:t[2]}}const n=t.match(/rgba?\(\s*(\d+)[,\s]+(\d+)[,\s]+(\d+)/i);return n?{r:+n[1],g:+n[2],b:+n[3]}:null}(o)??{r:80,g:80,b:80},i=t,s=i.length;return Array.from({length:n},(t,n)=>Array.from({length:e},(t,o)=>({char:i[(n*e+o)%s],r:a.r,g:a.g,b:a.b,a:r})))}var Tt=new WeakMap;function Ft(t,e,n,o,r={},i){const{fontSize:s=10,lineHeight:c=1.6,color:l="#505050",opacity:h=100,hoverEffect:d="spotlight",hoverStrength:f=.85,hoverRadius:m=.18,hoverColor:u="#d4ff00"}=r,g=Math.max(1,Math.floor(e/s)),M=Math.max(1,Math.floor(n/(s*c))),p=JSON.stringify([o,g,M,l,h]);let v=Tt.get(t);v&&v.key===p||(v={key:p,frame:Ct(o,g,M,l,h)},Tt.set(t,v));Z(t,v.frame,{...a,fontSize:s,hoverEffect:d,hoverStrength:f,hoverRadius:m,hoverColor:u},e,n,0,i??null)}function At(t,{format:e="png",quality:n=.92,scale:o=1}={}){return new Promise((r,a)=>{let i=t;if(1!==o){const e=document.createElement("canvas");e.width=Math.round(t.width*o),e.height=Math.round(t.height*o);const n=e.getContext("2d");if(!n)return void a(new Error("captureSnapshot: could not get 2d context"));n.drawImage(t,0,0,e.width,e.height),i=e}i.toBlob(t=>t?r(t):a(new Error("captureSnapshot: toBlob returned null")),`image/${e}`,n)})}async function kt(t,e={}){const{filename:n="asciify-snapshot",format:o="png",...r}=e,a=await At(t,{format:o,...r}),i="jpeg"===o?"jpg":o,s=document.createElement("a");s.href=URL.createObjectURL(a),s.download=`${n}.${i}`,s.click(),setTimeout(()=>URL.revokeObjectURL(s.href),1e4)}async function It(t,{fontSize:e=10,style:n="classic",options:r={},liveOptions:i,mirror:s=!0,constraints:c={facingMode:"user"},dpr:l}={}){if(!navigator.mediaDevices?.getUserMedia)throw new Error("asciifyWebcam: getUserMedia is not supported in this browser.");const h=await navigator.mediaDevices.getUserMedia({video:c}),d=document.createElement("video");d.srcObject=h,d.muted=!0,d.playsInline=!0,await new Promise((t,e)=>{d.onloadedmetadata=()=>t(),d.onerror=()=>e(new Error("asciifyWebcam: video stream failed to load.")),d.play().catch(e)});const f={...a,...o[n],...r,fontSize:e},m=t.getContext("2d");if(!m)throw new Error("asciifyWebcam: could not get 2d context from canvas.");const u=l??("undefined"!=typeof window?window.devicePixelRatio:1)??1;1!==u&&m.scale(u,u);let g=null;const M=e=>{const n=t.getBoundingClientRect();g={x:(e.clientX-n.left)/n.width,y:(e.clientY-n.top)/n.height}},p=()=>{g=null};f.hoverStrength>0&&(t.addEventListener("mousemove",M),t.addEventListener("mouseleave",p));let v,w=!1;const y=performance.now(),x=e=>{if(!w){if(d.readyState>=d.HAVE_CURRENT_DATA){const n=t.width/u,o=t.height/u,r=(e-y)/1e3,a=i?{...f,...i()}:f;a.hoverStrength>0?(t.addEventListener("mousemove",M),t.addEventListener("mouseleave",p)):(t.removeEventListener("mousemove",M),t.removeEventListener("mouseleave",p));const{frame:c}=V(d,a,n,o),l=g&&s?{x:1-g.x,y:g.y}:g;s?(m.save(),m.scale(-1,1),m.translate(-n,0),Z(m,c,a,n,o,r,l),m.restore()):Z(m,c,a,n,o,r,l)}v=requestAnimationFrame(x)}};return v=requestAnimationFrame(x),()=>{w=!0,cancelAnimationFrame(v),t.removeEventListener("mousemove",M),t.removeEventListener("mouseleave",p),h.getTracks().forEach(t=>t.stop()),d.srcObject=null}}var Rt={A:[28,54,99,127,99,99,99],B:[126,99,99,126,99,99,126],C:[62,99,96,96,96,99,62],D:[124,102,99,99,99,102,124],E:[127,96,96,124,96,96,127],F:[127,96,96,124,96,96,96],G:[62,99,96,111,99,99,62],H:[99,99,99,127,99,99,99],I:[127,8,8,8,8,8,127],J:[63,6,6,6,102,102,60],K:[99,102,108,120,108,102,99],L:[96,96,96,96,96,96,127],M:[99,119,107,107,99,99,99],N:[99,115,107,103,99,99,99],O:[62,99,99,99,99,99,62],P:[126,99,99,126,96,96,96],Q:[62,99,99,99,107,102,61],R:[126,99,99,126,108,102,99],S:[62,99,96,62,3,99,62],T:[127,8,8,8,8,8,8],U:[99,99,99,99,99,99,62],V:[99,99,99,99,54,28,8],W:[99,99,99,107,107,54,20],X:[99,54,28,8,28,54,99],Y:[99,99,54,28,8,8,8],Z:[127,3,6,12,24,48,127],a:[0,0,60,3,62,99,61],b:[96,96,124,99,99,99,124],c:[0,0,62,96,96,96,62],d:[3,3,31,99,99,99,31],e:[0,0,62,99,127,96,62],f:[30,48,48,126,48,48,48],g:[0,0,63,99,63,3,62],h:[96,96,124,99,99,99,99],i:[8,0,24,8,8,8,28],j:[4,0,12,4,4,36,24],k:[96,96,102,108,120,108,102],l:[24,8,8,8,8,8,28],m:[0,0,92,107,107,99,99],n:[0,0,94,99,99,99,99],o:[0,0,62,99,99,99,62],p:[0,0,126,99,126,96,96],q:[0,0,63,99,63,3,3],r:[0,0,94,99,96,96,96],s:[0,0,62,96,62,3,124],t:[48,48,126,48,48,48,30],u:[0,0,99,99,99,103,59],v:[0,0,99,99,54,28,8],w:[0,0,99,99,107,54,20],x:[0,0,99,54,28,54,99],y:[0,0,99,99,63,3,62],z:[0,0,127,6,12,24,127],0:[62,99,103,107,115,99,62],1:[8,24,56,8,8,8,62],2:[62,99,3,6,24,48,127],3:[62,99,3,30,3,99,62],4:[6,14,22,38,127,6,6],5:[127,96,126,3,3,99,62],6:[62,99,96,126,99,99,62],7:[127,3,6,12,24,24,24],8:[62,99,99,62,99,99,62],9:[62,99,99,63,3,99,62]," ":[0,0,0,0,0,0,0],"!":[24,24,24,24,24,0,24],"?":[62,99,3,14,8,0,8],".":[0,0,0,0,0,24,24],",":[0,0,0,0,0,24,48],";":[0,24,24,0,24,24,48],":":[0,24,24,0,24,24,0],"-":[0,0,0,62,0,0,0],_:[0,0,0,0,0,0,127],"'":[24,24,32,0,0,0,0],'"':[54,54,36,0,0,0,0],"`":[24,8,0,0,0,0,0],")":[24,12,6,6,6,12,24],"(":[12,24,48,48,48,24,12],"[":[60,48,48,48,48,48,60],"]":[30,6,6,6,6,6,30],"{":[14,24,24,48,24,24,14],"}":[56,12,12,6,12,12,56],"/":[3,6,12,24,48,96,0],"\\":[96,48,24,12,6,3,0],"|":[8,8,8,8,8,8,8],"+":[0,8,8,62,8,8,0],"=":[0,0,62,0,62,0,0],"*":[0,42,28,127,28,42,0],"#":[36,36,127,36,127,36,36],"@":[62,99,111,107,111,96,62],"&":[24,36,24,60,74,68,58],"%":[99,38,4,8,16,50,99],$:[8,62,72,62,9,62,8],"^":[8,20,34,0,0,0,0],"~":[0,0,50,76,0,0,0],"<":[6,12,24,48,24,12,6],">":[48,24,12,6,12,24,48]},Lt=[127,65,65,65,65,65,127];function Ht(t){return Rt[t]??Rt[t.toUpperCase()]??Lt}function Wt(t,e={}){if(!t)return"";const{char:n="█",scale:o=1}=e,r=[...n][0]??"█",a=Math.max(1,Math.floor(o)),i=7*a,s=a,c=Array.from({length:i},()=>"");for(let e=0;e<t.length;e++){const n=Ht(t[e]);for(let t=0;t<7;t++){const e=n[t];let o="";for(let t=6;t>=0;t--)o+=(e>>t&1?r:" ").repeat(a);for(let e=0;e<a;e++)c[t*a+e]+=o}if(e<t.length-1)for(let t=0;t<i;t++)c[t]+=" ".repeat(s)}return c.join("\n")}function $t(t,e,n={}){const{color:o="#d4ff00",bgColor:r,fontSize:a=10}=n,i=Wt(e,n);if(!i)return;const s=i.split("\n"),c=Math.max(...s.map(t=>[...t].length));t.width=Math.ceil(c*a*.6),t.height=Math.ceil(s.length*a);const l=t.getContext("2d");r&&"transparent"!==r?(l.fillStyle=r,l.fillRect(0,0,t.width,t.height)):l.clearRect(0,0,t.width,t.height),l.fillStyle=o,l.font=`${a}px monospace`,l.textBaseline="top",s.forEach((t,e)=>l.fillText(t,0,e*a))}export{o as ART_STYLE_PRESETS,e as CHARSETS,n as CHARSET_SEQUENCES,a as DEFAULT_OPTIONS,i as HOVER_PRESETS,r as LIVING_STYLE_PRESETS,t as PALETTE_THEMES,St as asciiText,Et as asciiTextAnsi,wt as asciify,yt as asciifyGif,bt as asciifyLiveVideo,Wt as asciifyText,xt as asciifyVideo,It as asciifyWebcam,Ct as buildTextFrame,At as captureSnapshot,j as clearAsciifyCaches,Mt as computeCanvasRenderSize,ct as createVideoScrollScrub,X as gifToAsciiFrames,G as gifToAsciiTextFrames,V as imageToAsciiFrame,N as imageToAsciiTextFrame,Z as renderFrameToCanvas,Ft as renderTextBackground,D as renderTextFrameToCanvas,$t as renderTextToCanvas,kt as snapshotAndDownload,K as videoToAsciiFrames,Y as videoToAsciiTextFrames};//# sourceMappingURL=core.js.map
|
package/dist/hover.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var t=[{value:"none",mode:"none",label:"Off",description:"Keep the image still. Hover stays available."},{value:"breathe",mode:"print",label:"Living Print",description:"Soft tonal movement. The character grid stays still."},{value:"wave",mode:"current",label:"Slow Current",description:"A gentle flow through the image, with steady edges."},{value:"rain",mode:"reform",label:"Reveal & Reform",description:"Disperse, gather, then hold the complete image."}];function e(e){return"orbit"===e?"current":t.find(t=>t.value===e||t.mode===e)?.mode??"none"}var i=(t,e,i)=>{const s=(t=>Math.max(0,Math.min(1,t)))((i-t)/(e-t));return s*s*(3-2*s)},s=(t,e)=>{const i=(.06711056*t+.00583715*e)%1*52.9829189;return i-Math.floor(i)},n=class{constructor(){this.last=null,this.mode="none",this.phase=0}update(t,e,i=1){return Number.isFinite(t)?((e!==this.mode||null!==this.last&&t<this.last)&&(this.mode=e,this.phase=0,this.last=t),null!==this.last&&(this.phase+=Math.max(0,t-this.last)*Math.max(.1,Math.min(3,Number.isFinite(i)?i:1))),this.last=t,this.phase):this.phase}};function h(t,e,s,n,h){const a=n*Math.PI/6,o=i(0,.12,Math.min(e,1-e,s,1-s));if(h[0]=h[1]=h[2]=0,h[3]=1,"print"===t)h[2]=Math.sin(9*e+5*s+a)*Math.cos(8*s-3*e-a)*.065*o,h[3]=.9+.1*Math.sin(6*e-4*s+a);else if("current"===t)h[0]=Math.sin(9*s+a)*Math.cos(7*e-a)*6*o,h[1]=Math.cos(8*e+a)*Math.sin(6*s-a)*4*o;else if("reform"===t){const t=(n%12+12)%12,a=.8*e+.2*s+.08*Math.sin(8*e-5*s),o=i(1.8+1.2*a,3.8+1.2*a,t)*(1-i(5+1.7*a,7.2+1.7*a,t));h[2]=.95*-o,h[3]=1-.82*o}return h}function a(t,e,i){const s=Math.min(t*Math.max(1,i),(1-t)*Math.max(1,i),e*Math.max(1,1/i),(1-e)*Math.max(1,1/i)),n=Math.max(0,Math.min(1,(s-.035)/.105));return n*n*n*(n*(6*n-15)+10)}var o=class{constructor(t,e){this.previous=null,this.peak=0,this.mode="dissolve",this.width=t,this.height=e;const i=t*e;this.pixels=new Uint8Array(4*i),this.ink=new Float32Array(i),this.targetX=new Float32Array(i),this.targetY=new Float32Array(i),this.offsetX=new Float32Array(i),this.offsetY=new Float32Array(i),this.edge=new Float32Array(i);for(let i=0;i<e;i++)for(let s=0;s<t;s++)this.edge[i*t+s]=a(s/(t-1),i/(e-1),t/e);this.clear()}get active(){return this.peak>2e-4}setMode(t){t!==this.mode&&(this.mode=t,this.clear())}clear(){for(const t of[this.ink,this.targetX,this.targetY,this.offsetX,this.offsetY,this.pixels])t.fill(0);if(this.previous=null,this.peak=0,"dissolve"!==this.mode)for(let t=0;t<this.pixels.length;t+=4)this.pixels[t]=this.pixels[t+2]=128}leave(){this.previous=null}move(t,e,i){if(!Number.isFinite(t+e+i))return;t=Math.max(0,Math.min(1,t)),e=Math.max(0,Math.min(1,e));const s=this.previous;this.previous={x:t,y:e};const n=this.width,h=this.height,a=Math.max(1,n/h),o=Math.max(1,h/n),r=s?(t-s.x)*a:0,l=s?(e-s.y)*o:0,c=Math.hypot(r,l);if(!s&&"dissolve"!==this.mode)return;if(s&&c<1e-4)return;const m=.035+.11*Math.max(.1,Math.min(1,i)),d=Math.min(128,Math.max(1,Math.ceil(c/(.45*m)))),u=c?r/c:1,f=c?l/c:0,g=Math.min(1,c/(m*d)*2.2);for(let i=0;i<d;i++){const r=(i+.5)/d,l=s?s.x+(t-s.x)*r:t,c=s?s.y+(e-s.y)*r:e,p=Math.max(0,Math.floor((l-2.5*m/a)*(n-1))),x=Math.min(n-1,Math.ceil((l+2.5*m/a)*(n-1))),v=Math.max(0,Math.floor((c-2.5*m/o)*(h-1))),M=Math.min(h-1,Math.ceil((c+2.5*m/o)*(h-1)));for(let t=v;t<=M;t++)for(let e=p;e<=x;e++){const i=(e/(n-1)-l)*a/m,s=(t/(h-1)-c)*o/m,r=Math.exp(1.5*-(i*i+s*s)),d=t*n+e;if("dissolve"===this.mode)this.ink[d]=Math.max(this.ink[d],r);else{const t=(-i*f+s*u)*r*2.8,e="silk"===this.mode?u*t:-s*r*2.5,n="silk"===this.mode?f*t:i*r*2.5;this.targetX[d]=Math.max(-1,Math.min(1,this.targetX[d]+e*g)),this.targetY[d]=Math.max(-1,Math.min(1,this.targetY[d]+n*g))}}}this.peak=1}step(t){if(!this.active||!Number.isFinite(t))return;const e=Math.max(0,Math.min(.05,t)),i=Math.exp(-("dissolve"===this.mode?2.15:3.2)*e),s=1-Math.exp(-22*e);let n=0;for(let t=0;t<this.ink.length;t++)if("dissolve"===this.mode){this.ink[t]*=i,n=Math.max(n,this.ink[t]);const e=Math.round(65535*this.ink[t]);this.pixels[4*t]=e>>>8,this.pixels[4*t+1]=255&e}else{this.targetX[t]*=i,this.targetY[t]*=i,this.offsetX[t]+=(this.targetX[t]-this.offsetX[t])*s,this.offsetY[t]+=(this.targetY[t]-this.offsetY[t])*s,n=Math.max(n,Math.abs(this.offsetX[t]),Math.abs(this.offsetY[t]),Math.abs(this.targetX[t]),Math.abs(this.targetY[t]));const e=Math.round(this.offsetX[t]*this.edge[t]*32767+32768),h=Math.round(this.offsetY[t]*this.edge[t]*32767+32768);this.pixels[4*t]=e>>>8,this.pixels[4*t+1]=255&e,this.pixels[4*t+2]=h>>>8,this.pixels[4*t+3]=255&h}this.peak=n,this.active||this.clear()}sample(t,e,i){const s=Math.max(0,Math.min(this.width-1.001,t*(this.width-1))),n=Math.max(0,Math.min(this.height-1.001,e*(this.height-1))),h=Math.floor(s),o=Math.floor(n),r=s-h,l=n-o,c=o*this.width+h,m=c+this.width,d=t=>(t[c]*(1-r)+t[c+1]*r)*(1-l)+(t[m]*(1-r)+t[m+1]*r)*l;i[0]=d(this.offsetX)*a(t,e,this.width/this.height)*.08,i[1]=d(this.offsetY)*a(t,e,this.width/this.height)*.08,i[2]="dissolve"===this.mode?6*-d(this.ink):0}},r=class{constructor(t,e){this.rings=[],this.previous=null,this.elapsed=1,this.echoPeak=0,this.width=t,this.height=e,this.pixels=new Uint8Array(t*e*4),this.echo=new Float32Array(t*e)}get active(){return this.rings.length>0||this.echoPeak>2e-4}clear(){this.rings=[],this.previous=null,this.elapsed=1,this.pixels.fill(0),this.echo.fill(0),this.echoPeak=0}leave(){this.previous=null}move(t,e,i){const s=Math.max(1,this.width/this.height),n=Math.max(1,this.height/this.width);this.previous&&(Math.hypot((t-this.previous.x)*s,(e-this.previous.y)*n)<.065||this.elapsed<.3)||4!==this.rings.length&&(this.previous={x:t,y:e},this.elapsed=0,this.rings.push({x:t,y:e,age:0,radius:i}))}ringSample(t,e){const i=Math.max(1,this.width/this.height),s=Math.max(1,this.height/this.width);let n=0;for(const h of this.rings){const a=.015+h.age*(.15+.22*h.radius),o=.009+.014*h.radius,r=(Math.hypot((t-h.x)*i,(e-h.y)*s)-a)/o,l=Math.sin(Math.min(1,h.age/.07)*Math.PI/2)*Math.max(0,1-h.age/1.35)**2;n=Math.max(n,Math.exp(-r*r)*l)}return n}sample(t,e){const i=Math.max(0,Math.min(this.width-1,Math.round(t*(this.width-1)))),s=Math.max(0,Math.min(this.height-1,Math.round(e*(this.height-1))));return Math.max(this.ringSample(t,e),this.echo[s*this.width+i])}step(t){if(!Number.isFinite(t))return;const e=Math.max(0,Math.min(.05,t));this.elapsed+=e;for(const t of this.rings)t.age+=e;if(this.rings=this.rings.filter(t=>t.age<1.35),!this.active)return void this.pixels.fill(0);const i=Math.exp(-5.5*e);let s=0;for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++){const n=t*this.width+e;this.echo[n]=Math.max(this.ringSample(e/(this.width-1),t/(this.height-1)),this.echo[n]*i),s=Math.max(s,this.echo[n]);const h=Math.round(65535*this.echo[n]),a=4*n;this.pixels[a]=h>>>8,this.pixels[a+1]=255&h}this.echoPeak=s,this.active||(this.echo.fill(0),this.pixels.fill(0))}},l=class{constructor(t,e){this.previous=null,this.remainder=0,this.peak=0,this.width=t,this.height=e;const i=t*e;this.pixels=new Uint8Array(4*i),this.u=new Float32Array(i),this.v=new Float32Array(i),this.ink=new Float32Array(i),this.a=new Float32Array(i),this.b=new Float32Array(i),this.c=new Float32Array(i),this.pressure=new Float32Array(i),this.pressureNext=new Float32Array(i),this.divergence=new Float32Array(i),this.curl=new Float32Array(i)}get active(){return this.peak>2e-4}clear(){for(const t of[this.u,this.v,this.ink,this.a,this.b,this.c,this.pressure,this.pressureNext,this.divergence,this.curl,this.pixels])t.fill(0);this.previous=null,this.peak=0,this.remainder=0}leave(){this.previous=null}move(t,e,i){const s=this.previous;if(this.previous={x:t,y:e},!s)return;const n=(t-s.x)*(this.width-1),h=(e-s.y)*(this.height-1),a=Math.hypot(n,h);if(a<.001)return;const o=Math.min(this.width,this.height)*(.038+.12*i),r=Math.min(128,Math.max(1,Math.ceil(a/(.5*o)))),l=a/o*.95/r;for(let i=0;i<r;i++){const a=(i+.5)/r,c=(s.x+(t-s.x)*a)*(this.width-1),m=(s.y+(e-s.y)*a)*(this.height-1),d=Math.max(1,Math.floor(c-2.5*o)),u=Math.min(this.width-2,Math.ceil(c+2.5*o)),f=Math.max(1,Math.floor(m-2.5*o)),g=Math.min(this.height-2,Math.ceil(m+2.5*o));for(let t=f;t<=g;t++)for(let e=d;e<=u;e++){const i=Math.exp(-((e-c)**2+(t-m)**2)/(o*o)),s=t*this.width+e;this.ink[s]=Math.min(1,this.ink[s]+i*l),this.u[s]=Math.max(-50,Math.min(50,this.u[s]+n*i*5/r)),this.v[s]=Math.max(-50,Math.min(50,this.v[s]+h*i*5/r))}}this.peak=1}read(t,e,i){const s=0|(e=Math.max(.5,Math.min(this.width-1.5,e))),n=0|(i=Math.max(.5,Math.min(this.height-1.5,i))),h=e-s,a=i-n,o=n*this.width+s;return(t[o]*(1-h)+t[o+1]*h)*(1-a)+(t[o+this.width]*(1-h)+t[o+this.width+1]*h)*a}sample(t,e){return this.read(this.ink,t*(this.width-1),e*(this.height-1))}step(t){if(!this.active||!Number.isFinite(t))return;this.remainder+=Math.max(0,Math.min(.05,t));const e=1/60,i=this.width,s=this.height;for(;this.remainder+1e-8>=e;){this.remainder-=e;for(let t=1;t<s-1;t++)for(let s=1;s<i-1;s++){const n=t*i+s,h=s-this.u[n]*e,a=t-this.v[n]*e;this.a[n]=.972*this.read(this.u,h,a),this.b[n]=.972*this.read(this.v,h,a),this.c[n]=.964*this.read(this.ink,h,a)}[this.u,this.a]=[this.a,this.u],[this.v,this.b]=[this.b,this.v],[this.ink,this.c]=[this.c,this.ink];for(let t=1;t<s-1;t++)for(let e=1;e<i-1;e++){const s=t*i+e;this.curl[s]=.5*(this.v[s+1]-this.v[s-1]-this.u[s+i]+this.u[s-i])}for(let t=1;t<s-1;t++)for(let s=1;s<i-1;s++){const n=t*i+s,h=Math.abs(this.curl[n+1])-Math.abs(this.curl[n-1]),a=Math.abs(this.curl[n+i])-Math.abs(this.curl[n-i]),o=Math.hypot(h,a)+1e-4,r=this.curl[n]*e*5;this.u[n]+=a/o*r,this.v[n]-=h/o*r,this.divergence[n]=-.5*(this.u[n+1]-this.u[n-1]+this.v[n+i]-this.v[n-i])}this.pressure.fill(0);for(let t=0;t<4;t++){for(let t=1;t<s-1;t++)for(let e=1;e<i-1;e++){const s=t*i+e;this.pressureNext[s]=.25*(this.divergence[s]+this.pressure[s-1]+this.pressure[s+1]+this.pressure[s-i]+this.pressure[s+i])}[this.pressure,this.pressureNext]=[this.pressureNext,this.pressure]}let t=0;for(let e=1;e<s-1;e++)for(let s=1;s<i-1;s++){const n=e*i+s;this.u[n]=Math.max(-50,Math.min(50,this.u[n]-.5*(this.pressure[n+1]-this.pressure[n-1]))),this.v[n]=Math.max(-50,Math.min(50,this.v[n]-.5*(this.pressure[n+i]-this.pressure[n-i]))),t=Math.max(t,this.ink[n])}this.peak=t}if(this.active)for(let t=0;t<this.ink.length;t++){const e=Math.round(65535*Math.min(1,this.ink[t]));this.pixels[4*t]=e>>>8,this.pixels[4*t+1]=255&e}else this.clear()}},c=t=>["trail","contour","dissolve"].includes(t),m=class{constructor(t=1){this.mode="water",this.amount=.55,this.radius=.2,this.lensX=.5,this.lensY=.5,this.lensStrength=0,this.previous=null,this.energy=0,this.pending=!1,this.remainder=0,t=Math.max(.25,Math.min(4,t)),this.columns=Math.round(t>=1?128:128*t),this.rows=Math.round(t>=1?128/t:128),this.xScale=Math.max(1,t),this.yScale=Math.max(1,1/t),this.heights=new Float32Array(this.columns*this.rows),this.velocity=new Float32Array(this.heights.length),this.next=new Float32Array(this.heights.length),this.normals=new Float32Array(2*this.heights.length),this.edgeMask=new Float32Array(this.heights.length);for(let e=0;e<this.rows;e++)for(let i=0;i<this.columns;i++)this.edgeMask[e*this.columns+i]=a(i/(this.columns-1),e/(this.rows-1),t);this.refraction={width:this.columns,height:this.rows,pixels:new Uint8Array(4*this.heights.length),strength:30,mode:"water",focus:[.5,.5,0,.2]},this.waterPixels=this.refraction.pixels,this.trail=new l(this.columns,this.rows),this.contour=new r(this.columns,this.rows),this.afterimage=new o(this.columns,this.rows),this.clear()}get densityTrail(){return["trail","contour","dissolve"].includes(this.mode)}get hasRefraction(){return this.active||this.lensStrength>15e-5}get active(){return["dissolve","silk","vortex"].includes(this.mode)?this.afterimage.active:"contour"===this.mode?this.contour.active:"trail"===this.mode?this.trail.active:this.pending||this.energy>15e-5}setMode(t){t!==this.mode&&(this.clear(),this.mode=t,this.refraction.mode=t,"dissolve"!==t&&"silk"!==t&&"vortex"!==t||this.afterimage.setMode(t),this.refraction.pixels="trail"===t?this.trail.pixels:"contour"===t?this.contour.pixels:["dissolve","silk","vortex"].includes(t)?this.afterimage.pixels:this.waterPixels,this.refraction.strength="water"===t?30*this.amount/.55:"silk"===t?28*this.amount:"vortex"===t?38*this.amount:0)}configure(t,e=.55,i=.2){this.setMode(t),this.amount=Number.isFinite(e)?Math.max(0,Math.min(1,e)):.55,this.radius=Number.isFinite(i)?Math.max(.1,Math.min(1,i)):.2,this.refraction.strength="water"===t?30*this.amount/.55:"silk"===t?28*this.amount:"vortex"===t?38*this.amount:0,this.refraction.focus[2]=this.densityTrail?this.amount:this.lensStrength*this.amount,this.refraction.focus[3]=this.radius}move(t,e){if("none"===this.mode||0===this.amount)return;if(!Number.isFinite(t+e))return;if(t=Math.max(0,Math.min(1,t)),e=Math.max(0,Math.min(1,e)),["dissolve","silk","vortex"].includes(this.mode))return void this.afterimage.move(t,e,this.radius);if("contour"===this.mode)return void this.contour.move(t,e,this.radius);if("trail"===this.mode)return void this.trail.move(t,e,this.radius);if("water"!==this.mode)return!this.previous&&this.lensStrength<.001&&(this.lensX=t,this.lensY=e),this.previous={x:t,y:e},void(this.pending=!0);if(!this.previous)return void(this.previous={x:t,y:e});const i=this.previous;this.previous={x:t,y:e};const s=(t-i.x)*this.xScale,n=(e-i.y)*this.yScale,h=Math.hypot(s,n);if(h<1e-5)return;const a=.035+.1*this.radius,o=3*a,r=Math.min(192,Math.max(1,Math.ceil(h/(.5*a)))),l=95*Math.min(h,1)/r;for(let s=0;s<r;s++){const n=(s+.5)/r,h=i.x+(t-i.x)*n,c=i.y+(e-i.y)*n,m=Math.max(1,Math.floor((h-o/this.xScale)*(this.columns-1))),d=Math.min(this.columns-2,Math.ceil((h+o/this.xScale)*(this.columns-1))),u=Math.max(1,Math.floor((c-o/this.yScale)*(this.rows-1))),f=Math.min(this.rows-2,Math.ceil((c+o/this.yScale)*(this.rows-1)));for(let t=u;t<=f;t++)for(let e=m;e<=d;e++){const i=(e/(this.columns-1)-h)*this.xScale,s=(t/(this.rows-1)-c)*this.yScale,n=Math.exp(-(i*i+s*s)/(a*a))*l,o=t*this.columns+e;this.velocity[o]=Math.max(-12,this.velocity[o]-n)}}this.pending=!0}leave(){this.afterimage.leave(),this.contour.leave(),this.trail.leave(),this.previous=null,"water"!==this.mode&&this.lensStrength&&(this.pending=!0)}clear(){this.trail.clear(),this.contour.clear(),this.afterimage.clear(),this.heights.fill(0),this.velocity.fill(0),this.next.fill(0),this.normals.fill(0),this.refraction.focus[2]=0,this.previous=null,this.lensStrength=0,this.energy=0,this.pending=!1,this.remainder=0;for(let t=0;t<this.waterPixels.length;t+=4)this.waterPixels[t]=this.waterPixels[t+2]=128,this.waterPixels[t+1]=this.waterPixels[t+3]=0}step(t){if(!this.active||!Number.isFinite(t))return;if(["dissolve","silk","vortex"].includes(this.mode))return void this.afterimage.step(t);if("contour"===this.mode)return void this.contour.step(t);if("trail"===this.mode)return void this.trail.step(t);if("water"!==this.mode)return void this.stepLight(Math.max(0,Math.min(.05,t)));this.remainder+=Math.max(0,Math.min(.05,t));const e=1/120,i=Math.exp(-3.8*e),s=.3*Math.min(this.columns,this.rows);for(;this.remainder+1e-8>=e;){this.remainder-=e;let t=0;for(let n=1;n<this.rows-1;n++)for(let h=1;h<this.columns-1;h++){const a=n*this.columns+h,o=this.heights[a],r=this.heights[a-1]+this.heights[a+1]+this.heights[a-this.columns]+this.heights[a+this.columns]-4*o,l=Math.min(h,n,this.columns-1-h,this.rows-1-n),c=l<5?.88+.024*l:1,m=(this.velocity[a]+(r*s*s-8*o)*e)*i*c;this.velocity[a]=m,this.next[a]=(o+m*e)*c,t=Math.max(t,Math.abs(this.next[a]),.1*Math.abs(m))}this.heights.set(this.next),this.energy=t,this.pending=!1}if(!this.active)return void this.clear();const n=.18*Math.min(this.columns,this.rows);for(let t=0;t<this.rows;t++)for(let e=0;e<this.columns;e++){const i=t*this.columns+e,s=(this.heights[t*this.columns+Math.max(0,e-1)]-this.heights[t*this.columns+Math.min(this.columns-1,e+1)])*n,h=(this.heights[Math.max(0,t-1)*this.columns+e]-this.heights[Math.min(this.rows-1,t+1)*this.columns+e])*n,a=Math.tanh(s)*this.edgeMask[i],o=Math.tanh(h)*this.edgeMask[i];this.normals[2*i]=a,this.normals[2*i+1]=o;const r=Math.round(32767*a+32768),l=Math.round(32767*o+32768);this.refraction.pixels[4*i]=r>>>8,this.refraction.pixels[4*i+1]=255&r,this.refraction.pixels[4*i+2]=l>>>8,this.refraction.pixels[4*i+3]=255&l}}stepLight(t){const e=this.previous,i=1-Math.exp(-30*t),s=1-Math.exp(-12*t);e&&(this.lensX+=(e.x-this.lensX)*i,this.lensY+=(e.y-this.lensY)*i),this.lensStrength+=((e?1:0)-this.lensStrength)*s,this.energy=Math.max(e?Math.abs(e.x-this.lensX)+Math.abs(e.y-this.lensY):0,Math.abs((e?1:0)-this.lensStrength)),this.pending=!1,e||this.active?this.refraction.focus=[this.lensX,this.lensY,this.lensStrength*this.amount,this.radius]:this.clear()}sample(t,e,i){if(["dissolve","silk","vortex"].includes(this.mode))return this.afterimage.sample(t,e,i),i[0]*=this.amount,i[1]*=this.amount,void(i[2]*=this.amount);if("contour"===this.mode)return i[0]=i[1]=0,void(i[2]=this.contour.sample(t,e)*this.amount*3);if("trail"===this.mode)return i[0]=i[1]=0,void(i[2]=this.trail.sample(t,e)*this.amount*3);const s=Math.max(0,Math.min(this.columns-1.001,t*(this.columns-1))),n=Math.max(0,Math.min(this.rows-1.001,e*(this.rows-1))),h=Math.floor(s),a=Math.floor(n),o=s-h,r=n-a,l=2*(a*this.columns+h),c=l+2*this.columns;for(let t=0;t<2;t++)i[t]=.08*((this.normals[l+t]*(1-o)+this.normals[l+2+t]*o)*(1-r)+(this.normals[c+t]*(1-o)+this.normals[c+2+t]*o)*r);i[0]*=this.amount/.55,i[1]*=this.amount/.55,i[2]="light"===this.mode||"scan"===this.mode?function(t,e,i,s){const[n,h,a,o]=i.focus,r=(t-n)*Math.max(1,s)/o,l=(e-h)*Math.max(1,1/s)/o;return"light"===i.mode?Math.exp(-3*(r*r+l*l))*a:"scan"===i.mode?(1.3*Math.exp(-r*r*110)-.3*Math.exp(-r*r*12))*Math.exp(-l*l*1.8)*a:0}(t,e,this.refraction,this.xScale/this.yScale):0}};function d(t){const e=Intl.Segmenter;return e?Array.from(new e(void 0,{granularity:"grapheme"}).segment(t),t=>t.segment):Array.from(t)}function u(){const t=document.createElement("canvas"),e=document.createElement("canvas"),i=t.getContext("2d"),s=e.getContext("2d",{willReadFrequently:!0});let n,h=null;return{update(a,o,r,l,c,m,u,f){const g=u?.[0]?.length??Math.max(1,Math.round(o/l)),p=u?.length??Math.max(1,Math.round(r/c)),x=f??{charset:" .:-=+*#%@",customText:"",colorMode:"fullcolor"},v=x.charset+(x.charsetFrames?.join("")??""),M=function(t,e,i,s,n,h,a,o=4096,r=0){if(![i,s,n,h,a,o].every(t=>Number.isFinite(t)&&t>0))throw new Error("Glyph atlas dimensions must be positive and finite.");const l=JSON.stringify([e.charset,e.customText,i,s,n,h,a,o,r]);if(t?.key===l)return t;const c=[...new Set([" ",...d(e.charset),...d(e.customText??"")])];if(c.length>65536)throw new Error("This character set exceeds the glyph texture capacity.");const m=i/h,u=s/a,f=.9*Math.min(m/.55,u),g=Math.ceil(m*n)+4,p=Math.ceil(u*n)+4,x=Math.min(c.length,Math.floor(o/g));if(x<1||Math.ceil(c.length/x)*p>o)throw new Error("The glyph atlas exceeds the available GPU texture size.");return{key:l,glyphs:c,indices:new Map(c.map((t,e)=>[t,e])),cellWidth:m,cellHeight:u,fontSize:f,padding:2,tileWidth:g,tileHeight:p,atlasColumns:x,atlasWidth:x*g,atlasHeight:Math.ceil(c.length/x)*p}}(h,{...x,charset:v},o,r,m,g,p);if(M!==h&&(t.width=M.atlasWidth,t.height=M.atlasHeight,i.font=M.fontSize*m+'px "JetBrains Mono", monospace',i.textAlign="center",i.textBaseline="middle",i.fillStyle="#fff",M.glyphs.forEach((t,e)=>i.fillText(t,e%M.atlasColumns*M.tileWidth+M.padding+M.cellWidth*m*.5,Math.floor(e/M.atlasColumns)*M.tileHeight+M.padding+M.cellHeight*m*.5))),h=M,u){n=function(t,e,i,s,n=!1){const h=t.length,a=t[0]?.length??0,o=s?.cols===a&&s.rows===h?s:{cols:a,rows:h,indices:new Uint8Array(a*h*4),colors:new Uint8ClampedArray(a*h*4)};o.indices.fill(0),o.colors.fill(0);const r="accent"===i.colorMode?[1,3,5].map(t=>parseInt(i.accentColor.slice(t,t+2),16)):null;for(let s=0;s<h;s++){if(t[s].length!==a)throw new Error("Glyph frames must have a rectangular cell grid.");for(let h=0;h<a;h++){const l=t[s][h];if(!l.char||!n&&" "===l.char||l.a<10)continue;const c=e.get(l.char);if(void 0===c)throw new Error(`Glyph is absent from the configured character set: ${l.char}`);const m=4*(s*a+h);let d=l.r,u=l.g,f=l.b;if(r)[d,u,f]=r;else if("fullcolor"!==i.colorMode){const t=.299*d+.587*u+.114*f|0;d="matrix"===i.colorMode?0:t,u=t,f=d}(n||0!==d||0!==u||0!==f)&&(o.indices[m]=255&c,o.indices[m+1]=c>>>8,o.colors[m]=d,o.colors[m+1]=u,o.colors[m+2]=f,o.colors[m+3]=l.a)}}return o}(u,h.indices,x,n,!0);for(let t=0;t<p;t++)for(let e=0;e<g;e++){const i=u[t][e],s=4*(t*g+e);n.indices[s+2]=Math.round(.299*i.r+.587*i.g+.114*i.b)}}else{e.width=g,e.height=p,s.drawImage(a,0,0,g,p);const t=s.getImageData(0,0,g,p).data;n={cols:g,rows:p,indices:new Uint8Array(g*p*4),colors:new Uint8ClampedArray(t)};for(let e=0;e<t.length;e+=4){const i=Math.min(1,(.299*t[e]+.587*t[e+1]+.114*t[e+2])/255*(t[e+3]/255)*3);n.indices[e+2]=Math.round(255*i),n.indices[e]=Math.min(h.glyphs.length-1,Math.floor(i*h.glyphs.length))}}return{plan:h,packed:n,atlas:t,dots:"dots"===x.renderMode,dotSize:x.dotSizeRatio??.72}},destroy(){t.width=t.height=e.width=e.height=1,n=void 0,h=null}}}function f(t,i,a={}){let o={effect:"trail",strength:.55,radius:.2,animated:!1,fps:30,fontSize:7,charAspect:.58,charSpacing:1,paused:!1,charset:" .:-=+*#%@",customText:"",renderMode:"ascii",dotSizeRatio:.72,...a},r=new m(i.clientWidth/Math.max(1,i.clientHeight)),l=!1,d=!1,f=!0,g=0,p=0,x=-1/0,v=0,M=null,w=!1;const y=matchMedia("(prefers-reduced-motion: reduce)"),S=()=>{l||!d||document.hidden||g||(g=requestAnimationFrame(b))},E=function(t,i,a){const o=i.style.visibility;let r=document.createElement("canvas"),l=null,m=null,d=null,f=null;const g=[],p=[];let x=!1,v=!1,M=4096;const w=document.createElement("canvas"),y=document.createElement("canvas"),S=w.getContext("2d"),E=y.getContext("2d");let b=!1;const T=new n,A=u();let k=null,R={};const z=()=>{r.className="ascii-hover-surface",r.style.cssText="position:absolute;inset:0;width:100%;height:100%;pointer-events:none",r.setAttribute("role","img"),r.setAttribute("aria-label","ASCII artwork preview"),r.dataset.renderer=l?"surface-gpu":"surface-canvas",t.prepend(r),i.style.visibility="hidden"},_=()=>{l&&(g.forEach(t=>l.deleteTexture(t)),p.forEach(t=>l.deleteShader(t)),d&&l.deleteProgram(d),f&&l.deleteBuffer(f))},D=()=>{x||m||(r.removeEventListener("webglcontextlost",D),_(),r.remove(),l=null,r=document.createElement("canvas"),m=r.getContext("2d"),z(),a())};try{if(l=r.getContext("webgl",{alpha:!0,antialias:!1,depth:!1,stencil:!1,premultipliedAlpha:!0,preserveDrawingBuffer:!0}),!l)throw new Error("WebGL unavailable");M=l.getParameter(l.MAX_TEXTURE_SIZE);const t=(t,e)=>{const i=l.createShader(t);if(p.push(i),l.shaderSource(i,e),l.compileShader(i),!l.getShaderParameter(i,l.COMPILE_STATUS))throw new Error(l.getShaderInfoLog(i)||"Shader compilation failed");return i};if(d=l.createProgram(),l.attachShader(d,t(l.VERTEX_SHADER,"attribute vec2 position; void main(){gl_Position=vec4(position,0.,1.);}")),l.attachShader(d,t(l.FRAGMENT_SHADER,"\n precision highp float;\n uniform sampler2D artwork; uniform sampler2D surface;\n uniform vec2 resolution; uniform vec2 sceneSize; uniform vec2 cellSize;\n uniform vec2 surfaceSize; uniform float strength;\n \nuniform float hoverMode;\nuniform vec4 hoverFocus;\nfloat surfaceLight(vec2 uv, vec2 size) {\n vec2 delta = (uv - hoverFocus.xy) * size / min(size.x, size.y) / hoverFocus.w;\n float light = exp(-3.0 * dot(delta, delta));\n if (hoverMode > 1.5) light = (exp(-delta.x * delta.x * 110.0) * 1.3 - exp(-delta.x * delta.x * 12.0) * .3) * exp(-delta.y * delta.y * 1.8);\n return hoverMode > .5 ? light * hoverFocus.z : 0.0;\n}\nvec3 illuminate(vec3 ink, float light) {\n return mix(ink, vec3(1.0), max(0.0, light) * .82) * (1.0 + min(0.0, light));\n}\n\n uniform sampler2D codes; uniform sampler2D cellColors; uniform sampler2D glyphAtlas;\n uniform vec2 gridSize; uniform vec2 atlasSize; uniform vec2 tileSize;\n uniform float atlasColumns; uniform float padding; uniform float glyphCount;\n uniform float dots; uniform float dotSize;\n \nuniform float trailAmount;\nuniform float trailKind;\nfloat trailDensity(vec2 address) {\n vec2 encodedInk = texture2D(surface, (address * (surfaceSize - 1.0) + .5) / surfaceSize).rg;\n return (encodedInk.r * 65280.0 + encodedInk.g * 255.0) / 65535.0 * trailAmount;\n}\nvec3 trailInk(vec3 ink, float density) {\n float peak=max(ink.r,max(ink.g,ink.b));\n float raised=trailKind>1.5?peak:max(peak,min(.44,density*.75));\n return peak>.001 ? ink*(raised/peak) : vec3(raised);\n}\nfloat trailIndex(float index, float count, float density, vec2 cell) {\n // A stable cell pattern gives Dissolve a granular edge without random flicker.\n float grain=fract((cell.x*cell.x*17.0+cell.y*cell.y*23.0+cell.x*cell.y*19.0)*.0137);\n if(trailKind>1.5) return max(0.0,index-floor(density*count*(1.35+grain*.9)));\n return min(count - 1.0, index + floor(density * count * .85));\n}\n\n \n uniform float motionMode; uniform float motionTime; uniform float fineDither; uniform float ditherAmount;\n float printGrain(vec2 p) { return fract(52.9829189*fract(dot(p,vec2(.06711056,.00583715)))); }\n vec4 ambientAt(vec2 uv) {\n float p=motionTime*.5235987756;\n float edge=smoothstep(0.,.12,min(min(uv.x,1.-uv.x),min(uv.y,1.-uv.y)));\n if(motionMode<.5) return vec4(0.,0.,0.,1.);\n if(motionMode<1.5) return vec4(0.,0.,sin(uv.x*9.+uv.y*5.+p)*cos(uv.y*8.-uv.x*3.-p)*.065*edge,.9+.1*sin(uv.x*6.-uv.y*4.+p));\n if(motionMode<2.5) return vec4(sin(uv.y*9.+p)*cos(uv.x*7.-p)*6.*edge,cos(uv.x*8.+p)*sin(uv.y*6.-p)*4.*edge,0.,1.);\n float cycle=mod(motionTime,12.);\n float order=uv.x*.8+uv.y*.2+sin(uv.x*8.-uv.y*5.)*.08;\n float gone=smoothstep(1.8+order*1.2,3.8+order*1.2,cycle)*(1.-smoothstep(5.+order*1.7,7.2+order*1.7,cycle));\n return vec4(0.,0.,-gone*.95,1.-gone*.82);\n }\n\n float toneAt(vec2 uv) {\n vec2 p=uv*gridSize-.5, b=floor(p), f=fract(p);\n return mix(mix(texture2D(codes,(b+.5)/gridSize).b,texture2D(codes,(b+vec2(1.5,.5))/gridSize).b,f.x),mix(texture2D(codes,(b+vec2(.5,1.5))/gridSize).b,texture2D(codes,(b+1.5)/gridSize).b,f.x),f.y);\n }\n void main(){\n vec2 uv = vec2(gl_FragCoord.x, resolution.y - gl_FragCoord.y) / resolution;\n vec2 pixel = uv * sceneSize;\n if (strength > 0.) {\n vec4 normal = texture2D(surface, (uv * (surfaceSize - 1.) + .5) / surfaceSize) * 255.;\n vec2 slope = (vec2(normal.r * 256. + normal.g, normal.b * 256. + normal.a) - 32768.) / 32767.;\n vec2 edge = min(pixel, sceneSize - pixel) / cellSize;\n uv -= slope * strength * smoothstep(2.,8.,min(edge.x,edge.y)) / sceneSize;\n }\n vec4 ambient=ambientAt(uv);\n uv -= ambient.xy/sceneSize;\n pixel=uv*sceneSize;\n vec4 ink = texture2D(artwork, uv);\n if (fineDither > .5) {\n vec2 cell=floor(pixel/cellSize),address=(cell+.5)/gridSize;\n vec4 color=texture2D(cellColors,address);\n float density=trailAmount>0.?trailDensity(address):0.;\n float tone=clamp(toneAt(uv)+ambient.z+(trailKind>1.5?-density:density)*.65,0.,1.);\n float pitch=max(1.,min(cellSize.x,cellSize.y)*.32);\n float grain=.5+(printGrain(floor(pixel/pitch))-.5)*ditherAmount;\n float alpha=(tone<.001?0.:tone>.999?1.:smoothstep(grain-.035,grain+.035,tone))*color.a*ambient.w;\n // Preserve hue; tone is carried by mark coverage rather than muddy ink.\n vec3 hue=color.rgb/max(.001,max(color.r,max(color.g,color.b)));\n gl_FragColor=vec4(hue*alpha,alpha); return;\n }\n if (trailAmount > 0. || motionMode > .5) {\n vec2 cell=floor(pixel/cellSize), address=(cell+.5)/gridSize;\n float density=trailAmount>0.?trailDensity(address):0.;\n vec4 encoded=texture2D(codes,address);\n float original=floor(encoded.r*255.+.5)+floor(encoded.g*255.+.5)*256.;\n float index=trailIndex(original,glyphCount,density,cell);\n if(original>.5) index=clamp(floor(index+ambient.z*(glyphCount-1.)+printGrain(cell)),0.,glyphCount-1.);\n vec4 color=texture2D(cellColors,address);\n if((index!=original || motionMode>.5) && color.a>.01) {\n vec2 local=(pixel-cell*cellSize)*resolution/sceneSize;\n vec2 slot=vec2(mod(index,atlasColumns),floor(index/atlasColumns));\n float alpha=texture2D(glyphAtlas,(slot*tileSize+padding+local)/atlasSize).a;\n if(dots>.5) {\n vec2 d=(pixel-(cell+.5)*cellSize)/min(cellSize.x,cellSize.y);\n float r=min(.48,(index/(glyphCount-1.))*.5*dotSize);\n alpha=1.-smoothstep(r-.06,r+.02,length(d));\n }\n // Replace the cell, rather than blending two glyphs into a ghost.\n vec3 rgb=trailInk(color.rgb,density);\n ink=vec4(rgb*alpha*color.a,alpha*color.a);\n }\n }\n vec3 straightInk = ink.a > .0 ? ink.rgb / ink.a : vec3(.0);\n float value = max(straightInk.r, max(straightInk.g, straightInk.b));\n // Lighting belongs to character ink; black/transparent gaps stay empty.\n float light = surfaceLight((floor(pixel / cellSize) + .5) * cellSize / sceneSize, sceneSize);\n vec3 lit = illuminate(straightInk, light * smoothstep(0., .22, value)) * ink.a;\n gl_FragColor = vec4(lit, ink.a)*ambient.w;\n }")),l.linkProgram(d),!l.getProgramParameter(d,l.LINK_STATUS))throw new Error("Surface shader link failed");l.useProgram(d),f=l.createBuffer(),l.bindBuffer(l.ARRAY_BUFFER,f),l.bufferData(l.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),l.STATIC_DRAW);const e=l.getAttribLocation(d,"position");l.enableVertexAttribArray(e),l.vertexAttribPointer(e,2,l.FLOAT,!1,0,0),R=Object.fromEntries(["artwork","surface","resolution","sceneSize","cellSize","surfaceSize","strength","hoverMode","hoverFocus","codes","cellColors","glyphAtlas","gridSize","atlasSize","tileSize","atlasColumns","padding","glyphCount","dots","dotSize","trailKind","trailAmount","motionMode","motionTime","fineDither","ditherAmount"].map(t=>[t,l.getUniformLocation(d,t)]));for(let t=0;t<5;t++){const e=l.createTexture();g.push(e),l.activeTexture(l.TEXTURE0+t),l.bindTexture(l.TEXTURE_2D,e),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,l.LINEAR),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,l.LINEAR),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,1,1,0,l.RGBA,l.UNSIGNED_BYTE,new Uint8Array(4)),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE)}l.uniform1i(R.codes,2),l.uniform1i(R.cellColors,3),l.uniform1i(R.glyphAtlas,4),l.uniform1i(R.artwork,0),l.uniform1i(R.surface,1),l.pixelStorei(l.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),l.disable(l.BLEND),l.disable(l.DEPTH_TEST),r.addEventListener("webglcontextlost",D),z()}catch{D()}return{get canvas(){return r},render(t,n,a,o,d,u,f,p,z=0){const _=e(p?.animationStyle),C=T.update(z,_,p?.animationSpeed),F=(t=>"terminal"===t?.artStyle&&!t.customText&&!t.charsetFrames?.length&&!/[A-Za-z]/.test(t.charset??""))(p);if(x||!a||!o||!i.width||!i.height)return;const I=Math.min(i.width/a,1.5,Math.sqrt(4e6/(a*o))),P=Math.max(1,Math.round(a*I)),U=Math.max(1,Math.round(o*I));if(r.width===P&&r.height===U||(r.width=P,r.height=U,v=!1),l&&(i.width>M||i.height>M)&&D(),(c(n.mode)||"none"!==_||F)&&(t||!v||!k)&&(k=A.update(i,a,o,d,u,I,f,p),l)){const{plan:t,packed:e,atlas:i}=k;for(const[t,i]of[[2,e.indices],[3,e.colors]])l.activeTexture(l.TEXTURE0+t),l.bindTexture(l.TEXTURE_2D,g[t]),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,l.NEAREST),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,l.NEAREST),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,e.cols,e.rows,0,l.RGBA,l.UNSIGNED_BYTE,i);l.activeTexture(l.TEXTURE4),l.bindTexture(l.TEXTURE_2D,g[4]),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,l.RGBA,l.UNSIGNED_BYTE,i),l.uniform2f(R.gridSize,e.cols,e.rows),l.uniform2f(R.atlasSize,t.atlasWidth,t.atlasHeight),l.uniform2f(R.tileSize,t.tileWidth,t.tileHeight),l.uniform1f(R.atlasColumns,t.atlasColumns),l.uniform1f(R.padding,t.padding),l.uniform1f(R.glyphCount,t.glyphs.length),l.uniform1f(R.dots,k.dots?1:0),l.uniform1f(R.dotSize,k.dotSize)}if(l)l.uniform1f(R.motionMode,(t=>["none","print","current","reform"].indexOf(t))(_)),l.uniform1f(R.motionTime,C),l.uniform1f(R.fineDither,F?1:0),l.uniform1f(R.ditherAmount,Math.max(0,Math.min(2,p?.ditherStrength??1))),l.uniform1f(R.trailKind,"dissolve"===n.mode?2:0),l.uniform1f(R.trailAmount,c(n.mode)?n.focus[2]:0),l.viewport(0,0,P,U),!t&&v||(l.activeTexture(l.TEXTURE0),l.bindTexture(l.TEXTURE_2D,g[0]),l.pixelStorei(l.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,l.RGBA,l.UNSIGNED_BYTE,i),l.pixelStorei(l.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),v=!0),l.activeTexture(l.TEXTURE1),l.bindTexture(l.TEXTURE_2D,g[1]),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,n.width,n.height,0,l.RGBA,l.UNSIGNED_BYTE,n.pixels),l.uniform2f(R.resolution,P,U),l.uniform2f(R.sceneSize,a,o),l.uniform2f(R.cellSize,d,u),l.uniform2f(R.surfaceSize,n.width,n.height),l.uniform1f(R.strength,n.strength),l.uniform1f(R.hoverMode,"light"===n.mode?1:"scan"===n.mode?2:0),l.uniform4fv(R.hoverFocus,n.focus),l.drawArrays(l.TRIANGLE_STRIP,0,4);else if(m)if(m.setTransform(I,0,0,I,0,0),m.clearRect(0,0,a,o),m.drawImage(i,0,0,a,o),("none"!==_||F)&&k){m.clearRect(0,0,a,o);const{plan:t,packed:e,atlas:i}=k,r=[0,0,0,1],l=Math.max(1,.32*Math.min(d,u));for(let a=0;a<e.rows;a++)for(let o=0;o<e.cols;o++){const f=(o+.5)/e.cols,g=(a+.5)/e.rows,x=4*(a*e.cols+o);if(e.colors[x+3]<10)continue;h(_,f,g,C,r);const v=4*(Math.min(n.height-1,Math.round(g*(n.height-1)))*n.width+Math.min(n.width-1,Math.round(f*(n.width-1)))),M=c(n.mode)?(256*n.pixels[v]+n.pixels[v+1])/65535*n.focus[2]:0,w=e.indices[x]+256*e.indices[x+1];let y="dissolve"===n.mode?w-Math.floor(M*t.glyphs.length*1.8):w+Math.floor(M*t.glyphs.length*.85);w>0&&(y+=r[2]*(t.glyphs.length-1)),y=Math.max(0,Math.min(t.glyphs.length-1,Math.floor(y+s(o,a))));let S=r[0],E=r[1];n.strength>0&&(S+=(256*n.pixels[v]+n.pixels[v+1]-32768)/32767*n.strength,E+=(256*n.pixels[v+2]+n.pixels[v+3]-32768)/32767*n.strength);const b=o*d+S,T=a*u+E,A=e.colors[x+3]/255*r[3],R=F?Math.max(1,e.colors[x],e.colors[x+1],e.colors[x+2]):255,z=`rgb(${e.colors[x]/R*255},${e.colors[x+1]/R*255},${e.colors[x+2]/R*255})`;if(m.fillStyle=z,F){const t=Math.max(0,Math.min(1,e.indices[x+2]/255+r[2]+.65*("dissolve"===n.mode?-M:M)));m.globalAlpha=A;for(let e=0;e<u;e+=l)for(let i=0;i<d;i+=l)t>.5+(s(Math.floor((b+i)/l),Math.floor((T+e)/l))-.5)*Math.max(0,Math.min(2,p?.ditherStrength??1))&&m.fillRect(b+i,T+e,Math.min(l,d-i),Math.min(l,u-e))}else if(y>0)if(m.globalAlpha=A,k.dots){const e=Math.min(.48,y/(t.glyphs.length-1)*.5*k.dotSize)*Math.min(d,u);m.beginPath(),m.arc(b+.5*d,T+.5*u,e,0,2*Math.PI),m.fill()}else m.drawImage(i,y%t.atlasColumns*t.tileWidth+t.padding,Math.floor(y/t.atlasColumns)*t.tileHeight+t.padding,t.cellWidth*I,t.cellHeight*I,b,T,d,u),m.globalAlpha=1,m.globalCompositeOperation="source-atop",m.fillRect(b,T,d,u),m.globalCompositeOperation="source-over"}m.globalAlpha=1}else if(c(n.mode)&&k){const{plan:t,packed:e,atlas:i}=k;for(let s=0;s<e.rows;s++)for(let h=0;h<e.cols;h++){const a=4*(Math.min(n.height-1,Math.round((s+.5)/e.rows*(n.height-1)))*n.width+Math.min(n.width-1,Math.round((h+.5)/e.cols*(n.width-1)))),o=(256*n.pixels[a]+n.pixels[a+1])/65535*n.focus[2],r=4*(s*e.cols+h),l=.0137*(h*h*17+s*s*23+h*s*19),c=l-Math.floor(l),f=e.indices[r]+256*e.indices[r+1],g="dissolve"===n.mode?Math.max(0,f-Math.floor(o*t.glyphs.length*(1.35+.9*c))):Math.min(t.glyphs.length-1,f+Math.floor(o*t.glyphs.length*.85));if(g===f||e.colors[r+3]<10)continue;const p=h*d,x=s*u;if(m.clearRect(p,x,d,u),m.globalAlpha=e.colors[r+3]/255,k.dots){const e=Math.min(.48,g/(t.glyphs.length-1)*.5*k.dotSize)*Math.min(d,u);m.fillStyle="#fff",m.beginPath(),m.arc(p+.5*d,x+.5*u,e,0,2*Math.PI),m.fill()}else m.drawImage(i,g%t.atlasColumns*t.tileWidth+t.padding,Math.floor(g/t.atlasColumns)*t.tileHeight+t.padding,t.cellWidth*I,t.cellHeight*I,p,x,d,u);m.globalAlpha=1,m.globalCompositeOperation="source-atop";const v=Math.max(e.colors[r],e.colors[r+1],e.colors[r+2]),M="dissolve"===n.mode?v:Math.max(v,Math.min(112,191*o)),w=v?M/v:0;m.fillStyle=`rgb(${v?e.colors[r]*w:M},${v?e.colors[r+1]*w:M},${v?e.colors[r+2]*w:M})`,m.fillRect(p,x,d,u),m.globalCompositeOperation="source-over"}}else if("light"===n.mode||"scan"===n.mode){!t&&b&&w.width===P&&w.height===U||(w.width=P,w.height=U,y.width=P,y.height=U,S.filter="brightness(3)",S.drawImage(i,0,0,P,U),S.filter="none",b=!0);const[e,s,h,r]=n.focus;if(h>.001){E.setTransform(1,0,0,1,0,0),E.clearRect(0,0,P,U),E.drawImage(w,0,0),E.globalCompositeOperation="destination-in",E.save(),E.translate(e*P,s*U),E.scale("scan"===n.mode?.13:1,1);const t=r*Math.min(P,U),i=E.createRadialGradient(0,0,0,0,0,t);i.addColorStop(0,`rgba(255,255,255,${h})`),i.addColorStop(.5,`rgba(255,255,255,${.4*h})`),i.addColorStop(1,"rgba(255,255,255,0)"),E.fillStyle=i,E.fillRect(10*-P,10*-U,20*P,20*U),E.restore(),E.globalCompositeOperation="source-over",m.globalCompositeOperation="source-atop",m.drawImage(y,0,0,a,o),m.globalCompositeOperation="source-over"}}else if(n.strength>0){const t=32,e=18,s=a/t,h=o/e;for(let r=0;r<e;r++)for(let l=0;l<t;l++){const c=(l+.5)/t,f=(r+.5)/e,g=Math.min(n.width-1,Math.round(c*(n.width-1))),p=4*(Math.min(n.height-1,Math.round(f*(n.height-1)))*n.width+g),x=n.pixels,v=Math.min(l*s/d,(a-(l+1)*s)/d,r*h/u,(o-(r+1)*h)/u),M=Math.max(0,Math.min(1,(v-2)/6)),w=M*M*(3-2*M),y=(256*x[p]+x[p+1]-32768)/32767*n.strength*w,S=(256*x[p+2]+x[p+3]-32768)/32767*n.strength*w;Math.abs(y)+Math.abs(S)<.02||(m.clearRect(l*s,r*h,s,h),m.drawImage(i,Math.max(0,Math.min(a-s,l*s-y))*i.width/a,Math.max(0,Math.min(o-h,r*h-S))*i.height/o,s*i.width/a,h*i.height/o,l*s,r*h,s,h))}}},destroy(){x=!0,A.destroy(),r.removeEventListener("webglcontextlost",D),_(),r.remove(),w.width=w.height=y.width=y.height=1,i.style.visibility=o,l?.getExtension("WEBGL_lose_context")?.loseContext()}}}(t,i,()=>queueMicrotask(()=>{f=!0,S()}));function b(t){if(g=0,l||!d||document.hidden)return;const s=i.clientWidth,n=i.clientHeight;if(!s||!n)return;const h=y.matches||o.paused;r.configure(o.effect,o.strength,o.radius);const a=r.active;if(!h){if(v+=p?Math.min(.1,(t-p)/1e3):0,w){const t=i.getBoundingClientRect();M&&t.width&&t.height?r.move((M.x-t.left)/t.width,(M.y-t.top)/t.height):r.leave(),w=!1}r.step(p?(t-p)/1e3:1/60)}const c=f||o.animated&&!h&&t-x>=1e3/Math.max(1,Math.min(60,o.fps))-.5;(c||a||r.active||!h&&"none"!==e(o.motion))&&(E.render(c,r.refraction,s,n,o.fontSize*o.charSpacing,o.fontSize/o.charAspect*o.charSpacing,c?o.getFrame?.():void 0,{charset:o.charset,customText:o.customText,renderMode:o.renderMode,dotSizeRatio:o.dotSizeRatio,colorMode:"fullcolor",animationStyle:o.motion,animationSpeed:o.motionSpeed??1,artStyle:o.fineDither?"terminal":"classic",ditherStrength:o.ditherStrength??1},v),c&&(x=t),f=!1),p=t,h||!o.animated&&!r.active&&"none"===e(o.motion)||S()}const T=()=>{r.clear(),M=null,w=!1,p=0,f=!0,cancelAnimationFrame(g),g=0,S()},A=t=>{if("touch"===t.pointerType||o.paused||y.matches)return;if(t.target instanceof Element&&t.target.closest("button,a,input,summary,select"))return void k();const e=i.getBoundingClientRect();t.clientX<e.left||t.clientX>e.right||t.clientY<e.top||t.clientY>e.bottom?k():(M={x:t.clientX,y:t.clientY},w=!0,S())},k=()=>{M=null,w=!0,S()},R=new IntersectionObserver(([t])=>{d=t.isIntersecting,T()});R.observe(t);const z=new ResizeObserver(()=>{r=new m(i.clientWidth/Math.max(1,i.clientHeight)),T()});return z.observe(i),t.addEventListener("pointermove",A),t.addEventListener("pointerleave",k),t.addEventListener("pointercancel",k),document.addEventListener("visibilitychange",T),y.addEventListener("change",T),{get canvas(){return E.canvas},invalidate(){f=!0,S()},update(t){o={...o,...t},T()},destroy(){l||(l=!0,cancelAnimationFrame(g),R.disconnect(),z.disconnect(),E.destroy(),t.removeEventListener("pointermove",A),t.removeEventListener("pointerleave",k),t.removeEventListener("pointercancel",k),document.removeEventListener("visibilitychange",T),y.removeEventListener("change",T))}}}exports.mountHover=f,exports.mountStudioHover=f;//# sourceMappingURL=hover.cjs.map
|
package/dist/hover.d.cts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { d as AsciiFrame } from './types-w2CRgyk6.cjs';
|
|
2
|
+
|
|
3
|
+
type AmbientMotion = 'none' | 'print' | 'current' | 'reform';
|
|
4
|
+
|
|
5
|
+
type HeroHover = 'none' | 'trail' | 'water' | 'contour' | 'dissolve' | 'silk' | 'vortex' | 'light' | 'scan';
|
|
6
|
+
|
|
7
|
+
type StudioHoverEffect = Exclude<HeroHover, 'light' | 'scan'>;
|
|
8
|
+
interface StudioHoverOptions {
|
|
9
|
+
effect?: StudioHoverEffect;
|
|
10
|
+
/** Supply the current object frame when available for exact glyph identities/colors. */
|
|
11
|
+
getFrame?: () => AsciiFrame | undefined;
|
|
12
|
+
motion?: AmbientMotion;
|
|
13
|
+
motionSpeed?: number;
|
|
14
|
+
fineDither?: boolean;
|
|
15
|
+
ditherStrength?: number;
|
|
16
|
+
strength?: number;
|
|
17
|
+
radius?: number;
|
|
18
|
+
/** Enable when the backing canvas is drawn by a video/animation renderer. */
|
|
19
|
+
animated?: boolean;
|
|
20
|
+
fps?: number;
|
|
21
|
+
fontSize?: number;
|
|
22
|
+
charAspect?: number;
|
|
23
|
+
/** Match the backing engine character spacing. Default: 1. */
|
|
24
|
+
charSpacing?: number;
|
|
25
|
+
paused?: boolean;
|
|
26
|
+
charset?: string;
|
|
27
|
+
customText?: string;
|
|
28
|
+
renderMode?: 'ascii' | 'dots';
|
|
29
|
+
dotSizeRatio?: number;
|
|
30
|
+
}
|
|
31
|
+
/** Optional studio surface layer. Keep engine hoverStrength: 0 to avoid two effects.
|
|
32
|
+
* Host must be a positioned wrapper fitted to the source canvas, e.g. width:fit-content.
|
|
33
|
+
* Call invalidate() after drawing a new still; destroy() before removing the host.
|
|
34
|
+
*/
|
|
35
|
+
declare function mountStudioHover(host: HTMLElement, source: HTMLCanvasElement, initial?: StudioHoverOptions): {
|
|
36
|
+
/** Visible canvas; use this for CSS layering or snapshots. */
|
|
37
|
+
readonly canvas: HTMLCanvasElement;
|
|
38
|
+
invalidate(): void;
|
|
39
|
+
update(next: StudioHoverOptions): void;
|
|
40
|
+
destroy(): void;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
type HoverController = ReturnType<typeof mountStudioHover>;
|
|
44
|
+
|
|
45
|
+
export { type AmbientMotion, type HoverController, type StudioHoverOptions as HoverOptions, type StudioHoverEffect, type StudioHoverOptions, mountStudioHover as mountHover, mountStudioHover };
|
package/dist/hover.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { d as AsciiFrame } from './types-w2CRgyk6.js';
|
|
2
|
+
|
|
3
|
+
type AmbientMotion = 'none' | 'print' | 'current' | 'reform';
|
|
4
|
+
|
|
5
|
+
type HeroHover = 'none' | 'trail' | 'water' | 'contour' | 'dissolve' | 'silk' | 'vortex' | 'light' | 'scan';
|
|
6
|
+
|
|
7
|
+
type StudioHoverEffect = Exclude<HeroHover, 'light' | 'scan'>;
|
|
8
|
+
interface StudioHoverOptions {
|
|
9
|
+
effect?: StudioHoverEffect;
|
|
10
|
+
/** Supply the current object frame when available for exact glyph identities/colors. */
|
|
11
|
+
getFrame?: () => AsciiFrame | undefined;
|
|
12
|
+
motion?: AmbientMotion;
|
|
13
|
+
motionSpeed?: number;
|
|
14
|
+
fineDither?: boolean;
|
|
15
|
+
ditherStrength?: number;
|
|
16
|
+
strength?: number;
|
|
17
|
+
radius?: number;
|
|
18
|
+
/** Enable when the backing canvas is drawn by a video/animation renderer. */
|
|
19
|
+
animated?: boolean;
|
|
20
|
+
fps?: number;
|
|
21
|
+
fontSize?: number;
|
|
22
|
+
charAspect?: number;
|
|
23
|
+
/** Match the backing engine character spacing. Default: 1. */
|
|
24
|
+
charSpacing?: number;
|
|
25
|
+
paused?: boolean;
|
|
26
|
+
charset?: string;
|
|
27
|
+
customText?: string;
|
|
28
|
+
renderMode?: 'ascii' | 'dots';
|
|
29
|
+
dotSizeRatio?: number;
|
|
30
|
+
}
|
|
31
|
+
/** Optional studio surface layer. Keep engine hoverStrength: 0 to avoid two effects.
|
|
32
|
+
* Host must be a positioned wrapper fitted to the source canvas, e.g. width:fit-content.
|
|
33
|
+
* Call invalidate() after drawing a new still; destroy() before removing the host.
|
|
34
|
+
*/
|
|
35
|
+
declare function mountStudioHover(host: HTMLElement, source: HTMLCanvasElement, initial?: StudioHoverOptions): {
|
|
36
|
+
/** Visible canvas; use this for CSS layering or snapshots. */
|
|
37
|
+
readonly canvas: HTMLCanvasElement;
|
|
38
|
+
invalidate(): void;
|
|
39
|
+
update(next: StudioHoverOptions): void;
|
|
40
|
+
destroy(): void;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
type HoverController = ReturnType<typeof mountStudioHover>;
|
|
44
|
+
|
|
45
|
+
export { type AmbientMotion, type HoverController, type StudioHoverOptions as HoverOptions, type StudioHoverEffect, type StudioHoverOptions, mountStudioHover as mountHover, mountStudioHover };
|
package/dist/hover.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var t=[{value:"none",mode:"none",label:"Off",description:"Keep the image still. Hover stays available."},{value:"breathe",mode:"print",label:"Living Print",description:"Soft tonal movement. The character grid stays still."},{value:"wave",mode:"current",label:"Slow Current",description:"A gentle flow through the image, with steady edges."},{value:"rain",mode:"reform",label:"Reveal & Reform",description:"Disperse, gather, then hold the complete image."}];function e(e){return"orbit"===e?"current":t.find(t=>t.value===e||t.mode===e)?.mode??"none"}var i=(t,e,i)=>{const s=(t=>Math.max(0,Math.min(1,t)))((i-t)/(e-t));return s*s*(3-2*s)},s=(t,e)=>{const i=(.06711056*t+.00583715*e)%1*52.9829189;return i-Math.floor(i)},n=class{constructor(){this.last=null,this.mode="none",this.phase=0}update(t,e,i=1){return Number.isFinite(t)?((e!==this.mode||null!==this.last&&t<this.last)&&(this.mode=e,this.phase=0,this.last=t),null!==this.last&&(this.phase+=Math.max(0,t-this.last)*Math.max(.1,Math.min(3,Number.isFinite(i)?i:1))),this.last=t,this.phase):this.phase}};function h(t,e,s,n,h){const a=n*Math.PI/6,o=i(0,.12,Math.min(e,1-e,s,1-s));if(h[0]=h[1]=h[2]=0,h[3]=1,"print"===t)h[2]=Math.sin(9*e+5*s+a)*Math.cos(8*s-3*e-a)*.065*o,h[3]=.9+.1*Math.sin(6*e-4*s+a);else if("current"===t)h[0]=Math.sin(9*s+a)*Math.cos(7*e-a)*6*o,h[1]=Math.cos(8*e+a)*Math.sin(6*s-a)*4*o;else if("reform"===t){const t=(n%12+12)%12,a=.8*e+.2*s+.08*Math.sin(8*e-5*s),o=i(1.8+1.2*a,3.8+1.2*a,t)*(1-i(5+1.7*a,7.2+1.7*a,t));h[2]=.95*-o,h[3]=1-.82*o}return h}function a(t,e,i){const s=Math.min(t*Math.max(1,i),(1-t)*Math.max(1,i),e*Math.max(1,1/i),(1-e)*Math.max(1,1/i)),n=Math.max(0,Math.min(1,(s-.035)/.105));return n*n*n*(n*(6*n-15)+10)}var o=class{constructor(t,e){this.previous=null,this.peak=0,this.mode="dissolve",this.width=t,this.height=e;const i=t*e;this.pixels=new Uint8Array(4*i),this.ink=new Float32Array(i),this.targetX=new Float32Array(i),this.targetY=new Float32Array(i),this.offsetX=new Float32Array(i),this.offsetY=new Float32Array(i),this.edge=new Float32Array(i);for(let i=0;i<e;i++)for(let s=0;s<t;s++)this.edge[i*t+s]=a(s/(t-1),i/(e-1),t/e);this.clear()}get active(){return this.peak>2e-4}setMode(t){t!==this.mode&&(this.mode=t,this.clear())}clear(){for(const t of[this.ink,this.targetX,this.targetY,this.offsetX,this.offsetY,this.pixels])t.fill(0);if(this.previous=null,this.peak=0,"dissolve"!==this.mode)for(let t=0;t<this.pixels.length;t+=4)this.pixels[t]=this.pixels[t+2]=128}leave(){this.previous=null}move(t,e,i){if(!Number.isFinite(t+e+i))return;t=Math.max(0,Math.min(1,t)),e=Math.max(0,Math.min(1,e));const s=this.previous;this.previous={x:t,y:e};const n=this.width,h=this.height,a=Math.max(1,n/h),o=Math.max(1,h/n),r=s?(t-s.x)*a:0,l=s?(e-s.y)*o:0,c=Math.hypot(r,l);if(!s&&"dissolve"!==this.mode)return;if(s&&c<1e-4)return;const m=.035+.11*Math.max(.1,Math.min(1,i)),d=Math.min(128,Math.max(1,Math.ceil(c/(.45*m)))),u=c?r/c:1,f=c?l/c:0,g=Math.min(1,c/(m*d)*2.2);for(let i=0;i<d;i++){const r=(i+.5)/d,l=s?s.x+(t-s.x)*r:t,c=s?s.y+(e-s.y)*r:e,p=Math.max(0,Math.floor((l-2.5*m/a)*(n-1))),x=Math.min(n-1,Math.ceil((l+2.5*m/a)*(n-1))),v=Math.max(0,Math.floor((c-2.5*m/o)*(h-1))),M=Math.min(h-1,Math.ceil((c+2.5*m/o)*(h-1)));for(let t=v;t<=M;t++)for(let e=p;e<=x;e++){const i=(e/(n-1)-l)*a/m,s=(t/(h-1)-c)*o/m,r=Math.exp(1.5*-(i*i+s*s)),d=t*n+e;if("dissolve"===this.mode)this.ink[d]=Math.max(this.ink[d],r);else{const t=(-i*f+s*u)*r*2.8,e="silk"===this.mode?u*t:-s*r*2.5,n="silk"===this.mode?f*t:i*r*2.5;this.targetX[d]=Math.max(-1,Math.min(1,this.targetX[d]+e*g)),this.targetY[d]=Math.max(-1,Math.min(1,this.targetY[d]+n*g))}}}this.peak=1}step(t){if(!this.active||!Number.isFinite(t))return;const e=Math.max(0,Math.min(.05,t)),i=Math.exp(-("dissolve"===this.mode?2.15:3.2)*e),s=1-Math.exp(-22*e);let n=0;for(let t=0;t<this.ink.length;t++)if("dissolve"===this.mode){this.ink[t]*=i,n=Math.max(n,this.ink[t]);const e=Math.round(65535*this.ink[t]);this.pixels[4*t]=e>>>8,this.pixels[4*t+1]=255&e}else{this.targetX[t]*=i,this.targetY[t]*=i,this.offsetX[t]+=(this.targetX[t]-this.offsetX[t])*s,this.offsetY[t]+=(this.targetY[t]-this.offsetY[t])*s,n=Math.max(n,Math.abs(this.offsetX[t]),Math.abs(this.offsetY[t]),Math.abs(this.targetX[t]),Math.abs(this.targetY[t]));const e=Math.round(this.offsetX[t]*this.edge[t]*32767+32768),h=Math.round(this.offsetY[t]*this.edge[t]*32767+32768);this.pixels[4*t]=e>>>8,this.pixels[4*t+1]=255&e,this.pixels[4*t+2]=h>>>8,this.pixels[4*t+3]=255&h}this.peak=n,this.active||this.clear()}sample(t,e,i){const s=Math.max(0,Math.min(this.width-1.001,t*(this.width-1))),n=Math.max(0,Math.min(this.height-1.001,e*(this.height-1))),h=Math.floor(s),o=Math.floor(n),r=s-h,l=n-o,c=o*this.width+h,m=c+this.width,d=t=>(t[c]*(1-r)+t[c+1]*r)*(1-l)+(t[m]*(1-r)+t[m+1]*r)*l;i[0]=d(this.offsetX)*a(t,e,this.width/this.height)*.08,i[1]=d(this.offsetY)*a(t,e,this.width/this.height)*.08,i[2]="dissolve"===this.mode?6*-d(this.ink):0}},r=class{constructor(t,e){this.rings=[],this.previous=null,this.elapsed=1,this.echoPeak=0,this.width=t,this.height=e,this.pixels=new Uint8Array(t*e*4),this.echo=new Float32Array(t*e)}get active(){return this.rings.length>0||this.echoPeak>2e-4}clear(){this.rings=[],this.previous=null,this.elapsed=1,this.pixels.fill(0),this.echo.fill(0),this.echoPeak=0}leave(){this.previous=null}move(t,e,i){const s=Math.max(1,this.width/this.height),n=Math.max(1,this.height/this.width);this.previous&&(Math.hypot((t-this.previous.x)*s,(e-this.previous.y)*n)<.065||this.elapsed<.3)||4!==this.rings.length&&(this.previous={x:t,y:e},this.elapsed=0,this.rings.push({x:t,y:e,age:0,radius:i}))}ringSample(t,e){const i=Math.max(1,this.width/this.height),s=Math.max(1,this.height/this.width);let n=0;for(const h of this.rings){const a=.015+h.age*(.15+.22*h.radius),o=.009+.014*h.radius,r=(Math.hypot((t-h.x)*i,(e-h.y)*s)-a)/o,l=Math.sin(Math.min(1,h.age/.07)*Math.PI/2)*Math.max(0,1-h.age/1.35)**2;n=Math.max(n,Math.exp(-r*r)*l)}return n}sample(t,e){const i=Math.max(0,Math.min(this.width-1,Math.round(t*(this.width-1)))),s=Math.max(0,Math.min(this.height-1,Math.round(e*(this.height-1))));return Math.max(this.ringSample(t,e),this.echo[s*this.width+i])}step(t){if(!Number.isFinite(t))return;const e=Math.max(0,Math.min(.05,t));this.elapsed+=e;for(const t of this.rings)t.age+=e;if(this.rings=this.rings.filter(t=>t.age<1.35),!this.active)return void this.pixels.fill(0);const i=Math.exp(-5.5*e);let s=0;for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++){const n=t*this.width+e;this.echo[n]=Math.max(this.ringSample(e/(this.width-1),t/(this.height-1)),this.echo[n]*i),s=Math.max(s,this.echo[n]);const h=Math.round(65535*this.echo[n]),a=4*n;this.pixels[a]=h>>>8,this.pixels[a+1]=255&h}this.echoPeak=s,this.active||(this.echo.fill(0),this.pixels.fill(0))}},l=class{constructor(t,e){this.previous=null,this.remainder=0,this.peak=0,this.width=t,this.height=e;const i=t*e;this.pixels=new Uint8Array(4*i),this.u=new Float32Array(i),this.v=new Float32Array(i),this.ink=new Float32Array(i),this.a=new Float32Array(i),this.b=new Float32Array(i),this.c=new Float32Array(i),this.pressure=new Float32Array(i),this.pressureNext=new Float32Array(i),this.divergence=new Float32Array(i),this.curl=new Float32Array(i)}get active(){return this.peak>2e-4}clear(){for(const t of[this.u,this.v,this.ink,this.a,this.b,this.c,this.pressure,this.pressureNext,this.divergence,this.curl,this.pixels])t.fill(0);this.previous=null,this.peak=0,this.remainder=0}leave(){this.previous=null}move(t,e,i){const s=this.previous;if(this.previous={x:t,y:e},!s)return;const n=(t-s.x)*(this.width-1),h=(e-s.y)*(this.height-1),a=Math.hypot(n,h);if(a<.001)return;const o=Math.min(this.width,this.height)*(.038+.12*i),r=Math.min(128,Math.max(1,Math.ceil(a/(.5*o)))),l=a/o*.95/r;for(let i=0;i<r;i++){const a=(i+.5)/r,c=(s.x+(t-s.x)*a)*(this.width-1),m=(s.y+(e-s.y)*a)*(this.height-1),d=Math.max(1,Math.floor(c-2.5*o)),u=Math.min(this.width-2,Math.ceil(c+2.5*o)),f=Math.max(1,Math.floor(m-2.5*o)),g=Math.min(this.height-2,Math.ceil(m+2.5*o));for(let t=f;t<=g;t++)for(let e=d;e<=u;e++){const i=Math.exp(-((e-c)**2+(t-m)**2)/(o*o)),s=t*this.width+e;this.ink[s]=Math.min(1,this.ink[s]+i*l),this.u[s]=Math.max(-50,Math.min(50,this.u[s]+n*i*5/r)),this.v[s]=Math.max(-50,Math.min(50,this.v[s]+h*i*5/r))}}this.peak=1}read(t,e,i){const s=0|(e=Math.max(.5,Math.min(this.width-1.5,e))),n=0|(i=Math.max(.5,Math.min(this.height-1.5,i))),h=e-s,a=i-n,o=n*this.width+s;return(t[o]*(1-h)+t[o+1]*h)*(1-a)+(t[o+this.width]*(1-h)+t[o+this.width+1]*h)*a}sample(t,e){return this.read(this.ink,t*(this.width-1),e*(this.height-1))}step(t){if(!this.active||!Number.isFinite(t))return;this.remainder+=Math.max(0,Math.min(.05,t));const e=1/60,i=this.width,s=this.height;for(;this.remainder+1e-8>=e;){this.remainder-=e;for(let t=1;t<s-1;t++)for(let s=1;s<i-1;s++){const n=t*i+s,h=s-this.u[n]*e,a=t-this.v[n]*e;this.a[n]=.972*this.read(this.u,h,a),this.b[n]=.972*this.read(this.v,h,a),this.c[n]=.964*this.read(this.ink,h,a)}[this.u,this.a]=[this.a,this.u],[this.v,this.b]=[this.b,this.v],[this.ink,this.c]=[this.c,this.ink];for(let t=1;t<s-1;t++)for(let e=1;e<i-1;e++){const s=t*i+e;this.curl[s]=.5*(this.v[s+1]-this.v[s-1]-this.u[s+i]+this.u[s-i])}for(let t=1;t<s-1;t++)for(let s=1;s<i-1;s++){const n=t*i+s,h=Math.abs(this.curl[n+1])-Math.abs(this.curl[n-1]),a=Math.abs(this.curl[n+i])-Math.abs(this.curl[n-i]),o=Math.hypot(h,a)+1e-4,r=this.curl[n]*e*5;this.u[n]+=a/o*r,this.v[n]-=h/o*r,this.divergence[n]=-.5*(this.u[n+1]-this.u[n-1]+this.v[n+i]-this.v[n-i])}this.pressure.fill(0);for(let t=0;t<4;t++){for(let t=1;t<s-1;t++)for(let e=1;e<i-1;e++){const s=t*i+e;this.pressureNext[s]=.25*(this.divergence[s]+this.pressure[s-1]+this.pressure[s+1]+this.pressure[s-i]+this.pressure[s+i])}[this.pressure,this.pressureNext]=[this.pressureNext,this.pressure]}let t=0;for(let e=1;e<s-1;e++)for(let s=1;s<i-1;s++){const n=e*i+s;this.u[n]=Math.max(-50,Math.min(50,this.u[n]-.5*(this.pressure[n+1]-this.pressure[n-1]))),this.v[n]=Math.max(-50,Math.min(50,this.v[n]-.5*(this.pressure[n+i]-this.pressure[n-i]))),t=Math.max(t,this.ink[n])}this.peak=t}if(this.active)for(let t=0;t<this.ink.length;t++){const e=Math.round(65535*Math.min(1,this.ink[t]));this.pixels[4*t]=e>>>8,this.pixels[4*t+1]=255&e}else this.clear()}},c=t=>["trail","contour","dissolve"].includes(t),m=class{constructor(t=1){this.mode="water",this.amount=.55,this.radius=.2,this.lensX=.5,this.lensY=.5,this.lensStrength=0,this.previous=null,this.energy=0,this.pending=!1,this.remainder=0,t=Math.max(.25,Math.min(4,t)),this.columns=Math.round(t>=1?128:128*t),this.rows=Math.round(t>=1?128/t:128),this.xScale=Math.max(1,t),this.yScale=Math.max(1,1/t),this.heights=new Float32Array(this.columns*this.rows),this.velocity=new Float32Array(this.heights.length),this.next=new Float32Array(this.heights.length),this.normals=new Float32Array(2*this.heights.length),this.edgeMask=new Float32Array(this.heights.length);for(let e=0;e<this.rows;e++)for(let i=0;i<this.columns;i++)this.edgeMask[e*this.columns+i]=a(i/(this.columns-1),e/(this.rows-1),t);this.refraction={width:this.columns,height:this.rows,pixels:new Uint8Array(4*this.heights.length),strength:30,mode:"water",focus:[.5,.5,0,.2]},this.waterPixels=this.refraction.pixels,this.trail=new l(this.columns,this.rows),this.contour=new r(this.columns,this.rows),this.afterimage=new o(this.columns,this.rows),this.clear()}get densityTrail(){return["trail","contour","dissolve"].includes(this.mode)}get hasRefraction(){return this.active||this.lensStrength>15e-5}get active(){return["dissolve","silk","vortex"].includes(this.mode)?this.afterimage.active:"contour"===this.mode?this.contour.active:"trail"===this.mode?this.trail.active:this.pending||this.energy>15e-5}setMode(t){t!==this.mode&&(this.clear(),this.mode=t,this.refraction.mode=t,"dissolve"!==t&&"silk"!==t&&"vortex"!==t||this.afterimage.setMode(t),this.refraction.pixels="trail"===t?this.trail.pixels:"contour"===t?this.contour.pixels:["dissolve","silk","vortex"].includes(t)?this.afterimage.pixels:this.waterPixels,this.refraction.strength="water"===t?30*this.amount/.55:"silk"===t?28*this.amount:"vortex"===t?38*this.amount:0)}configure(t,e=.55,i=.2){this.setMode(t),this.amount=Number.isFinite(e)?Math.max(0,Math.min(1,e)):.55,this.radius=Number.isFinite(i)?Math.max(.1,Math.min(1,i)):.2,this.refraction.strength="water"===t?30*this.amount/.55:"silk"===t?28*this.amount:"vortex"===t?38*this.amount:0,this.refraction.focus[2]=this.densityTrail?this.amount:this.lensStrength*this.amount,this.refraction.focus[3]=this.radius}move(t,e){if("none"===this.mode||0===this.amount)return;if(!Number.isFinite(t+e))return;if(t=Math.max(0,Math.min(1,t)),e=Math.max(0,Math.min(1,e)),["dissolve","silk","vortex"].includes(this.mode))return void this.afterimage.move(t,e,this.radius);if("contour"===this.mode)return void this.contour.move(t,e,this.radius);if("trail"===this.mode)return void this.trail.move(t,e,this.radius);if("water"!==this.mode)return!this.previous&&this.lensStrength<.001&&(this.lensX=t,this.lensY=e),this.previous={x:t,y:e},void(this.pending=!0);if(!this.previous)return void(this.previous={x:t,y:e});const i=this.previous;this.previous={x:t,y:e};const s=(t-i.x)*this.xScale,n=(e-i.y)*this.yScale,h=Math.hypot(s,n);if(h<1e-5)return;const a=.035+.1*this.radius,o=3*a,r=Math.min(192,Math.max(1,Math.ceil(h/(.5*a)))),l=95*Math.min(h,1)/r;for(let s=0;s<r;s++){const n=(s+.5)/r,h=i.x+(t-i.x)*n,c=i.y+(e-i.y)*n,m=Math.max(1,Math.floor((h-o/this.xScale)*(this.columns-1))),d=Math.min(this.columns-2,Math.ceil((h+o/this.xScale)*(this.columns-1))),u=Math.max(1,Math.floor((c-o/this.yScale)*(this.rows-1))),f=Math.min(this.rows-2,Math.ceil((c+o/this.yScale)*(this.rows-1)));for(let t=u;t<=f;t++)for(let e=m;e<=d;e++){const i=(e/(this.columns-1)-h)*this.xScale,s=(t/(this.rows-1)-c)*this.yScale,n=Math.exp(-(i*i+s*s)/(a*a))*l,o=t*this.columns+e;this.velocity[o]=Math.max(-12,this.velocity[o]-n)}}this.pending=!0}leave(){this.afterimage.leave(),this.contour.leave(),this.trail.leave(),this.previous=null,"water"!==this.mode&&this.lensStrength&&(this.pending=!0)}clear(){this.trail.clear(),this.contour.clear(),this.afterimage.clear(),this.heights.fill(0),this.velocity.fill(0),this.next.fill(0),this.normals.fill(0),this.refraction.focus[2]=0,this.previous=null,this.lensStrength=0,this.energy=0,this.pending=!1,this.remainder=0;for(let t=0;t<this.waterPixels.length;t+=4)this.waterPixels[t]=this.waterPixels[t+2]=128,this.waterPixels[t+1]=this.waterPixels[t+3]=0}step(t){if(!this.active||!Number.isFinite(t))return;if(["dissolve","silk","vortex"].includes(this.mode))return void this.afterimage.step(t);if("contour"===this.mode)return void this.contour.step(t);if("trail"===this.mode)return void this.trail.step(t);if("water"!==this.mode)return void this.stepLight(Math.max(0,Math.min(.05,t)));this.remainder+=Math.max(0,Math.min(.05,t));const e=1/120,i=Math.exp(-3.8*e),s=.3*Math.min(this.columns,this.rows);for(;this.remainder+1e-8>=e;){this.remainder-=e;let t=0;for(let n=1;n<this.rows-1;n++)for(let h=1;h<this.columns-1;h++){const a=n*this.columns+h,o=this.heights[a],r=this.heights[a-1]+this.heights[a+1]+this.heights[a-this.columns]+this.heights[a+this.columns]-4*o,l=Math.min(h,n,this.columns-1-h,this.rows-1-n),c=l<5?.88+.024*l:1,m=(this.velocity[a]+(r*s*s-8*o)*e)*i*c;this.velocity[a]=m,this.next[a]=(o+m*e)*c,t=Math.max(t,Math.abs(this.next[a]),.1*Math.abs(m))}this.heights.set(this.next),this.energy=t,this.pending=!1}if(!this.active)return void this.clear();const n=.18*Math.min(this.columns,this.rows);for(let t=0;t<this.rows;t++)for(let e=0;e<this.columns;e++){const i=t*this.columns+e,s=(this.heights[t*this.columns+Math.max(0,e-1)]-this.heights[t*this.columns+Math.min(this.columns-1,e+1)])*n,h=(this.heights[Math.max(0,t-1)*this.columns+e]-this.heights[Math.min(this.rows-1,t+1)*this.columns+e])*n,a=Math.tanh(s)*this.edgeMask[i],o=Math.tanh(h)*this.edgeMask[i];this.normals[2*i]=a,this.normals[2*i+1]=o;const r=Math.round(32767*a+32768),l=Math.round(32767*o+32768);this.refraction.pixels[4*i]=r>>>8,this.refraction.pixels[4*i+1]=255&r,this.refraction.pixels[4*i+2]=l>>>8,this.refraction.pixels[4*i+3]=255&l}}stepLight(t){const e=this.previous,i=1-Math.exp(-30*t),s=1-Math.exp(-12*t);e&&(this.lensX+=(e.x-this.lensX)*i,this.lensY+=(e.y-this.lensY)*i),this.lensStrength+=((e?1:0)-this.lensStrength)*s,this.energy=Math.max(e?Math.abs(e.x-this.lensX)+Math.abs(e.y-this.lensY):0,Math.abs((e?1:0)-this.lensStrength)),this.pending=!1,e||this.active?this.refraction.focus=[this.lensX,this.lensY,this.lensStrength*this.amount,this.radius]:this.clear()}sample(t,e,i){if(["dissolve","silk","vortex"].includes(this.mode))return this.afterimage.sample(t,e,i),i[0]*=this.amount,i[1]*=this.amount,void(i[2]*=this.amount);if("contour"===this.mode)return i[0]=i[1]=0,void(i[2]=this.contour.sample(t,e)*this.amount*3);if("trail"===this.mode)return i[0]=i[1]=0,void(i[2]=this.trail.sample(t,e)*this.amount*3);const s=Math.max(0,Math.min(this.columns-1.001,t*(this.columns-1))),n=Math.max(0,Math.min(this.rows-1.001,e*(this.rows-1))),h=Math.floor(s),a=Math.floor(n),o=s-h,r=n-a,l=2*(a*this.columns+h),c=l+2*this.columns;for(let t=0;t<2;t++)i[t]=.08*((this.normals[l+t]*(1-o)+this.normals[l+2+t]*o)*(1-r)+(this.normals[c+t]*(1-o)+this.normals[c+2+t]*o)*r);i[0]*=this.amount/.55,i[1]*=this.amount/.55,i[2]="light"===this.mode||"scan"===this.mode?function(t,e,i,s){const[n,h,a,o]=i.focus,r=(t-n)*Math.max(1,s)/o,l=(e-h)*Math.max(1,1/s)/o;return"light"===i.mode?Math.exp(-3*(r*r+l*l))*a:"scan"===i.mode?(1.3*Math.exp(-r*r*110)-.3*Math.exp(-r*r*12))*Math.exp(-l*l*1.8)*a:0}(t,e,this.refraction,this.xScale/this.yScale):0}};function d(t){const e=Intl.Segmenter;return e?Array.from(new e(void 0,{granularity:"grapheme"}).segment(t),t=>t.segment):Array.from(t)}function u(){const t=document.createElement("canvas"),e=document.createElement("canvas"),i=t.getContext("2d"),s=e.getContext("2d",{willReadFrequently:!0});let n,h=null;return{update(a,o,r,l,c,m,u,f){const g=u?.[0]?.length??Math.max(1,Math.round(o/l)),p=u?.length??Math.max(1,Math.round(r/c)),x=f??{charset:" .:-=+*#%@",customText:"",colorMode:"fullcolor"},v=x.charset+(x.charsetFrames?.join("")??""),M=function(t,e,i,s,n,h,a,o=4096,r=0){if(![i,s,n,h,a,o].every(t=>Number.isFinite(t)&&t>0))throw new Error("Glyph atlas dimensions must be positive and finite.");const l=JSON.stringify([e.charset,e.customText,i,s,n,h,a,o,r]);if(t?.key===l)return t;const c=[...new Set([" ",...d(e.charset),...d(e.customText??"")])];if(c.length>65536)throw new Error("This character set exceeds the glyph texture capacity.");const m=i/h,u=s/a,f=.9*Math.min(m/.55,u),g=Math.ceil(m*n)+4,p=Math.ceil(u*n)+4,x=Math.min(c.length,Math.floor(o/g));if(x<1||Math.ceil(c.length/x)*p>o)throw new Error("The glyph atlas exceeds the available GPU texture size.");return{key:l,glyphs:c,indices:new Map(c.map((t,e)=>[t,e])),cellWidth:m,cellHeight:u,fontSize:f,padding:2,tileWidth:g,tileHeight:p,atlasColumns:x,atlasWidth:x*g,atlasHeight:Math.ceil(c.length/x)*p}}(h,{...x,charset:v},o,r,m,g,p);if(M!==h&&(t.width=M.atlasWidth,t.height=M.atlasHeight,i.font=M.fontSize*m+'px "JetBrains Mono", monospace',i.textAlign="center",i.textBaseline="middle",i.fillStyle="#fff",M.glyphs.forEach((t,e)=>i.fillText(t,e%M.atlasColumns*M.tileWidth+M.padding+M.cellWidth*m*.5,Math.floor(e/M.atlasColumns)*M.tileHeight+M.padding+M.cellHeight*m*.5))),h=M,u){n=function(t,e,i,s,n=!1){const h=t.length,a=t[0]?.length??0,o=s?.cols===a&&s.rows===h?s:{cols:a,rows:h,indices:new Uint8Array(a*h*4),colors:new Uint8ClampedArray(a*h*4)};o.indices.fill(0),o.colors.fill(0);const r="accent"===i.colorMode?[1,3,5].map(t=>parseInt(i.accentColor.slice(t,t+2),16)):null;for(let s=0;s<h;s++){if(t[s].length!==a)throw new Error("Glyph frames must have a rectangular cell grid.");for(let h=0;h<a;h++){const l=t[s][h];if(!l.char||!n&&" "===l.char||l.a<10)continue;const c=e.get(l.char);if(void 0===c)throw new Error(`Glyph is absent from the configured character set: ${l.char}`);const m=4*(s*a+h);let d=l.r,u=l.g,f=l.b;if(r)[d,u,f]=r;else if("fullcolor"!==i.colorMode){const t=.299*d+.587*u+.114*f|0;d="matrix"===i.colorMode?0:t,u=t,f=d}(n||0!==d||0!==u||0!==f)&&(o.indices[m]=255&c,o.indices[m+1]=c>>>8,o.colors[m]=d,o.colors[m+1]=u,o.colors[m+2]=f,o.colors[m+3]=l.a)}}return o}(u,h.indices,x,n,!0);for(let t=0;t<p;t++)for(let e=0;e<g;e++){const i=u[t][e],s=4*(t*g+e);n.indices[s+2]=Math.round(.299*i.r+.587*i.g+.114*i.b)}}else{e.width=g,e.height=p,s.drawImage(a,0,0,g,p);const t=s.getImageData(0,0,g,p).data;n={cols:g,rows:p,indices:new Uint8Array(g*p*4),colors:new Uint8ClampedArray(t)};for(let e=0;e<t.length;e+=4){const i=Math.min(1,(.299*t[e]+.587*t[e+1]+.114*t[e+2])/255*(t[e+3]/255)*3);n.indices[e+2]=Math.round(255*i),n.indices[e]=Math.min(h.glyphs.length-1,Math.floor(i*h.glyphs.length))}}return{plan:h,packed:n,atlas:t,dots:"dots"===x.renderMode,dotSize:x.dotSizeRatio??.72}},destroy(){t.width=t.height=e.width=e.height=1,n=void 0,h=null}}}function f(t,i,a={}){let o={effect:"trail",strength:.55,radius:.2,animated:!1,fps:30,fontSize:7,charAspect:.58,charSpacing:1,paused:!1,charset:" .:-=+*#%@",customText:"",renderMode:"ascii",dotSizeRatio:.72,...a},r=new m(i.clientWidth/Math.max(1,i.clientHeight)),l=!1,d=!1,f=!0,g=0,p=0,x=-1/0,v=0,M=null,w=!1;const y=matchMedia("(prefers-reduced-motion: reduce)"),S=()=>{l||!d||document.hidden||g||(g=requestAnimationFrame(b))},E=function(t,i,a){const o=i.style.visibility;let r=document.createElement("canvas"),l=null,m=null,d=null,f=null;const g=[],p=[];let x=!1,v=!1,M=4096;const w=document.createElement("canvas"),y=document.createElement("canvas"),S=w.getContext("2d"),E=y.getContext("2d");let b=!1;const T=new n,A=u();let k=null,R={};const z=()=>{r.className="ascii-hover-surface",r.style.cssText="position:absolute;inset:0;width:100%;height:100%;pointer-events:none",r.setAttribute("role","img"),r.setAttribute("aria-label","ASCII artwork preview"),r.dataset.renderer=l?"surface-gpu":"surface-canvas",t.prepend(r),i.style.visibility="hidden"},_=()=>{l&&(g.forEach(t=>l.deleteTexture(t)),p.forEach(t=>l.deleteShader(t)),d&&l.deleteProgram(d),f&&l.deleteBuffer(f))},D=()=>{x||m||(r.removeEventListener("webglcontextlost",D),_(),r.remove(),l=null,r=document.createElement("canvas"),m=r.getContext("2d"),z(),a())};try{if(l=r.getContext("webgl",{alpha:!0,antialias:!1,depth:!1,stencil:!1,premultipliedAlpha:!0,preserveDrawingBuffer:!0}),!l)throw new Error("WebGL unavailable");M=l.getParameter(l.MAX_TEXTURE_SIZE);const t=(t,e)=>{const i=l.createShader(t);if(p.push(i),l.shaderSource(i,e),l.compileShader(i),!l.getShaderParameter(i,l.COMPILE_STATUS))throw new Error(l.getShaderInfoLog(i)||"Shader compilation failed");return i};if(d=l.createProgram(),l.attachShader(d,t(l.VERTEX_SHADER,"attribute vec2 position; void main(){gl_Position=vec4(position,0.,1.);}")),l.attachShader(d,t(l.FRAGMENT_SHADER,"\n precision highp float;\n uniform sampler2D artwork; uniform sampler2D surface;\n uniform vec2 resolution; uniform vec2 sceneSize; uniform vec2 cellSize;\n uniform vec2 surfaceSize; uniform float strength;\n \nuniform float hoverMode;\nuniform vec4 hoverFocus;\nfloat surfaceLight(vec2 uv, vec2 size) {\n vec2 delta = (uv - hoverFocus.xy) * size / min(size.x, size.y) / hoverFocus.w;\n float light = exp(-3.0 * dot(delta, delta));\n if (hoverMode > 1.5) light = (exp(-delta.x * delta.x * 110.0) * 1.3 - exp(-delta.x * delta.x * 12.0) * .3) * exp(-delta.y * delta.y * 1.8);\n return hoverMode > .5 ? light * hoverFocus.z : 0.0;\n}\nvec3 illuminate(vec3 ink, float light) {\n return mix(ink, vec3(1.0), max(0.0, light) * .82) * (1.0 + min(0.0, light));\n}\n\n uniform sampler2D codes; uniform sampler2D cellColors; uniform sampler2D glyphAtlas;\n uniform vec2 gridSize; uniform vec2 atlasSize; uniform vec2 tileSize;\n uniform float atlasColumns; uniform float padding; uniform float glyphCount;\n uniform float dots; uniform float dotSize;\n \nuniform float trailAmount;\nuniform float trailKind;\nfloat trailDensity(vec2 address) {\n vec2 encodedInk = texture2D(surface, (address * (surfaceSize - 1.0) + .5) / surfaceSize).rg;\n return (encodedInk.r * 65280.0 + encodedInk.g * 255.0) / 65535.0 * trailAmount;\n}\nvec3 trailInk(vec3 ink, float density) {\n float peak=max(ink.r,max(ink.g,ink.b));\n float raised=trailKind>1.5?peak:max(peak,min(.44,density*.75));\n return peak>.001 ? ink*(raised/peak) : vec3(raised);\n}\nfloat trailIndex(float index, float count, float density, vec2 cell) {\n // A stable cell pattern gives Dissolve a granular edge without random flicker.\n float grain=fract((cell.x*cell.x*17.0+cell.y*cell.y*23.0+cell.x*cell.y*19.0)*.0137);\n if(trailKind>1.5) return max(0.0,index-floor(density*count*(1.35+grain*.9)));\n return min(count - 1.0, index + floor(density * count * .85));\n}\n\n \n uniform float motionMode; uniform float motionTime; uniform float fineDither; uniform float ditherAmount;\n float printGrain(vec2 p) { return fract(52.9829189*fract(dot(p,vec2(.06711056,.00583715)))); }\n vec4 ambientAt(vec2 uv) {\n float p=motionTime*.5235987756;\n float edge=smoothstep(0.,.12,min(min(uv.x,1.-uv.x),min(uv.y,1.-uv.y)));\n if(motionMode<.5) return vec4(0.,0.,0.,1.);\n if(motionMode<1.5) return vec4(0.,0.,sin(uv.x*9.+uv.y*5.+p)*cos(uv.y*8.-uv.x*3.-p)*.065*edge,.9+.1*sin(uv.x*6.-uv.y*4.+p));\n if(motionMode<2.5) return vec4(sin(uv.y*9.+p)*cos(uv.x*7.-p)*6.*edge,cos(uv.x*8.+p)*sin(uv.y*6.-p)*4.*edge,0.,1.);\n float cycle=mod(motionTime,12.);\n float order=uv.x*.8+uv.y*.2+sin(uv.x*8.-uv.y*5.)*.08;\n float gone=smoothstep(1.8+order*1.2,3.8+order*1.2,cycle)*(1.-smoothstep(5.+order*1.7,7.2+order*1.7,cycle));\n return vec4(0.,0.,-gone*.95,1.-gone*.82);\n }\n\n float toneAt(vec2 uv) {\n vec2 p=uv*gridSize-.5, b=floor(p), f=fract(p);\n return mix(mix(texture2D(codes,(b+.5)/gridSize).b,texture2D(codes,(b+vec2(1.5,.5))/gridSize).b,f.x),mix(texture2D(codes,(b+vec2(.5,1.5))/gridSize).b,texture2D(codes,(b+1.5)/gridSize).b,f.x),f.y);\n }\n void main(){\n vec2 uv = vec2(gl_FragCoord.x, resolution.y - gl_FragCoord.y) / resolution;\n vec2 pixel = uv * sceneSize;\n if (strength > 0.) {\n vec4 normal = texture2D(surface, (uv * (surfaceSize - 1.) + .5) / surfaceSize) * 255.;\n vec2 slope = (vec2(normal.r * 256. + normal.g, normal.b * 256. + normal.a) - 32768.) / 32767.;\n vec2 edge = min(pixel, sceneSize - pixel) / cellSize;\n uv -= slope * strength * smoothstep(2.,8.,min(edge.x,edge.y)) / sceneSize;\n }\n vec4 ambient=ambientAt(uv);\n uv -= ambient.xy/sceneSize;\n pixel=uv*sceneSize;\n vec4 ink = texture2D(artwork, uv);\n if (fineDither > .5) {\n vec2 cell=floor(pixel/cellSize),address=(cell+.5)/gridSize;\n vec4 color=texture2D(cellColors,address);\n float density=trailAmount>0.?trailDensity(address):0.;\n float tone=clamp(toneAt(uv)+ambient.z+(trailKind>1.5?-density:density)*.65,0.,1.);\n float pitch=max(1.,min(cellSize.x,cellSize.y)*.32);\n float grain=.5+(printGrain(floor(pixel/pitch))-.5)*ditherAmount;\n float alpha=(tone<.001?0.:tone>.999?1.:smoothstep(grain-.035,grain+.035,tone))*color.a*ambient.w;\n // Preserve hue; tone is carried by mark coverage rather than muddy ink.\n vec3 hue=color.rgb/max(.001,max(color.r,max(color.g,color.b)));\n gl_FragColor=vec4(hue*alpha,alpha); return;\n }\n if (trailAmount > 0. || motionMode > .5) {\n vec2 cell=floor(pixel/cellSize), address=(cell+.5)/gridSize;\n float density=trailAmount>0.?trailDensity(address):0.;\n vec4 encoded=texture2D(codes,address);\n float original=floor(encoded.r*255.+.5)+floor(encoded.g*255.+.5)*256.;\n float index=trailIndex(original,glyphCount,density,cell);\n if(original>.5) index=clamp(floor(index+ambient.z*(glyphCount-1.)+printGrain(cell)),0.,glyphCount-1.);\n vec4 color=texture2D(cellColors,address);\n if((index!=original || motionMode>.5) && color.a>.01) {\n vec2 local=(pixel-cell*cellSize)*resolution/sceneSize;\n vec2 slot=vec2(mod(index,atlasColumns),floor(index/atlasColumns));\n float alpha=texture2D(glyphAtlas,(slot*tileSize+padding+local)/atlasSize).a;\n if(dots>.5) {\n vec2 d=(pixel-(cell+.5)*cellSize)/min(cellSize.x,cellSize.y);\n float r=min(.48,(index/(glyphCount-1.))*.5*dotSize);\n alpha=1.-smoothstep(r-.06,r+.02,length(d));\n }\n // Replace the cell, rather than blending two glyphs into a ghost.\n vec3 rgb=trailInk(color.rgb,density);\n ink=vec4(rgb*alpha*color.a,alpha*color.a);\n }\n }\n vec3 straightInk = ink.a > .0 ? ink.rgb / ink.a : vec3(.0);\n float value = max(straightInk.r, max(straightInk.g, straightInk.b));\n // Lighting belongs to character ink; black/transparent gaps stay empty.\n float light = surfaceLight((floor(pixel / cellSize) + .5) * cellSize / sceneSize, sceneSize);\n vec3 lit = illuminate(straightInk, light * smoothstep(0., .22, value)) * ink.a;\n gl_FragColor = vec4(lit, ink.a)*ambient.w;\n }")),l.linkProgram(d),!l.getProgramParameter(d,l.LINK_STATUS))throw new Error("Surface shader link failed");l.useProgram(d),f=l.createBuffer(),l.bindBuffer(l.ARRAY_BUFFER,f),l.bufferData(l.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),l.STATIC_DRAW);const e=l.getAttribLocation(d,"position");l.enableVertexAttribArray(e),l.vertexAttribPointer(e,2,l.FLOAT,!1,0,0),R=Object.fromEntries(["artwork","surface","resolution","sceneSize","cellSize","surfaceSize","strength","hoverMode","hoverFocus","codes","cellColors","glyphAtlas","gridSize","atlasSize","tileSize","atlasColumns","padding","glyphCount","dots","dotSize","trailKind","trailAmount","motionMode","motionTime","fineDither","ditherAmount"].map(t=>[t,l.getUniformLocation(d,t)]));for(let t=0;t<5;t++){const e=l.createTexture();g.push(e),l.activeTexture(l.TEXTURE0+t),l.bindTexture(l.TEXTURE_2D,e),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,l.LINEAR),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,l.LINEAR),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,1,1,0,l.RGBA,l.UNSIGNED_BYTE,new Uint8Array(4)),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE)}l.uniform1i(R.codes,2),l.uniform1i(R.cellColors,3),l.uniform1i(R.glyphAtlas,4),l.uniform1i(R.artwork,0),l.uniform1i(R.surface,1),l.pixelStorei(l.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),l.disable(l.BLEND),l.disable(l.DEPTH_TEST),r.addEventListener("webglcontextlost",D),z()}catch{D()}return{get canvas(){return r},render(t,n,a,o,d,u,f,p,z=0){const _=e(p?.animationStyle),C=T.update(z,_,p?.animationSpeed),F=(t=>"terminal"===t?.artStyle&&!t.customText&&!t.charsetFrames?.length&&!/[A-Za-z]/.test(t.charset??""))(p);if(x||!a||!o||!i.width||!i.height)return;const I=Math.min(i.width/a,1.5,Math.sqrt(4e6/(a*o))),P=Math.max(1,Math.round(a*I)),U=Math.max(1,Math.round(o*I));if(r.width===P&&r.height===U||(r.width=P,r.height=U,v=!1),l&&(i.width>M||i.height>M)&&D(),(c(n.mode)||"none"!==_||F)&&(t||!v||!k)&&(k=A.update(i,a,o,d,u,I,f,p),l)){const{plan:t,packed:e,atlas:i}=k;for(const[t,i]of[[2,e.indices],[3,e.colors]])l.activeTexture(l.TEXTURE0+t),l.bindTexture(l.TEXTURE_2D,g[t]),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,l.NEAREST),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,l.NEAREST),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,e.cols,e.rows,0,l.RGBA,l.UNSIGNED_BYTE,i);l.activeTexture(l.TEXTURE4),l.bindTexture(l.TEXTURE_2D,g[4]),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,l.RGBA,l.UNSIGNED_BYTE,i),l.uniform2f(R.gridSize,e.cols,e.rows),l.uniform2f(R.atlasSize,t.atlasWidth,t.atlasHeight),l.uniform2f(R.tileSize,t.tileWidth,t.tileHeight),l.uniform1f(R.atlasColumns,t.atlasColumns),l.uniform1f(R.padding,t.padding),l.uniform1f(R.glyphCount,t.glyphs.length),l.uniform1f(R.dots,k.dots?1:0),l.uniform1f(R.dotSize,k.dotSize)}if(l)l.uniform1f(R.motionMode,(t=>["none","print","current","reform"].indexOf(t))(_)),l.uniform1f(R.motionTime,C),l.uniform1f(R.fineDither,F?1:0),l.uniform1f(R.ditherAmount,Math.max(0,Math.min(2,p?.ditherStrength??1))),l.uniform1f(R.trailKind,"dissolve"===n.mode?2:0),l.uniform1f(R.trailAmount,c(n.mode)?n.focus[2]:0),l.viewport(0,0,P,U),!t&&v||(l.activeTexture(l.TEXTURE0),l.bindTexture(l.TEXTURE_2D,g[0]),l.pixelStorei(l.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,l.RGBA,l.UNSIGNED_BYTE,i),l.pixelStorei(l.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),v=!0),l.activeTexture(l.TEXTURE1),l.bindTexture(l.TEXTURE_2D,g[1]),l.texImage2D(l.TEXTURE_2D,0,l.RGBA,n.width,n.height,0,l.RGBA,l.UNSIGNED_BYTE,n.pixels),l.uniform2f(R.resolution,P,U),l.uniform2f(R.sceneSize,a,o),l.uniform2f(R.cellSize,d,u),l.uniform2f(R.surfaceSize,n.width,n.height),l.uniform1f(R.strength,n.strength),l.uniform1f(R.hoverMode,"light"===n.mode?1:"scan"===n.mode?2:0),l.uniform4fv(R.hoverFocus,n.focus),l.drawArrays(l.TRIANGLE_STRIP,0,4);else if(m)if(m.setTransform(I,0,0,I,0,0),m.clearRect(0,0,a,o),m.drawImage(i,0,0,a,o),("none"!==_||F)&&k){m.clearRect(0,0,a,o);const{plan:t,packed:e,atlas:i}=k,r=[0,0,0,1],l=Math.max(1,.32*Math.min(d,u));for(let a=0;a<e.rows;a++)for(let o=0;o<e.cols;o++){const f=(o+.5)/e.cols,g=(a+.5)/e.rows,x=4*(a*e.cols+o);if(e.colors[x+3]<10)continue;h(_,f,g,C,r);const v=4*(Math.min(n.height-1,Math.round(g*(n.height-1)))*n.width+Math.min(n.width-1,Math.round(f*(n.width-1)))),M=c(n.mode)?(256*n.pixels[v]+n.pixels[v+1])/65535*n.focus[2]:0,w=e.indices[x]+256*e.indices[x+1];let y="dissolve"===n.mode?w-Math.floor(M*t.glyphs.length*1.8):w+Math.floor(M*t.glyphs.length*.85);w>0&&(y+=r[2]*(t.glyphs.length-1)),y=Math.max(0,Math.min(t.glyphs.length-1,Math.floor(y+s(o,a))));let S=r[0],E=r[1];n.strength>0&&(S+=(256*n.pixels[v]+n.pixels[v+1]-32768)/32767*n.strength,E+=(256*n.pixels[v+2]+n.pixels[v+3]-32768)/32767*n.strength);const b=o*d+S,T=a*u+E,A=e.colors[x+3]/255*r[3],R=F?Math.max(1,e.colors[x],e.colors[x+1],e.colors[x+2]):255,z=`rgb(${e.colors[x]/R*255},${e.colors[x+1]/R*255},${e.colors[x+2]/R*255})`;if(m.fillStyle=z,F){const t=Math.max(0,Math.min(1,e.indices[x+2]/255+r[2]+.65*("dissolve"===n.mode?-M:M)));m.globalAlpha=A;for(let e=0;e<u;e+=l)for(let i=0;i<d;i+=l)t>.5+(s(Math.floor((b+i)/l),Math.floor((T+e)/l))-.5)*Math.max(0,Math.min(2,p?.ditherStrength??1))&&m.fillRect(b+i,T+e,Math.min(l,d-i),Math.min(l,u-e))}else if(y>0)if(m.globalAlpha=A,k.dots){const e=Math.min(.48,y/(t.glyphs.length-1)*.5*k.dotSize)*Math.min(d,u);m.beginPath(),m.arc(b+.5*d,T+.5*u,e,0,2*Math.PI),m.fill()}else m.drawImage(i,y%t.atlasColumns*t.tileWidth+t.padding,Math.floor(y/t.atlasColumns)*t.tileHeight+t.padding,t.cellWidth*I,t.cellHeight*I,b,T,d,u),m.globalAlpha=1,m.globalCompositeOperation="source-atop",m.fillRect(b,T,d,u),m.globalCompositeOperation="source-over"}m.globalAlpha=1}else if(c(n.mode)&&k){const{plan:t,packed:e,atlas:i}=k;for(let s=0;s<e.rows;s++)for(let h=0;h<e.cols;h++){const a=4*(Math.min(n.height-1,Math.round((s+.5)/e.rows*(n.height-1)))*n.width+Math.min(n.width-1,Math.round((h+.5)/e.cols*(n.width-1)))),o=(256*n.pixels[a]+n.pixels[a+1])/65535*n.focus[2],r=4*(s*e.cols+h),l=.0137*(h*h*17+s*s*23+h*s*19),c=l-Math.floor(l),f=e.indices[r]+256*e.indices[r+1],g="dissolve"===n.mode?Math.max(0,f-Math.floor(o*t.glyphs.length*(1.35+.9*c))):Math.min(t.glyphs.length-1,f+Math.floor(o*t.glyphs.length*.85));if(g===f||e.colors[r+3]<10)continue;const p=h*d,x=s*u;if(m.clearRect(p,x,d,u),m.globalAlpha=e.colors[r+3]/255,k.dots){const e=Math.min(.48,g/(t.glyphs.length-1)*.5*k.dotSize)*Math.min(d,u);m.fillStyle="#fff",m.beginPath(),m.arc(p+.5*d,x+.5*u,e,0,2*Math.PI),m.fill()}else m.drawImage(i,g%t.atlasColumns*t.tileWidth+t.padding,Math.floor(g/t.atlasColumns)*t.tileHeight+t.padding,t.cellWidth*I,t.cellHeight*I,p,x,d,u);m.globalAlpha=1,m.globalCompositeOperation="source-atop";const v=Math.max(e.colors[r],e.colors[r+1],e.colors[r+2]),M="dissolve"===n.mode?v:Math.max(v,Math.min(112,191*o)),w=v?M/v:0;m.fillStyle=`rgb(${v?e.colors[r]*w:M},${v?e.colors[r+1]*w:M},${v?e.colors[r+2]*w:M})`,m.fillRect(p,x,d,u),m.globalCompositeOperation="source-over"}}else if("light"===n.mode||"scan"===n.mode){!t&&b&&w.width===P&&w.height===U||(w.width=P,w.height=U,y.width=P,y.height=U,S.filter="brightness(3)",S.drawImage(i,0,0,P,U),S.filter="none",b=!0);const[e,s,h,r]=n.focus;if(h>.001){E.setTransform(1,0,0,1,0,0),E.clearRect(0,0,P,U),E.drawImage(w,0,0),E.globalCompositeOperation="destination-in",E.save(),E.translate(e*P,s*U),E.scale("scan"===n.mode?.13:1,1);const t=r*Math.min(P,U),i=E.createRadialGradient(0,0,0,0,0,t);i.addColorStop(0,`rgba(255,255,255,${h})`),i.addColorStop(.5,`rgba(255,255,255,${.4*h})`),i.addColorStop(1,"rgba(255,255,255,0)"),E.fillStyle=i,E.fillRect(10*-P,10*-U,20*P,20*U),E.restore(),E.globalCompositeOperation="source-over",m.globalCompositeOperation="source-atop",m.drawImage(y,0,0,a,o),m.globalCompositeOperation="source-over"}}else if(n.strength>0){const t=32,e=18,s=a/t,h=o/e;for(let r=0;r<e;r++)for(let l=0;l<t;l++){const c=(l+.5)/t,f=(r+.5)/e,g=Math.min(n.width-1,Math.round(c*(n.width-1))),p=4*(Math.min(n.height-1,Math.round(f*(n.height-1)))*n.width+g),x=n.pixels,v=Math.min(l*s/d,(a-(l+1)*s)/d,r*h/u,(o-(r+1)*h)/u),M=Math.max(0,Math.min(1,(v-2)/6)),w=M*M*(3-2*M),y=(256*x[p]+x[p+1]-32768)/32767*n.strength*w,S=(256*x[p+2]+x[p+3]-32768)/32767*n.strength*w;Math.abs(y)+Math.abs(S)<.02||(m.clearRect(l*s,r*h,s,h),m.drawImage(i,Math.max(0,Math.min(a-s,l*s-y))*i.width/a,Math.max(0,Math.min(o-h,r*h-S))*i.height/o,s*i.width/a,h*i.height/o,l*s,r*h,s,h))}}},destroy(){x=!0,A.destroy(),r.removeEventListener("webglcontextlost",D),_(),r.remove(),w.width=w.height=y.width=y.height=1,i.style.visibility=o,l?.getExtension("WEBGL_lose_context")?.loseContext()}}}(t,i,()=>queueMicrotask(()=>{f=!0,S()}));function b(t){if(g=0,l||!d||document.hidden)return;const s=i.clientWidth,n=i.clientHeight;if(!s||!n)return;const h=y.matches||o.paused;r.configure(o.effect,o.strength,o.radius);const a=r.active;if(!h){if(v+=p?Math.min(.1,(t-p)/1e3):0,w){const t=i.getBoundingClientRect();M&&t.width&&t.height?r.move((M.x-t.left)/t.width,(M.y-t.top)/t.height):r.leave(),w=!1}r.step(p?(t-p)/1e3:1/60)}const c=f||o.animated&&!h&&t-x>=1e3/Math.max(1,Math.min(60,o.fps))-.5;(c||a||r.active||!h&&"none"!==e(o.motion))&&(E.render(c,r.refraction,s,n,o.fontSize*o.charSpacing,o.fontSize/o.charAspect*o.charSpacing,c?o.getFrame?.():void 0,{charset:o.charset,customText:o.customText,renderMode:o.renderMode,dotSizeRatio:o.dotSizeRatio,colorMode:"fullcolor",animationStyle:o.motion,animationSpeed:o.motionSpeed??1,artStyle:o.fineDither?"terminal":"classic",ditherStrength:o.ditherStrength??1},v),c&&(x=t),f=!1),p=t,h||!o.animated&&!r.active&&"none"===e(o.motion)||S()}const T=()=>{r.clear(),M=null,w=!1,p=0,f=!0,cancelAnimationFrame(g),g=0,S()},A=t=>{if("touch"===t.pointerType||o.paused||y.matches)return;if(t.target instanceof Element&&t.target.closest("button,a,input,summary,select"))return void k();const e=i.getBoundingClientRect();t.clientX<e.left||t.clientX>e.right||t.clientY<e.top||t.clientY>e.bottom?k():(M={x:t.clientX,y:t.clientY},w=!0,S())},k=()=>{M=null,w=!0,S()},R=new IntersectionObserver(([t])=>{d=t.isIntersecting,T()});R.observe(t);const z=new ResizeObserver(()=>{r=new m(i.clientWidth/Math.max(1,i.clientHeight)),T()});return z.observe(i),t.addEventListener("pointermove",A),t.addEventListener("pointerleave",k),t.addEventListener("pointercancel",k),document.addEventListener("visibilitychange",T),y.addEventListener("change",T),{get canvas(){return E.canvas},invalidate(){f=!0,S()},update(t){o={...o,...t},T()},destroy(){l||(l=!0,cancelAnimationFrame(g),R.disconnect(),z.disconnect(),E.destroy(),t.removeEventListener("pointermove",A),t.removeEventListener("pointerleave",k),t.removeEventListener("pointercancel",k),document.removeEventListener("visibilitychange",T),y.removeEventListener("change",T))}}}export{f as mountHover,f as mountStudioHover};//# sourceMappingURL=hover.js.map
|