asciify-engine 4.21.0 → 4.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/{animation-presets-DztfFvTc.d.cts → animation-presets-CEdD0FMM.d.cts} +42 -28
- package/dist/{animation-presets-Bqupq1Gx.d.ts → animation-presets-KnEWoJ_q.d.ts} +42 -28
- package/dist/core.cjs +1 -1
- package/dist/core.d.cts +4 -4
- package/dist/core.d.ts +4 -4
- package/dist/core.js +1 -1
- package/dist/{hover-guide-DKRQPtDO.d.cts → hover-guide-CAfsLjFZ.d.cts} +56 -77
- package/dist/{hover-guide-DKRQPtDO.d.ts → hover-guide-CAfsLjFZ.d.ts} +56 -77
- package/dist/hover.cjs +1 -1
- package/dist/hover.d.cts +6 -6
- package/dist/hover.d.ts +6 -6
- package/dist/hover.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/{model-D2L86aNZ.d.ts → model-BHIQYYk-.d.ts} +1 -1
- package/dist/{model-BNShxUhx.d.cts → model-BzgEEqzP.d.cts} +1 -1
- package/dist/studio.cjs +1 -1
- package/dist/studio.d.cts +4 -5
- package/dist/studio.d.ts +4 -5
- package/dist/studio.js +1 -1
- package/dist/{types-Bmu4dXdQ.d.ts → types-C9lka3yC.d.ts} +2 -2
- package/dist/{types-Cn3wY-ST.d.cts → types-DOl5f2x3.d.cts} +2 -2
- package/package.json +1 -1
- package/skills/asciify-engine/SKILL.md +3 -3
- package/skills/asciify-engine/references/design-matching.md +1 -1
- package/skills/asciify-engine/references/looks.md +2 -2
- package/skills/asciify-engine/references/studio-effects.md +21 -6
- package/skills/asciify-engine/references/studio-workspace.md +6 -7
- package/skills/asciify-engine/references/upgrading.md +6 -0
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:"ripple",label:"Ripple rings",group:"Change characters",description:"Expanding light-and-shadow rings follow your stroke. Faster movement excites stronger rings; the grid stays still."},{value:"bleed",label:"Ink bleed",group:"Change characters",description:"Ink wells up where the cursor rests, spreads along the paper grain, then dries back."},{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:"Characters scatter in soft drifts from your stroke, then spring back into place."},{value:"elastic",label:"Elastic",group:"Move the image",description:"Push the image with your stroke; it recoils past its rest once, then settles."},{value:"lens",label:"Lens wake",group:"Move the image",description:"A soft magnifying wake brings details closer, then relaxes back into focus."},{value:"smudge",label:"Smudge",group:"Move the image",description:"Drag the image in the direction of your stroke; a smooth, lingering pull settles without a bounce."},{value:"loupe",label:"Loupe",group:"Follow the cursor",description:"A glass loupe glides after the cursor and magnifies what it covers, easing through a soft rim."},{value:"reveal",label:"Reveal",group:"Follow the cursor",description:"A soft spotlight shows the original photograph through the characters."},{value:"repel",label:"Repel",group:"Follow the cursor",description:"Characters part around the cursor and spring back with one soft rebound when it leaves."},{value:"tilt",label:"Tilt",group:"Follow the cursor",description:"The image leans toward the cursor; bright areas sit nearer and move more, like a parallax card."},{value:"haze",label:"Heat haze",group:"Follow the cursor",description:"A rising shimmer bends the characters above the cursor, livelier while you move."}],e={rake:"silk"};function i(i){if("string"==typeof i)return i in e?e[i]:t.some(t=>t.value===i)?i:void 0}var s=t=>"subject"===t||"outside"===t?t:"all";function a(t,e,i,s,a){if(!(a<1))for(let r=0;r<2;r++){for(let r=0;r<s;r++){let s=0;const o=r*i;for(let e=-a;e<=a;e++)s+=t[o+Math.max(0,Math.min(i-1,e))];for(let r=0;r<i;r++)e[o+r]=s/(2*a+1),s+=t[o+Math.min(i-1,r+a+1)]-t[o+Math.max(0,r-a)]}for(let r=0;r<i;r++){let o=0;for(let t=-a;t<=a;t++)o+=e[Math.max(0,Math.min(s-1,t))*i+r];for(let n=0;n<s;n++)t[n*i+r]=o/(2*a+1),o+=e[Math.min(s-1,n+a+1)*i+r]-e[Math.max(0,n-a)*i+r]}}}function r(t,e,i="ground"){return"none"===i?1:"subject"===t?e:"outside"===t?1-e:1}var o=[{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."},{value:"relight",mode:"relight",group:"Light and texture",label:"Relight",description:"A slow orbit of light models the image’s midtones, while the character grid stays fixed."},{value:"shimmer",mode:"shimmer",group:"Light and texture",label:"Shimmer",description:"Small highlights glint at different moments. Shadows stay quiet and the image stays in place."},{value:"breeze",mode:"breeze",group:"Flow and depth",label:"Breeze",description:"A traveling bend gently sways the image, like a print suspended in moving air."},{value:"unfold",mode:"unfold",group:"Rebuild",label:"Unfold",description:"Narrow panels turn, soften and return to a complete image, with a readable hold between cycles."}],n=t=>Math.max(0,Math.min(1,t)),h=(t,e,i)=>{const s=n((i-t)/(e-t));return s*s*(3-2*s)},l=(t,e)=>{const i=(.06711056*t+.00583715*e)%1*52.9829189;return i-Math.floor(i)},c=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 d(t,e,i,s,a,r=.5){if(a[0]=a[1]=a[2]=0,a[3]=1,"none"===t)return a;const o=s*Math.PI/6,c=h(0,.12,Math.min(e,1-e,i,1-i));if("caustics"===t){const t=Math.sin(9*e+5*i+o)+Math.sin(8*i-3*e-o),s=Math.pow(Math.max(0,1-.72*Math.abs(t)),3);a[2]=(.22*s-.045)*c}else if("current"===t)a[0]=Math.sin(9*i+o)*Math.cos(7*e-o)*10*c,a[1]=Math.cos(8*e+o)*Math.sin(6*i-o)*7*c;else if("sheen"===t)a[2]=.2*Math.pow(.5+.5*Math.cos(5*e+3*i-o),8)-.025;else if("tidal"===t){const t=e-.5,s=i-.5,r=Math.hypot(t,s),n=Math.sin(22*r-o)*c;a[0]=t*n*9,a[1]=s*n*9,a[2]=.035*n}else if("grain"===t){const t=l(Math.floor(160*e),Math.floor(100*i))*Math.PI*2;a[2]=.07*Math.sin(o+t)}else if("parallax"===t){const t=.45+.55*Math.max(0,1-1.4*Math.hypot(e-.5,i-.5));a[0]=12*Math.sin(o)*t*c,a[1]=6*(Math.cos(o)-1)*t*c}else if("weave"===t)a[0]=Math.sin(i*Math.PI*6+o)*Math.sin(o)*8*c,a[1]=Math.sin(e*Math.PI*6-o)*Math.sin(o)*6*c;else if("print"===t){const t=Math.floor(24*i),e=((s+3*l(t,3))%12+12)%12,r=h(1,2.5,e)*(1-h(3.5,5,e));a[0]=Math.sin(2.4*t)*r*9*c,a[1]=5*-r*c,a[2]=.22*-r,a[3]=1-.45*r}else if("trace"===t){const t=.5+.5*Math.cos(o);a[2]=.22*Math.pow(Math.max(0,1-Math.abs(n(r)-t)/.16),3)-.015}else if("relight"===t){const t=i-.5,s=1.3*((e-.5)*Math.cos(o)+t*Math.sin(o));a[2]=.3*s*(.25+3*n(r)*(1-n(r)))*c}else if("shimmer"===t){const t=l(Math.floor(160*e),Math.floor(100*i))*Math.PI*2,s=Math.pow(.5+.5*Math.cos(o+t),10);a[2]=.28*(s-.1762)*h(.35,.9,r)}else if("breeze"===t){const t=Math.sin(o-4*i),s=.35+.65*(1-i);a[0]=10*t*s*c,a[1]=2.5*Math.sin(2*o-4*i+3*e)*s*c,a[2]=.035*Math.cos(o-4*i)*c}else if("unfold"===t){const t=Math.floor(12*e),i=12*e-t-.5,r=((s-.11*t)%12+12)%12,o=h(1,3,r)*(1-h(5,7,r));a[0]=-i*o*24*c,a[1]=Math.sin(1.7*t)*o*3*c,a[2]=.12*-o,a[3]=1-.65*o}else if("reform"===t){const t=(s%12+12)%12,r=l(Math.floor(160*e),Math.floor(100*i)),n=.65*e+.2*i+.15*r+.08*Math.sin(8*e-5*i),d=h(1.8+1.2*n,3.8+1.2*n,t)*(1-h(5+1.7*n,7.2+1.7*n,t));a[0]=Math.sin(9*i+o)*d*(1-d)*24*c,a[1]=-d*(1-d)*(8+12*r)*c,a[2]=.45*-d,a[3]=1-.9*d}return a}function u(t,e){const i=Math.max(0,Math.min(2,Number.isFinite(e)?e:1));return t[0]*=i,t[1]*=i,t[2]*=i,t[3]=n(1+(t[3]-1)*i),t}var m=["rgb","red","green","blue"],f=t=>Math.max(0,Math.min(1,t));function p(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*f(i[0]))/255;!e.has(t)&&e.size>=16||e.set(t,f(i[1]))}return[...e].sort((t,e)=>t[0]-e[0])}function g(t){const e=t&&"object"==typeof t?t:{};return Object.fromEntries(m.map(t=>[t,p(e[t])]))}function M(t){const e=p(t),i=e.length,s=e.slice(1).map((t,i)=>t[0]-e[i][0]),a=e.slice(1).map((t,i)=>(t[1]-e[i][1])/s[i]),r=new Float64Array(i);r[0]=a[0],r[i-1]=a[i-2];for(let t=1;t<i-1;t++){const e=a[t-1],i=a[t];if(e*i<=0)continue;const o=2*s[t]+s[t-1],n=s[t]+2*s[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 a=t/255;for(;n<i-2&&a>e[n+1][0];)n++;const h=s[n],l=(a-e[n][0])/h,c=l*l,d=c*l,u=(2*d-3*c+1)*e[n][1]+(d-2*c+l)*h*r[n]+(-2*d+3*c)*e[n+1][1]+(d-c)*h*r[n+1];o[t]=Math.round(255*f(u))}return o}function x(t,e,i,s,a,r){s=Math.max(0,Math.min(e-1,s)),a=Math.max(0,Math.min(i-1,a));const o=Math.floor(s),n=Math.floor(a),h=s-o,l=a-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)),u=4*(Math.min(i-1,n+1)*e+o),m=4*(Math.min(i-1,n+1)*e+Math.min(e-1,o+1)),f=(1-h)*(1-l)*t[c+3],p=h*(1-l)*t[d+3],g=(1-h)*l*t[u+3],M=h*l*t[m+3],x=f+p+g+M;for(let e=0;e<3;e++)r[e]=x?(t[c+e]*f+t[d+e]*p+t[u+e]*g+t[m+e]*M)/x:0;r[3]=x}function v(t,e,i,s,a,r){if(s>=0&&s<=e-1&&a>=0&&a<=i-1)return x(t,e,i,s,a,r);if(r[0]=r[1]=r[2]=r[3]=0,s<=-1||s>=e||a<=-1||a>=i)return;const o=Math.floor(s),n=Math.floor(a),h=s-o,l=a-n;for(let s=0;s<=1;s++)for(let a=0;a<=1;a++){const c=o+a,d=n+s;if(c<0||c>=e||d<0||d>=i)continue;const u=4*(d*e+c),m=(a?h:1-h)*(s?l:1-l)*t[u+3];r[0]+=t[u]*m,r[1]+=t[u+1]*m,r[2]+=t[u+2]*m,r[3]+=m}r[3]&&(r[0]/=r[3],r[1]/=r[3],r[2]/=r[3])}var b=[{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}],w=(t,e,i,s)=>"number"==typeof t&&Number.isFinite(t)?Math.max(i,Math.min(s,t)):e;function y(t){if(!Array.isArray(t))return[];const e=[];for(const i of t.slice(0,64))if(i&&"object"==typeof i&&b.some(t=>t.value===i.type)&&(e.push({type:i.type,enabled:!1!==i.enabled,amount:w(i.amount,.35,-1,1),x:w(i.x,.5,0,1),y:w(i.y,.5,0,1),radius:w(i.radius,.55,.05,2),angle:w(i.angle,0,-180,180),frequency:w(i.frequency,5,1,24)}),8===e.length))break;return e}var S=2*Math.PI,k=(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},E=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=y(t).filter(t=>t.enabled&&0!==t.amount),s=JSON.stringify(i);this.edge="transparent"===e?"transparent":"clamp",s!==this.signature&&(this.signature=s,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,s=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(s)||s<=0)throw new Error("Warp dimensions do not match the source.");const a=`${e}:${i}:${s}`;if(a!==this.geometry){this.coordinates.length!==e*i*2&&(this.coordinates=new Float32Array(e*i*2));const t=Math.max(1,s),r=Math.max(1,1/s);for(let s=0;s<i;s++)for(let a=0;a<e;a++){let o=(a+.5)/e,n=(s+.5)/i;for(let e=this.warps.length-1;e>=0;e--){const i=this.warps[e],s=(o-i.x)*t/i.radius,a=(n-i.y)*r/i.radius,h=s*s+a*a;if(h>=1)continue;const l=Math.sqrt(h),c=(1-h)*(1-h),d=i.amount;let u=s,m=a;if("twirl"===i.type||"zigzag"===i.type){const t="twirl"===i.type?-d*S*c:.65*d*(2/Math.PI*Math.asin(Math.sin(l*S*i.frequency)))*c,e=Math.cos(t),r=Math.sin(t);u=s*e-a*r,m=s*r+a*e}else if("pinch"===i.type){const t=Math.exp(2*d*c);u=s*t,m=a*t}else if("sphere"===i.type&&l>0){const t=1+d*c*(2*Math.asin(l)/Math.PI/l-1);u=s*t,m=a*t}else if("ripple"===i.type&&l>0){const t=1+.12*d*Math.sin(l*S*i.frequency)*c/l;u=s*t,m=a*t}else if("shear"===i.type){const t=-s*i.sin+a*i.cos;u-=d*t*.9*c*i.cos,m-=d*t*.9*c*i.sin}else if("smudge"===i.type)u-=.65*d*c*i.cos,m-=.65*d*c*i.sin;else if("polar"===i.type){const t=s*i.cos+a*i.sin,e=-s*i.sin+a*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,f=o*i.sin+n*i.cos;u+=(h-s)*Math.abs(d)*c,m+=(f-a)*Math.abs(d)*c}else if("fragment"===i.type){const t=Math.floor((s*i.cos+a*i.sin)*i.frequency),e=Math.floor((-s*i.sin+a*i.cos)*i.frequency),r=(k(t,e)-.5)*d*.5*c,o=(k(e+71,t-31)-.5)*d*.5*c;u+=r*i.cos-o*i.sin,m+=r*i.sin+o*i.cos}o=i.x+u*i.radius/t,n=i.y+m*i.radius/r}const h=2*(s*e+a);this.coordinates[h]=o*e-.5,this.coordinates[h+1]=n*i-.5}this.geometry=a}this.output.length!==t.length&&(this.output=new Uint8ClampedArray(t.length));const r=t===this.output?t.slice():t,o="transparent"===this.edge?v:x;for(let s=0,a=0;s<t.length;s+=4,a+=2){o(r,e,i,this.coordinates[a],this.coordinates[a+1],this.sampled);for(let t=0;t<4;t++)this.output[s+t]=this.sampled[t]}return this.output}clear(){this.coordinates=new Float32Array(0),this.output=new Uint8ClampedArray(0),this.geometry=""}},A=["stipple","engraving","crosshatch","woodblock","risograph","pointillism"];function F(t){return A.includes(t)}var P={density:1,weight:1,angle:-35,roughness:.35,invert:!1,secondaryInk:"#ec6752",registration:.2,seed:7};function T(t){const e=t&&"object"==typeof t&&!Array.isArray(t)?t:{},i=(t,i,s)=>{const a=e[t];return"number"==typeof a&&Number.isFinite(a)?Math.max(i,Math.min(s,a)):P[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:P.secondaryInk,registration:i("registration",0,1),seed:Math.round(i("seed",0,65535))}}var I=["ascii","blocks","braille","dots","lines","cross","diagonal","diamond","mixed","pixel","mosaic","lego","voxel","disco","dither","hex","led","cmyk",...A],C=["none","bayer2","bayer4","bayer8","bayer16","floyd-steinberg","atkinson","stucki","sierra","sierra-lite","burkes","jarvis","halftone","lines","noise","vertical-lines","diagonal-lines","radial","blue-noise"],R=["source-over","multiply","screen","overlay","soft-light","hard-light","color-dodge","color-burn","hue","saturation","color","luminosity"],L={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:["#0b0b0a","#e6e3da"]},N={version:1,aspectRatio:"original",style:"ascii",cellSize:6,charset:" .:-=+*#%@",colorMode:"accent",ink:"#e6e3da",print:{...P},crop:{x:.5,y:.5,zoom:1,rotation:0},warps:[],warpEdge:"clamp",backdrop:{mode:"solid",color:"#080808",color2:"#1d1d1b",blur:12,opacity:1},color:{brightness:0,contrast:1,saturation:1,grayscale:0,tint:"#e6e3da",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,levels:"auto"},dither:{algorithm:"none",palette:"mono",colors:["#080808","#e6e3da"],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}},O=t=>t&&"object"==typeof t&&!Array.isArray(t)?t:{},D=(t,e,i,s)=>"number"==typeof t&&Number.isFinite(t)?Math.min(s,Math.max(i,t)):e,U=(t,e)=>"string"==typeof t&&/^#[\da-f]{6}$/i.test(t)?t:e,X=(t,e,i)=>e.includes(t)?t:i;function j(t={}){const e=O(t),a=N;if(void 0!==e.version&&1!==e.version)throw new Error("Unsupported studio settings version. Update asciify-engine.");const r=O(e.crop),n=O(e.backdrop),h=O(e.color),l=O(e.dither),c=O(e.mask),d=O(e.effects),u=O(e.motion),m=O(e.hover),f={...a.effects};for(const t of["bloom","characterBloom","grain","dust","scanlines","crt","prism","rgbSplit","sharpen","vignette","glitch","pixelate","halftone"])f[t]=D(d[t],0,0,1);f.blur=D(d.blur,0,0,24),f.blurType=X(d.blurType,["gaussian","directional","radial","progressive"],a.effects.blurType),f.angle=D(d.angle,0,-180,180),f.focus=D(d.focus,.5,0,1);let p=2048;return{version:1,aspectRatio:X(e.aspectRatio,["original","16:9","9:16","1:1","4:3","3:4","21:9"],"original"),style:X(e.style,I,a.style),cellSize:D(e.cellSize,a.cellSize,F(String(e.style))||["pixel","mosaic","lego","voxel","disco","dots","hex","led","cmyk"].includes(String(e.style))?1:3,60),charset:"string"==typeof e.charset&&e.charset.length?Array.from(e.charset).slice(0,128).join(""):a.charset,colorMode:X(e.colorMode,["accent","source","gray"],a.colorMode),ink:U(e.ink,a.ink),print:T(e.print),warps:y(e.warps),warpEdge:X(e.warpEdge,["clamp","transparent"],"clamp"),crop:{x:D(r.x,.5,0,1),y:D(r.y,.5,0,1),zoom:D(r.zoom,1,1,5),rotation:90*Math.round(D(r.rotation,0,-360,360)/90)},backdrop:{mode:X(n.mode,["solid","transparent","source","blurred","gradient"],a.backdrop.mode),color:U(n.color,a.backdrop.color),color2:U(n.color2,a.backdrop.color2),blur:D(n.blur,12,0,32),opacity:D(n.opacity,1,0,1)},color:{brightness:D(h.brightness,0,-1,1),contrast:D(h.contrast,1,0,3),saturation:D(h.saturation,1,0,3),grayscale:D(h.grayscale,0,0,1),tint:U(h.tint,a.color.tint),amount:D(h.amount,0,0,1),blend:X(h.blend,R,a.color.blend),blackPoint:D(h.blackPoint,0,0,.99),whitePoint:Math.max(D(h.blackPoint,0,0,.99)+1/255,D(h.whitePoint,1,1/255,1)),gamma:D(h.gamma,1,.25,4),shadows:D(h.shadows,0,-1,1),highlights:D(h.highlights,0,-1,1),curves:g(h.curves),denoise:D(h.denoise,0,0,1),levels:"none"===h.levels?"none":"auto"},dither:{algorithm:X(l.algorithm,C,"none"),palette:"string"==typeof l.palette&&Object.prototype.hasOwnProperty.call(L,l.palette)?l.palette:"mono",colors:Array.isArray(l.colors)&&l.colors.length>=2?l.colors.slice(0,32).map(t=>U(t,"#000000")):[...a.dither.colors],amount:D(l.amount,1,0,2),scale:Math.round(D(l.scale,2,1,12)),threshold:D(l.threshold,.5,0,1),motion:X(l.motion,["none","drift","shimmer"],"none"),speed:D(l.speed,1,.1,3),direction:D(l.direction,45,-180,180),colorSpace:X(l.colorSpace,["rgb","luminance"],"rgb")},mask:{enabled:!0===c.enabled,invert:!0===c.invert,shapes:Array.isArray(c.shapes)?c.shapes.slice(0,64).map(t=>{const e=O(t),i=X(e.kind,["rectangle","ellipse","brush"],"rectangle"),s="brush"===i&&Array.isArray(e.points)?e.points.slice(0,p).map(t=>Array.isArray(t)?[Math.round(1e4*D(t[0],0,0,1))/1e4,Math.round(1e4*D(t[1],0,0,1))/1e4]:[0,0]):[];return p-=s.length,{kind:i,x:D(e.x,0,0,1),y:D(e.y,0,0,1),width:D(e.width,.5,0,1),height:D(e.height,.5,0,1),size:D(e.size,.05,.005,.5),points:s}}):[]},lights:Array.isArray(e.lights)?e.lights.slice(0,4).map(t=>{const e=O(t);return{x:D(e.x,.5,0,1),y:D(e.y,.5,0,1),radius:D(e.radius,.3,.02,1),intensity:D(e.intensity,.5,0,1),color:U(e.color,"#ffffff")}}):[],effects:f,motion:{type:X(u.type,o.map(t=>t.mode),"none"),speed:D(u.speed,1,.1,3),amount:D(u.amount,1,0,2)},hover:{effect:i(m.effect)??"trail",strength:D(m.strength,.55,0,1),radius:D(m.radius,.2,.1,1),edgeSafe:!0===m.edgeSafe,..."all"!==s(m.scope)&&{scope:s(m.scope)},....5!==D(m.decay,.5,0,1)&&{decay:D(m.decay,.5,0,1)}}}}function z(t,e,i,s,a){const r=Math.abs(a.rotation/90)%2==1,o=r?e:t,n=r?t:e,h=Math.max(i/o,s/n)*a.zoom;return{width:o*h,height:n*h,x:(i-o*h)*a.x,y:(s-n*h)*a.y,scale:h,rotated:r}}function Y(t,e,i){if(Math.abs(i.crop.rotation/90)%2==1&&([t,e]=[e,t]),"original"===i.aspectRatio)return[t,e];const[s,a]=i.aspectRatio.split(":").map(Number);return t/e>s/a?[Math.round(e*s/a),e]:[t,Math.round(t*a/s)]}function q(t,e){const i={...t,...e};for(const s of["crop","backdrop","color","dither","mask","effects","motion","hover","print"])e[s]&&Object.assign(i,{[s]:{...t[s],...e[s]}});return e.color?.curves&&(i.color.curves={...t.color.curves,...e.color.curves}),j(i)}function B(t,e,i,s=12e3,a=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(s)?s:12e3)),h=Math.max(.01,Number.isFinite(a)?a:1),l=F(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(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,u=Math.max(c,d)*h;return{cell:u,rowHeight:u*l,columns:Math.ceil(r/u),rows:Math.ceil(o/(u*l)),minimum:c,limited:d<c}}var W=[["ascii","Signature ASCII","Clean characters in paper white on near black.",{cellSize:4,ink:"#ece9e0",backdrop:{mode:"solid",color:"#0b0b0a"},color:{contrast:1.25,gamma:1.25},effects:{characterBloom:.12}}],["print","Newsprint","Fine diffusion in soft black on warm paper.",{style:"dither",cellSize:6,ink:"#1d1c19",backdrop:{mode:"solid",color:"#efece4"},dither:{algorithm:"floyd-steinberg",palette:"custom",colors:["#efece4","#1d1c19"],scale:2}}],["handheld","Pocket camera","Four-tone ordered dither in graphite.",{style:"dither",cellSize:6,ink:"#dedbd2",backdrop:{mode:"solid",color:"#121211"},dither:{algorithm:"bayer4",palette:"custom",colors:["#121211","#3e3d39","#8a8880","#dedbd2"],scale:2}}],["riso","Two inks","Muted blue and coral on warm paper.",{style:"dither",cellSize:6,ink:"#3d5068",backdrop:{mode:"solid",color:"#f0ece3"},dither:{algorithm:"atkinson",palette:"custom",colors:["#f0ece3","#c27461","#3d5068"],scale:2}}],["night","Night signal","Graphite characters with a faint optical fringe.",{cellSize:4,ink:"#cdc9be",backdrop:{mode:"solid",color:"#0b0b0a"},color:{contrast:1.2,gamma:1.2},effects:{prism:.2,scanlines:.08,vignette:.3,bloom:.12}}],["terminal","Phosphor","Soft sage glyphs with a faint glow.",{cellSize:5,ink:"#a4c9b3",backdrop:{mode:"solid",color:"#0a0d0b"},effects:{bloom:.16,scanlines:.12,crt:.06}}],["mosaic","Mosaic study","Separated tiles in quiet source color.",{style:"mosaic",ink:"#e6e3da",cellSize:9,colorMode:"source",backdrop:{mode:"solid",color:"#0b0b0a"},color:{saturation:.55,contrast:1.05}}],["bricks","Brickwork","Studded cells in softened color.",{style:"lego",ink:"#e6e3da",cellSize:12,colorMode:"source",backdrop:{mode:"solid",color:"#0b0b0a"},color:{saturation:.55}}],["voxel","Little volumes","Three-face isometric tiles in muted color.",{style:"voxel",ink:"#e6e3da",cellSize:12,colorMode:"source",backdrop:{mode:"solid",color:"#0b0b0a"},color:{saturation:.5}}],["disco","Mirror room","Faceted tiles under one soft light.",{style:"disco",ink:"#e6e3da",cellSize:11,colorMode:"source",backdrop:{mode:"solid",color:"#0b0b0a"},color:{saturation:.5},lights:[{x:.35,y:.25,radius:.28,intensity:.28,color:"#f4efe4"}]}],["wallpaper","Wallpaper","Living ASCII over a softened source.",{cellSize:5,backdrop:{mode:"blurred",color:"#0b0b0a",blur:18,opacity:.4},ink:"#e6e3da",motion:{type:"caustics",speed:.35}}],["blueprint","Blueprint","Fine linework in pale blue on deep navy.",{style:"lines",cellSize:6,ink:"#b3c9d8",backdrop:{mode:"solid",color:"#0e1b28"}}]].map(([t,e,i,s])=>({id:t,name:e,description:i,settings:j(s)}));function G(t){const e=W.find(e=>e.id===t);if(!e)throw new Error("Unknown studio look.");return j(e.settings)}function H(t){const e=function(t){const e=t.blackPoint??0,i=t.whitePoint??1,s=t.gamma??1,a=t.shadows??0,r=t.highlights??0;if(0===e&&1===i&&1===s&&0===a&&0===r)return null;const o=[0,.25+.2*a,.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 a=Math.pow(Math.max(0,Math.min(1,(t/255-e)/(i-e))),1/s),r=Math.min(3,Math.floor(4*a)),n=4*a-r,c=n*n,d=c*n,u=(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,u)))}return l}(t),i=t.curves;if(!e&&(!i||Object.values(i).every(t=>t.every(([t,e])=>t===e))))return null;const s=M(i?.rgb),a=[i?.red,i?.green,i?.blue].map(M),r=new Uint8Array(768);for(let t=0;t<256;t++)for(let i=0;i<3;i++)r[256*i+t]=a[i][s[e?e[t]:t]];return r}var V=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 s=this.source;s.set(t);for(let a=0;a<i;a++)for(let r=0;r<e;r++){const o=4*(a*e+r);if(!s[o+3])continue;const n=s[o],h=s[o+1],l=s[o+2];let c=0,d=0,u=0,m=0;for(let t=-1;t<=1;t++){const o=a+t;if(!(o<0||o>=i))for(let i=-1;i<=1;i++){const a=r+i;if(a<0||a>=e)continue;const f=4*(o*e+a);if(!s[f+3])continue;const p=Math.max(Math.abs(s[f]-n),Math.abs(s[f+1]-h),Math.abs(s[f+2]-l)),g=this.weights[p]*(0===i?1:.6)*(0===t?1:.6)*s[f+3];c+=s[f]*g,d+=s[f+1]*g,u+=s[f+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+(u/m-l)*this.amount}}},Q=2*Math.PI,J=t=>Math.max(0,Math.min(1,t)),K=.1,Z=t=>Math.max(-.1,Math.min(1.1,t)),_=Float32Array.from({length:2048},(t,e)=>Math.sin(e/2048*Q)),$=t=>_[2047&Math.floor(t*(2048/Q))];function tt(t,e,i){let s=Math.imul(t,374761393)^Math.imul(e,668265263)^Math.imul(i,1442695041);return s=Math.imul(s^s>>>13,1274126177),((s^s>>>16)>>>0)/4294967296}function et(t){const e=T(t),{density:i,weight:s,angle:a,roughness:r,invert:o,secondaryInk:n,registration:h,seed:l}=e,c=a*Math.PI/180,d=[c,c+Math.PI/2,c+Math.PI/4].map(t=>[Math.cos(t),Math.sin(t)]),u=new Float32Array(6);function m(t,e,i,a,o,n,h,c,m=!1){if(h<=0)return;const[f,p]=d[c],g=-p,M=f,x=g*(e+.5)+M*(i+.5),v=.5*(Math.abs(g)+Math.abs(M)),b=m?1:.5,w=Math.ceil((x-v)/b),y=Math.floor((x+v)/b),S=Math.min(.94*b,.72*b*h*s);t.lineWidth=n*S,t.beginPath();for(let s=w;s<=y;s++){const h=s*b-x,c=.5+g*h,d=.5+M*h;let v=-2,w=2;if(Math.abs(f)>1e-8){const t=-c/f,e=(1-c)/f;v=Math.max(v,Math.min(t,e)),w=Math.min(w,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;v=Math.max(v,Math.min(t,e)),w=Math.min(w,Math.max(t,e))}else if(d<0||d>1)continue;if(!(w<=v))if(m&&(v-=K,w+=K),m){for(let t=0;t<6;t++){const a=v+(w-v)*t/5,r=f*(e+c+f*a)+p*(i+d+p*a);u[t]=.5*$(5.3*r+1.9*s+l)+.25*$(13.1*r+s)}for(let e=0;e<2;e++)for(let i=0;i<6;i++){const s=v+(w-v)*(e?5-i:i)/5,h=u[e?5-i:i],l=.5*S*(1+r*h*.5)*(e?-1:1),m=a+Z(c+f*s+g*l)*n,x=o+Z(d+p*s+M*l)*n;e||i?t.lineTo(m,x):t.moveTo(m,x)}t.closePath()}else t.moveTo(a+(c+f*v)*n,o+(d+p*v)*n),t.lineTo(a+(c+f*w)*n,o+(d+p*w)*n)}m?t.fill():t.stroke()}return{settings:e,paint(t,e,a,c,u,f,p,g,M,x,v,b,w){const y=J((o?1-g:g)*i);if(y<=0||t.globalAlpha<=0)return;t.fillStyle=M,t.strokeStyle=M;const S=tt(a,c,l);if("engraving"===e||"crosshatch"===e||"woodblock"===e){const i=y*(1-r*S*.3);"woodblock"===e?m(t,a,c,u,f,p,Math.ceil(5*i)/5,0,!0):(m(t,a,c,u,f,p,i,0),"crosshatch"===e&&(m(t,a,c,u,f,p,Math.max(0,1.5*i-.3),1),m(t,a,c,u,f,p,Math.max(0,2*i-1.2),2)))}else if("risograph"===e){const e="source"===w?J(.5+(x-b)/510):.5,i=.38*h*p,o=p*Math.min(.48,.44*Math.sqrt(y)*s);t.beginPath(),t.arc(u+.5*p,f+.5*p,o*Math.sqrt(.35+.65*(1-e)),0,Q),t.fill(),t.globalCompositeOperation="multiply",t.fillStyle=n;const m=1-r*tt(a,c,l+13)*.3;t.beginPath(),t.arc(u+.5*p+i*d[0][0],f+.5*p+i*d[0][1],o*Math.sqrt(.3+.7*e)*m,0,Q),t.fill(),t.globalCompositeOperation="source-over"}else{"stipple"===e&&t.beginPath();for(let i=0;i<4;i++){const o=tt(2*a+i%2,2*c+(i>>1),l),n=tt(a,c,l+11*i+1),h=u+((i%2+.5)/2+(o-.5)*r*.28)*p,d=f+((.5+(i>>1))/2+(n-.5)*r*.28)*p,m=Math.min(h-u,u+p-h,d-f,f+p-d,p*Math.min(.245,.21*s*Math.sqrt(y)*(1-r*o*.35)));if("stipple"===e)t.moveTo(h+m,d),t.arc(h,d,m,0,Q);else{const e=(o-.5)*r*64;t.fillStyle="source"===w?`rgb(${Math.round(x+e)},${Math.round(v-.4*e)},${Math.round(b-e)})`:"gray"===w?`rgb(${Math.round(x+e)},${Math.round(x+e)},${Math.round(x+e)})`:M,t.beginPath(),t.ellipse(h,d,m,.64*m,o*Math.PI,0,Q),t.fill()}}"stipple"===e&&t.fill()}}}}var it=new Set(["none","floyd-steinberg","atkinson","stucki","sierra","sierra-lite","burkes","jarvis"]);function st(t){return"dither"===t.style&&("shimmer"===t.dither.motion||"drift"===t.dither.motion&&t.dither.amount>0&&!it.has(t.dither.algorithm))}function at(t){return"none"!==t.motion.type&&(t.motion.amount??1)>0}function rt(t){return at(t)||st(t)||t.effects.grain>0||t.effects.dust>0||t.effects.glitch>0}var ot="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",nt="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",ht=new Uint16Array(4096);for(let t=0;t<ht.length;t++)ht[t]=ot.indexOf(nt[2*t])<<6|ot.indexOf(nt[2*t+1]);var lt=(t,e)=>{const i=43758.5453*Math.sin(127.1*t+311.7*e);return i-Math.floor(i)};var ct=new Map([2,4,8,16].map(t=>[t,Float64Array.from({length:t*t},(e,i)=>function(t,e,i){let s=0;for(let a=1;a<i;a*=2){const i=(Math.floor(t/a)%2+2)%2;s=4*s+[[0,2],[3,1]][(Math.floor(e/a)%2+2)%2][i]}return(s+.5)/(i*i)-.5}(i%t,Math.floor(i/t),t))])),dt={"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]]},ut=t=>[parseInt(t.slice(1,3),16),parseInt(t.slice(3,5),16),parseInt(t.slice(5,7),16)];function mt(t,e,i){const s=Math.min(t*Math.max(1,i),(1-t)*Math.max(1,i),e*Math.max(1,1/i),(1-e)*Math.max(1,1/i)),a=Math.max(0,Math.min(1,(s-.035)/.105));return a*a*a*(a*(6*a-15)+10)}var ft=class{constructor(t,e){this.edgeSafe=!1,this.rings=new Float64Array(40),this.slot=0,this.clock=0,this.lastRing=-1,this.previous=null,this.alive=!1,this.width=t,this.height=e,this.pixels=new Uint8Array(t*e*4),this.values=new Float32Array(t*e),this.clear()}get active(){return this.alive}clear(){this.rings.fill(0),this.values.fill(0),this.pixels.fill(0);for(let t=0;t<this.pixels.length;t+=4)this.pixels[t]=128;this.previous=null,this.alive=!1,this.slot=0,this.lastRing=-1,this.clock=0}leave(){this.previous=null}move(t,e,i,s){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=Number.isFinite(s)?s/1e3:this.clock,r=this.previous;if(this.previous={x:t,y:e,time:a},!r)return;const o=this.width/this.height,n=Math.hypot((t-r.x)*Math.max(1,o),(e-r.y)*Math.max(1,1/o));if(n<1e-4||this.clock-this.lastRing<1/24)return;const h=n/Math.max(1/240,Math.min(.1,a-r.time||1/60)),l=5*this.slot;this.slot=(this.slot+1)%8,this.rings[l]=t,this.rings[l+1]=e,this.rings[l+2]=0,this.rings[l+3]=Math.min(.9,.26+.2*h),this.rings[l+4]=.035+.13*Math.max(.1,Math.min(1,i)),this.alive=!0,this.lastRing=this.clock}step(t){if(!Number.isFinite(t)||t<=0)return;const e=Math.min(.05,t);if(this.clock+=e,!this.alive)return;this.values.fill(0),this.alive=!1;const i=this.width/this.height,s=Math.max(1,i),a=Math.max(1,1/i);for(let t=0;t<this.rings.length;t+=5){if(!this.rings[t+3])continue;const i=this.rings[t+2]+=e;if(i>2.8){this.rings[t+3]=0;continue}this.alive=!0;const r=this.rings[t+4],o=.17*i,n=this.rings[t+3]*(1-Math.exp(20*-i))*Math.exp(2.5*-i),h=o+1.8*r,l=this.rings[t],c=this.rings[t+1],d=Math.max(0,Math.floor((l-h/s)*(this.width-1))),u=Math.min(this.width-1,Math.ceil((l+h/s)*(this.width-1))),m=Math.max(0,Math.floor((c-h/a)*(this.height-1))),f=Math.min(this.height-1,Math.ceil((c+h/a)*(this.height-1)));for(let t=m;t<=f;t++)for(let e=d;e<=u;e++){const i=(Math.hypot((e/(this.width-1)-l)*s,(t/(this.height-1)-c)*a)-o)/r;Math.abs(i)>1.8||(this.values[t*this.width+e]+=n*Math.cos(i*Math.PI*2)*Math.exp(-i*i*2.5))}}for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++){const s=t*this.width+e,a=this.values[s]=Math.max(-1,Math.min(1,this.values[s]))*(this.edgeSafe?mt(e/(this.width-1),t/(this.height-1),i):1),r=Math.round(32767*a+32768);this.pixels[4*s]=r>>>8,this.pixels[4*s+1]=255&r}}sample(t,e,i){const s=Math.max(0,Math.min(this.width-1.001,t*(this.width-1))),a=Math.max(0,Math.min(this.height-1.001,e*(this.height-1))),r=Math.floor(s),o=Math.floor(a),n=s-r,h=a-o,l=o*this.width+r,c=l+this.width;i[0]=i[1]=0,i[2]=3*((this.values[l]*(1-n)+this.values[l+1]*n)*(1-h)+(this.values[c]*(1-n)+this.values[c+1]*n)*h)}},pt=t=>["dissolve","silk","vortex","magnetic","scatter","etch","elastic","lens","smudge"].includes(t),gt=t=>"elastic"===t||"scatter"===t,Mt={elastic:[150,4.2],scatter:[90,3.6]},xt=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 s=0;s<t;s++)this.edge[i*t+s]=mt(s/(t-1),i/(e-1),t/e);this.clear()}get active(){return this.peak>2e-4}setMode(t){if(gt(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),e=(t,e)=>{const i=43758.5453*Math.sin(127.1*t+311.7*e);return i-Math.floor(i)};for(let i=0;i<this.height;i++)for(let s=0;s<this.width;s++){const a=.09*s,r=.09*i,o=Math.floor(a),n=Math.floor(r),h=a-o,l=r-n,c=h*h*(3-2*h),d=l*l*(3-2*l),u=((e(o,n)*(1-c)+e(o+1,n)*c)*(1-d)+(e(o,n+1)*(1-c)+e(o+1,n+1)*c)*d)*Math.PI*4,m=2*(i*this.width+s);t[m]=.7*Math.cos(u),t[m+1]=.7*Math.sin(u)}}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 s=this.previous;this.previous={x:t,y:e};const a=this.width,r=this.height,o=Math.max(1,a/r),n=Math.max(1,r/a),h=s?(t-s.x)*o:0,l=s?(e-s.y)*n:0,c=Math.hypot(h,l);if(!s&&"dissolve"!==this.mode&&"etch"!==this.mode&&"lens"!==this.mode)return;if(s&&c<1e-4)return;const d=.035+.11*Math.max(.1,Math.min(1,i)),u=Math.min(128,Math.max(1,Math.ceil(c/(.45*d)))),m=c?h/c:1,f=c?l/c:0,p=s||"lens"!==this.mode?Math.min(1,c/(d*u)*2.2):.32;for(let i=0;i<u;i++){const h=(i+.5)/u,l=s?s.x+(t-s.x)*h:t,c=s?s.y+(e-s.y)*h:e,g=Math.max(0,Math.floor((l-2.5*d/o)*(a-1))),M=Math.min(a-1,Math.ceil((l+2.5*d/o)*(a-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/(a-1)-l)*o/d,s=(t/(r-1)-c)*n/d,h=Math.exp(1.5*-(i*i+s*s)),u=t*a+e;if("dissolve"===this.mode||"etch"===this.mode)this.ink[u]=Math.max(this.ink[u],h);else if("elastic"===this.mode)this.springX[u]=Math.max(-24,Math.min(24,this.springX[u]+m*h*p*12)),this.springY[u]=Math.max(-24,Math.min(24,this.springY[u]+f*h*p*12));else if("scatter"===this.mode){const t=this.scatterDirections;this.springX[u]=Math.max(-24,Math.min(24,this.springX[u]+(.6*i+t[2*u])*h*p*7)),this.springY[u]=Math.max(-24,Math.min(24,this.springY[u]+(.6*s+t[2*u+1])*h*p*7))}else if("lens"===this.mode)this.targetX[u]=Math.max(-.65,Math.min(.65,this.targetX[u]+i*h*p*1.6)),this.targetY[u]=Math.max(-.65,Math.min(.65,this.targetY[u]+s*h*p*1.6));else if("smudge"===this.mode)this.targetX[u]=Math.max(-1,Math.min(1,this.targetX[u]+m*h*p*1.3)),this.targetY[u]=Math.max(-1,Math.min(1,this.targetY[u]+f*h*p*1.3));else{const t=(-i*f+s*m)*h*2.8,e="magnetic"===this.mode?-i*h*2.5:"silk"===this.mode?m*t:-s*h*2.5,a="magnetic"===this.mode?-s*h*2.5:"silk"===this.mode?f*t:i*h*2.5;this.targetX[u]=Math.max(-1,Math.min(1,this.targetX[u]+e*p)),this.targetY[u]=Math.max(-1,Math.min(1,this.targetY[u]+a*p))}}}this.peak=1}step(t){if(!this.active||!Number.isFinite(t))return;const e=Math.max(0,Math.min(.05,t)),i="dissolve"===this.mode?2.15:"smudge"===this.mode?2.4:3.2,s="lens"===this.mode?16:22,a=Math.exp(-i*e),r=1-Math.exp(-s*e);let o=0;const[n,h]="scatter"===this.mode?Mt.scatter:Mt.elastic,l=Math.sqrt(n-h*h),c=Math.exp(-h*e),d=Math.cos(l*e),u=Math.sin(l*e)/l;for(let t=0;t<this.ink.length;t++)if("etch"===this.mode)this.ink[t]*=a,o=Math.max(o,this.ink[t]);else if("dissolve"===this.mode){this.ink[t]*=a,o=Math.max(o,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(gt(this.mode)){const e=this.offsetX[t],i=this.offsetY[t],s=this.springX[t],a=this.springY[t];this.offsetX[t]=Math.max(-1,Math.min(1,c*(e*d+(s+h*e)*u))),this.offsetY[t]=Math.max(-1,Math.min(1,c*(i*d+(a+h*i)*u))),this.springX[t]=c*(s*d-(h*s+n*e)*u),this.springY[t]=c*(a*d-(h*a+n*i)*u),o=Math.max(o,.05*Math.abs(this.springX[t]),.05*Math.abs(this.springY[t]))}else if("lens"===this.mode||"smudge"===this.mode){const e=1-r,o=s/(s-i)*(a-e);this.offsetX[t]=this.offsetX[t]*e+this.targetX[t]*o,this.offsetY[t]=this.offsetY[t]*e+this.targetY[t]*o,this.targetX[t]*=a,this.targetY[t]*=a}else this.targetX[t]*=a,this.targetY[t]*=a,this.offsetX[t]+=(this.targetX[t]-this.offsetX[t])*r,this.offsetY[t]+=(this.targetY[t]-this.offsetY[t])*r;o=Math.max(o,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),l=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]=l>>>8,this.pixels[4*t+3]=255&l}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,s=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,s))*(this.edgeSafe?this.edge[i]:1);const a=Math.round(32767*this.offsetX[i]+32768);this.pixels[4*i]=a>>>8,this.pixels[4*i+1]=255&a}this.peak=o,this.active||this.clear()}sample(t,e,i){const s=Math.max(0,Math.min(this.width-1.001,t*(this.width-1))),a=Math.max(0,Math.min(this.height-1.001,e*(this.height-1))),r=Math.floor(s),o=Math.floor(a),n=s-r,h=a-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?mt(t,e,this.width/this.height):1)*.08,i[1]=d(this.offsetY)*(this.edgeSafe?mt(t,e,this.width/this.height):1)*.08,i[2]="dissolve"===this.mode?6*-d(this.ink):0}},vt=class{constructor(t,e){this.rings=[],this.previous=null,this.elapsed=1,this.echoPeak=0,this.width=t,this.height=e,this.pixels=new Uint8Array(t*e*4),this.echo=new Float32Array(t*e)}get active(){return this.rings.length>0||this.echoPeak>2e-4}clear(){this.rings=[],this.previous=null,this.elapsed=1,this.pixels.fill(0),this.echo.fill(0),this.echoPeak=0}leave(){this.previous=null}move(t,e,i){const s=Math.max(1,this.width/this.height),a=Math.max(1,this.height/this.width);this.previous&&(Math.hypot((t-this.previous.x)*s,(e-this.previous.y)*a)<.065||this.elapsed<.3)||4!==this.rings.length&&(this.previous={x:t,y:e},this.elapsed=0,this.rings.push({x:t,y:e,age:0,radius:i}))}ringSample(t,e){const i=Math.max(1,this.width/this.height),s=Math.max(1,this.height/this.width);let a=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)*s)-o)/n,l=Math.sin(Math.min(1,r.age/.07)*Math.PI/2)*Math.max(0,1-r.age/1.35)**2;a=Math.max(a,Math.exp(-h*h)*l)}return a}sample(t,e){const i=Math.max(0,Math.min(this.width-1,Math.round(t*(this.width-1)))),s=Math.max(0,Math.min(this.height-1,Math.round(e*(this.height-1))));return Math.max(this.ringSample(t,e),this.echo[s*this.width+i])}step(t){if(!Number.isFinite(t))return;const e=Math.max(0,Math.min(.05,t));this.elapsed+=e;for(const t of this.rings)t.age+=e;if(this.rings=this.rings.filter(t=>t.age<1.35),!this.active)return void this.pixels.fill(0);const i=Math.exp(-5.5*e);let s=0;for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++){const a=t*this.width+e;this.echo[a]=Math.max(this.ringSample(e/(this.width-1),t/(this.height-1)),this.echo[a]*i),s=Math.max(s,this.echo[a]);const r=Math.round(65535*this.echo[a]),o=4*a;this.pixels[o]=r>>>8,this.pixels[o+1]=255&r}this.echoPeak=s,this.active||(this.echo.fill(0),this.pixels.fill(0))}},bt=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,s=performance.now()){if(!Number.isFinite(t+e+i+s))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 a=this.previous;if(this.previous={x:t,y:e,time:s},!a)return;const r=(t-a.x)*(this.width-1),o=(e-a.y)*(this.height-1),n=Math.hypot(r,o);if(n<.001)return;const h=Math.min(this.width,this.height),l=s>a.time?Math.max(1/240,(s-a.time)/1e3):1/60,c=Math.min(12,n/h/l),d=1-Math.exp(-c/2.2),u=h*(.022+.075*i)*(.65+.95*d),m=Math.min(128,Math.max(1,Math.ceil(n/(.4*u)))),f=n/u*(.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 s=(i+.5)/m,r=(a.x+(t-a.x)*s)*(this.width-1),o=(a.y+(e-a.y)*s)*(this.height-1),n=Math.max(1,Math.floor(r-3*u)),h=Math.min(this.width-2,Math.ceil(r+3*u)),l=Math.max(1,Math.floor(o-3*u)),c=Math.min(this.height-2,Math.ceil(o+3*u));for(let t=l;t<=c;t++)for(let e=n;e<=h;e++){const i=((e-r)*p+(t-o)*g)/u,s=((e-r)*M+(t-o)*x)/u,a=Math.exp(-i*i*.65-s*s*1.7),n=t*this.width+e;this.ink[n]=1-(1-this.ink[n])*Math.exp(-a*f);const h=1-s*s*.55,l=i*s*.7;this.u[n]=Math.max(-80,Math.min(80,this.u[n]+(p*h+M*l)*a*v)),this.v[n]=Math.max(-80,Math.min(80,this.v[n]+(g*h+x*l)*a*v))}}this.peak=1}read(t,e,i){const s=0|(e=Math.max(.5,Math.min(this.width-1.5,e))),a=0|(i=Math.max(.5,Math.min(this.height-1.5,i))),r=e-s,o=i-a,n=a*this.width+s;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,s=this.height;for(;e>1e-7;){const t=Math.min(1/60,e);e-=t;const a=Math.exp(-1.9*t),r=Math.exp(-3.2*t);for(let e=1;e<s-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(s-1.5,e-this.v[n]*t)),c=0|h,d=0|l,u=h-c,m=l-d,f=d*i+c,p=(1-u)*(1-m),g=u*(1-m),M=(1-u)*m,x=u*m;this.a[n]=(this.u[f]*p+this.u[f+1]*g+this.u[f+i]*M+this.u[f+i+1]*x)*a,this.b[n]=(this.v[f]*p+this.v[f+1]*g+this.v[f+i]*M+this.v[f+i+1]*x)*a,this.c[n]=(this.ink[f]*p+this.ink[f+1]*g+this.ink[f+i]*M+this.ink[f+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<s-1;t++)for(let e=1;e<i-1;e++){const s=t*i+e;this.curl[s]=.5*(this.v[s+1]-this.v[s-1]-this.u[s+i]+this.u[s-i])}for(let e=1;e<s-1;e++)for(let s=1;s<i-1;s++){const a=e*i+s,r=Math.abs(this.curl[a+1])-Math.abs(this.curl[a-1]),o=Math.abs(this.curl[a+i])-Math.abs(this.curl[a-i]),n=Math.hypot(r,o)+1e-4,h=this.curl[a]*t*10,l=Math.hypot(this.u[a],this.v[a]);this.u[a]+=o/n*h,this.v[a]-=r/n*h;const c=Math.min(1,l/(Math.hypot(this.u[a],this.v[a])+1e-6));this.u[a]*=c,this.v[a]*=c,this.divergence[a]=-.5*(this.u[a+1]-this.u[a-1]+this.v[a+i]-this.v[a-i])}this.pressure.fill(0);for(let t=0;t<4;t++){for(let t=1;t<s-1;t++)for(let e=1;e<i-1;e++){const s=t*i+e;this.pressureNext[s]=.25*(this.divergence[s]+this.pressure[s-1]+this.pressure[s+1]+this.pressure[s-i]+this.pressure[s+i])}[this.pressure,this.pressureNext]=[this.pressureNext,this.pressure]}let o=0;for(let e=1;e<s-1;e++)for(let s=1;s<i-1;s++){const a=e*i+s;this.u[a]=Math.max(-80,Math.min(80,this.u[a]-.5*(this.pressure[a+1]-this.pressure[a-1]))),this.v[a]=Math.max(-80,Math.min(80,this.v[a]-.5*(this.pressure[a+i]-this.pressure[a-i]))),this.driftX[a]+=(3.6*this.u[a]-58*this.offsetX[a]-12*this.driftX[a])*t,this.driftY[a]+=(3.6*this.v[a]-58*this.offsetY[a]-12*this.driftY[a])*t,this.offsetX[a]=Math.max(-2,Math.min(2,this.offsetX[a]+this.driftX[a]*t)),this.offsetY[a]=Math.max(-2,Math.min(2,this.offsetY[a]+this.driftY[a]*t)),this.signal[a]=1-Math.exp(.06*-Math.hypot(this.u[a],this.v[a])-.16*this.ink[a]),o=Math.max(o,this.signal[a])}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()}};var wt=["loupe","repel","tilt","reveal","haze","bleed"],yt=t=>wt.includes(t),St=class{constructor(){this.value=0,this.velocity=0}step(t,e,i,s){const a=2*Math.sqrt(i)*s;for(let s=e;s>1e-6;s-=1/480){const e=Math.min(1/480,s);this.velocity+=((t-this.value)*i-this.velocity*a)*e,this.value+=this.velocity*e}}resting(t){return Math.abs(this.value-t)<.0015&&Math.abs(this.velocity)<.01}set(t){this.value=t,this.velocity=0}},kt=t=>t*t*(3-2*t),Et=(t,e)=>{const i=43758.5453*Math.sin(127.1*t+311.7*e);return i-Math.floor(i)};function At(t,e){const i=Math.floor(t),s=Math.floor(e),a=kt(t-i),r=kt(e-s),o=Et(i,s),n=Et(i+1,s),h=Et(i,s+1);return(o+(n-o)*a)*(1-r)+(h+(Et(i+1,s+1)-h)*a)*r}var Ft=class{constructor(t,e){this.edgeSafe=!1,this.settle=1,this.focus=[.5,.5,0,.2],this.guide=null,this.mode="loupe",this.radius=.35,this.x=new St,this.y=new St,this.tx=new St,this.ty=new St,this.presence=new St,this.target=null,this.speed=0,this.clock=0,this.inkPeak=0,this.ink=null,this.next=null,this.fiber=null,this.sampled=[0,0,0],this.width=t,this.height=e,this.pixels=new Uint8Array(t*e*4),this.sx=Math.max(1,t/e),this.sy=Math.max(1,e/t),this.clear()}setMode(t){if(t!==this.mode&&(this.mode=t,this.clear(),"bleed"===t&&!this.ink)){const t=this.width*this.height;this.ink=new Float32Array(t),this.next=new Float32Array(t),this.fiber=new Float32Array(t);for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++)this.fiber[t*this.width+e]=.35+.5*At(.09*e,.045*t)+.15*Et(e,t)}}setRadius(t){this.radius=Math.max(.1,Math.min(1,t))}get reach(){return(.05+.25*this.radius)*("loupe"===this.mode?1-.14*this.speed:1)}get engaged(){return this.presence.value>.002||this.inkPeak>.002||Math.abs(this.tx.value)+Math.abs(this.ty.value)>4e-4}get active(){const t=this.target?1:0;return!this.presence.resting(t)||!!this.target&&(!this.x.resting(this.target.x)||!this.y.resting(this.target.y))||!this.tx.resting(this.tiltGoal(0))||!this.ty.resting(this.tiltGoal(1))||this.speed>.01||"haze"===this.mode&&this.presence.value>.002||this.inkPeak>.002}tiltGoal(t){return this.target&&"tilt"===this.mode?2*((t?this.target.y:this.target.x)-.5):0}clear(){for(const t of[this.x,this.y,this.tx,this.ty,this.presence])t.set(0);this.x.set(.5),this.y.set(.5),this.target=null,this.speed=0,this.inkPeak=0,this.ink?.fill(0),this.next?.fill(0),this.encode()}move(t,e,i){if(!Number.isFinite(t+e))return;t=Math.max(0,Math.min(1,t)),e=Math.max(0,Math.min(1,e));const s=Number.isFinite(i)?i/1e3:this.clock,a=this.target;if(!a&&this.presence.value<.05&&(this.x.set(t),this.y.set(e)),a){const i=Math.hypot((t-a.x)*this.sx,(e-a.y)*this.sy),r=i/Math.max(1/240,Math.min(.1,s-a.time||1/60));this.speed=Math.max(this.speed,Math.min(1,r/1.6)),"bleed"===this.mode&&this.deposit(a.x,a.y,t,e,Math.min(1,9*i))}else"bleed"===this.mode&&this.deposit(t,e,t,e,.5);this.target={x:t,y:e,time:s}}leave(){this.target=null}deposit(t,e,i,s,a){const r=this.ink,o=this.width,n=this.height,h=.55*this.reach,l=Math.hypot((i-t)*this.sx,(s-e)*this.sy),c=Math.min(48,Math.max(1,Math.ceil(l/(.5*h))));for(let l=0;l<c;l++){const d=(l+.5)/c,u=t+(i-t)*d,m=e+(s-e)*d,f=Math.max(0,Math.floor((u-2*h/this.sx)*(o-1))),p=Math.min(o-1,Math.ceil((u+2*h/this.sx)*(o-1))),g=Math.max(0,Math.floor((m-2*h/this.sy)*(n-1))),M=Math.min(n-1,Math.ceil((m+2*h/this.sy)*(n-1)));for(let t=g;t<=M;t++)for(let e=f;e<=p;e++){const i=(e/(o-1)-u)*this.sx/h,s=(t/(n-1)-m)*this.sy/h,l=t*o+e;r[l]=Math.min(1.4,r[l]+Math.exp(1.8*-(i*i+s*s))*a/c*1.6)}}this.inkPeak=Math.max(this.inkPeak,.01)}step(t){if(!Number.isFinite(t)||t<=0)return;const e=Math.min(.05,t),i=e*this.settle;this.clock+=e;const s=this.target,a=this.mode;if(s?this.presence.step(1,e,190,1):this.presence.step(0,i,"repel"===a?120:70,"repel"===a?.42:1),s){const t="tilt"===a?60:"haze"===a?90:240,i="loupe"===a||"repel"===a?.72:.9;this.x.step(s.x,e,t,i),this.y.step(s.y,e,t,i)}this.tx.step(this.tiltGoal(0),s?e:i,45,.78),this.ty.step(this.tiltGoal(1),s?e:i,45,.78),this.speed*=Math.exp(7*-e),"bleed"===a&&this.spread(e,i,!!s),this.engaged||this.active||(this.presence.set(0),this.tx.set(0),this.ty.set(0)),this.focus[0]=this.x.value,this.focus[1]=this.y.value,this.focus[2]=Math.max(0,Math.min(1,this.presence.value)),this.focus[3]=this.reach,this.encode()}spread(t,e,i){const s=this.ink,a=this.next,r=this.fiber,o=this.width,n=this.height;i&&this.target&&this.deposit(this.x.value,this.y.value,this.x.value,this.y.value,.9*t);const h=Math.max(1,Math.ceil(t/(1/240))),l=t/h,c=26*(.4+this.radius),d=(i?.02:.1)*e/t,u=Math.exp(-(i?.15:.9)*e/h);let m=0;for(let t=0;t<h;t++){m=0;for(let t=1;t<n-1;t++)for(let e=1;e<o-1;e++){const i=t*o+e,n=s[i],h=r[i],f=Math.min(h,r[i-1])*(s[i-1]-n)+Math.min(h,r[i+1])*(s[i+1]-n)+Math.min(h,r[i-o])*(s[i-o]-n)+Math.min(h,r[i+o])*(s[i+o]-n),p=Math.max(0,(n+f*Math.min(.24,c*l))*u-d*l);a[i]=p,p>m&&(m=p)}s.set(a)}this.inkPeak=m}sample(t,e,i){i[0]=i[1]=i[2]=0;const s=this.presence.value,a=this.mode;if("bleed"===a){if(this.inkPeak<=.002)return;const s=this.width,a=this.height,r=this.ink,o=Math.max(0,Math.min(s-1.001,t*(s-1))),n=Math.max(0,Math.min(a-1.001,e*(a-1))),h=Math.floor(o),l=Math.floor(n),c=o-h,d=n-l,u=l*s+h,m=u+s,f=(r[u]*(1-c)+r[u+1]*c)*(1-d)+(r[m]*(1-c)+r[m+1]*c)*d;return void(i[2]=1-Math.exp(2.4*-f))}if("tilt"===a){const s=this.guide?function(t,e,i,s){const a=t[e],r=t.width,o=t.height,n=Math.max(0,Math.min(r-1.001,i*(r-1))),h=Math.max(0,Math.min(o-1.001,s*(o-1))),l=Math.floor(n),c=Math.floor(h),d=n-l,u=h-c,m=c*r+l,f=Math.min(o-1,c+1)*r+l,p=l+1<r?1:0;return(a[m]*(1-d)+a[m+p]*d)*(1-u)+(a[f]*(1-d)+a[f+p]*d)*u}(this.guide,"depth",t,e):.6,a=.2+.8*s,r=this.edgeSafe?mt(t,e,this.sx/this.sy):1;return i[0]=.024*this.tx.value*a*r/this.sx,void(i[1]=.024*this.ty.value*a*r/this.sy)}if(s<=.001)return;const r=this.reach,o=(t-this.x.value)*this.sx,n=(e-this.y.value)*this.sy,h=(o*o+n*n)/(r*r);if("reveal"===a)return void(i[2]=Math.exp(2.4*-h)*s);if(h>9)return;const l=this.edgeSafe?mt(t,e,this.sx/this.sy):1;let c=0,d=0;if("loupe"===a){const t=Math.exp(-h*h)*s*.5;c=o*t,d=n*t;const e=Math.sqrt(h)-1;i[2]=Math.exp(-e*e/.018)*s*.55}else if("repel"===a){const t=Math.sqrt(h),e=.5*r*Math.exp(-h/1.7)*s,a=Math.max(1e-6,Math.sqrt(o*o+n*n));c=o/a*Math.min(e,a+.5*r*s),d=n/a*Math.min(e,a+.5*r*s);const l=Math.max(0,Math.min(1,(t-.3)/.32));i[2]=-(1-l*l*(3-2*l))*s}else if("haze"===a){const a=n/r+.45,h=Math.exp(-o*o/(r*r)-a*a/2.6)*s*(.35+.65*Math.min(1,1.4*this.speed+.25));if(h<.002)return;const l=this.clock,u=t*this.sx*9,m=e*this.sy*9+2.3*l;c=.06*(At(u,m)-.5)*h,d=.026*(At(u+17.3,1.3*m+.7*l)-.5)*h,i[2]=.35*(At(1.7*u+5,1.7*m)-.5)*h}i[0]=c*l/this.sx,i[1]=d*l/this.sy}encode(){const t=this.width,e=this.height,i=this.pixels,s=this.sampled,a=this.engaged;for(let r=0;r<e;r++)for(let o=0;o<t;o++){const n=4*(r*t+o);if(a?this.sample(o/(t-1),r/(e-1),s):s[0]=s[1]=s[2]=0,"bleed"===this.mode){const t=Math.round(32767*Math.max(-1,Math.min(1,s[2]))+32768);i[n]=t>>>8,i[n+1]=255&t,i[n+2]=128,i[n+3]=0}else{"repel"===this.mode&&(s[0]*=.3,s[1]*=.3);const t=Math.round(32767*Math.max(-1,Math.min(1,s[0]/.16))+32768),e=Math.round(32767*Math.max(-1,Math.min(1,s[1]/.16))+32768);i[n]=t>>>8,i[n+1]=255&t,i[n+2]=e>>>8,i[n+3]=255&e}}}},Pt=(t,e)=>"water"===t?30*e/.55:"silk"===t?28*e:"vortex"===t?38*e:["magnetic","scatter","elastic","lens","smudge"].includes(t)?32*e:["loupe","repel","tilt","haze"].includes(t)?.16*e/.55:0;function Tt(t,e,i,s=!1){if(!i)return e;const a=t=>Math.max(0,Math.min(1,t));switch(t){case"trail":case"contour":return function(t,e){const i=Math.max(0,Math.min(1,e/.38));return t+i*i*(3-2*i)*(1-2*t)}(e,i);case"etch":case"ripple":return a(e+.35*i);case"dissolve":{const t=Math.max(0,1+i);return s?1-(1-e)*t:e*t}case"bleed":return a(e+i*(s?-.6:.6));case"loupe":return a(e+.3*i);case"haze":return a(e+.5*i);default:return e}}var It=t=>["trail","contour","etch","ripple","bleed","haze"].includes(t),Ct=class{constructor(t=1){this.ripple=null,this.cursor=null,this.settle=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,this.guide=null,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]=mt(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 bt(this.columns,this.rows),this.contour=new vt(this.columns,this.rows),this.afterimage=new xt(this.columns,this.rows),this.clear()}get invertsDensity(){return"trail"===this.mode}get densityTrail(){return["trail","contour","dissolve","etch","ripple","bleed"].includes(this.mode)}get hasRefraction(){return this.active||this.lensStrength>15e-5}get effect(){return this.mode}get engaged(){return yt(this.mode)?this.cursor.engaged:this.active}get spotlight(){return"reveal"===this.mode&&this.cursor?this.cursor.focus:null}get signature(){return yt(this.mode)&&this.cursor.engaged?this.cursor.focus.map(t=>t.toFixed(4)).join(","):""}setGuide(t){this.cursor&&(this.cursor.guide=t),this.guide=t}get active(){return yt(this.mode)?this.cursor.active:"ripple"===this.mode?this.ripple?.active??!1:pt(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){const e="light"===t||"scan"===t?t:i(t)??"none";e!==this.mode&&(this.clear(),this.mode=e,this.refraction.mode=e,pt(e)&&this.afterimage.setMode(e),"ripple"!==e||this.ripple||(this.ripple=new ft(this.columns,this.rows)),yt(e)&&(this.cursor??(this.cursor=new Ft(this.columns,this.rows)),this.cursor.guide=this.guide,this.cursor.setMode(e)),this.refraction.pixels=yt(e)?this.cursor.pixels:"ripple"===e?this.ripple.pixels:"trail"===e?this.trail.pixels:"contour"===e?this.contour.pixels:pt(e)?this.afterimage.pixels:this.waterPixels,this.refraction.strength=Pt(e,this.amount),this.refraction.relative=yt(e))}configure(t,e=.55,i=.2,s=!1,a=.5){this.setMode(t),this.settle=((t=.5)=>Math.pow(2,2.4*(.5-(Number.isFinite(t)?Math.max(0,Math.min(1,t)):.5))))(a),this.refraction.edgeSafe=s,this.afterimage.edgeSafe=s,this.ripple&&(this.ripple.edgeSafe=s),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.cursor&&(this.cursor.edgeSafe=s,this.cursor.settle=this.settle,this.cursor.setRadius(this.radius)),this.refraction.strength=Pt(this.mode,this.amount),this.refraction.focus[2]=this.densityTrail?this.amount:this.lensStrength*this.amount,this.refraction.focus[3]=this.radius,"reveal"!==this.mode&&"repel"!==this.mode||this.syncSpot()}syncSpot(){const t=this.cursor.focus;this.refraction.focus=[t[0],t[1],t[2]*("repel"===this.mode?Math.min(1,this.amount/.55):this.amount),t[3]]}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)),yt(this.mode))return void this.cursor.move(t,e,i);if("ripple"===this.mode)return void this.ripple.move(t,e,this.radius,i);if(pt(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 s=this.previous;this.previous={x:t,y:e};const a=(t-s.x)*this.xScale,r=(e-s.y)*this.yScale,o=Math.hypot(a,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 a=(i+.5)/l,r=s.x+(t-s.x)*a,o=s.y+(e-s.y)*a,d=Math.max(1,Math.floor((r-h/this.xScale)*(this.columns-1))),u=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))),f=Math.min(this.rows-2,Math.ceil((o+h/this.yScale)*(this.rows-1)));for(let t=m;t<=f;t++)for(let e=d;e<=u;e++){const i=(e/(this.columns-1)-r)*this.xScale,s=(t/(this.rows-1)-o)*this.yScale,a=Math.exp(-(i*i+s*s)/(n*n))*c,h=t*this.columns+e;this.velocity[h]=Math.max(-12,this.velocity[h]-a)}}this.pending=!0}leave(){this.cursor?.leave(),this.ripple?.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.ripple?.clear(),this.cursor?.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(yt(this.mode))return this.cursor.step(t),void("reveal"!==this.mode&&"repel"!==this.mode||this.syncSpot());if(t*=this.settle,"ripple"===this.mode)return void this.ripple.step(t);if(pt(this.mode))return void this.afterimage.step(t);if("contour"===this.mode)return void this.contour.step(t);if("trail"===this.mode)return void this.trail.step(t);if("water"!==this.mode)return void this.stepLight(Math.max(0,Math.min(.05,t)));this.remainder+=Math.max(0,Math.min(.05,t));const e=1/120,i=Math.exp(-3.8*e),s=.3*Math.min(this.columns,this.rows);for(;this.remainder+1e-8>=e;){this.remainder-=e;let t=0;for(let a=1;a<this.rows-1;a++)for(let r=1;r<this.columns-1;r++){const o=a*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,a,this.columns-1-r,this.rows-1-a),c=l<5?.88+.024*l:1,d=(this.velocity[o]+(h*s*s-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 a=.18*Math.min(this.columns,this.rows);for(let t=0;t<this.rows;t++)for(let e=0;e<this.columns;e++){const i=t*this.columns+e,s=(this.heights[t*this.columns+Math.max(0,e-1)]-this.heights[t*this.columns+Math.min(this.columns-1,e+1)])*a,r=(this.heights[Math.max(0,t-1)*this.columns+e]-this.heights[Math.min(this.rows-1,t+1)*this.columns+e])*a,o=Math.tanh(s)*(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),s=1-Math.exp(-12*t);e&&(this.lensX+=(e.x-this.lensX)*i,this.lensY+=(e.y-this.lensY)*i),this.lensStrength+=((e?1:0)-this.lensStrength)*s,this.energy=Math.max(e?Math.abs(e.x-this.lensX)+Math.abs(e.y-this.lensY):0,Math.abs((e?1:0)-this.lensStrength)),this.pending=!1,e||this.active?this.refraction.focus=[this.lensX,this.lensY,this.lensStrength*this.amount,this.radius]:this.clear()}sample(t,e,i){if(yt(this.mode))return this.cursor.sample(t,e,i),i[0]*=this.amount/.55,i[1]*=this.amount/.55,void(i[2]*="reveal"===this.mode||"repel"===this.mode?Math.min(1,this.amount/.55):3*this.amount);if("ripple"===this.mode)return this.ripple.sample(t,e,i),void(i[2]*=this.amount);if(pt(this.mode))return this.afterimage.sample(t,e,i),i[0]*=this.amount,i[1]*=this.amount,void(i[2]*=this.amount);if("contour"===this.mode)return i[0]=i[1]=0,void(i[2]=this.contour.sample(t,e)*this.amount*3);if("trail"===this.mode)return i[0]=i[1]=0,void(i[2]=this.trail.sample(t,e)*this.amount*3);const s=Math.max(0,Math.min(this.columns-1.001,t*(this.columns-1))),a=Math.max(0,Math.min(this.rows-1.001,e*(this.rows-1))),r=Math.floor(s),o=Math.floor(a),n=s-r,h=a-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,s){const[a,r,o,n]=i.focus,h=(t-a)*Math.max(1,s)/n,l=(e-r)*Math.max(1,1/s)/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 Rt(t){return"videoWidth"in t?[t.videoWidth,t.videoHeight]:"naturalWidth"in t?[t.naturalWidth,t.naturalHeight]:[t.width,t.height]}var Lt=(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}},Nt=(t,e,i)=>{t.width===e&&t.height===i||(t.width=e,t.height=i)},Ot={blocks:" ░▒▓█",braille:" ⠁⠃⠇⡇⣇⣧⣷⣿",lines:" -═╪╬",cross:" ·+xX#",diagonal:" /╱╳",diamond:" ·◇◈◆",mixed:" .:+/◇#@"},Dt=.32,Ut=.9;function Xt(t){const e=new Uint32Array(256);let i=0;for(let s=0;s<t.length;s+=4)t[s+3]<8||(e[Math.min(255,.299*t[s]+.587*t[s+1]+.114*t[s+2]|0)]++,i++);if(!i)return[0,1];const s=t=>{let s=0;const a=t*i;for(let t=0;t<256;t++)if((s+=e[t])>=a)return t/255;return 1};let a=s(.01),r=s(.99);return r-a<Dt&&(a=Math.max(0,Math.min(1-Dt,(a+r)/2-.16)),r=a+Dt),[a,r]}function jt(t,e,i){const s=Math.max(.001,i-e);let a=0,r=0;for(let i=0;i<t.length;i+=4){if(t[i+3]<8)continue;const o=((.299*t[i]+.587*t[i+1]+.114*t[i+2])/255-e)/s;o<=.06||(a+=Math.min(1,o),r++)}if(!r)return Ut;const o=Math.min(.99,Math.max(.01,a/r));return Math.min(Ut,Math.max(.6,Math.log(.5)/Math.log(o)))}function zt(t,e=.9){const i=Math.min(...t),s=Math.max(...t);if(!(s-i>1e-4))return null;const a=t.map(t=>(t-i)/(s-i)),r=new Uint8Array(256);for(let t=0;t<256;t++){if(t/255<.07){r[t]=a.indexOf(0);continue}const i=Math.pow(t/255,e);let s=0;for(let t=1;t<a.length;t++)Math.abs(a[t]-i)<Math.abs(a[s]-i)&&(s=t);r[t]=s}return r}function Yt(t,e,i,s){t.clearRect(0,0,e,i),t.fillStyle="#fff",t.strokeStyle="#fff",t.lineCap="round",t.lineJoin="round";for(const a of s){if(t.beginPath(),"ellipse"===a.kind)t.ellipse((a.x+a.width/2)*e,(a.y+a.height/2)*i,a.width*e/2,a.height*i/2,0,0,2*Math.PI);else{if("rectangle"!==a.kind){if(t.lineWidth=(a.size??.05)*e,1===a.points?.length){t.arc(a.points[0][0]*e,a.points[0][1]*i,t.lineWidth/2,0,2*Math.PI),t.fill();continue}a.points?.forEach(([s,a],r)=>r?t.lineTo(s*e,a*i):t.moveTo(s*e,a*i)),t.stroke();continue}t.rect(a.x*e,a.y*i,a.width*e,a.height*i)}t.fill()}}function qt(t,e={},i={}){const s=t.getContext("2d");if(!s)throw new Error("Canvas is already owned by another renderer.");const o=Lt(),n=Lt(!0),h=Lt(),l=Lt(),c=Lt(),m=Lt(),f=Lt(),p=Lt(),g=Lt(),M=Lt();let v,b=0,w=0,y=1,S=Ut,k=null,A=null,P=null,T="",I=j(e),C=0,R="",N="",O="",D=new Uint8ClampedArray(0),U=new Uint8ClampedArray(0),X=0,Y=0,q=0,W=null,G="",Q=new Ct,J=null,K=new Float32Array(0);const Z=Lt(!0),_=Lt(),$=Lt();let tt=0;const it=[0,0,0],rt=[0,0,0,1],ot=[0,0,0,0];let nt=H(I.color),mt=et(I.print);const ft=new V(I.color.denoise),pt=new E(I.warps,I.warpEdge),gt=Math.max(64,Math.min(4096,Number.isFinite(i.maxDimension)?i.maxDimension:960)),Mt=Math.max(256,Math.min(1048576,Number.isFinite(i.maxCells)?i.maxCells:12e3));let xt=Mt,vt=Math.max(.1,Math.min(8,i.pixelRatio??1));return{canvas:t,render:function(e,i=0,E=960,j=540,H=i*I.motion.speed){if(Number.isFinite(i)||(i=0),!Number.isFinite(E)||!Number.isFinite(j)||E<1||j<1)throw new Error("Render dimensions must be positive finite numbers.");const[V,et]=Rt(e);if(!V||!et)return;const Mt=Math.min(1,gt/Math.max(E,j)),bt=Math.max(2,Math.round(E*Mt)),wt=Math.max(2,Math.round(j*Mt));Nt(t,bt,wt),Nt(o.canvas,bt,wt),Nt(h.canvas,bt,wt),Nt(l.canvas,bt,wt),Nt(c.canvas,bt,wt),tt!==bt/wt&&(tt=bt/wt,Q=new Ct(tt),Q.setGuide(J)),Q.configure(I.hover.effect,I.hover.strength,I.hover.radius,I.hover.edgeSafe,I.hover.decay),Q.step(Math.max(0,Math.min(.05,i-q))),q=i;const yt="currentTime"in e?e.getVideoPlaybackQuality?.().totalVideoFrames??e.currentTime:0,St=[C,bt,wt,yt].join(":"),kt="dither"===I.style,Et=B(bt,wt,I,xt,vt),At=Et.cell,Ft=Et.rowHeight,Pt=Et.columns,Lt=Et.rows;if(R!==St||W!==e||X!==Pt||Y!==Lt){W=e,R=St,N="",O="",X=Pt,Y=Lt,o.ctx.clearRect(0,0,bt,wt),o.ctx.save();const t=z(V,et,bt,wt,I.crop);o.ctx.translate(t.x+t.width/2,t.y+t.height/2),o.ctx.rotate(I.crop.rotation*Math.PI/180),o.ctx.drawImage(e,-V*t.scale/2,-et*t.scale/2,V*t.scale,et*t.scale),o.ctx.restore(),Nt(n.canvas,X,Y),n.ctx.clearRect(0,0,X,Y),n.ctx.drawImage(o.canvas,0,0,X,Y),D=n.ctx.getImageData(0,0,X,Y).data,ft.apply(D,X,Y);const i=I.color;for(let t=0;t<D.length;t+=4){const e=.299*D[t]+.587*D[t+1]+.114*D[t+2];for(let s=0;s<3;s++){const a=e+(D[t+s]-e)*i.saturation;D[t+s]=((a*(1-i.grayscale)+e*i.grayscale)/255-.5)*i.contrast*255+127.5+255*i.brightness}}if(nt&&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]])}(D,nt),D=pt.apply(D,X,Y,bt/wt),"none"!==I.color.levels){const[t,i]=Xt(D),s=jt(D,t,i),a=k===e&&"currentTime"in e?.15:1;k=e,w+=(t-w)*a,y+=(i-y)*a,S+=(s-S)*a}const s=I.hover,h=s.scope??"all";if("none"===s.effect||"all"===h&&"tilt"!==s.effect)J=null;else{let t=null;if(I.mask.enabled&&I.mask.shapes.length){Nt(Z.canvas,X,Y),Z.ctx.clearRect(0,0,X,Y),Yt(Z.ctx,X,Y,I.mask.shapes);const e=Z.ctx.getImageData(0,0,X,Y).data;t=new Float32Array(X*Y);for(let i=0;i<t.length;i++)t[i]=I.mask.invert?1-e[4*i+3]/255:e[4*i+3]/255}J=function(t,e,i,s,r){const o=e*i,n=r&&r.width===e&&r.height===i?r:{width:e,height:i,subject:new Float32Array(o),depth:new Float32Array(o),key:"none"},{subject:h,depth:l}=n;let c=0;for(let e=0;e<o;e++)t[4*e+3]<250&&c++;const d=e=>(.2126*t[4*e]+.7152*t[4*e+1]+.0722*t[4*e+2])/255;let u="none",m=0;if(c>.01*o)u="alpha";else if(s)u="mask";else{let t=0,s=0,a=0;const r=Math.max(1,Math.round(.03*Math.min(e,i)));for(let o=0;o<i;o++)for(let n=0;n<e;n++){if(n>=r&&o>=r&&n<e-r&&o<i-r)continue;const h=d(o*e+n);t+=h,s+=h*h,a++}m=t/Math.max(1,a),Math.sqrt(Math.max(0,s/Math.max(1,a)-m*m))<.07&&(u="ground")}for(let e=0;e<o;e++){const i=t[4*e+3]/255,a=d(e);let r=1;if("alpha"===u)r=i;else if("ground"===u){const t=Math.max(0,Math.min(1,(Math.abs(a-m)-.035)/.12));r=t*t*(3-2*t)}h[e]=r*(s?Math.max(0,Math.min(1,s[e])):1),l[e]=a*i}n.key=u;const f=new Float32Array(o);return a(h,f,e,i,Math.max(1,Math.round(.02*Math.min(e,i)))),a(l,f,e,i,Math.max(1,Math.round(.035*Math.min(e,i)))),n}(D,X,Y,t,J),K.length!==X*Y&&(K=new Float32Array(X*Y));for(let t=0;t<K.length;t++)K[t]=r(h,J.subject[t],J.key);if("reveal"===s.effect){Nt(_.canvas,X,Y);const t=new ImageData(X,Y);for(let e=0;e<K.length;e++)t.data[4*e+3]=255*K[e];_.ctx.putImageData(t,0,0)}}Q.setGuide(J)}const Dt=at(I),Ut=st(I),qt=!Q.active&&!Dt&&!Ut,Bt=[St,X,Y,At,Ft,vt,Q.signature].join(":"),Wt=Q.engaged,Gt=Q.effect;if(!qt||O!==Bt){h.ctx.clearRect(0,0,bt,wt),h.ctx.globalAlpha=1,h.ctx.globalCompositeOperation="source-over";const t=H,e=Dt?I.motion.type:"none",s=["none","caustics","sheen","grain","trace","relight","shimmer"].includes(e);if(kt){const s=qt;if(!s||N!==St){U.length!==D.length&&(U=new Uint8ClampedArray(D.length));const a=U;if(a.set(D),Wt||"none"!==e)for(let i=0;i<Y;i++)for(let s=0;s<X;s++){const r=s/X,o=i/Y;let n=s,h=i,l=0,c=1,m=1;if(Wt){Q.sample(r,o,it);const t=J?K[i*X+s]:1;n-=it[0]*t*X,h-=it[1]*t*Y,"reveal"===Gt?m=1-.72*Math.min(1,it[2]*t):"repel"===Gt?m=1+Math.max(-1,it[2])*t:l=it[2]/3*t}const f=4*(i*X+s);d(e,r,o,t,rt,(.299*D[f]+.587*D[f+1]+.114*D[f+2])/255),u(rt,I.motion.amount??1),n-=rt[0]/960*X,h-=rt[1]/960*Y,c=1+rt[2],m*=rt[3];const p=4*(i*X+s);x(D,X,Y,n,h,ot);for(let t=0;t<3;t++){let e=Tt(Gt,ot[t]/255,l)*c;a[p+t]=255*e}a[p+3]=ot[3]*m}!function(t,e,i,s,a=0){const{algorithm:r,amount:o,threshold:n}=s,h="blue-noise"===r,l=r.startsWith("bayer")?Number(r.slice(5)):0,c=ct.get(l),d=l-1,u="luminance"===s.colorSpace,m=("custom"===s.palette?s.colors:L[s.palette]??L.mono).map(ut),f=dt[r],p=f?new Float32Array(3*e*3):null,g="drift"===s.motion?a*s.speed*3:0,M=(s.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"===s.motion?.15*Math.sin(a*s.speed*2):0;for(let s=0;s<i;s++)for(let a=0;a<e;a++){const M=4*(s*e+a),S=3*(s%3*e+a);if(0===t[M+3]){p&&(p[S]=p[S+1]=p[S+2]=0);continue}let k=0;const E=h?(ht[64*(s-v&63)+(a-x&63)]+.5)/ht.length:0;c?k=c[(s-v&d)*l+(a-x&d)]:"noise"===r?k=lt(a-x,s-v)-.5:"lines"===r?k=b(s-v,4)/3-.5:"vertical-lines"===r?k=b(a-x,4)/3-.5:"diagonal-lines"===r?k=b(a-x+s-v,4)/3-.5:"radial"===r?k=b(Math.hypot(a-e/2,s-i/2)-g,6)/6-.5:"halftone"===r&&(k=Math.hypot(b(a-x,6)-2.5,b(s-v,6)-2.5)/3.54-.5);const A=128*(k*o+y+(.5-n)),F=t[M]+A+(p?.[S]??0),P=t[M+1]+A+(p?.[S+1]??0),T=t[M+2]+A+(p?.[S+2]??0);let I=0,C=0,R=0;if(m.length){let t=1/0,e=1/0,i=0,s=0;const a=.299*F+.587*P+.114*T;for(let r=0;r<m.length;r++){const o=m[r],n=u?(a-w[r])**2:(F-o[0])**2*.299+(P-o[1])**2*.587+(T-o[2])**2*.114;n<t?(h&&(e=t,s=i,i=r),t=n,[I,C,R]=o):h&&n<e&&(e=n,s=r)}if(h&&o>0&&Number.isFinite(e)){const t=m[s],e=t[0]-I,r=t[1]-C,n=t[2]-R,h=w[s]-w[i],l=u?h*h:e*e*.299+r*r*.587+n*n*.114,c=u?(a-w[i])*h:(F-I)*e*.299+(P-C)*r*.587+(T-R)*n*.114;E<(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+(E-.5)*o));I=51*Math.floor(F/51+1-t),C=51*Math.floor(P/51+1-t),R=51*Math.floor(T/51+1-t)}else I=51*Math.round(F/51),C=51*Math.round(P/51),R=51*Math.round(T/51);if(t[M]=I,t[M+1]=C,t[M+2]=R,p&&f){p[S]=p[S+1]=p[S+2]=0;for(const[t,r,n]of f){const h=a+t;if(h<0||h>=e||s+r>=i)continue;const l=3*((s+r)%3*e+h);p[l]+=(F-I)*n*o,p[l+1]+=(P-C)*n*o,p[l+2]+=(T-R)*n*o}}}}(a,X,Y,I.dither,i),n.ctx.putImageData(new ImageData(a,X,Y),0,0),N=s?St:""}h.ctx.imageSmoothingEnabled=!1,h.ctx.drawImage(n.canvas,0,0,bt,wt)}else{const i=Array.from(Ot[I.style]??I.charset),a=h.ctx,r=ut(I.ink),o="ascii"===I.style||!!Ot[I.style],n=F(I.style)?I.style:null,l=Math.max(3,Math.round(.92*Ft)),c=Math.ceil(At+4),m=Math.ceil(Ft+4),p=[i.join(""),l,c,m,I.ink,I.colorMode].join(":");if(o&&p!==G){G=p,Nt(f.canvas,c*i.length,m),f.ctx.clearRect(0,0,f.canvas.width,m),f.ctx.font=`${l}px monospace`,f.ctx.textBaseline="middle",f.ctx.textAlign="center",f.ctx.fillStyle="accent"===I.colorMode?I.ink:"#ffffff",i.forEach((t,e)=>f.ctx.fillText(t,e*c+c/2,m/2)),A=null,T="";try{const t=f.ctx.getImageData(0,0,f.canvas.width,f.canvas.height).data;A=i.map((e,i)=>{let s=0;for(let e=0;e<f.canvas.height;e++)for(let a=i*c;a<(i+1)*c&&a<f.canvas.width;a++)s+=t[4*(e*f.canvas.width+a)+3];return s})}catch{A=null}}const g=o&&"none"!==I.color.levels;if(g&&A){const t=G+":"+S.toFixed(2);t!==T&&(T=t,P=zt(A,S))}const v=Math.max(.001,y-w);if("lego"===I.style&&b!==At){b=At,Nt(M.canvas,Math.ceil(At),Math.ceil(Ft));const t=M.ctx;t.clearRect(0,0,M.canvas.width,M.canvas.height),t.fillStyle="rgba(255,255,255,.2)",t.strokeStyle="rgba(0,0,0,.25)",t.lineWidth=Math.max(.5,.6*vt),t.beginPath(),t.arc(At/2,Ft/2,.28*At,0,2*Math.PI),t.fill(),t.stroke()}a.font=`${l}px monospace`,a.textBaseline="middle",a.textAlign="center";for(let h=0;h<Y;h++)for(let l=0;l<X;l++){let p=l,b=h,y=0,k=0;if(Wt){Q.sample(l/X,h/Y,it);const t=J?K[h*X+l]:1;p=Math.max(0,Math.min(X-1,l-it[0]*t*X)),b=Math.max(0,Math.min(Y-1,h-it[1]*t*Y)),"reveal"===Gt?k=.72*Math.min(1,it[2]*t):"repel"===Gt?k=-Math.max(-1,it[2])*t:y=it[2]/3*t}if(x(D,X,Y,p,b,ot),!ot[3]){if(!(y>.03&&"outside"===I.hover.scope&&It(Gt)))continue;ot[0]=r[0],ot[1]=r[1],ot[2]=r[2],ot[3]=Math.min(255,640*y)}const E=ot[0],A=ot[1],F=ot[2],T=(.299*E+.587*A+.114*F)/255;let C=g?Math.max(0,Math.min(1,(T-w)/v)):T;C=Tt(Gt,C,y,!!n&&mt.settings.invert);let R=l*At,L=h*Ft,N=1;d(e,l/X,h/Y,t,rt,T),u(rt,I.motion.amount??1),R+=rt[0]*bt/960,L+=rt[1]*wt/960,C=Math.max(0,Math.min(1,C+rt[2])),N=rt[3]*ot[3]/255*(1-k),o||n||"accent"!==I.colorMode||"cmyk"===I.style?g&&"accent"===I.colorMode&&(N*=.32+.68*Math.pow(C,S)):N*=C,a.globalAlpha=N;const O=255*(C-T),U="source"===I.colorMode?`rgb(${E+O},${A+O},${F+O})`:"gray"===I.colorMode?`rgb(${Math.round(255*C)},${Math.round(255*C)},${Math.round(255*C)})`:I.ink;if(a.fillStyle=U,n)mt.paint(a,n,l,h,R,L,At,C,U,"gray"===I.colorMode?255*C:E+O,"gray"===I.colorMode?255*C:A+O,"gray"===I.colorMode?255*C:F+O,I.colorMode);else if(o){const t=g&&P?P[Math.round(255*C)]:Math.max(0,Math.min(i.length-1,Math.round(C*(i.length-1))));"accent"===I.colorMode?a.drawImage(f.canvas,t*c,0,c,m,s?Math.round(R+(At-c)/2):R+(At-c)/2,s?Math.round(L+(Ft-m)/2):L+(Ft-m)/2,c,m):a.fillText(i[t],R+At/2,L+Ft/2)}else if("dots"===I.style)a.beginPath(),a.arc(R+At/2,L+Ft/2,.48*At*Math.sqrt(C),0,2*Math.PI),a.fill();else if("led"===I.style)a.beginPath(),a.arc(R+At/2,L+Ft/2,.39*At,0,2*Math.PI),a.fill(),a.globalAlpha=.35*N,a.fillStyle="#ffffff",a.beginPath(),a.arc(R+.43*At,L+.4*Ft,.11*At,0,2*Math.PI),a.fill();else if("hex"===I.style){const t=R+At/2,e=L+Ft/2;a.beginPath();for(let i=0;i<6;i++){const s=Math.PI/3*i,r=t+Math.cos(s)*At*.49,o=e+Math.sin(s)*Ft*.49;0===i?a.moveTo(r,o):a.lineTo(r,o)}a.closePath(),a.fill()}else if("cmyk"===I.style){a.fillStyle="#ffffff",a.fillRect(R,L,At,Ft);const t=(t,e)=>Math.max(0,Math.min(255,"source"===I.colorMode?t+O:"gray"===I.colorMode?255*C:e*C)),e=t(E,r[0]),i=t(A,r[1]),s=t(F,r[2]),o=1-Math.max(e,i,s)/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-s/255-o)/n,.5,.66],["#000000",o,.5,.5]];a.globalCompositeOperation="multiply";for(const[t,e,i,s]of h)a.fillStyle=t,a.beginPath(),a.arc(R+At*i,L+Ft*s,.48*At*Math.sqrt(Math.max(0,e)),0,2*Math.PI),a.fill();a.globalCompositeOperation="source-over"}else if("voxel"===I.style){const t=R+At/2,e=L+Ft/2;a.beginPath(),a.moveTo(t,L),a.lineTo(R+At,L+.25*Ft),a.lineTo(t,e),a.lineTo(R,L+.25*Ft),a.closePath(),a.fill(),a.globalAlpha=.72*N,a.beginPath(),a.moveTo(R,L+.25*Ft),a.lineTo(t,e),a.lineTo(t,L+Ft),a.lineTo(R,L+.75*Ft),a.closePath(),a.fill(),a.globalAlpha=.42*N,a.beginPath(),a.moveTo(t,e),a.lineTo(R+At,L+.25*Ft),a.lineTo(R+At,L+.75*Ft),a.lineTo(t,L+Ft),a.closePath(),a.fill()}else{const t="pixel"===I.style?0:Math.max(.5,.06*At);a.fillRect(R,L,At-t,Ft-t),"lego"===I.style&&a.drawImage(M.canvas,R,L),"disco"===I.style&&(a.fillStyle=`rgba(255,255,255,${.1+.25*lt(l,h)})`,a.fillRect(R,L,At-t,.35*Ft),a.fillStyle="rgba(0,0,0,.25)",a.fillRect(R,L+.65*Ft,At-t,.35*Ft-t))}}}h.ctx.globalAlpha=1,(I.color.amount||I.lights.length)&&(Nt(p.canvas,bt,wt),p.ctx.clearRect(0,0,bt,wt),p.ctx.drawImage(h.canvas,0,0)),I.color.amount&&(h.ctx.save(),h.ctx.globalCompositeOperation=I.color.blend,h.ctx.globalAlpha=I.color.amount,h.ctx.fillStyle=I.color.tint,h.ctx.fillRect(0,0,bt,wt),h.ctx.restore());for(const t of I.lights){const e=t.radius*Math.max(bt,wt),i=h.ctx.createRadialGradient(t.x*bt,t.y*wt,0,t.x*bt,t.y*wt,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,bt,wt),h.ctx.restore()}(I.color.amount||I.lights.length)&&(h.ctx.globalCompositeOperation="destination-in",h.ctx.drawImage(p.canvas,0,0),h.ctx.globalCompositeOperation="source-over"),I.mask.enabled&&I.mask.shapes.length&&(Yt(c.ctx,bt,wt,I.mask.shapes),h.ctx.globalCompositeOperation=I.mask.invert?"destination-out":"destination-in",h.ctx.drawImage(c.canvas,0,0),h.ctx.globalCompositeOperation="source-over");const a=l.ctx;a.clearRect(0,0,bt,wt),a.globalAlpha=I.backdrop.opacity;const r=I.backdrop;if("solid"===r.mode&&(a.fillStyle=r.color,a.fillRect(0,0,bt,wt)),"gradient"===r.mode){const t=a.createLinearGradient(0,0,bt,wt);t.addColorStop(0,r.color),t.addColorStop(1,r.color2),a.fillStyle=t,a.fillRect(0,0,bt,wt)}if("source"===r.mode&&a.drawImage(o.canvas,0,0),"blurred"===r.mode){const t=Math.max(1,r.blur);Nt(m.canvas,Math.max(2,Math.round(bt/t)),Math.max(2,Math.round(wt/t))),m.ctx.drawImage(o.canvas,0,0,m.canvas.width,m.canvas.height),a.imageSmoothingEnabled=!0,a.drawImage(m.canvas,0,0,bt,wt)}a.globalAlpha=1,I.effects.characterBloom>0&&(Nt(g.canvas,Math.max(2,Math.round(bt/3)),Math.max(2,Math.round(wt/3))),g.ctx.clearRect(0,0,g.canvas.width,g.canvas.height),g.ctx.drawImage(h.canvas,0,0,g.canvas.width,g.canvas.height),a.save(),a.globalAlpha=.8*I.effects.characterBloom,a.globalCompositeOperation="screen",a.filter=`blur(${1+4*I.effects.characterBloom}px)`,a.drawImage(g.canvas,0,0,bt,wt),a.restore());const v=Q.spotlight;if(v&&v[2]>.002){Nt($.canvas,bt,wt);const t=$.ctx,e=v[3]*Math.min(bt,wt)*1.6;t.globalCompositeOperation="source-over",t.clearRect(0,0,bt,wt),t.drawImage(o.canvas,0,0),t.globalCompositeOperation="destination-in";const i=t.createRadialGradient(v[0]*bt,v[1]*wt,0,v[0]*bt,v[1]*wt,e),s=Math.min(1,v[2]*I.hover.strength/.55);for(const t of[0,.2,.4,.6,.8,1])i.addColorStop(t,`rgba(0,0,0,${s*Math.exp(-2.4*(1.6*t)**2)*(1-t)})`);t.fillStyle=i,t.fillRect(0,0,bt,wt),J&&"all"!==(I.hover.scope??"all")&&(t.imageSmoothingEnabled=!0,t.drawImage(_.canvas,0,0,bt,wt)),t.globalCompositeOperation="source-over",a.drawImage($.canvas,0,0)}a.drawImage(h.canvas,0,0),O=qt?Bt:""}const Ht=Object.entries(I.effects).some(([t,e])=>!["angle","focus","blurType","characterBloom"].includes(t)&&"number"==typeof e&&e>0);s.clearRect(0,0,bt,wt),Ht?(void 0===v&&(v=function(){const t=document.createElement("canvas"),e=t.getContext("webgl",{alpha:!0,premultipliedAlpha:!1,antialias:!1,preserveDrawingBuffer:!0});if(!e)return null;const i=[],s=(t,s)=>{const a=e.createShader(t);if(i.push(a),e.shaderSource(a,s),e.compileShader(a),!e.getShaderParameter(a,e.COMPILE_STATUS))throw new Error(e.getShaderInfoLog(a)||"Finish shader failed");return a},a=e.createProgram();if(e.attachShader(a,s(e.VERTEX_SHADER,"attribute vec2 p;varying vec2 uv;void main(){uv=(p+1.)*.5;gl_Position=vec4(p,0.,1.);}")),e.attachShader(a,s(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(a),!e.getProgramParameter(a,e.LINK_STATUS))throw new Error("Finish link failed");e.useProgram(a);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(a,"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(a,t)])),c=e.getUniformLocation(a,"size");return{canvas:t,render(i,s,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(a),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(s.blurType):"angle"===t?s.angle*Math.PI/180:s[t]??0);return e.drawArrays(e.TRIANGLE_STRIP,0,4),t},destroy(){e.deleteTexture(n),e.deleteBuffer(r),e.deleteProgram(a),i.forEach(t=>e.deleteShader(t)),t.width=t.height=1,e.getExtension("WEBGL_lose_context")?.loseContext()}}}()),v?s.drawImage(v.render(l.canvas,I.effects,i,vt),0,0):s.drawImage(l.canvas,0,0),t.dataset.studioFinish=v?"gpu":"unavailable"):(s.drawImage(l.canvas,0,0),t.dataset.studioFinish="none")},setPixelRatio(t){vt=Math.max(.1,Math.min(8,Number.isFinite(t)?t:1))},get pixelRatio(){return vt},setBudget(t){xt=Math.max(256,Math.min(Mt,Number.isFinite(t)?Math.round(t):Mt))},get maxCells(){return xt},configure(t){I=j(t),nt=H(I.color),mt=et(I.print),ft.configure(I.color.denoise),pt.configure(I.warps,I.warpEdge),C++},pointer:(t,e,i)=>{Q.configure(I.hover.effect,I.hover.strength,I.hover.radius,I.hover.edgeSafe,I.hover.decay),Q.move(t,e,i)},leave(){Q.leave()},get active(){return Q.active},get settings(){return j(I)},get capabilities(){return{gpuFinish:null!==v}},invalidate(){R=""},destroy(){v?.destroy(),pt.clear(),ft.configure(0);for(const t of[o,n,h,l,c,m,f,p,g,M,Z,_,$])t.canvas.width=t.canvas.height=1;W=null,D=new Uint8ClampedArray(0),U=new Uint8ClampedArray(0)}}}function Bt(t,e,i){return new Promise((s,a)=>{const r=()=>{l(),s()},o=()=>{l(),a(new Error("Unable to load this media. Check its format and cross-origin permissions."))},n=()=>{l(),a(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 Wt(t,e){if("string"==typeof t&&t.startsWith("blob:")){const i=await fetch(t,{signal:e}),s=await i.blob();return Wt(new File([s],"Imported media",{type:s.type}),e)}const i="string"!=typeof t,s=i?t.name:t;if(i?"image/gif"===t.type:/\.gif(?:[?#]|$)/i.test(s)){const s=await import("gifuct-js"),{parseGIF:a,decompressFrames:r}="function"==typeof s.parseGIF?s:s.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=a(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 u=document.createElement("canvas");u.width=h,u.height=l;const m=u.getContext("2d"),f=document.createElement("canvas"),p=f.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,s=0;for(;s<d.length-1&&(i+=Math.max(20,d[s].delay),!(e<i));s++);s<M&&(m.clearRect(0,0,h,l),M=-1,x=null);for(let t=M+1;t<=s;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,f.width=i.dims.width,f.height=i.dims.height,p.putImageData(new ImageData(new Uint8ClampedArray(i.patch),f.width,f.height),0,0),m.drawImage(f,i.dims.left,i.dims.top)}return M=s,u};return v(0),{source:u,width:h,height:l,duration:g,animated:!0,seek:async()=>{},frame:v,destroy(){u.width=f.width=1,d.length=0,x=null}}}const a=i?t.type.startsWith("video/"):/\.(mp4|webm|mov)(?:[?#]|$)/i.test(s),r=i?URL.createObjectURL(t):t,o=a?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=Bt(o,a?"loadeddata":"load",e);o.src=r,await t;const i=o instanceof HTMLVideoElement?o.videoWidth:o.naturalWidth,s=o instanceof HTMLVideoElement?o.videoHeight:o.naturalHeight;return{source:o,width:i,height:s,duration:o instanceof HTMLVideoElement?o.duration:0,animated:a,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 s=Bt(o,"seeked",e);o.currentTime=i,await s},frame:()=>o,destroy:n}}catch(t){throw n(),t}}var Gt=t=>{if(t?.aborted)throw new DOMException("Export cancelled","AbortError")};async function Ht(t,e){const{format:i,signal:s}=e,a=Math.round(e.width),r=Math.round(e.height);if(!Number.isFinite(a)||!Number.isFinite(r)||a<2||r<2||a>4096||r>4096||a*r>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&&a*r>8294400)throw new Error("Video exports support up to 3840 × 2160 pixels.");if("gif"===i&&(a*r>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(Gt(s),e.onProgress?.(0),h){if(await t(c,l,a,r,s,e.motionTime),"unavailable"===c.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");Gt(s);const o=await new Promise((t,s)=>c.toBlob(e=>e?t(e):s(new Error("Image export failed.")),"png"===i?"image/png":"image/jpeg",e.quality??.92));return Gt(s),e.onProgress?.(1),o}const u=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,m=h(),f=c.getContext("2d");for(let i=0;i<u;i++){Gt(s);const h=i/o;if(await t(c,h,a,r,s),Gt(s),"unavailable"===c.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");const p=f.getImageData(0,0,a,r).data,g=l(p,256),M=d(p,g);m.writeFrame(M,a,r,{palette:g,delay:10*(Math.round(100*Math.min((i+1)/o,n))-Math.round(100*i/o)),repeat:0}),e.onProgress?.((i+1)/u*.98),await new Promise(t=>setTimeout(t,0))}return Gt(s),m.finish(),e.onProgress?.(1),new Blob([new Uint8Array(m.bytes())],{type:"image/gif"})}const{Output:m,Mp4OutputFormat:f,WebMOutputFormat:p,BufferTarget:g,CanvasSource:M,canEncodeVideo:x}=await import("mediabunny"),v="mp4"===i?"avc":"vp9";if(!await x(v,{width:a,height:r}))throw new Error(`${i.toUpperCase()} encoding is unavailable in this browser. Try another format or a current browser with WebCodecs.`);const b=new m({format:"mp4"===i?new f({fastStart:"in-memory"}):new p,target:new g});c.width=a,c.height=r,d=()=>b.cancel();const w=new M(c,{codec:v,bitrate:Math.max(5e5,Math.round(a*r*o*.15))});b.addVideoTrack(w,{frameRate:o}),c.width=a,c.height=r,await b.start();for(let i=0;i<u;i++){Gt(s);const h=i/o;if(await t(c,h,a,r,s),Gt(s),"unavailable"===c.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");await w.add(h,Math.min(1/o,n-h)),e.onProgress?.((i+1)/u*.98),i%4==0&&await new Promise(t=>setTimeout(t,0))}return w.close(),Gt(s),await b.finalize(),Gt(s),d=void 0,e.onProgress?.(1),new Blob([b.target.buffer],{type:"mp4"===i?"video/mp4":"video/webm"})}catch(t){throw await(d?.().catch(()=>{})),t}finally{c.width=c.height=1}}function Vt(t,e,i={}){let s=j(i.settings),a=i.width??e.width,r=i.height??e.height;const o=qt(t,s,i),n=new c;let h=0,l=!1,d=!0,u=!1,m=!0,f=0,p=0,g=0,M=0,x=-1,v=!1!==i.adaptive,b=0,w=0,y=0,S=0,k=o.maxCells;const E=matchMedia("(prefers-reduced-motion: reduce)"),A=e.source instanceof HTMLVideoElement?e.source:null,F=()=>{l||h||!m||document.hidden||(h=requestAnimationFrame(I))},P=()=>!u&&!E.matches&&m&&!document.hidden,T=()=>{A&&(A.loop=!0,P()?A.play().catch(()=>{u=!0,d=!0,F()}):A.pause()),g=0,d=!0,F()};function I(t){if(h=0,l||!m||document.hidden)return;const c=P();c&&(f+=g?Math.min(.1,(t-g)/1e3):0),g=t;const E=rt(s),T=c&&(e.animated||E),I=A?.getVideoPlaybackQuality?.().totalVideoFrames??-1,C=!A||I<0||I!==x;if(d||o.active||T&&(C||E)&&t-M>=1e3/Math.max(1,Math.min(60,i.fps??60))-.5){const h=performance.now();try{e.animated&&!A&&o.invalidate();const[t,l]=Y(a,r,s);p=n.update(f,s.motion.type,s.motion.speed),o.render(e.frame(A?.currentTime??f),f,t,l,p);const c=performance.now()-h;if(i.onFrame?.(A?.currentTime??f,c),w=w?.9*w+.1*c:c,++b>20&&v&&(T||o.active)){const t=1e3/Math.max(1,Math.min(60,i.fps??60));y=w>1.1*t?y+1:0,S=w<.5*t?S+1:0,y>=20&&o.maxCells>3e3?(o.setBudget(Math.max(3e3,.8*o.maxCells)),i.onQualityChange?.(o.maxCells),y=0,w=0):S>=30&&o.maxCells<k&&(o.setBudget(Math.min(k,1.25*o.maxCells)),i.onQualityChange?.(o.maxCells),S=0,w=0)}}catch(t){u=!0,i.onError?.(t instanceof Error?t:new Error(String(t)))}d=!1,M=t,x=I}c&&(T||o.active)?F():T||o.active||o.maxCells>=k||(o.setBudget(k),i.onQualityChange?.(o.maxCells),y=S=w=b=0,0)||(d=!0,F())}const C=e=>{if(!P())return;const i=t.getBoundingClientRect();o.pointer((e.clientX-i.left)/i.width,(e.clientY-i.top)/i.height,e.timeStamp),F()},R=()=>{o.leave(),F()},L=t=>{"touch"===t.pointerType&&R()},N=new IntersectionObserver(([t])=>{m=t.isIntersecting,T()});N.observe(t),t.addEventListener("pointermove",C),t.addEventListener("pointerup",L),t.addEventListener("pointerleave",R),t.addEventListener("pointercancel",R),document.addEventListener("visibilitychange",T),E.addEventListener("change",T);const O=()=>{l||(l=!0,cancelAnimationFrame(h),N.disconnect(),t.removeEventListener("pointermove",C),t.removeEventListener("pointerup",L),t.removeEventListener("pointerleave",R),t.removeEventListener("pointercancel",R),document.removeEventListener("visibilitychange",T),E.removeEventListener("change",T),i.signal?.removeEventListener("abort",O),o.destroy(),e.destroy())};if(i.signal?.addEventListener("abort",O,{once:!0}),i.signal?.aborted)throw O(),new DOMException("Cancelled","AbortError");return T(),{canvas:t,media:e,update(t){s=q(s,t),o.configure(s),d=!0,F()},resize(t,e,i){void 0!==i&&o.setPixelRatio(i),a=Math.max(2,t),r=Math.max(2,e),d=!0,F()},pause(t=!0){u=t,T()},async seek(t){f=Math.max(0,t),await e.seek(f),o.invalidate(),d=!0,F()},redraw(){o.invalidate(),d=!0,F()},get time(){return A?.currentTime??f},get settings(){return j(s)},get motionTime(){return p},get paused(){return u||E.matches},setAdaptive(t){v=t,b=y=w=0},setBudget(t){o.setBudget(t),k=o.maxCells,y=S=w=b=0,i.onQualityChange?.(o.maxCells),d=!0,F()},get pixelRatio(){return o.pixelRatio},get maxCells(){return o.maxCells},get capabilities(){return o.capabilities},destroy:O}}var Qt={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")},Jt=Object.keys(Qt);async function Kt(t,e="Standard",i="#ffffff",s="#080808"){if(!Object.prototype.hasOwnProperty.call(Qt,e))throw new Error("Unknown text font.");const{default:a}=await import("figlet/browser"),r=await Qt[e]();a.parseFont(e,r.default),a.defaults({fetchFontIfMissing:!1});const o=a.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 u=d.getContext("2d");return null!==s&&(u.fillStyle=s,u.fillRect(0,0,d.width,d.height)),u.fillStyle=i,u.font=15*c+"px monospace",u.textBaseline="top",n.forEach((t,e)=>u.fillText(t,16,16+15*e*c)),{canvas:d,ascii:o}}var Zt={standard:{label:"Classic ASCII",chars:" .:-=+*#%@"},asciify:{label:"Asciify",chars:" .:-=+YCIFSA#@"},minimal:{label:"Minimal",chars:" .:+"},detailed:{label:"Detailed",chars:" .,:;-~=+*xX#%@"},letters:{label:"Letters",chars:" .liLTYCFSAWM"},technical:{label:"Technical",chars:" ._:;+/>=][{}*$#@"},blocks:{label:"Tonal blocks",chars:" ░▒▓█"},braille:{label:"Braille",chars:" ⠁⠃⠇⡇⣇⣧⣷⣿"}},_t=Zt,$t=t=>t&&"object"==typeof t&&!Array.isArray(t)?t:{},te=(t,e,i,s)=>"number"==typeof t&&Number.isFinite(t)?Math.max(i,Math.min(s,t)):e,ee=(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 ie(t={}){const e=$t(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 s=new Set;return{kind:"asciify-project",version:1,width:Math.round(te(e.width,1280,2,4096)),height:Math.round(te(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=$t(t),a=$t(i.placement),r=$t(i.settings),o=$t(r.backdrop),n=ee(i.id,"Layer id"),h=ee(i.source,"Source key");if(s.has(n))throw new Error(`Duplicate layer id: ${n}`);return s.add(n),{id:n,source:h,name:"string"==typeof i.name?i.name.slice(0,80):`Layer ${e+1}`,visible:!1!==i.visible,opacity:te(i.opacity,1,0,1),blend:R.includes(i.blend)?i.blend:"source-over",placement:{x:te(a.x,.5,-1,2),y:te(a.y,.5,-1,2),width:te(a.width,1,.01,2),height:te(a.height,1,.01,2),rotation:te(a.rotation,0,-180,180),flipX:!0===a.flipX,flipY:!0===a.flipY},settings:j({...r,backdrop:{mode:"transparent",...o}})}})}}function se(t,e,i){if(!t.layers.some(t=>t.id===e))throw new Error(`Unknown layer: ${e}`);return ie({...t,layers:t.layers.map(t=>t.id!==e?t:{...t,...i,id:e,placement:{...t.placement,...i.placement},settings:q(t.settings,i.settings??{})})})}function ae(t,e,i,s,a){const r=t.placement,o=r.rotation*Math.PI/180,n=Math.cos(o),h=Math.sin(o),l=(e-r.x)*s,c=(i-r.y)*a,d=(l*n+c*h)/(r.width*s),u=(-l*h+c*n)/(r.height*a);return[.5+d*(r.flipX?-1:1),.5+u*(r.flipY?-1:1)]}function re(t){return t.layers.filter(e=>{if(!e.visible||e.opacity<=0)return!1;const i=e.placement,s=i.rotation*Math.PI/180,a=Math.abs(Math.cos(s)),r=Math.abs(Math.sin(s)),o=(a*i.width*t.width+r*i.height*t.height)/2,n=(r*i.width*t.width+a*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 oe(t,e=24e3,i=4194304,s=t.width,a=t.height){const r=re(t),o=Math.round(te(e,24e3,2048,1048576)),n=te(i,4194304,65536,16777216),h=r.map(t=>t.placement.width*t.placement.height),l=h.reduce((t,e)=>t+e,0),c=o-256*r.length,d=r.map(t=>{const e=s*t.placement.width,i=a*t.placement.height,r=Math.min(1,4096/Math.max(e,i));return{width:Math.max(2,e*r),height:Math.max(2,i*r)}}),u=d.reduce((t,e)=>t+e.width*e.height,0);let m=0,f=0;return r.map((t,e)=>{const i=e===r.length-1?o-m:256+Math.floor(c*h[e]/l);m+=i;const s=d[e],a=e===r.length-1?n-f:4+Math.floor((n-4*r.length)*s.width*s.height/Math.max(1,u));f+=a;const p=Math.min(1,Math.sqrt(a/(s.width*s.height)));let g=Math.max(2,Math.floor(s.width*p)),M=Math.max(2,Math.floor(s.height*p));return g*M>a&&(g>=M?g=Math.max(2,Math.floor(a/M)):M=Math.max(2,Math.floor(a/g))),{id:t.id,maxCells:i,width:g,height:M}})}function ne(t,e={},i={}){const s=t.getContext("2d");if(!s)throw new Error("Project canvas is already owned by another renderer.");let a=ie(e),r=!0,o=!1,n=new Map(a.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)),u=[];const m=new Map,f=()=>{if(o)throw new Error("Project renderer has been destroyed.")};return{canvas:t,render(e,o=0,p=a.width,g=a.height,M={}){if(f(),!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)),v=Math.max(2,Math.round(p*x)),b=Math.max(2,Math.round(g*x));t.width===v&&t.height===b||(t.width=v,t.height=b,r=!0);const w={...a,width:v,height:b},y=re(w);for(const t of y)if(!e.has(t.source))throw new Error(`Missing project source: ${t.source}`);const S=new Set(y.map(t=>t.id));for(const[t,e]of m)S.has(t)||(e.renderer.destroy(),m.delete(t),r=!0);u=oe(w,c,i.maxRasterPixels,v,b);for(let t=0;t<y.length;t++){const i=y[t],s=u[t],a=e.get(i.source);if(!a)throw new Error(`Missing project source: ${i.source}`);let h=m.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:qt(document.createElement("canvas"),i.settings,{maxDimension:4096,maxCells:l}),signature:c,dirty:!0,geometry:""},m.set(i.id,h));const f=d*s.width/(p*i.placement.width),g=`${s.width}:${s.height}:${s.maxCells}:${f}`;h.geometry!==g&&(h.renderer.setBudget(s.maxCells),h.renderer.setPixelRatio(f),h.geometry=g,h.dirty=!0);const x="currentTime"in a?a.getVideoPlaybackQuality?.().totalVideoFrames??a.currentTime:0;if(h.dirty||h.source!==a||h.stamp!==x||h.renderer.active||rt(i.settings)){const t=Object.prototype.hasOwnProperty.call(M,i.id)?M[i.id]:void 0;h.renderer.render(a,o,s.width,s.height,t),h.dirty=!1,h.source=a,h.stamp=x,r=!0}}if(!r)return!1;s.clearRect(0,0,v,b),s.globalCompositeOperation="source-over",s.globalAlpha=1,null!==a.background&&(s.fillStyle=a.background,s.fillRect(0,0,v,b));let k="none";for(const t of y){const e=m.get(t.id),i=t.placement;s.save(),s.globalAlpha=t.opacity,s.globalCompositeOperation=t.blend;try{s.translate(i.x*v,i.y*b),s.rotate(i.rotation*Math.PI/180),s.scale(i.flipX?-1:1,i.flipY?-1:1),s.drawImage(e.renderer.canvas,-i.width*v/2,-i.height*b/2,i.width*v,i.height*b)}finally{s.restore()}"unavailable"===e.renderer.canvas.dataset.studioFinish?k="unavailable":"unavailable"!==k&&"gpu"===e.renderer.canvas.dataset.studioFinish&&(k="gpu")}return s.globalAlpha=1,s.globalCompositeOperation="source-over",t.dataset.studioFinish=k,r=!1,!0},configure(t){f(),a=ie(t),n=new Map(a.layers.map(t=>[t.id,JSON.stringify(t.settings)])),(()=>{const t=new Set(re(a).map(t=>t.id));for(const[e,i]of m)t.has(e)||(i.renderer.destroy(),m.delete(e))})(),r=!0},pointer(e,i,s){if(o||!Number.isFinite(e)||!Number.isFinite(i))return;if(e<0||e>1||i<0||i>1){for(const t of m.values())t.renderer.leave();return}let r=!1;for(const o of re({...a,width:t.width,height:t.height}).reverse()){const n=m.get(o.id);if(!n)continue;const[h,l]=ae(o,e,i,t.width,t.height);(!r||"all"===a.pointerMode)&&h>=0&&h<=1&&l>=0&&l<=1&&"none"!==o.settings.hover.effect&&o.settings.hover.strength>0?(n.renderer.pointer(h,l,s),r=!0):n.renderer.leave()}},leave(){for(const t of m.values())t.renderer.leave()},invalidate(t){f();for(const e of a.layers)if(void 0===t||t===e.source){const t=m.get(e.id);t&&(t.renderer.invalidate(),t.dirty=!0)}r=!0},setBudget(t){f(),c=Math.max(2048,Math.min(l,Number.isFinite(t)?Math.round(t):l)),r=!0},setPixelRatio(t){f(),d=Math.max(.1,Math.min(8,Number.isFinite(t)?t:1)),r=!0},get maxCells(){return c},get pixelRatio(){return d},get quality(){return u.map(t=>({...t}))},get active(){return[...m.values()].some(t=>t.renderer.active)},destroy(){if(!o){o=!0;for(const t of m.values())t.renderer.destroy();m.clear(),t.width=t.height=1}}}}function he(t,e){for(const i of t.layers)if(!e.has(i.source))throw new Error(`Missing project source: ${i.source}`)}async function le(t,e,i){const s=Object.entries(e),a=new Map;if(s.length>8)throw new Error("A project supports up to 8 media bindings.");he(t,new Map(s));try{for(const[t,e]of s){if(i?.aborted)throw new DOMException("Cancelled","AbortError");if("string"==typeof e||"undefined"!=typeof File&&e instanceof File)a.set(t,await Wt(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:s}=await Kt(i.text,i.font,i.ink??"#ffffff",null);a.set(t,{source:s,width:s.width,height:s.height,duration:0,animated:!1,frame:()=>s,seek:async()=>{},destroy:()=>{s.width=s.height=1}})}}}if(i?.aborted)throw new DOMException("Cancelled","AbortError");return a}catch(t){for(const t of a.values())t.destroy();throw t}}function ce(t,e,i,s={}){if((i=new Map(i)).size>8)throw new Error("A project supports up to 8 media bindings.");let a=ie(e);if(he(a,i),s.signal?.aborted)throw new DOMException("Cancelled","AbortError");const r=ne(t,a,s),o=matchMedia("(prefers-reduced-motion: reduce)"),n=[...new Set(i.values())],h=n.filter(t=>t.source instanceof HTMLVideoElement).map(t=>t.source),l=new Map;let d,u={},m=0,f=0,p=0,g=0,M=!0,x=!1,v=!0,b=!1,w=!1!==s.adaptive,y=0,S=0,k=0,E=0,A=a.width,F=a.height,P=0,T=!1,I=r.maxCells;const C=new WeakSet,R=Math.max(1,Math.min(60,Number.isFinite(s.fps)?s.fps:60)),L=()=>!b&&!x&&!T&&!o.matches&&v&&!document.hidden,N=()=>{b||g||!v||document.hidden||(g=requestAnimationFrame(X))},O=()=>new Set(re({...a,width:A,height:F}).map(t=>i.get(t.source).source)),D=()=>{const t=O();for(const e of h)e.loop=!0,L()&&t.has(e)?e.paused&&!C.has(e)&&(C.add(e),e.play().then(()=>{C.delete(e),L()&&O().has(e)||e.pause()}).catch(t=>{C.delete(e),b||(x=!0,D(),s.onError?.(t instanceof Error?t:new Error(String(t))),M=!0,N())})):e.pause()},U=()=>{f=0,M=!0,D(),N()};function X(t){if(g=0,b||!v||document.hidden)return;const e=L();e&&(m+=f?Math.min(.1,(t-f)/1e3):0),f=t;const o=re({...a,width:A,height:F}),n=o.some(t=>i.get(t.source).animated||rt(t.settings));if(M||e&&r.active||e&&n&&t-p>=1e3/R-.5){const a=performance.now();try{const t=new Map,h=new Set(o.map(t=>t.source));for(const s of h){const a=i.get(s);!a.animated||a.source instanceof HTMLVideoElement||!e||r.invalidate(s),t.set(s,a.frame(m))}u={};for(const t of o){let e=l.get(t.id);e||(e=new c,l.set(t.id,e)),u[t.id]=e.update(m,t.settings.motion.type,t.settings.motion.speed)}r.render(t,m,A,F,u);const d=performance.now()-a;if(s.onFrame?.(m,d),S=S?.9*S+.1*d:d,++y>20&&w&&e&&(n||r.active)){const t=1e3/R;k=S>1.1*t?k+1:0,E=S<.5*t?E+1:0,k>=20&&r.maxCells>2048?(r.setBudget(Math.max(2048,.8*r.maxCells)),s.onQualityChange?.(r.maxCells),S=k=0,M=!0):E>=30&&r.maxCells<I&&(r.setBudget(Math.min(I,1.25*r.maxCells)),s.onQualityChange?.(r.maxCells),S=E=0,M=!0)}}catch(t){x=!0,D(),s.onError?.(t instanceof Error?t:new Error(String(t)))}M=!1,p=t}e&&(n||r.active)?N():!n&&!r.active&&r.maxCells<I&&(r.setBudget(I),s.onQualityChange?.(r.maxCells),y=k=E=S=0,M=!0,N())}const j=e=>{if(!L())return;const i=t.getBoundingClientRect();i.width&&i.height&&(r.pointer((e.clientX-i.left)/i.width,(e.clientY-i.top)/i.height,e.timeStamp),N())},z=()=>{r.leave(),N()},Y=new IntersectionObserver(([t])=>{v=t.isIntersecting,U()});Y.observe(t),t.addEventListener("pointermove",j),t.addEventListener("pointerleave",z),t.addEventListener("pointercancel",z),document.addEventListener("visibilitychange",U),o.addEventListener("change",U);const q=()=>{if(!b){b=!0,P++,d?.abort(),cancelAnimationFrame(g),g=0,Y.disconnect(),t.removeEventListener("pointermove",j),t.removeEventListener("pointerleave",z),t.removeEventListener("pointercancel",z),document.removeEventListener("visibilitychange",U),o.removeEventListener("change",U),s.signal?.removeEventListener("abort",q),r.destroy();for(const t of n)t.destroy();l.clear()}};s.signal?.addEventListener("abort",q,{once:!0});const B=()=>{if(b)throw new Error("Project player has been destroyed.")},W=t=>{B();const e=ie(t);he(e,i),A===a.width&&F===a.height&&(A=e.width,F=e.height),a=e,r.configure(a);for(const t of l.keys())a.layers.some(e=>e.id===t)||l.delete(t);U()};return U(),{canvas:t,get project(){return ie(a)},get time(){return m},get motionTimes(){return{...u}},get paused(){return x||o.matches},get maxCells(){return r.maxCells},get pixelRatio(){return r.pixelRatio},get quality(){return r.quality},update:W,updateLayer:(t,e)=>W(se(a,t,e)),resize(t,e,i){if(B(),!Number.isFinite(t)||!Number.isFinite(e)||t<2||e<2)throw new Error("Project dimensions must be positive finite numbers.");A=t,F=e,void 0!==i&&r.setPixelRatio(i),U()},pause(t=!0){B(),x=t,U()},async seek(t){if(B(),!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,D();try{if(await Promise.all(n.map(e=>e.seek(t,i))),b||e!==P)return;m=t,l.clear(),r.invalidate()}finally{b||e!==P||(T=!1,U())}},redraw(){B(),r.invalidate(),M=!0,N()},setBudget(t){B(),r.setBudget(t),I=r.maxCells,y=k=E=S=0,s.onQualityChange?.(r.maxCells),M=!0,N()},setAdaptive(t){w=t,y=k=E=S=0},destroy:q}}exports.BLEND_MODES=R,exports.CHARACTER_SETS=Zt,exports.DEFAULT_STUDIO_PRINT=P,exports.DEFAULT_STUDIO_SETTINGS=N,exports.DEPRECATED_STUDIO_HOVERS=e,exports.DITHER_ALGORITHMS=C,exports.HOVER_SCOPES=[{value:"all",label:"Everywhere",description:"The hover acts on the whole artwork."},{value:"subject",label:"Subject",description:"The hover stays on the subject and fades softly at its edge."},{value:"outside",label:"Around",description:"The hover acts only on the ground around the subject."}],exports.MAX_STUDIO_LAYERS=8,exports.MAX_STUDIO_WARPS=8,exports.STUDIO_ANIMATION_PRESETS=[{id:"quiet-light",label:"Quiet light",description:"Stationary detail with slowly turning light and a soft magnifying wake.",motion:{type:"relight",speed:.6,amount:.7},hover:{effect:"lens",radius:.45,strength:.5}},{id:"living-paper",label:"Living paper",description:"A gentle traveling bend and a directional pull under your cursor.",motion:{type:"breeze",speed:.8,amount:.6},hover:{effect:"smudge",radius:.4,strength:.5}},{id:"silver-grain",label:"Silver grain",description:"Slow highlight glints with a fluid character trail.",motion:{type:"shimmer",speed:.75,amount:.85},hover:{effect:"trail",radius:.35,strength:.55}},{id:"ripple-study",label:"Ripple study",description:"Soft moving light and expanding tonal rings on an anchored grid.",motion:{type:"caustics",speed:.6,amount:.55},hover:{effect:"ripple",radius:.45,strength:.75}},{id:"unfolding-print",label:"Unfolding print",description:"Panels turn and reassemble; your cursor dissolves a soft path.",motion:{type:"unfold",speed:.7,amount:.75},hover:{effect:"dissolve",radius:.35,strength:.55}},{id:"silk-flow",label:"Silk flow",description:"A slow current with directional folds that follow your hand.",motion:{type:"current",speed:.6,amount:.55},hover:{effect:"silk",radius:.4,strength:.5}}],exports.STUDIO_CHARACTER_SETS=_t,exports.STUDIO_CURVE_CHANNELS=m,exports.STUDIO_HOVERS=t,exports.STUDIO_LOOKS=W,exports.STUDIO_MOTIONS=o,exports.STUDIO_PALETTES=L,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=A,exports.STUDIO_STYLES=I,exports.STUDIO_TEXT_FONTS=Jt,exports.STUDIO_WARPS=b,exports.createStudioCurveLookup=M,exports.createStudioProjectRenderer=ne,exports.createStudioRenderer=qt,exports.createStudioText=Kt,exports.exportStudio=async function(t,e,i){let s;const a=j(e),r="png"!==i.format&&"jpeg"!==i.format;try{return await Ht(async(e,o,n,h,l,c)=>{s??(s=qt(e,a,{maxDimension:4096,maxCells:i.maxCells??12e3,pixelRatio:n/(i.referenceWidth??Math.min(n,960))})),r&&s.invalidate(),s.render(await t.frame(o,l),o,n,h,c)},i)}finally{s?.destroy()}},exports.exportStudioProject=async function(t,e,i){const s=ie(t),a={...i.motionTimes};if(Object.values(a).some(t=>!Number.isFinite(t)||t<0))throw new Error("Layer motion times must be finite non-negative numbers.");const r=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 Ht(async(t,e,h,l,d)=>{n??(n=await le(s,r,d)),o??(o=ne(t,s,{maxDimension:4096,maxCells:i.maxCells??24e3,maxRasterPixels:i.maxRasterPixels,pixelRatio:h/(i.referenceWidth??Math.min(h,960))}));const u=new Set(re({...s,width:h,height:l}).map(t=>t.source)),m=new Map;await Promise.all([...u].map(async t=>{const i=n.get(t);await i.seek(e,d),m.set(t,i.frame(e)),i.animated&&o.invalidate(t)})),o.render(m,e,h,l,c?a:{})},{...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.inkIndexLookup=zt,exports.isStudioPrintStyle=F,exports.loadStudioMedia=Wt,exports.mountStudio=async function(t,e,i={}){const s=await Wt(e,i.signal);try{return Vt(t,s,i)}catch(t){throw s.destroy(),t}},exports.mountStudioMedia=Vt,exports.mountStudioProject=async function(t,e,i,s={}){const a=ie(e),r=await le(a,i,s.signal);try{return ce(t,a,r,s)}catch(t){for(const t of new Set(r.values()))t.destroy();throw t}},exports.mountStudioProjectMedia=ce,exports.normalizeStudioCurve=p,exports.normalizeStudioCurves=g,exports.normalizeStudioPrint=T,exports.normalizeStudioProject=ie,exports.normalizeStudioSettings=j,exports.normalizeStudioWarps=y,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 ie(e)},exports.parseStudioSettings=function(t){if(t.length>1e5)throw new Error("Settings exceed 100 KB.");return j(JSON.parse(t))},exports.restyleStudio=function(t,e=Math.random){const i=W.filter(e=>e.settings.style!==t.style||e.settings.ink!==t.ink),s=G(i[Math.min(i.length-1,Math.max(0,Math.floor(e()*i.length)))].id);return s.aspectRatio=t.aspectRatio,s.crop={...t.crop},s.mask=j(t).mask,s},exports.serializeStudioProject=t=>JSON.stringify(ie(t)),exports.serializeStudioSettings=function(t){return JSON.stringify(j(t))},exports.studioCrop=z,exports.studioDimensions=Y,exports.studioGrid=B,exports.studioLayerPoint=ae,exports.studioLevels=Xt,exports.studioLook=G,exports.studioProjectBudget=oe,exports.studioSourceSize=Rt,exports.studioToneGamma=jt,exports.updateStudioProjectLayer=se,exports.updateStudioSettings=q,exports.visibleStudioLayers=re;//# 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:"ripple",label:"Ripple rings",group:"Change characters",description:"Expanding light-and-shadow rings follow your stroke. Faster movement excites stronger rings; the grid stays still."},{value:"bleed",label:"Ink bleed",group:"Change characters",description:"Ink wells up where the cursor rests, spreads along the paper grain, then dries back."},{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:"Characters scatter in soft drifts from your stroke, then spring back into place."},{value:"elastic",label:"Elastic",group:"Move the image",description:"Push the image with your stroke; it recoils past its rest once, then settles."},{value:"lens",label:"Lens wake",group:"Move the image",description:"A soft magnifying wake brings details closer, then relaxes back into focus."},{value:"smudge",label:"Smudge",group:"Move the image",description:"Drag the image in the direction of your stroke; a smooth, lingering pull settles without a bounce."},{value:"loupe",label:"Loupe",group:"Follow the cursor",description:"A glass loupe glides after the cursor and magnifies what it covers, easing through a soft rim."},{value:"reveal",label:"Reveal",group:"Follow the cursor",description:"A soft spotlight shows the original photograph through the characters."},{value:"repel",label:"Repel",group:"Follow the cursor",description:"Characters part around the cursor and spring back with one soft rebound when it leaves."},{value:"tilt",label:"Tilt",group:"Follow the cursor",description:"The image leans toward the cursor; bright areas sit nearer and move more, like a parallax card."},{value:"haze",label:"Heat haze",group:"Follow the cursor",description:"A rising shimmer bends the characters above the cursor, livelier while you move."}],e={rake:"silk"};function i(i){if("string"==typeof i)return i in e?e[i]:t.some(t=>t.value===i)?i:void 0}var s=t=>"subject"===t||"outside"===t?t:"all";function a(t,e,i,s,a){if(!(a<1))for(let r=0;r<2;r++){for(let r=0;r<s;r++){let s=0;const o=r*i;for(let e=-a;e<=a;e++)s+=t[o+Math.max(0,Math.min(i-1,e))];for(let r=0;r<i;r++)e[o+r]=s/(2*a+1),s+=t[o+Math.min(i-1,r+a+1)]-t[o+Math.max(0,r-a)]}for(let r=0;r<i;r++){let o=0;for(let t=-a;t<=a;t++)o+=e[Math.max(0,Math.min(s-1,t))*i+r];for(let n=0;n<s;n++)t[n*i+r]=o/(2*a+1),o+=e[Math.min(s-1,n+a+1)*i+r]-e[Math.max(0,n-a)*i+r]}}}function r(t,e,i,s,r){const o=e*i,n=r&&r.width===e&&r.height===i?r:{width:e,height:i,subject:new Float32Array(o),depth:new Float32Array(o),key:"none"},{subject:h,depth:l}=n;let c=0;for(let e=0;e<o;e++)t[4*e+3]<250&&c++;const d=e=>(.2126*t[4*e]+.7152*t[4*e+1]+.0722*t[4*e+2])/255;let m="none",u=0;if(c>.01*o)m="alpha";else if(s)m="mask";else{let t=0,s=0,a=0;const r=Math.max(1,Math.round(.03*Math.min(e,i)));for(let o=0;o<i;o++)for(let n=0;n<e;n++){if(n>=r&&o>=r&&n<e-r&&o<i-r)continue;const h=d(o*e+n);t+=h,s+=h*h,a++}u=t/Math.max(1,a);Math.sqrt(Math.max(0,s/Math.max(1,a)-u*u))<.07&&(m="ground")}for(let e=0;e<o;e++){const i=t[4*e+3]/255,a=d(e);let r=1;if("alpha"===m)r=i;else if("ground"===m){const t=Math.max(0,Math.min(1,(Math.abs(a-u)-.035)/.12));r=t*t*(3-2*t)}h[e]=r*(s?Math.max(0,Math.min(1,s[e])):1),l[e]=a*i}n.key=m;const f=new Float32Array(o);return a(h,f,e,i,Math.max(1,Math.round(.02*Math.min(e,i)))),a(l,f,e,i,Math.max(1,Math.round(.035*Math.min(e,i)))),n}function o(t,e,i="ground"){return"none"===i?1:"subject"===t?e:"outside"===t?1-e:1}var n={caustics:"sheen",grain:"shimmer",trace:"relight",tidal:"current",weave:"current",breeze:"current",reform:"develop",print:"develop",unfold:"develop"},h=[{value:"none",mode:"none",group:"Still",label:"Off",description:"Keep the image still. Hover stays available."},{value:"relight",mode:"relight",group:"Light",label:"Relight",description:"A key light circles the subject and models its own relief, like moving a lamp around a sculpture."},{value:"sheen",mode:"sheen",group:"Light",label:"Specular sweep",description:"One slow pass of light glances across the highlights and follows their form, then rests."},{value:"glow",mode:"glow",group:"Light",label:"Highlight bloom",description:"The brightest areas breathe a soft halo into their surroundings. Shadows stay deep."},{value:"shimmer",mode:"shimmer",group:"Light",label:"Glints",description:"Sparse glints on bright fine detail, like light on water, metal or an eye. Everything else holds still."},{value:"parallax",mode:"parallax",group:"Depth",label:"Parallax",description:"A slow camera drift: the subject moves against its background, read from the photo’s own depth cues."},{value:"push",mode:"push",group:"Depth",label:"Slow push",description:"A gentle push toward the subject and back, with nearer areas moving slightly more."},{value:"focus",mode:"focus",group:"Depth",label:"Focus pull",description:"Focus racks from the subject to the background and back; the characters soften out of focus."},{value:"mist",mode:"mist",group:"Atmosphere",label:"Mist",description:"Soft mist drifts through the distance and plain areas, leaving the subject clear."},{value:"current",mode:"current",group:"Atmosphere",label:"Drift",description:"Sky, water and smooth grounds flow slowly, like a cinemagraph; detailed areas hold still."},{value:"develop",mode:"develop",group:"Reveal",label:"Develop",description:"The image holds, fades, then develops back in from its highlights to its shadows, like a print in the tray."}];function l(t){const e=t&&Object.prototype.hasOwnProperty.call(n,t)?n[t]:t;return h.find(t=>t.value===e||t.mode===e)?.mode??"none"}var c=t=>Math.max(0,Math.min(1,t)),d=(t,e,i)=>{const s=c((i-t)/(e-t));return s*s*(3-2*s)},m=(t,e)=>{const i=(.06711056*t+.00583715*e)%1*52.9829189;return i-Math.floor(i)},u=class{constructor(){this.last=null,this.mode="none",this.phase=0}update(t,e,i=1){const s=l(e);return Number.isFinite(t)?((s!==this.mode||null!==this.last&&t<this.last)&&(this.mode=s,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 f(t,e,i,s,a,r=.5,o,n=0){if(a[0]=a[1]=a[2]=0,a[3]=1,"none"===t)return a;r=c(r);const h=o?o[n]:r,l=o?o[n+1]:.5+.5*c(1-2*Math.hypot(e-.5,i-.55)),u=o?o[n+2]:d(.55,1,r)**2,f=o?o[n+3]:.5,p=o?o[n+4]:0,g=o?o[n+5]:0,M=s*Math.PI/6,x=(s%12+12)%12,v=d(0,.12,Math.min(e,1-e,i,1-i));if("relight"===t){const t=M+.6,s=Math.cos(t),o=Math.sin(t),n=Math.max(-1,Math.min(1,p*s+g*o))+.35*(s*(e-.5)+o*(i-.5));a[2]=.2*n*(.3+.7*d(.04,.3,h)*(1-.6*d(.82,1,r)))}else if("sheen"===t){const t=1.9*d(0,8,x)-.35,s=(.75*e+.45*i)/1.2+.05*(.75*p+.45*g),o=Math.exp(-(((s-t)/.12)**2));a[2]=o*d(.3,.8,h)*(1-.5*d(.9,1,r))*.45}else if("glow"===t){const t=.5-.5*Math.cos(M),e=1-.8*t;a[2]=.2*d(e-.3,e+.02,u)*Math.sqrt(u)*(1-.65*r)+.05*t*d(.6,.95,r)}else if("shimmer"===t){const t=m(Math.floor(160*e),Math.floor(100*i))*Math.PI*2,s=Math.pow(.5+.5*Math.cos(2*M+t),28);a[2]=s*d(.5,.88,r)*(.35+.65*d(.1,.55,f))*.42}else if("parallax"===t){const t=l-.45;a[0]=16*t*Math.sin(M)*v,a[1]=7*t*Math.sin(2*M)*v}else if("push"===t){const t=.045*(.5-.5*Math.cos(M))*(.7+.6*l)*960,s=o?o[n+6]:.5,r=o?o[n+7]:.5;a[0]=(e-s)*t,a[1]=(i-r)*t}else if("focus"===t){const t=Math.sin(M),e=t*t*d(.15,.6,t>=0?1-l:l);a[2]=(h-r)*e*.9}else if("mist"===t){const t=Math.pow(1-l,1.5)*(1-.6*f),s=.5*Math.sin(4.1*e-M+.9*Math.sin(3.3*i+M))+.3*Math.sin(7.3*e+2.1*i-2*M+1.1*Math.sin(2.7*e-5.1*i+M))+.2*Math.sin(5.7*i-1.9*e+M);a[2]=d(-.3,.9,s)*t*.16*(1-.55*r)}else if("current"===t){const t=(1-.4*f)*(1-.8*l)*v,s=t=>14*i-t+1.5*Math.sin(3*e+t);a[0]=7*(Math.sin(s(M))-Math.sin(s(0))+.43*(Math.sin(5*e-3*i+M)-Math.sin(5*e-3*i)))*t,a[1]=2*(Math.sin(11*e+M)-Math.sin(11*e))*t,a[2]=.03*(Math.cos(s(M))-Math.cos(s(0)))*t}else if("develop"===t){const t=d(7,8.5,x),s=c((x-8.5)/3.5),o=x<8.5?1-t:d(0,1,(1.45*s-(1-r)+.06*(m(Math.floor(160*e),Math.floor(100*i))-.5))/.3);a[2]=.3*-(1-o),a[3]=1-.9*(1-o)}return a}function p(t,e){const i=Math.max(0,Math.min(2,Number.isFinite(e)?e:1));return t[0]*=i,t[1]*=i,t[2]*=i,t[3]=c(1+(t[3]-1)*i),t}var g=["rgb","red","green","blue"],M=t=>Math.max(0,Math.min(1,t));function x(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*M(i[0]))/255;!e.has(t)&&e.size>=16||e.set(t,M(i[1]))}return[...e].sort((t,e)=>t[0]-e[0])}function v(t){const e=t&&"object"==typeof t?t:{};return Object.fromEntries(g.map(t=>[t,x(e[t])]))}function y(t){const e=x(t),i=e.length,s=e.slice(1).map((t,i)=>t[0]-e[i][0]),a=e.slice(1).map((t,i)=>(t[1]-e[i][1])/s[i]),r=new Float64Array(i);r[0]=a[0],r[i-1]=a[i-2];for(let t=1;t<i-1;t++){const e=a[t-1],i=a[t];if(e*i<=0)continue;const o=2*s[t]+s[t-1],n=s[t]+2*s[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 a=t/255;for(;n<i-2&&a>e[n+1][0];)n++;const h=s[n],l=(a-e[n][0])/h,c=l*l,d=c*l,m=(2*d-3*c+1)*e[n][1]+(d-2*c+l)*h*r[n]+(-2*d+3*c)*e[n+1][1]+(d-c)*h*r[n+1];o[t]=Math.round(255*M(m))}return o}function w(t,e,i,s,a,r){s=Math.max(0,Math.min(e-1,s)),a=Math.max(0,Math.min(i-1,a));const o=Math.floor(s),n=Math.floor(a),h=s-o,l=a-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)),m=4*(Math.min(i-1,n+1)*e+o),u=4*(Math.min(i-1,n+1)*e+Math.min(e-1,o+1)),f=(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[u+3],x=f+p+g+M;for(let e=0;e<3;e++)r[e]=x?(t[c+e]*f+t[d+e]*p+t[m+e]*g+t[u+e]*M)/x:0;r[3]=x}function b(t,e,i,s,a,r){if(s>=0&&s<=e-1&&a>=0&&a<=i-1)return w(t,e,i,s,a,r);if(r[0]=r[1]=r[2]=r[3]=0,s<=-1||s>=e||a<=-1||a>=i)return;const o=Math.floor(s),n=Math.floor(a),h=s-o,l=a-n;for(let s=0;s<=1;s++)for(let a=0;a<=1;a++){const c=o+a,d=n+s;if(c<0||c>=e||d<0||d>=i)continue;const m=4*(d*e+c),u=(a?h:1-h)*(s?l:1-l)*t[m+3];r[0]+=t[m]*u,r[1]+=t[m+1]*u,r[2]+=t[m+2]*u,r[3]+=u}r[3]&&(r[0]/=r[3],r[1]/=r[3],r[2]/=r[3])}var k=[{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}],S=(t,e,i,s)=>"number"==typeof t&&Number.isFinite(t)?Math.max(i,Math.min(s,t)):e;function A(t){if(!Array.isArray(t))return[];const e=[];for(const i of t.slice(0,64))if(i&&"object"==typeof i&&k.some(t=>t.value===i.type)&&(e.push({type:i.type,enabled:!1!==i.enabled,amount:S(i.amount,.35,-1,1),x:S(i.x,.5,0,1),y:S(i.y,.5,0,1),radius:S(i.radius,.55,.05,2),angle:S(i.angle,0,-180,180),frequency:S(i.frequency,5,1,24)}),8===e.length))break;return e}var E=2*Math.PI,F=(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},T=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=A(t).filter(t=>t.enabled&&0!==t.amount),s=JSON.stringify(i);this.edge="transparent"===e?"transparent":"clamp",s!==this.signature&&(this.signature=s,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,s=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(s)||s<=0)throw new Error("Warp dimensions do not match the source.");const a=`${e}:${i}:${s}`;if(a!==this.geometry){this.coordinates.length!==e*i*2&&(this.coordinates=new Float32Array(e*i*2));const t=Math.max(1,s),r=Math.max(1,1/s);for(let s=0;s<i;s++)for(let a=0;a<e;a++){let o=(a+.5)/e,n=(s+.5)/i;for(let e=this.warps.length-1;e>=0;e--){const i=this.warps[e],s=(o-i.x)*t/i.radius,a=(n-i.y)*r/i.radius,h=s*s+a*a;if(h>=1)continue;const l=Math.sqrt(h),c=(1-h)*(1-h),d=i.amount;let m=s,u=a;if("twirl"===i.type||"zigzag"===i.type){const t="twirl"===i.type?-d*E*c:.65*d*(2/Math.PI*Math.asin(Math.sin(l*E*i.frequency)))*c,e=Math.cos(t),r=Math.sin(t);m=s*e-a*r,u=s*r+a*e}else if("pinch"===i.type){const t=Math.exp(2*d*c);m=s*t,u=a*t}else if("sphere"===i.type&&l>0){const t=1+d*c*(2*Math.asin(l)/Math.PI/l-1);m=s*t,u=a*t}else if("ripple"===i.type&&l>0){const t=1+.12*d*Math.sin(l*E*i.frequency)*c/l;m=s*t,u=a*t}else if("shear"===i.type){const t=-s*i.sin+a*i.cos;m-=d*t*.9*c*i.cos,u-=d*t*.9*c*i.sin}else if("smudge"===i.type)m-=.65*d*c*i.cos,u-=.65*d*c*i.sin;else if("polar"===i.type){const t=s*i.cos+a*i.sin,e=-s*i.sin+a*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,f=o*i.sin+n*i.cos;m+=(h-s)*Math.abs(d)*c,u+=(f-a)*Math.abs(d)*c}else if("fragment"===i.type){const t=Math.floor((s*i.cos+a*i.sin)*i.frequency),e=Math.floor((-s*i.sin+a*i.cos)*i.frequency),r=(F(t,e)-.5)*d*.5*c,o=(F(e+71,t-31)-.5)*d*.5*c;m+=r*i.cos-o*i.sin,u+=r*i.sin+o*i.cos}o=i.x+m*i.radius/t,n=i.y+u*i.radius/r}const h=2*(s*e+a);this.coordinates[h]=o*e-.5,this.coordinates[h+1]=n*i-.5}this.geometry=a}this.output.length!==t.length&&(this.output=new Uint8ClampedArray(t.length));const r=t===this.output?t.slice():t,o="transparent"===this.edge?b:w;for(let s=0,a=0;s<t.length;s+=4,a+=2){o(r,e,i,this.coordinates[a],this.coordinates[a+1],this.sampled);for(let t=0;t<4;t++)this.output[s+t]=this.sampled[t]}return this.output}clear(){this.coordinates=new Float32Array(0),this.output=new Uint8ClampedArray(0),this.geometry=""}},P=["stipple","engraving","crosshatch","woodblock","risograph","pointillism"];function I(t){return P.includes(t)}var C={density:1,weight:1,angle:-35,roughness:.35,invert:!1,secondaryInk:"#ec6752",registration:.2,seed:7};function R(t){const e=t&&"object"==typeof t&&!Array.isArray(t)?t:{},i=(t,i,s)=>{const a=e[t];return"number"==typeof a&&Number.isFinite(a)?Math.max(i,Math.min(s,a)):C[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:C.secondaryInk,registration:i("registration",0,1),seed:Math.round(i("seed",0,65535))}}var O=["ascii","blocks","braille","dots","lines","cross","diagonal","diamond","mixed","pixel","mosaic","lego","voxel","disco","dither","hex","led","cmyk",...P],D=["none","bayer2","bayer4","bayer8","bayer16","floyd-steinberg","atkinson","stucki","sierra","sierra-lite","burkes","jarvis","halftone","lines","noise","vertical-lines","diagonal-lines","radial","blue-noise"],L=["source-over","multiply","screen","overlay","soft-light","hard-light","color-dodge","color-burn","hue","saturation","color","luminosity"],N={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:["#0b0b0a","#e6e3da"]},j={version:1,aspectRatio:"original",style:"ascii",cellSize:6,charset:" .:-=+*#%@",colorMode:"accent",ink:"#e6e3da",print:{...C},crop:{x:.5,y:.5,zoom:1,rotation:0},warps:[],warpEdge:"clamp",backdrop:{mode:"solid",color:"#080808",color2:"#1d1d1b",blur:12,opacity:1},color:{brightness:0,contrast:1,saturation:1,grayscale:0,tint:"#e6e3da",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,levels:"auto"},dither:{algorithm:"none",palette:"mono",colors:["#080808","#e6e3da"],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}},U=t=>t&&"object"==typeof t&&!Array.isArray(t)?t:{},X=(t,e,i,s)=>"number"==typeof t&&Number.isFinite(t)?Math.min(s,Math.max(i,t)):e,z=(t,e)=>"string"==typeof t&&/^#[\da-f]{6}$/i.test(t)?t:e,Y=(t,e,i)=>e.includes(t)?t:i;function q(t={}){const e=U(t),a=j;if(void 0!==e.version&&1!==e.version)throw new Error("Unsupported studio settings version. Update asciify-engine.");const r=U(e.crop),o=U(e.backdrop),n=U(e.color),c=U(e.dither),d=U(e.mask),m=U(e.effects),u=U(e.motion),f=U(e.hover),p={...a.effects};for(const t of["bloom","characterBloom","grain","dust","scanlines","crt","prism","rgbSplit","sharpen","vignette","glitch","pixelate","halftone"])p[t]=X(m[t],0,0,1);p.blur=X(m.blur,0,0,24),p.blurType=Y(m.blurType,["gaussian","directional","radial","progressive"],a.effects.blurType),p.angle=X(m.angle,0,-180,180),p.focus=X(m.focus,.5,0,1);let g=2048;return{version:1,aspectRatio:Y(e.aspectRatio,["original","16:9","9:16","1:1","4:3","3:4","21:9"],"original"),style:Y(e.style,O,a.style),cellSize:X(e.cellSize,a.cellSize,I(String(e.style))||["pixel","mosaic","lego","voxel","disco","dots","hex","led","cmyk"].includes(String(e.style))?1:3,60),charset:"string"==typeof e.charset&&e.charset.length?Array.from(e.charset).slice(0,128).join(""):a.charset,colorMode:Y(e.colorMode,["accent","source","gray"],a.colorMode),ink:z(e.ink,a.ink),print:R(e.print),warps:A(e.warps),warpEdge:Y(e.warpEdge,["clamp","transparent"],"clamp"),crop:{x:X(r.x,.5,0,1),y:X(r.y,.5,0,1),zoom:X(r.zoom,1,1,5),rotation:90*Math.round(X(r.rotation,0,-360,360)/90)},backdrop:{mode:Y(o.mode,["solid","transparent","source","blurred","gradient"],a.backdrop.mode),color:z(o.color,a.backdrop.color),color2:z(o.color2,a.backdrop.color2),blur:X(o.blur,12,0,32),opacity:X(o.opacity,1,0,1)},color:{brightness:X(n.brightness,0,-1,1),contrast:X(n.contrast,1,0,3),saturation:X(n.saturation,1,0,3),grayscale:X(n.grayscale,0,0,1),tint:z(n.tint,a.color.tint),amount:X(n.amount,0,0,1),blend:Y(n.blend,L,a.color.blend),blackPoint:X(n.blackPoint,0,0,.99),whitePoint:Math.max(X(n.blackPoint,0,0,.99)+1/255,X(n.whitePoint,1,1/255,1)),gamma:X(n.gamma,1,.25,4),shadows:X(n.shadows,0,-1,1),highlights:X(n.highlights,0,-1,1),curves:v(n.curves),denoise:X(n.denoise,0,0,1),levels:"none"===n.levels?"none":"auto"},dither:{algorithm:Y(c.algorithm,D,"none"),palette:"string"==typeof c.palette&&Object.prototype.hasOwnProperty.call(N,c.palette)?c.palette:"mono",colors:Array.isArray(c.colors)&&c.colors.length>=2?c.colors.slice(0,32).map(t=>z(t,"#000000")):[...a.dither.colors],amount:X(c.amount,1,0,2),scale:Math.round(X(c.scale,2,1,12)),threshold:X(c.threshold,.5,0,1),motion:Y(c.motion,["none","drift","shimmer"],"none"),speed:X(c.speed,1,.1,3),direction:X(c.direction,45,-180,180),colorSpace:Y(c.colorSpace,["rgb","luminance"],"rgb")},mask:{enabled:!0===d.enabled,invert:!0===d.invert,shapes:Array.isArray(d.shapes)?d.shapes.slice(0,64).map(t=>{const e=U(t),i=Y(e.kind,["rectangle","ellipse","brush"],"rectangle"),s="brush"===i&&Array.isArray(e.points)?e.points.slice(0,g).map(t=>Array.isArray(t)?[Math.round(1e4*X(t[0],0,0,1))/1e4,Math.round(1e4*X(t[1],0,0,1))/1e4]:[0,0]):[];return g-=s.length,{kind:i,x:X(e.x,0,0,1),y:X(e.y,0,0,1),width:X(e.width,.5,0,1),height:X(e.height,.5,0,1),size:X(e.size,.05,.005,.5),points:s}}):[]},lights:Array.isArray(e.lights)?e.lights.slice(0,4).map(t=>{const e=U(t);return{x:X(e.x,.5,0,1),y:X(e.y,.5,0,1),radius:X(e.radius,.3,.02,1),intensity:X(e.intensity,.5,0,1),color:z(e.color,"#ffffff")}}):[],effects:p,motion:{type:Y("string"==typeof u.type?l(u.type):u.type,h.map(t=>t.mode),"none"),speed:X(u.speed,1,.1,3),amount:X(u.amount,1,0,2)},hover:{effect:i(f.effect)??"trail",strength:X(f.strength,.55,0,1),radius:X(f.radius,.2,.1,1),edgeSafe:!0===f.edgeSafe,..."all"!==s(f.scope)&&{scope:s(f.scope)},....5!==X(f.decay,.5,0,1)&&{decay:X(f.decay,.5,0,1)}}}}function B(t,e,i,s,a){const r=Math.abs(a.rotation/90)%2==1,o=r?e:t,n=r?t:e,h=Math.max(i/o,s/n)*a.zoom;return{width:o*h,height:n*h,x:(i-o*h)*a.x,y:(s-n*h)*a.y,scale:h,rotated:r}}function G(t,e,i){if(Math.abs(i.crop.rotation/90)%2==1&&([t,e]=[e,t]),"original"===i.aspectRatio)return[t,e];const[s,a]=i.aspectRatio.split(":").map(Number);return t/e>s/a?[Math.round(e*s/a),e]:[t,Math.round(t*a/s)]}function W(t,e){const i={...t,...e};for(const s of["crop","backdrop","color","dither","mask","effects","motion","hover","print"])e[s]&&Object.assign(i,{[s]:{...t[s],...e[s]}});return e.color?.curves&&(i.color.curves={...t.color.curves,...e.color.curves}),q(i)}function H(t,e,i,s=12e3,a=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(s)?s:12e3)),h=Math.max(.01,Number.isFinite(a)?a:1),l=I(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(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,m=Math.max(c,d)*h;return{cell:m,rowHeight:m*l,columns:Math.ceil(r/m),rows:Math.ceil(o/(m*l)),minimum:c,limited:d<c}}var V=[["ascii","Signature ASCII","Clean characters in paper white on near black.",{cellSize:4,ink:"#ece9e0",backdrop:{mode:"solid",color:"#0b0b0a"},color:{contrast:1.25,gamma:1.25},effects:{characterBloom:.12}}],["print","Newsprint","Fine diffusion in soft black on warm paper.",{style:"dither",cellSize:6,ink:"#1d1c19",backdrop:{mode:"solid",color:"#efece4"},dither:{algorithm:"floyd-steinberg",palette:"custom",colors:["#efece4","#1d1c19"],scale:2}}],["handheld","Pocket camera","Four-tone ordered dither in graphite.",{style:"dither",cellSize:6,ink:"#dedbd2",backdrop:{mode:"solid",color:"#121211"},dither:{algorithm:"bayer4",palette:"custom",colors:["#121211","#3e3d39","#8a8880","#dedbd2"],scale:2}}],["riso","Two inks","Muted blue and coral on warm paper.",{style:"dither",cellSize:6,ink:"#3d5068",backdrop:{mode:"solid",color:"#f0ece3"},dither:{algorithm:"atkinson",palette:"custom",colors:["#f0ece3","#c27461","#3d5068"],scale:2}}],["night","Night signal","Graphite characters with a faint optical fringe.",{cellSize:4,ink:"#cdc9be",backdrop:{mode:"solid",color:"#0b0b0a"},color:{contrast:1.2,gamma:1.2},effects:{prism:.2,scanlines:.08,vignette:.3,bloom:.12}}],["terminal","Phosphor","Soft sage glyphs with a faint glow.",{cellSize:5,ink:"#a4c9b3",backdrop:{mode:"solid",color:"#0a0d0b"},effects:{bloom:.16,scanlines:.12,crt:.06}}],["mosaic","Mosaic study","Separated tiles in quiet source color.",{style:"mosaic",ink:"#e6e3da",cellSize:9,colorMode:"source",backdrop:{mode:"solid",color:"#0b0b0a"},color:{saturation:.55,contrast:1.05}}],["bricks","Brickwork","Studded cells in softened color.",{style:"lego",ink:"#e6e3da",cellSize:12,colorMode:"source",backdrop:{mode:"solid",color:"#0b0b0a"},color:{saturation:.55}}],["voxel","Little volumes","Three-face isometric tiles in muted color.",{style:"voxel",ink:"#e6e3da",cellSize:12,colorMode:"source",backdrop:{mode:"solid",color:"#0b0b0a"},color:{saturation:.5}}],["disco","Mirror room","Faceted tiles under one soft light.",{style:"disco",ink:"#e6e3da",cellSize:11,colorMode:"source",backdrop:{mode:"solid",color:"#0b0b0a"},color:{saturation:.5},lights:[{x:.35,y:.25,radius:.28,intensity:.28,color:"#f4efe4"}]}],["wallpaper","Wallpaper","Living ASCII over a softened source.",{cellSize:5,backdrop:{mode:"blurred",color:"#0b0b0a",blur:18,opacity:.4},ink:"#e6e3da",motion:{type:"relight",speed:.35,amount:.8}}],["blueprint","Blueprint","Fine linework in pale blue on deep navy.",{style:"lines",cellSize:6,ink:"#b3c9d8",backdrop:{mode:"solid",color:"#0e1b28"}}]].map(([t,e,i,s])=>({id:t,name:e,description:i,settings:q(s)}));function Q(t){const e=V.find(e=>e.id===t);if(!e)throw new Error("Unknown studio look.");return q(e.settings)}function J(t){const e=function(t){const e=t.blackPoint??0,i=t.whitePoint??1,s=t.gamma??1,a=t.shadows??0,r=t.highlights??0;if(0===e&&1===i&&1===s&&0===a&&0===r)return null;const o=[0,.25+.2*a,.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 a=Math.pow(Math.max(0,Math.min(1,(t/255-e)/(i-e))),1/s),r=Math.min(3,Math.floor(4*a)),n=4*a-r,c=n*n,d=c*n,m=(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,m)))}return l}(t),i=t.curves;if(!e&&(!i||Object.values(i).every(t=>t.every(([t,e])=>t===e))))return null;const s=y(i?.rgb),a=[i?.red,i?.green,i?.blue].map(y),r=new Uint8Array(768);for(let t=0;t<256;t++)for(let i=0;i<3;i++)r[256*i+t]=a[i][s[e?e[t]:t]];return r}var K=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 s=this.source;s.set(t);for(let a=0;a<i;a++)for(let r=0;r<e;r++){const o=4*(a*e+r);if(!s[o+3])continue;const n=s[o],h=s[o+1],l=s[o+2];let c=0,d=0,m=0,u=0;for(let t=-1;t<=1;t++){const o=a+t;if(!(o<0||o>=i))for(let i=-1;i<=1;i++){const a=r+i;if(a<0||a>=e)continue;const f=4*(o*e+a);if(!s[f+3])continue;const p=Math.max(Math.abs(s[f]-n),Math.abs(s[f+1]-h),Math.abs(s[f+2]-l)),g=this.weights[p]*(0===i?1:.6)*(0===t?1:.6)*s[f+3];c+=s[f]*g,d+=s[f+1]*g,m+=s[f+2]*g,u+=g}}t[o]=n+(c/u-n)*this.amount,t[o+1]=h+(d/u-h)*this.amount,t[o+2]=l+(m/u-l)*this.amount}}},Z=2*Math.PI,_=t=>Math.max(0,Math.min(1,t)),$=.1,tt=t=>Math.max(-.1,Math.min(1.1,t)),et=Float32Array.from({length:2048},(t,e)=>Math.sin(e/2048*Z)),it=t=>et[2047&Math.floor(t*(2048/Z))];function st(t,e,i){let s=Math.imul(t,374761393)^Math.imul(e,668265263)^Math.imul(i,1442695041);return s=Math.imul(s^s>>>13,1274126177),((s^s>>>16)>>>0)/4294967296}function at(t){const e=R(t),{density:i,weight:s,angle:a,roughness:r,invert:o,secondaryInk:n,registration:h,seed:l}=e,c=a*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 u(t,e,i,a,o,n,h,c,u=!1){if(h<=0)return;const[f,p]=d[c],g=-p,M=f,x=g*(e+.5)+M*(i+.5),v=.5*(Math.abs(g)+Math.abs(M)),y=u?1:.5,w=Math.ceil((x-v)/y),b=Math.floor((x+v)/y),k=Math.min(.94*y,.72*y*h*s);t.lineWidth=n*k,t.beginPath();for(let s=w;s<=b;s++){const h=s*y-x,c=.5+g*h,d=.5+M*h;let v=-2,w=2;if(Math.abs(f)>1e-8){const t=-c/f,e=(1-c)/f;v=Math.max(v,Math.min(t,e)),w=Math.min(w,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;v=Math.max(v,Math.min(t,e)),w=Math.min(w,Math.max(t,e))}else if(d<0||d>1)continue;if(!(w<=v))if(u&&(v-=$,w+=$),u){for(let t=0;t<6;t++){const a=v+(w-v)*t/5,r=f*(e+c+f*a)+p*(i+d+p*a);m[t]=.5*it(5.3*r+1.9*s+l)+.25*it(13.1*r+s)}for(let e=0;e<2;e++)for(let i=0;i<6;i++){const s=v+(w-v)*(e?5-i:i)/5,h=m[e?5-i:i],l=.5*k*(1+r*h*.5)*(e?-1:1),u=a+tt(c+f*s+g*l)*n,x=o+tt(d+p*s+M*l)*n;e||i?t.lineTo(u,x):t.moveTo(u,x)}t.closePath()}else t.moveTo(a+(c+f*v)*n,o+(d+p*v)*n),t.lineTo(a+(c+f*w)*n,o+(d+p*w)*n)}u?t.fill():t.stroke()}return{settings:e,paint(t,e,a,c,m,f,p,g,M,x,v,y,w){const b=_((o?1-g:g)*i);if(b<=0||t.globalAlpha<=0)return;t.fillStyle=M,t.strokeStyle=M;const k=st(a,c,l);if("engraving"===e||"crosshatch"===e||"woodblock"===e){const i=b*(1-r*k*.3);"woodblock"===e?u(t,a,c,m,f,p,Math.ceil(5*i)/5,0,!0):(u(t,a,c,m,f,p,i,0),"crosshatch"===e&&(u(t,a,c,m,f,p,Math.max(0,1.5*i-.3),1),u(t,a,c,m,f,p,Math.max(0,2*i-1.2),2)))}else if("risograph"===e){const e="source"===w?_(.5+(x-y)/510):.5,i=.38*h*p,o=p*Math.min(.48,.44*Math.sqrt(b)*s);t.beginPath(),t.arc(m+.5*p,f+.5*p,o*Math.sqrt(.35+.65*(1-e)),0,Z),t.fill(),t.globalCompositeOperation="multiply",t.fillStyle=n;const u=1-r*st(a,c,l+13)*.3;t.beginPath(),t.arc(m+.5*p+i*d[0][0],f+.5*p+i*d[0][1],o*Math.sqrt(.3+.7*e)*u,0,Z),t.fill(),t.globalCompositeOperation="source-over"}else{"stipple"===e&&t.beginPath();for(let i=0;i<4;i++){const o=st(2*a+i%2,2*c+(i>>1),l),n=st(a,c,l+11*i+1),h=m+((i%2+.5)/2+(o-.5)*r*.28)*p,d=f+((.5+(i>>1))/2+(n-.5)*r*.28)*p,u=Math.min(h-m,m+p-h,d-f,f+p-d,p*Math.min(.245,.21*s*Math.sqrt(b)*(1-r*o*.35)));if("stipple"===e)t.moveTo(h+u,d),t.arc(h,d,u,0,Z);else{const e=(o-.5)*r*64;t.fillStyle="source"===w?`rgb(${Math.round(x+e)},${Math.round(v-.4*e)},${Math.round(y-e)})`:"gray"===w?`rgb(${Math.round(x+e)},${Math.round(x+e)},${Math.round(x+e)})`:M,t.beginPath(),t.ellipse(h,d,u,.64*u,o*Math.PI,0,Z),t.fill()}}"stipple"===e&&t.fill()}}}}var rt=new Set(["none","floyd-steinberg","atkinson","stucki","sierra","sierra-lite","burkes","jarvis"]);function ot(t){return"dither"===t.style&&("shimmer"===t.dither.motion||"drift"===t.dither.motion&&t.dither.amount>0&&!rt.has(t.dither.algorithm))}function nt(t){return"none"!==t.motion.type&&(t.motion.amount??1)>0}function ht(t){return nt(t)||ot(t)||t.effects.grain>0||t.effects.dust>0||t.effects.glitch>0}var lt=(t,e,i)=>{const s=Math.max(0,Math.min(1,(i-t)/(e-t)));return s*s*(3-2*s)};function ct(t,e,i=256){let s=0;for(let e=0;e<t.length;e++)t[e]>s&&(s=t[e]);if(s<=0)return 0;const a=new Uint32Array(i);for(let e=0;e<t.length;e++)a[Math.min(i-1,Math.floor(t[e]/s*i))]++;let r=0;const o=t.length*e;for(let t=0;t<i;t++)if(r+=a[t],r>=o)return(t+1)/i*s;return s}var dt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",mt="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",ut=new Uint16Array(4096);for(let t=0;t<ut.length;t++)ut[t]=dt.indexOf(mt[2*t])<<6|dt.indexOf(mt[2*t+1]);var ft=(t,e)=>{const i=43758.5453*Math.sin(127.1*t+311.7*e);return i-Math.floor(i)};var pt=new Map([2,4,8,16].map(t=>[t,Float64Array.from({length:t*t},(e,i)=>function(t,e,i){let s=0;for(let a=1;a<i;a*=2){const i=(Math.floor(t/a)%2+2)%2;s=4*s+[[0,2],[3,1]][(Math.floor(e/a)%2+2)%2][i]}return(s+.5)/(i*i)-.5}(i%t,Math.floor(i/t),t))])),gt={"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]]},Mt=t=>[parseInt(t.slice(1,3),16),parseInt(t.slice(3,5),16),parseInt(t.slice(5,7),16)];function xt(t,e,i){const s=Math.min(t*Math.max(1,i),(1-t)*Math.max(1,i),e*Math.max(1,1/i),(1-e)*Math.max(1,1/i)),a=Math.max(0,Math.min(1,(s-.035)/.105));return a*a*a*(a*(6*a-15)+10)}var vt=class{constructor(t,e){this.edgeSafe=!1,this.rings=new Float64Array(40),this.slot=0,this.clock=0,this.lastRing=-1,this.previous=null,this.alive=!1,this.width=t,this.height=e,this.pixels=new Uint8Array(t*e*4),this.values=new Float32Array(t*e),this.clear()}get active(){return this.alive}clear(){this.rings.fill(0),this.values.fill(0),this.pixels.fill(0);for(let t=0;t<this.pixels.length;t+=4)this.pixels[t]=128;this.previous=null,this.alive=!1,this.slot=0,this.lastRing=-1,this.clock=0}leave(){this.previous=null}move(t,e,i,s){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=Number.isFinite(s)?s/1e3:this.clock,r=this.previous;if(this.previous={x:t,y:e,time:a},!r)return;const o=this.width/this.height,n=Math.hypot((t-r.x)*Math.max(1,o),(e-r.y)*Math.max(1,1/o));if(n<1e-4||this.clock-this.lastRing<1/24)return;const h=n/Math.max(1/240,Math.min(.1,a-r.time||1/60)),l=5*this.slot;this.slot=(this.slot+1)%8,this.rings[l]=t,this.rings[l+1]=e,this.rings[l+2]=0,this.rings[l+3]=Math.min(.9,.26+.2*h),this.rings[l+4]=.035+.13*Math.max(.1,Math.min(1,i)),this.alive=!0,this.lastRing=this.clock}step(t){if(!Number.isFinite(t)||t<=0)return;const e=Math.min(.05,t);if(this.clock+=e,!this.alive)return;this.values.fill(0),this.alive=!1;const i=this.width/this.height,s=Math.max(1,i),a=Math.max(1,1/i);for(let t=0;t<this.rings.length;t+=5){if(!this.rings[t+3])continue;const i=this.rings[t+2]+=e;if(i>2.8){this.rings[t+3]=0;continue}this.alive=!0;const r=this.rings[t+4],o=.17*i,n=this.rings[t+3]*(1-Math.exp(20*-i))*Math.exp(2.5*-i),h=o+1.8*r,l=this.rings[t],c=this.rings[t+1],d=Math.max(0,Math.floor((l-h/s)*(this.width-1))),m=Math.min(this.width-1,Math.ceil((l+h/s)*(this.width-1))),u=Math.max(0,Math.floor((c-h/a)*(this.height-1))),f=Math.min(this.height-1,Math.ceil((c+h/a)*(this.height-1)));for(let t=u;t<=f;t++)for(let e=d;e<=m;e++){const i=(Math.hypot((e/(this.width-1)-l)*s,(t/(this.height-1)-c)*a)-o)/r;Math.abs(i)>1.8||(this.values[t*this.width+e]+=n*Math.cos(i*Math.PI*2)*Math.exp(-i*i*2.5))}}for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++){const s=t*this.width+e,a=this.values[s]=Math.max(-1,Math.min(1,this.values[s]))*(this.edgeSafe?xt(e/(this.width-1),t/(this.height-1),i):1),r=Math.round(32767*a+32768);this.pixels[4*s]=r>>>8,this.pixels[4*s+1]=255&r}}sample(t,e,i){const s=Math.max(0,Math.min(this.width-1.001,t*(this.width-1))),a=Math.max(0,Math.min(this.height-1.001,e*(this.height-1))),r=Math.floor(s),o=Math.floor(a),n=s-r,h=a-o,l=o*this.width+r,c=l+this.width;i[0]=i[1]=0,i[2]=3*((this.values[l]*(1-n)+this.values[l+1]*n)*(1-h)+(this.values[c]*(1-n)+this.values[c+1]*n)*h)}},yt=t=>["dissolve","silk","vortex","magnetic","scatter","etch","elastic","lens","smudge"].includes(t),wt=t=>"elastic"===t||"scatter"===t,bt={elastic:[150,4.2],scatter:[90,3.6]},kt=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 s=0;s<t;s++)this.edge[i*t+s]=xt(s/(t-1),i/(e-1),t/e);this.clear()}get active(){return this.peak>2e-4}setMode(t){if(wt(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),e=(t,e)=>{const i=43758.5453*Math.sin(127.1*t+311.7*e);return i-Math.floor(i)};for(let i=0;i<this.height;i++)for(let s=0;s<this.width;s++){const a=.09*s,r=.09*i,o=Math.floor(a),n=Math.floor(r),h=a-o,l=r-n,c=h*h*(3-2*h),d=l*l*(3-2*l),m=((e(o,n)*(1-c)+e(o+1,n)*c)*(1-d)+(e(o,n+1)*(1-c)+e(o+1,n+1)*c)*d)*Math.PI*4,u=2*(i*this.width+s);t[u]=.7*Math.cos(m),t[u+1]=.7*Math.sin(m)}}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 s=this.previous;this.previous={x:t,y:e};const a=this.width,r=this.height,o=Math.max(1,a/r),n=Math.max(1,r/a),h=s?(t-s.x)*o:0,l=s?(e-s.y)*n:0,c=Math.hypot(h,l);if(!s&&"dissolve"!==this.mode&&"etch"!==this.mode&&"lens"!==this.mode)return;if(s&&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)))),u=c?h/c:1,f=c?l/c:0,p=s||"lens"!==this.mode?Math.min(1,c/(d*m)*2.2):.32;for(let i=0;i<m;i++){const h=(i+.5)/m,l=s?s.x+(t-s.x)*h:t,c=s?s.y+(e-s.y)*h:e,g=Math.max(0,Math.floor((l-2.5*d/o)*(a-1))),M=Math.min(a-1,Math.ceil((l+2.5*d/o)*(a-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/(a-1)-l)*o/d,s=(t/(r-1)-c)*n/d,h=Math.exp(1.5*-(i*i+s*s)),m=t*a+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]+u*h*p*12)),this.springY[m]=Math.max(-24,Math.min(24,this.springY[m]+f*h*p*12));else if("scatter"===this.mode){const t=this.scatterDirections;this.springX[m]=Math.max(-24,Math.min(24,this.springX[m]+(.6*i+t[2*m])*h*p*7)),this.springY[m]=Math.max(-24,Math.min(24,this.springY[m]+(.6*s+t[2*m+1])*h*p*7))}else if("lens"===this.mode)this.targetX[m]=Math.max(-.65,Math.min(.65,this.targetX[m]+i*h*p*1.6)),this.targetY[m]=Math.max(-.65,Math.min(.65,this.targetY[m]+s*h*p*1.6));else if("smudge"===this.mode)this.targetX[m]=Math.max(-1,Math.min(1,this.targetX[m]+u*h*p*1.3)),this.targetY[m]=Math.max(-1,Math.min(1,this.targetY[m]+f*h*p*1.3));else{const t=(-i*f+s*u)*h*2.8,e="magnetic"===this.mode?-i*h*2.5:"silk"===this.mode?u*t:-s*h*2.5,a="magnetic"===this.mode?-s*h*2.5:"silk"===this.mode?f*t:i*h*2.5;this.targetX[m]=Math.max(-1,Math.min(1,this.targetX[m]+e*p)),this.targetY[m]=Math.max(-1,Math.min(1,this.targetY[m]+a*p))}}}this.peak=1}step(t){if(!this.active||!Number.isFinite(t))return;const e=Math.max(0,Math.min(.05,t)),i="dissolve"===this.mode?2.15:"smudge"===this.mode?2.4:3.2,s="lens"===this.mode?16:22,a=Math.exp(-i*e),r=1-Math.exp(-s*e);let o=0;const[n,h]="scatter"===this.mode?bt.scatter:bt.elastic,l=Math.sqrt(n-h*h),c=Math.exp(-h*e),d=Math.cos(l*e),m=Math.sin(l*e)/l;for(let t=0;t<this.ink.length;t++)if("etch"===this.mode)this.ink[t]*=a,o=Math.max(o,this.ink[t]);else if("dissolve"===this.mode){this.ink[t]*=a,o=Math.max(o,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(wt(this.mode)){const e=this.offsetX[t],i=this.offsetY[t],s=this.springX[t],a=this.springY[t];this.offsetX[t]=Math.max(-1,Math.min(1,c*(e*d+(s+h*e)*m))),this.offsetY[t]=Math.max(-1,Math.min(1,c*(i*d+(a+h*i)*m))),this.springX[t]=c*(s*d-(h*s+n*e)*m),this.springY[t]=c*(a*d-(h*a+n*i)*m),o=Math.max(o,.05*Math.abs(this.springX[t]),.05*Math.abs(this.springY[t]))}else if("lens"===this.mode||"smudge"===this.mode){const e=1-r,o=s/(s-i)*(a-e);this.offsetX[t]=this.offsetX[t]*e+this.targetX[t]*o,this.offsetY[t]=this.offsetY[t]*e+this.targetY[t]*o,this.targetX[t]*=a,this.targetY[t]*=a}else this.targetX[t]*=a,this.targetY[t]*=a,this.offsetX[t]+=(this.targetX[t]-this.offsetX[t])*r,this.offsetY[t]+=(this.targetY[t]-this.offsetY[t])*r;o=Math.max(o,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),l=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]=l>>>8,this.pixels[4*t+3]=255&l}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,s=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,s))*(this.edgeSafe?this.edge[i]:1);const a=Math.round(32767*this.offsetX[i]+32768);this.pixels[4*i]=a>>>8,this.pixels[4*i+1]=255&a}this.peak=o,this.active||this.clear()}sample(t,e,i){const s=Math.max(0,Math.min(this.width-1.001,t*(this.width-1))),a=Math.max(0,Math.min(this.height-1.001,e*(this.height-1))),r=Math.floor(s),o=Math.floor(a),n=s-r,h=a-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?xt(t,e,this.width/this.height):1)*.08,i[1]=d(this.offsetY)*(this.edgeSafe?xt(t,e,this.width/this.height):1)*.08,i[2]="dissolve"===this.mode?6*-d(this.ink):0}},St=class{constructor(t,e){this.rings=[],this.previous=null,this.elapsed=1,this.echoPeak=0,this.width=t,this.height=e,this.pixels=new Uint8Array(t*e*4),this.echo=new Float32Array(t*e)}get active(){return this.rings.length>0||this.echoPeak>2e-4}clear(){this.rings=[],this.previous=null,this.elapsed=1,this.pixels.fill(0),this.echo.fill(0),this.echoPeak=0}leave(){this.previous=null}move(t,e,i){const s=Math.max(1,this.width/this.height),a=Math.max(1,this.height/this.width);this.previous&&(Math.hypot((t-this.previous.x)*s,(e-this.previous.y)*a)<.065||this.elapsed<.3)||4!==this.rings.length&&(this.previous={x:t,y:e},this.elapsed=0,this.rings.push({x:t,y:e,age:0,radius:i}))}ringSample(t,e){const i=Math.max(1,this.width/this.height),s=Math.max(1,this.height/this.width);let a=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)*s)-o)/n,l=Math.sin(Math.min(1,r.age/.07)*Math.PI/2)*Math.max(0,1-r.age/1.35)**2;a=Math.max(a,Math.exp(-h*h)*l)}return a}sample(t,e){const i=Math.max(0,Math.min(this.width-1,Math.round(t*(this.width-1)))),s=Math.max(0,Math.min(this.height-1,Math.round(e*(this.height-1))));return Math.max(this.ringSample(t,e),this.echo[s*this.width+i])}step(t){if(!Number.isFinite(t))return;const e=Math.max(0,Math.min(.05,t));this.elapsed+=e;for(const t of this.rings)t.age+=e;if(this.rings=this.rings.filter(t=>t.age<1.35),!this.active)return void this.pixels.fill(0);const i=Math.exp(-5.5*e);let s=0;for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++){const a=t*this.width+e;this.echo[a]=Math.max(this.ringSample(e/(this.width-1),t/(this.height-1)),this.echo[a]*i),s=Math.max(s,this.echo[a]);const r=Math.round(65535*this.echo[a]),o=4*a;this.pixels[o]=r>>>8,this.pixels[o+1]=255&r}this.echoPeak=s,this.active||(this.echo.fill(0),this.pixels.fill(0))}},At=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,s=performance.now()){if(!Number.isFinite(t+e+i+s))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 a=this.previous;if(this.previous={x:t,y:e,time:s},!a)return;const r=(t-a.x)*(this.width-1),o=(e-a.y)*(this.height-1),n=Math.hypot(r,o);if(n<.001)return;const h=Math.min(this.width,this.height),l=s>a.time?Math.max(1/240,(s-a.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),u=Math.min(128,Math.max(1,Math.ceil(n/(.4*m)))),f=n/m*(.32+.22*d)/u,p=r/n,g=o/n,M=-g,x=p,v=n*(2+18*d)/u;for(let i=0;i<u;i++){const s=(i+.5)/u,r=(a.x+(t-a.x)*s)*(this.width-1),o=(a.y+(e-a.y)*s)*(this.height-1),n=Math.max(1,Math.floor(r-3*m)),h=Math.min(this.width-2,Math.ceil(r+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-r)*p+(t-o)*g)/m,s=((e-r)*M+(t-o)*x)/m,a=Math.exp(-i*i*.65-s*s*1.7),n=t*this.width+e;this.ink[n]=1-(1-this.ink[n])*Math.exp(-a*f);const h=1-s*s*.55,l=i*s*.7;this.u[n]=Math.max(-80,Math.min(80,this.u[n]+(p*h+M*l)*a*v)),this.v[n]=Math.max(-80,Math.min(80,this.v[n]+(g*h+x*l)*a*v))}}this.peak=1}read(t,e,i){const s=0|(e=Math.max(.5,Math.min(this.width-1.5,e))),a=0|(i=Math.max(.5,Math.min(this.height-1.5,i))),r=e-s,o=i-a,n=a*this.width+s;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,s=this.height;for(;e>1e-7;){const t=Math.min(1/60,e);e-=t;const a=Math.exp(-1.9*t),r=Math.exp(-3.2*t);for(let e=1;e<s-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(s-1.5,e-this.v[n]*t)),c=0|h,d=0|l,m=h-c,u=l-d,f=d*i+c,p=(1-m)*(1-u),g=m*(1-u),M=(1-m)*u,x=m*u;this.a[n]=(this.u[f]*p+this.u[f+1]*g+this.u[f+i]*M+this.u[f+i+1]*x)*a,this.b[n]=(this.v[f]*p+this.v[f+1]*g+this.v[f+i]*M+this.v[f+i+1]*x)*a,this.c[n]=(this.ink[f]*p+this.ink[f+1]*g+this.ink[f+i]*M+this.ink[f+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<s-1;t++)for(let e=1;e<i-1;e++){const s=t*i+e;this.curl[s]=.5*(this.v[s+1]-this.v[s-1]-this.u[s+i]+this.u[s-i])}for(let e=1;e<s-1;e++)for(let s=1;s<i-1;s++){const a=e*i+s,r=Math.abs(this.curl[a+1])-Math.abs(this.curl[a-1]),o=Math.abs(this.curl[a+i])-Math.abs(this.curl[a-i]),n=Math.hypot(r,o)+1e-4,h=this.curl[a]*t*10,l=Math.hypot(this.u[a],this.v[a]);this.u[a]+=o/n*h,this.v[a]-=r/n*h;const c=Math.min(1,l/(Math.hypot(this.u[a],this.v[a])+1e-6));this.u[a]*=c,this.v[a]*=c,this.divergence[a]=-.5*(this.u[a+1]-this.u[a-1]+this.v[a+i]-this.v[a-i])}this.pressure.fill(0);for(let t=0;t<4;t++){for(let t=1;t<s-1;t++)for(let e=1;e<i-1;e++){const s=t*i+e;this.pressureNext[s]=.25*(this.divergence[s]+this.pressure[s-1]+this.pressure[s+1]+this.pressure[s-i]+this.pressure[s+i])}[this.pressure,this.pressureNext]=[this.pressureNext,this.pressure]}let o=0;for(let e=1;e<s-1;e++)for(let s=1;s<i-1;s++){const a=e*i+s;this.u[a]=Math.max(-80,Math.min(80,this.u[a]-.5*(this.pressure[a+1]-this.pressure[a-1]))),this.v[a]=Math.max(-80,Math.min(80,this.v[a]-.5*(this.pressure[a+i]-this.pressure[a-i]))),this.driftX[a]+=(3.6*this.u[a]-58*this.offsetX[a]-12*this.driftX[a])*t,this.driftY[a]+=(3.6*this.v[a]-58*this.offsetY[a]-12*this.driftY[a])*t,this.offsetX[a]=Math.max(-2,Math.min(2,this.offsetX[a]+this.driftX[a]*t)),this.offsetY[a]=Math.max(-2,Math.min(2,this.offsetY[a]+this.driftY[a]*t)),this.signal[a]=1-Math.exp(.06*-Math.hypot(this.u[a],this.v[a])-.16*this.ink[a]),o=Math.max(o,this.signal[a])}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()}};var Et=["loupe","repel","tilt","reveal","haze","bleed"],Ft=t=>Et.includes(t),Tt=class{constructor(){this.value=0,this.velocity=0}step(t,e,i,s){const a=2*Math.sqrt(i)*s;for(let s=e;s>1e-6;s-=1/480){const e=Math.min(1/480,s);this.velocity+=((t-this.value)*i-this.velocity*a)*e,this.value+=this.velocity*e}}resting(t){return Math.abs(this.value-t)<.0015&&Math.abs(this.velocity)<.01}set(t){this.value=t,this.velocity=0}},Pt=t=>t*t*(3-2*t),It=(t,e)=>{const i=43758.5453*Math.sin(127.1*t+311.7*e);return i-Math.floor(i)};function Ct(t,e){const i=Math.floor(t),s=Math.floor(e),a=Pt(t-i),r=Pt(e-s),o=It(i,s),n=It(i+1,s),h=It(i,s+1);return(o+(n-o)*a)*(1-r)+(h+(It(i+1,s+1)-h)*a)*r}var Rt=class{constructor(t,e){this.edgeSafe=!1,this.settle=1,this.focus=[.5,.5,0,.2],this.guide=null,this.mode="loupe",this.radius=.35,this.x=new Tt,this.y=new Tt,this.tx=new Tt,this.ty=new Tt,this.presence=new Tt,this.target=null,this.speed=0,this.clock=0,this.inkPeak=0,this.ink=null,this.next=null,this.fiber=null,this.sampled=[0,0,0],this.width=t,this.height=e,this.pixels=new Uint8Array(t*e*4),this.sx=Math.max(1,t/e),this.sy=Math.max(1,e/t),this.clear()}setMode(t){if(t!==this.mode&&(this.mode=t,this.clear(),"bleed"===t&&!this.ink)){const t=this.width*this.height;this.ink=new Float32Array(t),this.next=new Float32Array(t),this.fiber=new Float32Array(t);for(let t=0;t<this.height;t++)for(let e=0;e<this.width;e++)this.fiber[t*this.width+e]=.35+.5*Ct(.09*e,.045*t)+.15*It(e,t)}}setRadius(t){this.radius=Math.max(.1,Math.min(1,t))}get reach(){return(.05+.25*this.radius)*("loupe"===this.mode?1-.14*this.speed:1)}get engaged(){return this.presence.value>.002||this.inkPeak>.002||Math.abs(this.tx.value)+Math.abs(this.ty.value)>4e-4}get active(){const t=this.target?1:0;return!this.presence.resting(t)||!!this.target&&(!this.x.resting(this.target.x)||!this.y.resting(this.target.y))||!this.tx.resting(this.tiltGoal(0))||!this.ty.resting(this.tiltGoal(1))||this.speed>.01||"haze"===this.mode&&this.presence.value>.002||this.inkPeak>.002}tiltGoal(t){return this.target&&"tilt"===this.mode?2*((t?this.target.y:this.target.x)-.5):0}clear(){for(const t of[this.x,this.y,this.tx,this.ty,this.presence])t.set(0);this.x.set(.5),this.y.set(.5),this.target=null,this.speed=0,this.inkPeak=0,this.ink?.fill(0),this.next?.fill(0),this.encode()}move(t,e,i){if(!Number.isFinite(t+e))return;t=Math.max(0,Math.min(1,t)),e=Math.max(0,Math.min(1,e));const s=Number.isFinite(i)?i/1e3:this.clock,a=this.target;if(!a&&this.presence.value<.05&&(this.x.set(t),this.y.set(e)),a){const i=Math.hypot((t-a.x)*this.sx,(e-a.y)*this.sy),r=i/Math.max(1/240,Math.min(.1,s-a.time||1/60));this.speed=Math.max(this.speed,Math.min(1,r/1.6)),"bleed"===this.mode&&this.deposit(a.x,a.y,t,e,Math.min(1,9*i))}else"bleed"===this.mode&&this.deposit(t,e,t,e,.5);this.target={x:t,y:e,time:s}}leave(){this.target=null}deposit(t,e,i,s,a){const r=this.ink,o=this.width,n=this.height,h=.55*this.reach,l=Math.hypot((i-t)*this.sx,(s-e)*this.sy),c=Math.min(48,Math.max(1,Math.ceil(l/(.5*h))));for(let l=0;l<c;l++){const d=(l+.5)/c,m=t+(i-t)*d,u=e+(s-e)*d,f=Math.max(0,Math.floor((m-2*h/this.sx)*(o-1))),p=Math.min(o-1,Math.ceil((m+2*h/this.sx)*(o-1))),g=Math.max(0,Math.floor((u-2*h/this.sy)*(n-1))),M=Math.min(n-1,Math.ceil((u+2*h/this.sy)*(n-1)));for(let t=g;t<=M;t++)for(let e=f;e<=p;e++){const i=(e/(o-1)-m)*this.sx/h,s=(t/(n-1)-u)*this.sy/h,l=t*o+e;r[l]=Math.min(1.4,r[l]+Math.exp(1.8*-(i*i+s*s))*a/c*1.6)}}this.inkPeak=Math.max(this.inkPeak,.01)}step(t){if(!Number.isFinite(t)||t<=0)return;const e=Math.min(.05,t),i=e*this.settle;this.clock+=e;const s=this.target,a=this.mode;if(s?this.presence.step(1,e,190,1):this.presence.step(0,i,"repel"===a?120:70,"repel"===a?.42:1),s){const t="tilt"===a?60:"haze"===a?90:240,i="loupe"===a||"repel"===a?.72:.9;this.x.step(s.x,e,t,i),this.y.step(s.y,e,t,i)}this.tx.step(this.tiltGoal(0),s?e:i,45,.78),this.ty.step(this.tiltGoal(1),s?e:i,45,.78),this.speed*=Math.exp(7*-e),"bleed"===a&&this.spread(e,i,!!s),this.engaged||this.active||(this.presence.set(0),this.tx.set(0),this.ty.set(0)),this.focus[0]=this.x.value,this.focus[1]=this.y.value,this.focus[2]=Math.max(0,Math.min(1,this.presence.value)),this.focus[3]=this.reach,this.encode()}spread(t,e,i){const s=this.ink,a=this.next,r=this.fiber,o=this.width,n=this.height;i&&this.target&&this.deposit(this.x.value,this.y.value,this.x.value,this.y.value,.9*t);const h=Math.max(1,Math.ceil(t/(1/240))),l=t/h,c=26*(.4+this.radius),d=(i?.02:.1)*e/t,m=Math.exp(-(i?.15:.9)*e/h);let u=0;for(let t=0;t<h;t++){u=0;for(let t=1;t<n-1;t++)for(let e=1;e<o-1;e++){const i=t*o+e,n=s[i],h=r[i],f=Math.min(h,r[i-1])*(s[i-1]-n)+Math.min(h,r[i+1])*(s[i+1]-n)+Math.min(h,r[i-o])*(s[i-o]-n)+Math.min(h,r[i+o])*(s[i+o]-n),p=Math.max(0,(n+f*Math.min(.24,c*l))*m-d*l);a[i]=p,p>u&&(u=p)}s.set(a)}this.inkPeak=u}sample(t,e,i){i[0]=i[1]=i[2]=0;const s=this.presence.value,a=this.mode;if("bleed"===a){if(this.inkPeak<=.002)return;const s=this.width,a=this.height,r=this.ink,o=Math.max(0,Math.min(s-1.001,t*(s-1))),n=Math.max(0,Math.min(a-1.001,e*(a-1))),h=Math.floor(o),l=Math.floor(n),c=o-h,d=n-l,m=l*s+h,u=m+s,f=(r[m]*(1-c)+r[m+1]*c)*(1-d)+(r[u]*(1-c)+r[u+1]*c)*d;return void(i[2]=1-Math.exp(2.4*-f))}if("tilt"===a){const s=this.guide?function(t,e,i,s){const a=t[e],r=t.width,o=t.height,n=Math.max(0,Math.min(r-1.001,i*(r-1))),h=Math.max(0,Math.min(o-1.001,s*(o-1))),l=Math.floor(n),c=Math.floor(h),d=n-l,m=h-c,u=c*r+l,f=Math.min(o-1,c+1)*r+l,p=l+1<r?1:0;return(a[u]*(1-d)+a[u+p]*d)*(1-m)+(a[f]*(1-d)+a[f+p]*d)*m}(this.guide,"depth",t,e):.6,a=.2+.8*s,r=this.edgeSafe?xt(t,e,this.sx/this.sy):1;return i[0]=.024*this.tx.value*a*r/this.sx,void(i[1]=.024*this.ty.value*a*r/this.sy)}if(s<=.001)return;const r=this.reach,o=(t-this.x.value)*this.sx,n=(e-this.y.value)*this.sy,h=(o*o+n*n)/(r*r);if("reveal"===a)return void(i[2]=Math.exp(2.4*-h)*s);if(h>9)return;const l=this.edgeSafe?xt(t,e,this.sx/this.sy):1;let c=0,d=0;if("loupe"===a){const t=Math.exp(-h*h)*s*.5;c=o*t,d=n*t;const e=Math.sqrt(h)-1;i[2]=Math.exp(-e*e/.018)*s*.55}else if("repel"===a){const t=Math.sqrt(h),e=.5*r*Math.exp(-h/1.7)*s,a=Math.max(1e-6,Math.sqrt(o*o+n*n));c=o/a*Math.min(e,a+.5*r*s),d=n/a*Math.min(e,a+.5*r*s);const l=Math.max(0,Math.min(1,(t-.3)/.32));i[2]=-(1-l*l*(3-2*l))*s}else if("haze"===a){const a=n/r+.45,h=Math.exp(-o*o/(r*r)-a*a/2.6)*s*(.35+.65*Math.min(1,1.4*this.speed+.25));if(h<.002)return;const l=this.clock,m=t*this.sx*9,u=e*this.sy*9+2.3*l;c=.06*(Ct(m,u)-.5)*h,d=.026*(Ct(m+17.3,1.3*u+.7*l)-.5)*h,i[2]=.35*(Ct(1.7*m+5,1.7*u)-.5)*h}i[0]=c*l/this.sx,i[1]=d*l/this.sy}encode(){const t=this.width,e=this.height,i=this.pixels,s=this.sampled,a=this.engaged;for(let r=0;r<e;r++)for(let o=0;o<t;o++){const n=4*(r*t+o);if(a?this.sample(o/(t-1),r/(e-1),s):s[0]=s[1]=s[2]=0,"bleed"===this.mode){const t=Math.round(32767*Math.max(-1,Math.min(1,s[2]))+32768);i[n]=t>>>8,i[n+1]=255&t,i[n+2]=128,i[n+3]=0}else{"repel"===this.mode&&(s[0]*=.3,s[1]*=.3);const t=Math.round(32767*Math.max(-1,Math.min(1,s[0]/.16))+32768),e=Math.round(32767*Math.max(-1,Math.min(1,s[1]/.16))+32768);i[n]=t>>>8,i[n+1]=255&t,i[n+2]=e>>>8,i[n+3]=255&e}}}},Ot=(t,e)=>"water"===t?30*e/.55:"silk"===t?28*e:"vortex"===t?38*e:["magnetic","scatter","elastic","lens","smudge"].includes(t)?32*e:["loupe","repel","tilt","haze"].includes(t)?.16*e/.55:0;function Dt(t,e,i,s=!1){if(!i)return e;const a=t=>Math.max(0,Math.min(1,t));switch(t){case"trail":case"contour":return function(t,e){const i=Math.max(0,Math.min(1,e/.38));return t+i*i*(3-2*i)*(1-2*t)}(e,i);case"etch":case"ripple":return a(e+.35*i);case"dissolve":{const t=Math.max(0,1+i);return s?1-(1-e)*t:e*t}case"bleed":return a(e+i*(s?-.6:.6));case"loupe":return a(e+.3*i);case"haze":return a(e+.5*i);default:return e}}var Lt=t=>["trail","contour","etch","ripple","bleed","haze"].includes(t),Nt=class{constructor(t=1){this.ripple=null,this.cursor=null,this.settle=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,this.guide=null,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]=xt(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 At(this.columns,this.rows),this.contour=new St(this.columns,this.rows),this.afterimage=new kt(this.columns,this.rows),this.clear()}get invertsDensity(){return"trail"===this.mode}get densityTrail(){return["trail","contour","dissolve","etch","ripple","bleed"].includes(this.mode)}get hasRefraction(){return this.active||this.lensStrength>15e-5}get effect(){return this.mode}get engaged(){return Ft(this.mode)?this.cursor.engaged:this.active}get spotlight(){return"reveal"===this.mode&&this.cursor?this.cursor.focus:null}get signature(){return Ft(this.mode)&&this.cursor.engaged?this.cursor.focus.map(t=>t.toFixed(4)).join(","):""}setGuide(t){this.cursor&&(this.cursor.guide=t),this.guide=t}get active(){return Ft(this.mode)?this.cursor.active:"ripple"===this.mode?this.ripple?.active??!1:yt(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){const e="light"===t||"scan"===t?t:i(t)??"none";e!==this.mode&&(this.clear(),this.mode=e,this.refraction.mode=e,yt(e)&&this.afterimage.setMode(e),"ripple"!==e||this.ripple||(this.ripple=new vt(this.columns,this.rows)),Ft(e)&&(this.cursor??(this.cursor=new Rt(this.columns,this.rows)),this.cursor.guide=this.guide,this.cursor.setMode(e)),this.refraction.pixels=Ft(e)?this.cursor.pixels:"ripple"===e?this.ripple.pixels:"trail"===e?this.trail.pixels:"contour"===e?this.contour.pixels:yt(e)?this.afterimage.pixels:this.waterPixels,this.refraction.strength=Ot(e,this.amount),this.refraction.relative=Ft(e))}configure(t,e=.55,i=.2,s=!1,a=.5){this.setMode(t),this.settle=((t=.5)=>Math.pow(2,2.4*(.5-(Number.isFinite(t)?Math.max(0,Math.min(1,t)):.5))))(a),this.refraction.edgeSafe=s,this.afterimage.edgeSafe=s,this.ripple&&(this.ripple.edgeSafe=s),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.cursor&&(this.cursor.edgeSafe=s,this.cursor.settle=this.settle,this.cursor.setRadius(this.radius)),this.refraction.strength=Ot(this.mode,this.amount),this.refraction.focus[2]=this.densityTrail?this.amount:this.lensStrength*this.amount,this.refraction.focus[3]=this.radius,"reveal"!==this.mode&&"repel"!==this.mode||this.syncSpot()}syncSpot(){const t=this.cursor.focus;this.refraction.focus=[t[0],t[1],t[2]*("repel"===this.mode?Math.min(1,this.amount/.55):this.amount),t[3]]}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)),Ft(this.mode))return void this.cursor.move(t,e,i);if("ripple"===this.mode)return void this.ripple.move(t,e,this.radius,i);if(yt(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 s=this.previous;this.previous={x:t,y:e};const a=(t-s.x)*this.xScale,r=(e-s.y)*this.yScale,o=Math.hypot(a,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 a=(i+.5)/l,r=s.x+(t-s.x)*a,o=s.y+(e-s.y)*a,d=Math.max(1,Math.floor((r-h/this.xScale)*(this.columns-1))),m=Math.min(this.columns-2,Math.ceil((r+h/this.xScale)*(this.columns-1))),u=Math.max(1,Math.floor((o-h/this.yScale)*(this.rows-1))),f=Math.min(this.rows-2,Math.ceil((o+h/this.yScale)*(this.rows-1)));for(let t=u;t<=f;t++)for(let e=d;e<=m;e++){const i=(e/(this.columns-1)-r)*this.xScale,s=(t/(this.rows-1)-o)*this.yScale,a=Math.exp(-(i*i+s*s)/(n*n))*c,h=t*this.columns+e;this.velocity[h]=Math.max(-12,this.velocity[h]-a)}}this.pending=!0}leave(){this.cursor?.leave(),this.ripple?.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.ripple?.clear(),this.cursor?.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(Ft(this.mode))return this.cursor.step(t),void("reveal"!==this.mode&&"repel"!==this.mode||this.syncSpot());if(t*=this.settle,"ripple"===this.mode)return void this.ripple.step(t);if(yt(this.mode))return void this.afterimage.step(t);if("contour"===this.mode)return void this.contour.step(t);if("trail"===this.mode)return void this.trail.step(t);if("water"!==this.mode)return void this.stepLight(Math.max(0,Math.min(.05,t)));this.remainder+=Math.max(0,Math.min(.05,t));const e=1/120,i=Math.exp(-3.8*e),s=.3*Math.min(this.columns,this.rows);for(;this.remainder+1e-8>=e;){this.remainder-=e;let t=0;for(let a=1;a<this.rows-1;a++)for(let r=1;r<this.columns-1;r++){const o=a*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,a,this.columns-1-r,this.rows-1-a),c=l<5?.88+.024*l:1,d=(this.velocity[o]+(h*s*s-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 a=.18*Math.min(this.columns,this.rows);for(let t=0;t<this.rows;t++)for(let e=0;e<this.columns;e++){const i=t*this.columns+e,s=(this.heights[t*this.columns+Math.max(0,e-1)]-this.heights[t*this.columns+Math.min(this.columns-1,e+1)])*a,r=(this.heights[Math.max(0,t-1)*this.columns+e]-this.heights[Math.min(this.rows-1,t+1)*this.columns+e])*a,o=Math.tanh(s)*(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),s=1-Math.exp(-12*t);e&&(this.lensX+=(e.x-this.lensX)*i,this.lensY+=(e.y-this.lensY)*i),this.lensStrength+=((e?1:0)-this.lensStrength)*s,this.energy=Math.max(e?Math.abs(e.x-this.lensX)+Math.abs(e.y-this.lensY):0,Math.abs((e?1:0)-this.lensStrength)),this.pending=!1,e||this.active?this.refraction.focus=[this.lensX,this.lensY,this.lensStrength*this.amount,this.radius]:this.clear()}sample(t,e,i){if(Ft(this.mode))return this.cursor.sample(t,e,i),i[0]*=this.amount/.55,i[1]*=this.amount/.55,void(i[2]*="reveal"===this.mode||"repel"===this.mode?Math.min(1,this.amount/.55):3*this.amount);if("ripple"===this.mode)return this.ripple.sample(t,e,i),void(i[2]*=this.amount);if(yt(this.mode))return this.afterimage.sample(t,e,i),i[0]*=this.amount,i[1]*=this.amount,void(i[2]*=this.amount);if("contour"===this.mode)return i[0]=i[1]=0,void(i[2]=this.contour.sample(t,e)*this.amount*3);if("trail"===this.mode)return i[0]=i[1]=0,void(i[2]=this.trail.sample(t,e)*this.amount*3);const s=Math.max(0,Math.min(this.columns-1.001,t*(this.columns-1))),a=Math.max(0,Math.min(this.rows-1.001,e*(this.rows-1))),r=Math.floor(s),o=Math.floor(a),n=s-r,h=a-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,s){const[a,r,o,n]=i.focus,h=(t-a)*Math.max(1,s)/n,l=(e-r)*Math.max(1,1/s)/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 jt(t){return"videoWidth"in t?[t.videoWidth,t.videoHeight]:"naturalWidth"in t?[t.naturalWidth,t.naturalHeight]:[t.width,t.height]}var Ut=(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}},Xt=(t,e,i)=>{t.width===e&&t.height===i||(t.width=e,t.height=i)},zt={blocks:" ░▒▓█",braille:" ⠁⠃⠇⡇⣇⣧⣷⣿",lines:" -═╪╬",cross:" ·+xX#",diagonal:" /╱╳",diamond:" ·◇◈◆",mixed:" .:+/◇#@"},Yt=.32,qt=.9;function Bt(t){const e=new Uint32Array(256);let i=0;for(let s=0;s<t.length;s+=4)t[s+3]<8||(e[Math.min(255,.299*t[s]+.587*t[s+1]+.114*t[s+2]|0)]++,i++);if(!i)return[0,1];const s=t=>{let s=0;const a=t*i;for(let t=0;t<256;t++)if((s+=e[t])>=a)return t/255;return 1};let a=s(.01),r=s(.99);return r-a<Yt&&(a=Math.max(0,Math.min(1-Yt,(a+r)/2-.16)),r=a+Yt),[a,r]}function Gt(t,e,i){const s=Math.max(.001,i-e);let a=0,r=0;for(let i=0;i<t.length;i+=4){if(t[i+3]<8)continue;const o=((.299*t[i]+.587*t[i+1]+.114*t[i+2])/255-e)/s;o<=.06||(a+=Math.min(1,o),r++)}if(!r)return qt;const o=Math.min(.99,Math.max(.01,a/r));return Math.min(qt,Math.max(.6,Math.log(.5)/Math.log(o)))}function Wt(t,e=.9){const i=Math.min(...t),s=Math.max(...t);if(!(s-i>1e-4))return null;const a=t.map(t=>(t-i)/(s-i)),r=new Uint8Array(256);for(let t=0;t<256;t++){if(t/255<.07){r[t]=a.indexOf(0);continue}const i=Math.pow(t/255,e);let s=0;for(let t=1;t<a.length;t++)Math.abs(a[t]-i)<Math.abs(a[s]-i)&&(s=t);r[t]=s}return r}function Ht(t,e,i,s){t.clearRect(0,0,e,i),t.fillStyle="#fff",t.strokeStyle="#fff",t.lineCap="round",t.lineJoin="round";for(const a of s){if(t.beginPath(),"ellipse"===a.kind)t.ellipse((a.x+a.width/2)*e,(a.y+a.height/2)*i,a.width*e/2,a.height*i/2,0,0,2*Math.PI);else{if("rectangle"!==a.kind){if(t.lineWidth=(a.size??.05)*e,1===a.points?.length){t.arc(a.points[0][0]*e,a.points[0][1]*i,t.lineWidth/2,0,2*Math.PI),t.fill();continue}a.points?.forEach(([s,a],r)=>r?t.lineTo(s*e,a*i):t.moveTo(s*e,a*i)),t.stroke();continue}t.rect(a.x*e,a.y*i,a.width*e,a.height*i)}t.fill()}}function Vt(t){const e=Math.floor(t),i=Math.max(0,Math.min(1,(t-e-.2)/.6));return e+i*i*(3-2*i)}function Qt(t,e={},i={}){const s=t.getContext("2d");if(!s)throw new Error("Canvas is already owned by another renderer.");const n=Ut(),h=Ut(!0),l=Ut(),c=Ut(),d=Ut(),m=Ut(),u=Ut(),g=Ut(),M=Ut(),x=Ut();let v,y=0,b=0,k=1,S=qt,A=null,E=null,F=null,P="",C=q(e),R=0,O="",D="",L="",j=new Uint8ClampedArray(0),U=new Uint8ClampedArray(0),X=null,z="",Y=0,G=0,W=0,V=null,Q="",Z=new Nt,_=null,$=new Float32Array(0);const tt=Ut(!0),et=Ut(),it=Ut();let st=0;const rt=[0,0,0],ht=[0,0,0,1],dt=[0,0,0,0];let mt=J(C.color),xt=at(C.print);const vt=new K(C.color.denoise),yt=new T(C.warps,C.warpEdge),wt=Math.max(64,Math.min(4096,Number.isFinite(i.maxDimension)?i.maxDimension:960)),bt=Math.max(256,Math.min(1048576,Number.isFinite(i.maxCells)?i.maxCells:12e3));let kt=bt,St=Math.max(.1,Math.min(8,i.pixelRatio??1));return{canvas:t,render:function(e,i=0,T=960,q=540,J=i*C.motion.speed){if(Number.isFinite(i)||(i=0),!Number.isFinite(T)||!Number.isFinite(q)||T<1||q<1)throw new Error("Render dimensions must be positive finite numbers.");const[K,at]=jt(e);if(!K||!at)return;const bt=Math.min(1,wt/Math.max(T,q)),At=Math.max(2,Math.round(T*bt)),Et=Math.max(2,Math.round(q*bt));Xt(t,At,Et),Xt(n.canvas,At,Et),Xt(l.canvas,At,Et),Xt(c.canvas,At,Et),Xt(d.canvas,At,Et),st!==At/Et&&(st=At/Et,Z=new Nt(st),Z.setGuide(_)),Z.configure(C.hover.effect,C.hover.strength,C.hover.radius,C.hover.edgeSafe,C.hover.decay),Z.step(Math.max(0,Math.min(.05,i-W))),W=i;const Ft="currentTime"in e?e.getVideoPlaybackQuality?.().totalVideoFrames??e.currentTime:0,Tt=[R,At,Et,Ft].join(":"),Pt="dither"===C.style,It=H(At,Et,C,kt,St),Ct=It.cell,Rt=It.rowHeight,Ot=It.columns,Ut=It.rows;if(O!==Tt||V!==e||Y!==Ot||G!==Ut){V=e,O=Tt,D="",L="",Y=Ot,G=Ut,n.ctx.clearRect(0,0,At,Et),n.ctx.save();const t=B(K,at,At,Et,C.crop);n.ctx.translate(t.x+t.width/2,t.y+t.height/2),n.ctx.rotate(C.crop.rotation*Math.PI/180),n.ctx.drawImage(e,-K*t.scale/2,-at*t.scale/2,K*t.scale,at*t.scale),n.ctx.restore(),Xt(h.canvas,Y,G),h.ctx.clearRect(0,0,Y,G),h.ctx.drawImage(n.canvas,0,0,Y,G),j=h.ctx.getImageData(0,0,Y,G).data,vt.apply(j,Y,G);const i=C.color;for(let t=0;t<j.length;t+=4){const e=.299*j[t]+.587*j[t+1]+.114*j[t+2];for(let s=0;s<3;s++){const a=e+(j[t+s]-e)*i.saturation;j[t+s]=((a*(1-i.grayscale)+e*i.grayscale)/255-.5)*i.contrast*255+127.5+255*i.brightness}}if(mt&&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]])}(j,mt),j=yt.apply(j,Y,G,At/Et),"none"!==C.color.levels){const[t,i]=Bt(j),s=Gt(j,t,i),a=A===e&&"currentTime"in e?.15:1;A=e,b+=(t-b)*a,k+=(i-k)*a,S+=(s-S)*a}const s=C.hover,a=s.scope??"all";if("none"===s.effect||"all"===a&&"tilt"!==s.effect)_=null;else{let t=null;if(C.mask.enabled&&C.mask.shapes.length){Xt(tt.canvas,Y,G),tt.ctx.clearRect(0,0,Y,G),Ht(tt.ctx,Y,G,C.mask.shapes);const e=tt.ctx.getImageData(0,0,Y,G).data;t=new Float32Array(Y*G);for(let i=0;i<t.length;i++)t[i]=C.mask.invert?1-e[4*i+3]/255:e[4*i+3]/255}_=r(j,Y,G,t,_),$.length!==Y*G&&($=new Float32Array(Y*G));for(let t=0;t<$.length;t++)$[t]=o(a,_.subject[t],_.key);if("reveal"===s.effect){Xt(et.canvas,Y,G);const t=new ImageData(Y,G);for(let e=0;e<$.length;e++)t.data[4*e+3]=255*$[e];et.ctx.putImageData(t,0,0)}}Z.setGuide(_)}const Yt=nt(C),qt=ot(C),Qt=!Z.active&&!Yt&&!qt,Jt=[Tt,Y,G,Ct,Rt,St,Z.signature].join(":"),Kt=Z.engaged,Zt=Z.effect;if(!Qt||L!==Jt){l.ctx.clearRect(0,0,At,Et),l.ctx.globalAlpha=1,l.ctx.globalCompositeOperation="source-over";const t=J,e=Yt?C.motion.type:"none",s=C.motion.amount??1,o=["relight","sheen","glow","shimmer","mist"].includes(e);if("none"!==e&&z!==O&&(X=function(t,e,i,s){const o=e*i,n=s?.length===8*o?s:new Float32Array(8*o);if(!o)return n;const h=Math.min(e,i),l=new Float32Array(o),c=new Float32Array(o),d=new Float32Array(o),m=new Float32Array(o),u=new Float32Array(o),f=new Float32Array(o),p=new Float32Array(o);for(let e=0;e<o;e++){const i=t[4*e+3]/255;l[e]=(.299*t[4*e]+.587*t[4*e+1]+.114*t[4*e+2])/255*i}c.set(l),a(c,p,e,i,Math.max(1,Math.round(.012*h))),d.set(l),a(d,p,e,i,Math.max(1,Math.round(.03*h)));for(let t=0;t<o;t++){m[t]=Math.abs(l[t]-c[t]);const e=Math.max(0,l[t]-.55)/.45;u[t]=e*e}a(m,p,e,i,Math.max(1,Math.round(.02*h)));const g=1/Math.max(.02,ct(m,.95));a(u,p,e,i,Math.max(1,Math.round(.05*h)));const M=1/Math.max(.03,ct(u,.98)),x=r(t,e,i);let v=0,y=0,w=0;for(let t=0;t<i;t++)for(let s=0;s<e;s++){const a=t*e+s,r=(s+.5)/e,o=(t+.5)/i,n=.55*Math.min(1,m[a]*g)+.3*(1-Math.min(1,1.6*Math.hypot(1.3*(r-.5),o-.55)))+.15*lt(.2,1,o);f[a]="none"===x.key?n:.75*x.subject[a]+.25*n;const h=f[a]*f[a]*(.25+l[a]);v+=r*h,y+=o*h,w+=h}a(f,p,e,i,Math.max(1,Math.round(.06*h)));const b=ct(f,.05),k=ct(f,.95),S=Math.max(.05,k-b);v=w>0?Math.max(.3,Math.min(.7,v/w)):.5,y=w>0?Math.max(.3,Math.min(.7,y/w)):.5;const A=1/Math.max(.004,ct((()=>{const t=new Float32Array(o);for(let s=0;s<i;s++)for(let a=0;a<e;a++)t[s*e+a]=Math.hypot(d[s*e+Math.min(e-1,a+1)]-d[s*e+Math.max(0,a-1)],d[Math.min(i-1,s+1)*e+a]-d[Math.max(0,s-1)*e+a]);return t})(),.97));for(let t=0;t<i;t++)for(let s=0;s<e;s++){const a=t*e+s,r=8*a,o=(d[t*e+Math.min(e-1,s+1)]-d[t*e+Math.max(0,s-1)])*A,h=(d[Math.min(i-1,t+1)*e+s]-d[Math.max(0,t-1)*e+s])*A;n[r]=d[a],n[r+1]=Math.max(0,Math.min(1,(f[a]-b)/S)),n[r+2]=Math.min(1,u[a]*M),n[r+3]=Math.min(1,m[a]*g),n[r+4]=Math.max(-1,Math.min(1,-o)),n[r+5]=Math.max(-1,Math.min(1,-h)),n[r+6]=v,n[r+7]=y}return n}(j,Y,G,X),z=O),Pt){const a=Qt;if(!a||D!==Tt){U.length!==j.length&&(U=new Uint8ClampedArray(j.length));const r=U;if(r.set(j),Kt||"none"!==e)for(let i=0;i<G;i++)for(let a=0;a<Y;a++){const o=a/Y,n=i/G;let h=a,l=i,c=0,d=0,m=1;if(Kt){Z.sample(o,n,rt);const t=_?$[i*Y+a]:1;h-=rt[0]*t*Y,l-=rt[1]*t*G,"reveal"===Zt?m=1-.72*Math.min(1,rt[2]*t):"repel"===Zt?m=1+Math.max(-1,rt[2])*t:c=rt[2]/3*t}const u=4*(i*Y+a);f(e,o,n,t,ht,(.299*j[u]+.587*j[u+1]+.114*j[u+2])/255,X??void 0,8*(i*Y+a)),p(ht,s),(ht[0]||ht[1])&&(h=Vt(h-ht[0]/960*Y),l=Vt(l-ht[1]/960*G)),d=ht[2],m*=ht[3];const g=4*(i*Y+a);w(j,Y,G,h,l,dt);for(let t=0;t<3;t++){let e=Dt(Zt,dt[t]/255,c)+d;r[g+t]=255*e}r[g+3]=dt[3]*m}!function(t,e,i,s,a=0){const{algorithm:r,amount:o,threshold:n}=s,h="blue-noise"===r,l=r.startsWith("bayer")?Number(r.slice(5)):0,c=pt.get(l),d=l-1,m="luminance"===s.colorSpace,u=("custom"===s.palette?s.colors:N[s.palette]??N.mono).map(Mt),f=gt[r],p=f?new Float32Array(3*e*3):null,g="drift"===s.motion?a*s.speed*3:0,M=(s.direction??45)*Math.PI/180,x=Math.round(Math.cos(M)*g),v=Math.round(Math.sin(M)*g),y=(t,e)=>(t%e+e)%e,w=u.map(t=>.299*t[0]+.587*t[1]+.114*t[2]),b="shimmer"===s.motion?.15*Math.sin(a*s.speed*2):0;for(let s=0;s<i;s++)for(let a=0;a<e;a++){const M=4*(s*e+a),k=3*(s%3*e+a);if(0===t[M+3]){p&&(p[k]=p[k+1]=p[k+2]=0);continue}let S=0;const A=h?(ut[64*(s-v&63)+(a-x&63)]+.5)/ut.length:0;c?S=c[(s-v&d)*l+(a-x&d)]:"noise"===r?S=ft(a-x,s-v)-.5:"lines"===r?S=y(s-v,4)/3-.5:"vertical-lines"===r?S=y(a-x,4)/3-.5:"diagonal-lines"===r?S=y(a-x+s-v,4)/3-.5:"radial"===r?S=y(Math.hypot(a-e/2,s-i/2)-g,6)/6-.5:"halftone"===r&&(S=Math.hypot(y(a-x,6)-2.5,y(s-v,6)-2.5)/3.54-.5);const E=128*(S*o+b+(.5-n)),F=t[M]+E+(p?.[k]??0),T=t[M+1]+E+(p?.[k+1]??0),P=t[M+2]+E+(p?.[k+2]??0);let I=0,C=0,R=0;if(u.length){let t=1/0,e=1/0,i=0,s=0;const a=.299*F+.587*T+.114*P;for(let r=0;r<u.length;r++){const o=u[r],n=m?(a-w[r])**2:(F-o[0])**2*.299+(T-o[1])**2*.587+(P-o[2])**2*.114;n<t?(h&&(e=t,s=i,i=r),t=n,[I,C,R]=o):h&&n<e&&(e=n,s=r)}if(h&&o>0&&Number.isFinite(e)){const t=u[s],e=t[0]-I,r=t[1]-C,n=t[2]-R,h=w[s]-w[i],l=m?h*h:e*e*.299+r*r*.587+n*n*.114,c=m?(a-w[i])*h:(F-I)*e*.299+(T-C)*r*.587+(P-R)*n*.114;A<(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+(A-.5)*o));I=51*Math.floor(F/51+1-t),C=51*Math.floor(T/51+1-t),R=51*Math.floor(P/51+1-t)}else I=51*Math.round(F/51),C=51*Math.round(T/51),R=51*Math.round(P/51);if(t[M]=I,t[M+1]=C,t[M+2]=R,p&&f){p[k]=p[k+1]=p[k+2]=0;for(const[t,r,n]of f){const h=a+t;if(h<0||h>=e||s+r>=i)continue;const l=3*((s+r)%3*e+h);p[l]+=(F-I)*n*o,p[l+1]+=(T-C)*n*o,p[l+2]+=(P-R)*n*o}}}}(r,Y,G,C.dither,i),h.ctx.putImageData(new ImageData(r,Y,G),0,0),D=a?Tt:""}l.ctx.imageSmoothingEnabled=!1,l.ctx.drawImage(h.canvas,0,0,At,Et)}else{const i=Array.from(zt[C.style]??C.charset),a=l.ctx,r=Mt(C.ink),n="ascii"===C.style||!!zt[C.style],h=I(C.style)?C.style:null,c=Math.max(3,Math.round(.92*Rt)),d=Math.ceil(Ct+4),m=Math.ceil(Rt+4),g=[i.join(""),c,d,m,C.ink,C.colorMode].join(":");if(n&&g!==Q){Q=g,Xt(u.canvas,d*i.length,m),u.ctx.clearRect(0,0,u.canvas.width,m),u.ctx.font=`${c}px monospace`,u.ctx.textBaseline="middle",u.ctx.textAlign="center",u.ctx.fillStyle="accent"===C.colorMode?C.ink:"#ffffff",i.forEach((t,e)=>u.ctx.fillText(t,e*d+d/2,m/2)),E=null,P="";try{const t=u.ctx.getImageData(0,0,u.canvas.width,u.canvas.height).data;E=i.map((e,i)=>{let s=0;for(let e=0;e<u.canvas.height;e++)for(let a=i*d;a<(i+1)*d&&a<u.canvas.width;a++)s+=t[4*(e*u.canvas.width+a)+3];return s})}catch{E=null}}const M=n&&"none"!==C.color.levels;if(M&&E){const t=Q+":"+S.toFixed(2);t!==P&&(P=t,F=Wt(E,S))}const v=Math.max(.001,k-b);if("lego"===C.style&&y!==Ct){y=Ct,Xt(x.canvas,Math.ceil(Ct),Math.ceil(Rt));const t=x.ctx;t.clearRect(0,0,x.canvas.width,x.canvas.height),t.fillStyle="rgba(255,255,255,.2)",t.strokeStyle="rgba(0,0,0,.25)",t.lineWidth=Math.max(.5,.6*St),t.beginPath(),t.arc(Ct/2,Rt/2,.28*Ct,0,2*Math.PI),t.fill(),t.stroke()}a.font=`${c}px monospace`,a.textBaseline="middle",a.textAlign="center";for(let l=0;l<G;l++)for(let c=0;c<Y;c++){let g=c,y=l,k=0,A=0;if(Kt){Z.sample(c/Y,l/G,rt);const t=_?$[l*Y+c]:1;g=Math.max(0,Math.min(Y-1,c-rt[0]*t*Y)),y=Math.max(0,Math.min(G-1,l-rt[1]*t*G)),"reveal"===Zt?A=.72*Math.min(1,rt[2]*t):"repel"===Zt?A=-Math.max(-1,rt[2])*t:k=rt[2]/3*t}if("none"!==e){const i=4*(l*Y+c);f(e,c/Y,l/G,t,ht,(.299*j[i]+.587*j[i+1]+.114*j[i+2])/255,X??void 0,8*(l*Y+c)),p(ht,s),(ht[0]||ht[1])&&(g=Vt(Math.max(0,Math.min(Y-1,g-ht[0]/960*Y))),y=Vt(Math.max(0,Math.min(G-1,y-ht[1]/960*G))))}if(w(j,Y,G,g,y,dt),!dt[3]){if(!(k>.03&&"outside"===C.hover.scope&&Lt(Zt)))continue;dt[0]=r[0],dt[1]=r[1],dt[2]=r[2],dt[3]=Math.min(255,640*k)}const E=dt[0],T=dt[1],P=dt[2],I=(.299*E+.587*T+.114*P)/255;let R=M?Math.max(0,Math.min(1,(I-b)/v)):I;R=Dt(Zt,R,k,!!h&&xt.settings.invert);const O=c*Ct,D=l*Rt;let L=1,N=R;if("none"!==e){const t=ht[2]/(M?Math.max(.5,v):1);R=Math.max(0,Math.min(1,R+t)),N=Math.max(0,Math.min(1,N+t*(o?.45:1)))}else N=R;L=("none"!==e?ht[3]:1)*dt[3]/255*(1-A),n||h||"accent"!==C.colorMode||"cmyk"===C.style?M&&"accent"===C.colorMode&&(L*=.32+.68*Math.pow(R,S)):L*=R,a.globalAlpha=L;const U=255*(R-I),z="source"===C.colorMode?`rgb(${E+U},${T+U},${P+U})`:"gray"===C.colorMode?`rgb(${Math.round(255*R)},${Math.round(255*R)},${Math.round(255*R)})`:C.ink;if(a.fillStyle=z,h)xt.paint(a,h,c,l,O,D,Ct,R,z,"gray"===C.colorMode?255*R:E+U,"gray"===C.colorMode?255*R:T+U,"gray"===C.colorMode?255*R:P+U,C.colorMode);else if(n){const t=M&&F?F[Math.round(255*N)]:Math.max(0,Math.min(i.length-1,Math.round(N*(i.length-1))));"accent"===C.colorMode?a.drawImage(u.canvas,t*d,0,d,m,Math.round(O+(Ct-d)/2),Math.round(D+(Rt-m)/2),d,m):a.fillText(i[t],O+Ct/2,D+Rt/2)}else if("dots"===C.style)a.beginPath(),a.arc(O+Ct/2,D+Rt/2,.48*Ct*Math.sqrt(R),0,2*Math.PI),a.fill();else if("led"===C.style)a.beginPath(),a.arc(O+Ct/2,D+Rt/2,.39*Ct,0,2*Math.PI),a.fill(),a.globalAlpha=.35*L,a.fillStyle="#ffffff",a.beginPath(),a.arc(O+.43*Ct,D+.4*Rt,.11*Ct,0,2*Math.PI),a.fill();else if("hex"===C.style){const t=O+Ct/2,e=D+Rt/2;a.beginPath();for(let i=0;i<6;i++){const s=Math.PI/3*i,r=t+Math.cos(s)*Ct*.49,o=e+Math.sin(s)*Rt*.49;0===i?a.moveTo(r,o):a.lineTo(r,o)}a.closePath(),a.fill()}else if("cmyk"===C.style){a.fillStyle="#ffffff",a.fillRect(O,D,Ct,Rt);const t=(t,e)=>Math.max(0,Math.min(255,"source"===C.colorMode?t+U:"gray"===C.colorMode?255*R:e*R)),e=t(E,r[0]),i=t(T,r[1]),s=t(P,r[2]),o=1-Math.max(e,i,s)/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-s/255-o)/n,.5,.66],["#000000",o,.5,.5]];a.globalCompositeOperation="multiply";for(const[t,e,i,s]of h)a.fillStyle=t,a.beginPath(),a.arc(O+Ct*i,D+Rt*s,.48*Ct*Math.sqrt(Math.max(0,e)),0,2*Math.PI),a.fill();a.globalCompositeOperation="source-over"}else if("voxel"===C.style){const t=O+Ct/2,e=D+Rt/2;a.beginPath(),a.moveTo(t,D),a.lineTo(O+Ct,D+.25*Rt),a.lineTo(t,e),a.lineTo(O,D+.25*Rt),a.closePath(),a.fill(),a.globalAlpha=.72*L,a.beginPath(),a.moveTo(O,D+.25*Rt),a.lineTo(t,e),a.lineTo(t,D+Rt),a.lineTo(O,D+.75*Rt),a.closePath(),a.fill(),a.globalAlpha=.42*L,a.beginPath(),a.moveTo(t,e),a.lineTo(O+Ct,D+.25*Rt),a.lineTo(O+Ct,D+.75*Rt),a.lineTo(t,D+Rt),a.closePath(),a.fill()}else{const t="pixel"===C.style?0:Math.max(.5,.06*Ct);a.fillRect(O,D,Ct-t,Rt-t),"lego"===C.style&&a.drawImage(x.canvas,O,D),"disco"===C.style&&(a.fillStyle=`rgba(255,255,255,${.1+.25*ft(c,l)})`,a.fillRect(O,D,Ct-t,.35*Rt),a.fillStyle="rgba(0,0,0,.25)",a.fillRect(O,D+.65*Rt,Ct-t,.35*Rt-t))}}}l.ctx.globalAlpha=1,(C.color.amount||C.lights.length)&&(Xt(g.canvas,At,Et),g.ctx.clearRect(0,0,At,Et),g.ctx.drawImage(l.canvas,0,0)),C.color.amount&&(l.ctx.save(),l.ctx.globalCompositeOperation=C.color.blend,l.ctx.globalAlpha=C.color.amount,l.ctx.fillStyle=C.color.tint,l.ctx.fillRect(0,0,At,Et),l.ctx.restore());for(const t of C.lights){const e=t.radius*Math.max(At,Et),i=l.ctx.createRadialGradient(t.x*At,t.y*Et,0,t.x*At,t.y*Et,e);i.addColorStop(0,t.color),i.addColorStop(1,"transparent"),l.ctx.save(),l.ctx.globalCompositeOperation="screen",l.ctx.globalAlpha=t.intensity,l.ctx.fillStyle=i,l.ctx.fillRect(0,0,At,Et),l.ctx.restore()}(C.color.amount||C.lights.length)&&(l.ctx.globalCompositeOperation="destination-in",l.ctx.drawImage(g.canvas,0,0),l.ctx.globalCompositeOperation="source-over"),C.mask.enabled&&C.mask.shapes.length&&(Ht(d.ctx,At,Et,C.mask.shapes),l.ctx.globalCompositeOperation=C.mask.invert?"destination-out":"destination-in",l.ctx.drawImage(d.canvas,0,0),l.ctx.globalCompositeOperation="source-over");const v=c.ctx;v.clearRect(0,0,At,Et),v.globalAlpha=C.backdrop.opacity;const A=C.backdrop;if("solid"===A.mode&&(v.fillStyle=A.color,v.fillRect(0,0,At,Et)),"gradient"===A.mode){const t=v.createLinearGradient(0,0,At,Et);t.addColorStop(0,A.color),t.addColorStop(1,A.color2),v.fillStyle=t,v.fillRect(0,0,At,Et)}if("source"===A.mode&&v.drawImage(n.canvas,0,0),"blurred"===A.mode){const t=Math.max(1,A.blur);Xt(m.canvas,Math.max(2,Math.round(At/t)),Math.max(2,Math.round(Et/t))),m.ctx.drawImage(n.canvas,0,0,m.canvas.width,m.canvas.height),v.imageSmoothingEnabled=!0,v.drawImage(m.canvas,0,0,At,Et)}v.globalAlpha=1,C.effects.characterBloom>0&&(Xt(M.canvas,Math.max(2,Math.round(At/3)),Math.max(2,Math.round(Et/3))),M.ctx.clearRect(0,0,M.canvas.width,M.canvas.height),M.ctx.drawImage(l.canvas,0,0,M.canvas.width,M.canvas.height),v.save(),v.globalAlpha=.8*C.effects.characterBloom,v.globalCompositeOperation="screen",v.filter=`blur(${1+4*C.effects.characterBloom}px)`,v.drawImage(M.canvas,0,0,At,Et),v.restore());const T=Z.spotlight;if(T&&T[2]>.002){Xt(it.canvas,At,Et);const t=it.ctx,e=T[3]*Math.min(At,Et)*1.6;t.globalCompositeOperation="source-over",t.clearRect(0,0,At,Et),t.drawImage(n.canvas,0,0),t.globalCompositeOperation="destination-in";const i=t.createRadialGradient(T[0]*At,T[1]*Et,0,T[0]*At,T[1]*Et,e),s=Math.min(1,T[2]*C.hover.strength/.55);for(const t of[0,.2,.4,.6,.8,1])i.addColorStop(t,`rgba(0,0,0,${s*Math.exp(-2.4*(1.6*t)**2)*(1-t)})`);t.fillStyle=i,t.fillRect(0,0,At,Et),_&&"all"!==(C.hover.scope??"all")&&(t.imageSmoothingEnabled=!0,t.drawImage(et.canvas,0,0,At,Et)),t.globalCompositeOperation="source-over",v.drawImage(it.canvas,0,0)}v.drawImage(l.canvas,0,0),L=Qt?Jt:""}const _t=Object.entries(C.effects).some(([t,e])=>!["angle","focus","blurType","characterBloom"].includes(t)&&"number"==typeof e&&e>0);s.clearRect(0,0,At,Et),_t?(void 0===v&&(v=function(){const t=document.createElement("canvas"),e=t.getContext("webgl",{alpha:!0,premultipliedAlpha:!1,antialias:!1,preserveDrawingBuffer:!0});if(!e)return null;const i=[],s=(t,s)=>{const a=e.createShader(t);if(i.push(a),e.shaderSource(a,s),e.compileShader(a),!e.getShaderParameter(a,e.COMPILE_STATUS))throw new Error(e.getShaderInfoLog(a)||"Finish shader failed");return a},a=e.createProgram();if(e.attachShader(a,s(e.VERTEX_SHADER,"attribute vec2 p;varying vec2 uv;void main(){uv=(p+1.)*.5;gl_Position=vec4(p,0.,1.);}")),e.attachShader(a,s(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.);\n // Bloom: a wide golden-angle disc of soft-kneed highlights, screened on, so light spills like halation instead of ghosting glyphs.\n if(bloom>0.){float total=0.;for(int i=0;i<16;i++){float f=float(i);vec2 o=vec2(cos(f*2.39996),sin(f*2.39996))*(2.+f*1.6)/size;vec3 s=sampleAt(q+o).rgb;float w=1./(1.+f*.18);light+=s*smoothstep(.35,.9,max(s.r,max(s.g,s.b)))*w;total+=w;}light*=bloom*3.2/total;}\n vec3 col=1.-(1.-blurred.rgb)*(1.-min(light,vec3(1.)));\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 // Film grain: soft triangular noise, strongest in the midtones, quiet in deep shadow and paper-white highlights.\n float luma=dot(col,vec3(.299,.587,.114));vec2 g=floor(q*size/1.25)+floor(t*24.)*vec2(7.,13.);\n col+=(hash(g)+hash(g+31.7)-1.)*grain*.17*(.2+3.2*luma*(1.-luma));\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(a),!e.getProgramParameter(a,e.LINK_STATUS))throw new Error("Finish link failed");e.useProgram(a);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(a,"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(a,t)])),c=e.getUniformLocation(a,"size");return{canvas:t,render(i,s,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(a),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(s.blurType):"angle"===t?s.angle*Math.PI/180:s[t]??0);return e.drawArrays(e.TRIANGLE_STRIP,0,4),t},destroy(){e.deleteTexture(n),e.deleteBuffer(r),e.deleteProgram(a),i.forEach(t=>e.deleteShader(t)),t.width=t.height=1,e.getExtension("WEBGL_lose_context")?.loseContext()}}}()),v?s.drawImage(v.render(c.canvas,C.effects,i,St),0,0):s.drawImage(c.canvas,0,0),t.dataset.studioFinish=v?"gpu":"unavailable"):(s.drawImage(c.canvas,0,0),t.dataset.studioFinish="none")},setPixelRatio(t){St=Math.max(.1,Math.min(8,Number.isFinite(t)?t:1))},get pixelRatio(){return St},setBudget(t){kt=Math.max(256,Math.min(bt,Number.isFinite(t)?Math.round(t):bt))},get maxCells(){return kt},configure(t){C=q(t),mt=J(C.color),xt=at(C.print),vt.configure(C.color.denoise),yt.configure(C.warps,C.warpEdge),R++},pointer:(t,e,i)=>{Z.configure(C.hover.effect,C.hover.strength,C.hover.radius,C.hover.edgeSafe,C.hover.decay),Z.move(t,e,i)},leave(){Z.leave()},get active(){return Z.active},get settings(){return q(C)},get capabilities(){return{gpuFinish:null!==v}},invalidate(){O=""},destroy(){v?.destroy(),yt.clear(),vt.configure(0);for(const t of[n,h,l,c,d,m,u,g,M,x,tt,et,it])t.canvas.width=t.canvas.height=1;V=null,j=new Uint8ClampedArray(0),U=new Uint8ClampedArray(0),X=null,z=""}}}function Jt(t,e,i){return new Promise((s,a)=>{const r=()=>{l(),s()},o=()=>{l(),a(new Error("Unable to load this media. Check its format and cross-origin permissions."))},n=()=>{l(),a(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 Kt(t,e){if("string"==typeof t&&t.startsWith("blob:")){const i=await fetch(t,{signal:e}),s=await i.blob();return Kt(new File([s],"Imported media",{type:s.type}),e)}const i="string"!=typeof t,s=i?t.name:t;if(i?"image/gif"===t.type:/\.gif(?:[?#]|$)/i.test(s)){const s=await import("gifuct-js"),{parseGIF:a,decompressFrames:r}="function"==typeof s.parseGIF?s:s.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=a(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 m=document.createElement("canvas");m.width=h,m.height=l;const u=m.getContext("2d"),f=document.createElement("canvas"),p=f.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,s=0;for(;s<d.length-1&&(i+=Math.max(20,d[s].delay),!(e<i));s++);s<M&&(u.clearRect(0,0,h,l),M=-1,x=null);for(let t=M+1;t<=s;t++){const e=d[t-1];2===e?.disposalType&&u.clearRect(e.dims.left,e.dims.top,e.dims.width,e.dims.height),3===e?.disposalType&&x&&u.putImageData(x,0,0);const i=d[t];x=3===i.disposalType?u.getImageData(0,0,h,l):null,f.width=i.dims.width,f.height=i.dims.height,p.putImageData(new ImageData(new Uint8ClampedArray(i.patch),f.width,f.height),0,0),u.drawImage(f,i.dims.left,i.dims.top)}return M=s,m};return v(0),{source:m,width:h,height:l,duration:g,animated:!0,seek:async()=>{},frame:v,destroy(){m.width=f.width=1,d.length=0,x=null}}}const a=i?t.type.startsWith("video/"):/\.(mp4|webm|mov)(?:[?#]|$)/i.test(s),r=i?URL.createObjectURL(t):t,o=a?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=Jt(o,a?"loadeddata":"load",e);o.src=r,await t;const i=o instanceof HTMLVideoElement?o.videoWidth:o.naturalWidth,s=o instanceof HTMLVideoElement?o.videoHeight:o.naturalHeight;return{source:o,width:i,height:s,duration:o instanceof HTMLVideoElement?o.duration:0,animated:a,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 s=Jt(o,"seeked",e);o.currentTime=i,await s},frame:()=>o,destroy:n}}catch(t){throw n(),t}}var Zt=t=>{if(t?.aborted)throw new DOMException("Export cancelled","AbortError")};async function _t(t,e){const{format:i,signal:s}=e,a=Math.round(e.width),r=Math.round(e.height);if(!Number.isFinite(a)||!Number.isFinite(r)||a<2||r<2||a>4096||r>4096||a*r>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&&a*r>8294400)throw new Error("Video exports support up to 3840 × 2160 pixels.");if("gif"===i&&(a*r>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(Zt(s),e.onProgress?.(0),h){if(await t(c,l,a,r,s,e.motionTime),"unavailable"===c.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");Zt(s);const o=await new Promise((t,s)=>c.toBlob(e=>e?t(e):s(new Error("Image export failed.")),"png"===i?"image/png":"image/jpeg",e.quality??.92));return Zt(s),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,u=h(),f=c.getContext("2d");for(let i=0;i<m;i++){Zt(s);const h=i/o;if(await t(c,h,a,r,s),Zt(s),"unavailable"===c.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");const p=f.getImageData(0,0,a,r).data,g=l(p,256),M=d(p,g);u.writeFrame(M,a,r,{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 Zt(s),u.finish(),e.onProgress?.(1),new Blob([new Uint8Array(u.bytes())],{type:"image/gif"})}const{Output:u,Mp4OutputFormat:f,WebMOutputFormat:p,BufferTarget:g,CanvasSource:M,canEncodeVideo:x}=await import("mediabunny"),v="mp4"===i?"avc":"vp9";if(!await x(v,{width:a,height:r}))throw new Error(`${i.toUpperCase()} encoding is unavailable in this browser. Try another format or a current browser with WebCodecs.`);const y=new u({format:"mp4"===i?new f({fastStart:"in-memory"}):new p,target:new g});c.width=a,c.height=r,d=()=>y.cancel();const w=new M(c,{codec:v,bitrate:Math.max(5e5,Math.round(a*r*o*.15))});y.addVideoTrack(w,{frameRate:o}),c.width=a,c.height=r,await y.start();for(let i=0;i<m;i++){Zt(s);const h=i/o;if(await t(c,h,a,r,s),Zt(s),"unavailable"===c.dataset.studioFinish)throw new Error("Optical effects need WebGL. Disable these effects or export in a supported browser.");await w.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 w.close(),Zt(s),await y.finalize(),Zt(s),d=void 0,e.onProgress?.(1),new Blob([y.target.buffer],{type:"mp4"===i?"video/mp4":"video/webm"})}catch(t){throw await(d?.().catch(()=>{})),t}finally{c.width=c.height=1}}function $t(t,e,i={}){let s=q(i.settings),a=i.width??e.width,r=i.height??e.height;const o=Qt(t,s,i),n=new u;let h=0,l=!1,c=!0,d=!1,m=!0,f=0,p=0,g=0,M=0,x=-1,v=!1!==i.adaptive,y=0,w=0,b=0,k=0,S=o.maxCells;const A=matchMedia("(prefers-reduced-motion: reduce)"),E=e.source instanceof HTMLVideoElement?e.source:null,F=()=>{l||h||!m||document.hidden||(h=requestAnimationFrame(I))},T=()=>!d&&!A.matches&&m&&!document.hidden,P=()=>{E&&(E.loop=!0,T()?E.play().catch(()=>{d=!0,c=!0,F()}):E.pause()),g=0,c=!0,F()};function I(t){if(h=0,l||!m||document.hidden)return;const u=T();u&&(f+=g?Math.min(.1,(t-g)/1e3):0),g=t;const A=ht(s),P=u&&(e.animated||A),I=E?.getVideoPlaybackQuality?.().totalVideoFrames??-1,C=!E||I<0||I!==x;if(c||o.active||P&&(C||A)&&t-M>=1e3/Math.max(1,Math.min(60,i.fps??60))-.5){const h=performance.now();try{e.animated&&!E&&o.invalidate();const[t,l]=G(a,r,s);p=n.update(f,s.motion.type,s.motion.speed),o.render(e.frame(E?.currentTime??f),f,t,l,p);const c=performance.now()-h;if(i.onFrame?.(E?.currentTime??f,c),w=w?.9*w+.1*c:c,++y>20&&v&&(P||o.active)){const t=1e3/Math.max(1,Math.min(60,i.fps??60));b=w>1.1*t?b+1:0,k=w<.5*t?k+1:0,b>=20&&o.maxCells>3e3?(o.setBudget(Math.max(3e3,.8*o.maxCells)),i.onQualityChange?.(o.maxCells),b=0,w=0):k>=30&&o.maxCells<S&&(o.setBudget(Math.min(S,1.25*o.maxCells)),i.onQualityChange?.(o.maxCells),k=0,w=0)}}catch(t){d=!0,i.onError?.(t instanceof Error?t:new Error(String(t)))}c=!1,M=t,x=I}u&&(P||o.active)?F():P||o.active||o.maxCells>=S||(o.setBudget(S),i.onQualityChange?.(o.maxCells),b=k=w=y=0,0)||(c=!0,F())}const C=e=>{if(!T())return;const i=t.getBoundingClientRect();o.pointer((e.clientX-i.left)/i.width,(e.clientY-i.top)/i.height,e.timeStamp),F()},R=()=>{o.leave(),F()},O=t=>{"touch"===t.pointerType&&R()},D=new IntersectionObserver(([t])=>{m=t.isIntersecting,P()});D.observe(t),t.addEventListener("pointermove",C),t.addEventListener("pointerup",O),t.addEventListener("pointerleave",R),t.addEventListener("pointercancel",R),document.addEventListener("visibilitychange",P),A.addEventListener("change",P);const L=()=>{l||(l=!0,cancelAnimationFrame(h),D.disconnect(),t.removeEventListener("pointermove",C),t.removeEventListener("pointerup",O),t.removeEventListener("pointerleave",R),t.removeEventListener("pointercancel",R),document.removeEventListener("visibilitychange",P),A.removeEventListener("change",P),i.signal?.removeEventListener("abort",L),o.destroy(),e.destroy())};if(i.signal?.addEventListener("abort",L,{once:!0}),i.signal?.aborted)throw L(),new DOMException("Cancelled","AbortError");return P(),{canvas:t,media:e,update(t){s=W(s,t),o.configure(s),c=!0,F()},resize(t,e,i){void 0!==i&&o.setPixelRatio(i),a=Math.max(2,t),r=Math.max(2,e),c=!0,F()},pause(t=!0){d=t,P()},async seek(t){f=Math.max(0,t),await e.seek(f),o.invalidate(),c=!0,F()},redraw(){o.invalidate(),c=!0,F()},get time(){return E?.currentTime??f},get settings(){return q(s)},get motionTime(){return p},get paused(){return d||A.matches},setAdaptive(t){v=t,y=b=w=0},setBudget(t){o.setBudget(t),S=o.maxCells,b=k=w=y=0,i.onQualityChange?.(o.maxCells),c=!0,F()},get pixelRatio(){return o.pixelRatio},get maxCells(){return o.maxCells},get capabilities(){return o.capabilities},destroy:L}}var te={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")},ee=Object.keys(te);async function ie(t,e="Standard",i="#ffffff",s="#080808"){if(!Object.prototype.hasOwnProperty.call(te,e))throw new Error("Unknown text font.");const{default:a}=await import("figlet/browser"),r=await te[e]();a.parseFont(e,r.default),a.defaults({fetchFontIfMissing:!1});const o=a.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!==s&&(m.fillStyle=s,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 se={standard:{label:"Classic ASCII",chars:" .:-=+*#%@"},asciify:{label:"Asciify",chars:" .:-=+YCIFSA#@"},minimal:{label:"Minimal",chars:" .:+"},detailed:{label:"Detailed",chars:" .,:;-~=+*xX#%@"},letters:{label:"Letters",chars:" .liLTYCFSAWM"},technical:{label:"Technical",chars:" ._:;+/>=][{}*$#@"},blocks:{label:"Tonal blocks",chars:" ░▒▓█"},braille:{label:"Braille",chars:" ⠁⠃⠇⡇⣇⣧⣷⣿"}},ae=se,re=t=>t&&"object"==typeof t&&!Array.isArray(t)?t:{},oe=(t,e,i,s)=>"number"==typeof t&&Number.isFinite(t)?Math.max(i,Math.min(s,t)):e,ne=(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 he(t={}){const e=re(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 s=new Set;return{kind:"asciify-project",version:1,width:Math.round(oe(e.width,1280,2,4096)),height:Math.round(oe(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=re(t),a=re(i.placement),r=re(i.settings),o=re(r.backdrop),n=ne(i.id,"Layer id"),h=ne(i.source,"Source key");if(s.has(n))throw new Error(`Duplicate layer id: ${n}`);return s.add(n),{id:n,source:h,name:"string"==typeof i.name?i.name.slice(0,80):`Layer ${e+1}`,visible:!1!==i.visible,opacity:oe(i.opacity,1,0,1),blend:L.includes(i.blend)?i.blend:"source-over",placement:{x:oe(a.x,.5,-1,2),y:oe(a.y,.5,-1,2),width:oe(a.width,1,.01,2),height:oe(a.height,1,.01,2),rotation:oe(a.rotation,0,-180,180),flipX:!0===a.flipX,flipY:!0===a.flipY},settings:q({...r,backdrop:{mode:"transparent",...o}})}})}}function le(t,e,i){if(!t.layers.some(t=>t.id===e))throw new Error(`Unknown layer: ${e}`);return he({...t,layers:t.layers.map(t=>t.id!==e?t:{...t,...i,id:e,placement:{...t.placement,...i.placement},settings:W(t.settings,i.settings??{})})})}function ce(t,e,i,s,a){const r=t.placement,o=r.rotation*Math.PI/180,n=Math.cos(o),h=Math.sin(o),l=(e-r.x)*s,c=(i-r.y)*a,d=(l*n+c*h)/(r.width*s),m=(-l*h+c*n)/(r.height*a);return[.5+d*(r.flipX?-1:1),.5+m*(r.flipY?-1:1)]}function de(t){return t.layers.filter(e=>{if(!e.visible||e.opacity<=0)return!1;const i=e.placement,s=i.rotation*Math.PI/180,a=Math.abs(Math.cos(s)),r=Math.abs(Math.sin(s)),o=(a*i.width*t.width+r*i.height*t.height)/2,n=(r*i.width*t.width+a*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 me(t,e=24e3,i=4194304,s=t.width,a=t.height){const r=de(t),o=Math.round(oe(e,24e3,2048,1048576)),n=oe(i,4194304,65536,16777216),h=r.map(t=>t.placement.width*t.placement.height),l=h.reduce((t,e)=>t+e,0),c=o-256*r.length,d=r.map(t=>{const e=s*t.placement.width,i=a*t.placement.height,r=Math.min(1,4096/Math.max(e,i));return{width:Math.max(2,e*r),height:Math.max(2,i*r)}}),m=d.reduce((t,e)=>t+e.width*e.height,0);let u=0,f=0;return r.map((t,e)=>{const i=e===r.length-1?o-u:256+Math.floor(c*h[e]/l);u+=i;const s=d[e],a=e===r.length-1?n-f:4+Math.floor((n-4*r.length)*s.width*s.height/Math.max(1,m));f+=a;const p=Math.min(1,Math.sqrt(a/(s.width*s.height)));let g=Math.max(2,Math.floor(s.width*p)),M=Math.max(2,Math.floor(s.height*p));return g*M>a&&(g>=M?g=Math.max(2,Math.floor(a/M)):M=Math.max(2,Math.floor(a/g))),{id:t.id,maxCells:i,width:g,height:M}})}function ue(t,e={},i={}){const s=t.getContext("2d");if(!s)throw new Error("Project canvas is already owned by another renderer.");let a=he(e),r=!0,o=!1,n=new Map(a.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 u=new Map,f=()=>{if(o)throw new Error("Project renderer has been destroyed.")};return{canvas:t,render(e,o=0,p=a.width,g=a.height,M={}){if(f(),!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)),v=Math.max(2,Math.round(p*x)),y=Math.max(2,Math.round(g*x));t.width===v&&t.height===y||(t.width=v,t.height=y,r=!0);const w={...a,width:v,height:y},b=de(w);for(const t of b)if(!e.has(t.source))throw new Error(`Missing project source: ${t.source}`);const k=new Set(b.map(t=>t.id));for(const[t,e]of u)k.has(t)||(e.renderer.destroy(),u.delete(t),r=!0);m=me(w,c,i.maxRasterPixels,v,y);for(let t=0;t<b.length;t++){const i=b[t],s=m[t],a=e.get(i.source);if(!a)throw new Error(`Missing project source: ${i.source}`);let h=u.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:Qt(document.createElement("canvas"),i.settings,{maxDimension:4096,maxCells:l}),signature:c,dirty:!0,geometry:""},u.set(i.id,h));const f=d*s.width/(p*i.placement.width),g=`${s.width}:${s.height}:${s.maxCells}:${f}`;h.geometry!==g&&(h.renderer.setBudget(s.maxCells),h.renderer.setPixelRatio(f),h.geometry=g,h.dirty=!0);const x="currentTime"in a?a.getVideoPlaybackQuality?.().totalVideoFrames??a.currentTime:0;if(h.dirty||h.source!==a||h.stamp!==x||h.renderer.active||ht(i.settings)){const t=Object.prototype.hasOwnProperty.call(M,i.id)?M[i.id]:void 0;h.renderer.render(a,o,s.width,s.height,t),h.dirty=!1,h.source=a,h.stamp=x,r=!0}}if(!r)return!1;s.clearRect(0,0,v,y),s.globalCompositeOperation="source-over",s.globalAlpha=1,null!==a.background&&(s.fillStyle=a.background,s.fillRect(0,0,v,y));let S="none";for(const t of b){const e=u.get(t.id),i=t.placement;s.save(),s.globalAlpha=t.opacity,s.globalCompositeOperation=t.blend;try{s.translate(i.x*v,i.y*y),s.rotate(i.rotation*Math.PI/180),s.scale(i.flipX?-1:1,i.flipY?-1:1),s.drawImage(e.renderer.canvas,-i.width*v/2,-i.height*y/2,i.width*v,i.height*y)}finally{s.restore()}"unavailable"===e.renderer.canvas.dataset.studioFinish?S="unavailable":"unavailable"!==S&&"gpu"===e.renderer.canvas.dataset.studioFinish&&(S="gpu")}return s.globalAlpha=1,s.globalCompositeOperation="source-over",t.dataset.studioFinish=S,r=!1,!0},configure(t){f(),a=he(t),n=new Map(a.layers.map(t=>[t.id,JSON.stringify(t.settings)])),(()=>{const t=new Set(de(a).map(t=>t.id));for(const[e,i]of u)t.has(e)||(i.renderer.destroy(),u.delete(e))})(),r=!0},pointer(e,i,s){if(o||!Number.isFinite(e)||!Number.isFinite(i))return;if(e<0||e>1||i<0||i>1){for(const t of u.values())t.renderer.leave();return}let r=!1;for(const o of de({...a,width:t.width,height:t.height}).reverse()){const n=u.get(o.id);if(!n)continue;const[h,l]=ce(o,e,i,t.width,t.height);(!r||"all"===a.pointerMode)&&h>=0&&h<=1&&l>=0&&l<=1&&"none"!==o.settings.hover.effect&&o.settings.hover.strength>0?(n.renderer.pointer(h,l,s),r=!0):n.renderer.leave()}},leave(){for(const t of u.values())t.renderer.leave()},invalidate(t){f();for(const e of a.layers)if(void 0===t||t===e.source){const t=u.get(e.id);t&&(t.renderer.invalidate(),t.dirty=!0)}r=!0},setBudget(t){f(),c=Math.max(2048,Math.min(l,Number.isFinite(t)?Math.round(t):l)),r=!0},setPixelRatio(t){f(),d=Math.max(.1,Math.min(8,Number.isFinite(t)?t:1)),r=!0},get maxCells(){return c},get pixelRatio(){return d},get quality(){return m.map(t=>({...t}))},get active(){return[...u.values()].some(t=>t.renderer.active)},destroy(){if(!o){o=!0;for(const t of u.values())t.renderer.destroy();u.clear(),t.width=t.height=1}}}}function fe(t,e){for(const i of t.layers)if(!e.has(i.source))throw new Error(`Missing project source: ${i.source}`)}async function pe(t,e,i){const s=Object.entries(e),a=new Map;if(s.length>8)throw new Error("A project supports up to 8 media bindings.");fe(t,new Map(s));try{for(const[t,e]of s){if(i?.aborted)throw new DOMException("Cancelled","AbortError");if("string"==typeof e||"undefined"!=typeof File&&e instanceof File)a.set(t,await Kt(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:s}=await ie(i.text,i.font,i.ink??"#ffffff",null);a.set(t,{source:s,width:s.width,height:s.height,duration:0,animated:!1,frame:()=>s,seek:async()=>{},destroy:()=>{s.width=s.height=1}})}}}if(i?.aborted)throw new DOMException("Cancelled","AbortError");return a}catch(t){for(const t of a.values())t.destroy();throw t}}function ge(t,e,i,s={}){if((i=new Map(i)).size>8)throw new Error("A project supports up to 8 media bindings.");let a=he(e);if(fe(a,i),s.signal?.aborted)throw new DOMException("Cancelled","AbortError");const r=ue(t,a,s),o=matchMedia("(prefers-reduced-motion: reduce)"),n=[...new Set(i.values())],h=n.filter(t=>t.source instanceof HTMLVideoElement).map(t=>t.source),l=new Map;let c,d={},m=0,f=0,p=0,g=0,M=!0,x=!1,v=!0,y=!1,w=!1!==s.adaptive,b=0,k=0,S=0,A=0,E=a.width,F=a.height,T=0,P=!1,I=r.maxCells;const C=new WeakSet,R=Math.max(1,Math.min(60,Number.isFinite(s.fps)?s.fps:60)),O=()=>!y&&!x&&!P&&!o.matches&&v&&!document.hidden,D=()=>{y||g||!v||document.hidden||(g=requestAnimationFrame(U))},L=()=>new Set(de({...a,width:E,height:F}).map(t=>i.get(t.source).source)),N=()=>{const t=L();for(const e of h)e.loop=!0,O()&&t.has(e)?e.paused&&!C.has(e)&&(C.add(e),e.play().then(()=>{C.delete(e),O()&&L().has(e)||e.pause()}).catch(t=>{C.delete(e),y||(x=!0,N(),s.onError?.(t instanceof Error?t:new Error(String(t))),M=!0,D())})):e.pause()},j=()=>{f=0,M=!0,N(),D()};function U(t){if(g=0,y||!v||document.hidden)return;const e=O();e&&(m+=f?Math.min(.1,(t-f)/1e3):0),f=t;const o=de({...a,width:E,height:F}),n=o.some(t=>i.get(t.source).animated||ht(t.settings));if(M||e&&r.active||e&&n&&t-p>=1e3/R-.5){const a=performance.now();try{const t=new Map,h=new Set(o.map(t=>t.source));for(const s of h){const a=i.get(s);!a.animated||a.source instanceof HTMLVideoElement||!e||r.invalidate(s),t.set(s,a.frame(m))}d={};for(const t of o){let e=l.get(t.id);e||(e=new u,l.set(t.id,e)),d[t.id]=e.update(m,t.settings.motion.type,t.settings.motion.speed)}r.render(t,m,E,F,d);const c=performance.now()-a;if(s.onFrame?.(m,c),k=k?.9*k+.1*c:c,++b>20&&w&&e&&(n||r.active)){const t=1e3/R;S=k>1.1*t?S+1:0,A=k<.5*t?A+1:0,S>=20&&r.maxCells>2048?(r.setBudget(Math.max(2048,.8*r.maxCells)),s.onQualityChange?.(r.maxCells),k=S=0,M=!0):A>=30&&r.maxCells<I&&(r.setBudget(Math.min(I,1.25*r.maxCells)),s.onQualityChange?.(r.maxCells),k=A=0,M=!0)}}catch(t){x=!0,N(),s.onError?.(t instanceof Error?t:new Error(String(t)))}M=!1,p=t}e&&(n||r.active)?D():!n&&!r.active&&r.maxCells<I&&(r.setBudget(I),s.onQualityChange?.(r.maxCells),b=S=A=k=0,M=!0,D())}const X=e=>{if(!O())return;const i=t.getBoundingClientRect();i.width&&i.height&&(r.pointer((e.clientX-i.left)/i.width,(e.clientY-i.top)/i.height,e.timeStamp),D())},z=()=>{r.leave(),D()},Y=new IntersectionObserver(([t])=>{v=t.isIntersecting,j()});Y.observe(t),t.addEventListener("pointermove",X),t.addEventListener("pointerleave",z),t.addEventListener("pointercancel",z),document.addEventListener("visibilitychange",j),o.addEventListener("change",j);const q=()=>{if(!y){y=!0,T++,c?.abort(),cancelAnimationFrame(g),g=0,Y.disconnect(),t.removeEventListener("pointermove",X),t.removeEventListener("pointerleave",z),t.removeEventListener("pointercancel",z),document.removeEventListener("visibilitychange",j),o.removeEventListener("change",j),s.signal?.removeEventListener("abort",q),r.destroy();for(const t of n)t.destroy();l.clear()}};s.signal?.addEventListener("abort",q,{once:!0});const B=()=>{if(y)throw new Error("Project player has been destroyed.")},G=t=>{B();const e=he(t);fe(e,i),E===a.width&&F===a.height&&(E=e.width,F=e.height),a=e,r.configure(a);for(const t of l.keys())a.layers.some(e=>e.id===t)||l.delete(t);j()};return j(),{canvas:t,get project(){return he(a)},get time(){return m},get motionTimes(){return{...d}},get paused(){return x||o.matches},get maxCells(){return r.maxCells},get pixelRatio(){return r.pixelRatio},get quality(){return r.quality},update:G,updateLayer:(t,e)=>G(le(a,t,e)),resize(t,e,i){if(B(),!Number.isFinite(t)||!Number.isFinite(e)||t<2||e<2)throw new Error("Project dimensions must be positive finite numbers.");E=t,F=e,void 0!==i&&r.setPixelRatio(i),j()},pause(t=!0){B(),x=t,j()},async seek(t){if(B(),!Number.isFinite(t)||t<0)throw new Error("Project time must be finite and non-negative.");const e=++T;c?.abort(),c=new AbortController;const i=c.signal;P=!0,N();try{if(await Promise.all(n.map(e=>e.seek(t,i))),y||e!==T)return;m=t,l.clear(),r.invalidate()}finally{y||e!==T||(P=!1,j())}},redraw(){B(),r.invalidate(),M=!0,D()},setBudget(t){B(),r.setBudget(t),I=r.maxCells,b=S=A=k=0,s.onQualityChange?.(r.maxCells),M=!0,D()},setAdaptive(t){w=t,b=S=A=k=0},destroy:q}}exports.BLEND_MODES=L,exports.CHARACTER_SETS=se,exports.DEFAULT_STUDIO_PRINT=C,exports.DEFAULT_STUDIO_SETTINGS=j,exports.DEPRECATED_STUDIO_HOVERS=e,exports.DEPRECATED_STUDIO_MOTIONS=n,exports.DITHER_ALGORITHMS=D,exports.HOVER_SCOPES=[{value:"all",label:"Everywhere",description:"The hover acts on the whole artwork."},{value:"subject",label:"Subject",description:"The hover stays on the subject and fades softly at its edge."},{value:"outside",label:"Around",description:"The hover acts only on the ground around the subject."}],exports.MAX_STUDIO_LAYERS=8,exports.MAX_STUDIO_WARPS=8,exports.STUDIO_ANIMATION_PRESETS=[{id:"quiet-light",label:"Quiet light",description:"A key light circles the subject’s own relief, with a soft magnifying wake.",motion:{type:"relight",speed:.6,amount:.8},hover:{effect:"lens",radius:.45,strength:.5}},{id:"living-paper",label:"Memory",description:"A slow push toward the subject; the image leans toward your cursor.",motion:{type:"push",speed:.5,amount:.8},hover:{effect:"tilt",radius:.5,strength:.45}},{id:"silver-grain",label:"Silver light",description:"Sparse glints on bright detail, with a fluid character trail.",motion:{type:"shimmer",speed:.6,amount:.9},hover:{effect:"trail",radius:.35,strength:.55}},{id:"ripple-study",label:"Still water",description:"Smooth water and sky drift like a cinemagraph; your stroke sends out rings.",motion:{type:"current",speed:.6,amount:.8},hover:{effect:"ripple",radius:.45,strength:.7}},{id:"unfolding-print",label:"Darkroom",description:"The print develops from its highlights; your cursor dissolves a soft path.",motion:{type:"develop",speed:.7,amount:1},hover:{effect:"dissolve",radius:.35,strength:.55}},{id:"silk-flow",label:"Morning mist",description:"Mist drifts through the distance; directional folds follow your hand.",motion:{type:"mist",speed:.6,amount:1},hover:{effect:"silk",radius:.4,strength:.5}},{id:"depth-study",label:"Depth study",description:"A slow parallax drift from the photo’s own depth, with a loupe under your cursor.",motion:{type:"parallax",speed:.6,amount:.9},hover:{effect:"loupe",radius:.35,strength:.55}}],exports.STUDIO_CHARACTER_SETS=ae,exports.STUDIO_CURVE_CHANNELS=g,exports.STUDIO_HOVERS=t,exports.STUDIO_LOOKS=V,exports.STUDIO_MOTIONS=h,exports.STUDIO_PALETTES=N,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=P,exports.STUDIO_STYLES=O,exports.STUDIO_TEXT_FONTS=ee,exports.STUDIO_WARPS=k,exports.createStudioCurveLookup=y,exports.createStudioProjectRenderer=ue,exports.createStudioRenderer=Qt,exports.createStudioText=ie,exports.exportStudio=async function(t,e,i){let s;const a=q(e),r="png"!==i.format&&"jpeg"!==i.format;try{return await _t(async(e,o,n,h,l,c)=>{s??(s=Qt(e,a,{maxDimension:4096,maxCells:i.maxCells??12e3,pixelRatio:n/(i.referenceWidth??Math.min(n,960))})),r&&s.invalidate(),s.render(await t.frame(o,l),o,n,h,c)},i)}finally{s?.destroy()}},exports.exportStudioProject=async function(t,e,i){const s=he(t),a={...i.motionTimes};if(Object.values(a).some(t=>!Number.isFinite(t)||t<0))throw new Error("Layer motion times must be finite non-negative numbers.");const r=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 _t(async(t,e,h,l,d)=>{n??(n=await pe(s,r,d)),o??(o=ue(t,s,{maxDimension:4096,maxCells:i.maxCells??24e3,maxRasterPixels:i.maxRasterPixels,pixelRatio:h/(i.referenceWidth??Math.min(h,960))}));const m=new Set(de({...s,width:h,height:l}).map(t=>t.source)),u=new Map;await Promise.all([...m].map(async t=>{const i=n.get(t);await i.seek(e,d),u.set(t,i.frame(e)),i.animated&&o.invalidate(t)})),o.render(u,e,h,l,c?a:{})},{...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.inkIndexLookup=Wt,exports.isStudioPrintStyle=I,exports.loadStudioMedia=Kt,exports.mountStudio=async function(t,e,i={}){const s=await Kt(e,i.signal);try{return $t(t,s,i)}catch(t){throw s.destroy(),t}},exports.mountStudioMedia=$t,exports.mountStudioProject=async function(t,e,i,s={}){const a=he(e),r=await pe(a,i,s.signal);try{return ge(t,a,r,s)}catch(t){for(const t of new Set(r.values()))t.destroy();throw t}},exports.mountStudioProjectMedia=ge,exports.normalizeStudioCurve=x,exports.normalizeStudioCurves=v,exports.normalizeStudioPrint=R,exports.normalizeStudioProject=he,exports.normalizeStudioSettings=q,exports.normalizeStudioWarps=A,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 he(e)},exports.parseStudioSettings=function(t){if(t.length>1e5)throw new Error("Settings exceed 100 KB.");return q(JSON.parse(t))},exports.restyleStudio=function(t,e=Math.random){const i=V.filter(e=>e.settings.style!==t.style||e.settings.ink!==t.ink),s=Q(i[Math.min(i.length-1,Math.max(0,Math.floor(e()*i.length)))].id);return s.aspectRatio=t.aspectRatio,s.crop={...t.crop},s.mask=q(t).mask,s},exports.serializeStudioProject=t=>JSON.stringify(he(t)),exports.serializeStudioSettings=function(t){return JSON.stringify(q(t))},exports.studioCrop=B,exports.studioDimensions=G,exports.studioGrid=H,exports.studioLayerPoint=ce,exports.studioLevels=Bt,exports.studioLook=Q,exports.studioProjectBudget=me,exports.studioSourceSize=jt,exports.studioToneGamma=Gt,exports.updateStudioProjectLayer=le,exports.updateStudioSettings=W,exports.visibleStudioLayers=de;//# sourceMappingURL=studio.cjs.map
|