asciify-engine 4.7.0 → 4.9.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/dist/studio.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var t=[{value:"none",label:"Off",group:"Still",description:"Keep the artwork still under the pointer."},{value:"trail",label:"Trail",group:"Change characters",description:"A fluid wake changes character density and settles behind your cursor."},{value:"dissolve",label:"Dissolve",group:"Change characters",description:"Erase a soft path through the characters; the image gradually reforms."},{value:"contour",label:"Contour",group:"Change characters",description:"Fine tonal rings trace your path without moving the grid."},{value:"etch",label:"Emboss",group:"Change characters",description:"Press a light-and-shadow impression into the characters; the grid stays fixed."},{value:"water",label:"Water",group:"Move the image",description:"Soft ripples refract the image and settle after your stroke."},{value:"silk",label:"Silk",group:"Move the image",description:"Directional folds follow the movement of your hand."},{value:"vortex",label:"Vortex",group:"Move the image",description:"A swirling wake curls through the image."},{value:"magnetic",label:"Magnetic Pull",group:"Move the image",description:"The image gathers toward your stroke, then relaxes."},{value:"scatter",label:"Scatter",group:"Move the image",description:"A textured outward scatter settles behind your cursor."},{value:"elastic",label:"Elastic",group:"Move the image",description:"Push the image with your stroke; it recoils and springs back into place."},{value:"rake",label:"Rake",group:"Move the image",description:"Comb the image into alternating ribbons that glide back into alignment."}],e=[{value:"none",mode:"none",group:"Still",label:"Off",description:"Keep the image still. Hover stays available."},{value:"caustics",mode:"caustics",group:"Light and texture",label:"Caustics",description:"Soft ribbons of light travel across a stationary character grid."},{value:"current",mode:"current",group:"Flow and depth",label:"Slow Current",description:"A gentle flow through the image, with steady edges."},{value:"reform",mode:"reform",group:"Rebuild",label:"Reveal & Reform",description:"Disperse, gather, then hold the complete image."},{value:"sheen",mode:"sheen",group:"Light and texture",label:"Sheen",description:"A broad diagonal light sweep; characters stay anchored."},{value:"tidal",mode:"tidal",group:"Flow and depth",label:"Tidal Rings",description:"Concentric currents travel outward, with protected edges."},{value:"grain",mode:"grain",group:"Light and texture",label:"Living Grain",description:"Slow, individually phased tonal changes on a stationary grid."},{value:"parallax",mode:"parallax",group:"Flow and depth",label:"Parallax",description:"A shallow, continuous drift through the image, with the edges held in place."},{value:"weave",mode:"weave",group:"Flow and depth",label:"Woven Flow",description:"Interlaced bands move in opposing directions, like a flexible printed fabric."},{value:"print",mode:"print",group:"Rebuild",label:"Print Shift",description:"Staggered rows lift, soften and register back into the image."},{value:"trace",mode:"trace",group:"Light and texture",label:"Contour Light",description:"Light follows the source image’s tonal contours; every character stays anchored."}],i=t=>Math.max(0,Math.min(1,t)),a=(t,e,a)=>{const s=i((a-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)},r=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 o(t,e,r,o,n,h=.5){if(n[0]=n[1]=n[2]=0,n[3]=1,"none"===t)return n;const l=o*Math.PI/6,c=a(0,.12,Math.min(e,1-e,r,1-r));if("caustics"===t){const t=Math.sin(9*e+5*r+l)+Math.sin(8*r-3*e-l),i=Math.pow(Math.max(0,1-.72*Math.abs(t)),3);n[2]=(.22*i-.045)*c}else if("current"===t)n[0]=Math.sin(9*r+l)*Math.cos(7*e-l)*10*c,n[1]=Math.cos(8*e+l)*Math.sin(6*r-l)*7*c;else if("sheen"===t)n[2]=.2*Math.pow(.5+.5*Math.cos(5*e+3*r-l),8)-.025;else if("tidal"===t){const t=e-.5,i=r-.5,a=Math.hypot(t,i),s=Math.sin(22*a-l)*c;n[0]=t*s*9,n[1]=i*s*9,n[2]=.035*s}else if("grain"===t){const t=s(Math.floor(160*e),Math.floor(100*r))*Math.PI*2;n[2]=.07*Math.sin(l+t)}else if("parallax"===t){const t=.45+.55*Math.max(0,1-1.4*Math.hypot(e-.5,r-.5));n[0]=12*Math.sin(l)*t*c,n[1]=6*(Math.cos(l)-1)*t*c}else if("weave"===t)n[0]=Math.sin(r*Math.PI*6+l)*Math.sin(l)*8*c,n[1]=Math.sin(e*Math.PI*6-l)*Math.sin(l)*6*c;else if("print"===t){const t=Math.floor(24*r),e=((o+3*s(t,3))%12+12)%12,i=a(1,2.5,e)*(1-a(3.5,5,e));n[0]=Math.sin(2.4*t)*i*9*c,n[1]=5*-i*c,n[2]=.22*-i,n[3]=1-.45*i}else if("trace"===t){const t=.5+.5*Math.cos(l);n[2]=.22*Math.pow(Math.max(0,1-Math.abs(i(h)-t)/.16),3)-.015}else if("reform"===t){const t=(o%12+12)%12,i=s(Math.floor(160*e),Math.floor(100*r)),h=.65*e+.2*r+.15*i+.08*Math.sin(8*e-5*r),d=a(1.8+1.2*h,3.8+1.2*h,t)*(1-a(5+1.7*h,7.2+1.7*h,t));n[0]=Math.sin(9*r+l)*d*(1-d)*24*c,n[1]=-d*(1-d)*(8+12*i)*c,n[2]=.45*-d,n[3]=1-.9*d}return n}function n(t,e){const a=Math.max(0,Math.min(2,Number.isFinite(e)?e:1));return t[0]*=a,t[1]*=a,t[2]*=a,t[3]=i(1+(t[3]-1)*a),t}var h=["rgb","red","green","blue"],l=t=>Math.max(0,Math.min(1,t));function c(t){const e=new Map([[0,0],[1,1]]);if(Array.isArray(t))for(const i of t.slice(0,64)){if(!Array.isArray(i)||i.length<2||"number"!=typeof i[0]||!Number.isFinite(i[0])||"number"!=typeof i[1]||!Number.isFinite(i[1]))continue;const t=Math.round(255*l(i[0]))/255;!e.has(t)&&e.size>=16||e.set(t,l(i[1]))}return[...e].sort((t,e)=>t[0]-e[0])}function d(t){const e=t&&"object"==typeof t?t:{};return Object.fromEntries(h.map(t=>[t,c(e[t])]))}function f(t){const e=c(t),i=e.length,a=e.slice(1).map((t,i)=>t[0]-e[i][0]),s=e.slice(1).map((t,i)=>(t[1]-e[i][1])/a[i]),r=new Float64Array(i);r[0]=s[0],r[i-1]=s[i-2];for(let t=1;t<i-1;t++){const e=s[t-1],i=s[t];if(e*i<=0)continue;const o=2*a[t]+a[t-1],n=a[t]+2*a[t-1];r[t]=(o+n)/(o/e+n/i)}const o=new Uint8Array(256);let n=0;for(let t=0;t<256;t++){const s=t/255;for(;n<i-2&&s>e[n+1][0];)n++;const h=a[n],c=(s-e[n][0])/h,d=c*c,f=d*c,m=(2*f-3*d+1)*e[n][1]+(f-2*d+c)*h*r[n]+(-2*f+3*d)*e[n+1][1]+(f-d)*h*r[n+1];o[t]=Math.round(255*l(m))}return o}function m(t,e,i,a,s,r){a=Math.max(0,Math.min(e-1,a)),s=Math.max(0,Math.min(i-1,s));const o=Math.floor(a),n=Math.floor(s),h=a-o,l=s-n,c=4*(n*e+o);if(0===h&&0===l){for(let e=0;e<4;e++)r[e]=t[c+e];return}const d=4*(n*e+Math.min(e-1,o+1)),f=4*(Math.min(i-1,n+1)*e+o),m=4*(Math.min(i-1,n+1)*e+Math.min(e-1,o+1)),u=(1-h)*(1-l)*t[c+3],p=h*(1-l)*t[d+3],g=(1-h)*l*t[f+3],M=h*l*t[m+3],x=u+p+g+M;for(let e=0;e<3;e++)r[e]=x?(t[c+e]*u+t[d+e]*p+t[f+e]*g+t[m+e]*M)/x:0;r[3]=x}function u(t,e,i,a,s,r){if(a>=0&&a<=e-1&&s>=0&&s<=i-1)return m(t,e,i,a,s,r);if(r[0]=r[1]=r[2]=r[3]=0,a<=-1||a>=e||s<=-1||s>=i)return;const o=Math.floor(a),n=Math.floor(s),h=a-o,l=s-n;for(let a=0;a<=1;a++)for(let s=0;s<=1;s++){const c=o+s,d=n+a;if(c<0||c>=e||d<0||d>=i)continue;const f=4*(d*e+c),m=(s?h:1-h)*(a?l:1-l)*t[f+3];r[0]+=t[f]*m,r[1]+=t[f+1]*m,r[2]+=t[f+2]*m,r[3]+=m}r[3]&&(r[0]/=r[3],r[1]/=r[3],r[2]/=r[3])}var p=[{value:"twirl",label:"Twirl",description:"Rotate the center into a smooth spiral; the outer boundary stays fixed.",direction:!1,frequency:!1},{value:"pinch",label:"Pinch",description:"Contract the center, or expand it with negative strength.",direction:!1,frequency:!1},{value:"sphere",label:"Spherize",description:"Magnify a rounded lens through the source; negative strength recedes.",direction:!1,frequency:!1},{value:"ripple",label:"Ripple",description:"Bend the image through concentric, soft-edged waves.",direction:!1,frequency:!0},{value:"zigzag",label:"Zigzag",description:"Alternate the twist in sharp, concentric bands.",direction:!1,frequency:!0},{value:"shear",label:"Shear",description:"Slant a region along an adjustable direction.",direction:!0,frequency:!1},{value:"smudge",label:"Smudge",description:"Draw a soft region of the source along one direction.",direction:!0,frequency:!1},{value:"polar",label:"Polar",description:"Unwrap a region into polar coordinates; negative strength wraps it.",direction:!0,frequency:!1},{value:"fragment",label:"Fragment",description:"Offset small source tiles into a stable fractured texture.",direction:!0,frequency:!0}],g=(t,e,i,a)=>"number"==typeof t&&Number.isFinite(t)?Math.max(i,Math.min(a,t)):e;function M(t){if(!Array.isArray(t))return[];const e=[];for(const i of t.slice(0,64))if(i&&"object"==typeof i&&p.some(t=>t.value===i.type)&&(e.push({type:i.type,enabled:!1!==i.enabled,amount:g(i.amount,.35,-1,1),x:g(i.x,.5,0,1),y:g(i.y,.5,0,1),radius:g(i.radius,.55,.05,2),angle:g(i.angle,0,-180,180),frequency:g(i.frequency,5,1,24)}),8===e.length))break;return e}var x=2*Math.PI,v=(t,e)=>{let i=Math.imul(t,374761393)^Math.imul(e,668265263);return i=Math.imul(i^i>>>13,1274126177),((i^i>>>16)>>>0)/4294967296},b=class{constructor(t=[],e="clamp"){this.warps=[],this.signature="",this.geometry="",this.coordinates=new Float32Array(0),this.output=new Uint8ClampedArray(0),this.sampled=[0,0,0,0],this.edge="clamp",this.configure(t,e)}configure(t=[],e="clamp"){const i=M(t).filter(t=>t.enabled&&0!==t.amount),a=JSON.stringify(i);this.edge="transparent"===e?"transparent":"clamp",a!==this.signature&&(this.signature=a,this.geometry="",this.warps=i.map(t=>({...t,cos:Math.cos(t.angle*Math.PI/180),sin:Math.sin(t.angle*Math.PI/180)})),i.length||this.clear())}get active(){return this.warps.length>0}apply(t,e,i,a=e/i){if(!this.active)return t;if(!Number.isInteger(e)||!Number.isInteger(i)||e<1||i<1||e*i*4!==t.length||!Number.isFinite(a)||a<=0)throw new Error("Warp dimensions do not match the source.");const s=`${e}:${i}:${a}`;if(s!==this.geometry){this.coordinates.length!==e*i*2&&(this.coordinates=new Float32Array(e*i*2));const t=Math.max(1,a),r=Math.max(1,1/a);for(let a=0;a<i;a++)for(let s=0;s<e;s++){let o=(s+.5)/e,n=(a+.5)/i;for(let e=this.warps.length-1;e>=0;e--){const i=this.warps[e],a=(o-i.x)*t/i.radius,s=(n-i.y)*r/i.radius,h=a*a+s*s;if(h>=1)continue;const l=Math.sqrt(h),c=(1-h)*(1-h),d=i.amount;let f=a,m=s;if("twirl"===i.type||"zigzag"===i.type){const t="twirl"===i.type?-d*x*c:.65*d*(2/Math.PI*Math.asin(Math.sin(l*x*i.frequency)))*c,e=Math.cos(t),r=Math.sin(t);f=a*e-s*r,m=a*r+s*e}else if("pinch"===i.type){const t=Math.exp(2*d*c);f=a*t,m=s*t}else if("sphere"===i.type&&l>0){const t=1+d*c*(2*Math.asin(l)/Math.PI/l-1);f=a*t,m=s*t}else if("ripple"===i.type&&l>0){const t=1+.12*d*Math.sin(l*x*i.frequency)*c/l;f=a*t,m=s*t}else if("shear"===i.type){const t=-a*i.sin+s*i.cos;f-=d*t*.9*c*i.cos,m-=d*t*.9*c*i.sin}else if("smudge"===i.type)f-=.65*d*c*i.cos,m-=.65*d*c*i.sin;else if("polar"===i.type){const t=a*i.cos+s*i.sin,e=-a*i.sin+s*i.cos,r=Math.atan2(e,t),o=d>0?r/Math.PI:Math.cos(t*Math.PI)*(e+1)/2,n=d>0?2*l-1:Math.sin(t*Math.PI)*(e+1)/2,h=o*i.cos-n*i.sin,u=o*i.sin+n*i.cos;f+=(h-a)*Math.abs(d)*c,m+=(u-s)*Math.abs(d)*c}else if("fragment"===i.type){const t=Math.floor((a*i.cos+s*i.sin)*i.frequency),e=Math.floor((-a*i.sin+s*i.cos)*i.frequency),r=(v(t,e)-.5)*d*.5*c,o=(v(e+71,t-31)-.5)*d*.5*c;f+=r*i.cos-o*i.sin,m+=r*i.sin+o*i.cos}o=i.x+f*i.radius/t,n=i.y+m*i.radius/r}const h=2*(a*e+s);this.coordinates[h]=o*e-.5,this.coordinates[h+1]=n*i-.5}this.geometry=s}this.output.length!==t.length&&(this.output=new Uint8ClampedArray(t.length));const r=t===this.output?t.slice():t,o="transparent"===this.edge?u:m;for(let a=0,s=0;a<t.length;a+=4,s+=2){o(r,e,i,this.coordinates[s],this.coordinates[s+1],this.sampled);for(let t=0;t<4;t++)this.output[a+t]=this.sampled[t]}return this.output}clear(){this.coordinates=new Float32Array(0),this.output=new Uint8ClampedArray(0),this.geometry=""}},w=["ascii","blocks","braille","dots","lines","cross","diagonal","diamond","mixed","pixel","mosaic","lego","voxel","disco","dither","hex","led","cmyk"],y=["none","bayer2","bayer4","bayer8","bayer16","floyd-steinberg","atkinson","stucki","sierra","sierra-lite","burkes","jarvis","halftone","lines","noise","vertical-lines","diagonal-lines","radial","blue-noise"],S=["source-over","multiply","screen","overlay","soft-light","hard-light","color-dodge","color-burn","hue","saturation","color","luminosity"],k={original:[],gray4:["#000000","#555555","#aaaaaa","#ffffff"],gray8:["#000000","#242424","#494949","#6d6d6d","#929292","#b6b6b6","#dbdbdb","#ffffff"],rgb8:["#000000","#ff0000","#00ff00","#0000ff","#ffff00","#ff00ff","#00ffff","#ffffff"],cyberpunk:["#08081a","#3c1670","#ed299a","#29dfef","#fff7bf"],pastel:["#393448","#a5b4d4","#9ed9c6","#e7aac1","#f5e8be"],mono:["#080808","#f2f2e8"],asciify:["#080808","#625b38","#a19558","#e8b900"],gameboy:["#0f380f","#306230","#8bac0f","#9bbc0f"],cga:["#000000","#55ffff","#ff55ff","#ffffff"],pico8:["#000000","#1d2b53","#7e2553","#008751","#ab5236","#5f574f","#c2c3c7","#fff1e8","#ff004d","#ffa300","#ffec27","#00e436","#29adff","#83769c","#ff77a8","#ffccaa"],c64:["#000000","#ffffff","#880000","#aaffee","#cc44cc","#00cc55","#0000aa","#eeee77","#dd8855","#664400","#ff7777","#333333","#777777","#aaff66","#0088ff","#bbbbbb"],amber:["#100b00","#5f3b00","#c98014","#ffd17c"],ice:["#081b29","#25586e","#69a6b3","#d9ece7"],risograph:["#f4ebd0","#f2594b","#2853a5","#29232e"],sepia:["#201b17","#6b5039","#b49868","#f6e6c5"],nord:["#2e3440","#4c566a","#88c0d0","#eceff4"],dusk:["#211b35","#654271","#c3788c","#f5c9a3"],forest:["#101f1b","#355747","#87a16f","#e4e3ba"],ocean:["#071b33","#17577f","#3fa7a4","#d9efde"],newsprint:["#191919","#666666","#aaaaaa","#eee9df"],custom:["#080808","#e8b900"]},A={version:1,aspectRatio:"original",style:"ascii",cellSize:6,charset:" .:-=+*#%@",colorMode:"accent",ink:"#e8b900",crop:{x:.5,y:.5,zoom:1,rotation:0},warps:[],warpEdge:"clamp",backdrop:{mode:"solid",color:"#080808",color2:"#393323",blur:12,opacity:1},color:{brightness:0,contrast:1,saturation:1,grayscale:0,tint:"#e8b900",amount:0,blend:"source-over",blackPoint:0,whitePoint:1,gamma:1,shadows:0,highlights:0,curves:{rgb:[[0,0],[1,1]],red:[[0,0],[1,1]],green:[[0,0],[1,1]],blue:[[0,0],[1,1]]},denoise:0},dither:{algorithm:"none",palette:"mono",colors:["#080808","#e8b900"],amount:1,scale:2,threshold:.5,motion:"none",speed:1,direction:45,colorSpace:"rgb"},mask:{enabled:!1,invert:!1,shapes:[]},lights:[],effects:{bloom:0,characterBloom:0,grain:0,dust:0,scanlines:0,crt:0,prism:0,rgbSplit:0,sharpen:0,vignette:0,glitch:0,pixelate:0,blur:0,blurType:"gaussian",angle:0,focus:.5,halftone:0},motion:{type:"none",speed:1,amount:1},hover:{effect:"trail",strength:.55,radius:.2,edgeSafe:!1}},E=t=>t&&"object"==typeof t&&!Array.isArray(t)?t:{},T=(t,e,i,a)=>"number"==typeof t&&Number.isFinite(t)?Math.min(a,Math.max(i,t)):e,F=(t,e)=>"string"==typeof t&&/^#[\da-f]{6}$/i.test(t)?t:e,I=(t,e,i)=>e.includes(t)?t:i;function P(i={}){const a=E(i),s=A;if(void 0!==a.version&&1!==a.version)throw new Error("Unsupported studio settings version. Update asciify-engine.");const r=E(a.crop),o=E(a.backdrop),n=E(a.color),h=E(a.dither),l=E(a.mask),c=E(a.effects),f=E(a.motion),m=E(a.hover),u={...s.effects};for(const t of["bloom","characterBloom","grain","dust","scanlines","crt","prism","rgbSplit","sharpen","vignette","glitch","pixelate","halftone"])u[t]=T(c[t],0,0,1);u.blur=T(c.blur,0,0,24),u.blurType=I(c.blurType,["gaussian","directional","radial","progressive"],s.effects.blurType),u.angle=T(c.angle,0,-180,180),u.focus=T(c.focus,.5,0,1);let p=2048;return{version:1,aspectRatio:I(a.aspectRatio,["original","16:9","9:16","1:1","4:3","3:4","21:9"],"original"),style:I(a.style,w,s.style),cellSize:T(a.cellSize,s.cellSize,["pixel","mosaic","lego","voxel","disco","dots","hex","led","cmyk"].includes(String(a.style))?1:3,60),charset:"string"==typeof a.charset&&a.charset.length?Array.from(a.charset).slice(0,128).join(""):s.charset,colorMode:I(a.colorMode,["accent","source","gray"],s.colorMode),ink:F(a.ink,s.ink),warps:M(a.warps),warpEdge:I(a.warpEdge,["clamp","transparent"],"clamp"),crop:{x:T(r.x,.5,0,1),y:T(r.y,.5,0,1),zoom:T(r.zoom,1,1,5),rotation:90*Math.round(T(r.rotation,0,-360,360)/90)},backdrop:{mode:I(o.mode,["solid","transparent","source","blurred","gradient"],s.backdrop.mode),color:F(o.color,s.backdrop.color),color2:F(o.color2,s.backdrop.color2),blur:T(o.blur,12,0,32),opacity:T(o.opacity,1,0,1)},color:{brightness:T(n.brightness,0,-1,1),contrast:T(n.contrast,1,0,3),saturation:T(n.saturation,1,0,3),grayscale:T(n.grayscale,0,0,1),tint:F(n.tint,s.color.tint),amount:T(n.amount,0,0,1),blend:I(n.blend,S,s.color.blend),blackPoint:T(n.blackPoint,0,0,.99),whitePoint:Math.max(T(n.blackPoint,0,0,.99)+1/255,T(n.whitePoint,1,1/255,1)),gamma:T(n.gamma,1,.25,4),shadows:T(n.shadows,0,-1,1),highlights:T(n.highlights,0,-1,1),curves:d(n.curves),denoise:T(n.denoise,0,0,1)},dither:{algorithm:I(h.algorithm,y,"none"),palette:"string"==typeof h.palette&&Object.prototype.hasOwnProperty.call(k,h.palette)?h.palette:"mono",colors:Array.isArray(h.colors)&&h.colors.length>=2?h.colors.slice(0,32).map(t=>F(t,"#000000")):[...s.dither.colors],amount:T(h.amount,1,0,2),scale:Math.round(T(h.scale,2,1,12)),threshold:T(h.threshold,.5,0,1),motion:I(h.motion,["none","drift","shimmer"],"none"),speed:T(h.speed,1,.1,3),direction:T(h.direction,45,-180,180),colorSpace:I(h.colorSpace,["rgb","luminance"],"rgb")},mask:{enabled:!0===l.enabled,invert:!0===l.invert,shapes:Array.isArray(l.shapes)?l.shapes.slice(0,64).map(t=>{const e=E(t),i=I(e.kind,["rectangle","ellipse","brush"],"rectangle"),a="brush"===i&&Array.isArray(e.points)?e.points.slice(0,p).map(t=>Array.isArray(t)?[Math.round(1e4*T(t[0],0,0,1))/1e4,Math.round(1e4*T(t[1],0,0,1))/1e4]:[0,0]):[];return p-=a.length,{kind:i,x:T(e.x,0,0,1),y:T(e.y,0,0,1),width:T(e.width,.5,0,1),height:T(e.height,.5,0,1),size:T(e.size,.05,.005,.5),points:a}}):[]},lights:Array.isArray(a.lights)?a.lights.slice(0,4).map(t=>{const e=E(t);return{x:T(e.x,.5,0,1),y:T(e.y,.5,0,1),radius:T(e.radius,.3,.02,1),intensity:T(e.intensity,.5,0,1),color:F(e.color,"#ffffff")}}):[],effects:u,motion:{type:I(f.type,e.map(t=>t.mode),"none"),speed:T(f.speed,1,.1,3),amount:T(f.amount,1,0,2)},hover:{effect:I(m.effect,t.map(t=>t.value),"trail"),strength:T(m.strength,.55,0,1),radius:T(m.radius,.2,.1,1),edgeSafe:!0===m.edgeSafe}}}function R(t,e,i,a,s){const r=Math.abs(s.rotation/90)%2==1,o=r?e:t,n=r?t:e,h=Math.max(i/o,a/n)*s.zoom;return{width:o*h,height:n*h,x:(i-o*h)*s.x,y:(a-n*h)*s.y,scale:h,rotated:r}}function C(t,e,i){if(Math.abs(i.crop.rotation/90)%2==1&&([t,e]=[e,t]),"original"===i.aspectRatio)return[t,e];const[a,s]=i.aspectRatio.split(":").map(Number);return t/e>a/s?[Math.round(e*a/s),e]:[t,Math.round(t*s/a)]}function L(t,e){const i={...t,...e};for(const a of["crop","backdrop","color","dither","mask","effects","motion","hover"])e[a]&&Object.assign(i,{[a]:{...t[a],...e[a]}});return e.color?.curves&&(i.color.curves={...t.color.curves,...e.color.curves}),P(i)}function D(t,e,i,a=12e3,s=1){const r=Math.max(2,Number.isFinite(t)?t:960),o=Math.max(2,Number.isFinite(e)?e:540),n=Math.max(1,Math.floor(Number.isFinite(a)?a:12e3)),h=Math.max(.01,Number.isFinite(s)?s:1),l=["dither","pixel","mosaic","lego","voxel","disco","dots","hex","led","cmyk"].includes(i.style)?1:1.65;let c=Math.max(1,Math.ceil(Math.sqrt(r*o/(n*l))/h));for(;Math.ceil(r/(c*h))*Math.ceil(o/(c*h*l))>n;)c++;const d="dither"===i.style?i.dither.scale:i.cellSize,f=Math.max(c,d)*h;return{cell:f,rowHeight:f*l,columns:Math.ceil(r/f),rows:Math.ceil(o/(f*l)),minimum:c,limited:d<c}}var U=[["ascii","Signature ASCII","Brand ink and clean characters.",{}],["print","Newsprint","Fine diffusion on warm paper.",{style:"dither",dither:{algorithm:"floyd-steinberg",palette:"newsprint"}}],["handheld","Pocket camera","Four-tone ordered dither.",{style:"dither",dither:{algorithm:"bayer4",palette:"gameboy",scale:3}}],["riso","Two inks","Limited-color print texture.",{style:"dither",dither:{algorithm:"atkinson",palette:"risograph",scale:2}}],["night","Night signal","Gray characters and optical fringe.",{ink:"#888888",effects:{prism:.7,scanlines:.2,vignette:.3}}],["terminal","Phosphor","Green glyphs with a soft glow.",{ink:"#83efad",effects:{bloom:.4,scanlines:.35,crt:.2}}],["mosaic","Mosaic study","Separated color tiles.",{style:"mosaic",cellSize:14,colorMode:"source"}],["bricks","Brickwork","Colorful studded cells.",{style:"lego",cellSize:18,colorMode:"source"}],["voxel","Little volumes","Three-face isometric tiles.",{style:"voxel",cellSize:22,colorMode:"source"}],["disco","Mirror room","Faceted tiles and warm light.",{style:"disco",cellSize:18,colorMode:"source",lights:[{x:.35,y:.25,radius:.25,intensity:.45,color:"#fff2d4"}]}],["wallpaper","Wallpaper","Living ASCII over a softened source.",{backdrop:{mode:"blurred",blur:18,opacity:.55},ink:"#f2e9c9",motion:{type:"caustics",speed:.5}}],["blueprint","Blueprint","Linework in a cool monochrome.",{style:"lines",ink:"#9bccdf",backdrop:{mode:"solid",color:"#0a1e30"}}]].map(([t,e,i,a])=>({id:t,name:e,description:i,settings:P(a)}));function N(t){const e=U.find(e=>e.id===t);if(!e)throw new Error("Unknown studio look.");return P(e.settings)}function O(t){const e=function(t){const e=t.blackPoint??0,i=t.whitePoint??1,a=t.gamma??1,s=t.shadows??0,r=t.highlights??0;if(0===e&&1===i&&1===a&&0===s&&0===r)return null;const o=[0,.25+.2*s,.5,.75+.2*r,1],n=o.slice(1).map((t,e)=>4*(t-o[e])),h=[n[0],...n.slice(1).map((t,e)=>2*t*n[e]/(t+n[e])),n[3]],l=new Uint8Array(256);for(let t=0;t<256;t++){const s=Math.pow(Math.max(0,Math.min(1,(t/255-e)/(i-e))),1/a),r=Math.min(3,Math.floor(4*s)),n=4*s-r,c=n*n,d=c*n,f=(2*d-3*c+1)*o[r]+(d-2*c+n)*h[r]/4+(-2*d+3*c)*o[r+1]+(d-c)*h[r+1]/4;l[t]=Math.round(255*Math.max(0,Math.min(1,f)))}return l}(t),i=t.curves;if(!e&&(!i||Object.values(i).every(t=>t.every(([t,e])=>t===e))))return null;const a=f(i?.rgb),s=[i?.red,i?.green,i?.blue].map(f),r=new Uint8Array(768);for(let t=0;t<256;t++)for(let i=0;i<3;i++)r[256*i+t]=s[i][a[e?e[t]:t]];return r}var X=class{constructor(t=0){this.amount=0,this.weights=new Float32Array(256),this.source=new Uint8ClampedArray(0),this.configure(t)}configure(t=0){const e=Math.max(0,Math.min(1,Number.isFinite(t)?t:0));if(e===this.amount)return;if(this.amount=e,0===e)return void(this.source=new Uint8ClampedArray(0));const i=8+24*e;for(let t=0;t<256;t++)this.weights[t]=Math.exp(-t*t/(2*i*i))}apply(t,e,i){if(!this.amount)return;if(!Number.isInteger(e)||!Number.isInteger(i)||e<1||i<1||e*i*4!==t.length)throw new Error("Denoise dimensions do not match the source.");this.source.length!==t.length&&(this.source=new Uint8ClampedArray(t.length));const a=this.source;a.set(t);for(let s=0;s<i;s++)for(let r=0;r<e;r++){const o=4*(s*e+r);if(!a[o+3])continue;const n=a[o],h=a[o+1],l=a[o+2];let c=0,d=0,f=0,m=0;for(let t=-1;t<=1;t++){const o=s+t;if(!(o<0||o>=i))for(let i=-1;i<=1;i++){const s=r+i;if(s<0||s>=e)continue;const u=4*(o*e+s);if(!a[u+3])continue;const p=Math.max(Math.abs(a[u]-n),Math.abs(a[u+1]-h),Math.abs(a[u+2]-l)),g=this.weights[p]*(0===i?1:.6)*(0===t?1:.6)*a[u+3];c+=a[u]*g,d+=a[u+1]*g,f+=a[u+2]*g,m+=g}}t[o]=n+(c/m-n)*this.amount,t[o+1]=h+(d/m-h)*this.amount,t[o+2]=l+(f/m-l)*this.amount}}},Y=new Set(["none","floyd-steinberg","atkinson","stucki","sierra","sierra-lite","burkes","jarvis"]);function q(t){return"dither"===t.style&&("shimmer"===t.dither.motion||"drift"===t.dither.motion&&t.dither.amount>0&&!Y.has(t.dither.algorithm))}function z(t){return"none"!==t.motion.type&&(t.motion.amount??1)>0}var B="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",W="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",G=new Uint16Array(4096);for(let t=0;t<G.length;t++)G[t]=B.indexOf(W[2*t])<<6|B.indexOf(W[2*t+1]);var j=(t,e)=>{const i=43758.5453*Math.sin(127.1*t+311.7*e);return i-Math.floor(i)};var H=new Map([2,4,8,16].map(t=>[t,Float64Array.from({length:t*t},(e,i)=>function(t,e,i){let a=0;for(let s=1;s<i;s*=2){const i=(Math.floor(t/s)%2+2)%2;a=4*a+[[0,2],[3,1]][(Math.floor(e/s)%2+2)%2][i]}return(a+.5)/(i*i)-.5}(i%t,Math.floor(i/t),t))])),V={"floyd-steinberg":[[1,0,7/16],[-1,1,3/16],[0,1,5/16],[1,1,1/16]],atkinson:[[1,0,.125],[2,0,.125],[-1,1,.125],[0,1,.125],[1,1,.125],[0,2,.125]],stucki:[[1,0,8/42],[2,0,4/42],[-2,1,2/42],[-1,1,4/42],[0,1,8/42],[1,1,4/42],[2,1,2/42],[-2,2,1/42],[-1,2,2/42],[0,2,4/42],[1,2,2/42],[2,2,1/42]],sierra:[[1,0,5/32],[2,0,3/32],[-2,1,2/32],[-1,1,4/32],[0,1,5/32],[1,1,4/32],[2,1,2/32],[-1,2,2/32],[0,2,3/32],[1,2,2/32]],"sierra-lite":[[1,0,.5],[-1,1,.25],[0,1,.25]],burkes:[[1,0,.25],[2,0,4/32],[-2,1,2/32],[-1,1,4/32],[0,1,.25],[1,1,4/32],[2,1,2/32]],jarvis:[[1,0,7/48],[2,0,5/48],[-2,1,3/48],[-1,1,5/48],[0,1,7/48],[1,1,5/48],[2,1,3/48],[-2,2,1/48],[-1,2,3/48],[0,2,5/48],[1,2,3/48],[2,2,1/48]]},K=t=>[parseInt(t.slice(1,3),16),parseInt(t.slice(3,5),16),parseInt(t.slice(5,7),16)];function J(t,e,i){const a=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)),s=Math.max(0,Math.min(1,(a-.035)/.105));return s*s*s*(s*(6*s-15)+10)}var Q=t=>["dissolve","silk","vortex","magnetic","scatter","etch","elastic","rake"].includes(t),Z=class{constructor(t,e){this.edgeSafe=!1,this.previous=null,this.peak=0,this.scatterDirections=null,this.springX=null,this.springY=null,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 a=0;a<t;a++)this.edge[i*t+a]=J(a/(t-1),i/(e-1),t/e);this.clear()}get active(){return this.peak>2e-4}setMode(t){if("elastic"!==t||this.springX||(this.springX=new Float32Array(this.ink.length),this.springY=new Float32Array(this.ink.length)),"scatter"===t&&!this.scatterDirections){const t=this.scatterDirections=new Float64Array(this.width*this.height*2);for(let e=0;e<this.height;e++)for(let i=0;i<this.width;i++){const a=43758.5453*Math.sin(127.1*i+311.7*e),s=(a-Math.floor(a))*Math.PI*2,r=2*(e*this.width+i);t[r]=.7*Math.cos(s),t[r+1]=.7*Math.sin(s)}}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,this.springX?.fill(0),this.springY?.fill(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 a=this.previous;this.previous={x:t,y:e};const s=this.width,r=this.height,o=Math.max(1,s/r),n=Math.max(1,r/s),h=a?(t-a.x)*o:0,l=a?(e-a.y)*n:0,c=Math.hypot(h,l);if(!a&&"dissolve"!==this.mode&&"etch"!==this.mode)return;if(a&&c<1e-4)return;const d=.035+.11*Math.max(.1,Math.min(1,i)),f=Math.min(128,Math.max(1,Math.ceil(c/(.45*d)))),m=c?h/c:1,u=c?l/c:0,p=Math.min(1,c/(d*f)*2.2);for(let i=0;i<f;i++){const h=(i+.5)/f,l=a?a.x+(t-a.x)*h:t,c=a?a.y+(e-a.y)*h:e,g=Math.max(0,Math.floor((l-2.5*d/o)*(s-1))),M=Math.min(s-1,Math.ceil((l+2.5*d/o)*(s-1))),x=Math.max(0,Math.floor((c-2.5*d/n)*(r-1))),v=Math.min(r-1,Math.ceil((c+2.5*d/n)*(r-1)));for(let t=x;t<=v;t++)for(let e=g;e<=M;e++){const i=(e/(s-1)-l)*o/d,a=(t/(r-1)-c)*n/d,h=Math.exp(1.5*-(i*i+a*a)),f=t*s+e;if("dissolve"===this.mode||"etch"===this.mode)this.ink[f]=Math.max(this.ink[f],h);else if("elastic"===this.mode)this.springX[f]=Math.max(-24,Math.min(24,this.springX[f]+m*h*p*8)),this.springY[f]=Math.max(-24,Math.min(24,this.springY[f]+u*h*p*8));else{const s=(-i*u+a*m)*h*2.8,r="rake"===this.mode?m*Math.sin(t*Math.PI/3)*h*2:"magnetic"===this.mode?-i*h*2.5:"scatter"===this.mode?(i+this.scatterDirections[2*f])*h*2:"silk"===this.mode?m*s:-a*h*2.5,o="rake"===this.mode?u*Math.sin(e*Math.PI/3)*h*2:"magnetic"===this.mode?-a*h*2.5:"scatter"===this.mode?(a+this.scatterDirections[2*f+1])*h*2:"silk"===this.mode?u*s:i*h*2.5;this.targetX[f]=Math.max(-1,Math.min(1,this.targetX[f]+r*p)),this.targetY[f]=Math.max(-1,Math.min(1,this.targetY[f]+o*p))}}}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),a=1-Math.exp(-22*e);let s=0;const r=Math.sqrt(336),o=Math.exp(-8*e),n=Math.cos(r*e),h=Math.sin(r*e)/r;for(let t=0;t<this.ink.length;t++)if("etch"===this.mode)this.ink[t]*=i,s=Math.max(s,this.ink[t]);else if("dissolve"===this.mode){this.ink[t]*=i,s=Math.max(s,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{if("elastic"===this.mode){const e=this.offsetX[t],i=this.offsetY[t],a=this.springX[t],r=this.springY[t];this.offsetX[t]=Math.max(-1,Math.min(1,o*(e*n+(a+8*e)*h))),this.offsetY[t]=Math.max(-1,Math.min(1,o*(i*n+(r+8*i)*h))),this.springX[t]=o*(a*n-(8*a+400*e)*h),this.springY[t]=o*(r*n-(8*r+400*i)*h),s=Math.max(s,.05*Math.abs(this.springX[t]),.05*Math.abs(this.springY[t]))}else this.targetX[t]*=i,this.targetY[t]*=i,this.offsetX[t]+=(this.targetX[t]-this.offsetX[t])*a,this.offsetY[t]+=(this.targetY[t]-this.offsetY[t])*a;s=Math.max(s,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.edgeSafe?this.edge[t]:1)*32767+32768),r=Math.round(this.offsetY[t]*(this.edgeSafe?this.edge[t]:1)*32767+32768);this.pixels[4*t]=e>>>8,this.pixels[4*t+1]=255&e,this.pixels[4*t+2]=r>>>8,this.pixels[4*t+3]=255&r}if("etch"===this.mode)for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++){const i=t*this.width+e,a=3*(this.ink[t*this.width+Math.max(0,e-1)]-this.ink[t*this.width+Math.min(this.width-1,e+1)]+this.ink[Math.max(0,t-1)*this.width+e]-this.ink[Math.min(this.height-1,t+1)*this.width+e]);this.offsetX[i]=Math.max(-1,Math.min(1,a))*(this.edgeSafe?this.edge[i]:1);const s=Math.round(32767*this.offsetX[i]+32768);this.pixels[4*i]=s>>>8,this.pixels[4*i+1]=255&s}this.peak=s,this.active||this.clear()}sample(t,e,i){const a=Math.max(0,Math.min(this.width-1.001,t*(this.width-1))),s=Math.max(0,Math.min(this.height-1.001,e*(this.height-1))),r=Math.floor(a),o=Math.floor(s),n=a-r,h=s-o,l=o*this.width+r,c=l+this.width,d=t=>(t[l]*(1-n)+t[l+1]*n)*(1-h)+(t[c]*(1-n)+t[c+1]*n)*h;if("etch"===this.mode)return i[0]=i[1]=0,void(i[2]=3*d(this.offsetX));i[0]=d(this.offsetX)*(this.edgeSafe?J(t,e,this.width/this.height):1)*.08,i[1]=d(this.offsetY)*(this.edgeSafe?J(t,e,this.width/this.height):1)*.08,i[2]="dissolve"===this.mode?6*-d(this.ink):0}},_=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 a=Math.max(1,this.width/this.height),s=Math.max(1,this.height/this.width);this.previous&&(Math.hypot((t-this.previous.x)*a,(e-this.previous.y)*s)<.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),a=Math.max(1,this.height/this.width);let s=0;for(const r of this.rings){const o=.015+r.age*(.15+.22*r.radius),n=.009+.014*r.radius,h=(Math.hypot((t-r.x)*i,(e-r.y)*a)-o)/n,l=Math.sin(Math.min(1,r.age/.07)*Math.PI/2)*Math.max(0,1-r.age/1.35)**2;s=Math.max(s,Math.exp(-h*h)*l)}return s}sample(t,e){const i=Math.max(0,Math.min(this.width-1,Math.round(t*(this.width-1)))),a=Math.max(0,Math.min(this.height-1,Math.round(e*(this.height-1))));return Math.max(this.ringSample(t,e),this.echo[a*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 a=0;for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++){const s=t*this.width+e;this.echo[s]=Math.max(this.ringSample(e/(this.width-1),t/(this.height-1)),this.echo[s]*i),a=Math.max(a,this.echo[s]);const r=Math.round(65535*this.echo[s]),o=4*s;this.pixels[o]=r>>>8,this.pixels[o+1]=255&r}this.echoPeak=a,this.active||(this.echo.fill(0),this.pixels.fill(0))}},$=class{constructor(t,e){this.previous=null,this.peak=0,this.width=t,this.height=e;const i=t*e;this.pixels=new Uint8Array(4*i),this.signal=new Float32Array(i),this.offsetX=new Float32Array(i),this.offsetY=new Float32Array(i),this.driftX=new Float32Array(i),this.driftY=new Float32Array(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.signal,this.pixels,this.offsetX,this.offsetY,this.driftX,this.driftY])t.fill(0);this.previous=null,this.peak=0}leave(){this.previous=null}move(t,e,i,a=performance.now()){if(!Number.isFinite(t+e+i+a))return;t=Math.max(0,Math.min(1,t)),e=Math.max(0,Math.min(1,e)),i=Math.max(.1,Math.min(1,i));const s=this.previous;if(this.previous={x:t,y:e,time:a},!s)return;const r=(t-s.x)*(this.width-1),o=(e-s.y)*(this.height-1),n=Math.hypot(r,o);if(n<.001)return;const h=Math.min(this.width,this.height),l=a>s.time?Math.max(1/240,(a-s.time)/1e3):1/60,c=Math.min(12,n/h/l),d=1-Math.exp(-c/2.2),f=h*(.022+.075*i)*(.65+.95*d),m=Math.min(128,Math.max(1,Math.ceil(n/(.4*f)))),u=n/f*(.32+.22*d)/m,p=r/n,g=o/n,M=-g,x=p,v=n*(2+18*d)/m;for(let i=0;i<m;i++){const a=(i+.5)/m,r=(s.x+(t-s.x)*a)*(this.width-1),o=(s.y+(e-s.y)*a)*(this.height-1),n=Math.max(1,Math.floor(r-3*f)),h=Math.min(this.width-2,Math.ceil(r+3*f)),l=Math.max(1,Math.floor(o-3*f)),c=Math.min(this.height-2,Math.ceil(o+3*f));for(let t=l;t<=c;t++)for(let e=n;e<=h;e++){const i=((e-r)*p+(t-o)*g)/f,a=((e-r)*M+(t-o)*x)/f,s=Math.exp(-i*i*.65-a*a*1.7),n=t*this.width+e;this.ink[n]=1-(1-this.ink[n])*Math.exp(-s*u);const h=1-a*a*.55,l=i*a*.7;this.u[n]=Math.max(-80,Math.min(80,this.u[n]+(p*h+M*l)*s*v)),this.v[n]=Math.max(-80,Math.min(80,this.v[n]+(g*h+x*l)*s*v))}}this.peak=1}read(t,e,i){const a=0|(e=Math.max(.5,Math.min(this.width-1.5,e))),s=0|(i=Math.max(.5,Math.min(this.height-1.5,i))),r=e-a,o=i-s,n=s*this.width+a;return(t[n]*(1-r)+t[n+1]*r)*(1-o)+(t[n+this.width]*(1-r)+t[n+this.width+1]*r)*o}sample(t,e){return this.read(this.signal,t*(this.width-1),e*(this.height-1))}displacement(t,e,i){i[0]=this.read(this.offsetX,t*(this.width-1),e*(this.height-1)),i[1]=this.read(this.offsetY,t*(this.width-1),e*(this.height-1))}step(t){if(!this.active||!Number.isFinite(t))return;let e=Math.max(0,Math.min(.05,t));const i=this.width,a=this.height;for(;e>1e-7;){const t=Math.min(1/60,e);e-=t;const s=Math.exp(-1.9*t),r=Math.exp(-3.2*t);for(let e=1;e<a-1;e++)for(let o=1;o<i-1;o++){const n=e*i+o,h=Math.max(.5,Math.min(i-1.5,o-this.u[n]*t)),l=Math.max(.5,Math.min(a-1.5,e-this.v[n]*t)),c=0|h,d=0|l,f=h-c,m=l-d,u=d*i+c,p=(1-f)*(1-m),g=f*(1-m),M=(1-f)*m,x=f*m;this.a[n]=(this.u[u]*p+this.u[u+1]*g+this.u[u+i]*M+this.u[u+i+1]*x)*s,this.b[n]=(this.v[u]*p+this.v[u+1]*g+this.v[u+i]*M+this.v[u+i+1]*x)*s,this.c[n]=(this.ink[u]*p+this.ink[u+1]*g+this.ink[u+i]*M+this.ink[u+i+1]*x)*r}[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<a-1;t++)for(let e=1;e<i-1;e++){const a=t*i+e;this.curl[a]=.5*(this.v[a+1]-this.v[a-1]-this.u[a+i]+this.u[a-i])}for(let e=1;e<a-1;e++)for(let a=1;a<i-1;a++){const s=e*i+a,r=Math.abs(this.curl[s+1])-Math.abs(this.curl[s-1]),o=Math.abs(this.curl[s+i])-Math.abs(this.curl[s-i]),n=Math.hypot(r,o)+1e-4,h=this.curl[s]*t*10,l=Math.hypot(this.u[s],this.v[s]);this.u[s]+=o/n*h,this.v[s]-=r/n*h;const c=Math.min(1,l/(Math.hypot(this.u[s],this.v[s])+1e-6));this.u[s]*=c,this.v[s]*=c,this.divergence[s]=-.5*(this.u[s+1]-this.u[s-1]+this.v[s+i]-this.v[s-i])}this.pressure.fill(0);for(let t=0;t<4;t++){for(let t=1;t<a-1;t++)for(let e=1;e<i-1;e++){const a=t*i+e;this.pressureNext[a]=.25*(this.divergence[a]+this.pressure[a-1]+this.pressure[a+1]+this.pressure[a-i]+this.pressure[a+i])}[this.pressure,this.pressureNext]=[this.pressureNext,this.pressure]}let o=0;for(let e=1;e<a-1;e++)for(let a=1;a<i-1;a++){const s=e*i+a;this.u[s]=Math.max(-80,Math.min(80,this.u[s]-.5*(this.pressure[s+1]-this.pressure[s-1]))),this.v[s]=Math.max(-80,Math.min(80,this.v[s]-.5*(this.pressure[s+i]-this.pressure[s-i]))),this.driftX[s]+=(3.6*this.u[s]-58*this.offsetX[s]-12*this.driftX[s])*t,this.driftY[s]+=(3.6*this.v[s]-58*this.offsetY[s]-12*this.driftY[s])*t,this.offsetX[s]=Math.max(-2,Math.min(2,this.offsetX[s]+this.driftX[s]*t)),this.offsetY[s]=Math.max(-2,Math.min(2,this.offsetY[s]+this.driftY[s]*t)),this.signal[s]=1-Math.exp(.06*-Math.hypot(this.u[s],this.v[s])-.16*this.ink[s]),o=Math.max(o,this.signal[s])}this.peak=o}if(this.active)for(let t=0;t<this.ink.length;t++){const e=Math.round(65535*Math.min(1,this.signal[t]));this.pixels[4*t]=e>>>8,this.pixels[4*t+1]=255&e,this.pixels[4*t+2]=Math.round(128+63.5*this.offsetX[t]),this.pixels[4*t+3]=Math.round(128+63.5*this.offsetY[t])}else this.clear()}};function tt(t,e){const i=Math.max(0,Math.min(1,e/.38));return t+(1-2*t)*(i*i*(3-2*i))}var et=(t,e)=>"water"===t?30*e/.55:"silk"===t?28*e:"vortex"===t?38*e:["magnetic","scatter","elastic","rake"].includes(t)?32*e:0,it=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]=J(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 $(this.columns,this.rows),this.contour=new _(this.columns,this.rows),this.afterimage=new Z(this.columns,this.rows),this.clear()}get invertsDensity(){return"trail"===this.mode}get densityTrail(){return["trail","contour","dissolve","etch"].includes(this.mode)}get hasRefraction(){return this.active||this.lensStrength>15e-5}get active(){return Q(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,Q(t)&&this.afterimage.setMode(t),this.refraction.pixels="trail"===t?this.trail.pixels:"contour"===t?this.contour.pixels:Q(t)?this.afterimage.pixels:this.waterPixels,this.refraction.strength=et(t,this.amount))}configure(t,e=.55,i=.2,a=!1){this.setMode(t),this.refraction.edgeSafe=a,this.afterimage.edgeSafe=a,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=et(t,this.amount),this.refraction.focus[2]=this.densityTrail?this.amount:this.lensStrength*this.amount,this.refraction.focus[3]=this.radius}move(t,e,i){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)),Q(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,i);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 a=this.previous;this.previous={x:t,y:e};const s=(t-a.x)*this.xScale,r=(e-a.y)*this.yScale,o=Math.hypot(s,r);if(o<1e-5)return;const n=.035+.1*this.radius,h=3*n,l=Math.min(192,Math.max(1,Math.ceil(o/(.5*n)))),c=95*Math.min(o,1)/l;for(let i=0;i<l;i++){const s=(i+.5)/l,r=a.x+(t-a.x)*s,o=a.y+(e-a.y)*s,d=Math.max(1,Math.floor((r-h/this.xScale)*(this.columns-1))),f=Math.min(this.columns-2,Math.ceil((r+h/this.xScale)*(this.columns-1))),m=Math.max(1,Math.floor((o-h/this.yScale)*(this.rows-1))),u=Math.min(this.rows-2,Math.ceil((o+h/this.yScale)*(this.rows-1)));for(let t=m;t<=u;t++)for(let e=d;e<=f;e++){const i=(e/(this.columns-1)-r)*this.xScale,a=(t/(this.rows-1)-o)*this.yScale,s=Math.exp(-(i*i+a*a)/(n*n))*c,h=t*this.columns+e;this.velocity[h]=Math.max(-12,this.velocity[h]-s)}}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(Q(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),a=.3*Math.min(this.columns,this.rows);for(;this.remainder+1e-8>=e;){this.remainder-=e;let t=0;for(let s=1;s<this.rows-1;s++)for(let r=1;r<this.columns-1;r++){const o=s*this.columns+r,n=this.heights[o],h=this.heights[o-1]+this.heights[o+1]+this.heights[o-this.columns]+this.heights[o+this.columns]-4*n,l=Math.min(r,s,this.columns-1-r,this.rows-1-s),c=l<5?.88+.024*l:1,d=(this.velocity[o]+(h*a*a-8*n)*e)*i*c;this.velocity[o]=d,this.next[o]=(n+d*e)*c,t=Math.max(t,Math.abs(this.next[o]),.1*Math.abs(d))}this.heights.set(this.next),this.energy=t,this.pending=!1}if(!this.active)return void this.clear();const s=.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,a=(this.heights[t*this.columns+Math.max(0,e-1)]-this.heights[t*this.columns+Math.min(this.columns-1,e+1)])*s,r=(this.heights[Math.max(0,t-1)*this.columns+e]-this.heights[Math.min(this.rows-1,t+1)*this.columns+e])*s,o=Math.tanh(a)*(this.refraction.edgeSafe?this.edgeMask[i]:1),n=Math.tanh(r)*(this.refraction.edgeSafe?this.edgeMask[i]:1);this.normals[2*i]=o,this.normals[2*i+1]=n;const h=Math.round(32767*o+32768),l=Math.round(32767*n+32768);this.refraction.pixels[4*i]=h>>>8,this.refraction.pixels[4*i+1]=255&h,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),a=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)*a,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(Q(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 a=Math.max(0,Math.min(this.columns-1.001,t*(this.columns-1))),s=Math.max(0,Math.min(this.rows-1.001,e*(this.rows-1))),r=Math.floor(a),o=Math.floor(s),n=a-r,h=s-o,l=2*(o*this.columns+r),c=l+2*this.columns;for(let t=0;t<2;t++)i[t]=.08*((this.normals[l+t]*(1-n)+this.normals[l+2+t]*n)*(1-h)+(this.normals[c+t]*(1-n)+this.normals[c+2+t]*n)*h);i[0]*=this.amount/.55,i[1]*=this.amount/.55,i[2]="light"===this.mode||"scan"===this.mode?function(t,e,i,a){const[s,r,o,n]=i.focus,h=(t-s)*Math.max(1,a)/n,l=(e-r)*Math.max(1,1/a)/n;return"light"===i.mode?Math.exp(-3*(h*h+l*l))*o:"scan"===i.mode?(1.3*Math.exp(-h*h*110)-.3*Math.exp(-h*h*12))*Math.exp(-l*l*1.8)*o:0}(t,e,this.refraction,this.xScale/this.yScale):0}};function at(t){return"videoWidth"in t?[t.videoWidth,t.videoHeight]:"naturalWidth"in t?[t.naturalWidth,t.naturalHeight]:[t.width,t.height]}var st=(t=!1)=>{const e=document.createElement("canvas"),i=e.getContext("2d",{willReadFrequently:t});if(!i)throw new Error("Canvas 2D is unavailable.");return{canvas:e,ctx:i}},rt=(t,e,i)=>{t.width===e&&t.height===i||(t.width=e,t.height=i)},ot={blocks:" ░▒▓█",braille:" ⠁⠃⠇⡇⣇⣧⣷⣿",lines:" -═╪╬",cross:" ·+xX#",diagonal:" /╱╳",diamond:" ·◇◈◆",mixed:" .:+/◇#@"};function nt(t,e={},i={}){const a=t.getContext("2d");if(!a)throw new Error("Canvas is already owned by another renderer.");const s=st(),r=st(!0),h=st(),l=st(),c=st(),d=st(),f=st(),u=st(),p=st(),g=st();let M,x=0,v=P(e),w=0,y="",S="",A="",E=new Uint8ClampedArray(0),T=new Uint8ClampedArray(0),F=0,I=0,C=0,L=null,U="",N=new it,Y=0;const B=[0,0,0],W=[0,0,0,1],J=[0,0,0,0];let Q=O(v.color);const Z=new X(v.color.denoise),_=new b(v.warps,v.warpEdge),$=Math.max(64,Math.min(4096,Number.isFinite(i.maxDimension)?i.maxDimension:960)),et=Math.max(256,Math.min(1048576,Number.isFinite(i.maxCells)?i.maxCells:12e3));let nt=et,ht=Math.max(.1,Math.min(8,i.pixelRatio??1));return{canvas:t,render:function(e,i=0,b=960,P=540,O=i*v.motion.speed){if(Number.isFinite(i)||(i=0),!Number.isFinite(b)||!Number.isFinite(P)||b<1||P<1)throw new Error("Render dimensions must be positive finite numbers.");const[X,et]=at(e);if(!X||!et)return;const st=Math.min(1,$/Math.max(b,P)),lt=Math.max(2,Math.round(b*st)),ct=Math.max(2,Math.round(P*st));rt(t,lt,ct),rt(s.canvas,lt,ct),rt(h.canvas,lt,ct),rt(l.canvas,lt,ct),rt(c.canvas,lt,ct),Y!==lt/ct&&(Y=lt/ct,N=new it(Y)),N.configure(v.hover.effect,v.hover.strength,v.hover.radius,v.hover.edgeSafe),N.step(Math.max(0,Math.min(.05,i-C))),C=i;const dt="currentTime"in e?e.getVideoPlaybackQuality?.().totalVideoFrames??e.currentTime:0,ft=[w,lt,ct,dt].join(":"),mt="dither"===v.style,ut=D(lt,ct,v,nt,ht),pt=ut.cell,gt=ut.rowHeight,Mt=ut.columns,xt=ut.rows;if(y!==ft||L!==e||F!==Mt||I!==xt){L=e,y=ft,S="",A="",F=Mt,I=xt,s.ctx.clearRect(0,0,lt,ct),s.ctx.save();const t=R(X,et,lt,ct,v.crop);s.ctx.translate(t.x+t.width/2,t.y+t.height/2),s.ctx.rotate(v.crop.rotation*Math.PI/180),s.ctx.drawImage(e,-X*t.scale/2,-et*t.scale/2,X*t.scale,et*t.scale),s.ctx.restore(),rt(r.canvas,F,I),r.ctx.clearRect(0,0,F,I),r.ctx.drawImage(s.canvas,0,0,F,I),E=r.ctx.getImageData(0,0,F,I).data,Z.apply(E,F,I);const i=v.color;for(let t=0;t<E.length;t+=4){const e=.299*E[t]+.587*E[t+1]+.114*E[t+2];for(let a=0;a<3;a++){const s=e+(E[t+a]-e)*i.saturation;E[t+a]=((s*(1-i.grayscale)+e*i.grayscale)/255-.5)*i.contrast*255+127.5+255*i.brightness}}Q&&function(t,e){for(let i=0;i<t.length;i+=4)t[i+3]&&(t[i]=e[t[i]],t[i+1]=e[256+t[i+1]],t[i+2]=e[512+t[i+2]])}(E,Q),E=_.apply(E,F,I,lt/ct)}const vt=z(v),bt=q(v),wt=!N.active&&!vt&&!bt,yt=[ft,F,I,pt,gt,ht].join(":");if(!wt||A!==yt){h.ctx.clearRect(0,0,lt,ct),h.ctx.globalAlpha=1,h.ctx.globalCompositeOperation="source-over";const t=O,e=vt?v.motion.type:"none",a=["none","caustics","sheen","grain","trace"].includes(e);if(mt){const a=wt;if(!a||S!==ft){T.length!==E.length&&(T=new Uint8ClampedArray(E.length));const s=T;if(s.set(E),N.active||"none"!==e)for(let i=0;i<I;i++)for(let a=0;a<F;a++){const r=a/F,h=i/I;let l=a,c=i,d=0,f=1,u=1;N.active&&(N.sample(r,h,B),l-=B[0]*F,c-=B[1]*I,d=B[2]/3);const p=4*(i*F+a);o(e,r,h,t,W,(.299*E[p]+.587*E[p+1]+.114*E[p+2])/255),n(W,v.motion.amount??1),l-=W[0]/960*F,c-=W[1]/960*I,f=1+W[2],u=W[3];const g=4*(i*F+a);m(E,F,I,l,c,J);for(let t=0;t<3;t++){const e=J[t]/255;let i=(["trail","contour"].includes(v.hover.effect)?tt(e,d):"etch"===v.hover.effect?Math.max(0,Math.min(1,e+.35*d)):"dissolve"===v.hover.effect?e*Math.max(0,1+d):e)*f;s[g+t]=255*i}s[g+3]=J[3]*u}!function(t,e,i,a,s=0){const{algorithm:r,amount:o,threshold:n}=a,h="blue-noise"===r,l=r.startsWith("bayer")?Number(r.slice(5)):0,c=H.get(l),d=l-1,f="luminance"===a.colorSpace,m=("custom"===a.palette?a.colors:k[a.palette]??k.mono).map(K),u=V[r],p=u?new Float32Array(3*e*3):null,g="drift"===a.motion?s*a.speed*3:0,M=(a.direction??45)*Math.PI/180,x=Math.round(Math.cos(M)*g),v=Math.round(Math.sin(M)*g),b=(t,e)=>(t%e+e)%e,w=m.map(t=>.299*t[0]+.587*t[1]+.114*t[2]),y="shimmer"===a.motion?.15*Math.sin(s*a.speed*2):0;for(let a=0;a<i;a++)for(let s=0;s<e;s++){const M=4*(a*e+s),S=3*(a%3*e+s);if(0===t[M+3]){p&&(p[S]=p[S+1]=p[S+2]=0);continue}let k=0;const A=h?(G[64*(a-v&63)+(s-x&63)]+.5)/G.length:0;c?k=c[(a-v&d)*l+(s-x&d)]:"noise"===r?k=j(s-x,a-v)-.5:"lines"===r?k=b(a-v,4)/3-.5:"vertical-lines"===r?k=b(s-x,4)/3-.5:"diagonal-lines"===r?k=b(s-x+a-v,4)/3-.5:"radial"===r?k=b(Math.hypot(s-e/2,a-i/2)-g,6)/6-.5:"halftone"===r&&(k=Math.hypot(b(s-x,6)-2.5,b(a-v,6)-2.5)/3.54-.5);const E=128*(k*o+y+(.5-n)),T=t[M]+E+(p?.[S]??0),F=t[M+1]+E+(p?.[S+1]??0),I=t[M+2]+E+(p?.[S+2]??0);let P=0,R=0,C=0;if(m.length){let t=1/0,e=1/0,i=0,a=0;const s=.299*T+.587*F+.114*I;for(let r=0;r<m.length;r++){const o=m[r],n=f?(s-w[r])**2:(T-o[0])**2*.299+(F-o[1])**2*.587+(I-o[2])**2*.114;n<t?(h&&(e=t,a=i,i=r),t=n,[P,R,C]=o):h&&n<e&&(e=n,a=r)}if(h&&o>0&&Number.isFinite(e)){const t=m[a],e=t[0]-P,r=t[1]-R,n=t[2]-C,h=w[a]-w[i],l=f?h*h:e*e*.299+r*r*.587+n*n*.114,c=f?(s-w[i])*h:(T-P)*e*.299+(F-R)*r*.587+(I-C)*n*.114;A<(l?Math.max(0,Math.min(1,c/l*o)):0)&&([P,R,C]=t)}}else if(h){const t=Math.max(0,Math.min(1,.5+(A-.5)*o));P=51*Math.floor(T/51+1-t),R=51*Math.floor(F/51+1-t),C=51*Math.floor(I/51+1-t)}else P=51*Math.round(T/51),R=51*Math.round(F/51),C=51*Math.round(I/51);if(t[M]=P,t[M+1]=R,t[M+2]=C,p&&u){p[S]=p[S+1]=p[S+2]=0;for(const[t,r,n]of u){const h=s+t;if(h<0||h>=e||a+r>=i)continue;const l=3*((a+r)%3*e+h);p[l]+=(T-P)*n*o,p[l+1]+=(F-R)*n*o,p[l+2]+=(I-C)*n*o}}}}(s,F,I,v.dither,i),r.ctx.putImageData(new ImageData(s,F,I),0,0),S=a?ft:""}h.ctx.imageSmoothingEnabled=!1,h.ctx.drawImage(r.canvas,0,0,lt,ct)}else{const i=Array.from(ot[v.style]??v.charset),s=h.ctx,r=K(v.ink),l="ascii"===v.style||!!ot[v.style],c=Math.max(3,Math.round(.92*gt)),d=Math.ceil(pt+4),u=Math.ceil(gt+4),p=[i.join(""),c,d,u,v.ink,v.colorMode].join(":");if(l&&p!==U&&(U=p,rt(f.canvas,d*i.length,u),f.ctx.clearRect(0,0,f.canvas.width,u),f.ctx.font=`${c}px monospace`,f.ctx.textBaseline="middle",f.ctx.textAlign="center",f.ctx.fillStyle="accent"===v.colorMode?v.ink:"#ffffff",i.forEach((t,e)=>f.ctx.fillText(t,e*d+d/2,u/2))),"lego"===v.style&&x!==pt){x=pt,rt(g.canvas,Math.ceil(pt),Math.ceil(gt));const t=g.ctx;t.clearRect(0,0,g.canvas.width,g.canvas.height),t.fillStyle="rgba(255,255,255,.2)",t.strokeStyle="rgba(0,0,0,.25)",t.lineWidth=Math.max(.5,.6*ht),t.beginPath(),t.arc(pt/2,gt/2,.28*pt,0,2*Math.PI),t.fill(),t.stroke()}s.font=`${c}px monospace`,s.textBaseline="middle",s.textAlign="center";for(let h=0;h<I;h++)for(let c=0;c<F;c++){let p=c,M=h,x=0;if(N.active&&(N.sample(c/F,h/I,B),p=Math.max(0,Math.min(F-1,c-B[0]*F)),M=Math.max(0,Math.min(I-1,h-B[1]*I)),x=B[2]/3),m(E,F,I,p,M,J),!J[3])continue;const b=J[0],w=J[1],y=J[2],S=(.299*b+.587*w+.114*y)/255;let k=S;["trail","contour"].includes(v.hover.effect)&&x?k=tt(k,x):"etch"===v.hover.effect?k=Math.max(0,Math.min(1,k+.35*x)):"dissolve"===v.hover.effect&&(k*=Math.max(0,1+x));let A=c*pt,T=h*gt,P=1;o(e,c/F,h/I,t,W,S),n(W,v.motion.amount??1),A+=W[0]*lt/960,T+=W[1]*ct/960,k=Math.max(0,Math.min(1,k+W[2])),P=W[3]*J[3]/255,l||"accent"!==v.colorMode||"cmyk"===v.style||(P*=k),s.globalAlpha=P;const R=255*(k-S),C="source"===v.colorMode?`rgb(${b+R},${w+R},${y+R})`:"gray"===v.colorMode?`rgb(${Math.round(255*k)},${Math.round(255*k)},${Math.round(255*k)})`:v.ink;if(s.fillStyle=C,l){const t=Math.max(0,Math.min(i.length-1,Math.round(k*(i.length-1))));"accent"===v.colorMode?s.drawImage(f.canvas,t*d,0,d,u,a?Math.round(A+(pt-d)/2):A+(pt-d)/2,a?Math.round(T+(gt-u)/2):T+(gt-u)/2,d,u):s.fillText(i[t],A+pt/2,T+gt/2)}else if("dots"===v.style)s.beginPath(),s.arc(A+pt/2,T+gt/2,.48*pt*Math.sqrt(k),0,2*Math.PI),s.fill();else if("led"===v.style)s.beginPath(),s.arc(A+pt/2,T+gt/2,.39*pt,0,2*Math.PI),s.fill(),s.globalAlpha=.35*P,s.fillStyle="#ffffff",s.beginPath(),s.arc(A+.43*pt,T+.4*gt,.11*pt,0,2*Math.PI),s.fill();else if("hex"===v.style){const t=A+pt/2,e=T+gt/2;s.beginPath();for(let i=0;i<6;i++){const a=Math.PI/3*i,r=t+Math.cos(a)*pt*.49,o=e+Math.sin(a)*gt*.49;0===i?s.moveTo(r,o):s.lineTo(r,o)}s.closePath(),s.fill()}else if("cmyk"===v.style){s.fillStyle="#ffffff",s.fillRect(A,T,pt,gt);const t=(t,e)=>Math.max(0,Math.min(255,"source"===v.colorMode?t+R:"gray"===v.colorMode?255*k:e*k)),e=t(b,r[0]),i=t(w,r[1]),a=t(y,r[2]),o=1-Math.max(e,i,a)/255,n=Math.max(.001,1-o),h=[["#00ffff",(1-e/255-o)/n,.36,.36],["#ff00ff",(1-i/255-o)/n,.64,.36],["#ffff00",(1-a/255-o)/n,.5,.66],["#000000",o,.5,.5]];s.globalCompositeOperation="multiply";for(const[t,e,i,a]of h)s.fillStyle=t,s.beginPath(),s.arc(A+pt*i,T+gt*a,.48*pt*Math.sqrt(Math.max(0,e)),0,2*Math.PI),s.fill();s.globalCompositeOperation="source-over"}else if("voxel"===v.style){const t=A+pt/2,e=T+gt/2;s.beginPath(),s.moveTo(t,T),s.lineTo(A+pt,T+.25*gt),s.lineTo(t,e),s.lineTo(A,T+.25*gt),s.closePath(),s.fill(),s.globalAlpha=.72*P,s.beginPath(),s.moveTo(A,T+.25*gt),s.lineTo(t,e),s.lineTo(t,T+gt),s.lineTo(A,T+.75*gt),s.closePath(),s.fill(),s.globalAlpha=.42*P,s.beginPath(),s.moveTo(t,e),s.lineTo(A+pt,T+.25*gt),s.lineTo(A+pt,T+.75*gt),s.lineTo(t,T+gt),s.closePath(),s.fill()}else{const t="pixel"===v.style?0:Math.max(.5,.06*pt);s.fillRect(A,T,pt-t,gt-t),"lego"===v.style&&s.drawImage(g.canvas,A,T),"disco"===v.style&&(s.fillStyle=`rgba(255,255,255,${.1+.25*j(c,h)})`,s.fillRect(A,T,pt-t,.35*gt),s.fillStyle="rgba(0,0,0,.25)",s.fillRect(A,T+.65*gt,pt-t,.35*gt-t))}}}h.ctx.globalAlpha=1,(v.color.amount||v.lights.length)&&(rt(u.canvas,lt,ct),u.ctx.clearRect(0,0,lt,ct),u.ctx.drawImage(h.canvas,0,0)),v.color.amount&&(h.ctx.save(),h.ctx.globalCompositeOperation=v.color.blend,h.ctx.globalAlpha=v.color.amount,h.ctx.fillStyle=v.color.tint,h.ctx.fillRect(0,0,lt,ct),h.ctx.restore());for(const t of v.lights){const e=t.radius*Math.max(lt,ct),i=h.ctx.createRadialGradient(t.x*lt,t.y*ct,0,t.x*lt,t.y*ct,e);i.addColorStop(0,t.color),i.addColorStop(1,"transparent"),h.ctx.save(),h.ctx.globalCompositeOperation="screen",h.ctx.globalAlpha=t.intensity,h.ctx.fillStyle=i,h.ctx.fillRect(0,0,lt,ct),h.ctx.restore()}if((v.color.amount||v.lights.length)&&(h.ctx.globalCompositeOperation="destination-in",h.ctx.drawImage(u.canvas,0,0),h.ctx.globalCompositeOperation="source-over"),v.mask.enabled&&v.mask.shapes.length){const t=c.ctx;t.clearRect(0,0,lt,ct),t.fillStyle="#fff",t.strokeStyle="#fff",t.lineCap="round",t.lineJoin="round";for(const e of v.mask.shapes){if(t.beginPath(),"ellipse"===e.kind)t.ellipse((e.x+e.width/2)*lt,(e.y+e.height/2)*ct,e.width*lt/2,e.height*ct/2,0,0,2*Math.PI);else{if("rectangle"!==e.kind){if(t.lineWidth=(e.size??.05)*lt,1===e.points?.length){t.arc(e.points[0][0]*lt,e.points[0][1]*ct,t.lineWidth/2,0,2*Math.PI),t.fill();continue}e.points?.forEach(([e,i],a)=>a?t.lineTo(e*lt,i*ct):t.moveTo(e*lt,i*ct)),t.stroke();continue}t.rect(e.x*lt,e.y*ct,e.width*lt,e.height*ct)}t.fill()}h.ctx.globalCompositeOperation=v.mask.invert?"destination-out":"destination-in",h.ctx.drawImage(c.canvas,0,0),h.ctx.globalCompositeOperation="source-over"}const M=l.ctx;M.clearRect(0,0,lt,ct),M.globalAlpha=v.backdrop.opacity;const b=v.backdrop;if("solid"===b.mode&&(M.fillStyle=b.color,M.fillRect(0,0,lt,ct)),"gradient"===b.mode){const t=M.createLinearGradient(0,0,lt,ct);t.addColorStop(0,b.color),t.addColorStop(1,b.color2),M.fillStyle=t,M.fillRect(0,0,lt,ct)}if("source"===b.mode&&M.drawImage(s.canvas,0,0),"blurred"===b.mode){const t=Math.max(1,b.blur);rt(d.canvas,Math.max(2,Math.round(lt/t)),Math.max(2,Math.round(ct/t))),d.ctx.drawImage(s.canvas,0,0,d.canvas.width,d.canvas.height),M.imageSmoothingEnabled=!0,M.drawImage(d.canvas,0,0,lt,ct)}M.globalAlpha=1,v.effects.characterBloom>0&&(rt(p.canvas,Math.max(2,Math.round(lt/3)),Math.max(2,Math.round(ct/3))),p.ctx.clearRect(0,0,p.canvas.width,p.canvas.height),p.ctx.drawImage(h.canvas,0,0,p.canvas.width,p.canvas.height),M.save(),M.globalAlpha=.8*v.effects.characterBloom,M.globalCompositeOperation="screen",M.filter=`blur(${1+4*v.effects.characterBloom}px)`,M.drawImage(p.canvas,0,0,lt,ct),M.restore()),M.drawImage(h.canvas,0,0),A=wt?yt:""}const St=Object.entries(v.effects).some(([t,e])=>!["angle","focus","blurType","characterBloom"].includes(t)&&"number"==typeof e&&e>0);a.clearRect(0,0,lt,ct),St?(void 0===M&&(M=function(){const t=document.createElement("canvas"),e=t.getContext("webgl",{alpha:!0,premultipliedAlpha:!1,antialias:!1,preserveDrawingBuffer:!0});if(!e)return null;const i=[],a=(t,a)=>{const s=e.createShader(t);if(i.push(s),e.shaderSource(s,a),e.compileShader(s),!e.getShaderParameter(s,e.COMPILE_STATUS))throw new Error(e.getShaderInfoLog(s)||"Finish shader failed");return s},s=e.createProgram();if(e.attachShader(s,a(e.VERTEX_SHADER,"attribute vec2 p;varying vec2 uv;void main(){uv=(p+1.)*.5;gl_Position=vec4(p,0.,1.);}")),e.attachShader(s,a(e.FRAGMENT_SHADER,"precision mediump float;varying vec2 uv;uniform sampler2D src;uniform vec2 size;uniform float t,bloom,grain,dust,scanlines,crt,prism,vignette,glitch,pixelate,blur,blurMode,angle,focus,halftone,rgbSplit,sharpen;\n float hash(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}\n vec4 sampleAt(vec2 p){if(min(min(p.x,p.y),min(1.-p.x,1.-p.y))<0.)return vec4(0.);return texture2D(src,vec2(p.x,1.-p.y));}\n void main(){vec2 q=uv,c=q-.5;q=c*(1.+dot(c,c)*crt*.25)+.5;\n if(glitch>0.)q.x+=(hash(vec2(floor(q.y*35.),floor(t*5.)))-.5)*.07*glitch*step(.82,hash(vec2(floor(q.y*35.),floor(t*5.)+3.)));\n if(pixelate>0.){vec2 grid=size/(1.+pixelate*20.);q=(floor(q*grid)+.5)/grid;}\n vec4 base=sampleAt(q);float edge=smoothstep(.12,.65,length(c));\n vec2 shift=vec2((prism*3.*edge+rgbSplit*8.)/size.x,prism*edge/size.y);\n if(prism>0.||rgbSplit>0.)base.rgb=vec3(sampleAt(q+shift).r,base.g,sampleAt(q-shift).b);\n vec2 dir=vec2(cos(angle),sin(angle))/size;float amount=blur;\n if(blurMode>1.5&&blurMode<2.5){dir=normalize(c+vec2(.0001))/size;amount*=length(c)*2.;}\n if(blurMode>2.5)amount*=smoothstep(.05,.5,abs(q.y-focus));\n vec4 blurred=base;\n if(amount>0.){blurred=base*.2;for(int i=1;i<=4;i++){float f=float(i)*amount*.35;vec2 off=dir*f;if(blurMode<.5)off=vec2(cos(float(i)*1.57),sin(float(i)*1.57))*amount/size;blurred+=sampleAt(q+off)*.1+sampleAt(q-off)*.1;}}\n vec3 light=vec3(0.);if(bloom>0.)for(int i=0;i<4;i++){float a=float(i)*1.5708;vec3 s=sampleAt(q+vec2(cos(a),sin(a))*6./size).rgb;light+=max(vec3(0.),s-.35)*.25;}\n vec3 col=blurred.rgb+light*bloom;\n if(sharpen>0.){vec2 px=1./size;vec3 near=sampleAt(q+vec2(px.x,0.)).rgb+sampleAt(q-vec2(px.x,0.)).rgb+sampleAt(q+vec2(0.,px.y)).rgb+sampleAt(q-vec2(0.,px.y)).rgb;col+=(base.rgb*4.-near)*sharpen*.5;}\ncol*=1.-scanlines*.4*(.5+.5*cos(q.y*size.y*3.14159));\n col*=1.-vignette*smoothstep(.15,.72,length(c));\n col+=(hash(floor(q*size)+floor(t*12.))-.5)*grain*.2;\n if(dust>0.)col+=step(1.-dust*.002,hash(floor(q*size*.25)+floor(t*2.)))*.4;\n if(halftone>0.)col*=mix(1.,smoothstep(.1,.65,length(fract(q*size/6.)-.5)),halftone);\n gl_FragColor=vec4(clamp(col,0.,1.),blurred.a);}")),e.linkProgram(s),!e.getProgramParameter(s,e.LINK_STATUS))throw new Error("Finish link failed");e.useProgram(s);const r=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,r),e.bufferData(e.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),e.STATIC_DRAW);const o=e.getAttribLocation(s,"p");e.enableVertexAttribArray(o),e.vertexAttribPointer(o,2,e.FLOAT,!1,0,0);const n=e.createTexture();e.bindTexture(e.TEXTURE_2D,n),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE);const h=["t","bloom","grain","dust","scanlines","crt","prism","rgbSplit","sharpen","vignette","glitch","pixelate","blur","blurMode","angle","focus","halftone"],l=Object.fromEntries(h.map(t=>[t,e.getUniformLocation(s,t)])),c=e.getUniformLocation(s,"size");return{canvas:t,render(i,a,r,o=1){t.width===i.width&&t.height===i.height||(t.width=i.width,t.height=i.height,e.viewport(0,0,t.width,t.height)),e.useProgram(s),e.bindTexture(e.TEXTURE_2D,n),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,i),e.uniform2f(c,t.width/o,t.height/o);for(const t of h)e.uniform1f(l[t],"t"===t?r:"blurMode"===t?["gaussian","directional","radial","progressive"].indexOf(a.blurType):"angle"===t?a.angle*Math.PI/180:a[t]??0);return e.drawArrays(e.TRIANGLE_STRIP,0,4),t},destroy(){e.deleteTexture(n),e.deleteBuffer(r),e.deleteProgram(s),i.forEach(t=>e.deleteShader(t)),t.width=t.height=1,e.getExtension("WEBGL_lose_context")?.loseContext()}}}()),M?a.drawImage(M.render(l.canvas,v.effects,i,ht),0,0):a.drawImage(l.canvas,0,0),t.dataset.studioFinish=M?"gpu":"unavailable"):(a.drawImage(l.canvas,0,0),t.dataset.studioFinish="none")},setPixelRatio(t){ht=Math.max(.1,Math.min(8,Number.isFinite(t)?t:1))},get pixelRatio(){return ht},setBudget(t){nt=Math.max(256,Math.min(et,Number.isFinite(t)?Math.round(t):et))},get maxCells(){return nt},configure(t){v=P(t),Q=O(v.color),Z.configure(v.color.denoise),_.configure(v.warps,v.warpEdge),w++},pointer:(t,e,i)=>{N.configure(v.hover.effect,v.hover.strength,v.hover.radius,v.hover.edgeSafe),N.move(t,e,i)},leave(){N.leave()},get active(){return N.active},get settings(){return P(v)},get capabilities(){return{gpuFinish:null!==M}},invalidate(){y=""},destroy(){M?.destroy(),_.clear(),Z.configure(0);for(const t of[s,r,h,l,c,d,f,u,p,g])t.canvas.width=t.canvas.height=1;L=null,E=new Uint8ClampedArray(0),T=new Uint8ClampedArray(0)}}}function ht(t,e,i){return new Promise((a,s)=>{const r=()=>{l(),a()},o=()=>{l(),s(new Error("Unable to load this media. Check its format and cross-origin permissions."))},n=()=>{l(),s(new DOMException("Cancelled","AbortError"))},h=setTimeout(o,2e4),l=()=>{clearTimeout(h),t.removeEventListener(e,r),t.removeEventListener("error",o),i?.removeEventListener("abort",n)};t.addEventListener(e,r,{once:!0}),t.addEventListener("error",o,{once:!0}),i?.addEventListener("abort",n,{once:!0}),i?.aborted&&n()})}async function lt(t,e){if("string"==typeof t&&t.startsWith("blob:")){const i=await fetch(t,{signal:e}),a=await i.blob();return lt(new File([a],"Imported media",{type:a.type}),e)}const i="string"!=typeof t,a=i?t.name:t;if(i?"image/gif"===t.type:/\.gif(?:[?#]|$)/i.test(a)){const a=await import("gifuct-js"),{parseGIF:s,decompressFrames:r}="function"==typeof a.parseGIF?a:a.default,o=i?await t.arrayBuffer():await fetch(t,{signal:e}).then(t=>{if(!t.ok)throw new Error("GIF download failed.");return t.arrayBuffer()});if(e?.aborted)throw new DOMException("Cancelled","AbortError");const n=s(o),h=n.lsd.width,l=n.lsd.height;if(h*l>4e6)throw new Error("GIF is too large. Use a smaller GIF or an MP4.");const c=n.frames.filter(t=>"image"in t).length;if(!c||c*h*l*4>128e6)throw new Error("GIF exceeds the decoded memory budget. Use MP4 for long animations.");const d=r(n,!0);if(d.length*h*l*4>128e6)throw new Error("GIF exceeds the 128 MB decoded budget. Use MP4 for long animations.");const f=document.createElement("canvas");f.width=h,f.height=l;const m=f.getContext("2d"),u=document.createElement("canvas"),p=u.getContext("2d"),g=d.reduce((t,e)=>t+Math.max(20,e.delay),0)/1e3;let M=-1,x=null;const v=t=>{const e=(t%g+g)%g*1e3;let i=0,a=0;for(;a<d.length-1&&(i+=Math.max(20,d[a].delay),!(e<i));a++);a<M&&(m.clearRect(0,0,h,l),M=-1,x=null);for(let t=M+1;t<=a;t++){const e=d[t-1];2===e?.disposalType&&m.clearRect(e.dims.left,e.dims.top,e.dims.width,e.dims.height),3===e?.disposalType&&x&&m.putImageData(x,0,0);const i=d[t];x=3===i.disposalType?m.getImageData(0,0,h,l):null,u.width=i.dims.width,u.height=i.dims.height,p.putImageData(new ImageData(new Uint8ClampedArray(i.patch),u.width,u.height),0,0),m.drawImage(u,i.dims.left,i.dims.top)}return M=a,f};return v(0),{source:f,width:h,height:l,duration:g,animated:!0,seek:async()=>{},frame:v,destroy(){f.width=u.width=1,d.length=0,x=null}}}const s=i?t.type.startsWith("video/"):/\.(mp4|webm|mov)(?:[?#]|$)/i.test(a),r=i?URL.createObjectURL(t):t,o=s?document.createElement("video"):new Image;o.crossOrigin="anonymous",o instanceof HTMLVideoElement&&(o.muted=!0,o.playsInline=!0,o.preload="auto");const n=()=>{o instanceof HTMLVideoElement?(o.pause(),o.removeAttribute("src"),o.load()):o.src="",i&&URL.revokeObjectURL(r)};try{const t=ht(o,s?"loadeddata":"load",e);o.src=r,await t;const i=o instanceof HTMLVideoElement?o.videoWidth:o.naturalWidth,a=o instanceof HTMLVideoElement?o.videoHeight:o.naturalHeight;return{source:o,width:i,height:a,duration:o instanceof HTMLVideoElement?o.duration:0,animated:s,async seek(t,e){if(!(o instanceof HTMLVideoElement))return;if(!Number.isFinite(o.duration)||o.duration<=0)throw new Error("Video duration is unavailable.");const i=Math.max(0,Math.min(o.duration-.001,t%o.duration));if(Math.abs(o.currentTime-i)<.001&&o.readyState>=2)return;const a=ht(o,"seeked",e);o.currentTime=i,await a},frame:()=>o,destroy:n}}catch(t){throw n(),t}}var ct=t=>{if(t?.aborted)throw new DOMException("Export cancelled","AbortError")};function dt(t,e,i={}){let a=P(i.settings),s=i.width??e.width,o=i.height??e.height;const n=nt(t,a,i),h=new r;let l=0,c=!1,d=!0,f=!1,m=!0,u=0,p=0,g=0,M=0,x=-1,v=!1!==i.adaptive,b=0,w=0,y=0;const S=matchMedia("(prefers-reduced-motion: reduce)"),k=e.source instanceof HTMLVideoElement?e.source:null,A=()=>{c||l||!m||document.hidden||(l=requestAnimationFrame(F))},E=()=>!f&&!S.matches&&m&&!document.hidden,T=()=>{k&&(k.loop=!0,E()?k.play().catch(()=>{f=!0,d=!0,A()}):k.pause()),g=0,d=!0,A()};function F(t){if(l=0,c||!m||document.hidden)return;const r=E();r&&(u+=g?Math.min(.1,(t-g)/1e3):0),g=t;const S=function(t){return z(t)||q(t)||t.effects.grain>0||t.effects.dust>0||t.effects.glitch>0}(a),T=r&&(e.animated||S),F=k?.getVideoPlaybackQuality?.().totalVideoFrames??-1,I=!k||F<0||F!==x;if(d||n.active||T&&(I||S)&&t-M>=1e3/Math.max(1,Math.min(60,i.fps??60))-.5){const r=performance.now();try{e.animated&&!k&&n.invalidate();const[t,l]=C(s,o,a);p=h.update(u,a.motion.type,a.motion.speed),n.render(e.frame(k?.currentTime??u),u,t,l,p);const c=performance.now()-r;i.onFrame?.(k?.currentTime??u,c),w=w?.9*w+.1*c:c,++b>20&&v&&(T||n.active)&&(y=w>13?y+1:0,y>=12&&n.maxCells>3e3&&(n.setBudget(Math.max(3e3,.8*n.maxCells)),i.onQualityChange?.(n.maxCells),y=0,w=0))}catch(t){f=!0,i.onError?.(t instanceof Error?t:new Error(String(t)))}d=!1,M=t,x=F}r&&(T||n.active)&&A()}const I=e=>{if(!E())return;const i=t.getBoundingClientRect();n.pointer((e.clientX-i.left)/i.width,(e.clientY-i.top)/i.height,e.timeStamp),A()},R=()=>{n.leave(),A()},D=new IntersectionObserver(([t])=>{m=t.isIntersecting,T()});D.observe(t),t.addEventListener("pointermove",I),t.addEventListener("pointerleave",R),t.addEventListener("pointercancel",R),document.addEventListener("visibilitychange",T),S.addEventListener("change",T);const U=()=>{c||(c=!0,cancelAnimationFrame(l),D.disconnect(),t.removeEventListener("pointermove",I),t.removeEventListener("pointerleave",R),t.removeEventListener("pointercancel",R),document.removeEventListener("visibilitychange",T),S.removeEventListener("change",T),i.signal?.removeEventListener("abort",U),n.destroy(),e.destroy())};if(i.signal?.addEventListener("abort",U,{once:!0}),i.signal?.aborted)throw U(),new DOMException("Cancelled","AbortError");return T(),{canvas:t,media:e,update(t){a=L(a,t),n.configure(a),d=!0,A()},resize(t,e,i){void 0!==i&&n.setPixelRatio(i),s=Math.max(2,t),o=Math.max(2,e),d=!0,A()},pause(t=!0){f=t,T()},async seek(t){u=Math.max(0,t),await e.seek(u),n.invalidate(),d=!0,A()},redraw(){n.invalidate(),d=!0,A()},get time(){return k?.currentTime??u},get settings(){return P(a)},get motionTime(){return p},get paused(){return f||S.matches},setAdaptive(t){v=t,b=y=w=0},setBudget(t){n.setBudget(t),i.onQualityChange?.(n.maxCells),d=!0,A()},get pixelRatio(){return n.pixelRatio},get maxCells(){return n.maxCells},get capabilities(){return n.capabilities},destroy:U}}var ft={Standard:()=>import("figlet/fonts/Standard"),Slant:()=>import("figlet/fonts/Slant"),Small:()=>import("figlet/fonts/Small"),Big:()=>import("figlet/fonts/Big"),Banner:()=>import("figlet/fonts/Banner"),Block:()=>import("figlet/fonts/Block"),Bubble:()=>import("figlet/fonts/Bubble"),Digital:()=>import("figlet/fonts/Digital"),Doom:()=>import("figlet/fonts/Doom"),Lean:()=>import("figlet/fonts/Lean"),Mini:()=>import("figlet/fonts/Mini"),Script:()=>import("figlet/fonts/Script"),Shadow:()=>import("figlet/fonts/Shadow"),Speed:()=>import("figlet/fonts/Speed"),Starwars:()=>import("figlet/fonts/Star Wars"),Stop:()=>import("figlet/fonts/Stop"),Straight:()=>import("figlet/fonts/Straight"),Thin:()=>import("figlet/fonts/Thin"),ThreeD:()=>import("figlet/fonts/3-D"),Univers:()=>import("figlet/fonts/Univers"),Wavy:()=>import("figlet/fonts/Wavy")},mt=Object.keys(ft);var ut={standard:{label:"Classic ASCII",chars:" .:-=+*#%@"},asciify:{label:"Asciify",chars:" .:-=+ASCIIFY#@"},minimal:{label:"Minimal",chars:" .:+"},detailed:{label:"Detailed",chars:" .,:;i1tfLCG08@"},letters:{label:"Letters",chars:" .ilLCFTYASMW"},technical:{label:"Technical",chars:" .:;>_/[{}]=+*#@$"},blocks:{label:"Tonal blocks",chars:" ░▒▓█"},braille:{label:"Braille",chars:" ⠁⠃⠇⡇⣇⣧⣷⣿"}},pt=ut;exports.BLEND_MODES=S,exports.CHARACTER_SETS=ut,exports.DEFAULT_STUDIO_SETTINGS=A,exports.DITHER_ALGORITHMS=y,exports.MAX_STUDIO_WARPS=8,exports.STUDIO_CHARACTER_SETS=pt,exports.STUDIO_CURVE_CHANNELS=h,exports.STUDIO_HOVERS=t,exports.STUDIO_LOOKS=U,exports.STUDIO_MOTIONS=e,exports.STUDIO_PALETTES=k,exports.STUDIO_STYLES=w,exports.STUDIO_TEXT_FONTS=mt,exports.STUDIO_WARPS=p,exports.createStudioCurveLookup=f,exports.createStudioRenderer=nt,exports.createStudioText=async function(t,e="Standard",i="#ffffff"){if(!Object.prototype.hasOwnProperty.call(ft,e))throw new Error("Unknown text font.");const{default:a}=await import("figlet/browser"),s=await ft[e]();a.parseFont(e,s.default),a.defaults({fetchFontIfMissing:!1});const r=a.textSync(t.slice(0,120),{font:e}),o=r.split("\n"),n=Math.max(1,...o.map(t=>t.length)),h=Math.max(1,o.length),l=Math.min(1,2048/(9*n)),c=document.createElement("canvas");c.width=Math.ceil(9*n*l+32),c.height=Math.ceil(15*h*l+32);const d=c.getContext("2d");return d.fillStyle="#080808",d.fillRect(0,0,c.width,c.height),d.fillStyle=i,d.font=15*l+"px monospace",d.textBaseline="top",o.forEach((t,e)=>d.fillText(t,16,16+15*e*l)),{canvas:c,ascii:r}},exports.exportStudio=async function(t,e,i){const{format:a,signal:s}=i,r=Math.round(i.width),o=Math.round(i.height);if(!Number.isFinite(r)||!Number.isFinite(o)||r<2||o<2||r>4096||o>4096||r*o>16777216)throw new Error("Choose export dimensions between 2 and 4096 pixels.");if(!["png","jpeg","mp4","webm","gif"].includes(a))throw new Error("Unknown export format.");if(void 0!==i.fps&&!Number.isFinite(i.fps))throw new Error("Frames per second must be finite.");const n=Math.max(1,Math.min(60,Math.round(i.fps??24))),h=i.duration??5;if(!Number.isFinite(h)||h<=0||h>60)throw new Error("Choose a duration from 0 to 60 seconds.");const l="png"===a||"jpeg"===a,c=i.time??0;if(!Number.isFinite(c)||c<0)throw new Error("Image time must be a finite non-negative number.");if(void 0!==i.motionTime&&(!Number.isFinite(i.motionTime)||i.motionTime<0))throw new Error("Motion time must be a finite non-negative number.");if(!l&&r*o>8294400)throw new Error("Video exports support up to 3840 × 2160 pixels.");if("gif"===a&&(r*o>921600||h*n>600))throw new Error("GIF export supports up to 1280 × 720 and 600 frames. Use MP4 for larger exports.");if(void 0!==i.referenceWidth&&(!Number.isFinite(i.referenceWidth)||i.referenceWidth<1))throw new Error("Reference width must be a positive number.");if("gif"===a&&n>30)throw new Error("GIF exports support up to 30 fps. Choose MP4 or WebM for higher frame rates.");const d=document.createElement("canvas"),f=nt(d,P(e),{maxDimension:4096,maxCells:i.maxCells??12e3,pixelRatio:r/(i.referenceWidth??Math.min(r,960))});let m;try{if(ct(s),i.onProgress?.(0),l){if(f.render(await t.frame(c,s),c,r,o,i.motionTime),"unavailable"===d.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");ct(s);const e=await new Promise((t,e)=>d.toBlob(i=>i?t(i):e(new Error("Image export failed.")),"png"===a?"image/png":"image/jpeg",i.quality??.92));return i.onProgress?.(1),e}const e=Math.ceil(h*n);if("gif"===a){const a=await import("gifenc"),{GIFEncoder:l,quantize:c,applyPalette:m}="function"==typeof a.GIFEncoder?a:a.default,u=l(),p=d.getContext("2d");for(let a=0;a<e;a++){ct(s);const l=a/n;if(f.invalidate(),f.render(await t.frame(l,s),l,r,o),"unavailable"===d.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");const g=p.getImageData(0,0,r,o).data,M=c(g,256),x=m(g,M);u.writeFrame(x,r,o,{palette:M,delay:10*(Math.round(100*Math.min((a+1)/n,h))-Math.round(100*a/n)),repeat:0}),i.onProgress?.((a+1)/e*.98),await new Promise(t=>setTimeout(t,0))}return u.finish(),i.onProgress?.(1),new Blob([new Uint8Array(u.bytes())],{type:"image/gif"})}const{Output:u,Mp4OutputFormat:p,WebMOutputFormat:g,BufferTarget:M,CanvasSource:x,canEncodeVideo:v}=await import("mediabunny"),b="mp4"===a?"avc":"vp9";if(!await v(b,{width:r,height:o}))throw new Error(`${a.toUpperCase()} encoding is unavailable in this browser. Try another format or a current browser with WebCodecs.`);const w=new u({format:"mp4"===a?new p({fastStart:"in-memory"}):new g,target:new M});d.width=r,d.height=o,m=()=>w.cancel();const y=new x(d,{codec:b,bitrate:Math.max(5e5,Math.round(r*o*n*.15))});w.addVideoTrack(y,{frameRate:n}),d.width=r,d.height=o,await w.start();for(let a=0;a<e;a++){ct(s);const l=a/n;if(f.invalidate(),f.render(await t.frame(l,s),l,r,o),"unavailable"===d.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");await y.add(l,Math.min(1/n,h-l)),i.onProgress?.((a+1)/e*.98),a%4==0&&await new Promise(t=>setTimeout(t,0))}return y.close(),ct(s),await w.finalize(),m=void 0,i.onProgress?.(1),new Blob([w.target.buffer],{type:"mp4"===a?"video/mp4":"video/webm"})}catch(t){throw await(m?.().catch(()=>{})),t}finally{f.destroy(),d.width=d.height=1}},exports.loadStudioMedia=lt,exports.mountStudio=async function(t,e,i={}){const a=await lt(e,i.signal);try{return dt(t,a,i)}catch(t){throw a.destroy(),t}},exports.mountStudioMedia=dt,exports.normalizeStudioCurve=c,exports.normalizeStudioCurves=d,exports.normalizeStudioSettings=P,exports.normalizeStudioWarps=M,exports.parseStudioSettings=function(t){if(t.length>1e5)throw new Error("Settings exceed 100 KB.");return P(JSON.parse(t))},exports.restyleStudio=function(t,e=Math.random){const i=U.filter(e=>e.settings.style!==t.style||e.settings.ink!==t.ink),a=N(i[Math.min(i.length-1,Math.max(0,Math.floor(e()*i.length)))].id);return a.aspectRatio=t.aspectRatio,a.crop={...t.crop},a.mask=P(t).mask,a},exports.serializeStudioSettings=function(t){return JSON.stringify(P(t))},exports.studioCrop=R,exports.studioDimensions=C,exports.studioGrid=D,exports.studioLook=N,exports.studioSourceSize=at,exports.updateStudioSettings=L;//# sourceMappingURL=studio.cjs.map
1
+ "use strict";var t=[{value:"none",label:"Off",group:"Still",description:"Keep the artwork still under the pointer."},{value:"trail",label:"Trail",group:"Change characters",description:"A fluid wake changes character density and settles behind your cursor."},{value:"dissolve",label:"Dissolve",group:"Change characters",description:"Erase a soft path through the characters; the image gradually reforms."},{value:"contour",label:"Contour",group:"Change characters",description:"Fine tonal rings trace your path without moving the grid."},{value:"etch",label:"Emboss",group:"Change characters",description:"Press a light-and-shadow impression into the characters; the grid stays fixed."},{value:"water",label:"Water",group:"Move the image",description:"Soft ripples refract the image and settle after your stroke."},{value:"silk",label:"Silk",group:"Move the image",description:"Directional folds follow the movement of your hand."},{value:"vortex",label:"Vortex",group:"Move the image",description:"A swirling wake curls through the image."},{value:"magnetic",label:"Magnetic Pull",group:"Move the image",description:"The image gathers toward your stroke, then relaxes."},{value:"scatter",label:"Scatter",group:"Move the image",description:"A textured outward scatter settles behind your cursor."},{value:"elastic",label:"Elastic",group:"Move the image",description:"Push the image with your stroke; it recoils and springs back into place."},{value:"rake",label:"Rake",group:"Move the image",description:"Comb the image into alternating ribbons that glide back into alignment."}],e=[{value:"none",mode:"none",group:"Still",label:"Off",description:"Keep the image still. Hover stays available."},{value:"caustics",mode:"caustics",group:"Light and texture",label:"Caustics",description:"Soft ribbons of light travel across a stationary character grid."},{value:"current",mode:"current",group:"Flow and depth",label:"Slow Current",description:"A gentle flow through the image, with steady edges."},{value:"reform",mode:"reform",group:"Rebuild",label:"Reveal & Reform",description:"Disperse, gather, then hold the complete image."},{value:"sheen",mode:"sheen",group:"Light and texture",label:"Sheen",description:"A broad diagonal light sweep; characters stay anchored."},{value:"tidal",mode:"tidal",group:"Flow and depth",label:"Tidal Rings",description:"Concentric currents travel outward, with protected edges."},{value:"grain",mode:"grain",group:"Light and texture",label:"Living Grain",description:"Slow, individually phased tonal changes on a stationary grid."},{value:"parallax",mode:"parallax",group:"Flow and depth",label:"Parallax",description:"A shallow, continuous drift through the image, with the edges held in place."},{value:"weave",mode:"weave",group:"Flow and depth",label:"Woven Flow",description:"Interlaced bands move in opposing directions, like a flexible printed fabric."},{value:"print",mode:"print",group:"Rebuild",label:"Print Shift",description:"Staggered rows lift, soften and register back into the image."},{value:"trace",mode:"trace",group:"Light and texture",label:"Contour Light",description:"Light follows the source image’s tonal contours; every character stays anchored."}],i=t=>Math.max(0,Math.min(1,t)),a=(t,e,a)=>{const r=i((a-t)/(e-t));return r*r*(3-2*r)},r=(t,e)=>{const i=(.06711056*t+.00583715*e)%1*52.9829189;return i-Math.floor(i)},s=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 o(t,e,s,o,n,h=.5){if(n[0]=n[1]=n[2]=0,n[3]=1,"none"===t)return n;const l=o*Math.PI/6,c=a(0,.12,Math.min(e,1-e,s,1-s));if("caustics"===t){const t=Math.sin(9*e+5*s+l)+Math.sin(8*s-3*e-l),i=Math.pow(Math.max(0,1-.72*Math.abs(t)),3);n[2]=(.22*i-.045)*c}else if("current"===t)n[0]=Math.sin(9*s+l)*Math.cos(7*e-l)*10*c,n[1]=Math.cos(8*e+l)*Math.sin(6*s-l)*7*c;else if("sheen"===t)n[2]=.2*Math.pow(.5+.5*Math.cos(5*e+3*s-l),8)-.025;else if("tidal"===t){const t=e-.5,i=s-.5,a=Math.hypot(t,i),r=Math.sin(22*a-l)*c;n[0]=t*r*9,n[1]=i*r*9,n[2]=.035*r}else if("grain"===t){const t=r(Math.floor(160*e),Math.floor(100*s))*Math.PI*2;n[2]=.07*Math.sin(l+t)}else if("parallax"===t){const t=.45+.55*Math.max(0,1-1.4*Math.hypot(e-.5,s-.5));n[0]=12*Math.sin(l)*t*c,n[1]=6*(Math.cos(l)-1)*t*c}else if("weave"===t)n[0]=Math.sin(s*Math.PI*6+l)*Math.sin(l)*8*c,n[1]=Math.sin(e*Math.PI*6-l)*Math.sin(l)*6*c;else if("print"===t){const t=Math.floor(24*s),e=((o+3*r(t,3))%12+12)%12,i=a(1,2.5,e)*(1-a(3.5,5,e));n[0]=Math.sin(2.4*t)*i*9*c,n[1]=5*-i*c,n[2]=.22*-i,n[3]=1-.45*i}else if("trace"===t){const t=.5+.5*Math.cos(l);n[2]=.22*Math.pow(Math.max(0,1-Math.abs(i(h)-t)/.16),3)-.015}else if("reform"===t){const t=(o%12+12)%12,i=r(Math.floor(160*e),Math.floor(100*s)),h=.65*e+.2*s+.15*i+.08*Math.sin(8*e-5*s),d=a(1.8+1.2*h,3.8+1.2*h,t)*(1-a(5+1.7*h,7.2+1.7*h,t));n[0]=Math.sin(9*s+l)*d*(1-d)*24*c,n[1]=-d*(1-d)*(8+12*i)*c,n[2]=.45*-d,n[3]=1-.9*d}return n}function n(t,e){const a=Math.max(0,Math.min(2,Number.isFinite(e)?e:1));return t[0]*=a,t[1]*=a,t[2]*=a,t[3]=i(1+(t[3]-1)*a),t}var h=["rgb","red","green","blue"],l=t=>Math.max(0,Math.min(1,t));function c(t){const e=new Map([[0,0],[1,1]]);if(Array.isArray(t))for(const i of t.slice(0,64)){if(!Array.isArray(i)||i.length<2||"number"!=typeof i[0]||!Number.isFinite(i[0])||"number"!=typeof i[1]||!Number.isFinite(i[1]))continue;const t=Math.round(255*l(i[0]))/255;!e.has(t)&&e.size>=16||e.set(t,l(i[1]))}return[...e].sort((t,e)=>t[0]-e[0])}function d(t){const e=t&&"object"==typeof t?t:{};return Object.fromEntries(h.map(t=>[t,c(e[t])]))}function m(t){const e=c(t),i=e.length,a=e.slice(1).map((t,i)=>t[0]-e[i][0]),r=e.slice(1).map((t,i)=>(t[1]-e[i][1])/a[i]),s=new Float64Array(i);s[0]=r[0],s[i-1]=r[i-2];for(let t=1;t<i-1;t++){const e=r[t-1],i=r[t];if(e*i<=0)continue;const o=2*a[t]+a[t-1],n=a[t]+2*a[t-1];s[t]=(o+n)/(o/e+n/i)}const o=new Uint8Array(256);let n=0;for(let t=0;t<256;t++){const r=t/255;for(;n<i-2&&r>e[n+1][0];)n++;const h=a[n],c=(r-e[n][0])/h,d=c*c,m=d*c,f=(2*m-3*d+1)*e[n][1]+(m-2*d+c)*h*s[n]+(-2*m+3*d)*e[n+1][1]+(m-d)*h*s[n+1];o[t]=Math.round(255*l(f))}return o}function f(t,e,i,a,r,s){a=Math.max(0,Math.min(e-1,a)),r=Math.max(0,Math.min(i-1,r));const o=Math.floor(a),n=Math.floor(r),h=a-o,l=r-n,c=4*(n*e+o);if(0===h&&0===l){for(let e=0;e<4;e++)s[e]=t[c+e];return}const d=4*(n*e+Math.min(e-1,o+1)),m=4*(Math.min(i-1,n+1)*e+o),f=4*(Math.min(i-1,n+1)*e+Math.min(e-1,o+1)),u=(1-h)*(1-l)*t[c+3],p=h*(1-l)*t[d+3],g=(1-h)*l*t[m+3],M=h*l*t[f+3],x=u+p+g+M;for(let e=0;e<3;e++)s[e]=x?(t[c+e]*u+t[d+e]*p+t[m+e]*g+t[f+e]*M)/x:0;s[3]=x}function u(t,e,i,a,r,s){if(a>=0&&a<=e-1&&r>=0&&r<=i-1)return f(t,e,i,a,r,s);if(s[0]=s[1]=s[2]=s[3]=0,a<=-1||a>=e||r<=-1||r>=i)return;const o=Math.floor(a),n=Math.floor(r),h=a-o,l=r-n;for(let a=0;a<=1;a++)for(let r=0;r<=1;r++){const c=o+r,d=n+a;if(c<0||c>=e||d<0||d>=i)continue;const m=4*(d*e+c),f=(r?h:1-h)*(a?l:1-l)*t[m+3];s[0]+=t[m]*f,s[1]+=t[m+1]*f,s[2]+=t[m+2]*f,s[3]+=f}s[3]&&(s[0]/=s[3],s[1]/=s[3],s[2]/=s[3])}var p=[{value:"twirl",label:"Twirl",description:"Rotate the center into a smooth spiral; the outer boundary stays fixed.",direction:!1,frequency:!1},{value:"pinch",label:"Pinch",description:"Contract the center, or expand it with negative strength.",direction:!1,frequency:!1},{value:"sphere",label:"Spherize",description:"Magnify a rounded lens through the source; negative strength recedes.",direction:!1,frequency:!1},{value:"ripple",label:"Ripple",description:"Bend the image through concentric, soft-edged waves.",direction:!1,frequency:!0},{value:"zigzag",label:"Zigzag",description:"Alternate the twist in sharp, concentric bands.",direction:!1,frequency:!0},{value:"shear",label:"Shear",description:"Slant a region along an adjustable direction.",direction:!0,frequency:!1},{value:"smudge",label:"Smudge",description:"Draw a soft region of the source along one direction.",direction:!0,frequency:!1},{value:"polar",label:"Polar",description:"Unwrap a region into polar coordinates; negative strength wraps it.",direction:!0,frequency:!1},{value:"fragment",label:"Fragment",description:"Offset small source tiles into a stable fractured texture.",direction:!0,frequency:!0}],g=(t,e,i,a)=>"number"==typeof t&&Number.isFinite(t)?Math.max(i,Math.min(a,t)):e;function M(t){if(!Array.isArray(t))return[];const e=[];for(const i of t.slice(0,64))if(i&&"object"==typeof i&&p.some(t=>t.value===i.type)&&(e.push({type:i.type,enabled:!1!==i.enabled,amount:g(i.amount,.35,-1,1),x:g(i.x,.5,0,1),y:g(i.y,.5,0,1),radius:g(i.radius,.55,.05,2),angle:g(i.angle,0,-180,180),frequency:g(i.frequency,5,1,24)}),8===e.length))break;return e}var x=2*Math.PI,w=(t,e)=>{let i=Math.imul(t,374761393)^Math.imul(e,668265263);return i=Math.imul(i^i>>>13,1274126177),((i^i>>>16)>>>0)/4294967296},v=class{constructor(t=[],e="clamp"){this.warps=[],this.signature="",this.geometry="",this.coordinates=new Float32Array(0),this.output=new Uint8ClampedArray(0),this.sampled=[0,0,0,0],this.edge="clamp",this.configure(t,e)}configure(t=[],e="clamp"){const i=M(t).filter(t=>t.enabled&&0!==t.amount),a=JSON.stringify(i);this.edge="transparent"===e?"transparent":"clamp",a!==this.signature&&(this.signature=a,this.geometry="",this.warps=i.map(t=>({...t,cos:Math.cos(t.angle*Math.PI/180),sin:Math.sin(t.angle*Math.PI/180)})),i.length||this.clear())}get active(){return this.warps.length>0}apply(t,e,i,a=e/i){if(!this.active)return t;if(!Number.isInteger(e)||!Number.isInteger(i)||e<1||i<1||e*i*4!==t.length||!Number.isFinite(a)||a<=0)throw new Error("Warp dimensions do not match the source.");const r=`${e}:${i}:${a}`;if(r!==this.geometry){this.coordinates.length!==e*i*2&&(this.coordinates=new Float32Array(e*i*2));const t=Math.max(1,a),s=Math.max(1,1/a);for(let a=0;a<i;a++)for(let r=0;r<e;r++){let o=(r+.5)/e,n=(a+.5)/i;for(let e=this.warps.length-1;e>=0;e--){const i=this.warps[e],a=(o-i.x)*t/i.radius,r=(n-i.y)*s/i.radius,h=a*a+r*r;if(h>=1)continue;const l=Math.sqrt(h),c=(1-h)*(1-h),d=i.amount;let m=a,f=r;if("twirl"===i.type||"zigzag"===i.type){const t="twirl"===i.type?-d*x*c:.65*d*(2/Math.PI*Math.asin(Math.sin(l*x*i.frequency)))*c,e=Math.cos(t),s=Math.sin(t);m=a*e-r*s,f=a*s+r*e}else if("pinch"===i.type){const t=Math.exp(2*d*c);m=a*t,f=r*t}else if("sphere"===i.type&&l>0){const t=1+d*c*(2*Math.asin(l)/Math.PI/l-1);m=a*t,f=r*t}else if("ripple"===i.type&&l>0){const t=1+.12*d*Math.sin(l*x*i.frequency)*c/l;m=a*t,f=r*t}else if("shear"===i.type){const t=-a*i.sin+r*i.cos;m-=d*t*.9*c*i.cos,f-=d*t*.9*c*i.sin}else if("smudge"===i.type)m-=.65*d*c*i.cos,f-=.65*d*c*i.sin;else if("polar"===i.type){const t=a*i.cos+r*i.sin,e=-a*i.sin+r*i.cos,s=Math.atan2(e,t),o=d>0?s/Math.PI:Math.cos(t*Math.PI)*(e+1)/2,n=d>0?2*l-1:Math.sin(t*Math.PI)*(e+1)/2,h=o*i.cos-n*i.sin,u=o*i.sin+n*i.cos;m+=(h-a)*Math.abs(d)*c,f+=(u-r)*Math.abs(d)*c}else if("fragment"===i.type){const t=Math.floor((a*i.cos+r*i.sin)*i.frequency),e=Math.floor((-a*i.sin+r*i.cos)*i.frequency),s=(w(t,e)-.5)*d*.5*c,o=(w(e+71,t-31)-.5)*d*.5*c;m+=s*i.cos-o*i.sin,f+=s*i.sin+o*i.cos}o=i.x+m*i.radius/t,n=i.y+f*i.radius/s}const h=2*(a*e+r);this.coordinates[h]=o*e-.5,this.coordinates[h+1]=n*i-.5}this.geometry=r}this.output.length!==t.length&&(this.output=new Uint8ClampedArray(t.length));const s=t===this.output?t.slice():t,o="transparent"===this.edge?u:f;for(let a=0,r=0;a<t.length;a+=4,r+=2){o(s,e,i,this.coordinates[r],this.coordinates[r+1],this.sampled);for(let t=0;t<4;t++)this.output[a+t]=this.sampled[t]}return this.output}clear(){this.coordinates=new Float32Array(0),this.output=new Uint8ClampedArray(0),this.geometry=""}},y=["stipple","engraving","crosshatch","woodblock","risograph","pointillism"];function b(t){return y.includes(t)}var S={density:1,weight:1,angle:-35,roughness:.35,invert:!1,secondaryInk:"#ec6752",registration:.2,seed:7};function E(t){const e=t&&"object"==typeof t&&!Array.isArray(t)?t:{},i=(t,i,a)=>{const r=e[t];return"number"==typeof r&&Number.isFinite(r)?Math.max(i,Math.min(a,r)):S[t]};return{density:i("density",0,2),weight:i("weight",.25,2),angle:i("angle",-180,180),roughness:i("roughness",0,1),invert:!0===e.invert,secondaryInk:"string"==typeof e.secondaryInk&&/^#[\da-f]{6}$/i.test(e.secondaryInk)?e.secondaryInk:S.secondaryInk,registration:i("registration",0,1),seed:Math.round(i("seed",0,65535))}}var k=["ascii","blocks","braille","dots","lines","cross","diagonal","diamond","mixed","pixel","mosaic","lego","voxel","disco","dither","hex","led","cmyk",...y],A=["none","bayer2","bayer4","bayer8","bayer16","floyd-steinberg","atkinson","stucki","sierra","sierra-lite","burkes","jarvis","halftone","lines","noise","vertical-lines","diagonal-lines","radial","blue-noise"],P=["source-over","multiply","screen","overlay","soft-light","hard-light","color-dodge","color-burn","hue","saturation","color","luminosity"],T={original:[],gray4:["#000000","#555555","#aaaaaa","#ffffff"],gray8:["#000000","#242424","#494949","#6d6d6d","#929292","#b6b6b6","#dbdbdb","#ffffff"],rgb8:["#000000","#ff0000","#00ff00","#0000ff","#ffff00","#ff00ff","#00ffff","#ffffff"],cyberpunk:["#08081a","#3c1670","#ed299a","#29dfef","#fff7bf"],pastel:["#393448","#a5b4d4","#9ed9c6","#e7aac1","#f5e8be"],mono:["#080808","#f2f2e8"],asciify:["#080808","#625b38","#a19558","#e8b900"],gameboy:["#0f380f","#306230","#8bac0f","#9bbc0f"],cga:["#000000","#55ffff","#ff55ff","#ffffff"],pico8:["#000000","#1d2b53","#7e2553","#008751","#ab5236","#5f574f","#c2c3c7","#fff1e8","#ff004d","#ffa300","#ffec27","#00e436","#29adff","#83769c","#ff77a8","#ffccaa"],c64:["#000000","#ffffff","#880000","#aaffee","#cc44cc","#00cc55","#0000aa","#eeee77","#dd8855","#664400","#ff7777","#333333","#777777","#aaff66","#0088ff","#bbbbbb"],amber:["#100b00","#5f3b00","#c98014","#ffd17c"],ice:["#081b29","#25586e","#69a6b3","#d9ece7"],risograph:["#f4ebd0","#f2594b","#2853a5","#29232e"],sepia:["#201b17","#6b5039","#b49868","#f6e6c5"],nord:["#2e3440","#4c566a","#88c0d0","#eceff4"],dusk:["#211b35","#654271","#c3788c","#f5c9a3"],forest:["#101f1b","#355747","#87a16f","#e4e3ba"],ocean:["#071b33","#17577f","#3fa7a4","#d9efde"],newsprint:["#191919","#666666","#aaaaaa","#eee9df"],custom:["#080808","#e8b900"]},F={version:1,aspectRatio:"original",style:"ascii",cellSize:6,charset:" .:-=+*#%@",colorMode:"accent",ink:"#e8b900",print:{...S},crop:{x:.5,y:.5,zoom:1,rotation:0},warps:[],warpEdge:"clamp",backdrop:{mode:"solid",color:"#080808",color2:"#393323",blur:12,opacity:1},color:{brightness:0,contrast:1,saturation:1,grayscale:0,tint:"#e8b900",amount:0,blend:"source-over",blackPoint:0,whitePoint:1,gamma:1,shadows:0,highlights:0,curves:{rgb:[[0,0],[1,1]],red:[[0,0],[1,1]],green:[[0,0],[1,1]],blue:[[0,0],[1,1]]},denoise:0},dither:{algorithm:"none",palette:"mono",colors:["#080808","#e8b900"],amount:1,scale:2,threshold:.5,motion:"none",speed:1,direction:45,colorSpace:"rgb"},mask:{enabled:!1,invert:!1,shapes:[]},lights:[],effects:{bloom:0,characterBloom:0,grain:0,dust:0,scanlines:0,crt:0,prism:0,rgbSplit:0,sharpen:0,vignette:0,glitch:0,pixelate:0,blur:0,blurType:"gaussian",angle:0,focus:.5,halftone:0},motion:{type:"none",speed:1,amount:1},hover:{effect:"trail",strength:.55,radius:.2,edgeSafe:!1}},I=t=>t&&"object"==typeof t&&!Array.isArray(t)?t:{},C=(t,e,i,a)=>"number"==typeof t&&Number.isFinite(t)?Math.min(a,Math.max(i,t)):e,R=(t,e)=>"string"==typeof t&&/^#[\da-f]{6}$/i.test(t)?t:e,L=(t,e,i)=>e.includes(t)?t:i;function N(i={}){const a=I(i),r=F;if(void 0!==a.version&&1!==a.version)throw new Error("Unsupported studio settings version. Update asciify-engine.");const s=I(a.crop),o=I(a.backdrop),n=I(a.color),h=I(a.dither),l=I(a.mask),c=I(a.effects),m=I(a.motion),f=I(a.hover),u={...r.effects};for(const t of["bloom","characterBloom","grain","dust","scanlines","crt","prism","rgbSplit","sharpen","vignette","glitch","pixelate","halftone"])u[t]=C(c[t],0,0,1);u.blur=C(c.blur,0,0,24),u.blurType=L(c.blurType,["gaussian","directional","radial","progressive"],r.effects.blurType),u.angle=C(c.angle,0,-180,180),u.focus=C(c.focus,.5,0,1);let p=2048;return{version:1,aspectRatio:L(a.aspectRatio,["original","16:9","9:16","1:1","4:3","3:4","21:9"],"original"),style:L(a.style,k,r.style),cellSize:C(a.cellSize,r.cellSize,b(String(a.style))||["pixel","mosaic","lego","voxel","disco","dots","hex","led","cmyk"].includes(String(a.style))?1:3,60),charset:"string"==typeof a.charset&&a.charset.length?Array.from(a.charset).slice(0,128).join(""):r.charset,colorMode:L(a.colorMode,["accent","source","gray"],r.colorMode),ink:R(a.ink,r.ink),print:E(a.print),warps:M(a.warps),warpEdge:L(a.warpEdge,["clamp","transparent"],"clamp"),crop:{x:C(s.x,.5,0,1),y:C(s.y,.5,0,1),zoom:C(s.zoom,1,1,5),rotation:90*Math.round(C(s.rotation,0,-360,360)/90)},backdrop:{mode:L(o.mode,["solid","transparent","source","blurred","gradient"],r.backdrop.mode),color:R(o.color,r.backdrop.color),color2:R(o.color2,r.backdrop.color2),blur:C(o.blur,12,0,32),opacity:C(o.opacity,1,0,1)},color:{brightness:C(n.brightness,0,-1,1),contrast:C(n.contrast,1,0,3),saturation:C(n.saturation,1,0,3),grayscale:C(n.grayscale,0,0,1),tint:R(n.tint,r.color.tint),amount:C(n.amount,0,0,1),blend:L(n.blend,P,r.color.blend),blackPoint:C(n.blackPoint,0,0,.99),whitePoint:Math.max(C(n.blackPoint,0,0,.99)+1/255,C(n.whitePoint,1,1/255,1)),gamma:C(n.gamma,1,.25,4),shadows:C(n.shadows,0,-1,1),highlights:C(n.highlights,0,-1,1),curves:d(n.curves),denoise:C(n.denoise,0,0,1)},dither:{algorithm:L(h.algorithm,A,"none"),palette:"string"==typeof h.palette&&Object.prototype.hasOwnProperty.call(T,h.palette)?h.palette:"mono",colors:Array.isArray(h.colors)&&h.colors.length>=2?h.colors.slice(0,32).map(t=>R(t,"#000000")):[...r.dither.colors],amount:C(h.amount,1,0,2),scale:Math.round(C(h.scale,2,1,12)),threshold:C(h.threshold,.5,0,1),motion:L(h.motion,["none","drift","shimmer"],"none"),speed:C(h.speed,1,.1,3),direction:C(h.direction,45,-180,180),colorSpace:L(h.colorSpace,["rgb","luminance"],"rgb")},mask:{enabled:!0===l.enabled,invert:!0===l.invert,shapes:Array.isArray(l.shapes)?l.shapes.slice(0,64).map(t=>{const e=I(t),i=L(e.kind,["rectangle","ellipse","brush"],"rectangle"),a="brush"===i&&Array.isArray(e.points)?e.points.slice(0,p).map(t=>Array.isArray(t)?[Math.round(1e4*C(t[0],0,0,1))/1e4,Math.round(1e4*C(t[1],0,0,1))/1e4]:[0,0]):[];return p-=a.length,{kind:i,x:C(e.x,0,0,1),y:C(e.y,0,0,1),width:C(e.width,.5,0,1),height:C(e.height,.5,0,1),size:C(e.size,.05,.005,.5),points:a}}):[]},lights:Array.isArray(a.lights)?a.lights.slice(0,4).map(t=>{const e=I(t);return{x:C(e.x,.5,0,1),y:C(e.y,.5,0,1),radius:C(e.radius,.3,.02,1),intensity:C(e.intensity,.5,0,1),color:R(e.color,"#ffffff")}}):[],effects:u,motion:{type:L(m.type,e.map(t=>t.mode),"none"),speed:C(m.speed,1,.1,3),amount:C(m.amount,1,0,2)},hover:{effect:L(f.effect,t.map(t=>t.value),"trail"),strength:C(f.strength,.55,0,1),radius:C(f.radius,.2,.1,1),edgeSafe:!0===f.edgeSafe}}}function O(t,e,i,a,r){const s=Math.abs(r.rotation/90)%2==1,o=s?e:t,n=s?t:e,h=Math.max(i/o,a/n)*r.zoom;return{width:o*h,height:n*h,x:(i-o*h)*r.x,y:(a-n*h)*r.y,scale:h,rotated:s}}function D(t,e,i){if(Math.abs(i.crop.rotation/90)%2==1&&([t,e]=[e,t]),"original"===i.aspectRatio)return[t,e];const[a,r]=i.aspectRatio.split(":").map(Number);return t/e>a/r?[Math.round(e*a/r),e]:[t,Math.round(t*r/a)]}function U(t,e){const i={...t,...e};for(const a of["crop","backdrop","color","dither","mask","effects","motion","hover","print"])e[a]&&Object.assign(i,{[a]:{...t[a],...e[a]}});return e.color?.curves&&(i.color.curves={...t.color.curves,...e.color.curves}),N(i)}function j(t,e,i,a=12e3,r=1){const s=Math.max(2,Number.isFinite(t)?t:960),o=Math.max(2,Number.isFinite(e)?e:540),n=Math.max(1,Math.floor(Number.isFinite(a)?a:12e3)),h=Math.max(.01,Number.isFinite(r)?r:1),l=b(i.style)||["dither","pixel","mosaic","lego","voxel","disco","dots","hex","led","cmyk"].includes(i.style)?1:1.65;let c=Math.max(1,Math.ceil(Math.sqrt(s*o/(n*l))/h));for(;Math.ceil(s/(c*h))*Math.ceil(o/(c*h*l))>n;)c++;const d="dither"===i.style?i.dither.scale:i.cellSize,m=Math.max(c,d)*h;return{cell:m,rowHeight:m*l,columns:Math.ceil(s/m),rows:Math.ceil(o/(m*l)),minimum:c,limited:d<c}}var X=[["ascii","Signature ASCII","Brand ink and clean characters.",{}],["print","Newsprint","Fine diffusion on warm paper.",{style:"dither",dither:{algorithm:"floyd-steinberg",palette:"newsprint"}}],["handheld","Pocket camera","Four-tone ordered dither.",{style:"dither",dither:{algorithm:"bayer4",palette:"gameboy",scale:3}}],["riso","Two inks","Limited-color print texture.",{style:"dither",dither:{algorithm:"atkinson",palette:"risograph",scale:2}}],["night","Night signal","Gray characters and optical fringe.",{ink:"#888888",effects:{prism:.7,scanlines:.2,vignette:.3}}],["terminal","Phosphor","Green glyphs with a soft glow.",{ink:"#83efad",effects:{bloom:.4,scanlines:.35,crt:.2}}],["mosaic","Mosaic study","Separated color tiles.",{style:"mosaic",cellSize:14,colorMode:"source"}],["bricks","Brickwork","Colorful studded cells.",{style:"lego",cellSize:18,colorMode:"source"}],["voxel","Little volumes","Three-face isometric tiles.",{style:"voxel",cellSize:22,colorMode:"source"}],["disco","Mirror room","Faceted tiles and warm light.",{style:"disco",cellSize:18,colorMode:"source",lights:[{x:.35,y:.25,radius:.25,intensity:.45,color:"#fff2d4"}]}],["wallpaper","Wallpaper","Living ASCII over a softened source.",{backdrop:{mode:"blurred",blur:18,opacity:.55},ink:"#f2e9c9",motion:{type:"caustics",speed:.5}}],["blueprint","Blueprint","Linework in a cool monochrome.",{style:"lines",ink:"#9bccdf",backdrop:{mode:"solid",color:"#0a1e30"}}]].map(([t,e,i,a])=>({id:t,name:e,description:i,settings:N(a)}));function Y(t){const e=X.find(e=>e.id===t);if(!e)throw new Error("Unknown studio look.");return N(e.settings)}function q(t){const e=function(t){const e=t.blackPoint??0,i=t.whitePoint??1,a=t.gamma??1,r=t.shadows??0,s=t.highlights??0;if(0===e&&1===i&&1===a&&0===r&&0===s)return null;const o=[0,.25+.2*r,.5,.75+.2*s,1],n=o.slice(1).map((t,e)=>4*(t-o[e])),h=[n[0],...n.slice(1).map((t,e)=>2*t*n[e]/(t+n[e])),n[3]],l=new Uint8Array(256);for(let t=0;t<256;t++){const r=Math.pow(Math.max(0,Math.min(1,(t/255-e)/(i-e))),1/a),s=Math.min(3,Math.floor(4*r)),n=4*r-s,c=n*n,d=c*n,m=(2*d-3*c+1)*o[s]+(d-2*c+n)*h[s]/4+(-2*d+3*c)*o[s+1]+(d-c)*h[s+1]/4;l[t]=Math.round(255*Math.max(0,Math.min(1,m)))}return l}(t),i=t.curves;if(!e&&(!i||Object.values(i).every(t=>t.every(([t,e])=>t===e))))return null;const a=m(i?.rgb),r=[i?.red,i?.green,i?.blue].map(m),s=new Uint8Array(768);for(let t=0;t<256;t++)for(let i=0;i<3;i++)s[256*i+t]=r[i][a[e?e[t]:t]];return s}var z=class{constructor(t=0){this.amount=0,this.weights=new Float32Array(256),this.source=new Uint8ClampedArray(0),this.configure(t)}configure(t=0){const e=Math.max(0,Math.min(1,Number.isFinite(t)?t:0));if(e===this.amount)return;if(this.amount=e,0===e)return void(this.source=new Uint8ClampedArray(0));const i=8+24*e;for(let t=0;t<256;t++)this.weights[t]=Math.exp(-t*t/(2*i*i))}apply(t,e,i){if(!this.amount)return;if(!Number.isInteger(e)||!Number.isInteger(i)||e<1||i<1||e*i*4!==t.length)throw new Error("Denoise dimensions do not match the source.");this.source.length!==t.length&&(this.source=new Uint8ClampedArray(t.length));const a=this.source;a.set(t);for(let r=0;r<i;r++)for(let s=0;s<e;s++){const o=4*(r*e+s);if(!a[o+3])continue;const n=a[o],h=a[o+1],l=a[o+2];let c=0,d=0,m=0,f=0;for(let t=-1;t<=1;t++){const o=r+t;if(!(o<0||o>=i))for(let i=-1;i<=1;i++){const r=s+i;if(r<0||r>=e)continue;const u=4*(o*e+r);if(!a[u+3])continue;const p=Math.max(Math.abs(a[u]-n),Math.abs(a[u+1]-h),Math.abs(a[u+2]-l)),g=this.weights[p]*(0===i?1:.6)*(0===t?1:.6)*a[u+3];c+=a[u]*g,d+=a[u+1]*g,m+=a[u+2]*g,f+=g}}t[o]=n+(c/f-n)*this.amount,t[o+1]=h+(d/f-h)*this.amount,t[o+2]=l+(m/f-l)*this.amount}}},B=2*Math.PI,W=t=>Math.max(0,Math.min(1,t)),G=Float32Array.from({length:2048},(t,e)=>Math.sin(e/2048*B)),H=t=>G[2047&Math.floor(t*(2048/B))];function V(t,e,i){let a=Math.imul(t,374761393)^Math.imul(e,668265263)^Math.imul(i,1442695041);return a=Math.imul(a^a>>>13,1274126177),((a^a>>>16)>>>0)/4294967296}function J(t){const e=E(t),{density:i,weight:a,angle:r,roughness:s,invert:o,secondaryInk:n,registration:h,seed:l}=e,c=r*Math.PI/180,d=[c,c+Math.PI/2,c+Math.PI/4].map(t=>[Math.cos(t),Math.sin(t)]),m=new Float32Array(6);function f(t,e,i,r,o,n,h,c,f=!1){if(h<=0)return;const[u,p]=d[c],g=-p,M=u,x=g*(e+.5)+M*(i+.5),w=.5*(Math.abs(g)+Math.abs(M)),v=f?1:.5,y=Math.ceil((x-w)/v),b=Math.floor((x+w)/v),S=Math.min(.94*v,.72*v*h*a);t.lineWidth=n*S,t.beginPath();for(let a=y;a<=b;a++){const h=a*v-x,c=.5+g*h,d=.5+M*h;let w=-2,y=2;if(Math.abs(u)>1e-8){const t=-c/u,e=(1-c)/u;w=Math.max(w,Math.min(t,e)),y=Math.min(y,Math.max(t,e))}else if(c<0||c>1)continue;if(Math.abs(p)>1e-8){const t=-d/p,e=(1-d)/p;w=Math.max(w,Math.min(t,e)),y=Math.min(y,Math.max(t,e))}else if(d<0||d>1)continue;if(!(y<=w))if(f){for(let t=0;t<6;t++){const r=w+(y-w)*t/5,s=u*(e+c+u*r)+p*(i+d+p*r);m[t]=.5*H(5.3*s+1.9*a+l)+.25*H(13.1*s+a)}for(let e=0;e<2;e++)for(let i=0;i<6;i++){const a=w+(y-w)*(e?5-i:i)/5,h=m[e?5-i:i],l=.5*S*(1+s*h*.5)*(e?-1:1),f=r+W(c+u*a+g*l)*n,x=o+W(d+p*a+M*l)*n;e||i?t.lineTo(f,x):t.moveTo(f,x)}t.closePath()}else t.moveTo(r+(c+u*w)*n,o+(d+p*w)*n),t.lineTo(r+(c+u*y)*n,o+(d+p*y)*n)}f?t.fill():t.stroke()}return{settings:e,paint(t,e,r,c,m,u,p,g,M,x,w,v,y){const b=W((o?1-g:g)*i);if(b<=0||t.globalAlpha<=0)return;t.fillStyle=M,t.strokeStyle=M;const S=V(r,c,l);if("engraving"===e||"crosshatch"===e||"woodblock"===e){const i=b*(1-s*S*.3);"woodblock"===e?f(t,r,c,m,u,p,Math.ceil(5*i)/5,0,!0):(f(t,r,c,m,u,p,i,0),"crosshatch"===e&&(f(t,r,c,m,u,p,Math.max(0,1.5*i-.3),1),f(t,r,c,m,u,p,Math.max(0,2*i-1.2),2)))}else if("risograph"===e){const e="source"===y?W(.5+(x-v)/510):.5,i=.38*h*p,o=p*Math.min(.48,.44*Math.sqrt(b)*a);t.beginPath(),t.arc(m+.5*p,u+.5*p,o*Math.sqrt(.35+.65*(1-e)),0,B),t.fill(),t.globalCompositeOperation="multiply",t.fillStyle=n;const f=1-s*V(r,c,l+13)*.3;t.beginPath(),t.arc(m+.5*p+i*d[0][0],u+.5*p+i*d[0][1],o*Math.sqrt(.3+.7*e)*f,0,B),t.fill(),t.globalCompositeOperation="source-over"}else{"stipple"===e&&t.beginPath();for(let i=0;i<4;i++){const o=V(2*r+i%2,2*c+(i>>1),l),n=V(r,c,l+11*i+1),h=m+((i%2+.5)/2+(o-.5)*s*.28)*p,d=u+((.5+(i>>1))/2+(n-.5)*s*.28)*p,f=Math.min(h-m,m+p-h,d-u,u+p-d,p*Math.min(.245,.21*a*Math.sqrt(b)*(1-s*o*.35)));if("stipple"===e)t.moveTo(h+f,d),t.arc(h,d,f,0,B);else{const e=(o-.5)*s*64;t.fillStyle="source"===y?`rgb(${Math.round(x+e)},${Math.round(w-.4*e)},${Math.round(v-e)})`:"gray"===y?`rgb(${Math.round(x+e)},${Math.round(x+e)},${Math.round(x+e)})`:M,t.beginPath(),t.ellipse(h,d,f,.64*f,o*Math.PI,0,B),t.fill()}}"stipple"===e&&t.fill()}}}}var Q=new Set(["none","floyd-steinberg","atkinson","stucki","sierra","sierra-lite","burkes","jarvis"]);function K(t){return"dither"===t.style&&("shimmer"===t.dither.motion||"drift"===t.dither.motion&&t.dither.amount>0&&!Q.has(t.dither.algorithm))}function Z(t){return"none"!==t.motion.type&&(t.motion.amount??1)>0}function _(t){return Z(t)||K(t)||t.effects.grain>0||t.effects.dust>0||t.effects.glitch>0}var $="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",tt="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",et=new Uint16Array(4096);for(let t=0;t<et.length;t++)et[t]=$.indexOf(tt[2*t])<<6|$.indexOf(tt[2*t+1]);var it=(t,e)=>{const i=43758.5453*Math.sin(127.1*t+311.7*e);return i-Math.floor(i)};var at=new Map([2,4,8,16].map(t=>[t,Float64Array.from({length:t*t},(e,i)=>function(t,e,i){let a=0;for(let r=1;r<i;r*=2){const i=(Math.floor(t/r)%2+2)%2;a=4*a+[[0,2],[3,1]][(Math.floor(e/r)%2+2)%2][i]}return(a+.5)/(i*i)-.5}(i%t,Math.floor(i/t),t))])),rt={"floyd-steinberg":[[1,0,7/16],[-1,1,3/16],[0,1,5/16],[1,1,1/16]],atkinson:[[1,0,.125],[2,0,.125],[-1,1,.125],[0,1,.125],[1,1,.125],[0,2,.125]],stucki:[[1,0,8/42],[2,0,4/42],[-2,1,2/42],[-1,1,4/42],[0,1,8/42],[1,1,4/42],[2,1,2/42],[-2,2,1/42],[-1,2,2/42],[0,2,4/42],[1,2,2/42],[2,2,1/42]],sierra:[[1,0,5/32],[2,0,3/32],[-2,1,2/32],[-1,1,4/32],[0,1,5/32],[1,1,4/32],[2,1,2/32],[-1,2,2/32],[0,2,3/32],[1,2,2/32]],"sierra-lite":[[1,0,.5],[-1,1,.25],[0,1,.25]],burkes:[[1,0,.25],[2,0,4/32],[-2,1,2/32],[-1,1,4/32],[0,1,.25],[1,1,4/32],[2,1,2/32]],jarvis:[[1,0,7/48],[2,0,5/48],[-2,1,3/48],[-1,1,5/48],[0,1,7/48],[1,1,5/48],[2,1,3/48],[-2,2,1/48],[-1,2,3/48],[0,2,5/48],[1,2,3/48],[2,2,1/48]]},st=t=>[parseInt(t.slice(1,3),16),parseInt(t.slice(3,5),16),parseInt(t.slice(5,7),16)];function ot(t,e,i){const a=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)),r=Math.max(0,Math.min(1,(a-.035)/.105));return r*r*r*(r*(6*r-15)+10)}var nt=t=>["dissolve","silk","vortex","magnetic","scatter","etch","elastic","rake"].includes(t),ht=class{constructor(t,e){this.edgeSafe=!1,this.previous=null,this.peak=0,this.scatterDirections=null,this.springX=null,this.springY=null,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 a=0;a<t;a++)this.edge[i*t+a]=ot(a/(t-1),i/(e-1),t/e);this.clear()}get active(){return this.peak>2e-4}setMode(t){if("elastic"!==t||this.springX||(this.springX=new Float32Array(this.ink.length),this.springY=new Float32Array(this.ink.length)),"scatter"===t&&!this.scatterDirections){const t=this.scatterDirections=new Float64Array(this.width*this.height*2);for(let e=0;e<this.height;e++)for(let i=0;i<this.width;i++){const a=43758.5453*Math.sin(127.1*i+311.7*e),r=(a-Math.floor(a))*Math.PI*2,s=2*(e*this.width+i);t[s]=.7*Math.cos(r),t[s+1]=.7*Math.sin(r)}}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,this.springX?.fill(0),this.springY?.fill(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 a=this.previous;this.previous={x:t,y:e};const r=this.width,s=this.height,o=Math.max(1,r/s),n=Math.max(1,s/r),h=a?(t-a.x)*o:0,l=a?(e-a.y)*n:0,c=Math.hypot(h,l);if(!a&&"dissolve"!==this.mode&&"etch"!==this.mode)return;if(a&&c<1e-4)return;const d=.035+.11*Math.max(.1,Math.min(1,i)),m=Math.min(128,Math.max(1,Math.ceil(c/(.45*d)))),f=c?h/c:1,u=c?l/c:0,p=Math.min(1,c/(d*m)*2.2);for(let i=0;i<m;i++){const h=(i+.5)/m,l=a?a.x+(t-a.x)*h:t,c=a?a.y+(e-a.y)*h:e,g=Math.max(0,Math.floor((l-2.5*d/o)*(r-1))),M=Math.min(r-1,Math.ceil((l+2.5*d/o)*(r-1))),x=Math.max(0,Math.floor((c-2.5*d/n)*(s-1))),w=Math.min(s-1,Math.ceil((c+2.5*d/n)*(s-1)));for(let t=x;t<=w;t++)for(let e=g;e<=M;e++){const i=(e/(r-1)-l)*o/d,a=(t/(s-1)-c)*n/d,h=Math.exp(1.5*-(i*i+a*a)),m=t*r+e;if("dissolve"===this.mode||"etch"===this.mode)this.ink[m]=Math.max(this.ink[m],h);else if("elastic"===this.mode)this.springX[m]=Math.max(-24,Math.min(24,this.springX[m]+f*h*p*8)),this.springY[m]=Math.max(-24,Math.min(24,this.springY[m]+u*h*p*8));else{const r=(-i*u+a*f)*h*2.8,s="rake"===this.mode?f*Math.sin(t*Math.PI/3)*h*2:"magnetic"===this.mode?-i*h*2.5:"scatter"===this.mode?(i+this.scatterDirections[2*m])*h*2:"silk"===this.mode?f*r:-a*h*2.5,o="rake"===this.mode?u*Math.sin(e*Math.PI/3)*h*2:"magnetic"===this.mode?-a*h*2.5:"scatter"===this.mode?(a+this.scatterDirections[2*m+1])*h*2:"silk"===this.mode?u*r:i*h*2.5;this.targetX[m]=Math.max(-1,Math.min(1,this.targetX[m]+s*p)),this.targetY[m]=Math.max(-1,Math.min(1,this.targetY[m]+o*p))}}}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),a=1-Math.exp(-22*e);let r=0;const s=Math.sqrt(336),o=Math.exp(-8*e),n=Math.cos(s*e),h=Math.sin(s*e)/s;for(let t=0;t<this.ink.length;t++)if("etch"===this.mode)this.ink[t]*=i,r=Math.max(r,this.ink[t]);else if("dissolve"===this.mode){this.ink[t]*=i,r=Math.max(r,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{if("elastic"===this.mode){const e=this.offsetX[t],i=this.offsetY[t],a=this.springX[t],s=this.springY[t];this.offsetX[t]=Math.max(-1,Math.min(1,o*(e*n+(a+8*e)*h))),this.offsetY[t]=Math.max(-1,Math.min(1,o*(i*n+(s+8*i)*h))),this.springX[t]=o*(a*n-(8*a+400*e)*h),this.springY[t]=o*(s*n-(8*s+400*i)*h),r=Math.max(r,.05*Math.abs(this.springX[t]),.05*Math.abs(this.springY[t]))}else this.targetX[t]*=i,this.targetY[t]*=i,this.offsetX[t]+=(this.targetX[t]-this.offsetX[t])*a,this.offsetY[t]+=(this.targetY[t]-this.offsetY[t])*a;r=Math.max(r,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.edgeSafe?this.edge[t]:1)*32767+32768),s=Math.round(this.offsetY[t]*(this.edgeSafe?this.edge[t]:1)*32767+32768);this.pixels[4*t]=e>>>8,this.pixels[4*t+1]=255&e,this.pixels[4*t+2]=s>>>8,this.pixels[4*t+3]=255&s}if("etch"===this.mode)for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++){const i=t*this.width+e,a=3*(this.ink[t*this.width+Math.max(0,e-1)]-this.ink[t*this.width+Math.min(this.width-1,e+1)]+this.ink[Math.max(0,t-1)*this.width+e]-this.ink[Math.min(this.height-1,t+1)*this.width+e]);this.offsetX[i]=Math.max(-1,Math.min(1,a))*(this.edgeSafe?this.edge[i]:1);const r=Math.round(32767*this.offsetX[i]+32768);this.pixels[4*i]=r>>>8,this.pixels[4*i+1]=255&r}this.peak=r,this.active||this.clear()}sample(t,e,i){const a=Math.max(0,Math.min(this.width-1.001,t*(this.width-1))),r=Math.max(0,Math.min(this.height-1.001,e*(this.height-1))),s=Math.floor(a),o=Math.floor(r),n=a-s,h=r-o,l=o*this.width+s,c=l+this.width,d=t=>(t[l]*(1-n)+t[l+1]*n)*(1-h)+(t[c]*(1-n)+t[c+1]*n)*h;if("etch"===this.mode)return i[0]=i[1]=0,void(i[2]=3*d(this.offsetX));i[0]=d(this.offsetX)*(this.edgeSafe?ot(t,e,this.width/this.height):1)*.08,i[1]=d(this.offsetY)*(this.edgeSafe?ot(t,e,this.width/this.height):1)*.08,i[2]="dissolve"===this.mode?6*-d(this.ink):0}},lt=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 a=Math.max(1,this.width/this.height),r=Math.max(1,this.height/this.width);this.previous&&(Math.hypot((t-this.previous.x)*a,(e-this.previous.y)*r)<.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),a=Math.max(1,this.height/this.width);let r=0;for(const s of this.rings){const o=.015+s.age*(.15+.22*s.radius),n=.009+.014*s.radius,h=(Math.hypot((t-s.x)*i,(e-s.y)*a)-o)/n,l=Math.sin(Math.min(1,s.age/.07)*Math.PI/2)*Math.max(0,1-s.age/1.35)**2;r=Math.max(r,Math.exp(-h*h)*l)}return r}sample(t,e){const i=Math.max(0,Math.min(this.width-1,Math.round(t*(this.width-1)))),a=Math.max(0,Math.min(this.height-1,Math.round(e*(this.height-1))));return Math.max(this.ringSample(t,e),this.echo[a*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 a=0;for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++){const r=t*this.width+e;this.echo[r]=Math.max(this.ringSample(e/(this.width-1),t/(this.height-1)),this.echo[r]*i),a=Math.max(a,this.echo[r]);const s=Math.round(65535*this.echo[r]),o=4*r;this.pixels[o]=s>>>8,this.pixels[o+1]=255&s}this.echoPeak=a,this.active||(this.echo.fill(0),this.pixels.fill(0))}},ct=class{constructor(t,e){this.previous=null,this.peak=0,this.width=t,this.height=e;const i=t*e;this.pixels=new Uint8Array(4*i),this.signal=new Float32Array(i),this.offsetX=new Float32Array(i),this.offsetY=new Float32Array(i),this.driftX=new Float32Array(i),this.driftY=new Float32Array(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.signal,this.pixels,this.offsetX,this.offsetY,this.driftX,this.driftY])t.fill(0);this.previous=null,this.peak=0}leave(){this.previous=null}move(t,e,i,a=performance.now()){if(!Number.isFinite(t+e+i+a))return;t=Math.max(0,Math.min(1,t)),e=Math.max(0,Math.min(1,e)),i=Math.max(.1,Math.min(1,i));const r=this.previous;if(this.previous={x:t,y:e,time:a},!r)return;const s=(t-r.x)*(this.width-1),o=(e-r.y)*(this.height-1),n=Math.hypot(s,o);if(n<.001)return;const h=Math.min(this.width,this.height),l=a>r.time?Math.max(1/240,(a-r.time)/1e3):1/60,c=Math.min(12,n/h/l),d=1-Math.exp(-c/2.2),m=h*(.022+.075*i)*(.65+.95*d),f=Math.min(128,Math.max(1,Math.ceil(n/(.4*m)))),u=n/m*(.32+.22*d)/f,p=s/n,g=o/n,M=-g,x=p,w=n*(2+18*d)/f;for(let i=0;i<f;i++){const a=(i+.5)/f,s=(r.x+(t-r.x)*a)*(this.width-1),o=(r.y+(e-r.y)*a)*(this.height-1),n=Math.max(1,Math.floor(s-3*m)),h=Math.min(this.width-2,Math.ceil(s+3*m)),l=Math.max(1,Math.floor(o-3*m)),c=Math.min(this.height-2,Math.ceil(o+3*m));for(let t=l;t<=c;t++)for(let e=n;e<=h;e++){const i=((e-s)*p+(t-o)*g)/m,a=((e-s)*M+(t-o)*x)/m,r=Math.exp(-i*i*.65-a*a*1.7),n=t*this.width+e;this.ink[n]=1-(1-this.ink[n])*Math.exp(-r*u);const h=1-a*a*.55,l=i*a*.7;this.u[n]=Math.max(-80,Math.min(80,this.u[n]+(p*h+M*l)*r*w)),this.v[n]=Math.max(-80,Math.min(80,this.v[n]+(g*h+x*l)*r*w))}}this.peak=1}read(t,e,i){const a=0|(e=Math.max(.5,Math.min(this.width-1.5,e))),r=0|(i=Math.max(.5,Math.min(this.height-1.5,i))),s=e-a,o=i-r,n=r*this.width+a;return(t[n]*(1-s)+t[n+1]*s)*(1-o)+(t[n+this.width]*(1-s)+t[n+this.width+1]*s)*o}sample(t,e){return this.read(this.signal,t*(this.width-1),e*(this.height-1))}displacement(t,e,i){i[0]=this.read(this.offsetX,t*(this.width-1),e*(this.height-1)),i[1]=this.read(this.offsetY,t*(this.width-1),e*(this.height-1))}step(t){if(!this.active||!Number.isFinite(t))return;let e=Math.max(0,Math.min(.05,t));const i=this.width,a=this.height;for(;e>1e-7;){const t=Math.min(1/60,e);e-=t;const r=Math.exp(-1.9*t),s=Math.exp(-3.2*t);for(let e=1;e<a-1;e++)for(let o=1;o<i-1;o++){const n=e*i+o,h=Math.max(.5,Math.min(i-1.5,o-this.u[n]*t)),l=Math.max(.5,Math.min(a-1.5,e-this.v[n]*t)),c=0|h,d=0|l,m=h-c,f=l-d,u=d*i+c,p=(1-m)*(1-f),g=m*(1-f),M=(1-m)*f,x=m*f;this.a[n]=(this.u[u]*p+this.u[u+1]*g+this.u[u+i]*M+this.u[u+i+1]*x)*r,this.b[n]=(this.v[u]*p+this.v[u+1]*g+this.v[u+i]*M+this.v[u+i+1]*x)*r,this.c[n]=(this.ink[u]*p+this.ink[u+1]*g+this.ink[u+i]*M+this.ink[u+i+1]*x)*s}[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<a-1;t++)for(let e=1;e<i-1;e++){const a=t*i+e;this.curl[a]=.5*(this.v[a+1]-this.v[a-1]-this.u[a+i]+this.u[a-i])}for(let e=1;e<a-1;e++)for(let a=1;a<i-1;a++){const r=e*i+a,s=Math.abs(this.curl[r+1])-Math.abs(this.curl[r-1]),o=Math.abs(this.curl[r+i])-Math.abs(this.curl[r-i]),n=Math.hypot(s,o)+1e-4,h=this.curl[r]*t*10,l=Math.hypot(this.u[r],this.v[r]);this.u[r]+=o/n*h,this.v[r]-=s/n*h;const c=Math.min(1,l/(Math.hypot(this.u[r],this.v[r])+1e-6));this.u[r]*=c,this.v[r]*=c,this.divergence[r]=-.5*(this.u[r+1]-this.u[r-1]+this.v[r+i]-this.v[r-i])}this.pressure.fill(0);for(let t=0;t<4;t++){for(let t=1;t<a-1;t++)for(let e=1;e<i-1;e++){const a=t*i+e;this.pressureNext[a]=.25*(this.divergence[a]+this.pressure[a-1]+this.pressure[a+1]+this.pressure[a-i]+this.pressure[a+i])}[this.pressure,this.pressureNext]=[this.pressureNext,this.pressure]}let o=0;for(let e=1;e<a-1;e++)for(let a=1;a<i-1;a++){const r=e*i+a;this.u[r]=Math.max(-80,Math.min(80,this.u[r]-.5*(this.pressure[r+1]-this.pressure[r-1]))),this.v[r]=Math.max(-80,Math.min(80,this.v[r]-.5*(this.pressure[r+i]-this.pressure[r-i]))),this.driftX[r]+=(3.6*this.u[r]-58*this.offsetX[r]-12*this.driftX[r])*t,this.driftY[r]+=(3.6*this.v[r]-58*this.offsetY[r]-12*this.driftY[r])*t,this.offsetX[r]=Math.max(-2,Math.min(2,this.offsetX[r]+this.driftX[r]*t)),this.offsetY[r]=Math.max(-2,Math.min(2,this.offsetY[r]+this.driftY[r]*t)),this.signal[r]=1-Math.exp(.06*-Math.hypot(this.u[r],this.v[r])-.16*this.ink[r]),o=Math.max(o,this.signal[r])}this.peak=o}if(this.active)for(let t=0;t<this.ink.length;t++){const e=Math.round(65535*Math.min(1,this.signal[t]));this.pixels[4*t]=e>>>8,this.pixels[4*t+1]=255&e,this.pixels[4*t+2]=Math.round(128+63.5*this.offsetX[t]),this.pixels[4*t+3]=Math.round(128+63.5*this.offsetY[t])}else this.clear()}};function dt(t,e){const i=Math.max(0,Math.min(1,e/.38));return t+(1-2*t)*(i*i*(3-2*i))}var mt=(t,e)=>"water"===t?30*e/.55:"silk"===t?28*e:"vortex"===t?38*e:["magnetic","scatter","elastic","rake"].includes(t)?32*e:0,ft=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]=ot(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 ct(this.columns,this.rows),this.contour=new lt(this.columns,this.rows),this.afterimage=new ht(this.columns,this.rows),this.clear()}get invertsDensity(){return"trail"===this.mode}get densityTrail(){return["trail","contour","dissolve","etch"].includes(this.mode)}get hasRefraction(){return this.active||this.lensStrength>15e-5}get active(){return nt(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,nt(t)&&this.afterimage.setMode(t),this.refraction.pixels="trail"===t?this.trail.pixels:"contour"===t?this.contour.pixels:nt(t)?this.afterimage.pixels:this.waterPixels,this.refraction.strength=mt(t,this.amount))}configure(t,e=.55,i=.2,a=!1){this.setMode(t),this.refraction.edgeSafe=a,this.afterimage.edgeSafe=a,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=mt(t,this.amount),this.refraction.focus[2]=this.densityTrail?this.amount:this.lensStrength*this.amount,this.refraction.focus[3]=this.radius}move(t,e,i){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)),nt(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,i);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 a=this.previous;this.previous={x:t,y:e};const r=(t-a.x)*this.xScale,s=(e-a.y)*this.yScale,o=Math.hypot(r,s);if(o<1e-5)return;const n=.035+.1*this.radius,h=3*n,l=Math.min(192,Math.max(1,Math.ceil(o/(.5*n)))),c=95*Math.min(o,1)/l;for(let i=0;i<l;i++){const r=(i+.5)/l,s=a.x+(t-a.x)*r,o=a.y+(e-a.y)*r,d=Math.max(1,Math.floor((s-h/this.xScale)*(this.columns-1))),m=Math.min(this.columns-2,Math.ceil((s+h/this.xScale)*(this.columns-1))),f=Math.max(1,Math.floor((o-h/this.yScale)*(this.rows-1))),u=Math.min(this.rows-2,Math.ceil((o+h/this.yScale)*(this.rows-1)));for(let t=f;t<=u;t++)for(let e=d;e<=m;e++){const i=(e/(this.columns-1)-s)*this.xScale,a=(t/(this.rows-1)-o)*this.yScale,r=Math.exp(-(i*i+a*a)/(n*n))*c,h=t*this.columns+e;this.velocity[h]=Math.max(-12,this.velocity[h]-r)}}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(nt(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),a=.3*Math.min(this.columns,this.rows);for(;this.remainder+1e-8>=e;){this.remainder-=e;let t=0;for(let r=1;r<this.rows-1;r++)for(let s=1;s<this.columns-1;s++){const o=r*this.columns+s,n=this.heights[o],h=this.heights[o-1]+this.heights[o+1]+this.heights[o-this.columns]+this.heights[o+this.columns]-4*n,l=Math.min(s,r,this.columns-1-s,this.rows-1-r),c=l<5?.88+.024*l:1,d=(this.velocity[o]+(h*a*a-8*n)*e)*i*c;this.velocity[o]=d,this.next[o]=(n+d*e)*c,t=Math.max(t,Math.abs(this.next[o]),.1*Math.abs(d))}this.heights.set(this.next),this.energy=t,this.pending=!1}if(!this.active)return void this.clear();const r=.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,a=(this.heights[t*this.columns+Math.max(0,e-1)]-this.heights[t*this.columns+Math.min(this.columns-1,e+1)])*r,s=(this.heights[Math.max(0,t-1)*this.columns+e]-this.heights[Math.min(this.rows-1,t+1)*this.columns+e])*r,o=Math.tanh(a)*(this.refraction.edgeSafe?this.edgeMask[i]:1),n=Math.tanh(s)*(this.refraction.edgeSafe?this.edgeMask[i]:1);this.normals[2*i]=o,this.normals[2*i+1]=n;const h=Math.round(32767*o+32768),l=Math.round(32767*n+32768);this.refraction.pixels[4*i]=h>>>8,this.refraction.pixels[4*i+1]=255&h,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),a=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)*a,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(nt(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 a=Math.max(0,Math.min(this.columns-1.001,t*(this.columns-1))),r=Math.max(0,Math.min(this.rows-1.001,e*(this.rows-1))),s=Math.floor(a),o=Math.floor(r),n=a-s,h=r-o,l=2*(o*this.columns+s),c=l+2*this.columns;for(let t=0;t<2;t++)i[t]=.08*((this.normals[l+t]*(1-n)+this.normals[l+2+t]*n)*(1-h)+(this.normals[c+t]*(1-n)+this.normals[c+2+t]*n)*h);i[0]*=this.amount/.55,i[1]*=this.amount/.55,i[2]="light"===this.mode||"scan"===this.mode?function(t,e,i,a){const[r,s,o,n]=i.focus,h=(t-r)*Math.max(1,a)/n,l=(e-s)*Math.max(1,1/a)/n;return"light"===i.mode?Math.exp(-3*(h*h+l*l))*o:"scan"===i.mode?(1.3*Math.exp(-h*h*110)-.3*Math.exp(-h*h*12))*Math.exp(-l*l*1.8)*o:0}(t,e,this.refraction,this.xScale/this.yScale):0}};function ut(t){return"videoWidth"in t?[t.videoWidth,t.videoHeight]:"naturalWidth"in t?[t.naturalWidth,t.naturalHeight]:[t.width,t.height]}var pt=(t=!1)=>{const e=document.createElement("canvas"),i=e.getContext("2d",{willReadFrequently:t});if(!i)throw new Error("Canvas 2D is unavailable.");return{canvas:e,ctx:i}},gt=(t,e,i)=>{t.width===e&&t.height===i||(t.width=e,t.height=i)},Mt={blocks:" ░▒▓█",braille:" ⠁⠃⠇⡇⣇⣧⣷⣿",lines:" -═╪╬",cross:" ·+xX#",diagonal:" /╱╳",diamond:" ·◇◈◆",mixed:" .:+/◇#@"};function xt(t,e={},i={}){const a=t.getContext("2d");if(!a)throw new Error("Canvas is already owned by another renderer.");const r=pt(),s=pt(!0),h=pt(),l=pt(),c=pt(),d=pt(),m=pt(),u=pt(),p=pt(),g=pt();let M,x=0,w=N(e),y=0,S="",E="",k="",A=new Uint8ClampedArray(0),P=new Uint8ClampedArray(0),F=0,I=0,C=0,R=null,L="",D=new ft,U=0;const X=[0,0,0],Y=[0,0,0,1],B=[0,0,0,0];let W=q(w.color),G=J(w.print);const H=new z(w.color.denoise),V=new v(w.warps,w.warpEdge),Q=Math.max(64,Math.min(4096,Number.isFinite(i.maxDimension)?i.maxDimension:960)),_=Math.max(256,Math.min(1048576,Number.isFinite(i.maxCells)?i.maxCells:12e3));let $=_,tt=Math.max(.1,Math.min(8,i.pixelRatio??1));return{canvas:t,render:function(e,i=0,v=960,N=540,q=i*w.motion.speed){if(Number.isFinite(i)||(i=0),!Number.isFinite(v)||!Number.isFinite(N)||v<1||N<1)throw new Error("Render dimensions must be positive finite numbers.");const[z,J]=ut(e);if(!z||!J)return;const _=Math.min(1,Q/Math.max(v,N)),ot=Math.max(2,Math.round(v*_)),nt=Math.max(2,Math.round(N*_));gt(t,ot,nt),gt(r.canvas,ot,nt),gt(h.canvas,ot,nt),gt(l.canvas,ot,nt),gt(c.canvas,ot,nt),U!==ot/nt&&(U=ot/nt,D=new ft(U)),D.configure(w.hover.effect,w.hover.strength,w.hover.radius,w.hover.edgeSafe),D.step(Math.max(0,Math.min(.05,i-C))),C=i;const ht="currentTime"in e?e.getVideoPlaybackQuality?.().totalVideoFrames??e.currentTime:0,lt=[y,ot,nt,ht].join(":"),ct="dither"===w.style,mt=j(ot,nt,w,$,tt),pt=mt.cell,xt=mt.rowHeight,wt=mt.columns,vt=mt.rows;if(S!==lt||R!==e||F!==wt||I!==vt){R=e,S=lt,E="",k="",F=wt,I=vt,r.ctx.clearRect(0,0,ot,nt),r.ctx.save();const t=O(z,J,ot,nt,w.crop);r.ctx.translate(t.x+t.width/2,t.y+t.height/2),r.ctx.rotate(w.crop.rotation*Math.PI/180),r.ctx.drawImage(e,-z*t.scale/2,-J*t.scale/2,z*t.scale,J*t.scale),r.ctx.restore(),gt(s.canvas,F,I),s.ctx.clearRect(0,0,F,I),s.ctx.drawImage(r.canvas,0,0,F,I),A=s.ctx.getImageData(0,0,F,I).data,H.apply(A,F,I);const i=w.color;for(let t=0;t<A.length;t+=4){const e=.299*A[t]+.587*A[t+1]+.114*A[t+2];for(let a=0;a<3;a++){const r=e+(A[t+a]-e)*i.saturation;A[t+a]=((r*(1-i.grayscale)+e*i.grayscale)/255-.5)*i.contrast*255+127.5+255*i.brightness}}W&&function(t,e){for(let i=0;i<t.length;i+=4)t[i+3]&&(t[i]=e[t[i]],t[i+1]=e[256+t[i+1]],t[i+2]=e[512+t[i+2]])}(A,W),A=V.apply(A,F,I,ot/nt)}const yt=Z(w),bt=K(w),St=!D.active&&!yt&&!bt,Et=[lt,F,I,pt,xt,tt].join(":");if(!St||k!==Et){h.ctx.clearRect(0,0,ot,nt),h.ctx.globalAlpha=1,h.ctx.globalCompositeOperation="source-over";const t=q,e=yt?w.motion.type:"none",a=["none","caustics","sheen","grain","trace"].includes(e);if(ct){const a=St;if(!a||E!==lt){P.length!==A.length&&(P=new Uint8ClampedArray(A.length));const r=P;if(r.set(A),D.active||"none"!==e)for(let i=0;i<I;i++)for(let a=0;a<F;a++){const s=a/F,h=i/I;let l=a,c=i,d=0,m=1,u=1;D.active&&(D.sample(s,h,X),l-=X[0]*F,c-=X[1]*I,d=X[2]/3);const p=4*(i*F+a);o(e,s,h,t,Y,(.299*A[p]+.587*A[p+1]+.114*A[p+2])/255),n(Y,w.motion.amount??1),l-=Y[0]/960*F,c-=Y[1]/960*I,m=1+Y[2],u=Y[3];const g=4*(i*F+a);f(A,F,I,l,c,B);for(let t=0;t<3;t++){const e=B[t]/255;let i=(["trail","contour"].includes(w.hover.effect)?dt(e,d):"etch"===w.hover.effect?Math.max(0,Math.min(1,e+.35*d)):"dissolve"===w.hover.effect?e*Math.max(0,1+d):e)*m;r[g+t]=255*i}r[g+3]=B[3]*u}!function(t,e,i,a,r=0){const{algorithm:s,amount:o,threshold:n}=a,h="blue-noise"===s,l=s.startsWith("bayer")?Number(s.slice(5)):0,c=at.get(l),d=l-1,m="luminance"===a.colorSpace,f=("custom"===a.palette?a.colors:T[a.palette]??T.mono).map(st),u=rt[s],p=u?new Float32Array(3*e*3):null,g="drift"===a.motion?r*a.speed*3:0,M=(a.direction??45)*Math.PI/180,x=Math.round(Math.cos(M)*g),w=Math.round(Math.sin(M)*g),v=(t,e)=>(t%e+e)%e,y=f.map(t=>.299*t[0]+.587*t[1]+.114*t[2]),b="shimmer"===a.motion?.15*Math.sin(r*a.speed*2):0;for(let a=0;a<i;a++)for(let r=0;r<e;r++){const M=4*(a*e+r),S=3*(a%3*e+r);if(0===t[M+3]){p&&(p[S]=p[S+1]=p[S+2]=0);continue}let E=0;const k=h?(et[64*(a-w&63)+(r-x&63)]+.5)/et.length:0;c?E=c[(a-w&d)*l+(r-x&d)]:"noise"===s?E=it(r-x,a-w)-.5:"lines"===s?E=v(a-w,4)/3-.5:"vertical-lines"===s?E=v(r-x,4)/3-.5:"diagonal-lines"===s?E=v(r-x+a-w,4)/3-.5:"radial"===s?E=v(Math.hypot(r-e/2,a-i/2)-g,6)/6-.5:"halftone"===s&&(E=Math.hypot(v(r-x,6)-2.5,v(a-w,6)-2.5)/3.54-.5);const A=128*(E*o+b+(.5-n)),P=t[M]+A+(p?.[S]??0),T=t[M+1]+A+(p?.[S+1]??0),F=t[M+2]+A+(p?.[S+2]??0);let I=0,C=0,R=0;if(f.length){let t=1/0,e=1/0,i=0,a=0;const r=.299*P+.587*T+.114*F;for(let s=0;s<f.length;s++){const o=f[s],n=m?(r-y[s])**2:(P-o[0])**2*.299+(T-o[1])**2*.587+(F-o[2])**2*.114;n<t?(h&&(e=t,a=i,i=s),t=n,[I,C,R]=o):h&&n<e&&(e=n,a=s)}if(h&&o>0&&Number.isFinite(e)){const t=f[a],e=t[0]-I,s=t[1]-C,n=t[2]-R,h=y[a]-y[i],l=m?h*h:e*e*.299+s*s*.587+n*n*.114,c=m?(r-y[i])*h:(P-I)*e*.299+(T-C)*s*.587+(F-R)*n*.114;k<(l?Math.max(0,Math.min(1,c/l*o)):0)&&([I,C,R]=t)}}else if(h){const t=Math.max(0,Math.min(1,.5+(k-.5)*o));I=51*Math.floor(P/51+1-t),C=51*Math.floor(T/51+1-t),R=51*Math.floor(F/51+1-t)}else I=51*Math.round(P/51),C=51*Math.round(T/51),R=51*Math.round(F/51);if(t[M]=I,t[M+1]=C,t[M+2]=R,p&&u){p[S]=p[S+1]=p[S+2]=0;for(const[t,s,n]of u){const h=r+t;if(h<0||h>=e||a+s>=i)continue;const l=3*((a+s)%3*e+h);p[l]+=(P-I)*n*o,p[l+1]+=(T-C)*n*o,p[l+2]+=(F-R)*n*o}}}}(r,F,I,w.dither,i),s.ctx.putImageData(new ImageData(r,F,I),0,0),E=a?lt:""}h.ctx.imageSmoothingEnabled=!1,h.ctx.drawImage(s.canvas,0,0,ot,nt)}else{const i=Array.from(Mt[w.style]??w.charset),r=h.ctx,s=st(w.ink),l="ascii"===w.style||!!Mt[w.style],c=b(w.style)?w.style:null,d=Math.max(3,Math.round(.92*xt)),u=Math.ceil(pt+4),p=Math.ceil(xt+4),M=[i.join(""),d,u,p,w.ink,w.colorMode].join(":");if(l&&M!==L&&(L=M,gt(m.canvas,u*i.length,p),m.ctx.clearRect(0,0,m.canvas.width,p),m.ctx.font=`${d}px monospace`,m.ctx.textBaseline="middle",m.ctx.textAlign="center",m.ctx.fillStyle="accent"===w.colorMode?w.ink:"#ffffff",i.forEach((t,e)=>m.ctx.fillText(t,e*u+u/2,p/2))),"lego"===w.style&&x!==pt){x=pt,gt(g.canvas,Math.ceil(pt),Math.ceil(xt));const t=g.ctx;t.clearRect(0,0,g.canvas.width,g.canvas.height),t.fillStyle="rgba(255,255,255,.2)",t.strokeStyle="rgba(0,0,0,.25)",t.lineWidth=Math.max(.5,.6*tt),t.beginPath(),t.arc(pt/2,xt/2,.28*pt,0,2*Math.PI),t.fill(),t.stroke()}r.font=`${d}px monospace`,r.textBaseline="middle",r.textAlign="center";for(let h=0;h<I;h++)for(let d=0;d<F;d++){let M=d,x=h,v=0;if(D.active&&(D.sample(d/F,h/I,X),M=Math.max(0,Math.min(F-1,d-X[0]*F)),x=Math.max(0,Math.min(I-1,h-X[1]*I)),v=X[2]/3),f(A,F,I,M,x,B),!B[3])continue;const y=B[0],b=B[1],S=B[2],E=(.299*y+.587*b+.114*S)/255;let k=E;if(["trail","contour"].includes(w.hover.effect)&&v)k=dt(k,v);else if("etch"===w.hover.effect)k=Math.max(0,Math.min(1,k+.35*v));else if("dissolve"===w.hover.effect){const t=Math.max(0,1+v);k=c&&G.settings.invert?1-(1-k)*t:k*t}let P=d*pt,T=h*xt,C=1;o(e,d/F,h/I,t,Y,E),n(Y,w.motion.amount??1),P+=Y[0]*ot/960,T+=Y[1]*nt/960,k=Math.max(0,Math.min(1,k+Y[2])),C=Y[3]*B[3]/255,l||c||"accent"!==w.colorMode||"cmyk"===w.style||(C*=k),r.globalAlpha=C;const R=255*(k-E),L="source"===w.colorMode?`rgb(${y+R},${b+R},${S+R})`:"gray"===w.colorMode?`rgb(${Math.round(255*k)},${Math.round(255*k)},${Math.round(255*k)})`:w.ink;if(r.fillStyle=L,c)G.paint(r,c,d,h,P,T,pt,k,L,"gray"===w.colorMode?255*k:y+R,"gray"===w.colorMode?255*k:b+R,"gray"===w.colorMode?255*k:S+R,w.colorMode);else if(l){const t=Math.max(0,Math.min(i.length-1,Math.round(k*(i.length-1))));"accent"===w.colorMode?r.drawImage(m.canvas,t*u,0,u,p,a?Math.round(P+(pt-u)/2):P+(pt-u)/2,a?Math.round(T+(xt-p)/2):T+(xt-p)/2,u,p):r.fillText(i[t],P+pt/2,T+xt/2)}else if("dots"===w.style)r.beginPath(),r.arc(P+pt/2,T+xt/2,.48*pt*Math.sqrt(k),0,2*Math.PI),r.fill();else if("led"===w.style)r.beginPath(),r.arc(P+pt/2,T+xt/2,.39*pt,0,2*Math.PI),r.fill(),r.globalAlpha=.35*C,r.fillStyle="#ffffff",r.beginPath(),r.arc(P+.43*pt,T+.4*xt,.11*pt,0,2*Math.PI),r.fill();else if("hex"===w.style){const t=P+pt/2,e=T+xt/2;r.beginPath();for(let i=0;i<6;i++){const a=Math.PI/3*i,s=t+Math.cos(a)*pt*.49,o=e+Math.sin(a)*xt*.49;0===i?r.moveTo(s,o):r.lineTo(s,o)}r.closePath(),r.fill()}else if("cmyk"===w.style){r.fillStyle="#ffffff",r.fillRect(P,T,pt,xt);const t=(t,e)=>Math.max(0,Math.min(255,"source"===w.colorMode?t+R:"gray"===w.colorMode?255*k:e*k)),e=t(y,s[0]),i=t(b,s[1]),a=t(S,s[2]),o=1-Math.max(e,i,a)/255,n=Math.max(.001,1-o),h=[["#00ffff",(1-e/255-o)/n,.36,.36],["#ff00ff",(1-i/255-o)/n,.64,.36],["#ffff00",(1-a/255-o)/n,.5,.66],["#000000",o,.5,.5]];r.globalCompositeOperation="multiply";for(const[t,e,i,a]of h)r.fillStyle=t,r.beginPath(),r.arc(P+pt*i,T+xt*a,.48*pt*Math.sqrt(Math.max(0,e)),0,2*Math.PI),r.fill();r.globalCompositeOperation="source-over"}else if("voxel"===w.style){const t=P+pt/2,e=T+xt/2;r.beginPath(),r.moveTo(t,T),r.lineTo(P+pt,T+.25*xt),r.lineTo(t,e),r.lineTo(P,T+.25*xt),r.closePath(),r.fill(),r.globalAlpha=.72*C,r.beginPath(),r.moveTo(P,T+.25*xt),r.lineTo(t,e),r.lineTo(t,T+xt),r.lineTo(P,T+.75*xt),r.closePath(),r.fill(),r.globalAlpha=.42*C,r.beginPath(),r.moveTo(t,e),r.lineTo(P+pt,T+.25*xt),r.lineTo(P+pt,T+.75*xt),r.lineTo(t,T+xt),r.closePath(),r.fill()}else{const t="pixel"===w.style?0:Math.max(.5,.06*pt);r.fillRect(P,T,pt-t,xt-t),"lego"===w.style&&r.drawImage(g.canvas,P,T),"disco"===w.style&&(r.fillStyle=`rgba(255,255,255,${.1+.25*it(d,h)})`,r.fillRect(P,T,pt-t,.35*xt),r.fillStyle="rgba(0,0,0,.25)",r.fillRect(P,T+.65*xt,pt-t,.35*xt-t))}}}h.ctx.globalAlpha=1,(w.color.amount||w.lights.length)&&(gt(u.canvas,ot,nt),u.ctx.clearRect(0,0,ot,nt),u.ctx.drawImage(h.canvas,0,0)),w.color.amount&&(h.ctx.save(),h.ctx.globalCompositeOperation=w.color.blend,h.ctx.globalAlpha=w.color.amount,h.ctx.fillStyle=w.color.tint,h.ctx.fillRect(0,0,ot,nt),h.ctx.restore());for(const t of w.lights){const e=t.radius*Math.max(ot,nt),i=h.ctx.createRadialGradient(t.x*ot,t.y*nt,0,t.x*ot,t.y*nt,e);i.addColorStop(0,t.color),i.addColorStop(1,"transparent"),h.ctx.save(),h.ctx.globalCompositeOperation="screen",h.ctx.globalAlpha=t.intensity,h.ctx.fillStyle=i,h.ctx.fillRect(0,0,ot,nt),h.ctx.restore()}if((w.color.amount||w.lights.length)&&(h.ctx.globalCompositeOperation="destination-in",h.ctx.drawImage(u.canvas,0,0),h.ctx.globalCompositeOperation="source-over"),w.mask.enabled&&w.mask.shapes.length){const t=c.ctx;t.clearRect(0,0,ot,nt),t.fillStyle="#fff",t.strokeStyle="#fff",t.lineCap="round",t.lineJoin="round";for(const e of w.mask.shapes){if(t.beginPath(),"ellipse"===e.kind)t.ellipse((e.x+e.width/2)*ot,(e.y+e.height/2)*nt,e.width*ot/2,e.height*nt/2,0,0,2*Math.PI);else{if("rectangle"!==e.kind){if(t.lineWidth=(e.size??.05)*ot,1===e.points?.length){t.arc(e.points[0][0]*ot,e.points[0][1]*nt,t.lineWidth/2,0,2*Math.PI),t.fill();continue}e.points?.forEach(([e,i],a)=>a?t.lineTo(e*ot,i*nt):t.moveTo(e*ot,i*nt)),t.stroke();continue}t.rect(e.x*ot,e.y*nt,e.width*ot,e.height*nt)}t.fill()}h.ctx.globalCompositeOperation=w.mask.invert?"destination-out":"destination-in",h.ctx.drawImage(c.canvas,0,0),h.ctx.globalCompositeOperation="source-over"}const M=l.ctx;M.clearRect(0,0,ot,nt),M.globalAlpha=w.backdrop.opacity;const v=w.backdrop;if("solid"===v.mode&&(M.fillStyle=v.color,M.fillRect(0,0,ot,nt)),"gradient"===v.mode){const t=M.createLinearGradient(0,0,ot,nt);t.addColorStop(0,v.color),t.addColorStop(1,v.color2),M.fillStyle=t,M.fillRect(0,0,ot,nt)}if("source"===v.mode&&M.drawImage(r.canvas,0,0),"blurred"===v.mode){const t=Math.max(1,v.blur);gt(d.canvas,Math.max(2,Math.round(ot/t)),Math.max(2,Math.round(nt/t))),d.ctx.drawImage(r.canvas,0,0,d.canvas.width,d.canvas.height),M.imageSmoothingEnabled=!0,M.drawImage(d.canvas,0,0,ot,nt)}M.globalAlpha=1,w.effects.characterBloom>0&&(gt(p.canvas,Math.max(2,Math.round(ot/3)),Math.max(2,Math.round(nt/3))),p.ctx.clearRect(0,0,p.canvas.width,p.canvas.height),p.ctx.drawImage(h.canvas,0,0,p.canvas.width,p.canvas.height),M.save(),M.globalAlpha=.8*w.effects.characterBloom,M.globalCompositeOperation="screen",M.filter=`blur(${1+4*w.effects.characterBloom}px)`,M.drawImage(p.canvas,0,0,ot,nt),M.restore()),M.drawImage(h.canvas,0,0),k=St?Et:""}const kt=Object.entries(w.effects).some(([t,e])=>!["angle","focus","blurType","characterBloom"].includes(t)&&"number"==typeof e&&e>0);a.clearRect(0,0,ot,nt),kt?(void 0===M&&(M=function(){const t=document.createElement("canvas"),e=t.getContext("webgl",{alpha:!0,premultipliedAlpha:!1,antialias:!1,preserveDrawingBuffer:!0});if(!e)return null;const i=[],a=(t,a)=>{const r=e.createShader(t);if(i.push(r),e.shaderSource(r,a),e.compileShader(r),!e.getShaderParameter(r,e.COMPILE_STATUS))throw new Error(e.getShaderInfoLog(r)||"Finish shader failed");return r},r=e.createProgram();if(e.attachShader(r,a(e.VERTEX_SHADER,"attribute vec2 p;varying vec2 uv;void main(){uv=(p+1.)*.5;gl_Position=vec4(p,0.,1.);}")),e.attachShader(r,a(e.FRAGMENT_SHADER,"precision mediump float;varying vec2 uv;uniform sampler2D src;uniform vec2 size;uniform float t,bloom,grain,dust,scanlines,crt,prism,vignette,glitch,pixelate,blur,blurMode,angle,focus,halftone,rgbSplit,sharpen;\n float hash(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}\n vec4 sampleAt(vec2 p){if(min(min(p.x,p.y),min(1.-p.x,1.-p.y))<0.)return vec4(0.);return texture2D(src,vec2(p.x,1.-p.y));}\n void main(){vec2 q=uv,c=q-.5;q=c*(1.+dot(c,c)*crt*.25)+.5;\n if(glitch>0.)q.x+=(hash(vec2(floor(q.y*35.),floor(t*5.)))-.5)*.07*glitch*step(.82,hash(vec2(floor(q.y*35.),floor(t*5.)+3.)));\n if(pixelate>0.){vec2 grid=size/(1.+pixelate*20.);q=(floor(q*grid)+.5)/grid;}\n vec4 base=sampleAt(q);float edge=smoothstep(.12,.65,length(c));\n vec2 shift=vec2((prism*3.*edge+rgbSplit*8.)/size.x,prism*edge/size.y);\n if(prism>0.||rgbSplit>0.)base.rgb=vec3(sampleAt(q+shift).r,base.g,sampleAt(q-shift).b);\n vec2 dir=vec2(cos(angle),sin(angle))/size;float amount=blur;\n if(blurMode>1.5&&blurMode<2.5){dir=normalize(c+vec2(.0001))/size;amount*=length(c)*2.;}\n if(blurMode>2.5)amount*=smoothstep(.05,.5,abs(q.y-focus));\n vec4 blurred=base;\n if(amount>0.){blurred=base*.2;for(int i=1;i<=4;i++){float f=float(i)*amount*.35;vec2 off=dir*f;if(blurMode<.5)off=vec2(cos(float(i)*1.57),sin(float(i)*1.57))*amount/size;blurred+=sampleAt(q+off)*.1+sampleAt(q-off)*.1;}}\n vec3 light=vec3(0.);if(bloom>0.)for(int i=0;i<4;i++){float a=float(i)*1.5708;vec3 s=sampleAt(q+vec2(cos(a),sin(a))*6./size).rgb;light+=max(vec3(0.),s-.35)*.25;}\n vec3 col=blurred.rgb+light*bloom;\n if(sharpen>0.){vec2 px=1./size;vec3 near=sampleAt(q+vec2(px.x,0.)).rgb+sampleAt(q-vec2(px.x,0.)).rgb+sampleAt(q+vec2(0.,px.y)).rgb+sampleAt(q-vec2(0.,px.y)).rgb;col+=(base.rgb*4.-near)*sharpen*.5;}\ncol*=1.-scanlines*.4*(.5+.5*cos(q.y*size.y*3.14159));\n col*=1.-vignette*smoothstep(.15,.72,length(c));\n col+=(hash(floor(q*size)+floor(t*12.))-.5)*grain*.2;\n if(dust>0.)col+=step(1.-dust*.002,hash(floor(q*size*.25)+floor(t*2.)))*.4;\n if(halftone>0.)col*=mix(1.,smoothstep(.1,.65,length(fract(q*size/6.)-.5)),halftone);\n gl_FragColor=vec4(clamp(col,0.,1.),blurred.a);}")),e.linkProgram(r),!e.getProgramParameter(r,e.LINK_STATUS))throw new Error("Finish link failed");e.useProgram(r);const s=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,s),e.bufferData(e.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),e.STATIC_DRAW);const o=e.getAttribLocation(r,"p");e.enableVertexAttribArray(o),e.vertexAttribPointer(o,2,e.FLOAT,!1,0,0);const n=e.createTexture();e.bindTexture(e.TEXTURE_2D,n),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE);const h=["t","bloom","grain","dust","scanlines","crt","prism","rgbSplit","sharpen","vignette","glitch","pixelate","blur","blurMode","angle","focus","halftone"],l=Object.fromEntries(h.map(t=>[t,e.getUniformLocation(r,t)])),c=e.getUniformLocation(r,"size");return{canvas:t,render(i,a,s,o=1){t.width===i.width&&t.height===i.height||(t.width=i.width,t.height=i.height,e.viewport(0,0,t.width,t.height)),e.useProgram(r),e.bindTexture(e.TEXTURE_2D,n),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,i),e.uniform2f(c,t.width/o,t.height/o);for(const t of h)e.uniform1f(l[t],"t"===t?s:"blurMode"===t?["gaussian","directional","radial","progressive"].indexOf(a.blurType):"angle"===t?a.angle*Math.PI/180:a[t]??0);return e.drawArrays(e.TRIANGLE_STRIP,0,4),t},destroy(){e.deleteTexture(n),e.deleteBuffer(s),e.deleteProgram(r),i.forEach(t=>e.deleteShader(t)),t.width=t.height=1,e.getExtension("WEBGL_lose_context")?.loseContext()}}}()),M?a.drawImage(M.render(l.canvas,w.effects,i,tt),0,0):a.drawImage(l.canvas,0,0),t.dataset.studioFinish=M?"gpu":"unavailable"):(a.drawImage(l.canvas,0,0),t.dataset.studioFinish="none")},setPixelRatio(t){tt=Math.max(.1,Math.min(8,Number.isFinite(t)?t:1))},get pixelRatio(){return tt},setBudget(t){$=Math.max(256,Math.min(_,Number.isFinite(t)?Math.round(t):_))},get maxCells(){return $},configure(t){w=N(t),W=q(w.color),G=J(w.print),H.configure(w.color.denoise),V.configure(w.warps,w.warpEdge),y++},pointer:(t,e,i)=>{D.configure(w.hover.effect,w.hover.strength,w.hover.radius,w.hover.edgeSafe),D.move(t,e,i)},leave(){D.leave()},get active(){return D.active},get settings(){return N(w)},get capabilities(){return{gpuFinish:null!==M}},invalidate(){S=""},destroy(){M?.destroy(),V.clear(),H.configure(0);for(const t of[r,s,h,l,c,d,m,u,p,g])t.canvas.width=t.canvas.height=1;R=null,A=new Uint8ClampedArray(0),P=new Uint8ClampedArray(0)}}}function wt(t,e,i){return new Promise((a,r)=>{const s=()=>{l(),a()},o=()=>{l(),r(new Error("Unable to load this media. Check its format and cross-origin permissions."))},n=()=>{l(),r(new DOMException("Cancelled","AbortError"))},h=setTimeout(o,2e4),l=()=>{clearTimeout(h),t.removeEventListener(e,s),t.removeEventListener("error",o),i?.removeEventListener("abort",n)};t.addEventListener(e,s,{once:!0}),t.addEventListener("error",o,{once:!0}),i?.addEventListener("abort",n,{once:!0}),i?.aborted&&n()})}async function vt(t,e){if("string"==typeof t&&t.startsWith("blob:")){const i=await fetch(t,{signal:e}),a=await i.blob();return vt(new File([a],"Imported media",{type:a.type}),e)}const i="string"!=typeof t,a=i?t.name:t;if(i?"image/gif"===t.type:/\.gif(?:[?#]|$)/i.test(a)){const a=await import("gifuct-js"),{parseGIF:r,decompressFrames:s}="function"==typeof a.parseGIF?a:a.default,o=i?await t.arrayBuffer():await fetch(t,{signal:e}).then(t=>{if(!t.ok)throw new Error("GIF download failed.");return t.arrayBuffer()});if(e?.aborted)throw new DOMException("Cancelled","AbortError");const n=r(o),h=n.lsd.width,l=n.lsd.height;if(h*l>4e6)throw new Error("GIF is too large. Use a smaller GIF or an MP4.");const c=n.frames.filter(t=>"image"in t).length;if(!c||c*h*l*4>128e6)throw new Error("GIF exceeds the decoded memory budget. Use MP4 for long animations.");const d=s(n,!0);if(d.length*h*l*4>128e6)throw new Error("GIF exceeds the 128 MB decoded budget. Use MP4 for long animations.");const m=document.createElement("canvas");m.width=h,m.height=l;const f=m.getContext("2d"),u=document.createElement("canvas"),p=u.getContext("2d"),g=d.reduce((t,e)=>t+Math.max(20,e.delay),0)/1e3;let M=-1,x=null;const w=t=>{const e=(t%g+g)%g*1e3;let i=0,a=0;for(;a<d.length-1&&(i+=Math.max(20,d[a].delay),!(e<i));a++);a<M&&(f.clearRect(0,0,h,l),M=-1,x=null);for(let t=M+1;t<=a;t++){const e=d[t-1];2===e?.disposalType&&f.clearRect(e.dims.left,e.dims.top,e.dims.width,e.dims.height),3===e?.disposalType&&x&&f.putImageData(x,0,0);const i=d[t];x=3===i.disposalType?f.getImageData(0,0,h,l):null,u.width=i.dims.width,u.height=i.dims.height,p.putImageData(new ImageData(new Uint8ClampedArray(i.patch),u.width,u.height),0,0),f.drawImage(u,i.dims.left,i.dims.top)}return M=a,m};return w(0),{source:m,width:h,height:l,duration:g,animated:!0,seek:async()=>{},frame:w,destroy(){m.width=u.width=1,d.length=0,x=null}}}const r=i?t.type.startsWith("video/"):/\.(mp4|webm|mov)(?:[?#]|$)/i.test(a),s=i?URL.createObjectURL(t):t,o=r?document.createElement("video"):new Image;o.crossOrigin="anonymous",o instanceof HTMLVideoElement&&(o.muted=!0,o.playsInline=!0,o.preload="auto");const n=()=>{o instanceof HTMLVideoElement?(o.pause(),o.removeAttribute("src"),o.load()):o.src="",i&&URL.revokeObjectURL(s)};try{const t=wt(o,r?"loadeddata":"load",e);o.src=s,await t;const i=o instanceof HTMLVideoElement?o.videoWidth:o.naturalWidth,a=o instanceof HTMLVideoElement?o.videoHeight:o.naturalHeight;return{source:o,width:i,height:a,duration:o instanceof HTMLVideoElement?o.duration:0,animated:r,async seek(t,e){if(!(o instanceof HTMLVideoElement))return;if(!Number.isFinite(o.duration)||o.duration<=0)throw new Error("Video duration is unavailable.");const i=Math.max(0,Math.min(o.duration-.001,t%o.duration));if(Math.abs(o.currentTime-i)<.001&&o.readyState>=2)return;const a=wt(o,"seeked",e);o.currentTime=i,await a},frame:()=>o,destroy:n}}catch(t){throw n(),t}}var yt=t=>{if(t?.aborted)throw new DOMException("Export cancelled","AbortError")};async function bt(t,e){const{format:i,signal:a}=e,r=Math.round(e.width),s=Math.round(e.height);if(!Number.isFinite(r)||!Number.isFinite(s)||r<2||s<2||r>4096||s>4096||r*s>16777216)throw new Error("Choose export dimensions between 2 and 4096 pixels.");if(!["png","jpeg","mp4","webm","gif"].includes(i))throw new Error("Unknown export format.");if(void 0!==e.fps&&!Number.isFinite(e.fps))throw new Error("Frames per second must be finite.");const o=Math.max(1,Math.min(60,Math.round(e.fps??24))),n=e.duration??5;if(!Number.isFinite(n)||n<=0||n>60)throw new Error("Choose a duration from 0 to 60 seconds.");const h="png"===i||"jpeg"===i,l=e.time??0;if(!Number.isFinite(l)||l<0)throw new Error("Image time must be a finite non-negative number.");if(void 0!==e.motionTime&&(!Number.isFinite(e.motionTime)||e.motionTime<0))throw new Error("Motion time must be a finite non-negative number.");if(!h&&r*s>8294400)throw new Error("Video exports support up to 3840 × 2160 pixels.");if("gif"===i&&(r*s>921600||n*o>600))throw new Error("GIF export supports up to 1280 × 720 and 600 frames. Use MP4 for larger exports.");if(void 0!==e.referenceWidth&&(!Number.isFinite(e.referenceWidth)||e.referenceWidth<1))throw new Error("Reference width must be a positive number.");if("gif"===i&&o>30)throw new Error("GIF exports support up to 30 fps. Choose MP4 or WebM for higher frame rates.");const c=document.createElement("canvas");let d;try{if(yt(a),e.onProgress?.(0),h){if(await t(c,l,r,s,a,e.motionTime),"unavailable"===c.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");yt(a);const o=await new Promise((t,a)=>c.toBlob(e=>e?t(e):a(new Error("Image export failed.")),"png"===i?"image/png":"image/jpeg",e.quality??.92));return yt(a),e.onProgress?.(1),o}const m=Math.ceil(n*o);if("gif"===i){const i=await import("gifenc"),{GIFEncoder:h,quantize:l,applyPalette:d}="function"==typeof i.GIFEncoder?i:i.default,f=h(),u=c.getContext("2d");for(let i=0;i<m;i++){yt(a);const h=i/o;if(await t(c,h,r,s,a),yt(a),"unavailable"===c.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");const p=u.getImageData(0,0,r,s).data,g=l(p,256),M=d(p,g);f.writeFrame(M,r,s,{palette:g,delay:10*(Math.round(100*Math.min((i+1)/o,n))-Math.round(100*i/o)),repeat:0}),e.onProgress?.((i+1)/m*.98),await new Promise(t=>setTimeout(t,0))}return yt(a),f.finish(),e.onProgress?.(1),new Blob([new Uint8Array(f.bytes())],{type:"image/gif"})}const{Output:f,Mp4OutputFormat:u,WebMOutputFormat:p,BufferTarget:g,CanvasSource:M,canEncodeVideo:x}=await import("mediabunny"),w="mp4"===i?"avc":"vp9";if(!await x(w,{width:r,height:s}))throw new Error(`${i.toUpperCase()} encoding is unavailable in this browser. Try another format or a current browser with WebCodecs.`);const v=new f({format:"mp4"===i?new u({fastStart:"in-memory"}):new p,target:new g});c.width=r,c.height=s,d=()=>v.cancel();const y=new M(c,{codec:w,bitrate:Math.max(5e5,Math.round(r*s*o*.15))});v.addVideoTrack(y,{frameRate:o}),c.width=r,c.height=s,await v.start();for(let i=0;i<m;i++){yt(a);const h=i/o;if(await t(c,h,r,s,a),yt(a),"unavailable"===c.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");await y.add(h,Math.min(1/o,n-h)),e.onProgress?.((i+1)/m*.98),i%4==0&&await new Promise(t=>setTimeout(t,0))}return y.close(),yt(a),await v.finalize(),yt(a),d=void 0,e.onProgress?.(1),new Blob([v.target.buffer],{type:"mp4"===i?"video/mp4":"video/webm"})}catch(t){throw await(d?.().catch(()=>{})),t}finally{c.width=c.height=1}}function St(t,e,i={}){let a=N(i.settings),r=i.width??e.width,o=i.height??e.height;const n=xt(t,a,i),h=new s;let l=0,c=!1,d=!0,m=!1,f=!0,u=0,p=0,g=0,M=0,x=-1,w=!1!==i.adaptive,v=0,y=0,b=0;const S=matchMedia("(prefers-reduced-motion: reduce)"),E=e.source instanceof HTMLVideoElement?e.source:null,k=()=>{c||l||!f||document.hidden||(l=requestAnimationFrame(T))},A=()=>!m&&!S.matches&&f&&!document.hidden,P=()=>{E&&(E.loop=!0,A()?E.play().catch(()=>{m=!0,d=!0,k()}):E.pause()),g=0,d=!0,k()};function T(t){if(l=0,c||!f||document.hidden)return;const s=A();s&&(u+=g?Math.min(.1,(t-g)/1e3):0),g=t;const S=_(a),P=s&&(e.animated||S),T=E?.getVideoPlaybackQuality?.().totalVideoFrames??-1,F=!E||T<0||T!==x;if(d||n.active||P&&(F||S)&&t-M>=1e3/Math.max(1,Math.min(60,i.fps??60))-.5){const s=performance.now();try{e.animated&&!E&&n.invalidate();const[t,l]=D(r,o,a);p=h.update(u,a.motion.type,a.motion.speed),n.render(e.frame(E?.currentTime??u),u,t,l,p);const c=performance.now()-s;i.onFrame?.(E?.currentTime??u,c),y=y?.9*y+.1*c:c,++v>20&&w&&(P||n.active)&&(b=y>13?b+1:0,b>=12&&n.maxCells>3e3&&(n.setBudget(Math.max(3e3,.8*n.maxCells)),i.onQualityChange?.(n.maxCells),b=0,y=0))}catch(t){m=!0,i.onError?.(t instanceof Error?t:new Error(String(t)))}d=!1,M=t,x=T}s&&(P||n.active)&&k()}const F=e=>{if(!A())return;const i=t.getBoundingClientRect();n.pointer((e.clientX-i.left)/i.width,(e.clientY-i.top)/i.height,e.timeStamp),k()},I=()=>{n.leave(),k()},C=new IntersectionObserver(([t])=>{f=t.isIntersecting,P()});C.observe(t),t.addEventListener("pointermove",F),t.addEventListener("pointerleave",I),t.addEventListener("pointercancel",I),document.addEventListener("visibilitychange",P),S.addEventListener("change",P);const R=()=>{c||(c=!0,cancelAnimationFrame(l),C.disconnect(),t.removeEventListener("pointermove",F),t.removeEventListener("pointerleave",I),t.removeEventListener("pointercancel",I),document.removeEventListener("visibilitychange",P),S.removeEventListener("change",P),i.signal?.removeEventListener("abort",R),n.destroy(),e.destroy())};if(i.signal?.addEventListener("abort",R,{once:!0}),i.signal?.aborted)throw R(),new DOMException("Cancelled","AbortError");return P(),{canvas:t,media:e,update(t){a=U(a,t),n.configure(a),d=!0,k()},resize(t,e,i){void 0!==i&&n.setPixelRatio(i),r=Math.max(2,t),o=Math.max(2,e),d=!0,k()},pause(t=!0){m=t,P()},async seek(t){u=Math.max(0,t),await e.seek(u),n.invalidate(),d=!0,k()},redraw(){n.invalidate(),d=!0,k()},get time(){return E?.currentTime??u},get settings(){return N(a)},get motionTime(){return p},get paused(){return m||S.matches},setAdaptive(t){w=t,v=b=y=0},setBudget(t){n.setBudget(t),i.onQualityChange?.(n.maxCells),d=!0,k()},get pixelRatio(){return n.pixelRatio},get maxCells(){return n.maxCells},get capabilities(){return n.capabilities},destroy:R}}var Et={Standard:()=>import("figlet/fonts/Standard"),Slant:()=>import("figlet/fonts/Slant"),Small:()=>import("figlet/fonts/Small"),Big:()=>import("figlet/fonts/Big"),Banner:()=>import("figlet/fonts/Banner"),Block:()=>import("figlet/fonts/Block"),Bubble:()=>import("figlet/fonts/Bubble"),Digital:()=>import("figlet/fonts/Digital"),Doom:()=>import("figlet/fonts/Doom"),Lean:()=>import("figlet/fonts/Lean"),Mini:()=>import("figlet/fonts/Mini"),Script:()=>import("figlet/fonts/Script"),Shadow:()=>import("figlet/fonts/Shadow"),Speed:()=>import("figlet/fonts/Speed"),Starwars:()=>import("figlet/fonts/Star Wars"),Stop:()=>import("figlet/fonts/Stop"),Straight:()=>import("figlet/fonts/Straight"),Thin:()=>import("figlet/fonts/Thin"),ThreeD:()=>import("figlet/fonts/3-D"),Univers:()=>import("figlet/fonts/Univers"),Wavy:()=>import("figlet/fonts/Wavy")},kt=Object.keys(Et);async function At(t,e="Standard",i="#ffffff",a="#080808"){if(!Object.prototype.hasOwnProperty.call(Et,e))throw new Error("Unknown text font.");const{default:r}=await import("figlet/browser"),s=await Et[e]();r.parseFont(e,s.default),r.defaults({fetchFontIfMissing:!1});const o=r.textSync(t.slice(0,120),{font:e}),n=o.split("\n"),h=Math.max(1,...n.map(t=>t.length)),l=Math.max(1,n.length),c=Math.min(1,2048/(9*h)),d=document.createElement("canvas");d.width=Math.ceil(9*h*c+32),d.height=Math.ceil(15*l*c+32);const m=d.getContext("2d");return null!==a&&(m.fillStyle=a,m.fillRect(0,0,d.width,d.height)),m.fillStyle=i,m.font=15*c+"px monospace",m.textBaseline="top",n.forEach((t,e)=>m.fillText(t,16,16+15*e*c)),{canvas:d,ascii:o}}var Pt={standard:{label:"Classic ASCII",chars:" .:-=+*#%@"},asciify:{label:"Asciify",chars:" .:-=+ASCIIFY#@"},minimal:{label:"Minimal",chars:" .:+"},detailed:{label:"Detailed",chars:" .,:;i1tfLCG08@"},letters:{label:"Letters",chars:" .ilLCFTYASMW"},technical:{label:"Technical",chars:" .:;>_/[{}]=+*#@$"},blocks:{label:"Tonal blocks",chars:" ░▒▓█"},braille:{label:"Braille",chars:" ⠁⠃⠇⡇⣇⣧⣷⣿"}},Tt=Pt,Ft=t=>t&&"object"==typeof t&&!Array.isArray(t)?t:{},It=(t,e,i,a)=>"number"==typeof t&&Number.isFinite(t)?Math.max(i,Math.min(a,t)):e,Ct=(t,e)=>{if("string"!=typeof t||!/^[a-zA-Z0-9][a-zA-Z0-9:_-]{0,63}$/.test(t))throw new Error(`${e} must be 1–64 letters, numbers, colons, dashes or underscores, starting with a letter or number.`);return t};function Rt(t={}){const e=Ft(t);if(void 0!==e.kind&&"asciify-project"!==e.kind||void 0!==e.version&&1!==e.version)throw new Error("Unsupported Studio project. Update asciify-engine.");if(void 0!==e.layers&&!Array.isArray(e.layers))throw new Error("Project layers must be an array.");const i=Array.isArray(e.layers)?e.layers:[];if(i.length>8)throw new Error("A project supports up to 8 layers.");const a=new Set;return{kind:"asciify-project",version:1,width:Math.round(It(e.width,1280,2,4096)),height:Math.round(It(e.height,720,2,4096)),background:null===e.background?null:"string"==typeof e.background&&/^#[a-f\d]{6}$/i.test(e.background)?e.background:"#0c1711",pointerMode:"all"===e.pointerMode?"all":"top",layers:i.map((t,e)=>{const i=Ft(t),r=Ft(i.placement),s=Ft(i.settings),o=Ft(s.backdrop),n=Ct(i.id,"Layer id"),h=Ct(i.source,"Source key");if(a.has(n))throw new Error(`Duplicate layer id: ${n}`);return a.add(n),{id:n,source:h,name:"string"==typeof i.name?i.name.slice(0,80):`Layer ${e+1}`,visible:!1!==i.visible,opacity:It(i.opacity,1,0,1),blend:P.includes(i.blend)?i.blend:"source-over",placement:{x:It(r.x,.5,-1,2),y:It(r.y,.5,-1,2),width:It(r.width,1,.01,2),height:It(r.height,1,.01,2),rotation:It(r.rotation,0,-180,180),flipX:!0===r.flipX,flipY:!0===r.flipY},settings:N({...s,backdrop:{mode:"transparent",...o}})}})}}function Lt(t,e,i){if(!t.layers.some(t=>t.id===e))throw new Error(`Unknown layer: ${e}`);return Rt({...t,layers:t.layers.map(t=>t.id!==e?t:{...t,...i,id:e,placement:{...t.placement,...i.placement},settings:U(t.settings,i.settings??{})})})}function Nt(t,e,i,a,r){const s=t.placement,o=s.rotation*Math.PI/180,n=Math.cos(o),h=Math.sin(o),l=(e-s.x)*a,c=(i-s.y)*r,d=(l*n+c*h)/(s.width*a),m=(-l*h+c*n)/(s.height*r);return[.5+d*(s.flipX?-1:1),.5+m*(s.flipY?-1:1)]}function Ot(t){return t.layers.filter(e=>{if(!e.visible||e.opacity<=0)return!1;const i=e.placement,a=i.rotation*Math.PI/180,r=Math.abs(Math.cos(a)),s=Math.abs(Math.sin(a)),o=(r*i.width*t.width+s*i.height*t.height)/2,n=(s*i.width*t.width+r*i.height*t.height)/2;return i.x*t.width+o>0&&i.x*t.width-o<t.width&&i.y*t.height+n>0&&i.y*t.height-n<t.height})}function Dt(t,e=24e3,i=4194304,a=t.width,r=t.height){const s=Ot(t),o=Math.round(It(e,24e3,2048,1048576)),n=It(i,4194304,65536,16777216),h=s.map(t=>t.placement.width*t.placement.height),l=h.reduce((t,e)=>t+e,0),c=o-256*s.length,d=s.map(t=>{const e=a*t.placement.width,i=r*t.placement.height,s=Math.min(1,4096/Math.max(e,i));return{width:Math.max(2,e*s),height:Math.max(2,i*s)}}),m=d.reduce((t,e)=>t+e.width*e.height,0);let f=0,u=0;return s.map((t,e)=>{const i=e===s.length-1?o-f:256+Math.floor(c*h[e]/l);f+=i;const a=d[e],r=e===s.length-1?n-u:4+Math.floor((n-4*s.length)*a.width*a.height/Math.max(1,m));u+=r;const p=Math.min(1,Math.sqrt(r/(a.width*a.height)));let g=Math.max(2,Math.floor(a.width*p)),M=Math.max(2,Math.floor(a.height*p));return g*M>r&&(g>=M?g=Math.max(2,Math.floor(r/M)):M=Math.max(2,Math.floor(r/g))),{id:t.id,maxCells:i,width:g,height:M}})}function Ut(t,e={},i={}){const a=t.getContext("2d");if(!a)throw new Error("Project canvas is already owned by another renderer.");let r=Rt(e),s=!0,o=!1,n=new Map(r.layers.map(t=>[t.id,JSON.stringify(t.settings)]));const h=Math.max(64,Math.min(4096,Number.isFinite(i.maxDimension)?i.maxDimension:960)),l=Math.max(2048,Math.min(1048576,Number.isFinite(i.maxCells)?i.maxCells:24e3));let c=l,d=Math.max(.1,Math.min(8,Number.isFinite(i.pixelRatio)?i.pixelRatio:1)),m=[];const f=new Map,u=()=>{if(o)throw new Error("Project renderer has been destroyed.")};return{canvas:t,render(e,o=0,p=r.width,g=r.height,M={}){if(u(),!Number.isFinite(p)||!Number.isFinite(g)||p<2||g<2)throw new Error("Project dimensions must be positive finite numbers.");const x=Math.min(1,h/Math.max(p,g)),w=Math.max(2,Math.round(p*x)),v=Math.max(2,Math.round(g*x));t.width===w&&t.height===v||(t.width=w,t.height=v,s=!0);const y={...r,width:w,height:v},b=Ot(y);for(const t of b)if(!e.has(t.source))throw new Error(`Missing project source: ${t.source}`);const S=new Set(b.map(t=>t.id));for(const[t,e]of f)S.has(t)||(e.renderer.destroy(),f.delete(t),s=!0);m=Dt(y,c,i.maxRasterPixels,w,v);for(let t=0;t<b.length;t++){const i=b[t],a=m[t],r=e.get(i.source);if(!r)throw new Error(`Missing project source: ${i.source}`);let h=f.get(i.id);const c=n.get(i.id);h?h.signature!==c&&(h.renderer.configure(i.settings),h.signature=c,h.dirty=!0):(h={renderer:xt(document.createElement("canvas"),i.settings,{maxDimension:4096,maxCells:l}),signature:c,dirty:!0,geometry:""},f.set(i.id,h));const u=d*a.width/(p*i.placement.width),g=`${a.width}:${a.height}:${a.maxCells}:${u}`;h.geometry!==g&&(h.renderer.setBudget(a.maxCells),h.renderer.setPixelRatio(u),h.geometry=g,h.dirty=!0);const x="currentTime"in r?r.getVideoPlaybackQuality?.().totalVideoFrames??r.currentTime:0;if(h.dirty||h.source!==r||h.stamp!==x||h.renderer.active||_(i.settings)){const t=Object.prototype.hasOwnProperty.call(M,i.id)?M[i.id]:void 0;h.renderer.render(r,o,a.width,a.height,t),h.dirty=!1,h.source=r,h.stamp=x,s=!0}}if(!s)return!1;a.clearRect(0,0,w,v),a.globalCompositeOperation="source-over",a.globalAlpha=1,null!==r.background&&(a.fillStyle=r.background,a.fillRect(0,0,w,v));let E="none";for(const t of b){const e=f.get(t.id),i=t.placement;a.save(),a.globalAlpha=t.opacity,a.globalCompositeOperation=t.blend;try{a.translate(i.x*w,i.y*v),a.rotate(i.rotation*Math.PI/180),a.scale(i.flipX?-1:1,i.flipY?-1:1),a.drawImage(e.renderer.canvas,-i.width*w/2,-i.height*v/2,i.width*w,i.height*v)}finally{a.restore()}"unavailable"===e.renderer.canvas.dataset.studioFinish?E="unavailable":"unavailable"!==E&&"gpu"===e.renderer.canvas.dataset.studioFinish&&(E="gpu")}return a.globalAlpha=1,a.globalCompositeOperation="source-over",t.dataset.studioFinish=E,s=!1,!0},configure(t){u(),r=Rt(t),n=new Map(r.layers.map(t=>[t.id,JSON.stringify(t.settings)])),(()=>{const t=new Set(Ot(r).map(t=>t.id));for(const[e,i]of f)t.has(e)||(i.renderer.destroy(),f.delete(e))})(),s=!0},pointer(e,i,a){if(o||!Number.isFinite(e)||!Number.isFinite(i))return;if(e<0||e>1||i<0||i>1){for(const t of f.values())t.renderer.leave();return}let s=!1;for(const o of Ot({...r,width:t.width,height:t.height}).reverse()){const n=f.get(o.id);if(!n)continue;const[h,l]=Nt(o,e,i,t.width,t.height);(!s||"all"===r.pointerMode)&&h>=0&&h<=1&&l>=0&&l<=1&&"none"!==o.settings.hover.effect&&o.settings.hover.strength>0?(n.renderer.pointer(h,l,a),s=!0):n.renderer.leave()}},leave(){for(const t of f.values())t.renderer.leave()},invalidate(t){u();for(const e of r.layers)if(void 0===t||t===e.source){const t=f.get(e.id);t&&(t.renderer.invalidate(),t.dirty=!0)}s=!0},setBudget(t){u(),c=Math.max(2048,Math.min(l,Number.isFinite(t)?Math.round(t):l)),s=!0},setPixelRatio(t){u(),d=Math.max(.1,Math.min(8,Number.isFinite(t)?t:1)),s=!0},get maxCells(){return c},get pixelRatio(){return d},get quality(){return m.map(t=>({...t}))},get active(){return[...f.values()].some(t=>t.renderer.active)},destroy(){if(!o){o=!0;for(const t of f.values())t.renderer.destroy();f.clear(),t.width=t.height=1}}}}function jt(t,e){for(const i of t.layers)if(!e.has(i.source))throw new Error(`Missing project source: ${i.source}`)}async function Xt(t,e,i){const a=Object.entries(e),r=new Map;if(a.length>8)throw new Error("A project supports up to 8 media bindings.");jt(t,new Map(a));try{for(const[t,e]of a){if(i?.aborted)throw new DOMException("Cancelled","AbortError");if("string"==typeof e||"undefined"!=typeof File&&e instanceof File)r.set(t,await vt(e,i));else{if(!e||"object"!=typeof e||!("text"in e)||"string"!=typeof e.text)throw new Error(`Invalid project source: ${t}`);{const i=e,{canvas:a}=await At(i.text,i.font,i.ink??"#ffffff",null);r.set(t,{source:a,width:a.width,height:a.height,duration:0,animated:!1,frame:()=>a,seek:async()=>{},destroy:()=>{a.width=a.height=1}})}}}if(i?.aborted)throw new DOMException("Cancelled","AbortError");return r}catch(t){for(const t of r.values())t.destroy();throw t}}function Yt(t,e,i,a={}){if((i=new Map(i)).size>8)throw new Error("A project supports up to 8 media bindings.");let r=Rt(e);if(jt(r,i),a.signal?.aborted)throw new DOMException("Cancelled","AbortError");const o=Ut(t,r,a),n=matchMedia("(prefers-reduced-motion: reduce)"),h=[...new Set(i.values())],l=h.filter(t=>t.source instanceof HTMLVideoElement).map(t=>t.source),c=new Map;let d,m={},f=0,u=0,p=0,g=0,M=!0,x=!1,w=!0,v=!1,y=!1!==a.adaptive,b=0,S=0,E=0,k=r.width,A=r.height,P=0,T=!1;const F=new WeakSet,I=Math.max(1,Math.min(60,Number.isFinite(a.fps)?a.fps:60)),C=()=>!v&&!x&&!T&&!n.matches&&w&&!document.hidden,R=()=>{v||g||!w||document.hidden||(g=requestAnimationFrame(D))},L=()=>new Set(Ot({...r,width:k,height:A}).map(t=>i.get(t.source).source)),N=()=>{const t=L();for(const e of l)e.loop=!0,C()&&t.has(e)?e.paused&&!F.has(e)&&(F.add(e),e.play().then(()=>{F.delete(e),C()&&L().has(e)||e.pause()}).catch(t=>{F.delete(e),v||(x=!0,N(),a.onError?.(t instanceof Error?t:new Error(String(t))),M=!0,R())})):e.pause()},O=()=>{u=0,M=!0,N(),R()};function D(t){if(g=0,v||!w||document.hidden)return;const e=C();e&&(f+=u?Math.min(.1,(t-u)/1e3):0),u=t;const n=Ot({...r,width:k,height:A}),h=n.some(t=>i.get(t.source).animated||_(t.settings));if(M||e&&o.active||e&&h&&t-p>=1e3/I-.5){const r=performance.now();try{const t=new Map,l=new Set(n.map(t=>t.source));for(const a of l){const r=i.get(a);!r.animated||r.source instanceof HTMLVideoElement||!e||o.invalidate(a),t.set(a,r.frame(f))}m={};for(const t of n){let e=c.get(t.id);e||(e=new s,c.set(t.id,e)),m[t.id]=e.update(f,t.settings.motion.type,t.settings.motion.speed)}o.render(t,f,k,A,m);const d=performance.now()-r;a.onFrame?.(f,d),S=S?.9*S+.1*d:d,++b>20&&y&&e&&(h||o.active)&&(E=S>13?E+1:0,E>=12&&o.maxCells>2048&&(o.setBudget(Math.max(2048,.8*o.maxCells)),a.onQualityChange?.(o.maxCells),S=E=0,M=!0))}catch(t){x=!0,N(),a.onError?.(t instanceof Error?t:new Error(String(t)))}M=!1,p=t}e&&(h||o.active)&&R()}const U=e=>{if(!C())return;const i=t.getBoundingClientRect();i.width&&i.height&&(o.pointer((e.clientX-i.left)/i.width,(e.clientY-i.top)/i.height,e.timeStamp),R())},j=()=>{o.leave(),R()},X=new IntersectionObserver(([t])=>{w=t.isIntersecting,O()});X.observe(t),t.addEventListener("pointermove",U),t.addEventListener("pointerleave",j),t.addEventListener("pointercancel",j),document.addEventListener("visibilitychange",O),n.addEventListener("change",O);const Y=()=>{if(!v){v=!0,P++,d?.abort(),cancelAnimationFrame(g),g=0,X.disconnect(),t.removeEventListener("pointermove",U),t.removeEventListener("pointerleave",j),t.removeEventListener("pointercancel",j),document.removeEventListener("visibilitychange",O),n.removeEventListener("change",O),a.signal?.removeEventListener("abort",Y),o.destroy();for(const t of h)t.destroy();c.clear()}};a.signal?.addEventListener("abort",Y,{once:!0});const q=()=>{if(v)throw new Error("Project player has been destroyed.")},z=t=>{q();const e=Rt(t);jt(e,i),k===r.width&&A===r.height&&(k=e.width,A=e.height),r=e,o.configure(r);for(const t of c.keys())r.layers.some(e=>e.id===t)||c.delete(t);O()};return O(),{canvas:t,get project(){return Rt(r)},get time(){return f},get motionTimes(){return{...m}},get paused(){return x||n.matches},get maxCells(){return o.maxCells},get pixelRatio(){return o.pixelRatio},get quality(){return o.quality},update:z,updateLayer:(t,e)=>z(Lt(r,t,e)),resize(t,e,i){if(q(),!Number.isFinite(t)||!Number.isFinite(e)||t<2||e<2)throw new Error("Project dimensions must be positive finite numbers.");k=t,A=e,void 0!==i&&o.setPixelRatio(i),O()},pause(t=!0){q(),x=t,O()},async seek(t){if(q(),!Number.isFinite(t)||t<0)throw new Error("Project time must be finite and non-negative.");const e=++P;d?.abort(),d=new AbortController;const i=d.signal;T=!0,N();try{if(await Promise.all(h.map(e=>e.seek(t,i))),v||e!==P)return;f=t,c.clear(),o.invalidate()}finally{v||e!==P||(T=!1,O())}},redraw(){q(),o.invalidate(),M=!0,R()},setBudget(t){q(),o.setBudget(t),a.onQualityChange?.(o.maxCells),M=!0,R()},setAdaptive(t){y=t,b=E=S=0},destroy:Y}}exports.BLEND_MODES=P,exports.CHARACTER_SETS=Pt,exports.DEFAULT_STUDIO_PRINT=S,exports.DEFAULT_STUDIO_SETTINGS=F,exports.DITHER_ALGORITHMS=A,exports.MAX_STUDIO_LAYERS=8,exports.MAX_STUDIO_WARPS=8,exports.STUDIO_CHARACTER_SETS=Tt,exports.STUDIO_CURVE_CHANNELS=h,exports.STUDIO_HOVERS=t,exports.STUDIO_LOOKS=X,exports.STUDIO_MOTIONS=e,exports.STUDIO_PALETTES=T,exports.STUDIO_PRINT_STYLES=[{value:"stipple",label:"Stipple",description:"Scattered ink dots shape the image through their size."},{value:"engraving",label:"Engraving",description:"Continuous parallel cuts change weight with the image."},{value:"crosshatch",label:"Crosshatch",description:"Crossing layers of fine lines build the tonal range."},{value:"woodblock",label:"Woodblock",description:"Broad carved bands with irregular edges and stepped tones."},{value:"risograph",label:"Risograph",description:"Two offset ink screens with adjustable registration."},{value:"pointillism",label:"Pointillism",description:"Small pigment strokes mix source colors into the image."}],exports.STUDIO_PRINT_STYLE_IDS=y,exports.STUDIO_STYLES=k,exports.STUDIO_TEXT_FONTS=kt,exports.STUDIO_WARPS=p,exports.createStudioCurveLookup=m,exports.createStudioProjectRenderer=Ut,exports.createStudioRenderer=xt,exports.createStudioText=At,exports.exportStudio=async function(t,e,i){let a;const r=N(e),s="png"!==i.format&&"jpeg"!==i.format;try{return await bt(async(e,o,n,h,l,c)=>{a??(a=xt(e,r,{maxDimension:4096,maxCells:i.maxCells??12e3,pixelRatio:n/(i.referenceWidth??Math.min(n,960))})),s&&a.invalidate(),a.render(await t.frame(o,l),o,n,h,c)},i)}finally{a?.destroy()}},exports.exportStudioProject=async function(t,e,i){const a=Rt(t),r={...i.motionTimes};if(Object.values(r).some(t=>!Number.isFinite(t)||t<0))throw new Error("Layer motion times must be finite non-negative numbers.");const s=Object.fromEntries(Object.entries(e).map(([t,e])=>[t,e&&"object"==typeof e&&"text"in e&&"string"==typeof e.text?{...e}:e]));let o,n;const h=new AbortController,l=()=>h.abort();i.signal?.aborted?l():i.signal?.addEventListener("abort",l,{once:!0});const c="png"===i.format||"jpeg"===i.format;try{return await bt(async(t,e,h,l,d)=>{n??(n=await Xt(a,s,d)),o??(o=Ut(t,a,{maxDimension:4096,maxCells:i.maxCells??24e3,maxRasterPixels:i.maxRasterPixels,pixelRatio:h/(i.referenceWidth??Math.min(h,960))}));const m=new Set(Ot({...a,width:h,height:l}).map(t=>t.source)),f=new Map;await Promise.all([...m].map(async t=>{const i=n.get(t);await i.seek(e,d),f.set(t,i.frame(e)),i.animated&&o.invalidate(t)})),o.render(f,e,h,l,c?r:{})},{...i,signal:h.signal})}finally{if(h.abort(),i.signal?.removeEventListener("abort",l),o?.destroy(),n)for(const t of new Set(n.values()))t.destroy()}},exports.isStudioPrintStyle=b,exports.loadStudioMedia=vt,exports.mountStudio=async function(t,e,i={}){const a=await vt(e,i.signal);try{return St(t,a,i)}catch(t){throw a.destroy(),t}},exports.mountStudioMedia=St,exports.mountStudioProject=async function(t,e,i,a={}){const r=Rt(e),s=await Xt(r,i,a.signal);try{return Yt(t,r,s,a)}catch(t){for(const t of new Set(s.values()))t.destroy();throw t}},exports.mountStudioProjectMedia=Yt,exports.normalizeStudioCurve=c,exports.normalizeStudioCurves=d,exports.normalizeStudioPrint=E,exports.normalizeStudioProject=Rt,exports.normalizeStudioSettings=N,exports.normalizeStudioWarps=M,exports.parseStudioProject=function(t){if(t.length>1e6)throw new Error("Project exceeds the 1 MB settings limit.");const e=JSON.parse(t);if("asciify-project"!==e?.kind||1!==e.version||!Array.isArray(e.layers))throw new Error("This is not an Asciify layered project.");return Rt(e)},exports.parseStudioSettings=function(t){if(t.length>1e5)throw new Error("Settings exceed 100 KB.");return N(JSON.parse(t))},exports.restyleStudio=function(t,e=Math.random){const i=X.filter(e=>e.settings.style!==t.style||e.settings.ink!==t.ink),a=Y(i[Math.min(i.length-1,Math.max(0,Math.floor(e()*i.length)))].id);return a.aspectRatio=t.aspectRatio,a.crop={...t.crop},a.mask=N(t).mask,a},exports.serializeStudioProject=t=>JSON.stringify(Rt(t)),exports.serializeStudioSettings=function(t){return JSON.stringify(N(t))},exports.studioCrop=O,exports.studioDimensions=D,exports.studioGrid=j,exports.studioLayerPoint=Nt,exports.studioLook=Y,exports.studioProjectBudget=Dt,exports.studioSourceSize=ut,exports.updateStudioProjectLayer=Lt,exports.updateStudioSettings=U,exports.visibleStudioLayers=Ot;//# sourceMappingURL=studio.cjs.map