@wave3d/core 0.2.1 → 0.3.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.
Files changed (40) hide show
  1. package/README.md +47 -0
  2. package/dist/config/model.d.ts +104 -1
  3. package/dist/config/model.js +111 -1
  4. package/dist/config/model.js.map +1 -1
  5. package/dist/index.d.ts +3 -2
  6. package/dist/index.js +2 -2
  7. package/dist/presets.js +15 -0
  8. package/dist/presets.js.map +1 -1
  9. package/dist/renderer/WaveRenderer.d.ts +34 -0
  10. package/dist/renderer/WaveRenderer.js +232 -7
  11. package/dist/renderer/WaveRenderer.js.map +1 -1
  12. package/dist/renderer/interaction.d.ts +119 -0
  13. package/dist/renderer/interaction.js +474 -0
  14. package/dist/renderer/interaction.js.map +1 -0
  15. package/dist/renderer/palette.js +14 -0
  16. package/dist/renderer/palette.js.map +1 -1
  17. package/dist/renderer/shaders.js +105 -0
  18. package/dist/renderer/shaders.js.map +1 -1
  19. package/dist/shell/createWave.d.ts +9 -1
  20. package/dist/shell/createWave.js +7 -1
  21. package/dist/shell/createWave.js.map +1 -1
  22. package/dist/shell/poster.d.ts +12 -0
  23. package/dist/shell/poster.js +4 -3
  24. package/dist/shell/poster.js.map +1 -1
  25. package/dist/standalone/wave3d.standalone.js +864 -219
  26. package/dist/standalone.d.ts +2 -2
  27. package/dist/standalone.js +2 -2
  28. package/dist/studio/StudioWaveRenderer.d.ts +15 -0
  29. package/dist/studio/StudioWaveRenderer.js +32 -1
  30. package/dist/studio/StudioWaveRenderer.js.map +1 -1
  31. package/dist/studio/index.d.ts +2 -1
  32. package/dist/studio/index.js +2 -1
  33. package/dist/studio/randomize.d.ts +3 -3
  34. package/dist/studio/randomize.js +4 -4
  35. package/dist/studio/randomize.js.map +1 -1
  36. package/dist/studio/thumbnail.d.ts +14 -0
  37. package/dist/studio/thumbnail.js +32 -0
  38. package/dist/studio/thumbnail.js.map +1 -0
  39. package/package.json +1 -1
  40. package/skills/wave3d/SKILL.md +20 -2
@@ -11575,24 +11575,97 @@ function Ol(e) {
11575
11575
  x: 10,
11576
11576
  y: 10,
11577
11577
  z: 7
11578
- }, typeof e.blendMode != "string" && (e.blendMode = "squared"), typeof e.speed != "number" && (e.speed = .04), typeof e.opacity != "number" && (e.opacity = 1), typeof e.seed != "number" && (e.seed = 0);
11578
+ }, typeof e.blendMode != "string" && (e.blendMode = "squared"), typeof e.speed != "number" && (e.speed = .04), typeof e.opacity != "number" && (e.opacity = 1), typeof e.seed != "number" && (e.seed = 0), e.interaction && Nl(e);
11579
11579
  }
11580
11580
  function kl(e) {
11581
11581
  El(e), Dl(e), typeof e.ambient != "number" && (e.ambient = .45), Array.isArray(e.lights) || (e.lights = []), typeof e.quality != "number" && (e.quality = 1), typeof e.dprMax != "number" && (e.dprMax = 2), typeof e.grain != "number" && (e.grain = 1.1), typeof e.blur != "number" && (e.blur = .02), typeof e.blurSamples != "number" && (e.blurSamples = 6), typeof e.bloomStrength != "number" && (e.bloomStrength = 0), typeof e.bloomRadius != "number" && (e.bloomRadius = .4), typeof e.bloomThreshold != "number" && (e.bloomThreshold = .85), typeof e.showCameraRig != "boolean" && (e.showCameraRig = !1), typeof e.paused != "boolean" && (e.paused = !1), typeof e.loopSeconds != "number" && (e.loopSeconds = 0), typeof e.mirrorH != "boolean" && (e.mirrorH = !1), typeof e.mirrorV != "boolean" && (e.mirrorV = !1);
11582
11582
  }
