asciify-engine 4.8.0 → 4.10.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 +19 -3
- package/dist/animation-presets-DhswE0D_.d.cts +105 -0
- package/dist/animation-presets-ZujFF3i8.d.ts +105 -0
- 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-catalog-BeIkNwhH.d.cts → hover-catalog-D85jh6dR.d.cts} +40 -1
- package/dist/{hover-catalog-BeIkNwhH.d.ts → hover-catalog-D85jh6dR.d.ts} +40 -1
- package/dist/hover.cjs +1 -1
- package/dist/hover.d.cts +4 -3
- package/dist/hover.d.ts +4 -3
- 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-CMKdRB30.d.ts → model-BVeBDUa9.d.ts} +46 -3
- package/dist/{model-fP9NdG-w.d.cts → model-DQNOpbbG.d.cts} +46 -3
- package/dist/studio.cjs +1 -1
- package/dist/studio.d.cts +4 -3
- package/dist/studio.d.ts +4 -3
- package/dist/studio.js +1 -1
- package/dist/{types-C05AfrjT.d.ts → types-CM4452nD.d.ts} +1 -1
- package/dist/{types-D38BMBRB.d.cts → types-FkqhgDYx.d.cts} +1 -1
- package/examples/living-image.ts +15 -0
- package/examples/print-composition.ts +15 -0
- package/package.json +4 -2
- package/skills/asciify-engine/SKILL.md +10 -4
- package/skills/asciify-engine/references/print-styles.md +63 -0
- package/skills/asciify-engine/references/studio-effects.md +29 -0
- package/skills/asciify-engine/references/studio-workspace.md +11 -3
- package/skills/asciify-engine/references/upgrading.md +8 -0
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<a href="https://www.buymeacoffee.com/asciify"><img src="https://img.shields.io/badge/buy_me_a_coffee-%E2%98%95-d4ff00?labelColor=0a0a0a&style=flat-square" alt="Buy Me A Coffee" /></a>
|
|
8
8
|
</p>
|
|
9
9
|
|
|
10
|
-
A framework-agnostic ASCII art rendering engine for the browser. Convert images, animated GIFs, and video into character-based art rendered onto an HTML canvas — with full color support, interactive hover effects, living-image motion,
|
|
10
|
+
A framework-agnostic ASCII art rendering engine for the browser. Convert images, animated GIFs, and video into character-based art rendered onto an HTML canvas — with full color support, interactive hover effects, living-image motion, 24 Studio render styles, and export.
|
|
11
11
|
|
|
12
12
|
### Media first, optional backgrounds
|
|
13
13
|
|
|
@@ -536,7 +536,7 @@ Use `CHARACTER_SETS.standard.chars` (or another curated entry) from root or `/co
|
|
|
536
536
|
|
|
537
537
|
### Studio detail controls (4.2)
|
|
538
538
|
|
|
539
|
-
The optional `asciify-engine/studio` entry includes
|
|
539
|
+
The optional `asciify-engine/studio` entry includes 24 render styles, including hex mosaic, LED matrix and CMYK print. Dither supports pixel scale, custom palettes, RGB/luminance mapping, pattern speed and direction. Use `studioGrid` to report effective density and opt into a larger `maxCells` budget for one-pixel output; defaults stay performance-bounded. Mounts expose `setAdaptive` for an explicit detail/performance choice. Still-image motion has `amount`, and finishing adds `rgbSplit` and `sharpen` (WebGL required). See the [complete controls and export guidance](skills/asciify-engine/references/studio-workspace.md#fine-detail-and-controls-42). No AI service or server upload is introduced.
|
|
540
540
|
|
|
541
541
|
### More motion for still images (4.3)
|
|
542
542
|
|
|
@@ -565,7 +565,7 @@ All motion choices repeat every `12 / speed` seconds. Still exports preserve the
|
|
|
565
565
|
|
|
566
566
|
Studio adds `dither.algorithm: 'blue-noise'`: a stable precomputed dispersed pattern with no runtime generation or asset download. `noise` remains white noise. Choose the algorithm from `DITHER_ALGORITHMS`; drift and shimmer remain independently controlled.
|
|
567
567
|
|
|
568
|
-
Recover usable shadow/highlight separation before conversion with `color.gamma`, `shadows`, `highlights`, `blackPoint` and `whitePoint`. All
|
|
568
|
+
Recover usable shadow/highlight separation before conversion with `color.gamma`, `shadows`, `highlights`, `blackPoint` and `whitePoint`. All Studio styles share these controls and retain neutral defaults. They are a bounded monotone tonal curve, not arbitrary per-channel curve editing. See [exact ranges, sampling budgets and a live-project example](skills/asciify-engine/references/studio-workspace.md#tonal-detail-and-blue-noise-45).
|
|
569
569
|
|
|
570
570
|
### Channel curves and source noise reduction (4.6)
|
|
571
571
|
|
|
@@ -611,3 +611,19 @@ player.updateLayer('photo', { settings: { hover: { effect: 'water' } } });
|
|
|
611
611
|
```
|
|
612
612
|
|
|
613
613
|
`exportStudioProject` owns independent export media, so it does not disturb the live preview. Save layouts with `serializeStudioProject`, retain/rebind source assets separately, and restore with `parseStudioProject`. See the [layered-project guide](skills/asciify-engine/references/layered-projects.md) and [typed live/export example](examples/layered-composition.ts) for geometry, picking, ownership, cancellation and performance limits. This is an optional local composition API, not a claim of complete competitor-style or FPS parity.
|
|
614
|
+
|
|
615
|
+
### Print and illustration (4.9)
|
|
616
|
+
|
|
617
|
+
Stipple, Engraving, Crosshatch, Woodblock, Risograph and Pointillism add distinct print geometry to `/studio`. All share hover, living-image motion, masks, source shaping, saved settings and exports. Tune coverage, mark weight, angle, repeatable texture, light/dark ink polarity and two-ink registration with `print`. Use `STUDIO_PRINT_STYLES` for labels and [the print guide](skills/asciify-engine/references/print-styles.md) for a live still-image example, bounds and performance limits. ASCII remains the default.
|
|
618
|
+
|
|
619
|
+
## 4.10: more life for still images
|
|
620
|
+
|
|
621
|
+
Three additional pointer responses—Lens wake, Smudge and Ripple rings—and four autonomous motions—Relight, Shimmer, Breeze and Unfold—bring the catalogs to 14 each, plus Off. Source images, art styles and colors remain yours. Six editable combinations in `STUDIO_ANIMATION_PRESETS` help choose a starting point without replacing your look.
|
|
622
|
+
|
|
623
|
+
```ts
|
|
624
|
+
import { STUDIO_ANIMATION_PRESETS } from 'asciify-engine/studio';
|
|
625
|
+
const preset = STUDIO_ANIMATION_PRESETS.find(p => p.id === 'quiet-light')!;
|
|
626
|
+
player.update({ motion: preset.motion, hover: preset.hover });
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
Use one Studio player for live rendering, settings persistence and independent animation export. See [the complete interaction guide](skills/asciify-engine/references/studio-effects.md#lively-images-410) and [living-image helper](examples/living-image.ts). CPU simulation is bounded and wakes settle; device frame rates and visual fidelity still require browser measurement. Existing defaults and saved IDs are unchanged.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { A as AmbientMotion, S as SurfaceHover } from './hover-catalog-D85jh6dR.cjs';
|
|
2
|
+
|
|
3
|
+
interface StudioAnimationPreset {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly label: string;
|
|
6
|
+
readonly description: string;
|
|
7
|
+
readonly motion: {
|
|
8
|
+
readonly type: AmbientMotion;
|
|
9
|
+
readonly speed: number;
|
|
10
|
+
readonly amount: number;
|
|
11
|
+
};
|
|
12
|
+
readonly hover: {
|
|
13
|
+
readonly effect: SurfaceHover;
|
|
14
|
+
readonly radius: number;
|
|
15
|
+
readonly strength: number;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** Starting combinations, not new renderer styles. Preserve the image and its look. */
|
|
19
|
+
declare const STUDIO_ANIMATION_PRESETS: readonly [{
|
|
20
|
+
readonly id: "quiet-light";
|
|
21
|
+
readonly label: "Quiet light";
|
|
22
|
+
readonly description: "Stationary detail with slowly turning light and a soft magnifying wake.";
|
|
23
|
+
readonly motion: {
|
|
24
|
+
readonly type: "relight";
|
|
25
|
+
readonly speed: 0.6;
|
|
26
|
+
readonly amount: 0.7;
|
|
27
|
+
};
|
|
28
|
+
readonly hover: {
|
|
29
|
+
readonly effect: "lens";
|
|
30
|
+
readonly radius: 0.45;
|
|
31
|
+
readonly strength: 0.5;
|
|
32
|
+
};
|
|
33
|
+
}, {
|
|
34
|
+
readonly id: "living-paper";
|
|
35
|
+
readonly label: "Living paper";
|
|
36
|
+
readonly description: "A gentle traveling bend and a directional pull under your cursor.";
|
|
37
|
+
readonly motion: {
|
|
38
|
+
readonly type: "breeze";
|
|
39
|
+
readonly speed: 0.8;
|
|
40
|
+
readonly amount: 0.6;
|
|
41
|
+
};
|
|
42
|
+
readonly hover: {
|
|
43
|
+
readonly effect: "smudge";
|
|
44
|
+
readonly radius: 0.4;
|
|
45
|
+
readonly strength: 0.5;
|
|
46
|
+
};
|
|
47
|
+
}, {
|
|
48
|
+
readonly id: "silver-grain";
|
|
49
|
+
readonly label: "Silver grain";
|
|
50
|
+
readonly description: "Slow highlight glints with a fluid character trail.";
|
|
51
|
+
readonly motion: {
|
|
52
|
+
readonly type: "shimmer";
|
|
53
|
+
readonly speed: 0.75;
|
|
54
|
+
readonly amount: 0.85;
|
|
55
|
+
};
|
|
56
|
+
readonly hover: {
|
|
57
|
+
readonly effect: "trail";
|
|
58
|
+
readonly radius: 0.35;
|
|
59
|
+
readonly strength: 0.55;
|
|
60
|
+
};
|
|
61
|
+
}, {
|
|
62
|
+
readonly id: "ripple-study";
|
|
63
|
+
readonly label: "Ripple study";
|
|
64
|
+
readonly description: "Soft moving light and expanding tonal rings on an anchored grid.";
|
|
65
|
+
readonly motion: {
|
|
66
|
+
readonly type: "caustics";
|
|
67
|
+
readonly speed: 0.6;
|
|
68
|
+
readonly amount: 0.55;
|
|
69
|
+
};
|
|
70
|
+
readonly hover: {
|
|
71
|
+
readonly effect: "ripple";
|
|
72
|
+
readonly radius: 0.45;
|
|
73
|
+
readonly strength: 0.75;
|
|
74
|
+
};
|
|
75
|
+
}, {
|
|
76
|
+
readonly id: "unfolding-print";
|
|
77
|
+
readonly label: "Unfolding print";
|
|
78
|
+
readonly description: "Panels turn and reassemble; your cursor dissolves a soft path.";
|
|
79
|
+
readonly motion: {
|
|
80
|
+
readonly type: "unfold";
|
|
81
|
+
readonly speed: 0.7;
|
|
82
|
+
readonly amount: 0.75;
|
|
83
|
+
};
|
|
84
|
+
readonly hover: {
|
|
85
|
+
readonly effect: "dissolve";
|
|
86
|
+
readonly radius: 0.35;
|
|
87
|
+
readonly strength: 0.55;
|
|
88
|
+
};
|
|
89
|
+
}, {
|
|
90
|
+
readonly id: "silk-flow";
|
|
91
|
+
readonly label: "Silk flow";
|
|
92
|
+
readonly description: "A slow current with directional folds that follow your hand.";
|
|
93
|
+
readonly motion: {
|
|
94
|
+
readonly type: "current";
|
|
95
|
+
readonly speed: 0.6;
|
|
96
|
+
readonly amount: 0.55;
|
|
97
|
+
};
|
|
98
|
+
readonly hover: {
|
|
99
|
+
readonly effect: "silk";
|
|
100
|
+
readonly radius: 0.4;
|
|
101
|
+
readonly strength: 0.5;
|
|
102
|
+
};
|
|
103
|
+
}];
|
|
104
|
+
|
|
105
|
+
export { STUDIO_ANIMATION_PRESETS as S, type StudioAnimationPreset as a };
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { A as AmbientMotion, S as SurfaceHover } from './hover-catalog-D85jh6dR.js';
|
|
2
|
+
|
|
3
|
+
interface StudioAnimationPreset {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly label: string;
|
|
6
|
+
readonly description: string;
|
|
7
|
+
readonly motion: {
|
|
8
|
+
readonly type: AmbientMotion;
|
|
9
|
+
readonly speed: number;
|
|
10
|
+
readonly amount: number;
|
|
11
|
+
};
|
|
12
|
+
readonly hover: {
|
|
13
|
+
readonly effect: SurfaceHover;
|
|
14
|
+
readonly radius: number;
|
|
15
|
+
readonly strength: number;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** Starting combinations, not new renderer styles. Preserve the image and its look. */
|
|
19
|
+
declare const STUDIO_ANIMATION_PRESETS: readonly [{
|
|
20
|
+
readonly id: "quiet-light";
|
|
21
|
+
readonly label: "Quiet light";
|
|
22
|
+
readonly description: "Stationary detail with slowly turning light and a soft magnifying wake.";
|
|
23
|
+
readonly motion: {
|
|
24
|
+
readonly type: "relight";
|
|
25
|
+
readonly speed: 0.6;
|
|
26
|
+
readonly amount: 0.7;
|
|
27
|
+
};
|
|
28
|
+
readonly hover: {
|
|
29
|
+
readonly effect: "lens";
|
|
30
|
+
readonly radius: 0.45;
|
|
31
|
+
readonly strength: 0.5;
|
|
32
|
+
};
|
|
33
|
+
}, {
|
|
34
|
+
readonly id: "living-paper";
|
|
35
|
+
readonly label: "Living paper";
|
|
36
|
+
readonly description: "A gentle traveling bend and a directional pull under your cursor.";
|
|
37
|
+
readonly motion: {
|
|
38
|
+
readonly type: "breeze";
|
|
39
|
+
readonly speed: 0.8;
|
|
40
|
+
readonly amount: 0.6;
|
|
41
|
+
};
|
|
42
|
+
readonly hover: {
|
|
43
|
+
readonly effect: "smudge";
|
|
44
|
+
readonly radius: 0.4;
|
|
45
|
+
readonly strength: 0.5;
|
|
46
|
+
};
|
|
47
|
+
}, {
|
|
48
|
+
readonly id: "silver-grain";
|
|
49
|
+
readonly label: "Silver grain";
|
|
50
|
+
readonly description: "Slow highlight glints with a fluid character trail.";
|
|
51
|
+
readonly motion: {
|
|
52
|
+
readonly type: "shimmer";
|
|
53
|
+
readonly speed: 0.75;
|
|
54
|
+
readonly amount: 0.85;
|
|
55
|
+
};
|
|
56
|
+
readonly hover: {
|
|
57
|
+
readonly effect: "trail";
|
|
58
|
+
readonly radius: 0.35;
|
|
59
|
+
readonly strength: 0.55;
|
|
60
|
+
};
|
|
61
|
+
}, {
|
|
62
|
+
readonly id: "ripple-study";
|
|
63
|
+
readonly label: "Ripple study";
|
|
64
|
+
readonly description: "Soft moving light and expanding tonal rings on an anchored grid.";
|
|
65
|
+
readonly motion: {
|
|
66
|
+
readonly type: "caustics";
|
|
67
|
+
readonly speed: 0.6;
|
|
68
|
+
readonly amount: 0.55;
|
|
69
|
+
};
|
|
70
|
+
readonly hover: {
|
|
71
|
+
readonly effect: "ripple";
|
|
72
|
+
readonly radius: 0.45;
|
|
73
|
+
readonly strength: 0.75;
|
|
74
|
+
};
|
|
75
|
+
}, {
|
|
76
|
+
readonly id: "unfolding-print";
|
|
77
|
+
readonly label: "Unfolding print";
|
|
78
|
+
readonly description: "Panels turn and reassemble; your cursor dissolves a soft path.";
|
|
79
|
+
readonly motion: {
|
|
80
|
+
readonly type: "unfold";
|
|
81
|
+
readonly speed: 0.7;
|
|
82
|
+
readonly amount: 0.75;
|
|
83
|
+
};
|
|
84
|
+
readonly hover: {
|
|
85
|
+
readonly effect: "dissolve";
|
|
86
|
+
readonly radius: 0.35;
|
|
87
|
+
readonly strength: 0.55;
|
|
88
|
+
};
|
|
89
|
+
}, {
|
|
90
|
+
readonly id: "silk-flow";
|
|
91
|
+
readonly label: "Silk flow";
|
|
92
|
+
readonly description: "A slow current with directional folds that follow your hand.";
|
|
93
|
+
readonly motion: {
|
|
94
|
+
readonly type: "current";
|
|
95
|
+
readonly speed: 0.6;
|
|
96
|
+
readonly amount: 0.55;
|
|
97
|
+
};
|
|
98
|
+
readonly hover: {
|
|
99
|
+
readonly effect: "silk";
|
|
100
|
+
readonly radius: 0.4;
|
|
101
|
+
readonly strength: 0.5;
|
|
102
|
+
};
|
|
103
|
+
}];
|
|
104
|
+
|
|
105
|
+
export { STUDIO_ANIMATION_PRESETS as S, type StudioAnimationPreset as a };
|
package/dist/core.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var t={standard:{label:"Classic ASCII",chars:" .:-=+*#%@"},asciify:{label:"Asciify",chars:" .:-=+ASCIIFY#@"},minimal:{label:"Minimal",chars:" .:+"},detailed:{label:"Detailed",chars:" .,:;i1tfLCG08@"},letters:{label:"Letters",chars:" .ilLCFTYASMW"},technical:{label:"Technical",chars:" .:;>_/[{}]=+*#@$"},blocks:{label:"Tonal blocks",chars:" ░▒▓█"},braille:{label:"Braille",chars:" ⠁⠃⠇⡇⣇⣧⣷⣿"}},e={fontSize:7,charSpacing:1,brightness:0,contrast:0,charset:t.standard.chars,colorMode:"grayscale",accentColor:"#d4ff00",invert:!1,renderMode:"ascii",animationStyle:"none",animationSpeed:1,dotSizeRatio:.8,ditherStrength:0,charAspect:.55,normalize:!1,hoverStrength:0,hoverRadius:.2,hoverEffect:"spotlight",hoverColor:"#ffffff",hoverShape:"circle",hoverText:"ASCIIFY",artStyle:"classic",fineDither:!1,customText:"",chromaKey:null,chromaKeyTolerance:60,chromaKeyTrimPadding:.002,chromaKeyTrimLuminanceThreshold:0,chromaKeyTrimMode:"range"},n=[{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."}];var o=t=>Math.max(0,Math.min(1,t)),r=(t,e,n)=>{const r=o((n-t)/(e-t));return r*r*(3-2*r)},a=(t,e)=>{const n=(.06711056*t+.00583715*e)%1*52.9829189;return n-Math.floor(n)};function i(t,e,n,i,s,c=.5){if(s[0]=s[1]=s[2]=0,s[3]=1,"none"===t)return s;const l=i*Math.PI/6,h=r(0,.12,Math.min(e,1-e,n,1-n));if("caustics"===t){const t=Math.sin(9*e+5*n+l)+Math.sin(8*n-3*e-l),o=Math.pow(Math.max(0,1-.72*Math.abs(t)),3);s[2]=(.22*o-.045)*h}else if("current"===t)s[0]=Math.sin(9*n+l)*Math.cos(7*e-l)*10*h,s[1]=Math.cos(8*e+l)*Math.sin(6*n-l)*7*h;else if("sheen"===t)s[2]=.2*Math.pow(.5+.5*Math.cos(5*e+3*n-l),8)-.025;else if("tidal"===t){const t=e-.5,o=n-.5,r=Math.hypot(t,o),a=Math.sin(22*r-l)*h;s[0]=t*a*9,s[1]=o*a*9,s[2]=.035*a}else if("grain"===t){const t=a(Math.floor(160*e),Math.floor(100*n))*Math.PI*2;s[2]=.07*Math.sin(l+t)}else if("parallax"===t){const t=.45+.55*Math.max(0,1-1.4*Math.hypot(e-.5,n-.5));s[0]=12*Math.sin(l)*t*h,s[1]=6*(Math.cos(l)-1)*t*h}else if("weave"===t)s[0]=Math.sin(n*Math.PI*6+l)*Math.sin(l)*8*h,s[1]=Math.sin(e*Math.PI*6-l)*Math.sin(l)*6*h;else if("print"===t){const t=Math.floor(24*n),e=((i+3*a(t,3))%12+12)%12,o=r(1,2.5,e)*(1-r(3.5,5,e));s[0]=Math.sin(2.4*t)*o*9*h,s[1]=5*-o*h,s[2]=.22*-o,s[3]=1-.45*o}else if("trace"===t){const t=.5+.5*Math.cos(l);s[2]=.22*Math.pow(Math.max(0,1-Math.abs(o(c)-t)/.16),3)-.015}else if("reform"===t){const t=(i%12+12)%12,o=a(Math.floor(160*e),Math.floor(100*n)),c=.65*e+.2*n+.15*o+.08*Math.sin(8*e-5*n),d=r(1.8+1.2*c,3.8+1.2*c,t)*(1-r(5+1.7*c,7.2+1.7*c,t));s[0]=Math.sin(9*n+l)*d*(1-d)*24*h,s[1]=-d*(1-d)*(8+12*o)*h,s[2]=.45*-d,s[3]=1-.9*d}return s}function s(t,e){const n=document.createElement("canvas");n.width=t,n.height=e;const o=n.getContext("2d",{willReadFrequently:!0});return{canvas:n,ctx:o}}function c(t,e,n){let o=t+255*e;return o=259*(255*n+255)/(255*(259-255*n))*(o-128)+128,Math.max(0,Math.min(255,o))}function l(t,e,n,o,r,a){if((a?1-t/255:t/255)<.12)return" ";const i=[...e];return i[(o*r+n)%i.length]}var h=[[0,8,2,10],[12,4,14,6],[3,11,1,9],[15,7,13,5]];function d(t,e,n,o){if(o<=0)return t;const r=(h[n%4][e%4]/16-.5)*o*128;return Math.max(0,Math.min(255,t+r))}var f=new Array(256),m=new Array(256);for(let t=0;t<256;t++)f[t]=`rgb(${t},${t},${t})`,m[t]=`rgb(0,${t},0)`;function u(t,e,n,o,r,a=!1){switch(e){case"fullcolor":return`rgb(${t.r},${t.g},${t.b})`;case"matrix":return m[.299*t.r+.587*t.g+.114*t.b|0];case"accent":return`rgb(${n},${o},${r})`;default:{const e=.299*t.r+.587*t.g+.114*t.b|0;return f[e]}}}var g=[0,0,0];function p(t,e,n,o,r,a=!1){switch(e){case"fullcolor":g[0]=t.r,g[1]=t.g,g[2]=t.b;break;case"matrix":{const e=.299*t.r+.587*t.g+.114*t.b|0;g[0]=0,g[1]=e,g[2]=0;break}case"accent":g[0]=n,g[1]=o,g[2]=r;break;default:{const e=.299*t.r+.587*t.g+.114*t.b|0;g[0]=e,g[1]=e,g[2]=e;break}}return g}function M(t){const e=t.match(/rgba?\(\s*(\d+)\s*[,\s]\s*(\d+)\s*[,\s]\s*(\d+)(?:\s*[,/]\s*([\d.]+))?\s*\)/);return e?{r:+e[1],g:+e[2],b:+e[3],a:void 0!==e[4]?+e[4]:1}:null}function v(t){let e=t;for(;e&&e!==document.documentElement.parentElement;){const t=getComputedStyle(e).backgroundColor;if(t&&"transparent"!==t&&"rgba(0, 0, 0, 0)"!==t){const e=M(t);if(e&&e.a>.1)return e}e=e.parentElement}return null}function w(t){if(t){const e=v(t);if(e){return(.299*e.r+.587*e.g+.114*e.b)/255<.4}}if("undefined"!=typeof document){const t=document.documentElement,e=(t.getAttribute("data-theme")||"").toLowerCase();if("dark"===e)return!0;if("light"===e)return!1;if(t.classList.contains("dark"))return!0;if(document.body){const t=v(document.body);if(t){return(.299*t.r+.587*t.g+.114*t.b)/255<.4}}}return"undefined"!=typeof window&&window.matchMedia("(prefers-color-scheme: dark)").matches}function x(t){if("string"!=typeof t)return t;const e=document.createElement("canvas");e.width=1,e.height=1;const n=e.getContext("2d");n.fillStyle=t,n.fillRect(0,0,1,1);const o=n.getImageData(0,0,1,1).data;return{r:o[0],g:o[1],b:o[2]}}function y(t){return t*t*(3-2*t)}var b={scale:1,offsetX:0,offsetY:0,glow:0,colorBlend:0,proximity:0};function S(t,e,n,o,r,a,i,s,c="spotlight",l=.5,h="circle",d=[],f=1){const m=(t-n)*Math.max(1,f),u=(e-o)*Math.max(1,1/f),g=.08+.35*l+.04*a;let p,M;if("box"===h){const t=Math.abs(m),e=Math.abs(u);p=Math.max(t,e),M=g}else p=Math.sqrt(m*m+u*u),M=g;if(p>=M&&("trail"!==c||0===d.length))return b.scale=1,b.offsetX=0,b.offsetY=0,b.glow=0,b.colorBlend=0,b.proximity=0,b;const v=y(Math.max(0,1-p/M))*r;let w=1,x=0,S=0,E=0,T=0;switch(c){case"spotlight":{w=1+v*a*1.8;const t=Math.atan2(u,m),e=v*v*a*.6;x=Math.cos(t)*e*i,S=Math.sin(t)*e*s,E=v*a*.4,T=v*v*a*.25;break}case"magnify":w=1+v*a*.85,E=v*a*.15;break;case"repel":{w=1;const t=Math.atan2(u,m),e=v*v*a*1.8;x=Math.cos(t)*e*i,S=Math.sin(t)*e*s;break}case"glow":E=v*a*.8,T=v*a*.4;break;case"colorShift":w=1,E=v*a*.12,T=v*a;break;case"attract":{const t=Math.atan2(u,m),e=v*v*a*1;x=(.45*-Math.cos(t)-1.6*Math.sin(t))*e*i,S=(.45*-Math.sin(t)+1.6*Math.cos(t))*e*s,E=v*a*.3;break}case"shatter":{const t=Math.atan2(u,m),e=.5*Math.sin(43.7*m+29.3*u),n=v*a*1.4*(.7+.3*e);x=Math.cos(t+e)*n*i,S=Math.sin(t+e)*n*s,w=Math.max(.1,1-v*a*.6),E=v*a*.25;break}case"trail":{let n=v,o=-u*v,r=m*v;for(const a of d){const i=(t-a.x)*Math.max(1,f),s=(e-a.y)*Math.max(1,1/f),c=Math.hypot(i,s)/g;if(c>=1)continue;const l=y(1-c)*a.intensity;n=Math.max(n,l),o+=(.35*a.vx-2*s)*l*.35,r+=(.35*a.vy+2*i)*l*.35}x=Math.tanh(2*o)*a*i*3,S=Math.tanh(2*r)*a*s*3,T=n*a*.65,E=n*a*.35,w=1+n*a*.08,b.proximity=n;break}case"glitchText":w=1,E=v*a*.5,T=v*a*.6}return b.scale=w,b.offsetX=x,b.offsetY=S,b.glow=E,b.colorBlend=T,"trail"!==c&&(b.proximity=v),b}function E(t,e,{continuous:n=!1,interactive:o=!1}={}){const r=t.parentElement??t;let a=null,i=0,s=!1,c=!0,l=!0,h=-1/0;const d=window.matchMedia("(prefers-reduced-motion: reduce)"),f=()=>{l=!0,s||!c||document.hidden||i||(i=requestAnimationFrame(m))},m=t=>{if(i=0,s||!c||document.hidden)return;const o=!d.matches&&(n||t-h<1500);(l||o)&&(e(t,d.matches?null:a),l=!1),o&&(i=requestAnimationFrame(m))},u=e=>{if("touch"===e.pointerType)return;const n=t.getBoundingClientRect();if(!n.width||!n.height)return;const o=(e.clientX-n.left)/n.width,r=(e.clientY-n.top)/n.height;a=o>=0&&o<=1&&r>=0&&r<=1?{x:o,y:r}:null,h=performance.now(),f()},g=()=>{a=null,h=performance.now(),f()},p=()=>{document.hidden&&i?(cancelAnimationFrame(i),i=0):f()},M="undefined"==typeof IntersectionObserver?null:new IntersectionObserver(([t])=>{c=t.isIntersecting,c?f():i&&(cancelAnimationFrame(i),i=0)});return M?.observe(t),o&&(r.addEventListener("pointermove",u),r.addEventListener("pointerleave",g)),document.addEventListener("visibilitychange",p),d.addEventListener("change",f),f(),{wake:f,stop:()=>{s=!0,cancelAnimationFrame(i),M?.disconnect(),r.removeEventListener("pointermove",u),r.removeEventListener("pointerleave",g),document.removeEventListener("visibilitychange",p),d.removeEventListener("change",f)}}}var T=null,C=null;function A(t,e){if(!T||!C){const n=s(t,e);T=n.canvas,C=n.ctx}return T.width!==t&&(T.width=t),T.height!==e&&(T.height=e),C}var F=new Map,L=new Map,R=new WeakMap;function I(t){const e=Intl.Segmenter;return e?Array.from(new e(void 0,{granularity:"grapheme"}).segment(t),({segment:t})=>t):[...t]}function k(t){let e=F.get(t);return e||(e=I(t),F.set(t,e)),e}function H(t){return I(t)}function W(t,e,n){const o=n?1-t/255:t/255,r=Math.floor(o*(e.length-1));return e[Math.max(0,Math.min(e.length-1,r))]??" "}function P(t,e,n,o){const r=`${t}\0${e?1:0}\0${n}\0${o}`;let a=L.get(r);if(!a){const i=k(t);a=new Array(256);for(let t=0;t<256;t++)a[t]=W(c(t,n,o),i,e);L.set(r,a)}return a}function $(t,e){return"auto"!==t?t:!w(e)}function j(t){const e=t.match(/^#([0-9a-fA-F]{3,6})$/);if(e){let t=e[1];if(3===t.length&&(t=t[0]+t[0]+t[1]+t[1]+t[2]+t[2]),6===t.length)return t}const n=t.match(/rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);return n?[n[1],n[2],n[3]].map(t=>parseInt(t).toString(16).padStart(2,"0")).join(""):null}function z(t){const e=t||"auto";if("auto"!==e)return j(e)??"ffffff";if("undefined"!=typeof document){const t=getComputedStyle(document.documentElement);for(const e of["--accent-color","--color-accent","--accent","--color-primary","--primary","--brand-color"]){const n=j(t.getPropertyValue(e).trim());if(n)return n}const e=j(getComputedStyle(document.body).accentColor??"");if(e)return e}return w("undefined"!=typeof document?document.body:null)?"faf9f7":"0d0d0d"}function O(t,e,n){return Math.max(e,Math.min(n,t))}function V(t,e,n){if(!t)return{x:0,y:0,width:e,height:n};const o=t.unit??"percent",r=!1!==t.preserveAspect,a=t=>void 0===t?void 0:"percent"===o?t*e:t,i=t=>void 0===t?void 0:"percent"===o?t*n:t,s=O(a(t.left)??0,0,e-1),c=O(a(t.right)??0,0,e-s-1),l=O(i(t.top)??0,0,n-1),h=O(i(t.bottom)??0,0,n-l-1),d=void 0!==t.left||void 0!==t.right||void 0!==t.top||void 0!==t.bottom,f=Math.max(1,e-s-c),m=Math.max(1,n-l-h),u=d?f:a(t.width),g=d?m:i(t.height);let p=u??e,M=g??n;if(r&&!d){const t=p/e,o=M/n,r=Math.min(t,o),a=void 0===u?o:void 0===g?t:r;p=e*a,M=n*a}p=O(p,1,d?f:e),M=O(M,1,d?m:n);const v=t.anchor??"center",w=a(t.x),x=i(t.y),y=d?s:0,b=d?l:0,S=d?f:e,E=d?m:n,T=v.endsWith("left")||"left"===v?0:v.endsWith("right")||"right"===v?S-p:(S-p)/2,C=v.startsWith("top")||"top"===v?0:v.startsWith("bottom")||"bottom"===v?E-M:(E-M)/2;return{x:O(w??y+T,0,Math.max(0,e-p)),y:O(x??b+C,0,Math.max(0,n-M)),width:p,height:M}}function q(t,e,n,o){const r=t instanceof HTMLVideoElement?t.videoWidth:t.width,a=t instanceof HTMLVideoElement?t.videoHeight:t.height;if(0===r||0===a)return{frame:[],cols:0,rows:0};const i=e.charAspect,s=e.fontSize*e.charSpacing,h=e.fontSize/i*e.charSpacing,f=n||r,m=o||a,u=Math.floor(f/s),g=Math.floor(m/h);if(u<=0||g<=0)return{frame:[],cols:0,rows:0};const p=V(e.sourceCrop,r,a),M=Math.max(1,Math.min(Math.floor(2048/u),Math.floor(p.width/u))),v=Math.max(1,Math.min(Math.floor(2048/g),Math.floor(p.height/g))),w=u*M,y=g*v,b=A(w,y),S=b.globalCompositeOperation;b.globalCompositeOperation="copy";try{b.drawImage(t,p.x,p.y,p.width,p.height,0,0,w,y)}finally{b.globalCompositeOperation=S}const E=b.getImageData(0,0,w,y).data,T=e.chromaKey,C=null!=T&&!1!==T,F=!0===T,L="blue-screen"===T;let R=null,I=0;!C||F||L||(R=x(T),I=(e.chromaKeyTolerance??60)**2);let H=0,j=255;if(e.normalize){let t=255,e=0;for(let n=0;n<E.length;n+=4){if(C){const t=E[n],e=E[n+1],o=E[n+2];let r=!1;if(F)r=e>1.4*t&&e>1.4*o&&e>80;else if(L)r=o>1.4*t&&o>1.4*e&&o>80;else if(null!==R){const n=t-R.r,a=e-R.g,i=o-R.b;r=n*n+a*a+i*i<=I}if(r)continue}const o=.299*E[n]+.587*E[n+1]+.114*E[n+2];o<t&&(t=o),o>e&&(e=o)}H=t,j=e>t?e-t:255}const z=[],O=$(e.invert),q=C&&e.charset.replace(/ /g,"")||e.charset,D=k(q),B=e.customText?null:P(q,O,e.brightness,e.contrast),U=M*v;for(let t=0;t<g;t++){const n=[];for(let o=0;o<u;o++){let r=0,a=0,i=0,s=0,h=0;for(let e=0;e<v;e++){const n=(t*v+e)*w;for(let t=0;t<M;t++){const e=4*(n+o*M+t),c=E[e],l=E[e+1],d=E[e+2],f=E[e+3];if(C){let t=!1;if(F)t=l>1.4*c&&l>1.4*d&&l>80;else if(L)t=d>1.4*c&&d>1.4*l&&d>80;else if(null!==R){const e=c-R.r,n=l-R.g,o=d-R.b;t=e*e+n*n+o*o<=I}if(t){h++;continue}}r+=c,a+=l,i+=d,s+=f}}if(C&&h>U/2){n.push({char:" ",r:0,g:0,b:0,a:0});continue}const f=U-h,m=f>0?r/f:0,g=f>0?a/f:0,p=f>0?i/f:0,x=f>0?s/f:0,y=.299*m+.587*g+.114*p,b=e.normalize?(y-H)/j*255:y,S=c(b,e.brightness,e.contrast),T=e.ditherStrength>0?d(S,o,t,e.ditherStrength):S,A=e.customText?l(T,e.customText,o,t,u,O):e.ditherStrength>0?W(T,D,O):B[Math.max(0,Math.min(255,0|b))];n.push({char:A,r:m,g:g,b:p,a:x,lum:T})}z.push(n)}return{frame:z,cols:u,rows:g}}function D(t,e,n,o){const r=t instanceof HTMLVideoElement?t.videoWidth:t.width,a=t instanceof HTMLVideoElement?t.videoHeight:t.height;if(0===r||0===a)return{rows:[],cols:0,rowCount:0};const i=e.charAspect,s=e.fontSize*e.charSpacing,l=e.fontSize/i*e.charSpacing,h=n||r,f=o||a,m=Math.floor(h/s),u=Math.floor(f/l);if(m<=0||u<=0)return{rows:[],cols:0,rowCount:0};const g=m,p=u,M=A(g,p),v=V(e.sourceCrop,r,a),w=M.globalCompositeOperation;M.globalCompositeOperation="copy";try{M.drawImage(t,v.x,v.y,v.width,v.height,0,0,g,p)}finally{M.globalCompositeOperation=w}const y=M.getImageData(0,0,g,p).data,b=e.chromaKey,S=null!=b&&!1!==b,E=!0===b,T="blue-screen"===b;let C=null,F=0;!S||E||T||(C=x(b),F=(e.chromaKeyTolerance??60)**2);let L=0,R=255;if(e.normalize){let t=255,e=0;for(let n=0;n<y.length;n+=4){if(S){const t=y[n],e=y[n+1],o=y[n+2];let r=!1;if(E)r=e>1.4*t&&e>1.4*o&&e>80;else if(T)r=o>1.4*t&&o>1.4*e&&o>80;else if(null!==C){const n=t-C.r,a=e-C.g,i=o-C.b;r=n*n+a*a+i*i<=F}if(r)continue}const o=.299*y[n]+.587*y[n+1]+.114*y[n+2];o<t&&(t=o),o>e&&(e=o)}L=t,R=e>t?e-t:255}const I=$(e.invert),H=S&&e.charset.replace(/ /g,"")||e.charset,j=k(H),z=e.customText?null:P(H,I,e.brightness,e.contrast),O=e.customText?k(e.customText):null,q="fullcolor"===e.colorMode?new Uint8ClampedArray(m*u*4):void 0,D=[];for(let t=0;t<u;t++){let n="";for(let o=0;o<m;o++){const r=4*(t*g+o),a=r,i=y[r],s=y[r+1],l=y[r+2],h=y[r+3];if(S){let t=!1;if(E)t=s>1.4*i&&s>1.4*l&&s>80;else if(T)t=l>1.4*i&&l>1.4*s&&l>80;else if(null!==C){const e=i-C.r,n=s-C.g,o=l-C.b;t=e*e+n*n+o*o<=F}if(t){n+=" ",q&&(q[a]=0,q[a+1]=0,q[a+2]=0,q[a+3]=0);continue}}q&&(q[a]=i,q[a+1]=s,q[a+2]=l,q[a+3]=h);const f=.299*i+.587*s+.114*l,u=e.normalize?(f-L)/R*255:f,p=e.ditherStrength>0||O?c(u,e.brightness,e.contrast):u,M=e.ditherStrength>0?d(p,o,t,e.ditherStrength):p;if(O){n+=(I?1-M/255:M/255)<.12?" ":O[(t*m+o)%O.length]}else e.ditherStrength<=0?n+=z[Math.max(0,Math.min(255,0|u))]:n+=W(M,j,I)}D.push(n)}return{rows:D,cols:m,rowCount:u,colors:q}}function B(t,e,n,o,r){if(0===e.rows.length)return;const a=t.canvas,i=Boolean(n.chromaKey)||e.rows.some(t=>t.includes(" "));i||(R.delete(t),t.clearRect(0,0,o,r),t.fillStyle=w(a)?"#0a0a0a":"#faf9f7",t.fillRect(0,0,o,r));const s=z(n.accentColor),c=parseInt(s.substring(0,2),16),l=parseInt(s.substring(2,4),16),h=parseInt(s.substring(4,6),16),d=o/e.cols,f=r/e.rowCount,m=.9*Math.min(d/.55,f),u=e.colors;if("fullcolor"===n.colorMode&&u){R.delete(t),t.clearRect(0,0,o,r),t.font=`${m}px "JetBrains Mono", monospace`,t.textAlign="left",t.textBaseline="middle",t.globalAlpha=1;let n="";for(let o=0;o<e.rows.length;o++){const r=H(e.rows[o]);let a=0;for(;a<e.cols;){for(;a<e.cols&&" "===r[a];)a++;if(a>=e.cols)break;const i=a,s=4*(o*e.cols+a),c=240&u[s],l=240&u[s+1],h=240&u[s+2];for(a++;a<e.cols&&" "!==r[a];){const t=4*(o*e.cols+a);if((240&u[t])!==c||(240&u[t+1])!==l||(240&u[t+2])!==h)break;a++}const m=`rgb(${c},${l},${h})`;m!==n&&(t.fillStyle=m,n=m),t.fillText(r.slice(i,a).join(""),i*d+.5*d,o*f+.5*f)}}return void(t.globalAlpha=1)}t.font=`${m}px "JetBrains Mono", monospace`,t.textAlign="left",t.textBaseline="middle";const g="matrix"===n.colorMode?"rgb(0,255,0)":"grayscale"===n.colorMode?w(a)?"rgb(230,230,230)":"rgb(24,24,24)":`rgb(${c},${l},${h})`;t.fillStyle=g,t.globalAlpha=1;const p=R.get(t),M=i&&p&&p.cols===e.cols&&p.rowCount===e.rowCount&&p.canvasWidth===o&&p.canvasHeight===r&&p.fillStyle===g;M||t.clearRect(0,0,o,r);for(let n=0;n<e.rows.length;n++){const r=e.rows[n];M&&p.rows[n]===r||(M&&t.clearRect(0,n*f,o,f+1),0!==r.trim().length&&t.fillText(r,.5*d,n*f+.5*f))}R.set(t,{rows:e.rows.slice(),cols:e.cols,rowCount:e.rowCount,canvasWidth:o,canvasHeight:r,fillStyle:g}),t.globalAlpha=1}async function U(t,e,n,o,r=12,a=10,i,s=0){const c=Math.min(t.duration-s,a),l=Math.ceil(c*r),h=[];let d=0,f=0;for(let a=0;a<l;a++){const m=s+a/r;if(m>s+c)break;t.currentTime=m,await new Promise(e=>{const n=()=>{t.removeEventListener("seeked",n),e()};t.addEventListener("seeked",n)});const u=q(t,e,n,o);h.push(u.frame),d=u.cols,f=u.rows,i?.((a+1)/l)}return{frames:h,cols:d,rows:f,fps:r}}async function N(t,e,n,o,r=12,a=10,i,s=0){const c=Math.min(t.duration-s,a),l=Math.ceil(c*r),h=[];let d=0,f=0;for(let a=0;a<l;a++){const m=s+a/r;if(m>s+c)break;t.currentTime=m,await new Promise(e=>{const n=()=>{t.removeEventListener("seeked",n),e()};t.addEventListener("seeked",n)});const u=D(t,e,n,o);h.push(u),d=u.cols,f=u.rowCount,i?.((a+1)/l)}return{frames:h,cols:d,rows:f,fps:r}}async function K(t,e,n,o,r){const{parseGIF:a,decompressFrames:i}=await import("gifuct-js"),s=a(t),c=i(s,!0);if(0===c.length)return{frames:[],cols:0,rows:0,fps:10};const l=c[0].dims.width,h=c[0].dims.height,d=s.lsd?.width||l,f=s.lsd?.height||h,m=document.createElement("canvas");m.width=d,m.height=f;const u=m.getContext("2d"),g=document.createElement("canvas");g.width=d,g.height=f;const p=g.getContext("2d"),M=document.createElement("canvas"),v=M.getContext("2d"),w=[];let x=0,y=0,b=0;for(const t of c)b+=t.delay||100;const S=b/c.length,E=Math.round(Math.min(30,Math.max(5,1e3/S))),T=Math.min(c.length,300);for(let t=0;t<T;t++){const a=c[t],{dims:i,patch:s,disposalType:l}=a;3===l&&(p.clearRect(0,0,d,f),p.drawImage(m,0,0)),M.width!==i.width&&(M.width=i.width),M.height!==i.height&&(M.height=i.height);const h=new ImageData(new Uint8ClampedArray(s.buffer),i.width,i.height);v.putImageData(h,0,0),u.drawImage(M,i.left||0,i.top||0);const b=q(m,e,n,o);w.push(b.frame),x=b.cols,y=b.rows,2===l?u.clearRect(i.left||0,i.top||0,i.width,i.height):3===l&&(u.clearRect(0,0,d,f),u.drawImage(g,0,0)),r?.((t+1)/T)}return{frames:w,cols:x,rows:y,fps:E}}var Y=new WeakMap,_=new WeakMap,G=new WeakMap;function X(t,e,n,o,r,a=0,i){if(!e.length||!e[0].length||o<=0||r<=0)return;let s=null;if(n.hoverStrength>0){let e=Y.get(t);e||(e={x:.5,y:.5,intensity:0,time:-1,emittedAt:-1,points:[]},Y.set(t,e)),s=function(t,e,n){const o=t.time<0?1/60:Math.max(0,Math.min(.1,(n-t.time)/1e3));t.time=n;const r=t.intensity<.003,a=t.x,i=t.y;if(e){r&&(t.x=e.x,t.y=e.y);const n=1-Math.exp(-o/.055);t.x+=(e.x-t.x)*n,t.y+=(e.y-t.y)*n}t.intensity+=((e?.intensity??(e?1:0))-t.intensity)*(1-Math.exp(-o/(e?.09:.18)));const s=Math.exp(-o/.22);for(const e of t.points)e.intensity*=s;for(;t.points.length&&t.points[0].intensity<.01;)t.points.shift();return e&&!r&&n-t.emittedAt>=24&&Math.hypot(t.x-a,t.y-i)>5e-4&&(t.points.push({x:t.x,y:t.y,intensity:t.intensity,vx:Math.max(-1,Math.min(1,(t.x-a)/Math.max(o,.001))),vy:Math.max(-1,Math.min(1,(t.y-i)/Math.max(o,.001)))}),t.points.length>12&&t.points.shift(),t.emittedAt=n),!e&&t.intensity<.003&&!t.points.length?(t.intensity=0,null):{x:t.x,y:t.y,intensity:t.intensity,trail:t.points}}(e,i??null,performance.now())}else Y.delete(t);if("none"!==n.animationStyle||n.charsetFrames?.length||n.hoverStrength<=0)return G.delete(t),void J(t,e,n,o,r,a,s);const c=_.get(t);if(c?.frame!==e)return _.set(t,{frame:e,since:performance.now()}),G.delete(t),void J(t,e,n,o,r,a,s);if(performance.now()-c.since<100)return void J(t,e,n,o,r,a,s);const l=t.getTransform();if(l.b||l.c||l.a<=0||l.d<=0)return void J(t,e,n,o,r,a,s);if(!s||(s.intensity??0)<.003)return void J(t,e,n,o,r,a,null);const h=w(t.canvas),d={...n,accentColor:"#"+z(n.accentColor)},f=JSON.stringify([d,o,r,l.a,l.d,h,void 0!==document.fonts?document.fonts.status:"loaded"]);let m=G.get(t);if(!m||m.frame!==e||m.key!==f){const n=m?.canvas??document.createElement("canvas");n.width=Math.ceil(o*l.a),n.height=Math.ceil(r*l.d);const a=n.getContext("2d");a.setTransform(l.a,0,0,l.d,0,0),J(a,e,d,o,r,0,null,void 0,h),m={frame:e,key:f,canvas:n},G.set(t,m)}if(t.clearRect(0,0,o,r),t.drawImage(m.canvas,0,0,o,r),!s||(s.intensity??0)<.003)return;const u=e.length,g=e[0].length,p=.08+.35*n.hoverRadius+.04*n.hoverStrength,M="trail"===n.hoverEffect?[s,...s.trail??[]]:[s];let v=1,x=1,y=0,b=0;for(const t of M)v=Math.min(v,t.x-p),y=Math.max(y,t.x+p),x=Math.min(x,t.y-p),b=Math.max(b,t.y+p);if("glitchText"===n.hoverEffect){const t=n.hoverText,e=Math.max(1,...(Array.isArray(t)?t:[t]).map(t=>t.length));v=Math.min(v,s.x-e/g),y=Math.max(y,s.x+e/g)}const S=Math.ceil(5+4*n.hoverStrength),E={x:Math.max(0,Math.floor(v*g)-S),y:Math.max(0,Math.floor(x*u)-S),right:Math.min(g,Math.ceil(y*g)+S),bottom:Math.min(u,Math.ceil(b*u)+S)};t.save(),t.beginPath(),t.rect(E.x*o/g,E.y*r/u,(E.right-E.x)*o/g,(E.bottom-E.y)*r/u),t.clip(),J(t,e,d,o,r,a,s,E,h),t.restore()}function J(t,e,o,r,a,s=0,c,l,h){const d=e.length;if(0===d)return;const f=e[0].length;t.clearRect(0,0,r,a);let m=!1;const g=Math.max(1,d>>2),M=Math.max(1,f>>2);t:for(let t=0;t<d;t+=g){const n=e[t];for(let t=0;t<f;t+=M)if(n[t].a<200){m=!0;break t}}const v=t.canvas,x=h??w(v);m||(t.fillStyle=x?"#0a0a0a":"#faf9f7",t.fillRect(0,0,r,a));const y=r/f,b=a/d,E=c?.intensity??1,T=!!(c&&o.hoverStrength>0&&E>.005),C="#"+(j(o.hoverColor||"#ffffff")??"ffffff"),A=parseInt(C.slice(1,3),16),F=parseInt(C.slice(3,5),16),L=parseInt(C.slice(5,7),16),R=z(o.accentColor),I=parseInt(R.substring(0,2),16),H=parseInt(R.substring(2,4),16),P=parseInt(R.substring(4,6),16),O=o.hoverRadius;let V=0,q=f,D=0,B=d,U=0,N=0;if(T&&c){U=c.x,N=c.y;const t=.08+.35*O+.04*o.hoverStrength;V=Math.max(0,Math.floor((U-t)*f)-1),q=Math.min(f,Math.ceil((U+t)*f)+1),D=Math.max(0,Math.floor((N-t)*d)-1),B=Math.min(d,Math.ceil((N+t)*d)+1)}if(T&&"trail"===o.hoverEffect)for(const t of c?.trail??[]){const e=.08+.35*O+.04*o.hoverStrength;V=Math.min(V,Math.max(0,Math.floor((t.x-e)*f)-1)),q=Math.max(q,Math.min(f,Math.ceil((t.x+e)*f)+1)),D=Math.min(D,Math.max(0,Math.floor((t.y-e)*d)-1)),B=Math.max(B,Math.min(d,Math.ceil((t.y+e)*d)+1))}const K=o.animationStyle,Y=o.animationSpeed,_=(G=K,n.find(t=>t.value===G||t.mode===G)?.mode??"none");var G;const X="none"===_,J=[0,0,0,1],Q=o.hoverStrength,Z=o.hoverEffect,tt=O,et=o.hoverShape||"circle",nt=$(o.invert,v),ot=o.colorMode,rt=2*Math.PI,at=1/f,it=1/d;let st="",ct=-1;if("dots"===o.renderMode){const n=.5*Math.min(y,b)*o.dotSizeRatio;for(let o=l?.y??0;o<(l?.bottom??d);o++){const h=e[o];for(let e=l?.x??0;e<(l?.right??f);e++){const l=h[e];if(l.a<10)continue;const m=.00392156863*(.299*l.r+.587*l.g+.114*l.b),g=nt?1-m:m;if(g<.02)continue;X||i(_,e/f,o/d,s*Y,J,(.299*l.r+.587*l.g+.114*l.b)/255);const M=Math.max(0,Math.min(1,(1+J[2])*J[3]));let v=1,w=0,x=0,C=0,R=0;if(T&&e>=V&&e<=q&&o>=D&&o<=B){const t=S(e*at,o*it,U,N,E,Q,y,b,Z,tt,et,c?.trail,r/a);v=t.scale,w=t.offsetX,x=t.offsetY,C=t.glow,R=t.colorBlend}const k=n*g*M*v;if(k<.3)continue;const W=e*y+.5*y+w+J[0],$=o*b+.5*b+x+J[1];let j;if(R>0){const t=p(l,ot,I,H,P,nt);j=`rgb(${Math.min(255,t[0]+(A-t[0])*R|0)},${Math.min(255,t[1]+(F-t[1])*R|0)},${Math.min(255,t[2]+(L-t[2])*R|0)})`}else j=u(l,ot,I,H,P,nt);const z=Math.min(1,.00392156863*l.a*M*(1+C));if(z!==ct&&(t.globalAlpha=z,ct=z),j!==st&&(t.fillStyle=j,st=j),k<=3){const e=2*k;t.fillRect(W-k,$-k,e,e)}else t.beginPath(),t.arc(W,$,k,0,rt),t.fill()}}}else{const n=.55,h=.9*Math.min(y/n,b);{const e=/\p{Extended_Pictographic}/u.test(o.customText||o.charset);t.font=e?`${h}px "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Twemoji Mozilla", sans-serif`:`${h}px "JetBrains Mono", monospace`,t.textAlign="center",t.textBaseline="middle"}const m=o.charsetFrames,g=!!m?.length,M=g?m[Math.floor(Math.max(0,s)*(o.charsetFps??2))%m.length]:o.charset,v=t.getTransform();if(!T&&X&&!g&&"accent"===ot&&!l&&o.hoverStrength<=0&&!/\p{Extended_Pictographic}/u.test(o.customText||o.charset)&&"letterSpacing"in t&&/^[\x20-\x7e]*$/.test(o.customText||o.charset)&&e.every(t=>t.every(t=>t.a<10||255===t.a&&1===t.char.length&&/^[\x20-\x7e]$/.test(t.char)))){const n=t.letterSpacing;t.letterSpacing="0px";const o=t.measureText("M").width;t.letterSpacing=y-o+"px",t.fillStyle=`rgb(${I},${H},${P})`,t.globalAlpha=1,t.textAlign="left";for(let n=0;n<d;n++){const r=e[n];let a="";for(let t=0;t<f;t++){const e=r[t];a+=e.a<10?" ":e.char}0!==a.trim().length&&t.fillText(a,.5*(y-o),n*b+.5*b)}return t.letterSpacing=n,t.textAlign="center",void(t.globalAlpha=1)}const w="glitchText"===Z&&T,x="!@#$%^&*<>{}[]|/\\~`0123456789",C=x.length;let R="",$=0,j=0,z=0,K=0,G=0,rt=0;if(w){const t=o.hoverText??"ASCIIFY";if(j=Math.round(U*f),z=Math.round(N*d),Array.isArray(t)){const e=t.filter(t=>t.length>0);0===e.length&&e.push("ASCIIFY");R=e[((7*Math.floor(j/Math.max(1,Math.ceil(f/5)))+13*Math.floor(z/Math.max(1,Math.ceil(d/3))))%e.length+e.length)%e.length]}else R=t||"ASCIIFY";$=R.length,K=Math.max(3,Math.min(12,Math.round(d*O*.6)));const e=Math.floor(K/2);G=Math.max(0,z-e),G+K>d&&(G=Math.max(0,d-K)),rt=j-Math.floor($/2)}for(let n=l?.y??0;n<(l?.bottom??d);n++){const o=e[n];for(let h=l?.x??0;h<(l?.right??f);h++){const l=o[h];if(l.a<10)continue;let m=g&&null!=l.lum?W(l.lum,k(M),nt):l.char;if(" "===m)continue;X||i(_,h/f,n/d,s*Y,J,(.299*l.r+.587*l.g+.114*l.b)/255);const O=Math.max(0,Math.min(1,(1+J[2])*J[3]));if(O<.05)continue;let lt=1,ht=0,dt=0,ft=0,mt=0;if(T&&!w&&h>=V&&h<=q&&n>=D&&n<=B){const t=S(h*at,n*it,U,N,E,Q,y,b,Z,tt,et,c?.trail,r/a);if(lt=t.scale,ht=t.offsetX,dt=t.offsetY,ft=t.glow,mt=t.colorBlend,"trail"===Z&&t.proximity>0){const o=Math.max(0,Math.min(f-1,Math.round(h-t.offsetX/y))),r=e[Math.max(0,Math.min(d-1,Math.round(n-t.offsetY/b)))][o],a=r.lum??.299*r.r+.587*r.g+.114*r.b;m=W(Math.min(255,a+t.proximity*Q*65),k(M),nt)}}if(w&&n>=G&&n<G+K){const t=h-rt;if(t>=0&&t<$){const e=R[t],o=Math.abs(n-z)/Math.max(1,.5*K),r=Math.abs(h-j)/Math.max(1,$),a=Math.max(o,r),i=Math.max(0,Math.min(1,1-.9*a)),c=43758.5453*Math.sin(127.1*h+311.7*n+43758.5453*Math.floor(12*s));m=Math.abs(c-Math.floor(c))<i?e:x[Math.abs(Math.floor(97*c))%C],ft=.3+.7*i,mt=.3+.65*i}}const ut=h*y+.5*y+ht+J[0],gt=n*b+.5*b+dt+J[1];let pt;if(mt>0){const t=p(l,ot,I,H,P,nt);pt=`rgb(${Math.min(255,t[0]+(A-t[0])*mt|0)},${Math.min(255,t[1]+(F-t[1])*mt|0)},${Math.min(255,t[2]+(L-t[2])*mt|0)})`}else pt=u(l,ot,I,H,P,nt);const Mt=Math.min(1,.00392156863*l.a*O*(1+ft));Mt!==ct&&(t.globalAlpha=Mt,ct=Mt),pt!==st&&(t.fillStyle=pt,st=pt),1!==lt?(t.translate(ut,gt),t.scale(lt,lt),t.fillText(m,0,0),t.setTransform(v)):t.fillText(m,ut,gt)}}}t.globalAlpha=1}function Q(t="classic"){if("classic"!==t)throw new RangeError(`Art preset "${String(t)}" was removed in 4.1. Use a StudioStyle with asciify-engine/studio, or supply options.charset directly.`);return{artStyle:"classic"}}function Z(t){return Math.max(0,Math.min(1,t))}function tt(t){return"string"==typeof t?document.querySelector(t):t instanceof HTMLElement?t:null}function et(t){return"ascii"===t.renderMode&&"none"===t.animationStyle&&t.hoverStrength<=0&&!t.charsetFrames?.length}function nt(t,e={}){const n=Z(t),o=Z(n*(void 0===e.speed?1:Math.max(.001,e.speed)));return Z(e.ease?e.ease(o):o)}function ot(t,e,n={}){if(!Number.isFinite(t.duration)||t.duration<=0)return;const o=n.from??0,r=n.to??t.duration,a=Math.max(o,Math.min(r,t.duration)),i=nt(e,n),s=o+(a-o)*i;t.currentTime=Math.min(Math.max(o,s),Math.max(o,a-.04)),n.onUpdate?.(i,t)}function rt(t,e){return Math.abs(t.currentTime-e)<1/240?at(t):new Promise(n=>{const o=()=>{t.removeEventListener("seeked",o),n()};t.addEventListener("seeked",o,{once:!0});const r=t.fastSeek;r?r.call(t,e):t.currentTime=e})}function at(t){const e=t.requestVideoFrameCallback;return new Promise(e?n=>{let o=!1;const r=()=>{o||(o=!0,n())};e.call(t,r),window.setTimeout(r,32)}:t=>requestAnimationFrame(()=>t()))}function it(t,e={}){const n=tt(e.trigger)??t;t.pause();const o=e.gsap,r=e.ScrollTrigger??o?.ScrollTrigger;if(o&&r?.create){o.registerPlugin?.(r);const a=r.create({trigger:n,start:e.start??"top bottom",end:e.end??"bottom top",scrub:e.scrub??!0,onUpdate:n=>ot(t,n.progress,e)});return()=>a.kill?.()}return function(t,e,n){let o=0;const r=()=>{o=0;const r=e.getBoundingClientRect(),a=window.innerHeight||document.documentElement.clientHeight,i=r.height+a,s=i>0?Z((a-r.top)/i):0;ot(t,s,n)},a=()=>{o||(o=requestAnimationFrame(r))};return window.addEventListener("scroll",a,{passive:!0}),window.addEventListener("resize",a),a(),()=>{window.removeEventListener("scroll",a),window.removeEventListener("resize",a),o&&cancelAnimationFrame(o)}}(t,n,e)}function st(t,e,n){const o=e.gsap,r=e.ScrollTrigger??o?.ScrollTrigger;if(o&&r?.create){o.registerPlugin?.(r);const a=r.create({trigger:t,start:e.start??"top bottom",end:e.end??"bottom top",scrub:e.scrub??!0,onUpdate:t=>n(t.progress)});return()=>a.kill?.()}return function(t,e){let n=0;const o=()=>{n=0;const o=t.getBoundingClientRect(),r=window.innerHeight||document.documentElement.clientHeight,a=o.height+r,i=a>0?Z((r-o.top)/a):0;e(i)},r=()=>{n||(n=requestAnimationFrame(o))};return window.addEventListener("scroll",r,{passive:!0}),window.addEventListener("resize",r),r(),()=>{window.removeEventListener("scroll",r),window.removeEventListener("resize",r),n&&cancelAnimationFrame(n)}}(t,n)}function ct(t,e,n){if(!t||!e||!n.sourceCrop)return{w:t,h:e};const o=V(n.sourceCrop,t,e);return{w:Math.max(1,Math.round(o.width)),h:Math.max(1,Math.round(o.height))}}function lt(t,e,n,o){const r=o.chromaKey;if(null==r||!1===r)return!1;if(!0===r)return e>1.4*t&&e>1.4*n&&e>80;if("blue-screen"===r)return n>1.4*t&&n>1.4*e&&n>80;const a=x(r),i=(o.chromaKeyTolerance??60)**2,s=t-a.r,c=e-a.g,l=n-a.b;return s*s+c*c+l*l<=i}function ht(t,e,n){if(!e.chromaKey||!e.sourceCrop||"off"===e.chromaKeyTrimMode)return e;const o=t instanceof HTMLVideoElement?t.videoWidth:t.width,r=t instanceof HTMLVideoElement?t.videoHeight:t.height;if(!o||!r)return e;const a=V(e.sourceCrop,o,r),i=Math.min(360,Math.max(1,Math.round(a.width))),c=Math.max(1,Math.round(i*(a.height/a.width))),{ctx:l}=s(i,c);l.drawImage(t,a.x,a.y,a.width,a.height,0,0,i,c);const h=l.getImageData(0,0,i,c).data,d=Math.max(0,Math.min(255,e.chromaKeyTrimLuminanceThreshold??0));let f=i,m=c,u=-1,g=-1;for(let t=0;t<c;t++)for(let n=0;n<i;n++){const o=4*(t*i+n),r=h[o+3],a=h[o],s=h[o+1],c=h[o+2];r<=8||.2126*a+.7152*s+.0722*c<=d||lt(a,s,c,e)||(n<f&&(f=n),t<m&&(m=t),n>u&&(u=n),t>g&&(g=t))}if(u<f||g<m)return e;const p=Math.max(0,Math.min(.25,e.chromaKeyTrimPadding??.002)),M=Math.round(i*p),v=Math.round(c*p);f=Math.max(0,f-M),m=Math.max(0,m-v),u=Math.min(i-1,u+M),g=Math.min(c-1,g+v);const w=function(t,e,n,o,r){const a=r&&Number.isFinite(r)&&r>0?r:null;if(!a)return t;const i=e.x,s=e.y,c=e.x+e.width,l=e.y+e.height,h=Math.max(i,t.left),d=Math.max(s,t.top),f=Math.min(c,n-t.right),m=Math.min(l,o-t.bottom),u=Math.max(1,f-h),g=Math.max(1,m-d),p=h+u/2,M=d+g/2;let v=u,w=g;v/w<a?v=w*a:w=v/a;v>e.width&&(v=e.width,w=Math.max(g,Math.min(e.height,v/a)));w>e.height&&(w=e.height,v=Math.max(u,Math.min(e.width,w*a)));let x=p-v/2,y=M-w/2;return x=Math.max(i,Math.min(c-v,x)),y=Math.max(s,Math.min(l-w,y)),{left:x,top:y,right:n-(x+v),bottom:o-(y+w)}}({left:a.x+f/i*a.width,top:a.y+m/c*a.height,right:o-(a.x+(u+1)/i*a.width),bottom:r-(a.y+(g+1)/c*a.height)},{x:a.x,y:a.y,width:a.width,height:a.height},o,r,n);return{...e,sourceCrop:{unit:"pixel",...w,preserveAspect:!1}}}function dt(t){const e=t.sourceCrop;return e&&"pixel"===e.unit?void 0===e.left||void 0===e.top||void 0===e.right||void 0===e.bottom?null:{left:e.left,top:e.top,right:e.right,bottom:e.bottom}:null}async function ft(t,e,n,o,r){if(!e.chromaKey||!e.sourceCrop||"range"!==e.chromaKeyTrimMode)return e;const a=t.currentTime,i=function(t,e,n,o){const r=!0===o?{}:o||{},a=Math.max(0,r.from??e),i=r.to??n??(Number.isFinite(t.duration)?t.duration:a),s=Math.max(a,i-.04),c=Math.max(0,s-a),l=c>.1?[a,a+.25*c,a+.5*c,a+.75*c,s]:[a];return Array.from(new Set(l.map(t=>Math.max(0,Number(t.toFixed(3))))))}(t,n,o,r);let s=null;for(const n of i){await rt(t,n),await at(t);const o=dt(ht(t,e));o&&(s=s?{left:Math.min(s.left,o.left),top:Math.min(s.top,o.top),right:Math.min(s.right,o.right),bottom:Math.min(s.bottom,o.bottom)}:o)}return await rt(t,a),await at(t),s?{...e,sourceCrop:{unit:"pixel",...s,preserveAspect:!0}}:e}function mt(t,e,n=2048){return ut({sourceWidth:t,sourceHeight:e,maxRenderDimension:n})}function ut({sourceWidth:t,sourceHeight:e,cssWidth:n=0,cssHeight:o=0,maxRenderDimension:r=2048}){const a=Math.max(1,t),i=Math.max(1,e),s=a/i,c=Math.max(1,r),l=Math.min(1,c/Math.max(a,i)),h=Math.max(a,i)*l,d=Math.max(0,n,o),f=Math.min(c,Math.max(h,d));return s>=1?{renderW:Math.round(f),renderH:Math.round(f/s)}:{renderW:Math.round(f*s),renderH:Math.round(f)}}function gt(t,e,n,o){if(void 0===t)return;if("number"==typeof t)return t;const r=t.trim();if(r.endsWith("%")){const t=Number.parseFloat(r)/100;return Number.isFinite(t)?e*t:void 0}if(r.endsWith("px")){const t=Number.parseFloat(r);return Number.isFinite(t)?t:void 0}if(r.endsWith("vw")){const t=Number.parseFloat(r)/100;return Number.isFinite(t)?n*t:void 0}if(r.endsWith("vh")){const t=Number.parseFloat(r)/100;return Number.isFinite(t)?o*t:void 0}}function pt(t,e,n,o,r,a=2048,i={}){const{width:s,height:c}=e.getBoundingClientRect();if(!s||!c)return{renderW:0,renderH:0,dpr:1};const l="undefined"!=typeof window?window.innerWidth:s,h="undefined"!=typeof window?window.innerHeight:c,d=gt(i.width,s,l,h)??s,f=gt(i.height,c,l,h)??c,m=function(t,e,n,o,r){const a=t=>{const n=gt(t,e,o,r);return n&&n>0?n:0},i=t=>{const e=gt(t,n,o,r);return e&&e>0?e:0};return void 0===t?{x:0,y:0}:"number"==typeof t||"string"==typeof t?{x:a(t),y:i(t)}:{x:a(t.x),y:i(t.y)}}(i.bleed,s,c,l,h),u=d+2*m.x,g=f+2*m.y,{cssW:p,cssH:M}=function(t,e,n,o="contain"){if("fill"===o)return{cssW:t,cssH:e};let r=t,a=r/n;const i="cover"===o,s=a>e;return(i&&!s||!i&&s)&&(a=e,r=a*n),"scale-down"===o&&(r=Math.min(r,t),a=Math.min(a,e)),{cssW:Math.round(r),cssH:Math.round(a)}}(u,g,n,i.objectFit??"contain"),v="undefined"!=typeof window&&window.devicePixelRatio||1;let w,x;o&&r?({renderW:w,renderH:x}=ut({sourceWidth:o,sourceHeight:r,cssWidth:p,cssHeight:M,maxRenderDimension:a})):(w=p,x=M);const y=8e6,b=w*v*x*v>y?Math.sqrt(y/(w*x)):v;return t.width=Math.round(w*b),t.height=Math.round(x*b),t.style.width=`${p}px`,t.style.height=`${M}px`,{renderW:w,renderH:x,dpr:b}}async function Mt(t,n,{fontSize:o,artStyle:r="classic",options:a={},fitTo:i,objectFit:s,objectPosition:c,scale:l,width:h,height:d,bleed:f,preExtract:m=!1,fps:u,maxRenderDimension:g=2048,trim:p,scroll:M,maxCachedFrames:v=90,onReady:w,onFrame:x}={}){const y=p?.start??0,b=p?.end,S=o??a.fontSize??10;let T={...e,...Q(r),artStyle:r,...a,fontSize:S};const C=n.getContext("2d");if(!C)throw new Error("asciifyVideo: could not get 2d context from canvas.");const A="string"==typeof i?document.querySelector(i):i instanceof HTMLElement?i:null,F={objectFit:s,objectPosition:c,scale:l,width:h,height:d,bleed:f},L=function(t,e){var n;if(!function(t){return void 0!==t.objectFit||void 0!==t.objectPosition||void 0!==t.scale||void 0!==t.width||void 0!==t.height||void 0!==t.bleed}(e))return()=>{};const o={width:t.style.width,height:t.style.height,objectFit:t.style.objectFit,objectPosition:t.style.objectPosition,maxWidth:t.style.maxWidth,maxHeight:t.style.maxHeight,transformOrigin:t.style.transformOrigin,scale:t.style.getPropertyValue("scale")};if(e.objectFit&&(t.style.objectFit=e.objectFit),e.objectPosition&&(t.style.objectPosition=e.objectPosition,t.style.transformOrigin=e.objectPosition),void 0===e.scale&&void 0===e.bleed||(t.style.maxWidth="none",t.style.maxHeight="none"),void 0!==e.scale){const o=Number.isFinite(e.scale)&&e.scale>0?e.scale:1;t.style.setProperty("scale",String(o)),(n=t.style).transformOrigin||(n.transformOrigin=e.objectPosition??"center center")}return()=>{t.style.width=o.width,t.style.height=o.height,t.style.objectFit=o.objectFit,t.style.objectPosition=o.objectPosition,t.style.maxWidth=o.maxWidth,t.style.maxHeight=o.maxHeight,t.style.transformOrigin=o.transformOrigin,o.scale?t.style.setProperty("scale",o.scale):t.style.removeProperty("scale")}}(n,F),R=t=>()=>{t(),L()};if(m){let e;"string"==typeof t?(e=document.createElement("video"),e.crossOrigin="anonymous",e.src=t,e.readyState<2&&await new Promise((n,o)=>{e.onloadeddata=()=>n(),e.onerror=()=>o(new Error(`asciifyVideo: failed to load "${t}"`))})):e=t,T=await ft(e,T,y,b,M);const o=ct(e.videoWidth,e.videoHeight,T);A&&pt(n,A,o.w/o.h,o.w,o.h,g,F);const{renderW:r,renderH:a}=mt(o.w,o.h,g),i="undefined"!=typeof window&&window.devicePixelRatio||1,s=8e6,c=r*i*a*i>s?Math.sqrt(s/(r*a)):i;n.width===Math.round(r*c)&&n.height===Math.round(a*c)||(n.width=Math.round(r*c),n.height=Math.round(a*c));const l=void 0!==b?b-y:10,h=u??(M?18:void 0);if(et(T)){const{frames:t,fps:o}=await N(e,T,r,a,h,l,void 0,y),i=e=>{const n=t[e];n&&(C.save(),C.setTransform(c,0,0,c,0,0),B(C,n,T,r,a),C.restore(),x?.())};if(M){let o=!1,r=-1;const a=!0===M?{}:M,s=st(tt(a.trigger)??A??n,a,n=>{const s=nt(n,a),c=Math.max(0,Math.min(t.length-1,Math.round(s*(t.length-1))));c!==r&&(r=c,i(c),o||(o=!0,w?.(e)),a.onUpdate?.(s,e))});return i(0),o=!0,w?.(e),R(s)}let s,d=!1,f=0,m=performance.now(),u=!0;const g=1e3/o,p=n=>{d||(n-m>=g&&(i(f),f=(f+1)%t.length,m=n,u&&(u=!1,w?.(e))),s=requestAnimationFrame(p))};return s=requestAnimationFrame(p),R(()=>{d=!0,cancelAnimationFrame(s)})}const{frames:d,fps:f}=await U(e,T,r,a,h,l,void 0,y);if(!d.length)throw new Error("asciifyVideo: no frames were decoded.");let m=0;const p=performance.now(),v=E(n,(t,e)=>{M||(m=Math.floor((t-p)*f/1e3)%d.length),C.save(),C.setTransform(c,0,0,c,0,0),X(C,d[m],T,r,a,(t-p)/1e3,e),C.restore(),x?.()},{continuous:!M||"none"!==T.animationStyle||!!T.charsetFrames?.length,interactive:T.hoverStrength>0});let S;if(M){const t=!0===M?{}:M;S=st(tt(t.trigger)??A??n,t,n=>{m=Math.max(0,Math.min(d.length-1,Math.round(nt(n,t)*(d.length-1)))),v.wake(),t.onUpdate?.(n,e)})}return w?.(e),R(()=>{v.stop(),S?.()})}let I,k=!1;"string"==typeof t?(I=document.createElement("video"),I.crossOrigin="anonymous",I.src=t,I.muted=!0,I.loop=!0,I.playsInline=!0,I.setAttribute("playsinline",""),Object.assign(I.style,{position:"fixed",top:"0",left:"0",width:"1px",height:"1px",opacity:"0",pointerEvents:"none",zIndex:"-1"}),document.body.appendChild(I),k=!0,await new Promise((e,n)=>{I.onloadedmetadata=()=>e(),I.onerror=()=>n(new Error(`asciifyVideo: failed to load "${t}"`))}),await I.play().catch(()=>{})):(I=t,I.readyState<HTMLMediaElement.HAVE_METADATA&&await new Promise((t,e)=>{const n=()=>{I.removeEventListener("loadedmetadata",o),I.removeEventListener("error",r)},o=()=>{n(),t()},r=()=>{n(),e(new Error("asciifyVideo: provided video element failed to load metadata."))};I.addEventListener("loadedmetadata",o),I.addEventListener("error",r),I.load()}),I.paused&&await I.play().catch(()=>{})),y>0&&(I.currentTime=y,await new Promise(t=>{const e=()=>{I.removeEventListener("seeked",e),t()};I.addEventListener("seeked",e)}),await at(I));let H=null;(y>0||void 0!==b)&&(H=()=>{(void 0!==b&&I.currentTime>=b||y>0&&I.currentTime<y)&&(I.currentTime=y)},I.addEventListener("timeupdate",H)),T=await ft(I,T,y,b,M);let W=null;const P=ct(I.videoWidth,I.videoHeight,T);let{renderW:$,renderH:j}=mt(P.w,P.h,g);const z=t=>"frame"===T.chromaKeyTrimMode?ht(t,T,$/j):T;if(A){const t=P.w/P.h,e=P.w,o=P.h,r=pt(n,A,t,e,o,g,F);$=r.renderW,j=r.renderH;const a=n.getContext("2d");a&&a.setTransform(r.dpr,0,0,r.dpr,0,0),W=new ResizeObserver(()=>{const r=pt(n,A,t,e,o,g,F);$=r.renderW,j=r.renderH;const a=n.getContext("2d");a&&a.setTransform(r.dpr,0,0,r.dpr,0,0)}),W.observe(A)}else{const t="undefined"!=typeof window&&window.devicePixelRatio||1,e=8e6,o=$*t*j*t>e?Math.sqrt(e/($*j)):t;n.width===Math.round($*o)&&n.height===Math.round(j*o)||(n.width=Math.round($*o),n.height=Math.round(j*o)),C.setTransform(o,0,0,o,0,0)}let O=!0,V=null;const K=M&&!m,Y=u&&u>0?1e3/u:0;let _=0;const G=!K&&et(T);if(K&&"ascii"===T.renderMode&&"none"===T.animationStyle&&T.hoverStrength<=0&&!T.charsetFrames?.length){const t=!0===M?{}:M,e=tt(t.trigger)??A??n,o=t.from??y,r=t.to??b??I.duration,a=Math.max(o,Math.min(r,I.duration)),i=Math.max(.001,a-o),s=Math.min(60,Math.max(12,u??30)),c=Math.max(2,Math.ceil(i*s)+1),l=new Array(c),h=[],d=Math.max(2,Math.min(c,Math.floor(v))),f=()=>{for(;h.length>d;){const t=h.findIndex(t=>t!==g&&Math.abs(t-g)>2),e=t>=0?t:0,n=h.splice(e,1)[0];void 0!==n&&(l[n]=void 0)}},m=t=>{const e=h.indexOf(t);e>=0&&h.splice(e,1),h.push(t),f()};let g=0,p=0,S=-1,E=0,F=!1,L=!1,P=!1;const O=new Set,q=document.createElement("video");q.muted=!0,q.playsInline=!0,q.preload="auto",q.crossOrigin=I.crossOrigin||"anonymous",q.src=I.currentSrc||I.src,Object.assign(q.style,{position:"fixed",top:"0",left:"0",width:"1px",height:"1px",opacity:"0",pointerEvents:"none",zIndex:"-1"}),document.body.appendChild(q),q.readyState<HTMLMediaElement.HAVE_METADATA&&await new Promise((t,e)=>{const n=()=>{q.removeEventListener("loadedmetadata",o),q.removeEventListener("error",r)},o=()=>{n(),t()},r=()=>{n(),e(new Error("asciifyVideo: cache video failed to load metadata."))};q.addEventListener("loadedmetadata",o),q.addEventListener("error",r),q.load()}),q.pause(),I.paused&&await I.play().catch(()=>{});const U=t=>o+i*t/Math.max(1,c-1),N=t=>Math.max(0,Math.min(c-1,Math.round(t*(c-1)))),K=z(I),G=D(I,K,$,j);G.rows.length>0&&(l[0]=G,m(0),B(C,G,K,$,j),P=!0,w?.(I),x?.());const X=t=>{if(l[t])return t;for(let e=1;e<c;e++){const n=t-e,o=t+e;if(n>=0&&l[n])return n;if(o<c&&l[o])return o}return-1},J=()=>{if(!l[g])return g;for(const t of O)if(!l[t])return t;for(let t=1;t<c;t++){const e=g-t,n=g+t;if(e>=0&&!l[e])return e;if(n<c&&!l[n])return n}return-1},Q=t=>{t<0||t>=c||l[t]||(O.add(t),et())},et=async()=>{if(F||L)return;const t=J();if(!(t<0)){O.delete(t),L=!0;try{if(await rt(q,U(t)),!F){const e=z(q),n=D(q,e,$,j);n.rows.length>0&&(l[t]=n,m(t))}}finally{L=!1,F||requestAnimationFrame(()=>{et()})}}},ot=()=>{if(F)return;const t=X(g);if(t>=0&&t!==S){const e=l[t];e&&(B(C,e,T,$,j),S=t,P||(P=!0,w?.(I)),x?.())}else if(t<0||S<0){const t=performance.now();if(Y<=0||t-_>=Y){const e=z(I),n=D(I,e,$,j);n.rows.length>0&&(B(C,n,e,$,j),_=t,P||(P=!0,w?.(I)),x?.())}}Q(g),E=requestAnimationFrame(ot)};return V=st(e,t,e=>{const n=function(t,e,n={}){if(!Number.isFinite(t.duration)||t.duration<=0)return null;const o=n.from??0,r=n.to??t.duration,a=Math.max(o,Math.min(r,t.duration)),i=nt(e,n),s=o+(a-o)*i;return{progress:i,time:Math.min(Math.max(o,s),Math.max(o,a-.04))}}(I,e,{...t,from:o,to:a});p=n?.progress??Z(e),g=N(p),Q(g),Q(g-1),Q(g+1),Q(g-2),Q(g+2),Q(g-3),Q(g+3),t.onUpdate?.(p,I)}),Q(0),Q(1),E=requestAnimationFrame(ot),R(()=>{F=!0,cancelAnimationFrame(E),V?.(),W?.disconnect(),O.clear(),h.length=0,l.fill(void 0),q.pause(),q.src="",q.removeAttribute("src"),q.load(),q.isConnected&&q.remove(),H&&I.removeEventListener("timeupdate",H),k&&(I.pause(),I.src="",I.removeAttribute("src"),I.load(),I.isConnected&&I.remove())})}if(K){const t=!0===M?{}:M;V=it(I,{...t,trigger:t.trigger??A??n,from:t.from??y,to:t.to??b})}let J=-1,ot=0,lt=-1,dt=0;const ut="function"==typeof I.requestVideoFrameCallback,gt=()=>{dt=I.requestVideoFrameCallback(()=>{ot++,gt()})};ut&>();let Mt=0,vt=0,wt=null;const xt=E(n,(t,e)=>{if(I.readyState<2||0===n.width||0===n.height)return;if(Y>0&&t-_<Y&&!e)return;if(y>0&&I.currentTime<y)return;if(void 0!==b&&I.currentTime>=b)return;const o=(ut?ot!==lt:I.currentTime!==J)||Mt!==$||vt!==j;if(o||!(T.hoverStrength<=0)||"none"!==T.animationStyle||T.charsetFrames?.length){if(G){const t=z(I),e=D(I,t,$,j);B(C,e,t,$,j)}else!o&&wt||(wt=q(I,z(I),$,j).frame),X(C,wt,T,$,j,t/1e3,e);J=I.currentTime,lt=ot,Mt=$,vt=j,_=t,O&&(O=!1,w?.(I)),x?.()}},{continuous:!0,interactive:T.hoverStrength>0});return R(()=>{xt.stop(),dt&&I.cancelVideoFrameCallback(dt),V?.(),W?.disconnect(),H&&I.removeEventListener("timeupdate",H),k&&(I.pause(),I.src="",I.removeAttribute("src"),I.load(),I.isConnected&&I.remove())})}function vt(t,e,n,o="#505050",r=100){if(!t||e<=0||n<=0)return[];const a=function(t){const e=t.match(/^#([0-9a-f]{3,8})$/i)?.[1];if(e){const t=e.length<=4?e.split("").map(t=>parseInt(t+t,16)):[parseInt(e.slice(0,2),16),parseInt(e.slice(2,4),16),parseInt(e.slice(4,6),16)];return{r:t[0],g:t[1],b:t[2]}}const n=t.match(/rgba?\(\s*(\d+)[,\s]+(\d+)[,\s]+(\d+)/i);return n?{r:+n[1],g:+n[2],b:+n[3]}:null}(o)??{r:80,g:80,b:80},i=t,s=i.length;return Array.from({length:n},(t,n)=>Array.from({length:e},(t,o)=>({char:i[(n*e+o)%s],r:a.r,g:a.g,b:a.b,a:r})))}var wt=new WeakMap;function xt(t,{format:e="png",quality:n=.92,scale:o=1}={}){return new Promise((r,a)=>{let i=t;if(1!==o){const e=document.createElement("canvas");e.width=Math.round(t.width*o),e.height=Math.round(t.height*o);const n=e.getContext("2d");if(!n)return void a(new Error("captureSnapshot: could not get 2d context"));n.drawImage(t,0,0,e.width,e.height),i=e}i.toBlob(t=>t?r(t):a(new Error("captureSnapshot: toBlob returned null")),`image/${e}`,n)})}var yt={A:[28,54,99,127,99,99,99],B:[126,99,99,126,99,99,126],C:[62,99,96,96,96,99,62],D:[124,102,99,99,99,102,124],E:[127,96,96,124,96,96,127],F:[127,96,96,124,96,96,96],G:[62,99,96,111,99,99,62],H:[99,99,99,127,99,99,99],I:[127,8,8,8,8,8,127],J:[63,6,6,6,102,102,60],K:[99,102,108,120,108,102,99],L:[96,96,96,96,96,96,127],M:[99,119,107,107,99,99,99],N:[99,115,107,103,99,99,99],O:[62,99,99,99,99,99,62],P:[126,99,99,126,96,96,96],Q:[62,99,99,99,107,102,61],R:[126,99,99,126,108,102,99],S:[62,99,96,62,3,99,62],T:[127,8,8,8,8,8,8],U:[99,99,99,99,99,99,62],V:[99,99,99,99,54,28,8],W:[99,99,99,107,107,54,20],X:[99,54,28,8,28,54,99],Y:[99,99,54,28,8,8,8],Z:[127,3,6,12,24,48,127],a:[0,0,60,3,62,99,61],b:[96,96,124,99,99,99,124],c:[0,0,62,96,96,96,62],d:[3,3,31,99,99,99,31],e:[0,0,62,99,127,96,62],f:[30,48,48,126,48,48,48],g:[0,0,63,99,63,3,62],h:[96,96,124,99,99,99,99],i:[8,0,24,8,8,8,28],j:[4,0,12,4,4,36,24],k:[96,96,102,108,120,108,102],l:[24,8,8,8,8,8,28],m:[0,0,92,107,107,99,99],n:[0,0,94,99,99,99,99],o:[0,0,62,99,99,99,62],p:[0,0,126,99,126,96,96],q:[0,0,63,99,63,3,3],r:[0,0,94,99,96,96,96],s:[0,0,62,96,62,3,124],t:[48,48,126,48,48,48,30],u:[0,0,99,99,99,103,59],v:[0,0,99,99,54,28,8],w:[0,0,99,99,107,54,20],x:[0,0,99,54,28,54,99],y:[0,0,99,99,63,3,62],z:[0,0,127,6,12,24,127],0:[62,99,103,107,115,99,62],1:[8,24,56,8,8,8,62],2:[62,99,3,6,24,48,127],3:[62,99,3,30,3,99,62],4:[6,14,22,38,127,6,6],5:[127,96,126,3,3,99,62],6:[62,99,96,126,99,99,62],7:[127,3,6,12,24,24,24],8:[62,99,99,62,99,99,62],9:[62,99,99,63,3,99,62]," ":[0,0,0,0,0,0,0],"!":[24,24,24,24,24,0,24],"?":[62,99,3,14,8,0,8],".":[0,0,0,0,0,24,24],",":[0,0,0,0,0,24,48],";":[0,24,24,0,24,24,48],":":[0,24,24,0,24,24,0],"-":[0,0,0,62,0,0,0],_:[0,0,0,0,0,0,127],"'":[24,24,32,0,0,0,0],'"':[54,54,36,0,0,0,0],"`":[24,8,0,0,0,0,0],")":[24,12,6,6,6,12,24],"(":[12,24,48,48,48,24,12],"[":[60,48,48,48,48,48,60],"]":[30,6,6,6,6,6,30],"{":[14,24,24,48,24,24,14],"}":[56,12,12,6,12,12,56],"/":[3,6,12,24,48,96,0],"\\":[96,48,24,12,6,3,0],"|":[8,8,8,8,8,8,8],"+":[0,8,8,62,8,8,0],"=":[0,0,62,0,62,0,0],"*":[0,42,28,127,28,42,0],"#":[36,36,127,36,127,36,36],"@":[62,99,111,107,111,96,62],"&":[24,36,24,60,74,68,58],"%":[99,38,4,8,16,50,99],$:[8,62,72,62,9,62,8],"^":[8,20,34,0,0,0,0],"~":[0,0,50,76,0,0,0],"<":[6,12,24,48,24,12,6],">":[48,24,12,6,12,24,48]},bt=[127,65,65,65,65,65,127];function St(t){return yt[t]??yt[t.toUpperCase()]??bt}function Et(t,e={}){if(!t)return"";const{char:n="█",scale:o=1}=e,r=[...n][0]??"█",a=Math.max(1,Math.floor(o)),i=7*a,s=a,c=Array.from({length:i},()=>"");for(let e=0;e<t.length;e++){const n=St(t[e]);for(let t=0;t<7;t++){const e=n[t];let o="";for(let t=6;t>=0;t--)o+=(e>>t&1?r:" ").repeat(a);for(let e=0;e<a;e++)c[t*a+e]+=o}if(e<t.length-1)for(let t=0;t<i;t++)c[t]+=" ".repeat(s)}return c.join("\n")}exports.CHARACTER_SETS=t,exports.DEFAULT_OPTIONS=e,exports.HOVER_PRESETS={none:{label:"Off",options:{hoverStrength:0,hoverEffect:"spotlight",hoverRadius:.2,hoverColor:"#ffffff"}},subtle:{label:"Subtle",options:{hoverStrength:.25,hoverEffect:"glow",hoverRadius:.12,hoverColor:"#ffffff"}},flashlight:{label:"Flashlight",options:{hoverStrength:.6,hoverEffect:"spotlight",hoverRadius:.15,hoverColor:"#fffbe6"}},magnifier:{label:"Magnifier",options:{hoverStrength:.7,hoverEffect:"magnify",hoverRadius:.12,hoverColor:"#ffffff"}},forceField:{label:"Force Field",options:{hoverStrength:.7,hoverEffect:"repel",hoverRadius:.15,hoverColor:"#a0e8ff"}},neon:{label:"Neon",options:{hoverStrength:.6,hoverEffect:"colorShift",hoverRadius:.15,hoverColor:"#d946ef"}},fire:{label:"Fire",options:{hoverStrength:.7,hoverEffect:"spotlight",hoverRadius:.15,hoverColor:"#ff6b2b"}},ice:{label:"Ice",options:{hoverStrength:.5,hoverEffect:"glow",hoverRadius:.15,hoverColor:"#60d5f7"}},gravity:{label:"Gravity",options:{hoverStrength:.7,hoverEffect:"attract",hoverRadius:.18,hoverColor:"#a5d6ff"}},shatter:{label:"Shatter",options:{hoverStrength:.8,hoverEffect:"shatter",hoverRadius:.14,hoverColor:"#ff6090"}},ghost:{label:"Fluid trail",options:{hoverStrength:.55,hoverEffect:"trail",hoverRadius:.2,hoverColor:"#b39ddb"}},glitchReveal:{label:"Glitch Reveal",options:{hoverStrength:.8,hoverEffect:"glitchText",hoverRadius:.18,hoverColor:"#a3e635"}}},exports.PALETTE_THEMES={dracula:{name:"Dracula",accent:"#bd93f9",bg:"#282a36",fg:"#f8f8f2"},monokai:{name:"Monokai",accent:"#a6e22e",bg:"#272822",fg:"#f8f8f2"},nord:{name:"Nord",accent:"#88c0d0",bg:"#2e3440",fg:"#eceff4"},catppuccin:{name:"Catppuccin",accent:"#cba6f7",bg:"#1e1e2e",fg:"#cdd6f4"},solarized:{name:"Solarized",accent:"#268bd2",bg:"#002b36",fg:"#839496"},gruvbox:{name:"Gruvbox",accent:"#b8bb26",bg:"#282828",fg:"#ebdbb2"}},exports.STUDIO_STYLES=["ascii","blocks","braille","dots","lines","cross","diagonal","diamond","mixed","pixel","mosaic","lego","voxel","disco","dither","hex","led","cmyk"],exports.asciiText=function(t,n={},o,r){const a={...e,...n},{frame:i,cols:s}=q(t,a,o,r);if(!i.length||0===s)return"";const c=[];for(const t of i)c.push(t.map(t=>t.char).join(""));return c.join("\n")},exports.asciiTextAnsi=function(t,n={},o,r){const a={...e,...n},{frame:i,cols:s}=q(t,a,o,r);if(!i.length||0===s)return"";const c=[];for(const t of i){let e="";for(const n of t)" "===n.char||n.a<10?e+=" ":e+=`[38;2;${n.r};${n.g};${n.b}m${n.char}[0m`;c.push(e)}return c.join("\n")},exports.asciify=async function(t,n,{fontSize:o,artStyle:r="classic",options:a={}}={}){let i;if("string"==typeof t){const e=new Image;e.crossOrigin="anonymous",await new Promise((n,o)=>{e.onload=()=>n(),e.onerror=()=>o(new Error(`Failed to load image: ${t}`)),e.src=t}),i=e}else t instanceof HTMLImageElement&&!t.complete?(await new Promise((e,n)=>{t.onload=()=>e(),t.onerror=()=>n(new Error("Image failed to load"))}),i=t):i=t;const s=Q(r),c=o??a.fontSize??10,l={...e,...s,artStyle:r,...a,fontSize:c},h=n.getContext("2d");if(!h)throw new Error("Could not get 2d context from canvas");const{w:d,h:f}=function(t){return t instanceof HTMLVideoElement?{w:t.videoWidth,h:t.videoHeight}:t instanceof HTMLImageElement?{w:t.naturalWidth||t.width,h:t.naturalHeight||t.height}:{w:t.width,h:t.height}}(i),{renderW:m,renderH:u}=mt(d,f),g="undefined"!=typeof window&&window.devicePixelRatio||1,p=8e6,M=m*g*u*g>p?Math.sqrt(p/(m*u)):g;n.width===Math.round(m*M)&&n.height===Math.round(u*M)||(n.width=Math.round(m*M),n.height=Math.round(u*M));const{frame:v}=q(i,l,m,u),w=(t,e)=>{h.save(),h.setTransform(M,0,0,M,0,0),X(h,v,l,m,u,t/1e3,e),h.restore()};return w(0,null),E(n,w,{continuous:"none"!==l.animationStyle||!!l.charsetFrames?.length,interactive:l.hoverStrength>0}).stop},exports.asciifyGif=async function(t,n,{fontSize:o,artStyle:r="classic",options:a={}}={}){const i="string"==typeof t?await fetch(t).then(t=>t.arrayBuffer()):t,s=o??a.fontSize??10;let c={...e,...Q(r),artStyle:r,...a,fontSize:s};const l=n.getContext("2d");if(!l)throw new Error("Could not get 2d context from canvas");const{frames:h,fps:d}=await K(i,c,n.width,n.height);if(!h.length)throw new Error("asciifyGif: the GIF contains no renderable frames.");const f=performance.now();let m=-1;return E(n,(t,e)=>{const o=Math.floor((t-f)*d/1e3)%h.length;o===m&&!e&&c.hoverStrength<=0&&"none"===c.animationStyle&&!c.charsetFrames?.length||(X(l,h[o],c,n.width,n.height,(t-f)/1e3,e),m=o)},{continuous:!0,interactive:c.hoverStrength>0}).stop},exports.asciifyLiveVideo=function(t,e,n){return Mt(t,e,n)},exports.asciifyText=Et,exports.asciifyVideo=Mt,exports.asciifyWebcam=async function(t,{fontSize:n=10,style:o="classic",options:r={},liveOptions:a,mirror:i=!0,constraints:s={facingMode:"user"},dpr:c}={}){if(!navigator.mediaDevices?.getUserMedia)throw new Error("asciifyWebcam: getUserMedia is not supported in this browser.");const l=Q(o),h=await navigator.mediaDevices.getUserMedia({video:s}),d=document.createElement("video");d.srcObject=h,d.muted=!0,d.playsInline=!0,await new Promise((t,e)=>{d.onloadedmetadata=()=>t(),d.onerror=()=>e(new Error("asciifyWebcam: video stream failed to load.")),d.play().catch(e)});const f={...e,...l,...r,fontSize:n},m=t.getContext("2d");if(!m)throw new Error("asciifyWebcam: could not get 2d context from canvas.");const u=c??("undefined"!=typeof window?window.devicePixelRatio:1)??1;1!==u&&m.scale(u,u);let g=null;const p=e=>{const n=t.getBoundingClientRect();g={x:(e.clientX-n.left)/n.width,y:(e.clientY-n.top)/n.height}},M=()=>{g=null};f.hoverStrength>0&&(t.addEventListener("mousemove",p),t.addEventListener("mouseleave",M));let v,w=!1;const x=performance.now(),y=e=>{if(!w){if(d.readyState>=d.HAVE_CURRENT_DATA){const n=t.width/u,o=t.height/u,r=(e-x)/1e3,s=a?{...f,...a()}:f;s.hoverStrength>0?(t.addEventListener("mousemove",p),t.addEventListener("mouseleave",M)):(t.removeEventListener("mousemove",p),t.removeEventListener("mouseleave",M));const{frame:c}=q(d,s,n,o),l=g&&i?{x:1-g.x,y:g.y}:g;i?(m.save(),m.scale(-1,1),m.translate(-n,0),X(m,c,s,n,o,r,l),m.restore()):X(m,c,s,n,o,r,l)}v=requestAnimationFrame(y)}};return v=requestAnimationFrame(y),()=>{w=!0,cancelAnimationFrame(v),t.removeEventListener("mousemove",p),t.removeEventListener("mouseleave",M),h.getTracks().forEach(t=>t.stop()),d.srcObject=null}},exports.buildTextFrame=vt,exports.captureSnapshot=xt,exports.clearAsciifyCaches=function(){F.clear(),L.clear(),Y=new WeakMap,G=new WeakMap,_=new WeakMap,T=null,C=null},exports.computeCanvasRenderSize=ut,exports.createVideoScrollScrub=it,exports.gifToAsciiFrames=K,exports.gifToAsciiTextFrames=async function(t,e,n,o,r){const{parseGIF:a,decompressFrames:i}=await import("gifuct-js"),s=a(t),c=i(s,!0);if(0===c.length)return{frames:[],cols:0,rows:0,fps:10};const l=c[0].dims.width,h=c[0].dims.height,d=s.lsd?.width||l,f=s.lsd?.height||h,m=document.createElement("canvas");m.width=d,m.height=f;const u=m.getContext("2d"),g=document.createElement("canvas");g.width=d,g.height=f;const p=g.getContext("2d"),M=document.createElement("canvas"),v=M.getContext("2d"),w=[];let x=0,y=0,b=0;for(const t of c)b+=t.delay||100;const S=b/c.length,E=Math.round(Math.min(30,Math.max(5,1e3/S))),T=Math.min(c.length,300);for(let t=0;t<T;t++){const a=c[t],{dims:i,patch:s,disposalType:l}=a;3===l&&(p.clearRect(0,0,d,f),p.drawImage(m,0,0)),M.width!==i.width&&(M.width=i.width),M.height!==i.height&&(M.height=i.height);const h=new ImageData(new Uint8ClampedArray(s.buffer),i.width,i.height);v.putImageData(h,0,0),u.drawImage(M,i.left||0,i.top||0);const b=D(m,e,n,o);w.push(b),x=b.cols,y=b.rowCount,2===l?u.clearRect(i.left||0,i.top||0,i.width,i.height):3===l&&(u.clearRect(0,0,d,f),u.drawImage(g,0,0)),r?.((t+1)/T)}return{frames:w,cols:x,rows:y,fps:E}},exports.imageToAsciiFrame=q,exports.imageToAsciiTextFrame=D,exports.renderFrameToCanvas=X,exports.renderTextBackground=function(t,n,o,r,a={},i){const{fontSize:s=10,lineHeight:c=1.6,color:l="#505050",opacity:h=100,hoverEffect:d="spotlight",hoverStrength:f=.85,hoverRadius:m=.18,hoverColor:u="#d4ff00"}=a,g=Math.max(1,Math.floor(n/s)),p=Math.max(1,Math.floor(o/(s*c))),M=JSON.stringify([r,g,p,l,h]);let v=wt.get(t);v&&v.key===M||(v={key:M,frame:vt(r,g,p,l,h)},wt.set(t,v)),X(t,v.frame,{...e,fontSize:s,hoverEffect:d,hoverStrength:f,hoverRadius:m,hoverColor:u},n,o,0,i??null)},exports.renderTextFrameToCanvas=B,exports.renderTextToCanvas=function(t,e,n={}){const{color:o="#d4ff00",bgColor:r,fontSize:a=10}=n,i=Et(e,n);if(!i)return;const s=i.split("\n"),c=Math.max(...s.map(t=>[...t].length));t.width=Math.ceil(c*a*.6),t.height=Math.ceil(s.length*a);const l=t.getContext("2d");r&&"transparent"!==r?(l.fillStyle=r,l.fillRect(0,0,t.width,t.height)):l.clearRect(0,0,t.width,t.height),l.fillStyle=o,l.font=`${a}px monospace`,l.textBaseline="top",s.forEach((t,e)=>l.fillText(t,0,e*a))},exports.snapshotAndDownload=async function(t,e={}){const{filename:n="asciify-snapshot",format:o="png",...r}=e,a=await xt(t,{format:o,...r}),i="jpeg"===o?"jpg":o,s=document.createElement("a");s.href=URL.createObjectURL(a),s.download=`${n}.${i}`,s.click(),setTimeout(()=>URL.revokeObjectURL(s.href),1e4)},exports.videoToAsciiFrames=U,exports.videoToAsciiTextFrames=N;//# sourceMappingURL=core.cjs.map
|
|
1
|
+
"use strict";var t={standard:{label:"Classic ASCII",chars:" .:-=+*#%@"},asciify:{label:"Asciify",chars:" .:-=+ASCIIFY#@"},minimal:{label:"Minimal",chars:" .:+"},detailed:{label:"Detailed",chars:" .,:;i1tfLCG08@"},letters:{label:"Letters",chars:" .ilLCFTYASMW"},technical:{label:"Technical",chars:" .:;>_/[{}]=+*#@$"},blocks:{label:"Tonal blocks",chars:" ░▒▓█"},braille:{label:"Braille",chars:" ⠁⠃⠇⡇⣇⣧⣷⣿"}},e={fontSize:7,charSpacing:1,brightness:0,contrast:0,charset:t.standard.chars,colorMode:"grayscale",accentColor:"#d4ff00",invert:!1,renderMode:"ascii",animationStyle:"none",animationSpeed:1,dotSizeRatio:.8,ditherStrength:0,charAspect:.55,normalize:!1,hoverStrength:0,hoverRadius:.2,hoverEffect:"spotlight",hoverColor:"#ffffff",hoverShape:"circle",hoverText:"ASCIIFY",artStyle:"classic",fineDither:!1,customText:"",chromaKey:null,chromaKeyTolerance:60,chromaKeyTrimPadding:.002,chromaKeyTrimLuminanceThreshold:0,chromaKeyTrimMode:"range"},n=[{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."}];var o=t=>Math.max(0,Math.min(1,t)),r=(t,e,n)=>{const r=o((n-t)/(e-t));return r*r*(3-2*r)},i=(t,e)=>{const n=(.06711056*t+.00583715*e)%1*52.9829189;return n-Math.floor(n)};function a(t,e,n,a,s,c=.5){if(s[0]=s[1]=s[2]=0,s[3]=1,"none"===t)return s;const l=a*Math.PI/6,h=r(0,.12,Math.min(e,1-e,n,1-n));if("caustics"===t){const t=Math.sin(9*e+5*n+l)+Math.sin(8*n-3*e-l),o=Math.pow(Math.max(0,1-.72*Math.abs(t)),3);s[2]=(.22*o-.045)*h}else if("current"===t)s[0]=Math.sin(9*n+l)*Math.cos(7*e-l)*10*h,s[1]=Math.cos(8*e+l)*Math.sin(6*n-l)*7*h;else if("sheen"===t)s[2]=.2*Math.pow(.5+.5*Math.cos(5*e+3*n-l),8)-.025;else if("tidal"===t){const t=e-.5,o=n-.5,r=Math.hypot(t,o),i=Math.sin(22*r-l)*h;s[0]=t*i*9,s[1]=o*i*9,s[2]=.035*i}else if("grain"===t){const t=i(Math.floor(160*e),Math.floor(100*n))*Math.PI*2;s[2]=.07*Math.sin(l+t)}else if("parallax"===t){const t=.45+.55*Math.max(0,1-1.4*Math.hypot(e-.5,n-.5));s[0]=12*Math.sin(l)*t*h,s[1]=6*(Math.cos(l)-1)*t*h}else if("weave"===t)s[0]=Math.sin(n*Math.PI*6+l)*Math.sin(l)*8*h,s[1]=Math.sin(e*Math.PI*6-l)*Math.sin(l)*6*h;else if("print"===t){const t=Math.floor(24*n),e=((a+3*i(t,3))%12+12)%12,o=r(1,2.5,e)*(1-r(3.5,5,e));s[0]=Math.sin(2.4*t)*o*9*h,s[1]=5*-o*h,s[2]=.22*-o,s[3]=1-.45*o}else if("trace"===t){const t=.5+.5*Math.cos(l);s[2]=.22*Math.pow(Math.max(0,1-Math.abs(o(c)-t)/.16),3)-.015}else if("relight"===t){const t=n-.5,r=1.3*((e-.5)*Math.cos(l)+t*Math.sin(l));s[2]=.3*r*(.25+3*o(c)*(1-o(c)))*h}else if("shimmer"===t){const t=i(Math.floor(160*e),Math.floor(100*n))*Math.PI*2,o=Math.pow(.5+.5*Math.cos(l+t),10);s[2]=.28*(o-.1762)*r(.35,.9,c)}else if("breeze"===t){const t=Math.sin(l-4*n),o=.35+.65*(1-n);s[0]=10*t*o*h,s[1]=2.5*Math.sin(2*l-4*n+3*e)*o*h,s[2]=.035*Math.cos(l-4*n)*h}else if("unfold"===t){const t=Math.floor(12*e),n=12*e-t-.5,o=((a-.11*t)%12+12)%12,i=r(1,3,o)*(1-r(5,7,o));s[0]=-n*i*24*h,s[1]=Math.sin(1.7*t)*i*3*h,s[2]=.12*-i,s[3]=1-.65*i}else if("reform"===t){const t=(a%12+12)%12,o=i(Math.floor(160*e),Math.floor(100*n)),c=.65*e+.2*n+.15*o+.08*Math.sin(8*e-5*n),d=r(1.8+1.2*c,3.8+1.2*c,t)*(1-r(5+1.7*c,7.2+1.7*c,t));s[0]=Math.sin(9*n+l)*d*(1-d)*24*h,s[1]=-d*(1-d)*(8+12*o)*h,s[2]=.45*-d,s[3]=1-.9*d}return s}function s(t,e){const n=document.createElement("canvas");n.width=t,n.height=e;const o=n.getContext("2d",{willReadFrequently:!0});return{canvas:n,ctx:o}}function c(t,e,n){let o=t+255*e;return o=259*(255*n+255)/(255*(259-255*n))*(o-128)+128,Math.max(0,Math.min(255,o))}function l(t,e,n,o,r,i){if((i?1-t/255:t/255)<.12)return" ";const a=[...e];return a[(o*r+n)%a.length]}var h=[[0,8,2,10],[12,4,14,6],[3,11,1,9],[15,7,13,5]];function d(t,e,n,o){if(o<=0)return t;const r=(h[n%4][e%4]/16-.5)*o*128;return Math.max(0,Math.min(255,t+r))}var f=new Array(256),m=new Array(256);for(let t=0;t<256;t++)f[t]=`rgb(${t},${t},${t})`,m[t]=`rgb(0,${t},0)`;function u(t,e,n,o,r,i=!1){switch(e){case"fullcolor":return`rgb(${t.r},${t.g},${t.b})`;case"matrix":return m[.299*t.r+.587*t.g+.114*t.b|0];case"accent":return`rgb(${n},${o},${r})`;default:{const e=.299*t.r+.587*t.g+.114*t.b|0;return f[e]}}}var g=[0,0,0];function p(t,e,n,o,r,i=!1){switch(e){case"fullcolor":g[0]=t.r,g[1]=t.g,g[2]=t.b;break;case"matrix":{const e=.299*t.r+.587*t.g+.114*t.b|0;g[0]=0,g[1]=e,g[2]=0;break}case"accent":g[0]=n,g[1]=o,g[2]=r;break;default:{const e=.299*t.r+.587*t.g+.114*t.b|0;g[0]=e,g[1]=e,g[2]=e;break}}return g}function M(t){const e=t.match(/rgba?\(\s*(\d+)\s*[,\s]\s*(\d+)\s*[,\s]\s*(\d+)(?:\s*[,/]\s*([\d.]+))?\s*\)/);return e?{r:+e[1],g:+e[2],b:+e[3],a:void 0!==e[4]?+e[4]:1}:null}function v(t){let e=t;for(;e&&e!==document.documentElement.parentElement;){const t=getComputedStyle(e).backgroundColor;if(t&&"transparent"!==t&&"rgba(0, 0, 0, 0)"!==t){const e=M(t);if(e&&e.a>.1)return e}e=e.parentElement}return null}function w(t){if(t){const e=v(t);if(e){return(.299*e.r+.587*e.g+.114*e.b)/255<.4}}if("undefined"!=typeof document){const t=document.documentElement,e=(t.getAttribute("data-theme")||"").toLowerCase();if("dark"===e)return!0;if("light"===e)return!1;if(t.classList.contains("dark"))return!0;if(document.body){const t=v(document.body);if(t){return(.299*t.r+.587*t.g+.114*t.b)/255<.4}}}return"undefined"!=typeof window&&window.matchMedia("(prefers-color-scheme: dark)").matches}function x(t){if("string"!=typeof t)return t;const e=document.createElement("canvas");e.width=1,e.height=1;const n=e.getContext("2d");n.fillStyle=t,n.fillRect(0,0,1,1);const o=n.getImageData(0,0,1,1).data;return{r:o[0],g:o[1],b:o[2]}}function y(t){return t*t*(3-2*t)}var b={scale:1,offsetX:0,offsetY:0,glow:0,colorBlend:0,proximity:0};function S(t,e,n,o,r,i,a,s,c="spotlight",l=.5,h="circle",d=[],f=1){const m=(t-n)*Math.max(1,f),u=(e-o)*Math.max(1,1/f),g=.08+.35*l+.04*i;let p,M;if("box"===h){const t=Math.abs(m),e=Math.abs(u);p=Math.max(t,e),M=g}else p=Math.sqrt(m*m+u*u),M=g;if(p>=M&&("trail"!==c||0===d.length))return b.scale=1,b.offsetX=0,b.offsetY=0,b.glow=0,b.colorBlend=0,b.proximity=0,b;const v=y(Math.max(0,1-p/M))*r;let w=1,x=0,S=0,E=0,T=0;switch(c){case"spotlight":{w=1+v*i*1.8;const t=Math.atan2(u,m),e=v*v*i*.6;x=Math.cos(t)*e*a,S=Math.sin(t)*e*s,E=v*i*.4,T=v*v*i*.25;break}case"magnify":w=1+v*i*.85,E=v*i*.15;break;case"repel":{w=1;const t=Math.atan2(u,m),e=v*v*i*1.8;x=Math.cos(t)*e*a,S=Math.sin(t)*e*s;break}case"glow":E=v*i*.8,T=v*i*.4;break;case"colorShift":w=1,E=v*i*.12,T=v*i;break;case"attract":{const t=Math.atan2(u,m),e=v*v*i*1;x=(.45*-Math.cos(t)-1.6*Math.sin(t))*e*a,S=(.45*-Math.sin(t)+1.6*Math.cos(t))*e*s,E=v*i*.3;break}case"shatter":{const t=Math.atan2(u,m),e=.5*Math.sin(43.7*m+29.3*u),n=v*i*1.4*(.7+.3*e);x=Math.cos(t+e)*n*a,S=Math.sin(t+e)*n*s,w=Math.max(.1,1-v*i*.6),E=v*i*.25;break}case"trail":{let n=v,o=-u*v,r=m*v;for(const i of d){const a=(t-i.x)*Math.max(1,f),s=(e-i.y)*Math.max(1,1/f),c=Math.hypot(a,s)/g;if(c>=1)continue;const l=y(1-c)*i.intensity;n=Math.max(n,l),o+=(.35*i.vx-2*s)*l*.35,r+=(.35*i.vy+2*a)*l*.35}x=Math.tanh(2*o)*i*a*3,S=Math.tanh(2*r)*i*s*3,T=n*i*.65,E=n*i*.35,w=1+n*i*.08,b.proximity=n;break}case"glitchText":w=1,E=v*i*.5,T=v*i*.6}return b.scale=w,b.offsetX=x,b.offsetY=S,b.glow=E,b.colorBlend=T,"trail"!==c&&(b.proximity=v),b}function E(t,e,{continuous:n=!1,interactive:o=!1}={}){const r=t.parentElement??t;let i=null,a=0,s=!1,c=!0,l=!0,h=-1/0;const d=window.matchMedia("(prefers-reduced-motion: reduce)"),f=()=>{l=!0,s||!c||document.hidden||a||(a=requestAnimationFrame(m))},m=t=>{if(a=0,s||!c||document.hidden)return;const o=!d.matches&&(n||t-h<1500);(l||o)&&(e(t,d.matches?null:i),l=!1),o&&(a=requestAnimationFrame(m))},u=e=>{if("touch"===e.pointerType)return;const n=t.getBoundingClientRect();if(!n.width||!n.height)return;const o=(e.clientX-n.left)/n.width,r=(e.clientY-n.top)/n.height;i=o>=0&&o<=1&&r>=0&&r<=1?{x:o,y:r}:null,h=performance.now(),f()},g=()=>{i=null,h=performance.now(),f()},p=()=>{document.hidden&&a?(cancelAnimationFrame(a),a=0):f()},M="undefined"==typeof IntersectionObserver?null:new IntersectionObserver(([t])=>{c=t.isIntersecting,c?f():a&&(cancelAnimationFrame(a),a=0)});return M?.observe(t),o&&(r.addEventListener("pointermove",u),r.addEventListener("pointerleave",g)),document.addEventListener("visibilitychange",p),d.addEventListener("change",f),f(),{wake:f,stop:()=>{s=!0,cancelAnimationFrame(a),M?.disconnect(),r.removeEventListener("pointermove",u),r.removeEventListener("pointerleave",g),document.removeEventListener("visibilitychange",p),d.removeEventListener("change",f)}}}var T=null,C=null;function A(t,e){if(!T||!C){const n=s(t,e);T=n.canvas,C=n.ctx}return T.width!==t&&(T.width=t),T.height!==e&&(T.height=e),C}var F=new Map,L=new Map,R=new WeakMap;function I(t){const e=Intl.Segmenter;return e?Array.from(new e(void 0,{granularity:"grapheme"}).segment(t),({segment:t})=>t):[...t]}function k(t){let e=F.get(t);return e||(e=I(t),F.set(t,e)),e}function H(t){return I(t)}function W(t,e,n){const o=n?1-t/255:t/255,r=Math.floor(o*(e.length-1));return e[Math.max(0,Math.min(e.length-1,r))]??" "}function P(t,e,n,o){const r=`${t}\0${e?1:0}\0${n}\0${o}`;let i=L.get(r);if(!i){const a=k(t);i=new Array(256);for(let t=0;t<256;t++)i[t]=W(c(t,n,o),a,e);L.set(r,i)}return i}function $(t,e){return"auto"!==t?t:!w(e)}function j(t){const e=t.match(/^#([0-9a-fA-F]{3,6})$/);if(e){let t=e[1];if(3===t.length&&(t=t[0]+t[0]+t[1]+t[1]+t[2]+t[2]),6===t.length)return t}const n=t.match(/rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);return n?[n[1],n[2],n[3]].map(t=>parseInt(t).toString(16).padStart(2,"0")).join(""):null}function z(t){const e=t||"auto";if("auto"!==e)return j(e)??"ffffff";if("undefined"!=typeof document){const t=getComputedStyle(document.documentElement);for(const e of["--accent-color","--color-accent","--accent","--color-primary","--primary","--brand-color"]){const n=j(t.getPropertyValue(e).trim());if(n)return n}const e=j(getComputedStyle(document.body).accentColor??"");if(e)return e}return w("undefined"!=typeof document?document.body:null)?"faf9f7":"0d0d0d"}function O(t,e,n){return Math.max(e,Math.min(n,t))}function V(t,e,n){if(!t)return{x:0,y:0,width:e,height:n};const o=t.unit??"percent",r=!1!==t.preserveAspect,i=t=>void 0===t?void 0:"percent"===o?t*e:t,a=t=>void 0===t?void 0:"percent"===o?t*n:t,s=O(i(t.left)??0,0,e-1),c=O(i(t.right)??0,0,e-s-1),l=O(a(t.top)??0,0,n-1),h=O(a(t.bottom)??0,0,n-l-1),d=void 0!==t.left||void 0!==t.right||void 0!==t.top||void 0!==t.bottom,f=Math.max(1,e-s-c),m=Math.max(1,n-l-h),u=d?f:i(t.width),g=d?m:a(t.height);let p=u??e,M=g??n;if(r&&!d){const t=p/e,o=M/n,r=Math.min(t,o),i=void 0===u?o:void 0===g?t:r;p=e*i,M=n*i}p=O(p,1,d?f:e),M=O(M,1,d?m:n);const v=t.anchor??"center",w=i(t.x),x=a(t.y),y=d?s:0,b=d?l:0,S=d?f:e,E=d?m:n,T=v.endsWith("left")||"left"===v?0:v.endsWith("right")||"right"===v?S-p:(S-p)/2,C=v.startsWith("top")||"top"===v?0:v.startsWith("bottom")||"bottom"===v?E-M:(E-M)/2;return{x:O(w??y+T,0,Math.max(0,e-p)),y:O(x??b+C,0,Math.max(0,n-M)),width:p,height:M}}function q(t,e,n,o){const r=t instanceof HTMLVideoElement?t.videoWidth:t.width,i=t instanceof HTMLVideoElement?t.videoHeight:t.height;if(0===r||0===i)return{frame:[],cols:0,rows:0};const a=e.charAspect,s=e.fontSize*e.charSpacing,h=e.fontSize/a*e.charSpacing,f=n||r,m=o||i,u=Math.floor(f/s),g=Math.floor(m/h);if(u<=0||g<=0)return{frame:[],cols:0,rows:0};const p=V(e.sourceCrop,r,i),M=Math.max(1,Math.min(Math.floor(2048/u),Math.floor(p.width/u))),v=Math.max(1,Math.min(Math.floor(2048/g),Math.floor(p.height/g))),w=u*M,y=g*v,b=A(w,y),S=b.globalCompositeOperation;b.globalCompositeOperation="copy";try{b.drawImage(t,p.x,p.y,p.width,p.height,0,0,w,y)}finally{b.globalCompositeOperation=S}const E=b.getImageData(0,0,w,y).data,T=e.chromaKey,C=null!=T&&!1!==T,F=!0===T,L="blue-screen"===T;let R=null,I=0;!C||F||L||(R=x(T),I=(e.chromaKeyTolerance??60)**2);let H=0,j=255;if(e.normalize){let t=255,e=0;for(let n=0;n<E.length;n+=4){if(C){const t=E[n],e=E[n+1],o=E[n+2];let r=!1;if(F)r=e>1.4*t&&e>1.4*o&&e>80;else if(L)r=o>1.4*t&&o>1.4*e&&o>80;else if(null!==R){const n=t-R.r,i=e-R.g,a=o-R.b;r=n*n+i*i+a*a<=I}if(r)continue}const o=.299*E[n]+.587*E[n+1]+.114*E[n+2];o<t&&(t=o),o>e&&(e=o)}H=t,j=e>t?e-t:255}const z=[],O=$(e.invert),q=C&&e.charset.replace(/ /g,"")||e.charset,B=k(q),D=e.customText?null:P(q,O,e.brightness,e.contrast),U=M*v;for(let t=0;t<g;t++){const n=[];for(let o=0;o<u;o++){let r=0,i=0,a=0,s=0,h=0;for(let e=0;e<v;e++){const n=(t*v+e)*w;for(let t=0;t<M;t++){const e=4*(n+o*M+t),c=E[e],l=E[e+1],d=E[e+2],f=E[e+3];if(C){let t=!1;if(F)t=l>1.4*c&&l>1.4*d&&l>80;else if(L)t=d>1.4*c&&d>1.4*l&&d>80;else if(null!==R){const e=c-R.r,n=l-R.g,o=d-R.b;t=e*e+n*n+o*o<=I}if(t){h++;continue}}r+=c,i+=l,a+=d,s+=f}}if(C&&h>U/2){n.push({char:" ",r:0,g:0,b:0,a:0});continue}const f=U-h,m=f>0?r/f:0,g=f>0?i/f:0,p=f>0?a/f:0,x=f>0?s/f:0,y=.299*m+.587*g+.114*p,b=e.normalize?(y-H)/j*255:y,S=c(b,e.brightness,e.contrast),T=e.ditherStrength>0?d(S,o,t,e.ditherStrength):S,A=e.customText?l(T,e.customText,o,t,u,O):e.ditherStrength>0?W(T,B,O):D[Math.max(0,Math.min(255,0|b))];n.push({char:A,r:m,g:g,b:p,a:x,lum:T})}z.push(n)}return{frame:z,cols:u,rows:g}}function B(t,e,n,o){const r=t instanceof HTMLVideoElement?t.videoWidth:t.width,i=t instanceof HTMLVideoElement?t.videoHeight:t.height;if(0===r||0===i)return{rows:[],cols:0,rowCount:0};const a=e.charAspect,s=e.fontSize*e.charSpacing,l=e.fontSize/a*e.charSpacing,h=n||r,f=o||i,m=Math.floor(h/s),u=Math.floor(f/l);if(m<=0||u<=0)return{rows:[],cols:0,rowCount:0};const g=m,p=u,M=A(g,p),v=V(e.sourceCrop,r,i),w=M.globalCompositeOperation;M.globalCompositeOperation="copy";try{M.drawImage(t,v.x,v.y,v.width,v.height,0,0,g,p)}finally{M.globalCompositeOperation=w}const y=M.getImageData(0,0,g,p).data,b=e.chromaKey,S=null!=b&&!1!==b,E=!0===b,T="blue-screen"===b;let C=null,F=0;!S||E||T||(C=x(b),F=(e.chromaKeyTolerance??60)**2);let L=0,R=255;if(e.normalize){let t=255,e=0;for(let n=0;n<y.length;n+=4){if(S){const t=y[n],e=y[n+1],o=y[n+2];let r=!1;if(E)r=e>1.4*t&&e>1.4*o&&e>80;else if(T)r=o>1.4*t&&o>1.4*e&&o>80;else if(null!==C){const n=t-C.r,i=e-C.g,a=o-C.b;r=n*n+i*i+a*a<=F}if(r)continue}const o=.299*y[n]+.587*y[n+1]+.114*y[n+2];o<t&&(t=o),o>e&&(e=o)}L=t,R=e>t?e-t:255}const I=$(e.invert),H=S&&e.charset.replace(/ /g,"")||e.charset,j=k(H),z=e.customText?null:P(H,I,e.brightness,e.contrast),O=e.customText?k(e.customText):null,q="fullcolor"===e.colorMode?new Uint8ClampedArray(m*u*4):void 0,B=[];for(let t=0;t<u;t++){let n="";for(let o=0;o<m;o++){const r=4*(t*g+o),i=r,a=y[r],s=y[r+1],l=y[r+2],h=y[r+3];if(S){let t=!1;if(E)t=s>1.4*a&&s>1.4*l&&s>80;else if(T)t=l>1.4*a&&l>1.4*s&&l>80;else if(null!==C){const e=a-C.r,n=s-C.g,o=l-C.b;t=e*e+n*n+o*o<=F}if(t){n+=" ",q&&(q[i]=0,q[i+1]=0,q[i+2]=0,q[i+3]=0);continue}}q&&(q[i]=a,q[i+1]=s,q[i+2]=l,q[i+3]=h);const f=.299*a+.587*s+.114*l,u=e.normalize?(f-L)/R*255:f,p=e.ditherStrength>0||O?c(u,e.brightness,e.contrast):u,M=e.ditherStrength>0?d(p,o,t,e.ditherStrength):p;if(O){n+=(I?1-M/255:M/255)<.12?" ":O[(t*m+o)%O.length]}else e.ditherStrength<=0?n+=z[Math.max(0,Math.min(255,0|u))]:n+=W(M,j,I)}B.push(n)}return{rows:B,cols:m,rowCount:u,colors:q}}function D(t,e,n,o,r){if(0===e.rows.length)return;const i=t.canvas,a=Boolean(n.chromaKey)||e.rows.some(t=>t.includes(" "));a||(R.delete(t),t.clearRect(0,0,o,r),t.fillStyle=w(i)?"#0a0a0a":"#faf9f7",t.fillRect(0,0,o,r));const s=z(n.accentColor),c=parseInt(s.substring(0,2),16),l=parseInt(s.substring(2,4),16),h=parseInt(s.substring(4,6),16),d=o/e.cols,f=r/e.rowCount,m=.9*Math.min(d/.55,f),u=e.colors;if("fullcolor"===n.colorMode&&u){R.delete(t),t.clearRect(0,0,o,r),t.font=`${m}px "JetBrains Mono", monospace`,t.textAlign="left",t.textBaseline="middle",t.globalAlpha=1;let n="";for(let o=0;o<e.rows.length;o++){const r=H(e.rows[o]);let i=0;for(;i<e.cols;){for(;i<e.cols&&" "===r[i];)i++;if(i>=e.cols)break;const a=i,s=4*(o*e.cols+i),c=240&u[s],l=240&u[s+1],h=240&u[s+2];for(i++;i<e.cols&&" "!==r[i];){const t=4*(o*e.cols+i);if((240&u[t])!==c||(240&u[t+1])!==l||(240&u[t+2])!==h)break;i++}const m=`rgb(${c},${l},${h})`;m!==n&&(t.fillStyle=m,n=m),t.fillText(r.slice(a,i).join(""),a*d+.5*d,o*f+.5*f)}}return void(t.globalAlpha=1)}t.font=`${m}px "JetBrains Mono", monospace`,t.textAlign="left",t.textBaseline="middle";const g="matrix"===n.colorMode?"rgb(0,255,0)":"grayscale"===n.colorMode?w(i)?"rgb(230,230,230)":"rgb(24,24,24)":`rgb(${c},${l},${h})`;t.fillStyle=g,t.globalAlpha=1;const p=R.get(t),M=a&&p&&p.cols===e.cols&&p.rowCount===e.rowCount&&p.canvasWidth===o&&p.canvasHeight===r&&p.fillStyle===g;M||t.clearRect(0,0,o,r);for(let n=0;n<e.rows.length;n++){const r=e.rows[n];M&&p.rows[n]===r||(M&&t.clearRect(0,n*f,o,f+1),0!==r.trim().length&&t.fillText(r,.5*d,n*f+.5*f))}R.set(t,{rows:e.rows.slice(),cols:e.cols,rowCount:e.rowCount,canvasWidth:o,canvasHeight:r,fillStyle:g}),t.globalAlpha=1}async function U(t,e,n,o,r=12,i=10,a,s=0){const c=Math.min(t.duration-s,i),l=Math.ceil(c*r),h=[];let d=0,f=0;for(let i=0;i<l;i++){const m=s+i/r;if(m>s+c)break;t.currentTime=m,await new Promise(e=>{const n=()=>{t.removeEventListener("seeked",n),e()};t.addEventListener("seeked",n)});const u=q(t,e,n,o);h.push(u.frame),d=u.cols,f=u.rows,a?.((i+1)/l)}return{frames:h,cols:d,rows:f,fps:r}}async function N(t,e,n,o,r=12,i=10,a,s=0){const c=Math.min(t.duration-s,i),l=Math.ceil(c*r),h=[];let d=0,f=0;for(let i=0;i<l;i++){const m=s+i/r;if(m>s+c)break;t.currentTime=m,await new Promise(e=>{const n=()=>{t.removeEventListener("seeked",n),e()};t.addEventListener("seeked",n)});const u=B(t,e,n,o);h.push(u),d=u.cols,f=u.rowCount,a?.((i+1)/l)}return{frames:h,cols:d,rows:f,fps:r}}async function K(t,e,n,o,r){const{parseGIF:i,decompressFrames:a}=await import("gifuct-js"),s=i(t),c=a(s,!0);if(0===c.length)return{frames:[],cols:0,rows:0,fps:10};const l=c[0].dims.width,h=c[0].dims.height,d=s.lsd?.width||l,f=s.lsd?.height||h,m=document.createElement("canvas");m.width=d,m.height=f;const u=m.getContext("2d"),g=document.createElement("canvas");g.width=d,g.height=f;const p=g.getContext("2d"),M=document.createElement("canvas"),v=M.getContext("2d"),w=[];let x=0,y=0,b=0;for(const t of c)b+=t.delay||100;const S=b/c.length,E=Math.round(Math.min(30,Math.max(5,1e3/S))),T=Math.min(c.length,300);for(let t=0;t<T;t++){const i=c[t],{dims:a,patch:s,disposalType:l}=i;3===l&&(p.clearRect(0,0,d,f),p.drawImage(m,0,0)),M.width!==a.width&&(M.width=a.width),M.height!==a.height&&(M.height=a.height);const h=new ImageData(new Uint8ClampedArray(s.buffer),a.width,a.height);v.putImageData(h,0,0),u.drawImage(M,a.left||0,a.top||0);const b=q(m,e,n,o);w.push(b.frame),x=b.cols,y=b.rows,2===l?u.clearRect(a.left||0,a.top||0,a.width,a.height):3===l&&(u.clearRect(0,0,d,f),u.drawImage(g,0,0)),r?.((t+1)/T)}return{frames:w,cols:x,rows:y,fps:E}}var Y=new WeakMap,_=new WeakMap,G=new WeakMap;function X(t,e,n,o,r,i=0,a){if(!e.length||!e[0].length||o<=0||r<=0)return;let s=null;if(n.hoverStrength>0){let e=Y.get(t);e||(e={x:.5,y:.5,intensity:0,time:-1,emittedAt:-1,points:[]},Y.set(t,e)),s=function(t,e,n){const o=t.time<0?1/60:Math.max(0,Math.min(.1,(n-t.time)/1e3));t.time=n;const r=t.intensity<.003,i=t.x,a=t.y;if(e){r&&(t.x=e.x,t.y=e.y);const n=1-Math.exp(-o/.055);t.x+=(e.x-t.x)*n,t.y+=(e.y-t.y)*n}t.intensity+=((e?.intensity??(e?1:0))-t.intensity)*(1-Math.exp(-o/(e?.09:.18)));const s=Math.exp(-o/.22);for(const e of t.points)e.intensity*=s;for(;t.points.length&&t.points[0].intensity<.01;)t.points.shift();return e&&!r&&n-t.emittedAt>=24&&Math.hypot(t.x-i,t.y-a)>5e-4&&(t.points.push({x:t.x,y:t.y,intensity:t.intensity,vx:Math.max(-1,Math.min(1,(t.x-i)/Math.max(o,.001))),vy:Math.max(-1,Math.min(1,(t.y-a)/Math.max(o,.001)))}),t.points.length>12&&t.points.shift(),t.emittedAt=n),!e&&t.intensity<.003&&!t.points.length?(t.intensity=0,null):{x:t.x,y:t.y,intensity:t.intensity,trail:t.points}}(e,a??null,performance.now())}else Y.delete(t);if("none"!==n.animationStyle||n.charsetFrames?.length||n.hoverStrength<=0)return G.delete(t),void J(t,e,n,o,r,i,s);const c=_.get(t);if(c?.frame!==e)return _.set(t,{frame:e,since:performance.now()}),G.delete(t),void J(t,e,n,o,r,i,s);if(performance.now()-c.since<100)return void J(t,e,n,o,r,i,s);const l=t.getTransform();if(l.b||l.c||l.a<=0||l.d<=0)return void J(t,e,n,o,r,i,s);if(!s||(s.intensity??0)<.003)return void J(t,e,n,o,r,i,null);const h=w(t.canvas),d={...n,accentColor:"#"+z(n.accentColor)},f=JSON.stringify([d,o,r,l.a,l.d,h,void 0!==document.fonts?document.fonts.status:"loaded"]);let m=G.get(t);if(!m||m.frame!==e||m.key!==f){const n=m?.canvas??document.createElement("canvas");n.width=Math.ceil(o*l.a),n.height=Math.ceil(r*l.d);const i=n.getContext("2d");i.setTransform(l.a,0,0,l.d,0,0),J(i,e,d,o,r,0,null,void 0,h),m={frame:e,key:f,canvas:n},G.set(t,m)}if(t.clearRect(0,0,o,r),t.drawImage(m.canvas,0,0,o,r),!s||(s.intensity??0)<.003)return;const u=e.length,g=e[0].length,p=.08+.35*n.hoverRadius+.04*n.hoverStrength,M="trail"===n.hoverEffect?[s,...s.trail??[]]:[s];let v=1,x=1,y=0,b=0;for(const t of M)v=Math.min(v,t.x-p),y=Math.max(y,t.x+p),x=Math.min(x,t.y-p),b=Math.max(b,t.y+p);if("glitchText"===n.hoverEffect){const t=n.hoverText,e=Math.max(1,...(Array.isArray(t)?t:[t]).map(t=>t.length));v=Math.min(v,s.x-e/g),y=Math.max(y,s.x+e/g)}const S=Math.ceil(5+4*n.hoverStrength),E={x:Math.max(0,Math.floor(v*g)-S),y:Math.max(0,Math.floor(x*u)-S),right:Math.min(g,Math.ceil(y*g)+S),bottom:Math.min(u,Math.ceil(b*u)+S)};t.save(),t.beginPath(),t.rect(E.x*o/g,E.y*r/u,(E.right-E.x)*o/g,(E.bottom-E.y)*r/u),t.clip(),J(t,e,d,o,r,i,s,E,h),t.restore()}function J(t,e,o,r,i,s=0,c,l,h){const d=e.length;if(0===d)return;const f=e[0].length;t.clearRect(0,0,r,i);let m=!1;const g=Math.max(1,d>>2),M=Math.max(1,f>>2);t:for(let t=0;t<d;t+=g){const n=e[t];for(let t=0;t<f;t+=M)if(n[t].a<200){m=!0;break t}}const v=t.canvas,x=h??w(v);m||(t.fillStyle=x?"#0a0a0a":"#faf9f7",t.fillRect(0,0,r,i));const y=r/f,b=i/d,E=c?.intensity??1,T=!!(c&&o.hoverStrength>0&&E>.005),C="#"+(j(o.hoverColor||"#ffffff")??"ffffff"),A=parseInt(C.slice(1,3),16),F=parseInt(C.slice(3,5),16),L=parseInt(C.slice(5,7),16),R=z(o.accentColor),I=parseInt(R.substring(0,2),16),H=parseInt(R.substring(2,4),16),P=parseInt(R.substring(4,6),16),O=o.hoverRadius;let V=0,q=f,B=0,D=d,U=0,N=0;if(T&&c){U=c.x,N=c.y;const t=.08+.35*O+.04*o.hoverStrength;V=Math.max(0,Math.floor((U-t)*f)-1),q=Math.min(f,Math.ceil((U+t)*f)+1),B=Math.max(0,Math.floor((N-t)*d)-1),D=Math.min(d,Math.ceil((N+t)*d)+1)}if(T&&"trail"===o.hoverEffect)for(const t of c?.trail??[]){const e=.08+.35*O+.04*o.hoverStrength;V=Math.min(V,Math.max(0,Math.floor((t.x-e)*f)-1)),q=Math.max(q,Math.min(f,Math.ceil((t.x+e)*f)+1)),B=Math.min(B,Math.max(0,Math.floor((t.y-e)*d)-1)),D=Math.max(D,Math.min(d,Math.ceil((t.y+e)*d)+1))}const K=o.animationStyle,Y=o.animationSpeed,_=(G=K,n.find(t=>t.value===G||t.mode===G)?.mode??"none");var G;const X="none"===_,J=[0,0,0,1],Q=o.hoverStrength,Z=o.hoverEffect,tt=O,et=o.hoverShape||"circle",nt=$(o.invert,v),ot=o.colorMode,rt=2*Math.PI,it=1/f,at=1/d;let st="",ct=-1;if("dots"===o.renderMode){const n=.5*Math.min(y,b)*o.dotSizeRatio;for(let o=l?.y??0;o<(l?.bottom??d);o++){const h=e[o];for(let e=l?.x??0;e<(l?.right??f);e++){const l=h[e];if(l.a<10)continue;const m=.00392156863*(.299*l.r+.587*l.g+.114*l.b),g=nt?1-m:m;if(g<.02)continue;X||a(_,e/f,o/d,s*Y,J,(.299*l.r+.587*l.g+.114*l.b)/255);const M=Math.max(0,Math.min(1,(1+J[2])*J[3]));let v=1,w=0,x=0,C=0,R=0;if(T&&e>=V&&e<=q&&o>=B&&o<=D){const t=S(e*it,o*at,U,N,E,Q,y,b,Z,tt,et,c?.trail,r/i);v=t.scale,w=t.offsetX,x=t.offsetY,C=t.glow,R=t.colorBlend}const k=n*g*M*v;if(k<.3)continue;const W=e*y+.5*y+w+J[0],$=o*b+.5*b+x+J[1];let j;if(R>0){const t=p(l,ot,I,H,P,nt);j=`rgb(${Math.min(255,t[0]+(A-t[0])*R|0)},${Math.min(255,t[1]+(F-t[1])*R|0)},${Math.min(255,t[2]+(L-t[2])*R|0)})`}else j=u(l,ot,I,H,P,nt);const z=Math.min(1,.00392156863*l.a*M*(1+C));if(z!==ct&&(t.globalAlpha=z,ct=z),j!==st&&(t.fillStyle=j,st=j),k<=3){const e=2*k;t.fillRect(W-k,$-k,e,e)}else t.beginPath(),t.arc(W,$,k,0,rt),t.fill()}}}else{const n=.55,h=.9*Math.min(y/n,b);{const e=/\p{Extended_Pictographic}/u.test(o.customText||o.charset);t.font=e?`${h}px "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Twemoji Mozilla", sans-serif`:`${h}px "JetBrains Mono", monospace`,t.textAlign="center",t.textBaseline="middle"}const m=o.charsetFrames,g=!!m?.length,M=g?m[Math.floor(Math.max(0,s)*(o.charsetFps??2))%m.length]:o.charset,v=t.getTransform();if(!T&&X&&!g&&"accent"===ot&&!l&&o.hoverStrength<=0&&!/\p{Extended_Pictographic}/u.test(o.customText||o.charset)&&"letterSpacing"in t&&/^[\x20-\x7e]*$/.test(o.customText||o.charset)&&e.every(t=>t.every(t=>t.a<10||255===t.a&&1===t.char.length&&/^[\x20-\x7e]$/.test(t.char)))){const n=t.letterSpacing;t.letterSpacing="0px";const o=t.measureText("M").width;t.letterSpacing=y-o+"px",t.fillStyle=`rgb(${I},${H},${P})`,t.globalAlpha=1,t.textAlign="left";for(let n=0;n<d;n++){const r=e[n];let i="";for(let t=0;t<f;t++){const e=r[t];i+=e.a<10?" ":e.char}0!==i.trim().length&&t.fillText(i,.5*(y-o),n*b+.5*b)}return t.letterSpacing=n,t.textAlign="center",void(t.globalAlpha=1)}const w="glitchText"===Z&&T,x="!@#$%^&*<>{}[]|/\\~`0123456789",C=x.length;let R="",$=0,j=0,z=0,K=0,G=0,rt=0;if(w){const t=o.hoverText??"ASCIIFY";if(j=Math.round(U*f),z=Math.round(N*d),Array.isArray(t)){const e=t.filter(t=>t.length>0);0===e.length&&e.push("ASCIIFY");R=e[((7*Math.floor(j/Math.max(1,Math.ceil(f/5)))+13*Math.floor(z/Math.max(1,Math.ceil(d/3))))%e.length+e.length)%e.length]}else R=t||"ASCIIFY";$=R.length,K=Math.max(3,Math.min(12,Math.round(d*O*.6)));const e=Math.floor(K/2);G=Math.max(0,z-e),G+K>d&&(G=Math.max(0,d-K)),rt=j-Math.floor($/2)}for(let n=l?.y??0;n<(l?.bottom??d);n++){const o=e[n];for(let h=l?.x??0;h<(l?.right??f);h++){const l=o[h];if(l.a<10)continue;let m=g&&null!=l.lum?W(l.lum,k(M),nt):l.char;if(" "===m)continue;X||a(_,h/f,n/d,s*Y,J,(.299*l.r+.587*l.g+.114*l.b)/255);const O=Math.max(0,Math.min(1,(1+J[2])*J[3]));if(O<.05)continue;let lt=1,ht=0,dt=0,ft=0,mt=0;if(T&&!w&&h>=V&&h<=q&&n>=B&&n<=D){const t=S(h*it,n*at,U,N,E,Q,y,b,Z,tt,et,c?.trail,r/i);if(lt=t.scale,ht=t.offsetX,dt=t.offsetY,ft=t.glow,mt=t.colorBlend,"trail"===Z&&t.proximity>0){const o=Math.max(0,Math.min(f-1,Math.round(h-t.offsetX/y))),r=e[Math.max(0,Math.min(d-1,Math.round(n-t.offsetY/b)))][o],i=r.lum??.299*r.r+.587*r.g+.114*r.b;m=W(Math.min(255,i+t.proximity*Q*65),k(M),nt)}}if(w&&n>=G&&n<G+K){const t=h-rt;if(t>=0&&t<$){const e=R[t],o=Math.abs(n-z)/Math.max(1,.5*K),r=Math.abs(h-j)/Math.max(1,$),i=Math.max(o,r),a=Math.max(0,Math.min(1,1-.9*i)),c=43758.5453*Math.sin(127.1*h+311.7*n+43758.5453*Math.floor(12*s));m=Math.abs(c-Math.floor(c))<a?e:x[Math.abs(Math.floor(97*c))%C],ft=.3+.7*a,mt=.3+.65*a}}const ut=h*y+.5*y+ht+J[0],gt=n*b+.5*b+dt+J[1];let pt;if(mt>0){const t=p(l,ot,I,H,P,nt);pt=`rgb(${Math.min(255,t[0]+(A-t[0])*mt|0)},${Math.min(255,t[1]+(F-t[1])*mt|0)},${Math.min(255,t[2]+(L-t[2])*mt|0)})`}else pt=u(l,ot,I,H,P,nt);const Mt=Math.min(1,.00392156863*l.a*O*(1+ft));Mt!==ct&&(t.globalAlpha=Mt,ct=Mt),pt!==st&&(t.fillStyle=pt,st=pt),1!==lt?(t.translate(ut,gt),t.scale(lt,lt),t.fillText(m,0,0),t.setTransform(v)):t.fillText(m,ut,gt)}}}t.globalAlpha=1}function Q(t="classic"){if("classic"!==t)throw new RangeError(`Art preset "${String(t)}" was removed in 4.1. Use a StudioStyle with asciify-engine/studio, or supply options.charset directly.`);return{artStyle:"classic"}}function Z(t){return Math.max(0,Math.min(1,t))}function tt(t){return"string"==typeof t?document.querySelector(t):t instanceof HTMLElement?t:null}function et(t){return"ascii"===t.renderMode&&"none"===t.animationStyle&&t.hoverStrength<=0&&!t.charsetFrames?.length}function nt(t,e={}){const n=Z(t),o=Z(n*(void 0===e.speed?1:Math.max(.001,e.speed)));return Z(e.ease?e.ease(o):o)}function ot(t,e,n={}){if(!Number.isFinite(t.duration)||t.duration<=0)return;const o=n.from??0,r=n.to??t.duration,i=Math.max(o,Math.min(r,t.duration)),a=nt(e,n),s=o+(i-o)*a;t.currentTime=Math.min(Math.max(o,s),Math.max(o,i-.04)),n.onUpdate?.(a,t)}function rt(t,e){return Math.abs(t.currentTime-e)<1/240?it(t):new Promise(n=>{const o=()=>{t.removeEventListener("seeked",o),n()};t.addEventListener("seeked",o,{once:!0});const r=t.fastSeek;r?r.call(t,e):t.currentTime=e})}function it(t){const e=t.requestVideoFrameCallback;return new Promise(e?n=>{let o=!1;const r=()=>{o||(o=!0,n())};e.call(t,r),window.setTimeout(r,32)}:t=>requestAnimationFrame(()=>t()))}function at(t,e={}){const n=tt(e.trigger)??t;t.pause();const o=e.gsap,r=e.ScrollTrigger??o?.ScrollTrigger;if(o&&r?.create){o.registerPlugin?.(r);const i=r.create({trigger:n,start:e.start??"top bottom",end:e.end??"bottom top",scrub:e.scrub??!0,onUpdate:n=>ot(t,n.progress,e)});return()=>i.kill?.()}return function(t,e,n){let o=0;const r=()=>{o=0;const r=e.getBoundingClientRect(),i=window.innerHeight||document.documentElement.clientHeight,a=r.height+i,s=a>0?Z((i-r.top)/a):0;ot(t,s,n)},i=()=>{o||(o=requestAnimationFrame(r))};return window.addEventListener("scroll",i,{passive:!0}),window.addEventListener("resize",i),i(),()=>{window.removeEventListener("scroll",i),window.removeEventListener("resize",i),o&&cancelAnimationFrame(o)}}(t,n,e)}function st(t,e,n){const o=e.gsap,r=e.ScrollTrigger??o?.ScrollTrigger;if(o&&r?.create){o.registerPlugin?.(r);const i=r.create({trigger:t,start:e.start??"top bottom",end:e.end??"bottom top",scrub:e.scrub??!0,onUpdate:t=>n(t.progress)});return()=>i.kill?.()}return function(t,e){let n=0;const o=()=>{n=0;const o=t.getBoundingClientRect(),r=window.innerHeight||document.documentElement.clientHeight,i=o.height+r,a=i>0?Z((r-o.top)/i):0;e(a)},r=()=>{n||(n=requestAnimationFrame(o))};return window.addEventListener("scroll",r,{passive:!0}),window.addEventListener("resize",r),r(),()=>{window.removeEventListener("scroll",r),window.removeEventListener("resize",r),n&&cancelAnimationFrame(n)}}(t,n)}function ct(t,e,n){if(!t||!e||!n.sourceCrop)return{w:t,h:e};const o=V(n.sourceCrop,t,e);return{w:Math.max(1,Math.round(o.width)),h:Math.max(1,Math.round(o.height))}}function lt(t,e,n,o){const r=o.chromaKey;if(null==r||!1===r)return!1;if(!0===r)return e>1.4*t&&e>1.4*n&&e>80;if("blue-screen"===r)return n>1.4*t&&n>1.4*e&&n>80;const i=x(r),a=(o.chromaKeyTolerance??60)**2,s=t-i.r,c=e-i.g,l=n-i.b;return s*s+c*c+l*l<=a}function ht(t,e,n){if(!e.chromaKey||!e.sourceCrop||"off"===e.chromaKeyTrimMode)return e;const o=t instanceof HTMLVideoElement?t.videoWidth:t.width,r=t instanceof HTMLVideoElement?t.videoHeight:t.height;if(!o||!r)return e;const i=V(e.sourceCrop,o,r),a=Math.min(360,Math.max(1,Math.round(i.width))),c=Math.max(1,Math.round(a*(i.height/i.width))),{ctx:l}=s(a,c);l.drawImage(t,i.x,i.y,i.width,i.height,0,0,a,c);const h=l.getImageData(0,0,a,c).data,d=Math.max(0,Math.min(255,e.chromaKeyTrimLuminanceThreshold??0));let f=a,m=c,u=-1,g=-1;for(let t=0;t<c;t++)for(let n=0;n<a;n++){const o=4*(t*a+n),r=h[o+3],i=h[o],s=h[o+1],c=h[o+2];r<=8||.2126*i+.7152*s+.0722*c<=d||lt(i,s,c,e)||(n<f&&(f=n),t<m&&(m=t),n>u&&(u=n),t>g&&(g=t))}if(u<f||g<m)return e;const p=Math.max(0,Math.min(.25,e.chromaKeyTrimPadding??.002)),M=Math.round(a*p),v=Math.round(c*p);f=Math.max(0,f-M),m=Math.max(0,m-v),u=Math.min(a-1,u+M),g=Math.min(c-1,g+v);const w=function(t,e,n,o,r){const i=r&&Number.isFinite(r)&&r>0?r:null;if(!i)return t;const a=e.x,s=e.y,c=e.x+e.width,l=e.y+e.height,h=Math.max(a,t.left),d=Math.max(s,t.top),f=Math.min(c,n-t.right),m=Math.min(l,o-t.bottom),u=Math.max(1,f-h),g=Math.max(1,m-d),p=h+u/2,M=d+g/2;let v=u,w=g;v/w<i?v=w*i:w=v/i;v>e.width&&(v=e.width,w=Math.max(g,Math.min(e.height,v/i)));w>e.height&&(w=e.height,v=Math.max(u,Math.min(e.width,w*i)));let x=p-v/2,y=M-w/2;return x=Math.max(a,Math.min(c-v,x)),y=Math.max(s,Math.min(l-w,y)),{left:x,top:y,right:n-(x+v),bottom:o-(y+w)}}({left:i.x+f/a*i.width,top:i.y+m/c*i.height,right:o-(i.x+(u+1)/a*i.width),bottom:r-(i.y+(g+1)/c*i.height)},{x:i.x,y:i.y,width:i.width,height:i.height},o,r,n);return{...e,sourceCrop:{unit:"pixel",...w,preserveAspect:!1}}}function dt(t){const e=t.sourceCrop;return e&&"pixel"===e.unit?void 0===e.left||void 0===e.top||void 0===e.right||void 0===e.bottom?null:{left:e.left,top:e.top,right:e.right,bottom:e.bottom}:null}async function ft(t,e,n,o,r){if(!e.chromaKey||!e.sourceCrop||"range"!==e.chromaKeyTrimMode)return e;const i=t.currentTime,a=function(t,e,n,o){const r=!0===o?{}:o||{},i=Math.max(0,r.from??e),a=r.to??n??(Number.isFinite(t.duration)?t.duration:i),s=Math.max(i,a-.04),c=Math.max(0,s-i),l=c>.1?[i,i+.25*c,i+.5*c,i+.75*c,s]:[i];return Array.from(new Set(l.map(t=>Math.max(0,Number(t.toFixed(3))))))}(t,n,o,r);let s=null;for(const n of a){await rt(t,n),await it(t);const o=dt(ht(t,e));o&&(s=s?{left:Math.min(s.left,o.left),top:Math.min(s.top,o.top),right:Math.min(s.right,o.right),bottom:Math.min(s.bottom,o.bottom)}:o)}return await rt(t,i),await it(t),s?{...e,sourceCrop:{unit:"pixel",...s,preserveAspect:!0}}:e}function mt(t,e,n=2048){return ut({sourceWidth:t,sourceHeight:e,maxRenderDimension:n})}function ut({sourceWidth:t,sourceHeight:e,cssWidth:n=0,cssHeight:o=0,maxRenderDimension:r=2048}){const i=Math.max(1,t),a=Math.max(1,e),s=i/a,c=Math.max(1,r),l=Math.min(1,c/Math.max(i,a)),h=Math.max(i,a)*l,d=Math.max(0,n,o),f=Math.min(c,Math.max(h,d));return s>=1?{renderW:Math.round(f),renderH:Math.round(f/s)}:{renderW:Math.round(f*s),renderH:Math.round(f)}}function gt(t,e,n,o){if(void 0===t)return;if("number"==typeof t)return t;const r=t.trim();if(r.endsWith("%")){const t=Number.parseFloat(r)/100;return Number.isFinite(t)?e*t:void 0}if(r.endsWith("px")){const t=Number.parseFloat(r);return Number.isFinite(t)?t:void 0}if(r.endsWith("vw")){const t=Number.parseFloat(r)/100;return Number.isFinite(t)?n*t:void 0}if(r.endsWith("vh")){const t=Number.parseFloat(r)/100;return Number.isFinite(t)?o*t:void 0}}function pt(t,e,n,o,r,i=2048,a={}){const{width:s,height:c}=e.getBoundingClientRect();if(!s||!c)return{renderW:0,renderH:0,dpr:1};const l="undefined"!=typeof window?window.innerWidth:s,h="undefined"!=typeof window?window.innerHeight:c,d=gt(a.width,s,l,h)??s,f=gt(a.height,c,l,h)??c,m=function(t,e,n,o,r){const i=t=>{const n=gt(t,e,o,r);return n&&n>0?n:0},a=t=>{const e=gt(t,n,o,r);return e&&e>0?e:0};return void 0===t?{x:0,y:0}:"number"==typeof t||"string"==typeof t?{x:i(t),y:a(t)}:{x:i(t.x),y:a(t.y)}}(a.bleed,s,c,l,h),u=d+2*m.x,g=f+2*m.y,{cssW:p,cssH:M}=function(t,e,n,o="contain"){if("fill"===o)return{cssW:t,cssH:e};let r=t,i=r/n;const a="cover"===o,s=i>e;return(a&&!s||!a&&s)&&(i=e,r=i*n),"scale-down"===o&&(r=Math.min(r,t),i=Math.min(i,e)),{cssW:Math.round(r),cssH:Math.round(i)}}(u,g,n,a.objectFit??"contain"),v="undefined"!=typeof window&&window.devicePixelRatio||1;let w,x;o&&r?({renderW:w,renderH:x}=ut({sourceWidth:o,sourceHeight:r,cssWidth:p,cssHeight:M,maxRenderDimension:i})):(w=p,x=M);const y=8e6,b=w*v*x*v>y?Math.sqrt(y/(w*x)):v;return t.width=Math.round(w*b),t.height=Math.round(x*b),t.style.width=`${p}px`,t.style.height=`${M}px`,{renderW:w,renderH:x,dpr:b}}async function Mt(t,n,{fontSize:o,artStyle:r="classic",options:i={},fitTo:a,objectFit:s,objectPosition:c,scale:l,width:h,height:d,bleed:f,preExtract:m=!1,fps:u,maxRenderDimension:g=2048,trim:p,scroll:M,maxCachedFrames:v=90,onReady:w,onFrame:x}={}){const y=p?.start??0,b=p?.end,S=o??i.fontSize??10;let T={...e,...Q(r),artStyle:r,...i,fontSize:S};const C=n.getContext("2d");if(!C)throw new Error("asciifyVideo: could not get 2d context from canvas.");const A="string"==typeof a?document.querySelector(a):a instanceof HTMLElement?a:null,F={objectFit:s,objectPosition:c,scale:l,width:h,height:d,bleed:f},L=function(t,e){var n;if(!function(t){return void 0!==t.objectFit||void 0!==t.objectPosition||void 0!==t.scale||void 0!==t.width||void 0!==t.height||void 0!==t.bleed}(e))return()=>{};const o={width:t.style.width,height:t.style.height,objectFit:t.style.objectFit,objectPosition:t.style.objectPosition,maxWidth:t.style.maxWidth,maxHeight:t.style.maxHeight,transformOrigin:t.style.transformOrigin,scale:t.style.getPropertyValue("scale")};if(e.objectFit&&(t.style.objectFit=e.objectFit),e.objectPosition&&(t.style.objectPosition=e.objectPosition,t.style.transformOrigin=e.objectPosition),void 0===e.scale&&void 0===e.bleed||(t.style.maxWidth="none",t.style.maxHeight="none"),void 0!==e.scale){const o=Number.isFinite(e.scale)&&e.scale>0?e.scale:1;t.style.setProperty("scale",String(o)),(n=t.style).transformOrigin||(n.transformOrigin=e.objectPosition??"center center")}return()=>{t.style.width=o.width,t.style.height=o.height,t.style.objectFit=o.objectFit,t.style.objectPosition=o.objectPosition,t.style.maxWidth=o.maxWidth,t.style.maxHeight=o.maxHeight,t.style.transformOrigin=o.transformOrigin,o.scale?t.style.setProperty("scale",o.scale):t.style.removeProperty("scale")}}(n,F),R=t=>()=>{t(),L()};if(m){let e;"string"==typeof t?(e=document.createElement("video"),e.crossOrigin="anonymous",e.src=t,e.readyState<2&&await new Promise((n,o)=>{e.onloadeddata=()=>n(),e.onerror=()=>o(new Error(`asciifyVideo: failed to load "${t}"`))})):e=t,T=await ft(e,T,y,b,M);const o=ct(e.videoWidth,e.videoHeight,T);A&&pt(n,A,o.w/o.h,o.w,o.h,g,F);const{renderW:r,renderH:i}=mt(o.w,o.h,g),a="undefined"!=typeof window&&window.devicePixelRatio||1,s=8e6,c=r*a*i*a>s?Math.sqrt(s/(r*i)):a;n.width===Math.round(r*c)&&n.height===Math.round(i*c)||(n.width=Math.round(r*c),n.height=Math.round(i*c));const l=void 0!==b?b-y:10,h=u??(M?18:void 0);if(et(T)){const{frames:t,fps:o}=await N(e,T,r,i,h,l,void 0,y),a=e=>{const n=t[e];n&&(C.save(),C.setTransform(c,0,0,c,0,0),D(C,n,T,r,i),C.restore(),x?.())};if(M){let o=!1,r=-1;const i=!0===M?{}:M,s=st(tt(i.trigger)??A??n,i,n=>{const s=nt(n,i),c=Math.max(0,Math.min(t.length-1,Math.round(s*(t.length-1))));c!==r&&(r=c,a(c),o||(o=!0,w?.(e)),i.onUpdate?.(s,e))});return a(0),o=!0,w?.(e),R(s)}let s,d=!1,f=0,m=performance.now(),u=!0;const g=1e3/o,p=n=>{d||(n-m>=g&&(a(f),f=(f+1)%t.length,m=n,u&&(u=!1,w?.(e))),s=requestAnimationFrame(p))};return s=requestAnimationFrame(p),R(()=>{d=!0,cancelAnimationFrame(s)})}const{frames:d,fps:f}=await U(e,T,r,i,h,l,void 0,y);if(!d.length)throw new Error("asciifyVideo: no frames were decoded.");let m=0;const p=performance.now(),v=E(n,(t,e)=>{M||(m=Math.floor((t-p)*f/1e3)%d.length),C.save(),C.setTransform(c,0,0,c,0,0),X(C,d[m],T,r,i,(t-p)/1e3,e),C.restore(),x?.()},{continuous:!M||"none"!==T.animationStyle||!!T.charsetFrames?.length,interactive:T.hoverStrength>0});let S;if(M){const t=!0===M?{}:M;S=st(tt(t.trigger)??A??n,t,n=>{m=Math.max(0,Math.min(d.length-1,Math.round(nt(n,t)*(d.length-1)))),v.wake(),t.onUpdate?.(n,e)})}return w?.(e),R(()=>{v.stop(),S?.()})}let I,k=!1;"string"==typeof t?(I=document.createElement("video"),I.crossOrigin="anonymous",I.src=t,I.muted=!0,I.loop=!0,I.playsInline=!0,I.setAttribute("playsinline",""),Object.assign(I.style,{position:"fixed",top:"0",left:"0",width:"1px",height:"1px",opacity:"0",pointerEvents:"none",zIndex:"-1"}),document.body.appendChild(I),k=!0,await new Promise((e,n)=>{I.onloadedmetadata=()=>e(),I.onerror=()=>n(new Error(`asciifyVideo: failed to load "${t}"`))}),await I.play().catch(()=>{})):(I=t,I.readyState<HTMLMediaElement.HAVE_METADATA&&await new Promise((t,e)=>{const n=()=>{I.removeEventListener("loadedmetadata",o),I.removeEventListener("error",r)},o=()=>{n(),t()},r=()=>{n(),e(new Error("asciifyVideo: provided video element failed to load metadata."))};I.addEventListener("loadedmetadata",o),I.addEventListener("error",r),I.load()}),I.paused&&await I.play().catch(()=>{})),y>0&&(I.currentTime=y,await new Promise(t=>{const e=()=>{I.removeEventListener("seeked",e),t()};I.addEventListener("seeked",e)}),await it(I));let H=null;(y>0||void 0!==b)&&(H=()=>{(void 0!==b&&I.currentTime>=b||y>0&&I.currentTime<y)&&(I.currentTime=y)},I.addEventListener("timeupdate",H)),T=await ft(I,T,y,b,M);let W=null;const P=ct(I.videoWidth,I.videoHeight,T);let{renderW:$,renderH:j}=mt(P.w,P.h,g);const z=t=>"frame"===T.chromaKeyTrimMode?ht(t,T,$/j):T;if(A){const t=P.w/P.h,e=P.w,o=P.h,r=pt(n,A,t,e,o,g,F);$=r.renderW,j=r.renderH;const i=n.getContext("2d");i&&i.setTransform(r.dpr,0,0,r.dpr,0,0),W=new ResizeObserver(()=>{const r=pt(n,A,t,e,o,g,F);$=r.renderW,j=r.renderH;const i=n.getContext("2d");i&&i.setTransform(r.dpr,0,0,r.dpr,0,0)}),W.observe(A)}else{const t="undefined"!=typeof window&&window.devicePixelRatio||1,e=8e6,o=$*t*j*t>e?Math.sqrt(e/($*j)):t;n.width===Math.round($*o)&&n.height===Math.round(j*o)||(n.width=Math.round($*o),n.height=Math.round(j*o)),C.setTransform(o,0,0,o,0,0)}let O=!0,V=null;const K=M&&!m,Y=u&&u>0?1e3/u:0;let _=0;const G=!K&&et(T);if(K&&"ascii"===T.renderMode&&"none"===T.animationStyle&&T.hoverStrength<=0&&!T.charsetFrames?.length){const t=!0===M?{}:M,e=tt(t.trigger)??A??n,o=t.from??y,r=t.to??b??I.duration,i=Math.max(o,Math.min(r,I.duration)),a=Math.max(.001,i-o),s=Math.min(60,Math.max(12,u??30)),c=Math.max(2,Math.ceil(a*s)+1),l=new Array(c),h=[],d=Math.max(2,Math.min(c,Math.floor(v))),f=()=>{for(;h.length>d;){const t=h.findIndex(t=>t!==g&&Math.abs(t-g)>2),e=t>=0?t:0,n=h.splice(e,1)[0];void 0!==n&&(l[n]=void 0)}},m=t=>{const e=h.indexOf(t);e>=0&&h.splice(e,1),h.push(t),f()};let g=0,p=0,S=-1,E=0,F=!1,L=!1,P=!1;const O=new Set,q=document.createElement("video");q.muted=!0,q.playsInline=!0,q.preload="auto",q.crossOrigin=I.crossOrigin||"anonymous",q.src=I.currentSrc||I.src,Object.assign(q.style,{position:"fixed",top:"0",left:"0",width:"1px",height:"1px",opacity:"0",pointerEvents:"none",zIndex:"-1"}),document.body.appendChild(q),q.readyState<HTMLMediaElement.HAVE_METADATA&&await new Promise((t,e)=>{const n=()=>{q.removeEventListener("loadedmetadata",o),q.removeEventListener("error",r)},o=()=>{n(),t()},r=()=>{n(),e(new Error("asciifyVideo: cache video failed to load metadata."))};q.addEventListener("loadedmetadata",o),q.addEventListener("error",r),q.load()}),q.pause(),I.paused&&await I.play().catch(()=>{});const U=t=>o+a*t/Math.max(1,c-1),N=t=>Math.max(0,Math.min(c-1,Math.round(t*(c-1)))),K=z(I),G=B(I,K,$,j);G.rows.length>0&&(l[0]=G,m(0),D(C,G,K,$,j),P=!0,w?.(I),x?.());const X=t=>{if(l[t])return t;for(let e=1;e<c;e++){const n=t-e,o=t+e;if(n>=0&&l[n])return n;if(o<c&&l[o])return o}return-1},J=()=>{if(!l[g])return g;for(const t of O)if(!l[t])return t;for(let t=1;t<c;t++){const e=g-t,n=g+t;if(e>=0&&!l[e])return e;if(n<c&&!l[n])return n}return-1},Q=t=>{t<0||t>=c||l[t]||(O.add(t),et())},et=async()=>{if(F||L)return;const t=J();if(!(t<0)){O.delete(t),L=!0;try{if(await rt(q,U(t)),!F){const e=z(q),n=B(q,e,$,j);n.rows.length>0&&(l[t]=n,m(t))}}finally{L=!1,F||requestAnimationFrame(()=>{et()})}}},ot=()=>{if(F)return;const t=X(g);if(t>=0&&t!==S){const e=l[t];e&&(D(C,e,T,$,j),S=t,P||(P=!0,w?.(I)),x?.())}else if(t<0||S<0){const t=performance.now();if(Y<=0||t-_>=Y){const e=z(I),n=B(I,e,$,j);n.rows.length>0&&(D(C,n,e,$,j),_=t,P||(P=!0,w?.(I)),x?.())}}Q(g),E=requestAnimationFrame(ot)};return V=st(e,t,e=>{const n=function(t,e,n={}){if(!Number.isFinite(t.duration)||t.duration<=0)return null;const o=n.from??0,r=n.to??t.duration,i=Math.max(o,Math.min(r,t.duration)),a=nt(e,n),s=o+(i-o)*a;return{progress:a,time:Math.min(Math.max(o,s),Math.max(o,i-.04))}}(I,e,{...t,from:o,to:i});p=n?.progress??Z(e),g=N(p),Q(g),Q(g-1),Q(g+1),Q(g-2),Q(g+2),Q(g-3),Q(g+3),t.onUpdate?.(p,I)}),Q(0),Q(1),E=requestAnimationFrame(ot),R(()=>{F=!0,cancelAnimationFrame(E),V?.(),W?.disconnect(),O.clear(),h.length=0,l.fill(void 0),q.pause(),q.src="",q.removeAttribute("src"),q.load(),q.isConnected&&q.remove(),H&&I.removeEventListener("timeupdate",H),k&&(I.pause(),I.src="",I.removeAttribute("src"),I.load(),I.isConnected&&I.remove())})}if(K){const t=!0===M?{}:M;V=at(I,{...t,trigger:t.trigger??A??n,from:t.from??y,to:t.to??b})}let J=-1,ot=0,lt=-1,dt=0;const ut="function"==typeof I.requestVideoFrameCallback,gt=()=>{dt=I.requestVideoFrameCallback(()=>{ot++,gt()})};ut&>();let Mt=0,vt=0,wt=null;const xt=E(n,(t,e)=>{if(I.readyState<2||0===n.width||0===n.height)return;if(Y>0&&t-_<Y&&!e)return;if(y>0&&I.currentTime<y)return;if(void 0!==b&&I.currentTime>=b)return;const o=(ut?ot!==lt:I.currentTime!==J)||Mt!==$||vt!==j;if(o||!(T.hoverStrength<=0)||"none"!==T.animationStyle||T.charsetFrames?.length){if(G){const t=z(I),e=B(I,t,$,j);D(C,e,t,$,j)}else!o&&wt||(wt=q(I,z(I),$,j).frame),X(C,wt,T,$,j,t/1e3,e);J=I.currentTime,lt=ot,Mt=$,vt=j,_=t,O&&(O=!1,w?.(I)),x?.()}},{continuous:!0,interactive:T.hoverStrength>0});return R(()=>{xt.stop(),dt&&I.cancelVideoFrameCallback(dt),V?.(),W?.disconnect(),H&&I.removeEventListener("timeupdate",H),k&&(I.pause(),I.src="",I.removeAttribute("src"),I.load(),I.isConnected&&I.remove())})}function vt(t,e,n,o="#505050",r=100){if(!t||e<=0||n<=0)return[];const i=function(t){const e=t.match(/^#([0-9a-f]{3,8})$/i)?.[1];if(e){const t=e.length<=4?e.split("").map(t=>parseInt(t+t,16)):[parseInt(e.slice(0,2),16),parseInt(e.slice(2,4),16),parseInt(e.slice(4,6),16)];return{r:t[0],g:t[1],b:t[2]}}const n=t.match(/rgba?\(\s*(\d+)[,\s]+(\d+)[,\s]+(\d+)/i);return n?{r:+n[1],g:+n[2],b:+n[3]}:null}(o)??{r:80,g:80,b:80},a=t,s=a.length;return Array.from({length:n},(t,n)=>Array.from({length:e},(t,o)=>({char:a[(n*e+o)%s],r:i.r,g:i.g,b:i.b,a:r})))}var wt=new WeakMap;function xt(t,{format:e="png",quality:n=.92,scale:o=1}={}){return new Promise((r,i)=>{let a=t;if(1!==o){const e=document.createElement("canvas");e.width=Math.round(t.width*o),e.height=Math.round(t.height*o);const n=e.getContext("2d");if(!n)return void i(new Error("captureSnapshot: could not get 2d context"));n.drawImage(t,0,0,e.width,e.height),a=e}a.toBlob(t=>t?r(t):i(new Error("captureSnapshot: toBlob returned null")),`image/${e}`,n)})}var yt={A:[28,54,99,127,99,99,99],B:[126,99,99,126,99,99,126],C:[62,99,96,96,96,99,62],D:[124,102,99,99,99,102,124],E:[127,96,96,124,96,96,127],F:[127,96,96,124,96,96,96],G:[62,99,96,111,99,99,62],H:[99,99,99,127,99,99,99],I:[127,8,8,8,8,8,127],J:[63,6,6,6,102,102,60],K:[99,102,108,120,108,102,99],L:[96,96,96,96,96,96,127],M:[99,119,107,107,99,99,99],N:[99,115,107,103,99,99,99],O:[62,99,99,99,99,99,62],P:[126,99,99,126,96,96,96],Q:[62,99,99,99,107,102,61],R:[126,99,99,126,108,102,99],S:[62,99,96,62,3,99,62],T:[127,8,8,8,8,8,8],U:[99,99,99,99,99,99,62],V:[99,99,99,99,54,28,8],W:[99,99,99,107,107,54,20],X:[99,54,28,8,28,54,99],Y:[99,99,54,28,8,8,8],Z:[127,3,6,12,24,48,127],a:[0,0,60,3,62,99,61],b:[96,96,124,99,99,99,124],c:[0,0,62,96,96,96,62],d:[3,3,31,99,99,99,31],e:[0,0,62,99,127,96,62],f:[30,48,48,126,48,48,48],g:[0,0,63,99,63,3,62],h:[96,96,124,99,99,99,99],i:[8,0,24,8,8,8,28],j:[4,0,12,4,4,36,24],k:[96,96,102,108,120,108,102],l:[24,8,8,8,8,8,28],m:[0,0,92,107,107,99,99],n:[0,0,94,99,99,99,99],o:[0,0,62,99,99,99,62],p:[0,0,126,99,126,96,96],q:[0,0,63,99,63,3,3],r:[0,0,94,99,96,96,96],s:[0,0,62,96,62,3,124],t:[48,48,126,48,48,48,30],u:[0,0,99,99,99,103,59],v:[0,0,99,99,54,28,8],w:[0,0,99,99,107,54,20],x:[0,0,99,54,28,54,99],y:[0,0,99,99,63,3,62],z:[0,0,127,6,12,24,127],0:[62,99,103,107,115,99,62],1:[8,24,56,8,8,8,62],2:[62,99,3,6,24,48,127],3:[62,99,3,30,3,99,62],4:[6,14,22,38,127,6,6],5:[127,96,126,3,3,99,62],6:[62,99,96,126,99,99,62],7:[127,3,6,12,24,24,24],8:[62,99,99,62,99,99,62],9:[62,99,99,63,3,99,62]," ":[0,0,0,0,0,0,0],"!":[24,24,24,24,24,0,24],"?":[62,99,3,14,8,0,8],".":[0,0,0,0,0,24,24],",":[0,0,0,0,0,24,48],";":[0,24,24,0,24,24,48],":":[0,24,24,0,24,24,0],"-":[0,0,0,62,0,0,0],_:[0,0,0,0,0,0,127],"'":[24,24,32,0,0,0,0],'"':[54,54,36,0,0,0,0],"`":[24,8,0,0,0,0,0],")":[24,12,6,6,6,12,24],"(":[12,24,48,48,48,24,12],"[":[60,48,48,48,48,48,60],"]":[30,6,6,6,6,6,30],"{":[14,24,24,48,24,24,14],"}":[56,12,12,6,12,12,56],"/":[3,6,12,24,48,96,0],"\\":[96,48,24,12,6,3,0],"|":[8,8,8,8,8,8,8],"+":[0,8,8,62,8,8,0],"=":[0,0,62,0,62,0,0],"*":[0,42,28,127,28,42,0],"#":[36,36,127,36,127,36,36],"@":[62,99,111,107,111,96,62],"&":[24,36,24,60,74,68,58],"%":[99,38,4,8,16,50,99],$:[8,62,72,62,9,62,8],"^":[8,20,34,0,0,0,0],"~":[0,0,50,76,0,0,0],"<":[6,12,24,48,24,12,6],">":[48,24,12,6,12,24,48]},bt=[127,65,65,65,65,65,127];function St(t){return yt[t]??yt[t.toUpperCase()]??bt}function Et(t,e={}){if(!t)return"";const{char:n="█",scale:o=1}=e,r=[...n][0]??"█",i=Math.max(1,Math.floor(o)),a=7*i,s=i,c=Array.from({length:a},()=>"");for(let e=0;e<t.length;e++){const n=St(t[e]);for(let t=0;t<7;t++){const e=n[t];let o="";for(let t=6;t>=0;t--)o+=(e>>t&1?r:" ").repeat(i);for(let e=0;e<i;e++)c[t*i+e]+=o}if(e<t.length-1)for(let t=0;t<a;t++)c[t]+=" ".repeat(s)}return c.join("\n")}var Tt=["ascii","blocks","braille","dots","lines","cross","diagonal","diamond","mixed","pixel","mosaic","lego","voxel","disco","dither","hex","led","cmyk","stipple","engraving","crosshatch","woodblock","risograph","pointillism"];exports.CHARACTER_SETS=t,exports.DEFAULT_OPTIONS=e,exports.HOVER_PRESETS={none:{label:"Off",options:{hoverStrength:0,hoverEffect:"spotlight",hoverRadius:.2,hoverColor:"#ffffff"}},subtle:{label:"Subtle",options:{hoverStrength:.25,hoverEffect:"glow",hoverRadius:.12,hoverColor:"#ffffff"}},flashlight:{label:"Flashlight",options:{hoverStrength:.6,hoverEffect:"spotlight",hoverRadius:.15,hoverColor:"#fffbe6"}},magnifier:{label:"Magnifier",options:{hoverStrength:.7,hoverEffect:"magnify",hoverRadius:.12,hoverColor:"#ffffff"}},forceField:{label:"Force Field",options:{hoverStrength:.7,hoverEffect:"repel",hoverRadius:.15,hoverColor:"#a0e8ff"}},neon:{label:"Neon",options:{hoverStrength:.6,hoverEffect:"colorShift",hoverRadius:.15,hoverColor:"#d946ef"}},fire:{label:"Fire",options:{hoverStrength:.7,hoverEffect:"spotlight",hoverRadius:.15,hoverColor:"#ff6b2b"}},ice:{label:"Ice",options:{hoverStrength:.5,hoverEffect:"glow",hoverRadius:.15,hoverColor:"#60d5f7"}},gravity:{label:"Gravity",options:{hoverStrength:.7,hoverEffect:"attract",hoverRadius:.18,hoverColor:"#a5d6ff"}},shatter:{label:"Shatter",options:{hoverStrength:.8,hoverEffect:"shatter",hoverRadius:.14,hoverColor:"#ff6090"}},ghost:{label:"Fluid trail",options:{hoverStrength:.55,hoverEffect:"trail",hoverRadius:.2,hoverColor:"#b39ddb"}},glitchReveal:{label:"Glitch Reveal",options:{hoverStrength:.8,hoverEffect:"glitchText",hoverRadius:.18,hoverColor:"#a3e635"}}},exports.PALETTE_THEMES={dracula:{name:"Dracula",accent:"#bd93f9",bg:"#282a36",fg:"#f8f8f2"},monokai:{name:"Monokai",accent:"#a6e22e",bg:"#272822",fg:"#f8f8f2"},nord:{name:"Nord",accent:"#88c0d0",bg:"#2e3440",fg:"#eceff4"},catppuccin:{name:"Catppuccin",accent:"#cba6f7",bg:"#1e1e2e",fg:"#cdd6f4"},solarized:{name:"Solarized",accent:"#268bd2",bg:"#002b36",fg:"#839496"},gruvbox:{name:"Gruvbox",accent:"#b8bb26",bg:"#282828",fg:"#ebdbb2"}},exports.STUDIO_STYLES=Tt,exports.asciiText=function(t,n={},o,r){const i={...e,...n},{frame:a,cols:s}=q(t,i,o,r);if(!a.length||0===s)return"";const c=[];for(const t of a)c.push(t.map(t=>t.char).join(""));return c.join("\n")},exports.asciiTextAnsi=function(t,n={},o,r){const i={...e,...n},{frame:a,cols:s}=q(t,i,o,r);if(!a.length||0===s)return"";const c=[];for(const t of a){let e="";for(const n of t)" "===n.char||n.a<10?e+=" ":e+=`[38;2;${n.r};${n.g};${n.b}m${n.char}[0m`;c.push(e)}return c.join("\n")},exports.asciify=async function(t,n,{fontSize:o,artStyle:r="classic",options:i={}}={}){let a;if("string"==typeof t){const e=new Image;e.crossOrigin="anonymous",await new Promise((n,o)=>{e.onload=()=>n(),e.onerror=()=>o(new Error(`Failed to load image: ${t}`)),e.src=t}),a=e}else t instanceof HTMLImageElement&&!t.complete?(await new Promise((e,n)=>{t.onload=()=>e(),t.onerror=()=>n(new Error("Image failed to load"))}),a=t):a=t;const s=Q(r),c=o??i.fontSize??10,l={...e,...s,artStyle:r,...i,fontSize:c},h=n.getContext("2d");if(!h)throw new Error("Could not get 2d context from canvas");const{w:d,h:f}=function(t){return t instanceof HTMLVideoElement?{w:t.videoWidth,h:t.videoHeight}:t instanceof HTMLImageElement?{w:t.naturalWidth||t.width,h:t.naturalHeight||t.height}:{w:t.width,h:t.height}}(a),{renderW:m,renderH:u}=mt(d,f),g="undefined"!=typeof window&&window.devicePixelRatio||1,p=8e6,M=m*g*u*g>p?Math.sqrt(p/(m*u)):g;n.width===Math.round(m*M)&&n.height===Math.round(u*M)||(n.width=Math.round(m*M),n.height=Math.round(u*M));const{frame:v}=q(a,l,m,u),w=(t,e)=>{h.save(),h.setTransform(M,0,0,M,0,0),X(h,v,l,m,u,t/1e3,e),h.restore()};return w(0,null),E(n,w,{continuous:"none"!==l.animationStyle||!!l.charsetFrames?.length,interactive:l.hoverStrength>0}).stop},exports.asciifyGif=async function(t,n,{fontSize:o,artStyle:r="classic",options:i={}}={}){const a="string"==typeof t?await fetch(t).then(t=>t.arrayBuffer()):t,s=o??i.fontSize??10;let c={...e,...Q(r),artStyle:r,...i,fontSize:s};const l=n.getContext("2d");if(!l)throw new Error("Could not get 2d context from canvas");const{frames:h,fps:d}=await K(a,c,n.width,n.height);if(!h.length)throw new Error("asciifyGif: the GIF contains no renderable frames.");const f=performance.now();let m=-1;return E(n,(t,e)=>{const o=Math.floor((t-f)*d/1e3)%h.length;o===m&&!e&&c.hoverStrength<=0&&"none"===c.animationStyle&&!c.charsetFrames?.length||(X(l,h[o],c,n.width,n.height,(t-f)/1e3,e),m=o)},{continuous:!0,interactive:c.hoverStrength>0}).stop},exports.asciifyLiveVideo=function(t,e,n){return Mt(t,e,n)},exports.asciifyText=Et,exports.asciifyVideo=Mt,exports.asciifyWebcam=async function(t,{fontSize:n=10,style:o="classic",options:r={},liveOptions:i,mirror:a=!0,constraints:s={facingMode:"user"},dpr:c}={}){if(!navigator.mediaDevices?.getUserMedia)throw new Error("asciifyWebcam: getUserMedia is not supported in this browser.");const l=Q(o),h=await navigator.mediaDevices.getUserMedia({video:s}),d=document.createElement("video");d.srcObject=h,d.muted=!0,d.playsInline=!0,await new Promise((t,e)=>{d.onloadedmetadata=()=>t(),d.onerror=()=>e(new Error("asciifyWebcam: video stream failed to load.")),d.play().catch(e)});const f={...e,...l,...r,fontSize:n},m=t.getContext("2d");if(!m)throw new Error("asciifyWebcam: could not get 2d context from canvas.");const u=c??("undefined"!=typeof window?window.devicePixelRatio:1)??1;1!==u&&m.scale(u,u);let g=null;const p=e=>{const n=t.getBoundingClientRect();g={x:(e.clientX-n.left)/n.width,y:(e.clientY-n.top)/n.height}},M=()=>{g=null};f.hoverStrength>0&&(t.addEventListener("mousemove",p),t.addEventListener("mouseleave",M));let v,w=!1;const x=performance.now(),y=e=>{if(!w){if(d.readyState>=d.HAVE_CURRENT_DATA){const n=t.width/u,o=t.height/u,r=(e-x)/1e3,s=i?{...f,...i()}:f;s.hoverStrength>0?(t.addEventListener("mousemove",p),t.addEventListener("mouseleave",M)):(t.removeEventListener("mousemove",p),t.removeEventListener("mouseleave",M));const{frame:c}=q(d,s,n,o),l=g&&a?{x:1-g.x,y:g.y}:g;a?(m.save(),m.scale(-1,1),m.translate(-n,0),X(m,c,s,n,o,r,l),m.restore()):X(m,c,s,n,o,r,l)}v=requestAnimationFrame(y)}};return v=requestAnimationFrame(y),()=>{w=!0,cancelAnimationFrame(v),t.removeEventListener("mousemove",p),t.removeEventListener("mouseleave",M),h.getTracks().forEach(t=>t.stop()),d.srcObject=null}},exports.buildTextFrame=vt,exports.captureSnapshot=xt,exports.clearAsciifyCaches=function(){F.clear(),L.clear(),Y=new WeakMap,G=new WeakMap,_=new WeakMap,T=null,C=null},exports.computeCanvasRenderSize=ut,exports.createVideoScrollScrub=at,exports.gifToAsciiFrames=K,exports.gifToAsciiTextFrames=async function(t,e,n,o,r){const{parseGIF:i,decompressFrames:a}=await import("gifuct-js"),s=i(t),c=a(s,!0);if(0===c.length)return{frames:[],cols:0,rows:0,fps:10};const l=c[0].dims.width,h=c[0].dims.height,d=s.lsd?.width||l,f=s.lsd?.height||h,m=document.createElement("canvas");m.width=d,m.height=f;const u=m.getContext("2d"),g=document.createElement("canvas");g.width=d,g.height=f;const p=g.getContext("2d"),M=document.createElement("canvas"),v=M.getContext("2d"),w=[];let x=0,y=0,b=0;for(const t of c)b+=t.delay||100;const S=b/c.length,E=Math.round(Math.min(30,Math.max(5,1e3/S))),T=Math.min(c.length,300);for(let t=0;t<T;t++){const i=c[t],{dims:a,patch:s,disposalType:l}=i;3===l&&(p.clearRect(0,0,d,f),p.drawImage(m,0,0)),M.width!==a.width&&(M.width=a.width),M.height!==a.height&&(M.height=a.height);const h=new ImageData(new Uint8ClampedArray(s.buffer),a.width,a.height);v.putImageData(h,0,0),u.drawImage(M,a.left||0,a.top||0);const b=B(m,e,n,o);w.push(b),x=b.cols,y=b.rowCount,2===l?u.clearRect(a.left||0,a.top||0,a.width,a.height):3===l&&(u.clearRect(0,0,d,f),u.drawImage(g,0,0)),r?.((t+1)/T)}return{frames:w,cols:x,rows:y,fps:E}},exports.imageToAsciiFrame=q,exports.imageToAsciiTextFrame=B,exports.renderFrameToCanvas=X,exports.renderTextBackground=function(t,n,o,r,i={},a){const{fontSize:s=10,lineHeight:c=1.6,color:l="#505050",opacity:h=100,hoverEffect:d="spotlight",hoverStrength:f=.85,hoverRadius:m=.18,hoverColor:u="#d4ff00"}=i,g=Math.max(1,Math.floor(n/s)),p=Math.max(1,Math.floor(o/(s*c))),M=JSON.stringify([r,g,p,l,h]);let v=wt.get(t);v&&v.key===M||(v={key:M,frame:vt(r,g,p,l,h)},wt.set(t,v)),X(t,v.frame,{...e,fontSize:s,hoverEffect:d,hoverStrength:f,hoverRadius:m,hoverColor:u},n,o,0,a??null)},exports.renderTextFrameToCanvas=D,exports.renderTextToCanvas=function(t,e,n={}){const{color:o="#d4ff00",bgColor:r,fontSize:i=10}=n,a=Et(e,n);if(!a)return;const s=a.split("\n"),c=Math.max(...s.map(t=>[...t].length));t.width=Math.ceil(c*i*.6),t.height=Math.ceil(s.length*i);const l=t.getContext("2d");r&&"transparent"!==r?(l.fillStyle=r,l.fillRect(0,0,t.width,t.height)):l.clearRect(0,0,t.width,t.height),l.fillStyle=o,l.font=`${i}px monospace`,l.textBaseline="top",s.forEach((t,e)=>l.fillText(t,0,e*i))},exports.snapshotAndDownload=async function(t,e={}){const{filename:n="asciify-snapshot",format:o="png",...r}=e,i=await xt(t,{format:o,...r}),a="jpeg"===o?"jpg":o,s=document.createElement("a");s.href=URL.createObjectURL(i),s.download=`${n}.${a}`,s.click(),setTimeout(()=>URL.revokeObjectURL(s.href),1e4)},exports.videoToAsciiFrames=U,exports.videoToAsciiTextFrames=N;//# sourceMappingURL=core.cjs.map
|
package/dist/core.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as AsciiOptions, A as AsciiFrame, b as ArtStyle, H as HoverEffect } from './types-
|
|
2
|
-
export { c as AnimationStyle, d as AsciiCell, e as AsciiResult, C as ColorMode, D as DEFAULT_OPTIONS, f as HOVER_PRESETS, g as HoverPreset, h as HoverShape, P as PALETTE_THEMES, i as PaletteTheme, R as RenderMode, S as SourceType } from './types-
|
|
3
|
-
export { C as CHARACTER_SETS,
|
|
4
|
-
import './hover-catalog-
|
|
1
|
+
import { a as AsciiOptions, A as AsciiFrame, b as ArtStyle, H as HoverEffect } from './types-FkqhgDYx.cjs';
|
|
2
|
+
export { c as AnimationStyle, d as AsciiCell, e as AsciiResult, C as ColorMode, D as DEFAULT_OPTIONS, f as HOVER_PRESETS, g as HoverPreset, h as HoverShape, P as PALETTE_THEMES, i as PaletteTheme, R as RenderMode, S as SourceType } from './types-FkqhgDYx.cjs';
|
|
3
|
+
export { C as CHARACTER_SETS, j as STUDIO_STYLES, s as StudioStyle } from './model-DQNOpbbG.cjs';
|
|
4
|
+
import './hover-catalog-D85jh6dR.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Core frame-to-canvas renderer and source-to-frame converters.
|
package/dist/core.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as AsciiOptions, A as AsciiFrame, b as ArtStyle, H as HoverEffect } from './types-
|
|
2
|
-
export { c as AnimationStyle, d as AsciiCell, e as AsciiResult, C as ColorMode, D as DEFAULT_OPTIONS, f as HOVER_PRESETS, g as HoverPreset, h as HoverShape, P as PALETTE_THEMES, i as PaletteTheme, R as RenderMode, S as SourceType } from './types-
|
|
3
|
-
export { C as CHARACTER_SETS,
|
|
4
|
-
import './hover-catalog-
|
|
1
|
+
import { a as AsciiOptions, A as AsciiFrame, b as ArtStyle, H as HoverEffect } from './types-CM4452nD.js';
|
|
2
|
+
export { c as AnimationStyle, d as AsciiCell, e as AsciiResult, C as ColorMode, D as DEFAULT_OPTIONS, f as HOVER_PRESETS, g as HoverPreset, h as HoverShape, P as PALETTE_THEMES, i as PaletteTheme, R as RenderMode, S as SourceType } from './types-CM4452nD.js';
|
|
3
|
+
export { C as CHARACTER_SETS, j as STUDIO_STYLES, s as StudioStyle } from './model-BVeBDUa9.js';
|
|
4
|
+
import './hover-catalog-D85jh6dR.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Core frame-to-canvas renderer and source-to-frame converters.
|