11583
- function Al(e) {
11583
+ function Al(e, t, n, r) {
11584
+ let i = Number(e);
11585
+ return Number.isFinite(i) ? pl(i, t, n) : r;
11586
+ }
11587
+ function jl(e) {
11588
+ return typeof e == "string" && (Hl.includes(e) || e.startsWith("custom:") && e.length > 7);
11589
+ }
11590
+ function Ml(e, t) {
11591
+ let n = [];
11592
+ if (!Array.isArray(e)) return n;
11593
+ for (let r of e) {
11594
+ if (!r || typeof r != "object") continue;
11595
+ let e = r;
11596
+ if (!jl(e.source) || !t.includes(e.target)) continue;
11597
+ let i = Number(e.to);
11598
+ if (!Number.isFinite(i)) continue;
11599
+ let a = {
11600
+ source: e.source,
11601
+ target: e.target,
11602
+ to: i
11603
+ };
11604
+ if (e.from !== void 0) {
11605
+ let t = Number(e.from);
11606
+ Number.isFinite(t) && (a.from = t);
11607
+ }
11608
+ e.smoothing !== void 0 && (a.smoothing = Al(e.smoothing, 0, 2, .25)), n.push(a);
11609
+ }
11610
+ return n;
11611
+ }
11612
+ function Nl(e) {
11613
+ let t = e.interaction;
11614
+ if (!t) return;
11615
+ let n = t.hover;
11616
+ n && (n.agitate !== void 0 && (n.agitate = Al(n.agitate, 0, 60, 0)), n.push !== void 0 && (n.push = Al(n.push, -40, 40, 0)), n.wake !== void 0 && (n.wake = Al(n.wake, 0, 40, 0)), n.thin !== void 0 && (n.thin = Al(n.thin, 0, 1, 0)), n.hueShift !== void 0 && (n.hueShift = Al(n.hueShift, -360, 360, 0)), n.lighten !== void 0 && (n.lighten = Al(n.lighten, -1, 1, 0)), n.smoothing !== void 0 && (n.smoothing = Al(n.smoothing, 0, 2, .12))), t.press && t.press.ripple !== void 0 && (t.press.ripple = Al(t.press.ripple, 0, 60, 0)), t.bindings !== void 0 && (t.bindings = Ml(t.bindings, Ul));
11617
+ }
11618
+ function Pl(e) {
11619
+ let t = e.interaction;
11620
+ t && (t.radius !== void 0 && (t.radius = Al(t.radius, .02, 2, .3)), t.bindings !== void 0 && (t.bindings = Ml(t.bindings, Wl)));
11621
+ }
11622
+ function Fl(e) {
11584
11623
  let t = e;
11585
- return kl(t), (!Array.isArray(t.waves) || t.waves.length === 0) && (t.waves = [Sl()]), t.waves.forEach(Ol), t.waveCount = t.waves.length, t;
11624
+ return kl(t), (!Array.isArray(t.waves) || t.waves.length === 0) && (t.waves = [Sl()]), t.waves.forEach(Ol), t.waveCount = t.waves.length, t.interaction && Pl(t), t;
11586
11625
  }
11587
- var jl, Ml, Nl, Pl, Fl, Il, Ll = t((() => {
11588
- hl(), jl = 8, Ml = 8, Nl = 8, Pl = 4, Fl = 6, Il = {
11626
+ var Il, Ll, Rl, zl, Bl, Vl, Hl, Ul, Wl, Gl = t((() => {
11627
+ hl(), Il = 8, Ll = 8, Rl = 8, zl = 4, Bl = 6, Vl = {
11589
11628
  x: 800,
11590
11629
  y: 900,
11591
11630
  z: 1100
11592
- };
11593
- })), Rl, zl, Bl, Vl, Hl, Ul, Wl, Gl, Kl = t((() => {
11594
- Ll(), Rl = "\nfloat xxhash(vec2 x){\n uvec2 t = floatBitsToUint(x);\n uint h = 0xc2b2ae3du * t.x + 0x165667b9u;\n h = (h << 17u | h >> 15u) * 0x27d4eb2fu;\n h += 0xc2b2ae3du * t.y;\n h = (h << 17u | h >> 15u) * 0x27d4eb2fu;\n h ^= h >> 15u;\n h *= 0x85ebca77u;\n h ^= h >> 13u;\n h *= 0xc2b2ae3du;\n h ^= h >> 16u;\n return uintBitsToFloat(h >> 9u | 0x3f800000u) - 1.0;\n}\nvec2 hash(vec2 x){\n float k = 6.283185307 * xxhash(x);\n return vec2(cos(k), sin(k));\n}\nfloat simplexNoise(in vec2 p){\n const float K1 = 0.366025404; // (sqrt(3)-1)/2\n const float K2 = 0.211324865; // (3-sqrt(3))/6\n vec2 i = floor(p + (p.x + p.y) * K1);\n vec2 a = p - i + (i.x + i.y) * K2;\n float m = step(a.y, a.x);\n vec2 o = vec2(m, 1.0 - m);\n vec2 b = a - o + K2;\n vec2 c = a - 1.0 + 2.0 * K2;\n vec3 h = max(0.5 - vec3(dot(a, a), dot(b, b), dot(c, c)), 0.0);\n vec3 n = h * h * h * vec3(dot(a, hash(i + 0.0)), dot(b, hash(i + o)), dot(c, hash(i + 1.0)));\n return dot(n, vec3(32.99)); // analytic factor (= 2916*sqrt(2)/125)\n}\n", zl = "\nuniform vec3 uColors[MAX_COLORS];\nuniform float uColorPos[MAX_COLORS];\nuniform int uColorCount;\nuniform int uGradType;\nuniform float uGradAngle;\nuniform float uGradShift;\nuniform vec2 uMeshPointPos[MAX_MESH_POINTS];\nuniform vec3 uMeshPointColor[MAX_MESH_POINTS];\nuniform float uMeshPointInfluence[MAX_MESH_POINTS];\nuniform int uMeshPointCount;\nuniform float uMeshSoftness;\nuniform sampler2D uPalette; // baked 2D palette texture\nuniform float uUsePalette; // >0.5 = sample the texture; else procedural grad()\nuniform float uPaletteRaw; // >0.5 = sample palette by raw (uv.x,uv.y), not gradCoord\nuniform vec2 uPaletteScale;\nuniform vec2 uPaletteOffset;\nuniform float uPaletteRotation;\nuniform float uHueShift;\nuniform float uContrast;\nuniform float uSaturation;\nuniform float uOpacity;\nuniform float uSquared; // 1 = square the output colour (the deep \"squared\" hero look)\n", Bl = "\nvec3 contrastFn(vec3 v, float a){ return (v - 0.5) * a + 0.5; }\nvec3 desaturate(vec3 color, float factor){\n vec3 gray = vec3(dot(vec3(0.299, 0.587, 0.114), color));\n return mix(color, gray, factor);\n}\nvec3 hueShift(vec3 color, float shift){\n vec3 g = vec3(0.57735);\n vec3 proj = g * dot(g, color);\n vec3 U = color - proj;\n vec3 W = cross(g, U);\n return U * cos(shift) + W * sin(shift) + proj;\n}\n\n// Our gradient: interpolate stops by their positions (uColorPos sorted ascending).\nvec3 grad(float u){\n u = clamp(u, 0.0, 1.0);\n vec3 col = uColors[0];\n for (int i = 0; i < MAX_COLORS - 1; i++){\n if (i >= uColorCount - 1) break;\n float p0 = uColorPos[i];\n float p1 = uColorPos[i + 1];\n if (u >= p0){\n float t = clamp((u - p0) / max(p1 - p0, 1e-5), 0.0, 1.0);\n col = mix(uColors[i], uColors[i + 1], t);\n }\n }\n return col;\n}\n\n// iOS-style 2D colour field. Each control point contributes an inverse-distance\n// weight; normalising the sum fills the whole surface without dark seams.\nvec3 meshGradient(vec2 uv){\n vec3 colorSum = vec3(0.0);\n float weightSum = 0.0;\n float exponent = mix(4.8, 1.35, clamp(uMeshSoftness, 0.0, 1.0));\n for (int i = 0; i < MAX_MESH_POINTS; i++){\n if (i >= uMeshPointCount) break;\n float influence = max(uMeshPointInfluence[i], 0.05);\n float distanceFromPoint = length(uv - uMeshPointPos[i]) / influence;\n float weight = 1.0 / (pow(max(distanceFromPoint, 0.012), exponent) + 0.002);\n colorSum += uMeshPointColor[i] * weight;\n weightSum += weight;\n }\n return colorSum / max(weightSum, 0.0001);\n}\n\n// Map a surface uv to the 0–1 gradient coordinate per gradient type. uGradShift\n// adds a low-frequency simplex warp so the colour varies in 2D (along the length\n// as well as across the width) — a 2D palette feel instead\n// of flat 1-D bands.\nfloat gradCoord(vec2 uv){\n float warp = uGradShift * simplexNoise(uv * 1.6 + 4.0);\n if (uGradType == 1){ return clamp(length(uv - 0.5) * 2.0 + warp, 0.0, 1.0); } // radial\n if (uGradType == 2){ return fract(atan(uv.y - 0.5, uv.x - 0.5) / (2.0 * PI) + 0.5 + warp); } // conic\n vec2 dir = vec2(sin(uGradAngle), cos(uGradAngle)); // linear, angled\n return clamp(dot(uv - 0.5, dir) + 0.5 + warp, 0.0, 1.0);\n}\n\n// One base-colour sample for the whole surface: rotate/scale/offset the raw-palette uv,\n// then pick the mesh field / baked 2D texture / procedural stops by mode. The raw palette\n// is sampled by (uv.x, uv.y) directly; the stops-generated texture is sampled via\n// gradCoord so its angle/type/warp still apply.\nvec3 waveBaseColor(vec2 uv){\n float gc = gradCoord(uv);\n vec2 mediaUv = uv - 0.5;\n float mediaCos = cos(uPaletteRotation);\n float mediaSin = sin(uPaletteRotation);\n mediaUv = vec2(\n mediaCos * mediaUv.x + mediaSin * mediaUv.y,\n -mediaSin * mediaUv.x + mediaCos * mediaUv.y\n );\n mediaUv = mediaUv * uPaletteScale + 0.5 + uPaletteOffset;\n vec2 puv = uPaletteRaw > 0.5\n ? clamp(mediaUv, 0.0, 1.0)\n : vec2(gc, clamp(uv.y, 0.0, 1.0));\n return uGradType == 3\n ? meshGradient(uv)\n : (uUsePalette > 0.5 ? texture2D(uPalette, puv).rgb : grad(gc));\n}\n\n// The shared colour grade: contrast → desaturate → hue rotate (degrees).\nvec3 applyColorGrade(vec3 c){\n c = contrastFn(c, uContrast);\n c = desaturate(c, 1.0 - uSaturation);\n return hueShift(c, radians(uHueShift));\n}\n", Vl = `
11595
- ${Rl}
11631
+ }, Hl = [
11632
+ "scroll",
11633
+ "hover",
11634
+ "pointerX",
11635
+ "pointerY",
11636
+ "pointerSpeed",
11637
+ "press",
11638
+ "scrollVelocity",
11639
+ "appear"
11640
+ ], Ul = [
11641
+ "displaceAmount",
11642
+ "detailAmount",
11643
+ "twistPowerX",
11644
+ "twistPowerY",
11645
+ "twistPowerZ",
11646
+ "twistFrequencyX",
11647
+ "twistFrequencyY",
11648
+ "twistFrequencyZ",
11649
+ "hueShift",
11650
+ "gradientShift",
11651
+ "colorSaturation",
11652
+ "opacity",
11653
+ "lineThickness",
11654
+ "lineAmount",
11655
+ "fiberStrength",
11656
+ "sheen",
11657
+ "iridescence",
11658
+ "positionX",
11659
+ "positionY"
11660
+ ], Wl = [
11661
+ "timeOffset",
11662
+ "cameraZoom",
11663
+ "blur",
11664
+ "grain"
11665
+ ];
11666
+ })), Kl, ql, Jl, Yl, Xl, Zl, Ql, $l, eu = t((() => {
11667
+ Gl(), Kl = "\nfloat xxhash(vec2 x){\n uvec2 t = floatBitsToUint(x);\n uint h = 0xc2b2ae3du * t.x + 0x165667b9u;\n h = (h << 17u | h >> 15u) * 0x27d4eb2fu;\n h += 0xc2b2ae3du * t.y;\n h = (h << 17u | h >> 15u) * 0x27d4eb2fu;\n h ^= h >> 15u;\n h *= 0x85ebca77u;\n h ^= h >> 13u;\n h *= 0xc2b2ae3du;\n h ^= h >> 16u;\n return uintBitsToFloat(h >> 9u | 0x3f800000u) - 1.0;\n}\nvec2 hash(vec2 x){\n float k = 6.283185307 * xxhash(x);\n return vec2(cos(k), sin(k));\n}\nfloat simplexNoise(in vec2 p){\n const float K1 = 0.366025404; // (sqrt(3)-1)/2\n const float K2 = 0.211324865; // (3-sqrt(3))/6\n vec2 i = floor(p + (p.x + p.y) * K1);\n vec2 a = p - i + (i.x + i.y) * K2;\n float m = step(a.y, a.x);\n vec2 o = vec2(m, 1.0 - m);\n vec2 b = a - o + K2;\n vec2 c = a - 1.0 + 2.0 * K2;\n vec3 h = max(0.5 - vec3(dot(a, a), dot(b, b), dot(c, c)), 0.0);\n vec3 n = h * h * h * vec3(dot(a, hash(i + 0.0)), dot(b, hash(i + o)), dot(c, hash(i + 1.0)));\n return dot(n, vec3(32.99)); // analytic factor (= 2916*sqrt(2)/125)\n}\n", ql = "\nuniform vec3 uColors[MAX_COLORS];\nuniform float uColorPos[MAX_COLORS];\nuniform int uColorCount;\nuniform int uGradType;\nuniform float uGradAngle;\nuniform float uGradShift;\nuniform vec2 uMeshPointPos[MAX_MESH_POINTS];\nuniform vec3 uMeshPointColor[MAX_MESH_POINTS];\nuniform float uMeshPointInfluence[MAX_MESH_POINTS];\nuniform int uMeshPointCount;\nuniform float uMeshSoftness;\nuniform sampler2D uPalette; // baked 2D palette texture\nuniform float uUsePalette; // >0.5 = sample the texture; else procedural grad()\nuniform float uPaletteRaw; // >0.5 = sample palette by raw (uv.x,uv.y), not gradCoord\nuniform vec2 uPaletteScale;\nuniform vec2 uPaletteOffset;\nuniform float uPaletteRotation;\nuniform float uHueShift;\nuniform float uContrast;\nuniform float uSaturation;\nuniform float uOpacity;\nuniform float uSquared; // 1 = square the output colour (the deep \"squared\" hero look)\n", Jl = "\nvec3 contrastFn(vec3 v, float a){ return (v - 0.5) * a + 0.5; }\nvec3 desaturate(vec3 color, float factor){\n vec3 gray = vec3(dot(vec3(0.299, 0.587, 0.114), color));\n return mix(color, gray, factor);\n}\nvec3 hueShift(vec3 color, float shift){\n vec3 g = vec3(0.57735);\n vec3 proj = g * dot(g, color);\n vec3 U = color - proj;\n vec3 W = cross(g, U);\n return U * cos(shift) + W * sin(shift) + proj;\n}\n\n// Our gradient: interpolate stops by their positions (uColorPos sorted ascending).\nvec3 grad(float u){\n u = clamp(u, 0.0, 1.0);\n vec3 col = uColors[0];\n for (int i = 0; i < MAX_COLORS - 1; i++){\n if (i >= uColorCount - 1) break;\n float p0 = uColorPos[i];\n float p1 = uColorPos[i + 1];\n if (u >= p0){\n float t = clamp((u - p0) / max(p1 - p0, 1e-5), 0.0, 1.0);\n col = mix(uColors[i], uColors[i + 1], t);\n }\n }\n return col;\n}\n\n// iOS-style 2D colour field. Each control point contributes an inverse-distance\n// weight; normalising the sum fills the whole surface without dark seams.\nvec3 meshGradient(vec2 uv){\n vec3 colorSum = vec3(0.0);\n float weightSum = 0.0;\n float exponent = mix(4.8, 1.35, clamp(uMeshSoftness, 0.0, 1.0));\n for (int i = 0; i < MAX_MESH_POINTS; i++){\n if (i >= uMeshPointCount) break;\n float influence = max(uMeshPointInfluence[i], 0.05);\n float distanceFromPoint = length(uv - uMeshPointPos[i]) / influence;\n float weight = 1.0 / (pow(max(distanceFromPoint, 0.012), exponent) + 0.002);\n colorSum += uMeshPointColor[i] * weight;\n weightSum += weight;\n }\n return colorSum / max(weightSum, 0.0001);\n}\n\n// Map a surface uv to the 0–1 gradient coordinate per gradient type. uGradShift\n// adds a low-frequency simplex warp so the colour varies in 2D (along the length\n// as well as across the width) — a 2D palette feel instead\n// of flat 1-D bands.\nfloat gradCoord(vec2 uv){\n float warp = uGradShift * simplexNoise(uv * 1.6 + 4.0);\n if (uGradType == 1){ return clamp(length(uv - 0.5) * 2.0 + warp, 0.0, 1.0); } // radial\n if (uGradType == 2){ return fract(atan(uv.y - 0.5, uv.x - 0.5) / (2.0 * PI) + 0.5 + warp); } // conic\n vec2 dir = vec2(sin(uGradAngle), cos(uGradAngle)); // linear, angled\n return clamp(dot(uv - 0.5, dir) + 0.5 + warp, 0.0, 1.0);\n}\n\n// One base-colour sample for the whole surface: rotate/scale/offset the raw-palette uv,\n// then pick the mesh field / baked 2D texture / procedural stops by mode. The raw palette\n// is sampled by (uv.x, uv.y) directly; the stops-generated texture is sampled via\n// gradCoord so its angle/type/warp still apply.\nvec3 waveBaseColor(vec2 uv){\n float gc = gradCoord(uv);\n vec2 mediaUv = uv - 0.5;\n float mediaCos = cos(uPaletteRotation);\n float mediaSin = sin(uPaletteRotation);\n mediaUv = vec2(\n mediaCos * mediaUv.x + mediaSin * mediaUv.y,\n -mediaSin * mediaUv.x + mediaCos * mediaUv.y\n );\n mediaUv = mediaUv * uPaletteScale + 0.5 + uPaletteOffset;\n vec2 puv = uPaletteRaw > 0.5\n ? clamp(mediaUv, 0.0, 1.0)\n : vec2(gc, clamp(uv.y, 0.0, 1.0));\n return uGradType == 3\n ? meshGradient(uv)\n : (uUsePalette > 0.5 ? texture2D(uPalette, puv).rgb : grad(gc));\n}\n\n// The shared colour grade: contrast → desaturate → hue rotate (degrees).\nvec3 applyColorGrade(vec3 c){\n c = contrastFn(c, uContrast);\n c = desaturate(c, 1.0 - uSaturation);\n return hueShift(c, radians(uHueShift));\n}\n", Yl = `
11668
+ ${Kl}
11596
11669
 
11597
11670
  uniform float uTime, uSpeed, uSeed;
11598
11671
  uniform float uDispFreqX, uDispFreqZ, uDispAmount;
@@ -11605,6 +11678,31 @@ varying vec3 vWorldPos;
11605
11678
  varying vec3 vViewDir;
11606
11679
  varying vec4 vClipPosition; // = gl_Position, for the wireframe theme's depth fade
11607
11680
 
11681
+ // Pointer field (optional, additive). ALL declarations here sit behind POINTER_FX so a wave with
11682
+ // no interaction config compiles the exact same program (JS-side uniform entries are always present
11683
+ // — see makeUniforms — but three only uploads uniforms the compiled program actually declares).
11684
+ #ifdef POINTER_FX
11685
+ uniform vec2 uPointer; // smoothed pointer, NDC (-1..1)
11686
+ uniform float uPointerActive; // presence ramp 0..1 × per-wave influence
11687
+ uniform float uPointerRadius; // falloff radius in NDC-y units (config radius × 2)
11688
+ uniform float uPointerAspect; // drawing-buffer dw/dh (circular screen falloff)
11689
+ uniform float uPointerAgitate;
11690
+ uniform float uPointerPush; // signed membrane dome at the cursor (+ repel / − attract)
11691
+ uniform float uPointerWake; // drag-wake trough amplitude (behind the moving cursor)
11692
+ uniform vec2 uPointerVel; // smoothed pointer velocity, NDC/s (drag-wake direction)
11693
+ varying float vPointerFall; // falloff × presence — consumed by both fragment themes
11694
+ #ifdef POINTER_RIPPLES
11695
+ uniform vec2 uRippleOrigin[4]; // NDC
11696
+ uniform float uRippleAge[4]; // seconds since spawn (CPU-computed)
11697
+ uniform float uRippleAmp[4]; // shared 0..1 decay envelope per slot (CPU-computed; 0 = slot free)
11698
+ uniform float uPointerRipple; // THIS wave's ripple amplitude (scales the shared envelope)
11699
+ const float RIPPLE_WAVE_SPEED = 0.85; // NDC/s the ring crest travels outward
11700
+ const float RIPPLE_SIGMA = 0.14; // gaussian half-width of the travelling packet (NDC)
11701
+ const float RIPPLE_FREQ = 11.0; // oscillation within the packet (one crest + faint troughs)
11702
+ const float RIPPLE_MAX_R = 1.2; // reach where the crest has fully left the frame
11703
+ #endif
11704
+ #endif
11705
+
11608
11706
  // expStep: a falloff from 1 (at x=0) toward 0, sharpness set by n. The
11609
11707
  // max() guards pow(0, n) (= Infinity → NaN) so negative n is safe — negative n
11610
11708
  // just concentrates the twist toward the OTHER end instead.
@@ -11684,6 +11782,57 @@ void main(){
11684
11782
  pos = (vec4(pos, 1.0) * rotB).xyz;
11685
11783
  pos = (vec4(pos, 1.0) * rotC).xyz;
11686
11784
 
11785
+ #ifdef POINTER_FX
11786
+ // Pointer field: displace along the wave's own (post-twist) up-axis, weighted by a circular
11787
+ // screen-space falloff around the smoothed cursor. Everything here is ADDITIVE and fenced, so
11788
+ // the shared path above/below is untouched and byte-identical when POINTER_FX is off.
11789
+ vec4 preClip = projectionMatrix * viewMatrix * modelMatrix * vec4(pos, 1.0);
11790
+ vec2 dp = (preClip.xy / max(preClip.w, 1.0e-6) - uPointer) * vec2(uPointerAspect, 1.0);
11791
+ float fall = smoothstep(uPointerRadius, 0.0, length(dp));
11792
+ vPointerFall = fall * uPointerActive;
11793
+ // Displacement axis = local +Y carried through the SAME three twist rotations as pos (row-vector
11794
+ // convention). Rotations are linear, so post-twist axis displacement equals pre-twist Y displacement.
11795
+ vec3 dispAxis = (((vec4(0.0, 1.0, 0.0, 0.0) * rotA) * rotB) * rotC).xyz;
11796
+ // Agitation: a fast churn octave near the cursor (additive — never rewrites base noise t, which
11797
+ // would force restructuring the shared path). Loop-safe under both time variants.
11798
+ #ifdef LOOP_MOTION
11799
+ float disp = uPointerAgitate * vPointerFall
11800
+ * simplexNoise(vec2(pos.x * uDispFreqX * 3.0, pos.z * uDispFreqZ * 3.0) + loopOff * 4.0);
11801
+ #else
11802
+ float disp = uPointerAgitate * vPointerFall
11803
+ * simplexNoise(vec2(pos.x * uDispFreqX * 3.0 + t * 4.0, pos.z * uDispFreqZ * 3.0));
11804
+ #endif
11805
+ // Membrane push/pull: a smooth dome (vPointerFall is the falloff) that swells toward you (+ repel)
11806
+ // or dents away (− attract) at the cursor, riding along with the sprung field.
11807
+ disp += uPointerPush * vPointerFall;
11808
+ // Drag-wake: pull the surface just BEHIND the moving cursor into a trailing trough. dp points
11809
+ // from cursor to vertex; "behind" is how far the vertex sits opposite the velocity (0 ahead → 1 a
11810
+ // radius behind), gated by speed so it only forms while dragging and heals when the cursor stops.
11811
+ vec2 velC = uPointerVel * vec2(uPointerAspect, 1.0);
11812
+ float wakeSpeed = length(velC);
11813
+ if (uPointerWake != 0.0 && wakeSpeed > 1.0e-4) {
11814
+ float behind = clamp(dot(-dp, velC) / (wakeSpeed * uPointerRadius), 0.0, 1.0);
11815
+ disp -= uPointerWake * vPointerFall * behind * smoothstep(0.05, 0.6, wakeSpeed);
11816
+ }
11817
+ #ifdef POINTER_RIPPLES
11818
+ for (int i = 0; i < 4; i++) {
11819
+ if (uRippleAmp[i] > 0.0) {
11820
+ float rd = length((preClip.xy / max(preClip.w, 1.0e-6) - uRippleOrigin[i]) * vec2(uPointerAspect, 1.0));
11821
+ // A wave PACKET whose crest travels outward at RIPPLE_WAVE_SPEED: a gaussian window centred on
11822
+ // the moving front carrying a short oscillation (a raised ring with faint trailing troughs),
11823
+ // so the energy radiates instead of throbbing at the click point. The shared uRippleAmp
11824
+ // envelope fades the whole packet over its lifetime; reach fades it as the crest leaves frame.
11825
+ float front = uRippleAge[i] * RIPPLE_WAVE_SPEED;
11826
+ float band = rd - front;
11827
+ float packet = exp(-band * band / (2.0 * RIPPLE_SIGMA * RIPPLE_SIGMA)) * cos(band * RIPPLE_FREQ);
11828
+ float reach = 1.0 - smoothstep(RIPPLE_MAX_R * 0.7, RIPPLE_MAX_R, front);
11829
+ disp += uPointerRipple * uRippleAmp[i] * packet * reach;
11830
+ }
11831
+ }
11832
+ #endif
11833
+ pos += dispAxis * disp;
11834
+ #endif
11835
+
11687
11836
  // The scale / rotation / position transform lives on the mesh (modelMatrix), so the
11688
11837
  // orientation matches THREE's Euler-XYZ rather than an in-shader rotation order.
11689
11838
  vec4 world = modelMatrix * vec4(pos, 1.0);
@@ -11692,16 +11841,16 @@ void main(){
11692
11841
  gl_Position = projectionMatrix * viewMatrix * world;
11693
11842
  vClipPosition = gl_Position;
11694
11843
  }
11695
- `, Hl = `
11844
+ `, Xl = `
11696
11845
  #define MAX_COLORS 8
11697
11846
  #define MAX_MESH_POINTS 8
11698
11847
  #define MAX_LIGHTS 8
11699
11848
  #define MAX_NOISE_BANDS 4
11700
11849
  #define PI 3.14159265359
11701
11850
 
11702
- ${Rl}
11851
+ ${Kl}
11703
11852
 
11704
- ${zl}
11853
+ ${ql}
11705
11854
  uniform float uDebug; // dev: 1 = show crease, 2 = show derivative normal
11706
11855
  uniform float uSheen; // white-lift on the flat (low-crease) areas (1 = full)
11707
11856
  uniform float uRoundness; // pose-robust normal-based roundness/thickness strength
@@ -11735,6 +11884,12 @@ varying vec4 vClipPosition; // clip-space depth (written by the vertex shader fo
11735
11884
  #ifdef EDGE_FEATHER
11736
11885
  uniform float uEdgeFeather; // ribbon long-edge softness (only when it differs from the 0.1 default)
11737
11886
  #endif
11887
+ #ifdef POINTER_FX
11888
+ uniform float uPointerThin; // 0..1 local translucency near the cursor
11889
+ uniform float uPointerHue; // degrees, local hue rotation near the cursor
11890
+ uniform float uPointerLighten; // -1..1 local brightness lift near the cursor
11891
+ varying float vPointerFall; // falloff × presence, written by the vertex shader
11892
+ #endif
11738
11893
 
11739
11894
  // Cheap value hash for the optional grain overlay (distinct from the simplex hash).
11740
11895
  float grainHash(vec2 p){ return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453); }
@@ -11742,7 +11897,7 @@ float grainHash(vec2 p){ return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758
11742
11897
  float parabola(float x, float k){ return pow(4.0 * x * (1.0 - x), k); }
11743
11898
  float mapLinear(float v, float a, float b, float c, float d){ return c + (v - a) * (d - c) / (b - a); }
11744
11899
 
11745
- ${Bl}
11900
+ ${Jl}
11746
11901
 
11747
11902
  // Striations: a subtle high-frequency simplex-noise grain ADDED to the
11748
11903
  // colour — colour-matched (weaker where blue is high), only near folds (crease), and
@@ -11799,6 +11954,12 @@ void main(){
11799
11954
  col = surfaceStreaks(vUv, col, crease);
11800
11955
  col = applyColorGrade(col);
11801
11956
 
11957
+ #ifdef POINTER_FX
11958
+ // Local hue rotation + brightness lift near the cursor (both fade out with vPointerFall).
11959
+ col = hueShift(col, radians(uPointerHue) * vPointerFall);
11960
+ col *= 1.0 + uPointerLighten * vPointerFall;
11961
+ #endif
11962
+
11802
11963
  // Iridescence: a thin-film / holographic hue that shifts with view angle. Reuses the same
11803
11964
  // camera-facing ratio as roundness (recomputed here, since roundness may be off): grazing parts
11804
11965
  // of the ribbon (low facing) shift hue most, so the colour flows as the ribbon curves. Skipped
@@ -11861,6 +12022,9 @@ void main(){
11861
12022
  float ribEdge = smoothstep(0.0, 0.1, vUv.y) * (1.0 - smoothstep(0.9, 1.0, vUv.y));
11862
12023
  #endif
11863
12024
  float alpha = uOpacity * ribEdge;
12025
+ #ifdef POINTER_FX
12026
+ alpha *= clamp(1.0 - uPointerThin * vPointerFall, 0.0, 1.0); // solid: local translucency
12027
+ #endif
11864
12028
  if (uEdgeFade > 0.001) {
11865
12029
  vec2 sc = gl_FragCoord.xy / max(uResolution, vec2(1.0));
11866
12030
  float vig =
@@ -11882,14 +12046,14 @@ void main(){
11882
12046
  gl_FragColor.rgb *= gl_FragColor.a;
11883
12047
  #endif
11884
12048
  }
11885
- `, Ul = `
12049
+ `, Zl = `
11886
12050
  #define MAX_COLORS 8
11887
12051
  #define MAX_MESH_POINTS 8
11888
12052
  #define PI 3.14159265359
11889
12053
 
11890
- ${Rl}
12054
+ ${Kl}
11891
12055
 
11892
- ${zl}
12056
+ ${ql}
11893
12057
  uniform float uLineAmount; // default 425
11894
12058
  uniform float uLineThickness; // default 1
11895
12059
  uniform float uLineDerivativePower; // default 0.95
@@ -11898,16 +12062,30 @@ uniform vec3 uClearColor; // = page background colour (shown between t
11898
12062
 
11899
12063
  varying vec2 vUv;
11900
12064
  varying vec4 vClipPosition;
12065
+ #ifdef POINTER_FX
12066
+ uniform float uPointerThin; // 0..1 — strands taper to hairlines near the cursor
12067
+ uniform float uPointerHue; // degrees, local hue rotation near the cursor
12068
+ uniform float uPointerLighten; // -1..1 local brightness lift near the cursor
12069
+ varying float vPointerFall; // falloff × presence, written by the vertex shader
12070
+ #endif
11901
12071
 
11902
- ${Bl}
12072
+ ${Jl}
11903
12073
 
11904
12074
  void main(){
11905
12075
  // Same 2D palette sample + colour ops as the solid theme.
11906
12076
  vec3 color = applyColorGrade(waveBaseColor(vUv));
11907
12077
 
12078
+ #ifdef POINTER_FX
12079
+ color = hueShift(color, radians(uPointerHue) * vPointerFall);
12080
+ color *= 1.0 + uPointerLighten * vPointerFall;
12081
+ #endif
12082
+
11908
12083
  // Carve into fine vertical lines; thickness from the screen-space uv derivative.
11909
12084
  vec2 dy = dFdy(vUv);
11910
12085
  float lineThickness = uLineThickness * pow(abs(dy.x * uMaxWidth), uLineDerivativePower);
12086
+ #ifdef POINTER_FX
12087
+ lineThickness *= clamp(1.0 - uPointerThin * vPointerFall, 0.0, 1.0); // wireframe: taper strands
12088
+ #endif
11911
12089
  float a = abs(sin(vUv.x * uLineAmount));
11912
12090
  a = smoothstep(lineThickness, 0.0, a);
11913
12091
 
@@ -11924,9 +12102,9 @@ void main(){
11924
12102
  gl_FragColor.rgb *= gl_FragColor.a;
11925
12103
  #endif
11926
12104
  }
11927
- `, Wl = "\nvarying vec2 vUv;\nvoid main(){\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n", Gl = "\nuniform sampler2D tDiffuse;\nuniform vec2 uResolution;\nuniform float uBlurAmount;\nuniform int uBlurSamples;\nuniform float uGrainAmount;\nuniform float uTime;\nvarying vec2 vUv;\n\nfloat random2(vec2 st){ return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453); }\n\n// Angular (spin) blur: rotate the sample coord around the centre and\n// accumulate — a tangential smear that grows toward the edges. Carries alpha so a\n// transparent background survives the post pass.\nvec4 blurAngular(sampler2D tex, vec2 uv, float angle, int samples){\n vec4 total = vec4(0.0);\n vec2 coord = uv - 0.5;\n float dist = 1.0 / float(samples);\n vec2 dir = vec2(cos(angle * dist), sin(angle * dist));\n mat2 rot = mat2(dir.x, dir.y, -dir.y, dir.x);\n for (int i = 0; i < 64; i++){\n if (i >= samples) break;\n total += texture2D(tex, coord + 0.5);\n coord = coord * rot; // row-vector order (coord * rot) sets the spin direction\n }\n return total * dist;\n}\n\nvoid main(){\n vec4 sceneColor = texture2D(tDiffuse, vUv);\n vec4 blurColor = blurAngular(tDiffuse, vUv, uBlurAmount, uBlurSamples);\n // blurPower: keep a sharp band weighted to the middle, blurring toward top & bottom.\n float blurPower = smoothstep(0.0, 0.7, vUv.y) - smoothstep(0.2, 1.0, vUv.y);\n vec4 color = mix(blurColor, sceneColor, blurPower);\n // Static film grain: keyed off gl_FragCoord only (no uTime), so it doesn't flicker.\n color.rgb += mix(uGrainAmount, -uGrainAmount, random2(gl_FragCoord.xy * 0.01)) * (4.0 / 255.0);\n gl_FragColor = color; // preserve alpha → transparent background works\n}\n";
11928
- })), ql, Jl, Yl, Xl, Zl, Ql, $l = t((() => {
11929
- Vc(), ql = 400, Jl = 16, Yl = ql / 4, Xl = new K(1, 0, 0), Zl = new K(0, 1, 0), Ql = class {
12105
+ `, Ql = "\nvarying vec2 vUv;\nvoid main(){\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n", $l = "\nuniform sampler2D tDiffuse;\nuniform vec2 uResolution;\nuniform float uBlurAmount;\nuniform int uBlurSamples;\nuniform float uGrainAmount;\nuniform float uTime;\nvarying vec2 vUv;\n\nfloat random2(vec2 st){ return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453); }\n\n// Angular (spin) blur: rotate the sample coord around the centre and\n// accumulate — a tangential smear that grows toward the edges. Carries alpha so a\n// transparent background survives the post pass.\nvec4 blurAngular(sampler2D tex, vec2 uv, float angle, int samples){\n vec4 total = vec4(0.0);\n vec2 coord = uv - 0.5;\n float dist = 1.0 / float(samples);\n vec2 dir = vec2(cos(angle * dist), sin(angle * dist));\n mat2 rot = mat2(dir.x, dir.y, -dir.y, dir.x);\n for (int i = 0; i < 64; i++){\n if (i >= samples) break;\n total += texture2D(tex, coord + 0.5);\n coord = coord * rot; // row-vector order (coord * rot) sets the spin direction\n }\n return total * dist;\n}\n\nvoid main(){\n vec4 sceneColor = texture2D(tDiffuse, vUv);\n vec4 blurColor = blurAngular(tDiffuse, vUv, uBlurAmount, uBlurSamples);\n // blurPower: keep a sharp band weighted to the middle, blurring toward top & bottom.\n float blurPower = smoothstep(0.0, 0.7, vUv.y) - smoothstep(0.2, 1.0, vUv.y);\n vec4 color = mix(blurColor, sceneColor, blurPower);\n // Static film grain: keyed off gl_FragCoord only (no uTime), so it doesn't flicker.\n color.rgb += mix(uGrainAmount, -uGrainAmount, random2(gl_FragCoord.xy * 0.01)) * (4.0 / 255.0);\n gl_FragColor = color; // preserve alpha → transparent background works\n}\n";
12106
+ })), tu, nu, ru, iu, au, ou, su = t((() => {
12107
+ Vc(), tu = 400, nu = 16, ru = tu / 4, iu = new K(1, 0, 0), au = new K(0, 1, 0), ou = class {
11930
12108
  geometry;
11931
12109
  segments = -1;
11932
12110
  constructor(e) {
@@ -11935,11 +12113,11 @@ void main(){
11935
12113
  resize(e) {
11936
12114
  if (e === this.segments) return;
11937
12115
  this.segments = e;
11938
- let t = Gt.clamp(Math.round(e), 48, 200), n = t * 2, r = new wi(ql, ql, t, n), i = r.attributes.position, a = r.attributes.uv, o = new K();
12116
+ let t = Gt.clamp(Math.round(e), 48, 200), n = t * 2, r = new wi(tu, tu, t, n), i = r.attributes.position, a = r.attributes.uv, o = new K();
11939
12117
  for (let e = 0; e < i.count; e++) {
11940
12118
  o.fromBufferAttribute(i, e);
11941
12119
  let t = a.getY(e), n = 4 - 2 * (4 * t * (1 - t)) ** 9.5;
11942
- o.x < -16 ? o.z += n : o.x < Jl ? (o.z = Math.cos(Gt.mapLinear(o.x, -16, Jl, 0, Math.PI)) * n, o.x = Math.cos(Gt.mapLinear(o.x, -16, Jl, -Math.PI / 2, Math.PI / 2)) * n - Jl) : (o.z -= n, o.x = -o.x), o.x += Yl, o.applyAxisAngle(Xl, -Math.PI / 2), o.applyAxisAngle(Zl, -Math.PI / 2), i.setXYZ(e, o.x, o.y, o.z);
12120
+ o.x < -16 ? o.z += n : o.x < nu ? (o.z = Math.cos(Gt.mapLinear(o.x, -16, nu, 0, Math.PI)) * n, o.x = Math.cos(Gt.mapLinear(o.x, -16, nu, -Math.PI / 2, Math.PI / 2)) * n - nu) : (o.z -= n, o.x = -o.x), o.x += ru, o.applyAxisAngle(iu, -Math.PI / 2), o.applyAxisAngle(au, -Math.PI / 2), i.setXYZ(e, o.x, o.y, o.z);
11943
12121
  }
11944
12122
  i.needsUpdate = !0;
11945
12123
  let s = t + 1, c = r.getIndex(), l = c ? Array.from(c.array) : [];
@@ -11959,43 +12137,356 @@ void main(){
11959
12137
  };
11960
12138
  }));
11961
12139
  //#endregion
12140
+ //#region src/renderer/interaction.ts
12141
+ function cu(e, t) {
12142
+ return e > 0 ? 1 - Math.exp(-t / e) : 1;
12143
+ }
12144
+ function lu(e, t, n, r, i, a) {
12145
+ if (a <= 0) return;
12146
+ let o = a > Tu ? Math.min(Math.ceil(a / Tu), Eu) : 1, s = a / o, c = r * r, l = 2 * i * r;
12147
+ for (let r = 0; r < o; r++) t.x += (c * (n.x - e.x) - l * t.x) * s, t.y += (c * (n.y - e.y) - l * t.y) * s, e.x += t.x * s, e.y += t.y * s;
12148
+ }
12149
+ function uu(e) {
12150
+ return e.interaction?.enabled !== !1;
12151
+ }
12152
+ function du(e) {
12153
+ let t = e.interaction;
12154
+ return !!t && (!!t.hover || (t.press?.ripple ?? 0) > 0);
12155
+ }
12156
+ function fu(e, t) {
12157
+ return uu(e) && du(t);
12158
+ }
12159
+ function pu(e, t) {
12160
+ return uu(e) && (t.interaction?.press?.ripple ?? 0) > 0;
12161
+ }
12162
+ function mu(e) {
12163
+ return uu(e) && e.waves.some(du);
12164
+ }
12165
+ function hu(e) {
12166
+ return uu(e) ? (e.interaction?.bindings?.length ?? 0) > 0 ? !0 : e.waves.some((e) => {
12167
+ let t = e.interaction;
12168
+ return !!t && (!!t.hover || (t.press?.ripple ?? 0) > 0 || (t.bindings?.length ?? 0) > 0);
12169
+ }) : !1;
12170
+ }
12171
+ var gu, _u, vu, yu, bu, xu, Su, Cu, wu, Tu, Eu, Du, Ou, ku, Au, ju, Mu = t((() => {
12172
+ Vc(), hl(), gu = 1.5, _u = .08, vu = 4, yu = 2, bu = .15, xu = .12, Su = .25, Cu = .7, wu = .02, Tu = 1 / 120, Eu = 6, Du = (e, t) => ({
12173
+ base: e,
12174
+ apply: t
12175
+ }), Ou = (e, t) => ({
12176
+ base: e,
12177
+ apply: t
12178
+ }), ku = {
12179
+ displaceAmount: Du((e) => e.displaceAmount, (e, t) => {
12180
+ t.u.uDispAmount.value = e;
12181
+ }),
12182
+ detailAmount: Du((e) => e.detailAmount ?? 0, (e, t) => {
12183
+ t.u.uDetailAmount.value = e;
12184
+ }),
12185
+ twistPowerX: Du((e) => e.twistPower.x, (e, t) => {
12186
+ t.u.uTwPowX.value = e;
12187
+ }),
12188
+ twistPowerY: Du((e) => e.twistPower.y, (e, t) => {
12189
+ t.u.uTwPowY.value = e;
12190
+ }),
12191
+ twistPowerZ: Du((e) => e.twistPower.z, (e, t) => {
12192
+ t.u.uTwPowZ.value = e;
12193
+ }),
12194
+ twistFrequencyX: Du((e) => e.twistFrequency.x, (e, t) => {
12195
+ t.u.uTwFreqX.value = e;
12196
+ }),
12197
+ twistFrequencyY: Du((e) => e.twistFrequency.y, (e, t) => {
12198
+ t.u.uTwFreqY.value = e;
12199
+ }),
12200
+ twistFrequencyZ: Du((e) => e.twistFrequency.z, (e, t) => {
12201
+ t.u.uTwFreqZ.value = e;
12202
+ }),
12203
+ hueShift: Du((e) => e.hueShift, (e, t) => {
12204
+ t.u.uHueShift.value = e;
12205
+ }),
12206
+ gradientShift: Du((e) => e.gradientShift ?? 0, (e, t) => {
12207
+ t.u.uGradShift.value = e;
12208
+ }),
12209
+ colorSaturation: Du((e) => e.colorSaturation, (e, t) => {
12210
+ t.u.uSaturation.value = e;
12211
+ }),
12212
+ opacity: Du((e) => e.opacity, (e, t) => {
12213
+ t.u.uOpacity.value = e;
12214
+ }),
12215
+ lineThickness: Du((e) => e.lineThickness ?? 1, (e, t) => {
12216
+ t.u.uLineThickness.value = e;
12217
+ }),
12218
+ lineAmount: Du((e) => e.lineAmount ?? 425, (e, t) => {
12219
+ t.u.uLineAmount.value = e;
12220
+ }),
12221
+ fiberStrength: Du((e) => e.fiberStrength, (e, t) => {
12222
+ t.u.uFiberStrength.value = e;
12223
+ }),
12224
+ sheen: Du((e) => e.sheen ?? 1, (e, t) => {
12225
+ t.u.uSheen.value = e;
12226
+ }),
12227
+ iridescence: Du((e) => e.iridescence ?? 0, (e, t) => {
12228
+ t.u.uIridescence.value = e;
12229
+ }),
12230
+ positionX: Du((e) => e.position.x, (e, t) => {
12231
+ t.mesh.position.x = e;
12232
+ }),
12233
+ positionY: Du((e) => e.position.y, (e, t) => {
12234
+ t.mesh.position.y = e;
12235
+ })
12236
+ }, Au = {
12237
+ timeOffset: Ou((e) => e.timeOffset ?? 0, (e, t) => {
12238
+ t.out.timeOffset = e;
12239
+ }),
12240
+ cameraZoom: Ou((e) => e.cameraZoom ?? 1, (e, t) => {
12241
+ t.out.zoom = e;
12242
+ }),
12243
+ blur: Ou((e) => e.blur, (e, t) => {
12244
+ t.post.uBlurAmount.value = e;
12245
+ }),
12246
+ grain: Ou((e) => e.grain, (e, t) => {
12247
+ t.post.uGrainAmount.value = e;
12248
+ })
12249
+ }, ju = class {
12250
+ container;
12251
+ cfg;
12252
+ scrollOverride = null;
12253
+ ndc = new G();
12254
+ ndcTarget = new G();
12255
+ ndcPrev = new G();
12256
+ velNdc = new G();
12257
+ presence = 0;
12258
+ presenceTarget = 0;
12259
+ press = 0;
12260
+ pressTarget = 0;
12261
+ pointerSpeed = 0;
12262
+ scroll = 0;
12263
+ scrollPrev = 0;
12264
+ scrollVel = 0;
12265
+ appearLatched = !1;
12266
+ customInputs = /* @__PURE__ */ new Map();
12267
+ ripples = [];
12268
+ fields = [];
12269
+ bindingState = /* @__PURE__ */ new Map();
12270
+ seenBindings = /* @__PURE__ */ new Set();
12271
+ out;
12272
+ constructor(e, t) {
12273
+ this.container = e, this.cfg = t;
12274
+ for (let e = 0; e < 4; e++) this.ripples.push({
12275
+ origin: new G(),
12276
+ age: 0,
12277
+ amp: 0,
12278
+ active: !1
12279
+ });
12280
+ this.out = {
12281
+ ndc: this.ndc,
12282
+ presence: 0,
12283
+ ripples: this.ripples
12284
+ };
12285
+ let n = { passive: !0 };
12286
+ e.addEventListener("pointerenter", this.onPointerEnter, n), e.addEventListener("pointermove", this.onPointerMove, n), e.addEventListener("pointerleave", this.onPointerLeave, n), e.addEventListener("pointercancel", this.onPointerCancel, n), e.addEventListener("pointerdown", this.onPointerDown, n), e.addEventListener("pointerup", this.onPointerUp, n);
12287
+ }
12288
+ ignore(e) {
12289
+ return e.pointerType === "touch" && this.cfg()?.interaction?.touch !== !0;
12290
+ }
12291
+ setNdcTarget(e) {
12292
+ let t = this.container.getBoundingClientRect();
12293
+ t.width <= 0 || t.height <= 0 || this.ndcTarget.set((e.clientX - t.left) / t.width * 2 - 1, -((e.clientY - t.top) / t.height * 2 - 1));
12294
+ }
12295
+ onPointerEnter = (e) => {
12296
+ this.ignore(e) || (this.presenceTarget = 1, this.setNdcTarget(e));
12297
+ };
12298
+ onPointerMove = (e) => {
12299
+ this.ignore(e) || e.pointerType === "touch" && this.pressTarget < .5 || (this.presenceTarget = 1, this.setNdcTarget(e));
12300
+ };
12301
+ onPointerLeave = (e) => {
12302
+ this.ignore(e) || (this.presenceTarget = 0, this.ndcTarget.set(0, 0));
12303
+ };
12304
+ onPointerCancel = (e) => {
12305
+ this.ignore(e) || (this.pressTarget = 0, this.presenceTarget = 0, this.ndcTarget.set(0, 0));
12306
+ };
12307
+ onPointerDown = (e) => {
12308
+ if (this.ignore(e)) return;
12309
+ this.pressTarget = 1, this.presenceTarget = 1, this.setNdcTarget(e);
12310
+ let t = this.cfg();
12311
+ t && t.waves.some((e) => (e.interaction?.press?.ripple ?? 0) > 0) && this.spawnRipple();
12312
+ };
12313
+ onPointerUp = (e) => {
12314
+ this.ignore(e) || (this.pressTarget = 0, e.pointerType === "touch" && (this.presenceTarget = 0, this.ndcTarget.set(0, 0)));
12315
+ };
12316
+ spawnRipple() {
12317
+ let e = this.ripples.find((e) => !e.active);
12318
+ if (!e) {
12319
+ e = this.ripples[0];
12320
+ for (let t of this.ripples) t.age > e.age && (e = t);
12321
+ }
12322
+ e.origin.copy(this.ndcTarget), e.age = 0, e.amp = 1, e.active = !0;
12323
+ }
12324
+ update(e) {
12325
+ let t = this.cfg();
12326
+ if (!t) return;
12327
+ let n = Math.max(e, 0), r = cu(xu, n);
12328
+ if (this.ndcPrev.copy(this.ndc), this.ndc.lerp(this.ndcTarget, r), this.presence += (this.presenceTarget - this.presence) * r, this.press += (this.pressTarget - this.press) * r, n > 1e-5) {
12329
+ let e = cu(_u, n);
12330
+ this.velNdc.x += ((this.ndc.x - this.ndcPrev.x) / n - this.velNdc.x) * e, this.velNdc.y += ((this.ndc.y - this.ndcPrev.y) / n - this.velNdc.y) * e;
12331
+ }
12332
+ this.pointerSpeed = this.presence * ml(this.velNdc.length() / vu);
12333
+ let i = t.waves;
12334
+ this.fields.length > i.length && (this.fields.length = i.length);
12335
+ for (let e = 0; e < i.length; e++) {
12336
+ let t = this.fields[e];
12337
+ t || (t = {
12338
+ ndc: this.ndcTarget.clone(),
12339
+ vel: new G(),
12340
+ presence: this.presenceTarget
12341
+ }, this.fields[e] = t);
12342
+ let r = Math.max(i[e].interaction?.hover?.smoothing ?? xu, wu);
12343
+ lu(t.ndc, t.vel, this.ndcTarget, 1 / r, Cu, n), t.presence += (this.presenceTarget - t.presence) * cu(r, n);
12344
+ }
12345
+ let a = this.scrollOverride ?? this.computeScroll();
12346
+ if (n > 1e-5) {
12347
+ let e = Math.abs(a - this.scrollPrev) / n;
12348
+ this.scrollVel += (e - this.scrollVel) * cu(bu, n);
12349
+ }
12350
+ this.scrollPrev = a, this.scroll = a, this.appearLatched = !0;
12351
+ for (let e of this.ripples) {
12352
+ if (!e.active) continue;
12353
+ e.age += n;
12354
+ let t = Math.max(0, 1 - e.age / gu);
12355
+ e.amp = t * t, e.amp <= 0 && (e.active = !1);
12356
+ }
12357
+ this.updateBindings(t, n);
12358
+ }
12359
+ updateBindings(e, t) {
12360
+ let n = this.seenBindings;
12361
+ n.clear();
12362
+ let r = e.interaction?.bindings;
12363
+ if (r) for (let e = 0; e < r.length; e++) this.advanceBinding(r[e], t);
12364
+ for (let n = 0; n < e.waves.length; n++) {
12365
+ let r = e.waves[n].interaction?.bindings;
12366
+ if (r) for (let e = 0; e < r.length; e++) this.advanceBinding(r[e], t);
12367
+ }
12368
+ if (this.bindingState.size > n.size) for (let e of this.bindingState.keys()) n.has(e) || this.bindingState.delete(e);
12369
+ }
12370
+ advanceBinding(e, t) {
12371
+ this.seenBindings.add(e);
12372
+ let n = this.rawSource(e.source), r = this.bindingState.get(e);
12373
+ (!r || r.source !== e.source) && (r = {
12374
+ value: e.source === "appear" ? 0 : n,
12375
+ source: e.source
12376
+ }, this.bindingState.set(e, r)), r.value += (n - r.value) * cu(e.smoothing ?? Su, t);
12377
+ }
12378
+ bindingValue(e) {
12379
+ return this.bindingState.get(e)?.value ?? 0;
12380
+ }
12381
+ rawSource(e) {
12382
+ switch (e) {
12383
+ case "scroll": return this.scroll;
12384
+ case "hover": return this.presence;
12385
+ case "pointerX": return (this.ndc.x + 1) * .5;
12386
+ case "pointerY": return (this.ndc.y + 1) * .5;
12387
+ case "pointerSpeed": return this.pointerSpeed;
12388
+ case "press": return this.press;
12389
+ case "scrollVelocity": return ml(this.scrollVel / yu);
12390
+ case "appear": return +!!this.appearLatched;
12391
+ default: return this.customInputs.get(e.slice(7)) ?? 0;
12392
+ }
12393
+ }
12394
+ computeScroll() {
12395
+ let e = this.container.getBoundingClientRect(), t = window.innerHeight || document.documentElement.clientHeight || 1;
12396
+ return ml((t - e.top) / (t + e.height));
12397
+ }
12398
+ sample() {
12399
+ return this.out.presence = this.presence, this.out;
12400
+ }
12401
+ fieldFor(e) {
12402
+ return this.fields[e] ?? null;
12403
+ }
12404
+ pointerFlux() {
12405
+ return this.pointerSpeed;
12406
+ }
12407
+ pointerVelocity() {
12408
+ return this.velNdc;
12409
+ }
12410
+ setInput(e, t) {
12411
+ typeof e != "string" || !Number.isFinite(t) || this.customInputs.set(e, t);
12412
+ }
12413
+ settle() {
12414
+ this.presence = this.presenceTarget = 0, this.press = this.pressTarget = 0, this.pointerSpeed = 0, this.velNdc.set(0, 0), this.ndc.set(0, 0), this.ndcTarget.set(0, 0), this.ndcPrev.set(0, 0);
12415
+ for (let e of this.fields) e.ndc.set(0, 0), e.vel.set(0, 0), e.presence = 0;
12416
+ for (let e of this.ripples) e.age = 0, e.amp = 0, e.active = !1;
12417
+ let e = this.scrollOverride ?? this.computeScroll();
12418
+ this.scroll = this.scrollPrev = e, this.scrollVel = 0, this.appearLatched = !0;
12419
+ let t = this.cfg();
12420
+ if (t) {
12421
+ this.bindingState.clear();
12422
+ let e = (e) => {
12423
+ this.bindingState.set(e, {
12424
+ value: this.rawSource(e.source),
12425
+ source: e.source
12426
+ });
12427
+ };
12428
+ for (let n of t.interaction?.bindings ?? []) e(n);
12429
+ for (let n of t.waves) for (let t of n.interaction?.bindings ?? []) e(t);
12430
+ }
12431
+ }
12432
+ snapScroll() {
12433
+ let e = this.scrollOverride ?? this.computeScroll();
12434
+ this.scroll = this.scrollPrev = e, this.scrollVel = 0;
12435
+ let t = this.cfg();
12436
+ if (!t) return;
12437
+ let n = (e) => {
12438
+ (e.source === "scroll" || e.source === "scrollVelocity") && this.bindingState.set(e, {
12439
+ value: this.rawSource(e.source),
12440
+ source: e.source
12441
+ });
12442
+ };
12443
+ for (let e of t.interaction?.bindings ?? []) n(e);
12444
+ for (let e of t.waves) for (let t of e.interaction?.bindings ?? []) n(t);
12445
+ }
12446
+ dispose() {
12447
+ let e = this.container;
12448
+ e.removeEventListener("pointerenter", this.onPointerEnter), e.removeEventListener("pointermove", this.onPointerMove), e.removeEventListener("pointerleave", this.onPointerLeave), e.removeEventListener("pointercancel", this.onPointerCancel), e.removeEventListener("pointerdown", this.onPointerDown), e.removeEventListener("pointerup", this.onPointerUp), this.customInputs.clear(), this.bindingState.clear();
12449
+ }
12450
+ };
12451
+ }));
12452
+ //#endregion
11962
12453
  //#region src/renderer/palette.ts
11963
- function eu(e) {
12454
+ function Nu(e) {
11964
12455
  return e * e * (3 - 2 * e);
11965
12456
  }
11966
- function tu(e, t) {
12457
+ function Pu(e, t) {
11967
12458
  let n = new X(e).clone().convertLinearToSRGB();
11968
12459
  return `rgba(${Math.round(n.r * 255)}, ${Math.round(n.g * 255)}, ${Math.round(n.b * 255)}, ${t})`;
11969
12460
  }
11970
- function nu(e) {
12461
+ function Fu(e) {
11971
12462
  let t = document.createElement("canvas");
11972
- t.width = xu, t.height = Su;
12463
+ t.width = ed, t.height = td;
11973
12464
  let n = t.getContext("2d");
11974
12465
  if (!n) return t;
11975
- let r = [...e.stops].sort((e, t) => e.pos - t.pos), i = n.createLinearGradient(0, 0, xu, 0);
12466
+ let r = [...e.stops].sort((e, t) => e.pos - t.pos), i = n.createLinearGradient(0, 0, ed, 0);
11976
12467
  if (r.length === 0) i.addColorStop(0, "#ffffff");
11977
12468
  else for (let e of r) i.addColorStop(ml(e.pos), e.color);
11978
- n.fillStyle = i, n.fillRect(0, 0, xu, Su);
12469
+ n.fillStyle = i, n.fillRect(0, 0, ed, td);
11979
12470
  let a = ml(e.edgeAmount);
11980
12471
  if (a > .001) {
11981
- let t = n.createLinearGradient(0, 0, 0, Su);
11982
- t.addColorStop(0, tu(e.edgeColor, a)), t.addColorStop(.5, tu(e.edgeColor, 0)), t.addColorStop(1, tu(e.edgeColor, a)), n.fillStyle = t, n.fillRect(0, 0, xu, Su);
12472
+ let t = n.createLinearGradient(0, 0, 0, td);
12473
+ t.addColorStop(0, Pu(e.edgeColor, a)), t.addColorStop(.5, Pu(e.edgeColor, 0)), t.addColorStop(1, Pu(e.edgeColor, a)), n.fillStyle = t, n.fillRect(0, 0, ed, td);
11983
12474
  }
11984
12475
  return t;
11985
12476
  }
11986
- function ru(e) {
12477
+ function Iu(e) {
11987
12478
  return `${e.stops.map((e) => `${e.color}@${e.pos.toFixed(3)}`).join(",")}|${e.edgeColor}|${e.edgeAmount.toFixed(3)}`;
11988
12479
  }
11989
- function iu(e) {
12480
+ function Lu(e) {
11990
12481
  return e.colorSpace = At, e.minFilter = z, e.magFilter = z, e.wrapS = he, e.wrapT = he, e.generateMipmaps = !1, e;
11991
12482
  }
11992
- function au(e) {
11993
- return iu(new yi(e));
12483
+ function Ru(e) {
12484
+ return Lu(new yi(e));
11994
12485
  }
11995
- function ou(e) {
11996
- return au(nu(e));
12486
+ function zu(e) {
12487
+ return Ru(Fu(e));
11997
12488
  }
11998
- function su(e) {
12489
+ function Bu(e) {
11999
12490
  let t = document.createElement("canvas");
12000
12491
  t.width = Math.max(1, Math.round(e.width)), t.height = Math.max(1, Math.round(e.height));
12001
12492
  let n = t.getContext("2d");
@@ -12012,11 +12503,11 @@ function su(e) {
12012
12503
  else for (let e of l) c.addColorStop(ml(e.pos), e.color);
12013
12504
  return n.fillStyle = c, n.fillRect(0, 0, r, i), t;
12014
12505
  }
12015
- function cu(e) {
12506
+ function Vu(e) {
12016
12507
  let t = ml(e), n = t <= .0031308 ? t * 12.92 : 1.055 * t ** (1 / 2.4) - .055;
12017
12508
  return Math.round(ml(n) * 255);
12018
12509
  }
12019
- function lu(e, t, n, r) {
12510
+ function Hu(e, t, n, r) {
12020
12511
  let i = Math.max(1, Math.round(n)), a = Math.max(1, Math.round(r)), o = new ImageData(i, a), s = o.data, c = e.length >= 2 ? e : yl(), l = c.map((e) => new X(e.color)), u = 4.8 + -3.4499999999999997 * ml(t);
12021
12512
  for (let e = 0; e < a; e++) {
12022
12513
  let t = 1 - e / Math.max(1, a - 1);
@@ -12027,12 +12518,12 @@ function lu(e, t, n, r) {
12027
12518
  a += l[e].r * s, o += l[e].g * s, d += l[e].b * s, f += s;
12028
12519
  }
12029
12520
  let p = Math.max(f, 1e-4), m = (e * i + n) * 4;
12030
- s[m] = cu(a / p), s[m + 1] = cu(o / p), s[m + 2] = cu(d / p), s[m + 3] = 255;
12521
+ s[m] = Vu(a / p), s[m + 1] = Vu(o / p), s[m + 2] = Vu(d / p), s[m + 3] = 255;
12031
12522
  }
12032
12523
  }
12033
12524
  return o;
12034
12525
  }
12035
- function uu(e, t, n, r) {
12526
+ function Uu(e, t, n, r) {
12036
12527
  let i = document.createElement("canvas");
12037
12528
  i.width = Math.max(1, Math.round(n)), i.height = Math.max(1, Math.round(r));
12038
12529
  let a = i.getContext("2d");
@@ -12040,42 +12531,42 @@ function uu(e, t, n, r) {
12040
12531
  let o = Math.min(1, 320 / Math.max(i.width, i.height)), s = Math.max(2, Math.round(i.width * o)), c = Math.max(2, Math.round(i.height * o)), l = document.createElement("canvas");
12041
12532
  l.width = s, l.height = c;
12042
12533
  let u = l.getContext("2d");
12043
- return u ? (u.putImageData(lu(e, t, s, c), 0, 0), a.imageSmoothingEnabled = !0, a.imageSmoothingQuality = "high", a.drawImage(l, 0, 0, s, c, 0, 0, i.width, i.height), i) : i;
12534
+ return u ? (u.putImageData(Hu(e, t, s, c), 0, 0), a.imageSmoothingEnabled = !0, a.imageSmoothingQuality = "high", a.drawImage(l, 0, 0, s, c, 0, 0, i.width, i.height), i) : i;
12044
12535
  }
12045
- function du(e, t, n, r, i, a, o, s = 1, c = 0, l = 0) {
12536
+ function Wu(e, t, n, r, i, a, o, s = 1, c = 0, l = 0) {
12046
12537
  let u = document.createElement("canvas");
12047
- return u.width = Math.max(1, Math.round(r)), u.height = Math.max(1, Math.round(i)), fu(u, e, t, n, a, o, s, c, l), u;
12538
+ return u.width = Math.max(1, Math.round(r)), u.height = Math.max(1, Math.round(i)), Gu(u, e, t, n, a, o, s, c, l), u;
12048
12539
  }
12049
- function fu(e, t, n, r, i, a, o = 1, s = 0, c = 0) {
12540
+ function Gu(e, t, n, r, i, a, o = 1, s = 0, c = 0) {
12050
12541
  let l = e.getContext("2d");
12051
12542
  if (!l) return;
12052
12543
  l.fillStyle = a, l.fillRect(0, 0, e.width, e.height);
12053
12544
  let u = Math.max(.1, o), d = i === "stretch" ? e.width : n * (i === "contain" ? Math.min(e.width / n, e.height / r) : Math.max(e.width / n, e.height / r)), f = i === "stretch" ? e.height : r * (i === "contain" ? Math.min(e.width / n, e.height / r) : Math.max(e.width / n, e.height / r)), p = d * u, m = f * u, h = s / 100 * e.width, g = c / 100 * e.height;
12054
12545
  l.drawImage(t, (e.width - p) / 2 + h, (e.height - m) / 2 + g, p, m);
12055
12546
  }
12056
- function pu(e) {
12547
+ function Ku(e) {
12057
12548
  let t = (t, n) => {
12058
12549
  let r = t * 374761393 + n * 668265263 + e * 1442695041 | 0;
12059
12550
  return r = Math.imul(r ^ r >>> 13, 1274126177), ((r ^ r >>> 16) >>> 0) / 4294967295;
12060
12551
  };
12061
12552
  return (e, n) => {
12062
- let r = Math.floor(e), i = Math.floor(n), a = eu(e - r), o = eu(n - i), s = t(r, i), c = t(r + 1, i), l = t(r, i + 1), u = t(r + 1, i + 1);
12553
+ let r = Math.floor(e), i = Math.floor(n), a = Nu(e - r), o = Nu(n - i), s = t(r, i), c = t(r + 1, i), l = t(r, i + 1), u = t(r + 1, i + 1);
12063
12554
  return s * (1 - a) * (1 - o) + c * a * (1 - o) + l * (1 - a) * o + u * a * o;
12064
12555
  };
12065
12556
  }
12066
- function mu(e, t, n, r) {
12557
+ function qu(e, t, n, r) {
12067
12558
  let i = 0, a = .5, o = 1, s = 0;
12068
12559
  for (let c = 0; c < r; c++) i += a * e(t * o, n * o), s += a, o *= 2, a *= .5;
12069
12560
  return i / s;
12070
12561
  }
12071
- function hu(e = 220) {
12072
- let t = Math.max(64, Math.min(1280, Math.round(e))), n = wu.get(t);
12562
+ function Ju(e = 220) {
12563
+ let t = Math.max(64, Math.min(1280, Math.round(e))), n = rd.get(t);
12073
12564
  if (n) return n;
12074
12565
  let r = document.createElement("canvas");
12075
12566
  r.width = t, r.height = t;
12076
12567
  let i = r.getContext("2d");
12077
12568
  if (!i) return r;
12078
- let a = i.createImageData(t, t), o = pu(11), s = pu(91), c = pu(47), l = [
12569
+ let a = i.createImageData(t, t), o = Ku(11), s = Ku(91), c = Ku(47), l = [
12079
12570
  [0, [
12080
12571
  34,
12081
12572
  26,
@@ -12119,24 +12610,24 @@ function hu(e = 220) {
12119
12610
  return l[l.length - 1][1];
12120
12611
  };
12121
12612
  for (let e = 0; e < t; e++) for (let n = 0; n < t; n++) {
12122
- let r = n / t * 3, i = e / t * 3, l = r + .7 * s(r * .7 + 5, i * .7), d = i + .7 * s(r * .7, i * .7 + 9), [f, p, m] = u(mu(o, l, d, 4)), h = Math.max(0, mu(c, l * 1.6 + 3, d * 1.6, 3) - .55) * 1.7;
12613
+ let r = n / t * 3, i = e / t * 3, l = r + .7 * s(r * .7 + 5, i * .7), d = i + .7 * s(r * .7, i * .7 + 9), [f, p, m] = u(qu(o, l, d, 4)), h = Math.max(0, qu(c, l * 1.6 + 3, d * 1.6, 3) - .55) * 1.7;
12123
12614
  f = f * (1 - h) + 70 * h, p = p * (1 - h) + 210 * h, m = m * (1 - h) + 200 * h;
12124
12615
  let g = (e * t + n) * 4;
12125
12616
  a.data[g] = f, a.data[g + 1] = p, a.data[g + 2] = m, a.data[g + 3] = 255;
12126
12617
  }
12127
- return i.putImageData(a, 0, 0), wu.set(t, r), r;
12618
+ return i.putImageData(a, 0, 0), rd.set(t, r), r;
12128
12619
  }
12129
- function gu(e, t, n, r) {
12130
- let i = `${e}|${t}x${n}`, a = Tu.get(i);
12620
+ function Yu(e, t, n, r) {
12621
+ let i = `${e}|${t}x${n}`, a = id.get(i);
12131
12622
  if (a) return a;
12132
12623
  let o = document.createElement("canvas");
12133
12624
  o.width = t, o.height = n;
12134
12625
  let s = o.getContext("2d");
12135
- return s && r(s, t, n), Tu.set(i, o), o;
12626
+ return s && r(s, t, n), id.set(i, o), o;
12136
12627
  }
12137
- function _u(e = 240) {
12628
+ function Xu(e = 240) {
12138
12629
  let t = Math.max(120, Math.min(2048, Math.round(e)));
12139
- return gu("vaporwave", t, Math.round(t * 2 / 3), (e, t, n) => {
12630
+ return Yu("vaporwave", t, Math.round(t * 2 / 3), (e, t, n) => {
12140
12631
  let r = t / 240, i = e.createLinearGradient(0, 0, 0, n);
12141
12632
  i.addColorStop(0, "#120638"), i.addColorStop(.56, "#8e2de2"), i.addColorStop(1, "#ff2fa8"), e.fillStyle = i, e.fillRect(0, 0, t, n);
12142
12633
  let a = n * .48, o = n * .28, s = e.createLinearGradient(0, a - o, 0, a + o);
@@ -12152,9 +12643,9 @@ function _u(e = 240) {
12152
12643
  e.globalAlpha = 1;
12153
12644
  });
12154
12645
  }
12155
- function vu(e = 220) {
12646
+ function Zu(e = 220) {
12156
12647
  let t = Math.max(110, Math.min(2048, Math.round(e)));
12157
- return gu("kaleidoscope", t, t, (e, t, n) => {
12648
+ return Yu("kaleidoscope", t, t, (e, t, n) => {
12158
12649
  let r = t / 220, i = [
12159
12650
  "#00e5ff",
12160
12651
  "#6c3bff",
@@ -12170,25 +12661,25 @@ function vu(e = 220) {
12170
12661
  for (let t = 1; t <= 4; t++) e.strokeStyle = t % 2 ? "rgba(255,255,255,.55)" : "rgba(8,5,35,.6)", e.lineWidth = 5 * r, e.beginPath(), e.arc(a, o, t * 25 * r, 0, Math.PI * 2), e.stroke();
12171
12662
  });
12172
12663
  }
12173
- function yu(e, t) {
12174
- return e.build ? e.build(t) : nu({
12664
+ function Qu(e, t) {
12665
+ return e.build ? e.build(t) : Fu({
12175
12666
  stops: e.stops ?? [],
12176
12667
  edgeColor: e.edgeColor ?? "#8e9dff",
12177
12668
  edgeAmount: e.edgeAmount ?? 0
12178
12669
  });
12179
12670
  }
12180
- function bu(e) {
12181
- return iu(new Zi().load(e));
12671
+ function $u(e) {
12672
+ return Lu(new Zi().load(e));
12182
12673
  }
12183
- var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12184
- Vc(), hl(), Ll(), xu = 256, Su = 64, Cu = (e) => e.map(([e, t]) => ({
12674
+ var ed, td, nd, rd, id, ad, od = t((() => {
12675
+ Vc(), hl(), Gl(), ed = 256, td = 64, nd = (e) => e.map(([e, t]) => ({
12185
12676
  color: e,
12186
12677
  pos: t
12187
- })), wu = /* @__PURE__ */ new Map(), Tu = /* @__PURE__ */ new Map(), Eu = {
12678
+ })), rd = /* @__PURE__ */ new Map(), id = /* @__PURE__ */ new Map(), ad = {
12188
12679
  palestine: {
12189
12680
  label: "Palestine",
12190
12681
  kind: "gradient",
12191
- stops: Cu([
12682
+ stops: nd([
12192
12683
  ["#000000", 0],
12193
12684
  ["#f7f7f2", .34],
12194
12685
  ["#149954", .67],
@@ -12197,10 +12688,24 @@ var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12197
12688
  edgeColor: "#e4312b",
12198
12689
  edgeAmount: .22
12199
12690
  },
12691
+ spain: {
12692
+ label: "Spain",
12693
+ kind: "gradient",
12694
+ stops: nd([
12695
+ ["#aa151b", 0],
12696
+ ["#aa151b", .24],
12697
+ ["#f1bf00", .34],
12698
+ ["#f1bf00", .66],
12699
+ ["#aa151b", .76],
12700
+ ["#aa151b", 1]
12701
+ ]),
12702
+ edgeColor: "#7a0f14",
12703
+ edgeAmount: .22
12704
+ },
12200
12705
  grandLine: {
12201
12706
  label: "Grand Line",
12202
12707
  kind: "gradient",
12203
- stops: Cu([
12708
+ stops: nd([
12204
12709
  ["#071b33", 0],
12205
12710
  ["#087ea4", .22],
12206
12711
  ["#45d4c5", .4],
@@ -12215,22 +12720,22 @@ var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12215
12720
  vaporwave: {
12216
12721
  label: "Vaporwave Sunset",
12217
12722
  kind: "image",
12218
- build: _u
12723
+ build: Xu
12219
12724
  },
12220
12725
  kaleidoscope: {
12221
12726
  label: "Kaleidoscope",
12222
12727
  kind: "image",
12223
- build: vu
12728
+ build: Zu
12224
12729
  },
12225
12730
  nebula: {
12226
12731
  label: "Nebula (2D)",
12227
12732
  kind: "image",
12228
- build: hu
12733
+ build: Ju
12229
12734
  },
12230
12735
  sunset: {
12231
12736
  label: "Sunset",
12232
12737
  kind: "gradient",
12233
- stops: Cu([
12738
+ stops: nd([
12234
12739
  ["#3b1c6b", 0],
12235
12740
  ["#8b2fa0", .3],
12236
12741
  ["#e0457a", .56],
@@ -12243,7 +12748,7 @@ var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12243
12748
  aurora: {
12244
12749
  label: "Aurora",
12245
12750
  kind: "gradient",
12246
- stops: Cu([
12751
+ stops: nd([
12247
12752
  ["#0b3d4f", 0],
12248
12753
  ["#1fb89e", .3],
12249
12754
  ["#5ee0a0", .52],
@@ -12256,7 +12761,7 @@ var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12256
12761
  ocean: {
12257
12762
  label: "Ocean",
12258
12763
  kind: "gradient",
12259
- stops: Cu([
12764
+ stops: nd([
12260
12765
  ["#0a1f4d", 0],
12261
12766
  ["#1f6fb8", .36],
12262
12767
  ["#2bd0d0", .66],
@@ -12268,7 +12773,7 @@ var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12268
12773
  ember: {
12269
12774
  label: "Ember",
12270
12775
  kind: "gradient",
12271
- stops: Cu([
12776
+ stops: nd([
12272
12777
  ["#2a0707", 0],
12273
12778
  ["#a81e1e", .34],
12274
12779
  ["#ff5a2e", .64],
@@ -12280,7 +12785,7 @@ var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12280
12785
  iris: {
12281
12786
  label: "Iris",
12282
12787
  kind: "gradient",
12283
- stops: Cu([
12788
+ stops: nd([
12284
12789
  ["#2e1065", 0],
12285
12790
  ["#7c3aed", .34],
12286
12791
  ["#db2777", .64],
@@ -12292,7 +12797,7 @@ var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12292
12797
  mono: {
12293
12798
  label: "Mono",
12294
12799
  kind: "gradient",
12295
- stops: Cu([
12800
+ stops: nd([
12296
12801
  ["#16161e", 0],
12297
12802
  ["#6b7280", .4],
12298
12803
  ["#c2c8d2", .72],
@@ -12305,39 +12810,39 @@ var xu, Su, Cu, wu, Tu, Eu, Du = t((() => {
12305
12810
  }));
12306
12811
  //#endregion
12307
12812
  //#region src/util/base64.ts
12308
- function Ou(e) {
12813
+ function sd(e) {
12309
12814
  let t = atob(e.replace(/-/g, "+").replace(/_/g, "/")), n = new Uint8Array(new ArrayBuffer(t.length));
12310
12815
  for (let e = 0; e < t.length; e++) n[e] = t.charCodeAt(e);
12311
12816
  return n;
12312
12817
  }
12313
- var ku = t((() => {}));
12818
+ var cd = t((() => {}));
12314
12819
  //#endregion
12315
12820
  //#region src/renderer/heroPalette.ts
12316
- function Au() {
12821
+ function ld() {
12317
12822
  let e = document.createElement("canvas");
12318
- e.width = Mu, e.height = Mu;
12823
+ e.width = dd, e.height = dd;
12319
12824
  let t = e.getContext("2d");
12320
12825
  if (t) {
12321
- let e = Ou(Nu);
12322
- t.putImageData(new ImageData(new Uint8ClampedArray(e.buffer), Mu, Mu), 0, 0);
12826
+ let e = sd(fd);
12827
+ t.putImageData(new ImageData(new Uint8ClampedArray(e.buffer), dd, dd), 0, 0);
12323
12828
  }
12324
12829
  return e;
12325
12830
  }
12326
- function ju() {
12327
- let e = iu(new ci(Ou(Nu), Mu, Mu, U, Se));
12831
+ function ud() {
12832
+ let e = Lu(new ci(sd(fd), dd, dd, U, Se));
12328
12833
  return e.needsUpdate = !0, e;
12329
12834
  }
12330
- var Mu, Nu, Pu = t((() => {
12331
- Vc(), ku(), Du(), Mu = 32, Nu = "7PP//97s///O4/7/xt77/8vc7f/Y1sr/5c2f/+/EcP/2vEX/+rQp//2xGP/+rRv//J5M//uUf//7jp7/+4a3//2Ax//9g83//4vD//2bu//5kpv/83V+//Nbb//3VnT/81Sf/+tdxf/pid3/56Pr/+a58v/q1/P/6On3/+Xy/P/o8f//2ur+/8/j/P/O4ff/1tzc/+PSr//sx4X/879d//i3Of/8siD//rEP//6vD//9nz7//JJ4//uNnP/6h7f//IDJ//yEz//+jMX//Jq8//aOnf/xa3n/9Fxq//dief/1Y5v/8G62/+2K0v/tq+b/6Lby/+rP8v/q5fb/5vH7/+Pv///X6P7/0uT6/9bi8P/h2sf/682R//LCa//3ukn/+rQs//yxGv/+sQ7//q4T//2eRP/8knv/+o2e//eIuf/6g8v/+obR//yMx//6mb3/84uh//Bnef/1YWn/+nVx//lzj//1g6X/8pjC//Gz3f/stO//6cDx/+rf9P/m8fv/3uz//9Xm/f/V4vj/3d/r/+fWtP/xyHT/9r9R//m3N//7siP//bAW//6xDv/+qxr//ZpP//yPf//4jZ//9Yq6//eHzP/4itL/+o/K//iYvv/wiab/7mZ9//Zpbv/7gG///Il+//iYk//1pa//9LTO//Cx5v/qru7/69fy/+fw+v/Y6f7/1eL7/9nb9v/h2Of/7M+n//XCW//5uj3/+7Ur//yxHf/9rhX//q8Q//6mJP/9k1f/+4x///aNnv/zjbr/9Y3N//aR1f/4lM7/+JnC//COrv/ua4f/9m5y//uGc//8k3z/+qKI//aupP/1tMT/8J3b/+iJ6v/qzfD/6O75/9fl/f/Y3vn/3NPz/+TM4P/uxpr/+LxJ//u3MP/8syX//a8c//2sF//+rBb//p8w//2OX//7ioD/9o6e//KQu//zk8//9ZjX//ec0//4nsn/85i7//B3mf/1cHz/+oZ4//uSgf/6oYX/97Kg//Wpvv/vcdH/5W7n/+vG7f/p6vf/1d78/9nX9//fyu3/6MDN//O8fv/6uDv/+7Qr//yxJf/9rB///akd//6oIP/+mz3//oxm//uMg//2kaD/8pW9//Ob0f/2oNj/+aPX//ul1P/4o83/9Iyy//d7kP/6in3/+5OB//qhgv/5rpX/9pyy/+9czf/kZ+D/7L7q/+vk9f/S0/v/2s30/+O+4//ttK3/+LRW//u0Mf/8si7//K8q//2pJv/9pSj//qMu//6WSP/+jWv/+46F//aVo//zmr//9KHS//em2v/8qNr//qra//2q2P/5n8z/+Iuv//uOjP/7loH//KGA//ukjf/5kab/8VjD/+dq2P/tt+b/7t3y/9XJ+P/gwvD/6bPa//Osmf/6sEn/+7E1//ywNf/8ri///agu//2jNf/+nz3//pRT//6Pb//8k4j/95um//Shwv/1p9T/+Krc//yr2//+rdv//q3c//yp2v/5mM3/+pKp//ubhv/8oIH//J6L//yPmv/2a7D/63fL/++z4//w1u7/48D0/+257f/zr9n/96ic//urU//8rT//+689//yyMv/9ry///qk///6jUP/+nGT//pt6//yfj//4pKz/9ajG//at1v/6r9z//azb//+u3f//r93//q7e//ug3P/6lcn/+52g//ujhP/9nIz//ZKb//qJpP/zjrr/8rHc//PN6v/zuO//+7Ts//uw4f/7qK7//KVo//ynTf/7rEb//bU0//27Jv/9tz3//bJj//6weP/+sIj//a+a//mwsv/2scn/+LTY//uz3f/9rtz//7De//6w3//+reL//aXl//ya4P/8nML//KSZ//2cm//9mrD//aGz//uitf/4r87/9sPk//u07f//tO3//rLo//ymwP/8nYL//J9g//unU//8skL//b0v//zBQP/8xHD//saJ//7FlP/9waP/+725//i5y//5u9j/+rjd//yv3f/+r9///q7i//6r5v/9quj//aTp//2e2v/9oLr//aC1//2ouv/+s7b//rSz//ywwP/6uNn//bPs//6z6//+ruP//J7G//uRmv/7knn/+51m//yrUv/9tkb//MBZ//3Lf//+0pP//tSa//7PqP/8yb7/+sLM//vC1v/6v9z/+bHd//io4v/7pej//arp//2x6P/8ren//KHg//2hxf/9p7v//rC3//+4s///u7D//rS5//2x0f//tO3//7Lr//6n3f/8ksL/+oKl//mDkf/5kXz//KNi//2vWP/+vnH//suQ//7Umv/+2Zz//tan//7SwP/9ysn//srO//vF1P/3sdH/7p7b/+2c6P/2o+3/9Kvs//Gn7f/xn+L//KXF//6uuv//sLj//7S1//+5sf/+tLn//q7Q//+z7f//sen//p/W//uEuv/5daf/9ned//aFjv/6l3f//adp//65ff/+ypr//tGh//7Vn//+1af//ta9///Rv///0r///cvD//m1uP/vn8n/5Jff/96b6//Um/H/zZvy/9Wb6v/ypc7//6+8//+xuf//tLb//7mx//22vf/+rtT//q/q//2n4v/9jsr/+3Wy//drqP/0cKL/9H2Z//iOhv/8oHT//rV///7Hnv/+zqf//tGm//7Uqv/+2Ln//9az///Xsv/90bT//MSj//m6r//tqcn/0aDh/76a8v+9m/b/vZn0/9ue4f/8q8L//rO0//+5rv/+vqn//LrB//6v2v/8qef//JnY//x7vv/6Zq3/9mSn//NtpP/ze53/94qN//yceP/+sn3//sWb//7Oqf/+0an//tas//7cuf//27D//96r//7aqv/+1Jz//tSe//rLrP/htc3/waPr/7if9v+ymvn/zJzt//eoxf/+t6D//8WV//7Kmf/8v8L//a/c//yk5f/7jtL/+224//lcqv/2X6b/9Gyj//R8mv/4jIr//J53//6zfv/+xZr//s2o//7Sqf/+2K7//uC8///htf//46z//t2m//7XnP/+2Z///tmh//XLt//Osdr/s6Lx/7Kd9v/Ro+z/9qvH//64mf//y4j//s+S//zBwf/9sNv//aHk//uI0P/7Zbf/+Feq//Vdpv/0bqD/+IKR//uWfv/+qHf//rqI//7Gnv/+zaf//tSp//7bsP/+477//+W4///mrv//3qT//tic//7Yn//+2qH//NWr/967zP+6pOj/waTt/+Gt4P/4r8j//bWi///Hiv/+zpP//cDB//6v2//9oOT/+4bR//pkuf/3WK3/9F+o//Vynf/6jIX//qR1//61fv/+v5H//seg//7Npv/+1an//t2y//7kwP//5rj//+ex///fpv/+2J3//tie//7ZoP/91qb/5r7E/8am3//Yq97/9LbN//qzxf/8sa///r+R//7MlP/9vcL//q7b//yh5f/6iNP/+Gi8//Vdr//0Zan/93qW//yXev/+rXH//rp///6/kf/+xp///s6l//7WrP/+37j//uXE///kuP//57X//+Os//7Znv/+2J3//tme//3Sof/vu7z/4KvW/+6xz//7tsP/+7PC//uruf/9rJ7//bWd//yzxv/+rtv/+6Ll//iM1P/2b77/9GWw//Vvpf/5hoz//KBy//6ya//+unn//r+Q//7HoP/+z6n//tmz//7iwv/+58j//+K2///mt//+5rT//9ui//7Wnv/+057//smg//u5rv/4ssX/+rTF//u0wP/7sL//+p+7//mRrf/5lK3/+qXL//6u2//4o+X/9JDU//R5vf/1cq7/93ud//qQhf/7pW///bJm//67dP/+wY///smj//7Sr//+3Lz//uXK//7ny///37T//+O0//7isv/+0Jb//8WH///AjP/+upf//rSh//2zsf/7tLz/+7S7//yttf/6lbX/94Oz//WEtv/2n8///a7c//Gn5f/wltH/9IO5//h+pv/7h5X/+5WD//ukcP/9smL//r1t//7Dif/+yaD//tOy//7gw//+6M3//ujM///dsv//3q3//tur//7Agf//r2j//6px//+og//+pY3//qiX//ywov/8r6f//Kei//yVo//6hKv/9Ie3//Og0P/8rtz/563k/+mZzv/zibP/+oag//qLlf/5k4n/+6Jx//2zXf/+vWL//sJ5//7Hkv/+0av//uDC//3pyv/96Mz//tux///apf/+1qb//7h+//+lZf//nGf//5dt//+Tc///lXn//qN+//unjP/5nJ3//JWb//2Knv/2i7L/8KLR//uu3P/druT/4ZXN/+2FtP/1g6X/94Wd//iMj//6nXX//a5f//64Xv/+vW3//sKB//7KmP/+2bP//ebE//3nzf/+2bH//tWf//7Vpf/+toX//5xk//+RW///iFj//4Nc//+FYv/+l2j/+599//eQmv/3iKT/94aj/++HtP/tn9H/+q7d/9aq5f/ajND/5Hq7/+13rv/yeaL/9YCU//mPgf/8oW3//q1m//60a//+uHb//sKJ//7Spv/+48D//ufO//7Xsv/+0Zr//tSk//68kv//mGn//4ZP//9+S///elD//oJa//2Qav/5kIT/9YOX//N7pP/ueK7/5nu7/+iX0//5rd3/0aXp/9KB1v/ba8P/5Wa2/+xoqf/yb5v/936M//uUef/9pWz//qxr//6ucf/+u4X//tGl//7jwv/959H//tez//7PmP/+0KL//sWh//6rh//+i2D//3xQ//59VP/+iF///It1//d9j//ybpv/7Wmn/+Zmtv/dasP/447W//es3v/LpO7/yHnd/89czf/bU8H/5VW1/+5dpv/1cJT/+419//6ibf/+pWj//qZt//63hf/+0ar//eTJ//3o1f/+1rX//c2X//3Lof/+x6b//cCh//6dev/+hlz//ohd//6TZP/8iXn/9m2V/+5apv/mVbb/20/B/89YzP/ahdv/9are/8eo8v+/eeX/xFXW/9FIzP/fSML/6VC0//Nlnv/7ioH//qFt//6jaP/+q3H//rqL//3Ssf/95s///efa//7WuP/8y5j//Mik//7FqP/9xan//a6J//6caf/+kmL//ptn//yKe//0X5//6ky2/99Ew//RQcv/wk/V/9CB4f/yq+D/x7L3/76I7f/AZOH/zFXX/9pS0P/mVsb/8Guw//mRkP/8p3z//K15//y4hP/8w5v/+9W7//vm1v/75t///NbC//nMpP/6yq7//Mmy//vIs//7vZv//LWC//yldf/8o3X/+paM//FgtP/kT8n/20zR/8pN1v+9W+D/y4jn//Cs4f/Pw/v/xqL0/8aF6//PeeT/23Xf/+V32P/uhsf/9qWs//i3mv/4v5j/+Meh//jPsv/43Mn/9+jf//fm5v/31tb/9dXB//XWyP/31sr/99XI//fOt//3yqj/98Of//e9nv/2r6//7oXO/+R63f/beeH/z3vl/8aF7P/Soe3/8bHj/w==";
12835
+ var dd, fd, pd = t((() => {
12836
+ Vc(), cd(), od(), dd = 32, fd = "7PP//97s///O4/7/xt77/8vc7f/Y1sr/5c2f/+/EcP/2vEX/+rQp//2xGP/+rRv//J5M//uUf//7jp7/+4a3//2Ax//9g83//4vD//2bu//5kpv/83V+//Nbb//3VnT/81Sf/+tdxf/pid3/56Pr/+a58v/q1/P/6On3/+Xy/P/o8f//2ur+/8/j/P/O4ff/1tzc/+PSr//sx4X/879d//i3Of/8siD//rEP//6vD//9nz7//JJ4//uNnP/6h7f//IDJ//yEz//+jMX//Jq8//aOnf/xa3n/9Fxq//dief/1Y5v/8G62/+2K0v/tq+b/6Lby/+rP8v/q5fb/5vH7/+Pv///X6P7/0uT6/9bi8P/h2sf/682R//LCa//3ukn/+rQs//yxGv/+sQ7//q4T//2eRP/8knv/+o2e//eIuf/6g8v/+obR//yMx//6mb3/84uh//Bnef/1YWn/+nVx//lzj//1g6X/8pjC//Gz3f/stO//6cDx/+rf9P/m8fv/3uz//9Xm/f/V4vj/3d/r/+fWtP/xyHT/9r9R//m3N//7siP//bAW//6xDv/+qxr//ZpP//yPf//4jZ//9Yq6//eHzP/4itL/+o/K//iYvv/wiab/7mZ9//Zpbv/7gG///Il+//iYk//1pa//9LTO//Cx5v/qru7/69fy/+fw+v/Y6f7/1eL7/9nb9v/h2Of/7M+n//XCW//5uj3/+7Ur//yxHf/9rhX//q8Q//6mJP/9k1f/+4x///aNnv/zjbr/9Y3N//aR1f/4lM7/+JnC//COrv/ua4f/9m5y//uGc//8k3z/+qKI//aupP/1tMT/8J3b/+iJ6v/qzfD/6O75/9fl/f/Y3vn/3NPz/+TM4P/uxpr/+LxJ//u3MP/8syX//a8c//2sF//+rBb//p8w//2OX//7ioD/9o6e//KQu//zk8//9ZjX//ec0//4nsn/85i7//B3mf/1cHz/+oZ4//uSgf/6oYX/97Kg//Wpvv/vcdH/5W7n/+vG7f/p6vf/1d78/9nX9//fyu3/6MDN//O8fv/6uDv/+7Qr//yxJf/9rB///akd//6oIP/+mz3//oxm//uMg//2kaD/8pW9//Ob0f/2oNj/+aPX//ul1P/4o83/9Iyy//d7kP/6in3/+5OB//qhgv/5rpX/9pyy/+9czf/kZ+D/7L7q/+vk9f/S0/v/2s30/+O+4//ttK3/+LRW//u0Mf/8si7//K8q//2pJv/9pSj//qMu//6WSP/+jWv/+46F//aVo//zmr//9KHS//em2v/8qNr//qra//2q2P/5n8z/+Iuv//uOjP/7loH//KGA//ukjf/5kab/8VjD/+dq2P/tt+b/7t3y/9XJ+P/gwvD/6bPa//Osmf/6sEn/+7E1//ywNf/8ri///agu//2jNf/+nz3//pRT//6Pb//8k4j/95um//Shwv/1p9T/+Krc//yr2//+rdv//q3c//yp2v/5mM3/+pKp//ubhv/8oIH//J6L//yPmv/2a7D/63fL/++z4//w1u7/48D0/+257f/zr9n/96ic//urU//8rT//+689//yyMv/9ry///qk///6jUP/+nGT//pt6//yfj//4pKz/9ajG//at1v/6r9z//azb//+u3f//r93//q7e//ug3P/6lcn/+52g//ujhP/9nIz//ZKb//qJpP/zjrr/8rHc//PN6v/zuO//+7Ts//uw4f/7qK7//KVo//ynTf/7rEb//bU0//27Jv/9tz3//bJj//6weP/+sIj//a+a//mwsv/2scn/+LTY//uz3f/9rtz//7De//6w3//+reL//aXl//ya4P/8nML//KSZ//2cm//9mrD//aGz//uitf/4r87/9sPk//u07f//tO3//rLo//ymwP/8nYL//J9g//unU//8skL//b0v//zBQP/8xHD//saJ//7FlP/9waP/+725//i5y//5u9j/+rjd//yv3f/+r9///q7i//6r5v/9quj//aTp//2e2v/9oLr//aC1//2ouv/+s7b//rSz//ywwP/6uNn//bPs//6z6//+ruP//J7G//uRmv/7knn/+51m//yrUv/9tkb//MBZ//3Lf//+0pP//tSa//7PqP/8yb7/+sLM//vC1v/6v9z/+bHd//io4v/7pej//arp//2x6P/8ren//KHg//2hxf/9p7v//rC3//+4s///u7D//rS5//2x0f//tO3//7Lr//6n3f/8ksL/+oKl//mDkf/5kXz//KNi//2vWP/+vnH//suQ//7Umv/+2Zz//tan//7SwP/9ysn//srO//vF1P/3sdH/7p7b/+2c6P/2o+3/9Kvs//Gn7f/xn+L//KXF//6uuv//sLj//7S1//+5sf/+tLn//q7Q//+z7f//sen//p/W//uEuv/5daf/9ned//aFjv/6l3f//adp//65ff/+ypr//tGh//7Vn//+1af//ta9///Rv///0r///cvD//m1uP/vn8n/5Jff/96b6//Um/H/zZvy/9Wb6v/ypc7//6+8//+xuf//tLb//7mx//22vf/+rtT//q/q//2n4v/9jsr/+3Wy//drqP/0cKL/9H2Z//iOhv/8oHT//rV///7Hnv/+zqf//tGm//7Uqv/+2Ln//9az///Xsv/90bT//MSj//m6r//tqcn/0aDh/76a8v+9m/b/vZn0/9ue4f/8q8L//rO0//+5rv/+vqn//LrB//6v2v/8qef//JnY//x7vv/6Zq3/9mSn//NtpP/ze53/94qN//yceP/+sn3//sWb//7Oqf/+0an//tas//7cuf//27D//96r//7aqv/+1Jz//tSe//rLrP/htc3/waPr/7if9v+ymvn/zJzt//eoxf/+t6D//8WV//7Kmf/8v8L//a/c//yk5f/7jtL/+224//lcqv/2X6b/9Gyj//R8mv/4jIr//J53//6zfv/+xZr//s2o//7Sqf/+2K7//uC8///htf//46z//t2m//7XnP/+2Z///tmh//XLt//Osdr/s6Lx/7Kd9v/Ro+z/9qvH//64mf//y4j//s+S//zBwf/9sNv//aHk//uI0P/7Zbf/+Feq//Vdpv/0bqD/+IKR//uWfv/+qHf//rqI//7Gnv/+zaf//tSp//7bsP/+477//+W4///mrv//3qT//tic//7Yn//+2qH//NWr/967zP+6pOj/waTt/+Gt4P/4r8j//bWi///Hiv/+zpP//cDB//6v2//9oOT/+4bR//pkuf/3WK3/9F+o//Vynf/6jIX//qR1//61fv/+v5H//seg//7Npv/+1an//t2y//7kwP//5rj//+ex///fpv/+2J3//tie//7ZoP/91qb/5r7E/8am3//Yq97/9LbN//qzxf/8sa///r+R//7MlP/9vcL//q7b//yh5f/6iNP/+Gi8//Vdr//0Zan/93qW//yXev/+rXH//rp///6/kf/+xp///s6l//7WrP/+37j//uXE///kuP//57X//+Os//7Znv/+2J3//tme//3Sof/vu7z/4KvW/+6xz//7tsP/+7PC//uruf/9rJ7//bWd//yzxv/+rtv/+6Ll//iM1P/2b77/9GWw//Vvpf/5hoz//KBy//6ya//+unn//r+Q//7HoP/+z6n//tmz//7iwv/+58j//+K2///mt//+5rT//9ui//7Wnv/+057//smg//u5rv/4ssX/+rTF//u0wP/7sL//+p+7//mRrf/5lK3/+qXL//6u2//4o+X/9JDU//R5vf/1cq7/93ud//qQhf/7pW///bJm//67dP/+wY///smj//7Sr//+3Lz//uXK//7ny///37T//+O0//7isv/+0Jb//8WH///AjP/+upf//rSh//2zsf/7tLz/+7S7//yttf/6lbX/94Oz//WEtv/2n8///a7c//Gn5f/wltH/9IO5//h+pv/7h5X/+5WD//ukcP/9smL//r1t//7Dif/+yaD//tOy//7gw//+6M3//ujM///dsv//3q3//tur//7Agf//r2j//6px//+og//+pY3//qiX//ywov/8r6f//Kei//yVo//6hKv/9Ie3//Og0P/8rtz/563k/+mZzv/zibP/+oag//qLlf/5k4n/+6Jx//2zXf/+vWL//sJ5//7Hkv/+0av//uDC//3pyv/96Mz//tux///apf/+1qb//7h+//+lZf//nGf//5dt//+Tc///lXn//qN+//unjP/5nJ3//JWb//2Knv/2i7L/8KLR//uu3P/druT/4ZXN/+2FtP/1g6X/94Wd//iMj//6nXX//a5f//64Xv/+vW3//sKB//7KmP/+2bP//ebE//3nzf/+2bH//tWf//7Vpf/+toX//5xk//+RW///iFj//4Nc//+FYv/+l2j/+599//eQmv/3iKT/94aj/++HtP/tn9H/+q7d/9aq5f/ajND/5Hq7/+13rv/yeaL/9YCU//mPgf/8oW3//q1m//60a//+uHb//sKJ//7Spv/+48D//ufO//7Xsv/+0Zr//tSk//68kv//mGn//4ZP//9+S///elD//oJa//2Qav/5kIT/9YOX//N7pP/ueK7/5nu7/+iX0//5rd3/0aXp/9KB1v/ba8P/5Wa2/+xoqf/yb5v/936M//uUef/9pWz//qxr//6ucf/+u4X//tGl//7jwv/959H//tez//7PmP/+0KL//sWh//6rh//+i2D//3xQ//59VP/+iF///It1//d9j//ybpv/7Wmn/+Zmtv/dasP/447W//es3v/LpO7/yHnd/89czf/bU8H/5VW1/+5dpv/1cJT/+419//6ibf/+pWj//qZt//63hf/+0ar//eTJ//3o1f/+1rX//c2X//3Lof/+x6b//cCh//6dev/+hlz//ohd//6TZP/8iXn/9m2V/+5apv/mVbb/20/B/89YzP/ahdv/9are/8eo8v+/eeX/xFXW/9FIzP/fSML/6VC0//Nlnv/7ioH//qFt//6jaP/+q3H//rqL//3Ssf/95s///efa//7WuP/8y5j//Mik//7FqP/9xan//a6J//6caf/+kmL//ptn//yKe//0X5//6ky2/99Ew//RQcv/wk/V/9CB4f/yq+D/x7L3/76I7f/AZOH/zFXX/9pS0P/mVsb/8Guw//mRkP/8p3z//K15//y4hP/8w5v/+9W7//vm1v/75t///NbC//nMpP/6yq7//Mmy//vIs//7vZv//LWC//yldf/8o3X/+paM//FgtP/kT8n/20zR/8pN1v+9W+D/y4jn//Cs4f/Pw/v/xqL0/8aF6//PeeT/23Xf/+V32P/uhsf/9qWs//i3mv/4v5j/+Meh//jPsv/43Mn/9+jf//fm5v/31tb/9dXB//XWyP/31sr/99XI//fOt//3yqj/98Of//e9nv/2r6//7oXO/+R63f/beeH/z3vl/8aF7P/Soe3/8bHj/w==";
12332
12837
  }));
12333
12838
  //#endregion
12334
12839
  //#region src/renderer/WaveRenderer.ts
12335
- function Fu(e, t) {
12336
- let n = zu.set(e);
12840
+ function md(e, t) {
12841
+ let n = vd.set(e);
12337
12842
  return t.set(n.r, n.g, n.b);
12338
12843
  }
12339
- var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12340
- Vc(), nl(), il(), cl(), Zc(), fl(), Kl(), $l(), Du(), Pu(), Ll(), Iu = 220, Lu = 1333, Ru = class {
12844
+ var hd, gd, _d, vd, yd, bd = t((() => {
12845
+ Vc(), nl(), il(), cl(), Zc(), fl(), eu(), su(), Mu(), od(), pd(), Gl(), hd = 220, gd = 1333, _d = class {
12341
12846
  makeVideo;
12342
12847
  onVideoReady;
12343
12848
  texture;
@@ -12350,8 +12855,8 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12350
12855
  }
12351
12856
  apply(e, t) {
12352
12857
  let n = e.paletteVideoUrl, r = e.paletteImageUrl, i = e.paletteSource ?? "hero", a, o;
12353
- if (n) this.ensureVideo(n), this.video?.readyState && this.video.readyState >= 2 ? (a = "video|" + n, o = () => iu(new _i(this.video))) : (a = "video-loading|" + n, o = () => ju());
12354
- else if (r) this.clearVideo(), a = "url|" + r, o = () => bu(r);
12858
+ if (n) this.ensureVideo(n), this.video?.readyState && this.video.readyState >= 2 ? (a = "video|" + n, o = () => Lu(new _i(this.video))) : (a = "video-loading|" + n, o = () => ud());
12859
+ else if (r) this.clearVideo(), a = "url|" + r, o = () => $u(r);
12355
12860
  else if (i === "stops") {
12356
12861
  this.clearVideo();
12357
12862
  let t = {
@@ -12359,8 +12864,8 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12359
12864
  edgeColor: e.paletteEdgeColor ?? "#8e9dff",
12360
12865
  edgeAmount: e.paletteEdgeAmount ?? .3
12361
12866
  };
12362
- a = "stops|" + ru(t), o = () => ou(t);
12363
- } else Eu[i] ? (this.clearVideo(), a = "map|" + i, o = () => au(yu(Eu[i]))) : (this.clearVideo(), a = "hero", o = () => ju());
12867
+ a = "stops|" + Iu(t), o = () => zu(t);
12868
+ } else ad[i] ? (this.clearVideo(), a = "map|" + i, o = () => Ru(Qu(ad[i]))) : (this.clearVideo(), a = "hero", o = () => ud());
12364
12869
  (a !== this.sig || !this.texture) && (this.texture?.dispose(), this.texture = o(), this.sig = a), t.uPalette.value = this.texture, t.uUsePalette.value = e.usePaletteTexture === !1 ? 0 : 1, t.uPaletteRaw.value = 1;
12365
12870
  }
12366
12871
  syncPlayback(e, t) {
@@ -12383,7 +12888,7 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12383
12888
  dispose() {
12384
12889
  this.texture?.dispose(), this.texture = void 0, this.clearVideo(), this.failedUrl = "";
12385
12890
  }
12386
- }, zu = new X(), Bu = class {
12891
+ }, vd = new X(), yd = class {
12387
12892
  renderer;
12388
12893
  scene = new Gn();
12389
12894
  camera;
@@ -12411,6 +12916,13 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12411
12916
  clipSphere = new Ar();
12412
12917
  clipTmpA = new K();
12413
12918
  clipTmpB = new K();
12919
+ interaction;
12920
+ interactionZoom = 1;
12921
+ interactionTimeOffset = 0;
12922
+ interactionSceneOut = {
12923
+ timeOffset: 0,
12924
+ zoom: 1
12925
+ };
12414
12926
  timer = new da();
12415
12927
  time = 0;
12416
12928
  rafId = 0;
@@ -12426,7 +12938,7 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12426
12938
  capturing = !1;
12427
12939
  outputSize;
12428
12940
  constructor(e, t, n = {}) {
12429
- this.container = e, this.config = Al(t), this.respectReducedMotion = n.respectReducedMotion ?? !0, this.skipIntroRamp = n.skipIntroRamp ?? !1, this.renderer = new Bc({
12941
+ this.container = e, this.config = Fl(t), this.respectReducedMotion = n.respectReducedMotion ?? !0, this.skipIntroRamp = n.skipIntroRamp ?? !1, this.renderer = new Bc({
12430
12942
  antialias: !0,
12431
12943
  alpha: !0,
12432
12944
  preserveDrawingBuffer: !0,
@@ -12440,15 +12952,15 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12440
12952
  uGrainAmount: { value: t.grain },
12441
12953
  uTime: { value: 0 }
12442
12954
  },
12443
- vertexShader: Wl,
12444
- fragmentShader: Gl
12955
+ vertexShader: Ql,
12956
+ fragmentShader: $l
12445
12957
  }), this.composer.addPass(this.postPass), this.composer.addPass(new sl()), this.motionQuery = window.matchMedia("(prefers-reduced-motion: reduce)"), this.reducedMotion = this.respectReducedMotion && this.motionQuery.matches, this.motionQuery.addEventListener("change", this.onMotionChange), document.addEventListener("visibilitychange", this.onVisibilityChange), this.intersectionObserver = new IntersectionObserver((e) => {
12446
12958
  this.visible = e[0]?.isIntersecting ?? !0, this.updateRunning();
12447
12959
  }, { rootMargin: "100px" }), this.intersectionObserver.observe(e), this.resizeObserver = new ResizeObserver(this.onResize), this.resizeObserver.observe(e), this.applyBackground(), this.buildWaves(), this.resize();
12448
12960
  }
12449
12961
  get segments() {
12450
12962
  let e = this.config.quality / Math.sqrt(Math.max(1, this.config.waves.length));
12451
- return Gt.clamp(Math.round(Iu * e), 24, 360);
12963
+ return Gt.clamp(Math.round(hd * e), 24, 360);
12452
12964
  }
12453
12965
  makeUniforms() {
12454
12966
  let e = [], t = [];
@@ -12459,6 +12971,8 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12459
12971
  for (let e = 0; e < 8; e++) a.push(new K()), o.push(new K(1, 1, 1)), s.push(0);
12460
12972
  let c = [], l = [], u = [];
12461
12973
  for (let e = 0; e < 4; e++) c.push(new Y()), l.push(new Y()), u.push(0);
12974
+ let d = [], f = [], p = [];
12975
+ for (let e = 0; e < 4; e++) d.push(new G()), f.push(0), p.push(0);
12462
12976
  return {
12463
12977
  uTime: { value: 0 },
12464
12978
  uSpeed: { value: .05 },
@@ -12525,19 +13039,36 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12525
13039
  uLineThickness: { value: 1 },
12526
13040
  uLineDerivativePower: { value: .95 },
12527
13041
  uMaxWidth: { value: 1232 },
12528
- uClearColor: { value: new K(1, 1, 1) }
13042
+ uClearColor: { value: new K(1, 1, 1) },
13043
+ uPointer: { value: new G(0, 0) },
13044
+ uPointerActive: { value: 0 },
13045
+ uPointerRadius: { value: .6 },
13046
+ uPointerAspect: { value: 1 },
13047
+ uPointerAgitate: { value: 0 },
13048
+ uPointerPush: { value: 0 },
13049
+ uPointerWake: { value: 0 },
13050
+ uPointerVel: { value: new G(0, 0) },
13051
+ uPointerThin: { value: 0 },
13052
+ uPointerHue: { value: 0 },
13053
+ uPointerLighten: { value: 0 },
13054
+ uPointerRipple: { value: 0 },
13055
+ uRippleOrigin: { value: d },
13056
+ uRippleAge: { value: f },
13057
+ uRippleAmp: { value: p }
12529
13058
  };
12530
13059
  }
12531
13060
  waveDefines(e) {
12532
13061
  let t = {};
12533
- return e?.twistMotion && (t.TWIST_MOTION = ""), (this.config.loopSeconds ?? 0) > 0 && (t.LOOP_MOTION = ""), (e?.detailAmount ?? 0) !== 0 && (t.DETAIL_OCTAVE = ""), (e?.depthTint ?? 0) > 0 && (t.DEPTH_TINT = ""), (e?.edgeFeather ?? .1) !== .1 && (t.EDGE_FEATHER = ""), t;
13062
+ e?.twistMotion && (t.TWIST_MOTION = ""), (this.config.loopSeconds ?? 0) > 0 && (t.LOOP_MOTION = "");
13063
+ let n = e?.interaction?.bindings?.some((e) => e.target === "detailAmount") ?? !1;
13064
+ return ((e?.detailAmount ?? 0) !== 0 || n) && (t.DETAIL_OCTAVE = ""), (e?.depthTint ?? 0) > 0 && (t.DEPTH_TINT = ""), (e?.edgeFeather ?? .1) !== .1 && (t.EDGE_FEATHER = ""), e && fu(this.config, e) && (t.POINTER_FX = "", pu(this.config, e) && (t.POINTER_RIPPLES = "")), t;
12534
13065
  }
12535
13066
  addWave() {
12536
- let e = new Ql(this.segments), t = this.config.waves[this.waves.length] ?? this.config.waves[0], n = new Oi({
13067
+ let e = new ou(this.segments), t = this.config.waves[this.waves.length] ?? this.config.waves[0], n = new Oi({
12537
13068
  uniforms: this.makeUniforms(),
12538
13069
  defines: this.waveDefines(t),
12539
- vertexShader: Vl,
12540
- fragmentShader: t?.theme === "wireframe" ? Ul : Hl,
13070
+ vertexShader: Yl,
13071
+ fragmentShader: t?.theme === "wireframe" ? Zl : Xl,
12541
13072
  transparent: !0,
12542
13073
  depthTest: !0,
12543
13074
  depthWrite: !0,
@@ -12546,7 +13077,7 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12546
13077
  this.applyBlendMode(n, t?.blendMode ?? "squared");
12547
13078
  let r = new si(e.geometry, n);
12548
13079
  r.frustumCulled = !1, this.group.add(r);
12549
- let i = new Ru((e) => this.createLoopingVideo(e), () => {
13080
+ let i = new _d((e) => this.createLoopingVideo(e), () => {
12550
13081
  this.updatePaletteTextures(), this.syncVideoPlayback(), this.running || this.renderOnce();
12551
13082
  });
12552
13083
  this.waves.push({
@@ -12578,7 +13109,7 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12578
13109
  }), this.refresh();
12579
13110
  }
12580
13111
  refresh() {
12581
- if (this.applyBackground(), this.applyPost(), !this.isCameraExternallyDriven()) {
13112
+ if (this.applyBackground(), this.applyPost(), this.syncInteraction(), !this.isCameraExternallyDriven()) {
12582
13113
  let e = this.config.cameraPosition, t = this.config.cameraTarget;
12583
13114
  this.camera.position.set(e.x, e.y, e.z), this.camera.lookAt(t.x, t.y, t.z);
12584
13115
  }
@@ -12587,7 +13118,7 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12587
13118
  this.applyBlendMode(e.material, n.blendMode) && (e.material.needsUpdate = !0);
12588
13119
  let i = this.waveDefines(n), a = e.material.defines ?? {};
12589
13120
  Object.keys(i).sort().join(",") !== Object.keys(a).sort().join(",") && (e.material.defines = i, e.material.needsUpdate = !0);
12590
- let o = n.theme === "wireframe" ? Ul : Hl;
13121
+ let o = n.theme === "wireframe" ? Zl : Xl;
12591
13122
  e.material.fragmentShader !== o && (e.material.fragmentShader = o, e.material.needsUpdate = !0);
12592
13123
  let s = [...n.palette].sort((e, t) => e.pos - t.pos), c = Math.max(1, Math.min(s.length, 8)), l = r.uColors.value, u = r.uColorPos.value;
12593
13124
  for (let e = 0; e < 8; e++) {
@@ -12595,21 +13126,21 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12595
13126
  color: "#ffffff",
12596
13127
  pos: 0
12597
13128
  };
12598
- Fu(t.color, l[e]), u[e] = t.pos;
13129
+ md(t.color, l[e]), u[e] = t.pos;
12599
13130
  }
12600
13131
  r.uColorCount.value = c, r.uGradType.value = n.gradientType === "radial" ? 1 : n.gradientType === "conic" ? 2 : n.gradientType === "mesh" ? 3 : 0, r.uGradAngle.value = (n.gradientAngle ?? 0) * Math.PI / 180, r.uGradShift.value = n.gradientShift ?? 0;
12601
13132
  let d = n.meshGradientPoints.slice(0, 8), f = r.uMeshPointPos.value, p = r.uMeshPointColor.value, m = r.uMeshPointInfluence.value;
12602
13133
  for (let e = 0; e < 8; e++) {
12603
13134
  let t = d[e] ?? d[d.length - 1];
12604
- t && (f[e].set(t.x, t.y), Fu(t.color, p[e]), m[e] = t.influence);
13135
+ t && (f[e].set(t.x, t.y), md(t.color, p[e]), m[e] = t.influence);
12605
13136
  }
12606
- r.uMeshPointCount.value = d.length, r.uMeshSoftness.value = n.meshGradientSoftness, r.uPaletteScale.value.set(n.paletteTextureScale?.x ?? 1, n.paletteTextureScale?.y ?? 1), r.uPaletteOffset.value.set(n.paletteTextureOffset?.x ?? 0, n.paletteTextureOffset?.y ?? 0), r.uPaletteRotation.value = (n.paletteTextureRotation ?? 0) * Math.PI / 180, r.uHueShift.value = n.hueShift, r.uContrast.value = n.colorContrast, r.uSaturation.value = n.colorSaturation, r.uLineAmount.value = n.lineAmount ?? 425, r.uLineThickness.value = n.lineThickness ?? 1, r.uLineDerivativePower.value = n.lineDerivativePower ?? .95, r.uMaxWidth.value = n.maxWidth ?? 1232, Fu(this.config.background, r.uClearColor.value), r.uFiberCount.value = n.fiberCount, r.uFiberStrength.value = n.fiberStrength, r.uTexture.value = n.texture, r.uCreaseLight.value = n.creaseLight, r.uCreaseSharpness.value = n.creaseSharpness, r.uCreaseSoftness.value = n.creaseSoftness, r.uSheen.value = n.sheen ?? 1, r.uRoundness.value = n.roundness ?? .35, r.uIridescence.value = n.iridescence ?? 0, r.uDepthTint.value = n.depthTint ?? 0, Fu(n.depthTintColor ?? "#0a2540", r.uDepthTintColor.value), r.uEdgeFade.value = n.edgeFade, r.uEdgeFeather.value = n.edgeFeather ?? .1;
13137
+ r.uMeshPointCount.value = d.length, r.uMeshSoftness.value = n.meshGradientSoftness, r.uPaletteScale.value.set(n.paletteTextureScale?.x ?? 1, n.paletteTextureScale?.y ?? 1), r.uPaletteOffset.value.set(n.paletteTextureOffset?.x ?? 0, n.paletteTextureOffset?.y ?? 0), r.uPaletteRotation.value = (n.paletteTextureRotation ?? 0) * Math.PI / 180, r.uHueShift.value = n.hueShift, r.uContrast.value = n.colorContrast, r.uSaturation.value = n.colorSaturation, r.uLineAmount.value = n.lineAmount ?? 425, r.uLineThickness.value = n.lineThickness ?? 1, r.uLineDerivativePower.value = n.lineDerivativePower ?? .95, r.uMaxWidth.value = n.maxWidth ?? 1232, md(this.config.background, r.uClearColor.value), r.uFiberCount.value = n.fiberCount, r.uFiberStrength.value = n.fiberStrength, r.uTexture.value = n.texture, r.uCreaseLight.value = n.creaseLight, r.uCreaseSharpness.value = n.creaseSharpness, r.uCreaseSoftness.value = n.creaseSoftness, r.uSheen.value = n.sheen ?? 1, r.uRoundness.value = n.roundness ?? .35, r.uIridescence.value = n.iridescence ?? 0, r.uDepthTint.value = n.depthTint ?? 0, md(n.depthTintColor ?? "#0a2540", r.uDepthTintColor.value), r.uEdgeFade.value = n.edgeFade, r.uEdgeFeather.value = n.edgeFeather ?? .1;
12607
13138
  let h = this.config.lights ?? [];
12608
13139
  r.uAmbient.value = this.config.ambient ?? .45, r.uNumLights.value = Math.min(h.length, 8);
12609
13140
  let g = r.uLightPos.value, _ = r.uLightColor.value, v = r.uLightIntensity.value;
12610
13141
  for (let e = 0; e < 8; e++) {
12611
13142
  let t = h[e];
12612
- t ? (g[e].set(t.position.x, t.position.y, t.position.z), Fu(t.color, _[e]), v[e] = t.intensity) : v[e] = 0;
13143
+ t ? (g[e].set(t.position.x, t.position.y, t.position.z), md(t.color, _[e]), v[e] = t.intensity) : v[e] = 0;
12613
13144
  }
12614
13145
  let y = n.noiseBands ?? [];
12615
13146
  r.uNumNoiseBands.value = Math.min(y.length, 4);
@@ -12619,6 +13150,13 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12619
13150
  t && (b[e].set(t.startX, t.endX, t.startY, t.endY), x[e].set(t.feather, t.strength, t.frequency, t.colorAttenuation), S[e] = t.parabolaPower);
12620
13151
  }
12621
13152
  r.uSpeed.value = n.speed, r.uSeed.value = n.seed, r.uLoopSeconds.value = this.config.loopSeconds ?? 0, r.uDispFreqX.value = n.displaceFrequency.x, r.uDispFreqZ.value = n.displaceFrequency.y, r.uDispAmount.value = n.displaceAmount, r.uDetailFreq.value = n.detailFrequency ?? .04, r.uDetailAmount.value = n.detailAmount ?? 0, r.uTwFreqX.value = n.twistFrequency.x, r.uTwFreqY.value = n.twistFrequency.y, r.uTwFreqZ.value = n.twistFrequency.z, r.uTwPowX.value = n.twistPower.x, r.uTwPowY.value = n.twistPower.y, r.uTwPowZ.value = n.twistPower.z, e.mesh.scale.set(n.scale.x, n.scale.y, n.scale.z), e.mesh.rotation.set(Gt.degToRad(n.rotation.x), Gt.degToRad(n.rotation.y), Gt.degToRad(n.rotation.z)), e.mesh.position.set(n.position.x, n.position.y, n.position.z), r.uOpacity.value = n.opacity;
13153
+ });
13154
+ let e = (this.config.interaction?.radius ?? .3) * 2;
13155
+ this.waves.forEach((t, n) => {
13156
+ let r = this.config.waves[n] ?? this.config.waves[this.config.waves.length - 1];
13157
+ if (!fu(this.config, r)) return;
13158
+ let i = t.material.uniforms, a = r.interaction?.hover;
13159
+ i.uPointerRadius.value = e, i.uPointerAgitate.value = a?.agitate ?? 0, i.uPointerPush.value = a?.push ?? 0, i.uPointerWake.value = a?.wake ?? 0, i.uPointerThin.value = a?.thin ?? 0, i.uPointerHue.value = a?.hueShift ?? 0, i.uPointerLighten.value = a?.lighten ?? 0, i.uPointerRipple.value = r.interaction?.press?.ripple ?? 0;
12622
13160
  }), this.updatePaletteTextures(), this.syncVideoPlayback(), this.group.scale.set(this.config.mirrorH ? -1 : 1, this.config.mirrorV ? -1 : 1, 1), this.onAfterRefresh(), this.running || this.renderOnce();
12623
13161
  }
12624
13162
  updatePaletteTextures() {
@@ -12662,13 +13200,13 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12662
13200
  t
12663
13201
  ].join("|");
12664
13202
  if (a !== this.backgroundSig || !this.backgroundTexture) {
12665
- let i = uu(n, r, e, t);
12666
- this.backgroundTexture?.dispose(), this.backgroundTexture = au(i), this.backgroundSig = a;
13203
+ let i = Uu(n, r, e, t);
13204
+ this.backgroundTexture?.dispose(), this.backgroundTexture = Ru(i), this.backgroundSig = a;
12667
13205
  }
12668
13206
  this.scene.background = this.backgroundTexture;
12669
13207
  return;
12670
13208
  }
12671
- let r = this.config.backgroundGradientSource ?? "stops", i = Eu[r], a = r !== "stops" && i?.kind === "gradient" && i.stops ? i.stops : this.config.backgroundPalette, o = a.map((e) => `${e.color}@${e.pos.toFixed(3)}`).join(","), s = [
13209
+ let r = this.config.backgroundGradientSource ?? "stops", i = ad[r], a = r !== "stops" && i?.kind === "gradient" && i.stops ? i.stops : this.config.backgroundPalette, o = a.map((e) => `${e.color}@${e.pos.toFixed(3)}`).join(","), s = [
12672
13210
  "gradient",
12673
13211
  r,
12674
13212
  n,
@@ -12678,14 +13216,14 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12678
13216
  t
12679
13217
  ].join("|");
12680
13218
  if (s !== this.backgroundSig || !this.backgroundTexture) {
12681
- let r = su({
13219
+ let r = Bu({
12682
13220
  stops: a,
12683
13221
  type: n,
12684
13222
  angle: this.config.backgroundGradientAngle,
12685
13223
  width: e,
12686
13224
  height: t
12687
13225
  });
12688
- this.backgroundTexture?.dispose(), this.backgroundTexture = au(r), this.backgroundSig = s;
13226
+ this.backgroundTexture?.dispose(), this.backgroundTexture = Ru(r), this.backgroundSig = s;
12689
13227
  }
12690
13228
  this.scene.background = this.backgroundTexture;
12691
13229
  }
@@ -12708,7 +13246,7 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12708
13246
  c = this.backgroundImage, l = this.backgroundImage.naturalWidth, u = this.backgroundImage.naturalHeight, d = `custom|${s}`;
12709
13247
  } else {
12710
13248
  this.clearBackgroundVideo();
12711
- let r = this.config.backgroundImageSource ?? "vaporwave", i = r === "hero" ? Au() : Eu[r]?.kind === "image" ? yu(Eu[r], Math.max(t, n)) : null;
13249
+ let r = this.config.backgroundImageSource ?? "vaporwave", i = r === "hero" ? ld() : ad[r]?.kind === "image" ? Qu(ad[r], Math.max(t, n)) : null;
12712
13250
  if (!i) {
12713
13251
  this.scene.background = e;
12714
13252
  return;
@@ -12727,8 +13265,8 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12727
13265
  n
12728
13266
  ].join("|");
12729
13267
  if (f !== this.backgroundSig || !this.backgroundTexture) {
12730
- let e = du(c, l, u, t, n, r, this.config.background, i, a.x, a.y);
12731
- this.backgroundTexture?.dispose(), this.backgroundTexture = au(e), this.backgroundSig = f, this.backgroundVideoCanvas = o ? e : void 0;
13268
+ let e = Wu(c, l, u, t, n, r, this.config.background, i, a.x, a.y);
13269
+ this.backgroundTexture?.dispose(), this.backgroundTexture = Ru(e), this.backgroundSig = f, this.backgroundVideoCanvas = o ? e : void 0;
12732
13270
  }
12733
13271
  this.scene.background = this.backgroundTexture;
12734
13272
  }
@@ -12780,7 +13318,7 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12780
13318
  x: 0,
12781
13319
  y: 0
12782
13320
  };
12783
- fu(t, e, e.videoWidth, e.videoHeight, this.config.backgroundImageFit ?? "cover", this.config.background, this.config.backgroundImageZoom ?? 1, n.x, n.y), this.backgroundTexture.needsUpdate = !0;
13321
+ Gu(t, e, e.videoWidth, e.videoHeight, this.config.backgroundImageFit ?? "cover", this.config.background, this.config.backgroundImageZoom ?? 1, n.x, n.y), this.backgroundTexture.needsUpdate = !0;
12784
13322
  }
12785
13323
  applyPost() {
12786
13324
  let e = this.postPass.uniforms;
@@ -12833,13 +13371,16 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12833
13371
  };
12834
13372
  updateRunning() {
12835
13373
  let e = this.started && this.visible && this.pageVisible && !this.config.paused && !this.reducedMotion;
12836
- e && !this.running ? (this.running = !0, this.timer.update(), this.rafId = requestAnimationFrame(this.loop)) : !e && this.running && (this.running = !1, cancelAnimationFrame(this.rafId)), this.running || (this.introTimeRamp = 1, this.renderOnce()), this.syncVideoPlayback();
13374
+ e && !this.running ? (this.running = !0, this.timer.update(), this.rafId = requestAnimationFrame(this.loop)) : !e && this.running && (this.running = !1, cancelAnimationFrame(this.rafId)), this.running || (this.introTimeRamp = 1, this.interaction?.settle(), this.renderOnce()), this.syncVideoPlayback();
12837
13375
  }
12838
13376
  loop = () => {
12839
- this.running && (this.timer.update(), this.time += this.timer.getDelta(), this.introTimeRamp < 1 && (this.introTimeRamp = Math.min(1, this.introTimeRamp + .016)), this.renderOnce(), this.rafId = requestAnimationFrame(this.loop));
13377
+ if (!this.running) return;
13378
+ this.timer.update();
13379
+ let e = this.timer.getDelta();
13380
+ this.time += e, this.interaction?.update(e), this.introTimeRamp < 1 && (this.introTimeRamp = Math.min(1, this.introTimeRamp + .016)), this.renderOnce(), this.rafId = requestAnimationFrame(this.loop);
12840
13381
  };
12841
13382
  updateTime() {
12842
- let e = this.config.introRamp === !1 || this.skipIntroRamp ? 1 : this.introTimeRamp, t = this.time * e + (this.config.timeOffset ?? 0);
13383
+ let e = this.config.introRamp === !1 || this.skipIntroRamp ? 1 : this.introTimeRamp, t = this.time * e + (this.config.timeOffset ?? 0) + this.interactionTimeOffset;
12843
13384
  for (let e = 0; e < this.waves.length; e++) {
12844
13385
  let n = this.waves[e].material.uniforms;
12845
13386
  n.uTime.value = t;
@@ -12852,7 +13393,97 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12852
13393
  this.postPass.uniforms.uTime.value = t;
12853
13394
  }
12854
13395
  renderOnce() {
12855
- this.updateBackgroundVideoFrame(), this.updateTime(), this.updateClipPlanes(), this.composer.render(), this.onAfterRenderFrame();
13396
+ this.updateBackgroundVideoFrame(), this.updateTime(), this.applyInteraction(), this.updateClipPlanes(), this.composer.render(), this.onAfterRenderFrame();
13397
+ }
13398
+ syncInteraction() {
13399
+ let e = hu(this.config);
13400
+ e && !this.interaction ? this.interaction = new ju(this.container, () => this.config) : !e && this.interaction && (this.interaction.dispose(), this.interaction = void 0, this.interactionTimeOffset = 0, this.interactionZoom !== 1 && (this.interactionZoom = 1, this.applyZoom()));
13401
+ }
13402
+ applyInteraction() {
13403
+ if (this.interaction) {
13404
+ if (this.capturing) {
13405
+ this.applyInteractionRest();
13406
+ return;
13407
+ }
13408
+ mu(this.config) && this.applyPointerField(this.interaction), this.applyBindings(this.interaction);
13409
+ }
13410
+ }
13411
+ applyInteractionRest() {
13412
+ for (let e = 0; e < this.waves.length; e++) {
13413
+ let t = this.config.waves[e] ?? this.config.waves[this.config.waves.length - 1];
13414
+ if (!fu(this.config, t)) continue;
13415
+ let n = this.waves[e].material.uniforms;
13416
+ n.uPointerActive.value = 0;
13417
+ let r = n.uRippleAmp.value;
13418
+ for (let e = 0; e < 4; e++) r[e] = 0;
13419
+ }
13420
+ let e = this.config.interaction?.bindings;
13421
+ if (e) {
13422
+ this.interactionSceneOut.timeOffset = this.config.timeOffset ?? 0, this.interactionSceneOut.zoom = this.config.cameraZoom ?? 1;
13423
+ let t = {
13424
+ post: this.postPass.uniforms,
13425
+ out: this.interactionSceneOut
13426
+ };
13427
+ for (let n of e) {
13428
+ let e = Au[n.target];
13429
+ e.apply(e.base(this.config), t);
13430
+ }
13431
+ }
13432
+ this.interactionTimeOffset !== 0 && (this.interactionTimeOffset = 0, this.updateTime());
13433
+ for (let e = 0; e < this.waves.length; e++) {
13434
+ let t = this.config.waves[e], n = t?.interaction?.bindings;
13435
+ if (!t || !n || n.length === 0) continue;
13436
+ let r = this.waves[e];
13437
+ for (let e of n) {
13438
+ let n = ku[e.target];
13439
+ n.apply(n.base(t), {
13440
+ u: r.material.uniforms,
13441
+ mesh: r.mesh
13442
+ });
13443
+ }
13444
+ }
13445
+ }
13446
+ applyPointerField(e) {
13447
+ let t = this.camera.right - this.camera.left, n = this.camera.top - this.camera.bottom, r = n === 0 ? 1 : t / n, i = e.sample().ripples, a = Math.min(1, .2 + .85 * e.pointerFlux()), o = e.pointerVelocity();
13448
+ for (let t = 0; t < this.waves.length; t++) {
13449
+ let n = this.config.waves[t] ?? this.config.waves[this.config.waves.length - 1];
13450
+ if (!fu(this.config, n)) continue;
13451
+ let s = this.waves[t].material.uniforms;
13452
+ s.uPointerAgitate.value = (n.interaction?.hover?.agitate ?? 0) * a, s.uPointerVel.value.copy(o);
13453
+ let c = e.fieldFor(t);
13454
+ c ? (s.uPointer.value.copy(c.ndc), s.uPointerActive.value = c.presence) : s.uPointerActive.value = 0, s.uPointerAspect.value = r;
13455
+ let l = s.uRippleOrigin.value, u = s.uRippleAge.value, d = s.uRippleAmp.value;
13456
+ for (let e = 0; e < 4; e++) l[e].copy(i[e].origin), u[e] = i[e].age, d[e] = i[e].amp;
13457
+ }
13458
+ }
13459
+ applyBindings(e) {
13460
+ this.interactionSceneOut.timeOffset = this.config.timeOffset ?? 0, this.interactionSceneOut.zoom = this.config.cameraZoom ?? 1;
13461
+ let t = {
13462
+ post: this.postPass.uniforms,
13463
+ out: this.interactionSceneOut
13464
+ };
13465
+ for (let n of this.config.interaction?.bindings ?? []) {
13466
+ let r = Au[n.target], i = Gt.lerp(n.from ?? r.base(this.config), n.to, e.bindingValue(n));
13467
+ r.apply(i, t);
13468
+ }
13469
+ for (let t = 0; t < this.waves.length; t++) {
13470
+ let n = this.config.waves[t], r = n?.interaction?.bindings;
13471
+ if (!n || !r || r.length === 0) continue;
13472
+ let i = this.waves[t];
13473
+ for (let t of r) {
13474
+ let r = ku[t.target], a = Gt.lerp(t.from ?? r.base(n), t.to, e.bindingValue(t));
13475
+ r.apply(a, {
13476
+ u: i.material.uniforms,
13477
+ mesh: i.mesh
13478
+ });
13479
+ }
13480
+ }
13481
+ this.interactionTimeOffset = this.interactionSceneOut.timeOffset - (this.config.timeOffset ?? 0);
13482
+ let n = this.interactionSceneOut.zoom / (this.config.cameraZoom || 1);
13483
+ n !== this.interactionZoom && (this.interactionZoom = n, this.applyZoom());
13484
+ }
13485
+ setInteractionInput(e, t) {
13486
+ this.interaction?.setInput(e, t);
12856
13487
  }
12857
13488
  refreshPlayback() {
12858
13489
  this.updateRunning();
@@ -12869,17 +13500,22 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12869
13500
  onAfterResize() {}
12870
13501
  applyZoom() {
12871
13502
  let e = this.camera.right - this.camera.left, t = this.camera.top - this.camera.bottom;
12872
- this.camera.zoom = Math.max(e / Lu, t / 750) * (this.config.cameraZoom ?? 1), this.camera.updateProjectionMatrix();
13503
+ this.camera.zoom = Math.max(e / gd, t / 750) * (this.config.cameraZoom ?? 1) * this.interactionZoom, this.camera.updateProjectionMatrix();
12873
13504
  }
12874
13505
  updateClipPlanes() {
12875
13506
  this.clipBox.makeEmpty();
12876
- for (let e of this.waves) {
12877
- let t = e.mesh;
12878
- t.updateWorldMatrix(!0, !1);
12879
- let n = t.geometry.boundingSphere;
12880
- if (!n) continue;
12881
- let r = this.clipTmpA.setFromMatrixPosition(t.matrixWorld), i = Math.abs(Number(e.material.uniforms.uDispAmount.value) || 0), a = (n.center.length() + n.radius + i) * t.matrixWorld.getMaxScaleOnAxis() * 1.2;
12882
- this.clipBox.expandByPoint(this.clipTmpB.copy(r).addScalar(a)), this.clipBox.expandByPoint(this.clipTmpB.copy(r).addScalar(-a));
13507
+ for (let e = 0; e < this.waves.length; e++) {
13508
+ let t = this.waves[e], n = t.mesh;
13509
+ n.updateWorldMatrix(!0, !1);
13510
+ let r = n.geometry.boundingSphere;
13511
+ if (!r) continue;
13512
+ let i = this.clipTmpA.setFromMatrixPosition(n.matrixWorld), a = Math.abs(Number(t.material.uniforms.uDispAmount.value) || 0), o = this.config.waves[e] ?? this.config.waves[this.config.waves.length - 1], s = 0;
13513
+ if (fu(this.config, o)) {
13514
+ let e = o.interaction?.hover;
13515
+ s = (e?.agitate ?? 0) + Math.abs(e?.push ?? 0) + (e?.wake ?? 0) + (o.interaction?.press?.ripple ?? 0);
13516
+ }
13517
+ let c = (r.center.length() + r.radius + a + s) * n.matrixWorld.getMaxScaleOnAxis() * 1.2;
13518
+ this.clipBox.expandByPoint(this.clipTmpB.copy(i).addScalar(c)), this.clipBox.expandByPoint(this.clipTmpB.copy(i).addScalar(-c));
12883
13519
  }
12884
13520
  if (this.clipBox.isEmpty()) return;
12885
13521
  this.clipBox.getBoundingSphere(this.clipSphere);
@@ -12891,11 +13527,11 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12891
13527
  t !== i && (this.config.transparentBackground = t, this.applyBackground());
12892
13528
  let a = r !== void 0, o = this.time, s = this.introTimeRamp;
12893
13529
  a && (this.time = r, this.introTimeRamp = 1);
12894
- let c = null;
13530
+ let c = null, l = this.camera.zoom, u = this.interactionZoom !== 1;
12895
13531
  try {
12896
- this.capturing = !0, this.renderOnce(), c = await new Promise((t) => this.canvas.toBlob(t, e, n));
13532
+ this.capturing = !0, u && (this.camera.zoom = l / this.interactionZoom, this.camera.updateProjectionMatrix()), this.renderOnce(), c = await new Promise((t) => this.canvas.toBlob(t, e, n));
12897
13533
  } finally {
12898
- this.capturing = !1, t !== i && (this.config.transparentBackground = i, this.applyBackground()), a && (this.time = o, this.introTimeRamp = s), this.renderOnce();
13534
+ this.capturing = !1, u && (this.camera.zoom = l, this.camera.updateProjectionMatrix()), t !== i && (this.config.transparentBackground = i, this.applyBackground()), a && (this.time = o, this.introTimeRamp = s), this.renderOnce();
12899
13535
  }
12900
13536
  if (!c || c.type !== e) throw Error(`Failed to capture ${e}`);
12901
13537
  return c;
@@ -12910,25 +13546,25 @@ var Iu, Lu, Ru, zu, Bu, Vu = t((() => {
12910
13546
  return this.config;
12911
13547
  }
12912
13548
  setConfig(e) {
12913
- let t = Al(e), n = t.waves.length !== this.waves.length || t.quality !== this.config.quality;
13549
+ let t = Fl(e), n = t.waves.length !== this.waves.length || t.quality !== this.config.quality;
12914
13550
  this.config = t, n ? this.rebuild() : this.refresh(), this.applyCameraFromConfig();
12915
13551
  }
12916
13552
  dispose() {
12917
- cancelAnimationFrame(this.rafId), this.running = !1, this.resizeObserver.disconnect(), this.intersectionObserver.disconnect(), this.motionQuery.removeEventListener("change", this.onMotionChange), document.removeEventListener("visibilitychange", this.onVisibilityChange), this.renderer.domElement.removeEventListener("webglcontextlost", this.onContextLost), this.renderer.domElement.removeEventListener("webglcontextrestored", this.onContextRestored), this.clearBackgroundVideo(), this.backgroundTexture?.dispose();
13553
+ cancelAnimationFrame(this.rafId), this.running = !1, this.interaction?.dispose(), this.interaction = void 0, this.resizeObserver.disconnect(), this.intersectionObserver.disconnect(), this.motionQuery.removeEventListener("change", this.onMotionChange), document.removeEventListener("visibilitychange", this.onVisibilityChange), this.renderer.domElement.removeEventListener("webglcontextlost", this.onContextLost), this.renderer.domElement.removeEventListener("webglcontextrestored", this.onContextRestored), this.clearBackgroundVideo(), this.backgroundTexture?.dispose();
12918
13554
  for (let e of this.waves) e.material.dispose(), e.geometry.dispose(), e.palette.dispose();
12919
13555
  this.bloomPass?.dispose(), this.composer.dispose(), this.renderer.dispose(), this.renderer.domElement.remove();
12920
13556
  }
12921
13557
  };
12922
- })), Hu = /* @__PURE__ */ n({
12923
- WaveRenderer: () => Bu,
13558
+ })), xd = /* @__PURE__ */ n({
13559
+ WaveRenderer: () => yd,
12924
13560
  createDefaultConfig: () => wl
12925
13561
  });
12926
13562
  //#endregion
12927
13563
  //#region src/shell/probe.ts
12928
13564
  t((() => {
12929
- Vu(), Ll();
13565
+ bd(), Gl();
12930
13566
  }))();
12931
- function Uu() {
13567
+ function Sd() {
12932
13568
  if (typeof document > "u") return !1;
12933
13569
  try {
12934
13570
  let e = document.createElement("canvas"), t = { failIfMajorPerformanceCaveat: !0 }, n = e.getContext("webgl2", t) ?? e.getContext("webgl", t);
@@ -12937,122 +13573,124 @@ function Uu() {
12937
13573
  return !1;
12938
13574
  }
12939
13575
  }
12940
- function Wu() {
13576
+ function Cd() {
12941
13577
  return typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
12942
13578
  }
12943
- function Gu() {
13579
+ function wd() {
12944
13580
  return typeof navigator > "u" ? !1 : navigator.connection?.saveData === !0;
12945
13581
  }
12946
13582
  //#endregion
12947
13583
  //#region src/shell/poster.ts
12948
- var Ku = "data-wave3d-poster";
12949
- function qu(e) {
13584
+ var Td = "data-wave3d-poster";
13585
+ function Ed(e) {
12950
13586
  getComputedStyle(e).position === "static" && (e.style.position = "relative");
12951
13587
  }
12952
- function Ju(e, t) {
12953
- let n = e.querySelector(`img[${Ku}]`);
12954
- if (!n && !t) return null;
12955
- n || (n = document.createElement("img"), n.setAttribute(Ku, ""), n.decoding = "async", n.alt = "", n.setAttribute("aria-hidden", "true"), e.appendChild(n)), t && (n.src = t), Object.assign(n.style, {
13588
+ function Dd(e, t, n = "fill") {
13589
+ let r = e.querySelector(`img[${Td}]`);
13590
+ if (!r && !t) return null;
13591
+ r || (r = document.createElement("img"), r.setAttribute(Td, ""), r.decoding = "async", r.alt = "", r.setAttribute("aria-hidden", "true"), e.appendChild(r)), t && (r.src = t), Object.assign(r.style, {
12956
13592
  position: "absolute",
12957
13593
  inset: "0",
12958
13594
  width: "100%",
12959
13595
  height: "100%",
12960
- objectFit: "cover",
13596
+ objectFit: n,
12961
13597
  pointerEvents: "none",
12962
13598
  zIndex: "1",
12963
13599
  opacity: "1",
12964
13600
  visibility: "visible"
12965
13601
  });
12966
- let r = n;
13602
+ let i = r;
12967
13603
  return {
12968
- el: r,
13604
+ el: i,
12969
13605
  fadeOut(e) {
12970
13606
  if (e <= 0) {
12971
- r.style.opacity = "0", r.style.visibility = "hidden";
13607
+ i.style.opacity = "0", i.style.visibility = "hidden";
12972
13608
  return;
12973
13609
  }
12974
- r.style.transition = `opacity ${e}ms ease`, r.offsetWidth, r.style.opacity = "0", setTimeout(() => {
12975
- r.style.visibility = "hidden";
13610
+ i.style.transition = `opacity ${e}ms ease`, i.offsetWidth, i.style.opacity = "0", setTimeout(() => {
13611
+ i.style.visibility = "hidden";
12976
13612
  }, e + 50);
12977
13613
  },
12978
13614
  show() {
12979
- r.style.transition = "", r.style.opacity = "1", r.style.visibility = "visible";
13615
+ i.style.transition = "", i.style.opacity = "1", i.style.visibility = "visible";
12980
13616
  },
12981
13617
  remove() {
12982
- r.remove();
13618
+ i.remove();
12983
13619
  }
12984
13620
  };
12985
13621
  }
12986
13622
  //#endregion
12987
13623
  //#region src/shell/createWave.ts
12988
- function Yu(e, t, n, r) {
13624
+ function Od(e, t, n, r) {
12989
13625
  let { lazy: i = !0, rootMargin: a = "200px", webgl: o = "auto", respectReducedMotion: s = !0, reducedMotionBehavior: c = "static", respectSaveData: l = !0, fadeMs: u = 300 } = r, d = "poster", f = null, p = { ...n };
12990
13626
  r.paused !== void 0 && (p.paused = r.paused);
12991
- let m = !1, h = null, g, _ = 0;
12992
- qu(t);
12993
- let v = Ju(t, r.poster);
12994
- function y(e) {
12995
- d !== e && (d = e, r.onStateChange?.(e));
12996
- }
13627
+ let m = /* @__PURE__ */ new Map(), h = !1, g = null, _, v = 0;
13628
+ Ed(t);
13629
+ let y = Dd(t, r.poster, r.posterFit);
12997
13630
  function b(e) {
12998
- y("fallback"), v?.show(), r.onFallback?.(e);
13631
+ d !== e && (d = e, r.onStateChange?.(e));
12999
13632
  }
13000
- function x() {
13001
- clearTimeout(g);
13633
+ function x(e) {
13634
+ b("fallback"), y?.show(), r.onFallback?.(e);
13002
13635
  }
13003
13636
  function S() {
13004
- if (_ += 1, clearTimeout(g), _ >= 2) {
13005
- C(), b("context-lost");
13637
+ clearTimeout(_);
13638
+ }
13639
+ function C() {
13640
+ if (v += 1, clearTimeout(_), v >= 2) {
13641
+ w(), x("context-lost");
13006
13642
  return;
13007
13643
  }
13008
- g = setTimeout(() => {
13009
- C(), b("context-lost");
13644
+ _ = setTimeout(() => {
13645
+ w(), x("context-lost");
13010
13646
  }, 4e3);
13011
13647
  }
13012
- function C() {
13648
+ function w() {
13013
13649
  if (!f) return;
13014
13650
  let e = f.renderer.domElement;
13015
- e.removeEventListener("webglcontextlost", S), e.removeEventListener("webglcontextrestored", x), f.dispose(), f = null;
13651
+ e.removeEventListener("webglcontextlost", C), e.removeEventListener("webglcontextrestored", S), f.dispose(), f = null;
13016
13652
  }
13017
- async function w() {
13018
- y("loading");
13653
+ async function T() {
13654
+ b("loading");
13019
13655
  let n;
13020
13656
  try {
13021
13657
  n = await e();
13022
13658
  } catch {
13023
- m || b("load-error");
13659
+ h || x("load-error");
13024
13660
  return;
13025
13661
  }
13026
- if (m) return;
13662
+ if (h) return;
13027
13663
  let i = {
13028
13664
  ...n.createDefaultConfig(),
13029
13665
  ...p
13030
13666
  }, a = { respectReducedMotion: s };
13031
13667
  f = new n.WaveRenderer(t, i, a);
13032
13668
  let o = f.renderer.domElement;
13033
- o.addEventListener("webglcontextlost", S, !1), o.addEventListener("webglcontextrestored", x, !1), f.start(), y("running"), r.onReady?.(f), v && requestAnimationFrame(() => requestAnimationFrame(() => {
13034
- !m && f && v.fadeOut(u);
13669
+ o.addEventListener("webglcontextlost", C, !1), o.addEventListener("webglcontextrestored", S, !1), f.start();
13670
+ for (let [e, t] of m) f.setInteractionInput(e, t);
13671
+ b("running"), r.onReady?.(f), y && requestAnimationFrame(() => requestAnimationFrame(() => {
13672
+ !h && f && y.fadeOut(u);
13035
13673
  }));
13036
13674
  }
13037
- function T() {
13038
- if (!m) {
13039
- if (o === "auto" && !Uu()) {
13040
- b("no-webgl");
13675
+ function E() {
13676
+ if (!h) {
13677
+ if (o === "auto" && !Sd()) {
13678
+ x("no-webgl");
13041
13679
  return;
13042
13680
  }
13043
- w();
13681
+ T();
13044
13682
  }
13045
13683
  }
13046
- function E() {
13684
+ function D() {
13047
13685
  if (o !== "off") {
13048
- if (l && Gu()) return b("save-data");
13049
- if (s && c === "poster" && Wu()) return b("reduced-motion");
13050
- i && typeof IntersectionObserver < "u" ? (h = new IntersectionObserver((e) => {
13051
- e.some((e) => e.isIntersecting) && (h?.disconnect(), h = null, T());
13052
- }, { rootMargin: a }), h.observe(t)) : T();
13686
+ if (l && wd()) return x("save-data");
13687
+ if (s && c === "poster" && Cd()) return x("reduced-motion");
13688
+ i && typeof IntersectionObserver < "u" ? (g = new IntersectionObserver((e) => {
13689
+ e.some((e) => e.isIntersecting) && (g?.disconnect(), g = null, E());
13690
+ }, { rootMargin: a }), g.observe(t)) : E();
13053
13691
  }
13054
13692
  }
13055
- return E(), {
13693
+ return D(), {
13056
13694
  get state() {
13057
13695
  return d;
13058
13696
  },
@@ -13073,6 +13711,9 @@ function Yu(e, t, n, r) {
13073
13711
  ...e
13074
13712
  };
13075
13713
  },
13714
+ setInteractionInput(e, t) {
13715
+ f ? f.setInteractionInput(e, t) : m.set(e, t);
13716
+ },
13076
13717
  play() {
13077
13718
  f ? (f.getConfig().paused = !1, f.refreshPlayback()) : p.paused = !1;
13078
13719
  },
@@ -13080,17 +13721,17 @@ function Yu(e, t, n, r) {
13080
13721
  f ? (f.getConfig().paused = !0, f.refreshPlayback()) : p.paused = !0;
13081
13722
  },
13082
13723
  destroy() {
13083
- m = !0, h?.disconnect(), h = null, clearTimeout(g), C(), v?.remove();
13724
+ h = !0, g?.disconnect(), g = null, clearTimeout(_), w(), y?.remove();
13084
13725
  }
13085
13726
  };
13086
13727
  }
13087
13728
  //#endregion
13088
13729
  //#region src/presets.ts
13089
- Ll();
13090
- var Xu = 180 / Math.PI;
13091
- function Zu(e) {
13730
+ Gl();
13731
+ var kd = 180 / Math.PI;
13732
+ function Ad(e) {
13092
13733
  let t = wl(), n = t.waves[0];
13093
- return n.speed = e.speed, n.colorContrast = e.contrast, n.colorSaturation = e.sat, n.hueShift = e.hueRad * Xu, n.displaceFrequency = {
13734
+ return n.speed = e.speed, n.colorContrast = e.contrast, n.colorSaturation = e.sat, n.hueShift = e.hueRad * kd, n.displaceFrequency = {
13094
13735
  x: e.dispX,
13095
13736
  y: e.dispZ
13096
13737
  }, n.displaceAmount = e.dispAmt, n.position = {
@@ -13098,9 +13739,9 @@ function Zu(e) {
13098
13739
  y: e.pos[1],
13099
13740
  z: e.pos[2]
13100
13741
  }, n.rotation = {
13101
- x: e.rotRad[0] * Xu,
13102
- y: e.rotRad[1] * Xu,
13103
- z: e.rotRad[2] * Xu
13742
+ x: e.rotRad[0] * kd,
13743
+ y: e.rotRad[1] * kd,
13744
+ z: e.rotRad[2] * kd
13104
13745
  }, n.scale = {
13105
13746
  x: e.scale[0],
13106
13747
  y: e.scale[1],
@@ -13123,8 +13764,8 @@ function Zu(e) {
13123
13764
  z: 0
13124
13765
  }, t.cameraZoom = e.zoom, t;
13125
13766
  }
13126
- var Qu = {
13127
- Hero: () => Zu({
13767
+ var jd = {
13768
+ Hero: () => Ad({
13128
13769
  speed: .04,
13129
13770
  contrast: 1,
13130
13771
  sat: 1,
@@ -13168,7 +13809,7 @@ var Qu = {
13168
13809
  camTarget: [-420, -200]
13169
13810
  }),
13170
13811
  "Wave 2": () => wl(),
13171
- "Wave 3": () => Zu({
13812
+ "Wave 3": () => Ad({
13172
13813
  speed: .08,
13173
13814
  contrast: 1,
13174
13815
  sat: 1,
@@ -13211,7 +13852,7 @@ var Qu = {
13211
13852
  zoom: 1.3,
13212
13853
  camTarget: [-104, 13]
13213
13854
  }),
13214
- "Wave 4": () => Zu({
13855
+ "Wave 4": () => Ad({
13215
13856
  speed: .0525,
13216
13857
  contrast: .969,
13217
13858
  sat: 1.383,
@@ -13291,7 +13932,7 @@ var Qu = {
13291
13932
  ]), t.creaseLight = 1, e.background = "#05060c", e.transparentBackground = !1, e.waves = bl(t, 3), e.waveCount = 3, e;
13292
13933
  },
13293
13934
  "Mesh Gradient": () => {
13294
- let e = Qu.Hero(), t = e.waves[0];
13935
+ let e = jd.Hero(), t = e.waves[0];
13295
13936
  return t.gradientType = "mesh", t.meshGradientPoints = [
13296
13937
  {
13297
13938
  color: "#0a84ff",
@@ -13332,7 +13973,7 @@ var Qu = {
13332
13973
  ], t.meshGradientSoftness = .68, t.blendMode = "normal", t.hueShift = 0, t.colorContrast = 1.06, t.colorSaturation = 1.12, t.fiberStrength = .14, e.grain = .3, e.blur = .008, e.background = "#070914", e.backgroundMode = "color", e.transparentBackground = !1, e;
13333
13974
  },
13334
13975
  "Solar Bloom": () => {
13335
- let e = Qu.Hero(), t = e.waves[0];
13976
+ let e = jd.Hero(), t = e.waves[0];
13336
13977
  return t.usePaletteTexture = !1, t.gradientType = "radial", t.gradientShift = .14, t.palette = [
13337
13978
  {
13338
13979
  color: "#fff3c4",
@@ -13361,7 +14002,7 @@ var Qu = {
13361
14002
  ], t.blendMode = "normal", t.hueShift = 0, t.colorContrast = 1.05, t.colorSaturation = 1.18, t.fiberStrength = .12, e.grain = .3, e.blur = .01, e.background = "#0a0714", e.backgroundMode = "gradient", e.backgroundGradientType = "radial", e.backgroundGradientSource = "stops", e.backgroundPalette = vl(["#2a1330", "#08040f"]), e.transparentBackground = !1, e;
13362
14003
  },
13363
14004
  Holographic: () => {
13364
- let e = Qu.Hero(), t = e.waves[0];
14005
+ let e = jd.Hero(), t = e.waves[0];
13365
14006
  return t.usePaletteTexture = !1, t.gradientType = "conic", t.gradientShift = .08, t.palette = [
13366
14007
  {
13367
14008
  color: "#8ef6e4",
@@ -13394,7 +14035,7 @@ var Qu = {
13394
14035
  ], t.blendMode = "normal", t.hueShift = 0, t.colorContrast = 1.04, t.colorSaturation = 1.12, t.fiberStrength = .12, e.grain = .28, e.blur = .01, e.background = "#05060c", e.backgroundMode = "gradient", e.backgroundGradientType = "linear", e.backgroundGradientAngle = 135, e.backgroundGradientSource = "stops", e.backgroundPalette = vl(["#04121a", "#0a0518"]), e.transparentBackground = !1, e;
13395
14036
  },
13396
14037
  Aurora: () => {
13397
- let e = Qu.Hero(), t = e.waves[0];
14038
+ let e = jd.Hero(), t = e.waves[0];
13398
14039
  return t.gradientType = "mesh", t.meshGradientPoints = [
13399
14040
  {
13400
14041
  color: "#0a1f3c",
@@ -13466,27 +14107,31 @@ var Qu = {
13466
14107
  ], e.backgroundMeshSoftness = .75, e.transparentBackground = !1, e;
13467
14108
  },
13468
14109
  Palestine: () => {
13469
- let e = Qu.Hero(), t = e.waves[0];
14110
+ let e = jd.Hero(), t = e.waves[0];
13470
14111
  return t.paletteSource = "palestine", t.blendMode = "normal", t.hueShift = 0, t.colorContrast = 1, t.colorSaturation = 1, e.grain = .35, e.background = "#f2efe8", e.transparentBackground = !0, e;
13471
14112
  },
14113
+ Spain: () => {
14114
+ let e = jd.Hero(), t = e.waves[0];
14115
+ return t.paletteSource = "spain", t.blendMode = "normal", t.hueShift = 0, t.colorContrast = 1.18, t.colorSaturation = 1.25, t.creaseLight = 1.6, e.grain = .3, e.background = "#1a0608", e.backgroundMode = "color", e.transparentBackground = !1, e;
14116
+ },
13472
14117
  "Vaporwave Sunset": () => {
13473
- let e = Qu.Hero(), t = e.waves[0];
13474
- return t.position.x = 525, t.rotation.x = -.64 * Xu, t.rotation.z = 1.68 * Xu, t.paletteSource = "vaporwave", t.blendMode = "normal", t.hueShift = 0, t.colorContrast = 1.08, t.colorSaturation = 1.15, t.creaseLight = 1.25, e.cameraZoom = 1.1, e.cameraTarget = {
14118
+ let e = jd.Hero(), t = e.waves[0];
14119
+ return t.position.x = 525, t.rotation.x = -.64 * kd, t.rotation.z = 1.68 * kd, t.paletteSource = "vaporwave", t.blendMode = "normal", t.hueShift = 0, t.colorContrast = 1.08, t.colorSaturation = 1.15, t.creaseLight = 1.25, e.cameraZoom = 1.1, e.cameraTarget = {
13475
14120
  x: 150,
13476
14121
  y: 360,
13477
14122
  z: 0
13478
14123
  }, e.background = "#09051f", e.transparentBackground = !1, e;
13479
14124
  },
13480
14125
  Kaleidoscope: () => {
13481
- let e = Qu["Wave 3"](), t = e.waves[0];
14126
+ let e = jd["Wave 3"](), t = e.waves[0];
13482
14127
  return t.paletteSource = "kaleidoscope", t.blendMode = "normal", t.hueShift = 0, t.colorContrast = 1.05, t.colorSaturation = 1.12, e.grain = .5, e;
13483
14128
  }
13484
14129
  };
13485
- Vu(), Ll();
13486
- var $u = () => Promise.resolve(Hu);
13487
- function ed(e, t = {}, n = {}) {
13488
- return Yu($u, e, t, n);
14130
+ bd(), Gl();
14131
+ var Md = () => Promise.resolve(xd);
14132
+ function Nd(e, t = {}, n = {}) {
14133
+ return Od(Md, e, t, n);
13489
14134
  }
13490
- var td = ed;
14135
+ var Pd = Nd;
13491
14136
  //#endregion
13492
- export { Il as DEFAULT_LIGHT_POSITION, jl as MAX_COLORS, Nl as MAX_LIGHTS, Ml as MAX_MESH_POINTS, Pl as MAX_NOISE_BANDS, Fl as MAX_WAVES, Qu as PRESETS, Bu as WaveRenderer, wl as createDefaultConfig, yl as createDefaultMeshPoints, gl as createLight, _l as createNoiseBand, ed as createWave, Dl as ensureCamera, kl as ensureSceneDefaults, Al as ensureStudioConfig, vl as makeStops, Sl as makeWave, bl as makeWaveSpread, td as mountWave, El as normalizeBackground, Ol as normalizeWave, Cl as resizeWaves };
14137
+ export { Vl as DEFAULT_LIGHT_POSITION, Il as MAX_COLORS, Rl as MAX_LIGHTS, Ll as MAX_MESH_POINTS, zl as MAX_NOISE_BANDS, Bl as MAX_WAVES, jd as PRESETS, yd as WaveRenderer, wl as createDefaultConfig, yl as createDefaultMeshPoints, gl as createLight, _l as createNoiseBand, Nd as createWave, Dl as ensureCamera, kl as ensureSceneDefaults, Fl as ensureStudioConfig, vl as makeStops, Sl as makeWave, bl as makeWaveSpread, Pd as mountWave, El as normalizeBackground, Pl as normalizeSceneInteraction, Ol as normalizeWave, Nl as normalizeWaveInteraction, Cl as resizeWaves };