lensfx 0.1.1 → 0.1.3

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/vanilla.ts","../../src/engine/math.ts","../../src/createLens.ts","../../src/engine/types.ts","../../src/webgl/VideoRefractionRenderer.ts","../../src/webgl/QRRefractionRenderer.ts"],"sourcesContent":["/**\n * lensfx — Vanilla / Standalone Entry Point\n *\n * Zero external dependencies (no React, no Framer Motion).\n * This entry point is compiled into:\n * 1. The CDN IIFE bundle (window.lensfx) for plain <script> tag usage.\n * 2. The ESM/CJS vanilla build accessible via \"lensfx/vanilla\".\n */\n\n// ─── Vanilla DOM createLens API ──────────────────────────────────────────────\nexport { createLens } from \"./createLens\";\nexport type { LensOptions, LensInstance } from \"./createLens\";\n\n// ─── Pure Math & Physics Engine ──────────────────────────────────────────────\nexport type {\n LensParams,\n DomeConstants,\n MapGeneratorInput,\n MapGeneratorOutput,\n} from \"./engine/types\";\nexport {\n DEFAULT_LENS_PARAMS,\n SWITCH_GLASS_DEFAULTS,\n SWITCH_DARK_OVERRIDES,\n SWITCH_LIGHT_OVERRIDES,\n SLIDER_GLASS_DEFAULTS,\n SLIDER_DARK_OVERRIDES,\n SLIDER_LIGHT_OVERRIDES,\n SLIDER_SAFARI_OVERRIDES,\n} from \"./engine/types\";\nexport {\n erf,\n computeDomeConstants,\n domeGradient,\n colorMatrixValues,\n getSvgMaskDataUri,\n createDisplacementMapGeneratorSync,\n generateDisplacementMapAsync,\n} from \"./engine/math\";\n\n// ─── WebGL Renderers (Video & QR Fallbacks) ──────────────────────────────────\nexport { VideoRefractionRenderer } from \"./webgl/VideoRefractionRenderer\";\nexport { QRRefractionRenderer } from \"./webgl/QRRefractionRenderer\";\nexport type { VideoRendererOptions } from \"./webgl/VideoRefractionRenderer\";\nexport type { QRRendererOptions } from \"./webgl/QRRefractionRenderer\";\n","/**\n * lensfx — Engine Layer: Core Mathematics & Displacement Map Generation\n *\n * Pure TypeScript — no React, no DOM references at module load time.\n * DOM (canvas) is accessed only inside function bodies, never at import time,\n * making this SSR-safe.\n */\n\nimport { DomeConstants, MapGeneratorInput, MapGeneratorOutput } from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Mathematical primitives\n// ---------------------------------------------------------------------------\n\n/**\n * Approximation of the Gauss error function using hyperbolic tangent.\n *\n * erf(x) ≈ tanh(√π · x)\n *\n * The constant √π ≈ 1.7724538509 ensures that the derivative at 0 equals\n * 2/√π (matching the exact erf), giving a C∞ smooth clamping function that\n * avoids branching and is monotone on (−∞, +∞).\n */\nexport function erf(x: number): number {\n return Math.tanh(1.7724538509 * x);\n}\n\n/**\n * Numerical integration of dome slope over 200 samples using the trapezoid rule.\n * Used to derive the normalisation factor for the dome gradient lookup table.\n *\n * @param R - sphere radius\n * @param t - half-width/height of the lens face at the dome base\n */\nfunction integrateDome(R: number, t: number): number {\n let sum = 0;\n for (let n = 0; n <= 200; n++) {\n const a = (n / 200) * t;\n const slope = a / Math.sqrt(R * R - a * a);\n sum += n === 0 || n === 200 ? 0.5 * slope : slope;\n }\n return sum / 200;\n}\n\n/**\n * Computes ellipsoid dome curvature geometry constants for the X and Y axes.\n *\n * The dome is modelled as a sphere of radius R that just touches both the\n * centre and the edge of the lens: R = (halfDim² + depth²) / (2·depth).\n *\n * @param domeDepth - maximum height of the dome above the lens plane (px)\n * @param halfW - half-width of the lens (px)\n * @param halfH - half-height of the lens (px)\n */\nexport function computeDomeConstants(\n domeDepth: number,\n halfW: number,\n halfH: number\n): DomeConstants {\n const a = Math.max(0.01, Math.min(domeDepth, Math.min(halfW, halfH) - 1));\n const Rx = (halfW * halfW + a * a) / (2 * a);\n const Ry = (halfH * halfH + a * a) / (2 * a);\n const intX = integrateDome(Rx, halfW);\n const intY = integrateDome(Ry, halfH);\n\n return {\n Rx,\n Ry,\n scaleX: intX > 0 ? 0.5 / intX : 1,\n scaleY: intY > 0 ? 0.5 / intY : 1,\n };\n}\n\n/**\n * Evaluates the gradient (surface slope) of the dome at a given offset\n * from the lens centre. Returns a value in [0, 1] normalised by `scale`.\n */\nexport function domeGradient(pos: number, R: number, scale: number): number {\n const p = Math.min(pos, 0.999 * R);\n return (p / Math.sqrt(R * R - p * p)) * scale;\n}\n\n/**\n * Builds an SVG feColorMatrix 4×5 matrix string that rescales the\n * displacement map's R and G channels around the neutral midpoint (128/255 = 0.5).\n *\n * When scaleX ≠ scaleY the lens has asymmetric horizontal/vertical displacement\n * and we normalise the larger axis to 1 so both axes are within [0, 255].\n */\nexport function colorMatrixValues(ratioX: number, ratioY: number): string {\n return `${ratioX} 0 0 0 ${0.5 * (1 - ratioX)} 0 ${ratioY} 0 0 ${\n 0.5 * (1 - ratioY)\n } 0 0 1 0 0 0 0 0 1 0`;\n}\n\n// ---------------------------------------------------------------------------\n// SVG mask cache (safe because it is only written inside function bodies)\n// ---------------------------------------------------------------------------\n\nconst maskCache = new Map<string, string>();\n\n/**\n * Returns a memoised SVG rounded-rectangle mask as a data URI.\n * Used as CSS `mask-image` on the backdrop-blur and tint layers to\n * clip them to the lens shape without touching the filter graph.\n */\nexport function getSvgMaskDataUri(\n width: number,\n height: number,\n radius: number\n): { uri: string; key: string } {\n const n = Math.max(1, Math.round(width));\n const l = Math.max(1, Math.round(height));\n const i = Math.max(0, Math.min(Math.round(radius), Math.min(n, l) / 2));\n const key = `${n}|${l}|${i}`;\n\n const cached = maskCache.get(key);\n if (cached) return { uri: cached, key };\n\n const w = Math.max(0, n - 1);\n const h = Math.max(0, l - 1);\n const r = Math.max(0, i - 0.5);\n const svg = `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 ${n} ${l}' preserveAspectRatio='none'><rect x='0.5' y='0.5' width='${w}' height='${h}' rx='${r}' ry='${r}' fill='black'/></svg>`;\n const uri = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;\n maskCache.set(key, uri);\n\n return { uri, key };\n}\n\n// ---------------------------------------------------------------------------\n// Synchronous displacement map generator (for animated / interactive lenses)\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a stateful, synchronous displacement map generator with:\n * • 4-fold quadrant symmetry (75 % fewer pixel evaluations)\n * • Reusable canvas & ImageData to avoid GC pressure\n * • Cached dome gradient lookup table (recalculated only when geometry changes)\n *\n * Use for animated lenses where the map must update every frame in sync with\n * Framer Motion values. For static lenses, prefer `generateDisplacementMapAsync`.\n *\n * @param mapSize - side length of the square displacement map canvas (px)\n */\nexport function createDisplacementMapGeneratorSync(mapSize: number) {\n // Private mutable state — closed over by the returned object\n let canvas: HTMLCanvasElement | null = null;\n let ctx: CanvasRenderingContext2D | null = null;\n let imgData: ImageData | null = null;\n let domeConstants: DomeConstants | null = null;\n let cachedDomeDepth = -Infinity;\n let cachedHalfW = -Infinity;\n let cachedHalfH = -Infinity;\n let xLookup: Float32Array | null = null;\n let cachedF = 0;\n let dirtyDome = true;\n\n return {\n /**\n * Generate a new displacement map and return a PNG data URL.\n * Reuses internal canvas memory; safe to call every animation frame.\n */\n generate(input: MapGeneratorInput): MapGeneratorOutput {\n if (!canvas) {\n canvas = document.createElement(\"canvas\");\n canvas.width = mapSize;\n canvas.height = mapSize;\n ctx = canvas.getContext(\"2d\")!;\n imgData = ctx.createImageData(mapSize, mapSize);\n }\n\n const {\n lensHalfWidth: x,\n lensHalfHeight: y,\n borderRadius: b,\n depth: M,\n sdfBoundary: R,\n edgeFalloff: S,\n specularRotation: w = 45,\n glowStrength: A = 0,\n glowSpread: v = 1,\n glowExponent: E = 1.5,\n edgeStrength: $ = 0,\n edgeWidth: C = 3,\n edgeExponent: k = 1.5,\n domeDepth: j = 0,\n splayAmount: I = 1,\n } = input;\n\n const T = imgData!.data;\n const F = mapSize >> 1; // half-size\n const D = Math.min(b, Math.min(x, y));\n const L = Math.max(0, x - M);\n const B = Math.max(0, y - M);\n const H = Math.max(0, Math.min(b, Math.min(L, B)));\n const O = M > 0 ? 1 / (M * Math.SQRT2) : 1e6;\n const hasSpecular = A > 0 || $ > 0;\n const W = (w * Math.PI) / 180;\n const U = Math.cos(W);\n const G = Math.sin(W);\n const N = (1 - v) * Math.SQRT2;\n const q = v * Math.SQRT2;\n const z = q > 0.001 ? 1 / q : 0;\n const Y = C > 0 ? 1 / C : 0;\n const X = (2 * x) / mapSize;\n const P = (2 * y) / mapSize;\n const V = 1 / x;\n const K = 1 / y;\n const hasDome = j > 0;\n const hasSplay = I < 1;\n\n if (hasDome) {\n if (\n !domeConstants ||\n Math.abs(j - cachedDomeDepth) > 0.5 ||\n Math.abs(x - cachedHalfW) > 1 ||\n Math.abs(y - cachedHalfH) > 1\n ) {\n domeConstants = computeDomeConstants(j, x, y);\n cachedDomeDepth = j;\n cachedHalfW = x;\n cachedHalfH = y;\n dirtyDome = true;\n }\n if (cachedF !== F) {\n xLookup = new Float32Array(F);\n cachedF = F;\n dirtyDome = true;\n }\n if (dirtyDome && xLookup && domeConstants) {\n const r2 = domeConstants.Rx * domeConstants.Rx;\n const clampVal = 0.999 * domeConstants.Rx;\n for (let col = 0; col < F; col++) {\n const ox = -((col + 0.5) * X - x);\n const clamped = ox < clampVal ? ox : clampVal;\n xLookup[col] =\n (clamped / Math.sqrt(r2 - clamped * clamped)) *\n domeConstants.scaleX;\n }\n dirtyDome = false;\n }\n }\n\n const domeX = hasDome ? xLookup : null;\n const minHalf = 0.5 * Math.min(x, y);\n const invMinHalf = minHalf > 0 ? 1 / minHalf : 0;\n const startTime = performance.now();\n\n // ── Top-left quadrant loop (mirrored into all 4 quadrants) ──────────\n for (let t = 0; t < F; t++) {\n const rowOpposite = mapSize - 1 - t;\n const oy = -((t + 0.5) * P - y);\n const iy = oy - y + D;\n const oSdfY = S ? oy - B + H : 0;\n const gy =\n hasDome && domeConstants\n ? domeGradient(oy, domeConstants.Ry, domeConstants.scaleY)\n : oy * K > 1\n ? 1\n : oy * K;\n const rawGy = oy * K > 1 ? 1 : oy * K;\n const splayY = hasSplay ? Math.max(0, 1 - (y - oy) * invMinHalf) : 0;\n\n for (let n = 0; n < F; n++) {\n const colOpposite = mapSize - 1 - n;\n const ox = -((n + 0.5) * X - x);\n const ix = ox - x + D;\n\n // SDF of rounded rectangle\n const gxMax = ix > 0 ? ix : 0;\n const gyMax = iy > 0 ? iy : 0;\n const dist2 = gxMax * gxMax + gyMax * gyMax;\n const sdf =\n (dist2 > 0 ? Math.sqrt(dist2) : 0) +\n (ix > iy ? (ix > 0 ? 0 : ix) : iy > 0 ? 0 : iy) -\n D;\n\n // 4-way index addresses\n const idxTL = (t * mapSize + n) * 4;\n const idxTR = (t * mapSize + colOpposite) * 4;\n const idxBL = (rowOpposite * mapSize + n) * 4;\n const idxBR = (rowOpposite * mapSize + colOpposite) * 4;\n\n if (!R || sdf < 0) {\n let specTL = 128, specTR = 128, specBL = 128, specBR = 128;\n\n let curGx = domeX ? domeX[n] : ox * V > 1 ? 1 : ox * V;\n let curGy = gy;\n\n // Corner splay attenuation\n if (hasSplay) {\n const splayFac = 1 - I;\n const effY = splayY * splayFac;\n const effX = Math.max(0, 1 - (x - ox) * invMinHalf) * splayFac;\n if (effY > 0.001 || effX > 0.001) {\n const prevGx = curGx;\n const prevGy = curGy;\n curGx = prevGx * (1 - effY);\n curGy = prevGy * (1 - effX);\n const prevMag = Math.sqrt(prevGx * prevGx + prevGy * prevGy);\n const newMag = Math.sqrt(curGx * curGx + curGy * curGy);\n if (newMag > 0.001) {\n const norm = prevMag / newMag;\n curGx *= norm;\n curGy *= norm;\n }\n }\n }\n\n // erf edge falloff\n let falloff = 1;\n if (S) {\n const fx = ox - L + H;\n const fy = oSdfY;\n const mx = fx > 0 ? fx : 0;\n const my = fy > 0 ? fy : 0;\n const falloffSdf =\n Math.sqrt(mx * mx + my * my) +\n (fx > fy ? (fx > 0 ? 0 : fx) : fy > 0 ? 0 : fy) -\n H;\n falloff = 0.5 * (1 + erf(falloffSdf * O));\n }\n\n const hx = 0.5 * curGx * falloff;\n const hy = 0.5 * curGy * falloff;\n\n // Displacement channel encoding (neutral = 128)\n const rTL = ((0.5 + hx) * 255 + 0.5) | 0;\n const rTR = ((0.5 - hx) * 255 + 0.5) | 0;\n const gTL = ((0.5 + hy) * 255 + 0.5) | 0;\n const gBL = ((0.5 - hy) * 255 + 0.5) | 0;\n\n // Blue channel = specular highlight mask\n if (hasSpecular) {\n const rawGx = (ox * V > 1 ? 1 : ox * V) * U;\n const rawGyProj = rawGy * G;\n const dot1 = rawGx + rawGyProj;\n const dot2 = rawGx - rawGyProj;\n const absDot1 = dot1 < 0 ? -dot1 : dot1;\n const absDot2 = dot2 < 0 ? -dot2 : dot2;\n\n let edgeAtten = 0;\n if ($ > 0) {\n edgeAtten = sdf < 0 ? 1 + sdf * Y : 0;\n if (edgeAtten < 0) edgeAtten = 0;\n }\n\n let glow1 = 0, glow2 = 0;\n if (A > 0) {\n const s1 = (absDot1 - N) * z;\n glow1 += A * Math.pow(s1 < 0 ? 0 : s1 > 1 ? 1 : s1, E) * falloff;\n const s2 = (absDot2 - N) * z;\n glow2 += A * Math.pow(s2 < 0 ? 0 : s2 > 1 ? 1 : s2, E) * falloff;\n }\n if ($ > 0) {\n glow1 += $ * edgeAtten * Math.pow(absDot1, k);\n glow2 += $ * edgeAtten * Math.pow(absDot2, k);\n }\n if (glow1 > 1) glow1 = 1;\n if (glow2 > 1) glow2 = 1;\n\n specTL = (127 * glow1 + 128 + 0.5) | 0;\n specBR = (127 * glow1 + 128 + 0.5) | 0;\n specTR = (127 * glow2 + 128 + 0.5) | 0;\n specBL = (127 * glow2 + 128 + 0.5) | 0;\n }\n\n T[idxTL] = rTL; T[idxTL + 1] = gTL; T[idxTL + 2] = specTL; T[idxTL + 3] = 255;\n T[idxTR] = rTR; T[idxTR + 1] = gTL; T[idxTR + 2] = specTR; T[idxTR + 3] = 255;\n T[idxBL] = rTL; T[idxBL + 1] = gBL; T[idxBL + 2] = specBL; T[idxBL + 3] = 255;\n T[idxBR] = rTR; T[idxBR + 1] = gBL; T[idxBR + 2] = specBR; T[idxBR + 3] = 255;\n } else {\n // Outside lens — neutral (no displacement)\n for (const idx of [idxTL, idxTR, idxBL, idxBR]) {\n T[idx] = 128; T[idx + 1] = 128; T[idx + 2] = 128; T[idx + 3] = 255;\n }\n }\n }\n }\n\n const loopMs = performance.now() - startTime;\n ctx!.putImageData(imgData!, 0, 0);\n const encodeStart = performance.now();\n const dataUrl = canvas!.toDataURL();\n const encodeMs = performance.now() - encodeStart;\n\n return { dataUrl, loopMs, encodeMs };\n },\n\n /** Release canvas memory. Call in React cleanup (useEffect return). */\n dispose() {\n if (canvas) {\n canvas.width = 0;\n canvas.height = 0;\n canvas = null;\n }\n ctx = null;\n imgData = null;\n domeConstants = null;\n cachedDomeDepth = -Infinity;\n cachedHalfW = -Infinity;\n cachedHalfH = -Infinity;\n dirtyDome = true;\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Async displacement map generator (for static / resting lenses)\n// ---------------------------------------------------------------------------\n\n/**\n * Generates a displacement map asynchronously, processing 64 rows per\n * animation frame via `setTimeout(0)` to avoid blocking the main thread.\n *\n * Returns a Blob Object URL (PNG). Caller is responsible for calling\n * `URL.revokeObjectURL` when the Lens unmounts.\n *\n * Use for static lenses where the map does not need to update every frame.\n */\nexport async function generateDisplacementMapAsync(\n canvas: HTMLCanvasElement,\n params: {\n canvasSize: number;\n lensHalfWidth: number;\n lensHalfHeight: number;\n borderRadius: number;\n depth: number;\n sdfBoundary: boolean;\n edgeFalloff: boolean;\n specularRotation?: number;\n glowStrength?: number;\n glowSpread?: number;\n glowExponent?: number;\n edgeStrength?: number;\n edgeWidth?: number;\n edgeExponent?: number;\n domeDepth?: number;\n splayAmount?: number;\n }\n): Promise<string | null> {\n const {\n canvasSize: r,\n lensHalfWidth: n,\n lensHalfHeight: l,\n borderRadius: i,\n depth: o,\n sdfBoundary: u,\n edgeFalloff: c,\n specularRotation: f = 45,\n glowStrength: d = 0,\n glowSpread: g = 1,\n glowExponent: h = 1.5,\n edgeStrength: p = 0,\n edgeWidth: m = 3,\n edgeExponent: xx = 1.5,\n domeDepth: y = 0,\n splayAmount: bv = 1,\n } = params;\n\n canvas.width = r;\n canvas.height = r;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return null;\n\n const imgD = ctx.createImageData(r, r);\n const S = Math.min(i, Math.min(n, l));\n const w = Math.max(0, n - o);\n const A = Math.max(0, l - o);\n const v = Math.max(0, Math.min(i, Math.min(w, A)));\n const E = o > 0 ? 1 / (o * Math.SQRT2) : 1e6;\n const hasSpecular = d > 0 || p > 0;\n const C = (f * Math.PI) / 180;\n const k = Math.cos(C);\n const j = Math.sin(C);\n const II = (1 - g) * Math.SQRT2;\n const TT = g * Math.SQRT2;\n const F = y > 0 ? computeDomeConstants(y, n, l) : null;\n const D = bv < 1;\n const Lv = 0.5 * Math.min(n, l);\n const Bv = Lv > 0 ? 1 / Lv : 0;\n\n for (let rowBatch = 0; rowBatch < r; rowBatch += 64) {\n const endRow = Math.min(rowBatch + 64, r);\n for (let row = rowBatch; row < endRow; row++) {\n for (let col = 0; col < r; col++) {\n const idx = (row * r + col) * 4;\n const ox = ((col + 0.5) / r) * (2 * n) - n;\n const oy = ((row + 0.5) / r) * (2 * l) - l;\n const absX = Math.abs(ox);\n const absY = Math.abs(oy);\n\n const Mv = absX - n + S;\n const Cy = absY - l + S;\n const clampX = Math.max(Mv, 0);\n const clampY = Math.max(Cy, 0);\n const dist2 = clampX * clampX + clampY * clampY;\n const sdf =\n (dist2 > 0 ? Math.sqrt(dist2) : 0) +\n Math.min(Math.max(Mv, Cy), 0) -\n S;\n\n if (!u || sdf < 0) {\n let gx: number;\n let gy: number;\n if (F) {\n gx = Math.sign(ox) * domeGradient(absX, F.Rx, F.scaleX);\n gy = Math.sign(oy) * domeGradient(absY, F.Ry, F.scaleY);\n } else {\n gx = Math.max(-1, Math.min(1, ox / n));\n gy = Math.max(-1, Math.min(1, oy / l));\n }\n\n let effGx = gx;\n let effGy = gy;\n if (D) {\n const attenY = Math.max(0, 1 - (l - absY) * Bv) * (1 - bv);\n const attenX = Math.max(0, 1 - (n - absX) * Bv) * (1 - bv);\n if (attenY > 0.001 || attenX > 0.001) {\n const oldGx = effGx;\n const oldGy = effGy;\n effGx = oldGx * (1 - attenY);\n effGy = oldGy * (1 - attenX);\n const oldMag = Math.sqrt(oldGx * oldGx + oldGy * oldGy);\n const newMag = Math.sqrt(effGx * effGx + effGy * effGy);\n if (newMag > 0.001) {\n const norm = oldMag / newMag;\n effGx *= norm;\n effGy *= norm;\n }\n }\n }\n\n let falloff = 1;\n if (c) {\n const innerX = absX - w + v;\n const innerY = absY - A + v;\n const innerSdf =\n Math.sqrt(Math.max(innerX, 0) ** 2 + Math.max(innerY, 0) ** 2) +\n Math.min(Math.max(innerX, innerY), 0) -\n v;\n falloff = 0.5 * (1 + erf(innerSdf * E));\n }\n\n imgD.data[idx] = Math.round((0.5 - 0.5 * effGx * falloff) * 255);\n imgD.data[idx + 1] = Math.round((0.5 - 0.5 * effGy * falloff) * 255);\n\n if (hasSpecular) {\n const dot = Math.abs(\n Math.max(-1, Math.min(1, ox / n)) * k +\n Math.max(-1, Math.min(1, oy / l)) * j\n );\n let glow = 0;\n if (d > 0) {\n const spread =\n TT > 0.001 ? Math.min(1, Math.max(0, dot - II) / TT) : 0;\n glow += d * Math.pow(spread, h) * falloff;\n }\n if (p > 0) {\n const edgeVal = sdf < 0 ? Math.max(0, 1 + sdf / m) : 0;\n glow += p * edgeVal * Math.pow(dot, xx);\n }\n glow = Math.min(1, glow);\n imgD.data[idx + 2] = Math.round(127 * glow + 128);\n } else {\n imgD.data[idx + 2] = 128;\n }\n } else {\n imgD.data[idx] = 128;\n imgD.data[idx + 1] = 128;\n imgD.data[idx + 2] = 128;\n }\n imgD.data[idx + 3] = 255;\n }\n }\n if (rowBatch + 64 < r) {\n await new Promise((resolve) => setTimeout(resolve, 0));\n }\n }\n\n ctx.putImageData(imgD, 0, 0);\n const blob = await new Promise<Blob | null>((resolve) =>\n canvas.toBlob(resolve, \"image/png\")\n );\n return blob ? URL.createObjectURL(blob) : null;\n}\n","/**\n * lensfx — Vanilla DOM Engine: createLens\n *\n * Zero-dependency, pure DOM + SVG + Canvas optical glass refraction.\n * Runs anywhere without React, Framer Motion, or bundlers.\n */\n\nimport {\n createDisplacementMapGeneratorSync,\n colorMatrixValues,\n getSvgMaskDataUri,\n} from \"./engine/math\";\nimport { LensParams } from \"./engine/types\";\n\nexport interface LensOptions {\n /** Lens width in pixels. Default: 160 */\n width?: number;\n /** Alias for width */\n lensW?: number;\n /** Lens height in pixels. Default: 100 */\n height?: number;\n /** Alias for height */\n lensH?: number;\n /** Corner radius in pixels. Default: 24 */\n radius?: number;\n /** Alias for radius */\n borderRadius?: number;\n /** Lens center X: 0..1 (fraction of container width) or pixel value. Default: 0.5 */\n x?: number;\n /** Lens center Y: 0..1 (fraction of container height) or pixel value. Default: 0.5 */\n y?: number;\n /** Automatically track pointer / mouse movement over the container element. Default: false */\n interactive?: boolean;\n /** Refraction depth / distortion strength (0–10). Default: 2 */\n depth?: number;\n /** Chromatic aberration split (0–1). 0 = monochrome, 1 = full RGB split. Default: 0.6 */\n chroma?: number;\n /** Alias for chroma */\n chromaAmount?: number;\n /** Aspect-ratio displacement scale X (0–1). Default: 0.25 */\n scaleX?: number;\n /** Aspect-ratio displacement scale Y (0–1). Default: 0.25 */\n scaleY?: number;\n /** Ellipsoid dome height in pixels. Default: 6 */\n domeDepth?: number;\n /** Directional specular angle in degrees. Default: 45 */\n specularRotation?: number;\n /** Specular highlight intensity. Default: 1 */\n specularStrength?: number;\n /** Invert specular to dark shadow mode. Default: false */\n specularDark?: boolean;\n /** Clip refraction strictly to the lens SDF boundary. Default: true */\n sdfBoundary?: boolean;\n /** Apply erf-smoothed edge falloff. Default: true */\n edgeFalloff?: boolean;\n /** Glow intensity (0–1). Default: 0.3 */\n glowStrength?: number;\n /** Glow spread factor (0–1). Default: 1 */\n glowSpread?: number;\n /** Glow falloff exponent. Default: 1.5 */\n glowExponent?: number;\n /** Edge ring highlight intensity (0–1). Default: 0.4 */\n edgeStrength?: number;\n /** Edge ring highlight width in pixels. Default: 3 */\n edgeWidth?: number;\n /** Splay attenuation factor at corners (0–1). Default: 0.8 */\n splayAmount?: number;\n /** Frosted glass blur radius in pixels. Default: 0 */\n blur?: number;\n /** Tint color CSS string (e.g. \"rgba(255, 255, 255, 0.08)\"). Default: \"rgba(255, 255, 255, 0.05)\" */\n tintColor?: string;\n /** Tint backdrop blur in pixels. Default: 0 */\n tintBlur?: number;\n /** Tint opacity (0–1). Default: 1 */\n tintOpacity?: number;\n /** Lens rim shadow (boolean or custom CSS box-shadow string). Default: true */\n shadow?: boolean | string;\n /** Lens rim border (boolean or custom CSS border string). Default: true */\n border?: boolean | string;\n /** Displacement map resolution in pixels. Default: 256 */\n mapSize?: number;\n /** Pre-rendered displacement map data URL. */\n displacementMapUrl?: string;\n /** Alternative element / selector to apply the filter to instead of container */\n refractionTarget?: HTMLElement | string;\n /** Callback fired when displacement map data URL changes */\n onMapChange?: (url: string) => void;\n /** Callback fired when lens position changes */\n onPositionChange?: (x: number, y: number) => void;\n}\n\nexport interface LensInstance {\n /** The container element */\n el: HTMLElement;\n /** The element receiving the SVG displacement filter */\n targetEl: HTMLElement;\n /** The hidden SVG root element housing the filter defs */\n svgEl: SVGSVGElement;\n /** The SVG filter element */\n filterEl: SVGFilterElement;\n /** The floating lens overlay element (rim lighting, border, tint) */\n overlayEl: HTMLElement;\n /** Current active options */\n options: LensOptions;\n /** Current displacement map data URL */\n mapDataUrl: string;\n /** Move lens to new x, y position (pixel or 0..1 normalized) */\n setPosition: (x: number, y: number) => void;\n /** Update lens options dynamically */\n update: (newOptions: Partial<LensOptions>) => void;\n /** Toggle interactive mouse/pointer tracking */\n setInteractive: (interactive: boolean) => void;\n /** Destroy the lens and restore all DOM modifications */\n destroy: () => void;\n}\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n\nlet nextId = 0;\n\n/**\n * Creates a real optical glass refraction lens on any DOM element.\n *\n * @param target - Target container element or CSS selector string\n * @param options - Optical and behavioral options\n * @returns LensInstance with control methods (setPosition, update, destroy)\n *\n * @example\n * ```js\n * const lens = lensfx.createLens(document.querySelector(\"#card\"), {\n * width: 200,\n * height: 120,\n * radius: 28,\n * interactive: true,\n * });\n * ```\n */\nexport function createLens(\n target: HTMLElement | string,\n options: LensOptions = {}\n): LensInstance {\n if (typeof document === \"undefined\") {\n throw new Error(\"[lensfx] createLens can only be called in a browser environment.\");\n }\n\n const resolved =\n typeof target === \"string\" ? document.querySelector<HTMLElement>(target) : target;\n if (!resolved) {\n throw new Error(`[lensfx] Target element \"${target}\" was not found.`);\n }\n const container: HTMLElement = resolved;\n\n let currentOptions: LensOptions = { ...options };\n\n // Resolve refraction target element\n let targetEl: HTMLElement = container;\n if (currentOptions.refractionTarget) {\n const customTarget =\n typeof currentOptions.refractionTarget === \"string\"\n ? container.querySelector<HTMLElement>(currentOptions.refractionTarget) ||\n document.querySelector<HTMLElement>(currentOptions.refractionTarget)\n : currentOptions.refractionTarget;\n if (customTarget) {\n targetEl = customTarget;\n }\n }\n\n // Ensure container can anchor absolute children\n const computedStyle = window.getComputedStyle(container);\n const originalPosition = container.style.position;\n if (computedStyle.position === \"static\") {\n container.style.position = \"relative\";\n }\n\n const lensId = `lensfx-${++nextId}-${Math.random().toString(36).substring(2, 7)}`;\n const filterId = `${lensId}-filter`;\n\n // Create SVG defs container\n const svgEl = document.createElementNS(SVG_NS, \"svg\") as SVGSVGElement;\n svgEl.setAttribute(\"class\", \"lensfx-svg-root\");\n svgEl.setAttribute(\"aria-hidden\", \"true\");\n svgEl.style.cssText =\n \"position:absolute;width:0;height:0;overflow:hidden;pointer-events:none;left:0;top:0;\";\n\n const defsEl = document.createElementNS(SVG_NS, \"defs\");\n const filterEl = document.createElementNS(SVG_NS, \"filter\") as SVGFilterElement;\n filterEl.id = filterId;\n filterEl.setAttribute(\"filterUnits\", \"objectBoundingBox\");\n filterEl.setAttribute(\"primitiveUnits\", \"objectBoundingBox\");\n filterEl.setAttribute(\"color-interpolation-filters\", \"sRGB\");\n filterEl.setAttribute(\"x\", \"0\");\n filterEl.setAttribute(\"y\", \"0\");\n filterEl.setAttribute(\"width\", \"1\");\n filterEl.setAttribute(\"height\", \"1\");\n\n defsEl.appendChild(filterEl);\n svgEl.appendChild(defsEl);\n container.appendChild(svgEl);\n\n // Create floating lens rim overlay\n const overlayEl = document.createElement(\"div\");\n overlayEl.className = \"lensfx-lens-overlay\";\n overlayEl.style.cssText =\n \"position:absolute;top:0;left:0;pointer-events:none;box-sizing:border-box;will-change:transform;\";\n container.appendChild(overlayEl);\n\n // State variables\n let mapDataUrl = currentOptions.displacementMapUrl || \"\";\n let currentMapSize = currentOptions.mapSize || 256;\n let generator = createDisplacementMapGeneratorSync(currentMapSize);\n let feImageEl: SVGFEImageElement | null = null;\n let currentMaskKey: string | null = null;\n let isDestroyed = false;\n\n // Track coordinates\n let curX = currentOptions.x ?? 0.5;\n let curY = currentOptions.y ?? 0.5;\n\n function getDimensions() {\n const width = currentOptions.width ?? currentOptions.lensW ?? 160;\n const height = currentOptions.height ?? currentOptions.lensH ?? 100;\n const radius =\n currentOptions.radius ?? currentOptions.borderRadius ?? Math.min(width, height) / 4;\n return { width, height, radius };\n }\n\n function renderMap() {\n if (isDestroyed) return;\n if (currentOptions.displacementMapUrl) {\n mapDataUrl = currentOptions.displacementMapUrl;\n if (feImageEl) feImageEl.setAttribute(\"href\", mapDataUrl);\n currentOptions.onMapChange?.(mapDataUrl);\n return;\n }\n\n const { width, height, radius } = getDimensions();\n const mapSize = currentOptions.mapSize || 256;\n if (mapSize !== currentMapSize) {\n generator.dispose();\n currentMapSize = mapSize;\n generator = createDisplacementMapGeneratorSync(currentMapSize);\n }\n\n const depth = currentOptions.depth ?? 2;\n const result = generator.generate({\n lensHalfWidth: width / 2,\n lensHalfHeight: height / 2,\n borderRadius: radius,\n depth,\n sdfBoundary: currentOptions.sdfBoundary ?? true,\n edgeFalloff: currentOptions.edgeFalloff ?? true,\n specularRotation: currentOptions.specularRotation ?? 45,\n glowStrength: currentOptions.glowStrength ?? 0.3,\n glowSpread: currentOptions.glowSpread ?? 1,\n glowExponent: currentOptions.glowExponent ?? 1.5,\n edgeStrength: currentOptions.edgeStrength ?? 0.4,\n edgeWidth: currentOptions.edgeWidth ?? 3,\n edgeExponent: 1.5,\n domeDepth: currentOptions.domeDepth ?? 6,\n splayAmount: currentOptions.splayAmount ?? 0.8,\n });\n\n mapDataUrl = result.dataUrl;\n if (feImageEl) feImageEl.setAttribute(\"href\", mapDataUrl);\n currentOptions.onMapChange?.(mapDataUrl);\n }\n\n function buildFilterPipeline() {\n // Clear existing filter children\n while (filterEl.firstChild) {\n filterEl.removeChild(filterEl.firstChild);\n }\n\n const depth = currentOptions.depth ?? 2;\n const chroma = currentOptions.chroma ?? currentOptions.chromaAmount ?? 0.6;\n const scaleX = currentOptions.scaleX ?? 0.25;\n const scaleY = currentOptions.scaleY ?? 0.25;\n const maxScale = Math.max(scaleX, scaleY);\n const scaleRatioX = maxScale > 0 ? scaleX / maxScale : 0;\n const scaleRatioY = maxScale > 0 ? scaleY / maxScale : 0;\n const needsMatrix = scaleRatioX !== 1 || scaleRatioY !== 1;\n const matrixString = colorMatrixValues(scaleRatioX, scaleRatioY);\n\n // 1. Neutral gray background\n const feFlood = document.createElementNS(SVG_NS, \"feFlood\");\n feFlood.setAttribute(\"flood-color\", \"rgb(128,128,128)\");\n feFlood.setAttribute(\"flood-opacity\", \"1\");\n feFlood.setAttribute(\"result\", \"mapBg\");\n filterEl.appendChild(feFlood);\n\n // 2. Displacement map image\n feImageEl = document.createElementNS(SVG_NS, \"feImage\") as SVGFEImageElement;\n feImageEl.setAttribute(\"href\", mapDataUrl);\n feImageEl.setAttribute(\"preserveAspectRatio\", \"none\");\n feImageEl.setAttribute(\"result\", \"rawMap\");\n filterEl.appendChild(feImageEl);\n\n // 3. Composite over neutral gray\n const feComp = document.createElementNS(SVG_NS, \"feComposite\");\n feComp.setAttribute(\"in\", \"rawMap\");\n feComp.setAttribute(\"in2\", \"mapBg\");\n feComp.setAttribute(\"operator\", \"over\");\n feComp.setAttribute(\"result\", \"map\");\n filterEl.appendChild(feComp);\n\n // 4. ColorMatrix for aspect ratio scaling if needed\n if (needsMatrix) {\n const feMat = document.createElementNS(SVG_NS, \"feColorMatrix\");\n feMat.setAttribute(\"in\", \"map\");\n feMat.setAttribute(\"type\", \"matrix\");\n feMat.setAttribute(\"values\", matrixString);\n feMat.setAttribute(\"result\", \"scaledMap\");\n filterEl.appendChild(feMat);\n }\n const mapSource = needsMatrix ? \"scaledMap\" : \"map\";\n\n // 5. Gaussian blur for frosted glass\n let sourceGraphic = \"SourceGraphic\";\n if (currentOptions.blur && currentOptions.blur > 0) {\n const feBlur = document.createElementNS(SVG_NS, \"feGaussianBlur\");\n feBlur.setAttribute(\"in\", \"SourceGraphic\");\n const cRect = container.getBoundingClientRect();\n const bw = cRect.width > 0 ? currentOptions.blur / cRect.width : 0.01;\n const bh = cRect.height > 0 ? currentOptions.blur / cRect.height : 0.01;\n feBlur.setAttribute(\"stdDeviation\", `${bw} ${bh}`);\n feBlur.setAttribute(\"result\", \"blurred\");\n filterEl.appendChild(feBlur);\n sourceGraphic = \"blurred\";\n }\n\n // 6. Displacement mapping\n if (chroma > 0) {\n // Red\n const dispR = document.createElementNS(SVG_NS, \"feDisplacementMap\");\n dispR.setAttribute(\"in\", sourceGraphic);\n dispR.setAttribute(\"in2\", mapSource);\n dispR.setAttribute(\"scale\", String(maxScale * (1 + 0.2 * chroma)));\n dispR.setAttribute(\"xChannelSelector\", \"R\");\n dispR.setAttribute(\"yChannelSelector\", \"G\");\n filterEl.appendChild(dispR);\n\n const matR = document.createElementNS(SVG_NS, \"feColorMatrix\");\n matR.setAttribute(\"type\", \"matrix\");\n matR.setAttribute(\"values\", \"1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0\");\n matR.setAttribute(\"result\", \"dispR\");\n filterEl.appendChild(matR);\n\n // Green\n const dispG = document.createElementNS(SVG_NS, \"feDisplacementMap\");\n dispG.setAttribute(\"in\", sourceGraphic);\n dispG.setAttribute(\"in2\", mapSource);\n dispG.setAttribute(\"scale\", String(maxScale * (1 + 0.1 * chroma)));\n dispG.setAttribute(\"xChannelSelector\", \"R\");\n dispG.setAttribute(\"yChannelSelector\", \"G\");\n filterEl.appendChild(dispG);\n\n const matG = document.createElementNS(SVG_NS, \"feColorMatrix\");\n matG.setAttribute(\"type\", \"matrix\");\n matG.setAttribute(\"values\", \"0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0\");\n matG.setAttribute(\"result\", \"dispG\");\n filterEl.appendChild(matG);\n\n // Blue\n const dispB = document.createElementNS(SVG_NS, \"feDisplacementMap\");\n dispB.setAttribute(\"in\", sourceGraphic);\n dispB.setAttribute(\"in2\", mapSource);\n dispB.setAttribute(\"scale\", String(maxScale));\n dispB.setAttribute(\"xChannelSelector\", \"R\");\n dispB.setAttribute(\"yChannelSelector\", \"G\");\n filterEl.appendChild(dispB);\n\n const matB = document.createElementNS(SVG_NS, \"feColorMatrix\");\n matB.setAttribute(\"type\", \"matrix\");\n matB.setAttribute(\"values\", \"0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0\");\n matB.setAttribute(\"result\", \"dispB\");\n filterEl.appendChild(matB);\n\n // Composite R + G\n const compRG = document.createElementNS(SVG_NS, \"feComposite\");\n compRG.setAttribute(\"in\", \"dispR\");\n compRG.setAttribute(\"in2\", \"dispG\");\n compRG.setAttribute(\"operator\", \"arithmetic\");\n compRG.setAttribute(\"k1\", \"0\");\n compRG.setAttribute(\"k2\", \"1\");\n compRG.setAttribute(\"k3\", \"1\");\n compRG.setAttribute(\"k4\", \"0\");\n filterEl.appendChild(compRG);\n\n // Composite with B\n const compRGB = document.createElementNS(SVG_NS, \"feComposite\");\n compRGB.setAttribute(\"in2\", \"dispB\");\n compRGB.setAttribute(\"operator\", \"arithmetic\");\n compRGB.setAttribute(\"k1\", \"0\");\n compRGB.setAttribute(\"k2\", \"1\");\n compRGB.setAttribute(\"k3\", \"1\");\n compRGB.setAttribute(\"k4\", \"0\");\n compRGB.setAttribute(\"result\", \"lensResult\");\n filterEl.appendChild(compRGB);\n } else {\n const dispSingle = document.createElementNS(SVG_NS, \"feDisplacementMap\");\n dispSingle.setAttribute(\"in\", sourceGraphic);\n dispSingle.setAttribute(\"in2\", mapSource);\n dispSingle.setAttribute(\"scale\", String(maxScale));\n dispSingle.setAttribute(\"xChannelSelector\", \"R\");\n dispSingle.setAttribute(\"yChannelSelector\", \"G\");\n dispSingle.setAttribute(\"result\", \"lensResult\");\n filterEl.appendChild(dispSingle);\n }\n\n // 7. Specular highlight\n const specStrength = currentOptions.specularStrength ?? 1;\n if (specStrength > 0) {\n const specMat = document.createElementNS(SVG_NS, \"feColorMatrix\");\n specMat.setAttribute(\"in\", \"map\");\n specMat.setAttribute(\"type\", \"matrix\");\n specMat.setAttribute(\"values\", \"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 1 0 -0.50196\");\n specMat.setAttribute(\"result\", \"specMask\");\n filterEl.appendChild(specMat);\n\n const specComp = document.createElementNS(SVG_NS, \"feComposite\");\n specComp.setAttribute(\"in\", \"specMask\");\n specComp.setAttribute(\"in2\", \"lensResult\");\n specComp.setAttribute(\"operator\", \"arithmetic\");\n specComp.setAttribute(\"k1\", \"0\");\n specComp.setAttribute(\"k2\", String(specStrength));\n specComp.setAttribute(\"k3\", \"1\");\n specComp.setAttribute(\"k4\", \"0\");\n specComp.setAttribute(\"result\", \"lensResult\");\n filterEl.appendChild(specComp);\n }\n\n // 8. Cut hole and composite over SourceGraphic\n const lensMask = document.createElementNS(SVG_NS, \"feFlood\");\n lensMask.setAttribute(\"flood-color\", \"black\");\n lensMask.setAttribute(\"flood-opacity\", \"1\");\n lensMask.setAttribute(\"result\", \"lensMask\");\n filterEl.appendChild(lensMask);\n\n const holeComp = document.createElementNS(SVG_NS, \"feComposite\");\n holeComp.setAttribute(\"in\", \"SourceGraphic\");\n holeComp.setAttribute(\"in2\", \"lensMask\");\n holeComp.setAttribute(\"operator\", \"out\");\n holeComp.setAttribute(\"result\", \"holedSG\");\n filterEl.appendChild(holeComp);\n\n const finalComp = document.createElementNS(SVG_NS, \"feComposite\");\n finalComp.setAttribute(\"in\", \"lensResult\");\n finalComp.setAttribute(\"in2\", \"holedSG\");\n finalComp.setAttribute(\"operator\", \"over\");\n filterEl.appendChild(finalComp);\n }\n\n function updateLayout() {\n if (isDestroyed) return;\n const rect = container.getBoundingClientRect();\n const cw = rect.width || container.clientWidth || 300;\n const ch = rect.height || container.clientHeight || 200;\n\n const { width, height, radius } = getDimensions();\n\n const px = curX <= 1 && curX >= 0 ? curX * cw : curX;\n const py = curY <= 1 && curY >= 0 ? curY * ch : pyCoordinate(curY, ch);\n\n function pyCoordinate(val: number, containerH: number) {\n return val <= 1 && val >= 0 ? val * containerH : val;\n }\n\n const lensLeft = px - width / 2;\n const lensTop = py - height / 2;\n\n // Update feImage placement in normalized 0..1 bounding box coordinates\n if (feImageEl && cw > 0 && ch > 0) {\n feImageEl.setAttribute(\"x\", String(lensLeft / cw));\n feImageEl.setAttribute(\"y\", String(lensTop / ch));\n feImageEl.setAttribute(\"width\", String(width / cw));\n feImageEl.setAttribute(\"height\", String(height / ch));\n }\n\n // Update overlay layer styles\n overlayEl.style.width = `${width}px`;\n overlayEl.style.height = `${height}px`;\n overlayEl.style.borderRadius = `${radius}px`;\n overlayEl.style.transform = `translate3d(${lensLeft}px, ${lensTop}px, 0)`;\n\n // Shadow\n if (currentOptions.shadow === false) {\n overlayEl.style.boxShadow = \"none\";\n } else if (typeof currentOptions.shadow === \"string\") {\n overlayEl.style.boxShadow = currentOptions.shadow;\n } else {\n overlayEl.style.boxShadow =\n \"0 8px 32px rgba(0, 0, 0, 0.2), 0 2px 8px rgba(0, 0, 0, 0.12), inset 0 1px 1px rgba(255, 255, 255, 0.35), inset 0 -1px 1px rgba(0, 0, 0, 0.15)\";\n }\n\n // Border\n if (currentOptions.border === false) {\n overlayEl.style.border = \"none\";\n } else if (typeof currentOptions.border === \"string\") {\n overlayEl.style.border = currentOptions.border;\n } else {\n overlayEl.style.border = \"1px solid rgba(255, 255, 255, 0.2)\";\n }\n\n // Tint & backdrop-filter\n const tintColor = currentOptions.tintColor ?? \"rgba(255, 255, 255, 0.05)\";\n overlayEl.style.background = tintColor;\n\n const tintBlur = currentOptions.tintBlur ?? 0;\n if (tintBlur > 0) {\n const blurCss = `blur(${tintBlur}px)`;\n overlayEl.style.backdropFilter = blurCss;\n overlayEl.style.setProperty(\"-webkit-backdrop-filter\", blurCss);\n } else {\n overlayEl.style.backdropFilter = \"none\";\n overlayEl.style.setProperty(\"-webkit-backdrop-filter\", \"none\");\n }\n\n // Apply SVG mask for crisp rounded edges\n const { uri, key } = getSvgMaskDataUri(width, height, radius);\n if (currentMaskKey !== key) {\n const maskCss = `url(\"${uri}\")`;\n overlayEl.style.maskImage = maskCss;\n overlayEl.style.setProperty(\"-webkit-mask-image\", maskCss);\n overlayEl.style.maskSize = \"100% 100%\";\n overlayEl.style.setProperty(\"-webkit-mask-size\", \"100% 100%\");\n currentMaskKey = key;\n }\n\n // Ensure filter is applied to target element\n const filterStyle = `url(\"#${filterId}\")`;\n if (targetEl.style.filter !== filterStyle) {\n targetEl.style.filter = filterStyle;\n }\n }\n\n // Pointer event handler for interactive mode\n let isPointerActive = false;\n const onPointerMove = (e: PointerEvent) => {\n if (!currentOptions.interactive || isDestroyed) return;\n const rect = container.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n setPosition(x, y);\n };\n\n function setInteractive(interactive: boolean) {\n currentOptions.interactive = interactive;\n if (interactive && !isPointerActive) {\n container.addEventListener(\"pointermove\", onPointerMove);\n isPointerActive = true;\n } else if (!interactive && isPointerActive) {\n container.removeEventListener(\"pointermove\", onPointerMove);\n isPointerActive = false;\n }\n }\n\n function setPosition(x: number, y: number) {\n curX = x;\n curY = y;\n currentOptions.onPositionChange?.(x, y);\n updateLayout();\n }\n\n function update(newOptions: Partial<LensOptions>) {\n if (isDestroyed) return;\n const prev = { ...currentOptions };\n currentOptions = { ...currentOptions, ...newOptions };\n\n if (newOptions.x !== undefined) curX = newOptions.x;\n if (newOptions.y !== undefined) curY = newOptions.y;\n\n if (newOptions.interactive !== undefined) {\n setInteractive(newOptions.interactive);\n }\n\n // Check if map needs regeneration\n const needsRegen =\n newOptions.width !== undefined ||\n newOptions.lensW !== undefined ||\n newOptions.height !== undefined ||\n newOptions.lensH !== undefined ||\n newOptions.radius !== undefined ||\n newOptions.borderRadius !== undefined ||\n newOptions.depth !== undefined ||\n newOptions.domeDepth !== undefined ||\n newOptions.specularRotation !== undefined ||\n newOptions.glowStrength !== undefined ||\n newOptions.glowSpread !== undefined ||\n newOptions.edgeStrength !== undefined ||\n newOptions.edgeWidth !== undefined ||\n newOptions.splayAmount !== undefined ||\n newOptions.displacementMapUrl !== undefined ||\n newOptions.mapSize !== undefined;\n\n if (needsRegen) {\n renderMap();\n }\n\n // Check if filter pipeline structure changed\n const needsPipelineRebuild =\n newOptions.chroma !== undefined ||\n newOptions.chromaAmount !== undefined ||\n newOptions.scaleX !== undefined ||\n newOptions.scaleY !== undefined ||\n newOptions.specularStrength !== undefined ||\n newOptions.blur !== undefined;\n\n if (needsPipelineRebuild || needsRegen) {\n buildFilterPipeline();\n }\n\n updateLayout();\n }\n\n // Setup ResizeObserver for responsive layout updates\n let resizeObserver: ResizeObserver | null = null;\n if (typeof ResizeObserver !== \"undefined\") {\n resizeObserver = new ResizeObserver(() => {\n updateLayout();\n });\n resizeObserver.observe(container);\n }\n\n // Initial build\n renderMap();\n buildFilterPipeline();\n updateLayout();\n\n if (currentOptions.interactive) {\n setInteractive(true);\n }\n\n function destroy() {\n if (isDestroyed) return;\n isDestroyed = true;\n\n if (isPointerActive) {\n container.removeEventListener(\"pointermove\", onPointerMove);\n isPointerActive = false;\n }\n\n if (resizeObserver) {\n resizeObserver.disconnect();\n resizeObserver = null;\n }\n\n if (targetEl.style.filter.includes(filterId)) {\n targetEl.style.filter = \"\";\n }\n\n if (container.style.position === \"relative\" && originalPosition === \"\") {\n container.style.position = \"\";\n }\n\n if (svgEl.parentNode) {\n svgEl.parentNode.removeChild(svgEl);\n }\n\n if (overlayEl.parentNode) {\n overlayEl.parentNode.removeChild(overlayEl);\n }\n\n generator.dispose();\n }\n\n return {\n el: container,\n targetEl,\n svgEl,\n filterEl,\n overlayEl,\n get options() {\n return currentOptions;\n },\n get mapDataUrl() {\n return mapDataUrl;\n },\n setPosition,\n update,\n setInteractive,\n destroy,\n };\n}\n","/**\n * lensfx — Engine Layer: Types & Constants\n *\n * Pure TypeScript — no React, no DOM. Can be imported in any environment.\n */\n\n// ---------------------------------------------------------------------------\n// Core lens parameter interface\n// ---------------------------------------------------------------------------\n\n/** All optical parameters that control how a single lens looks and distorts. */\nexport interface LensParams {\n /** Lens width in pixels. */\n lensW: number;\n /** Lens height in pixels. */\n lensH: number;\n /** Lens corner radius in pixels. */\n borderRadius: number;\n /** Refraction depth/strength — higher = more distortion. Range: 0–10. */\n depth: number;\n /** Chromatic aberration split amount. 0 = monochromatic, 1 = full RGB split. */\n chromaAmount: number;\n /** Horizontal displacement scale. 0 = no lateral displacement. */\n scaleX: number;\n /** Vertical displacement scale. 0 = no vertical displacement. */\n scaleY: number;\n /** Resolution of the displacement map canvas (power-of-two recommended). */\n mapSize: number;\n /** Gaussian blur radius applied to the background behind the lens (px). */\n blurAmount: number;\n /** If true, clips displacement strictly to the lens SDF boundary. */\n sdfBoundary: boolean;\n /** If true, applies an erf-smoothed falloff at the lens edge. */\n edgeFalloff: boolean;\n /** Additive brightness overlay inside the lens. Positive = lighter, negative = darker. Range: -1 to 1. */\n brightness: number;\n /** Intensity of the specular highlight. Range: 0–3. */\n specularStrength: number;\n /** Angle of the specular directional light in degrees. */\n specularRotation: number;\n /** If true, uses dark (shadow) specular mode instead of bright. */\n specularDark: boolean;\n /** Uniform tint applied inside the lens. Range: -1 (black) to 1 (white). */\n tint: number;\n /** Strength of the inner glow band. Range: 0–1. */\n glowStrength: number;\n /** Angular spread of the glow band, normalised. Range: 0–1. */\n glowSpread: number;\n /** Exponent controlling glow falloff curve. Higher = sharper band. */\n glowExponent: number;\n /** Strength of the edge specular ring (separate from inner glow). Range: 0–1. */\n edgeStrength: number;\n /** Thickness of the edge specular ring in pixels. */\n edgeWidth: number;\n /** Exponent controlling edge ring falloff curve. */\n edgeExponent: number;\n /** Height of the ellipsoid dome above the lens surface in pixels. */\n domeDepth: number;\n /** How much to reduce displacement magnitude at corners (0 = no splay, 1 = full splay). */\n splayAmount: number;\n /** Box shadow applied to the lens container (outer drop shadow). */\n edgeShadow?: string;\n /** Inset box shadow applied to the lens container. */\n edgeInsetShadow?: string;\n /** Secondary rest-state shadow (e.g. when the slider thumb is at rest). */\n restEdgeShadow?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Internal engine types\n// ---------------------------------------------------------------------------\n\n/** Precomputed geometric constants for dome curvature. */\nexport interface DomeConstants {\n /** Horizontal sphere radius for dome curvature. */\n Rx: number;\n /** Vertical sphere radius for dome curvature. */\n Ry: number;\n /** Normalised scale factor for the X gradient (trapezoidal integration). */\n scaleX: number;\n /** Normalised scale factor for the Y gradient (trapezoidal integration). */\n scaleY: number;\n}\n\n/** Input to the synchronous displacement map generator. */\nexport interface MapGeneratorInput {\n lensHalfWidth: number;\n lensHalfHeight: number;\n borderRadius: number;\n depth: number;\n sdfBoundary: boolean;\n edgeFalloff: boolean;\n specularRotation: number;\n glowStrength: number;\n glowSpread: number;\n glowExponent: number;\n edgeStrength: number;\n edgeWidth: number;\n edgeExponent: number;\n domeDepth: number;\n splayAmount: number;\n}\n\n/** Output from the displacement map generator. */\nexport interface MapGeneratorOutput {\n /** PNG data URL of the generated displacement map. */\n dataUrl: string;\n /** Time taken for the pixel loop, in milliseconds. */\n loopMs: number;\n /** Time taken for canvas.toDataURL encoding, in milliseconds. */\n encodeMs: number;\n}\n\n// Internal SVG filter pooling types (not exposed in public API)\nexport interface MultiLensSlot {\n filterEl: SVGFilterElement | null;\n feDispEl: SVGFEDisplacementMapElement | null;\n subSlots: SubSlot[];\n assignedTo: HTMLElement | null;\n version: number;\n lastDispScale: string;\n lastFilterW: string;\n lastFilterH: string;\n}\n\nexport interface SubSlot {\n feImageEl: SVGFEImageElement | null;\n feColorMatrixEl: SVGFEColorMatrixElement | null;\n feMaskEl: SVGFEImageElement | null;\n feMaskColorMatrixEl: SVGFEColorMatrixElement | null;\n assignedLensId: string | null;\n lastHref: string;\n lastX: string;\n lastY: string;\n lastW: string;\n lastH: string;\n lastColorMatrix: string;\n lastMaskKey: string;\n lastMaskColorMatrix: string;\n}\n\nexport interface SingleLensSlot {\n filterEl: SVGFilterElement | null;\n lensEls: SVGElement[];\n dispEls: SVGFEDisplacementMapElement[];\n mapMatrixEl: SVGFEColorMatrixElement | null;\n feImageEl: SVGFEImageElement | null;\n version: number;\n assignedTo: HTMLElement | null;\n assignedRect: DOMRect | null;\n}\n\n// ---------------------------------------------------------------------------\n// Default parameter sets — calibrated baseline optical parameters\n// ---------------------------------------------------------------------------\n\n/** Zero-refraction baseline — all effects disabled. */\nexport const DEFAULT_LENS_PARAMS: LensParams = {\n lensW: 90,\n lensH: 60,\n depth: 0,\n chromaAmount: 0,\n scaleX: 0,\n scaleY: 0,\n mapSize: 256,\n borderRadius: 0,\n blurAmount: 0,\n sdfBoundary: false,\n edgeFalloff: false,\n brightness: 0,\n specularStrength: 0,\n specularRotation: 0,\n glowStrength: 0,\n glowSpread: 1,\n glowExponent: 1.5,\n tint: 0,\n edgeStrength: 0,\n edgeWidth: 3,\n edgeExponent: 1.5,\n specularDark: false,\n domeDepth: 0,\n splayAmount: 0,\n};\n\n/** Selector strings used by Lens to find refraction containers & targets. */\nexport const LENSFX_SELECTORS = {\n container: \"[data-lensfx-container]\",\n target: \"[data-lensfx-target]\",\n} as const;\n\n// ---------------------------------------------------------------------------\n// Component-specific presets\n// ---------------------------------------------------------------------------\n\n/** LensSwitch base optical parameters. */\nexport const SWITCH_GLASS_DEFAULTS: Partial<LensParams> = {\n lensW: 90,\n lensH: 60,\n borderRadius: 30,\n mapSize: 256,\n depth: 2,\n chromaAmount: 1,\n scaleX: 0.25,\n scaleY: 0.25,\n sdfBoundary: true,\n edgeFalloff: true,\n domeDepth: 6,\n splayAmount: 0.4,\n blurAmount: 0,\n brightness: 0.06,\n specularStrength: 1,\n specularRotation: 45,\n specularDark: false,\n tint: 0,\n glowStrength: 0,\n glowSpread: 0.5,\n glowExponent: 1.5,\n edgeStrength: 0,\n edgeWidth: 2,\n edgeExponent: 1.5,\n edgeShadow: \"0 2px 6px rgba(0, 0, 0, 0.16)\",\n edgeInsetShadow: \"0 -4px 10px rgba(0, 0, 0, 0.12)\",\n};\n\nexport const SWITCH_DARK_OVERRIDES: Partial<LensParams> = {\n brightness: 0.12,\n glowStrength: 0.4,\n edgeStrength: 0.5,\n};\n\nexport const SWITCH_LIGHT_OVERRIDES: Partial<LensParams> = {\n brightness: -0.02,\n specularRotation: 30,\n specularStrength: 1.5,\n glowStrength: 0.4,\n glowSpread: 0.5,\n glowExponent: 2,\n edgeStrength: 1,\n edgeWidth: 1.5,\n edgeExponent: 1,\n};\n\n/** LensSlider base optical parameters. */\nexport const SLIDER_GLASS_DEFAULTS: Partial<LensParams> = {\n lensW: 90,\n lensH: 60,\n borderRadius: 30,\n mapSize: 256,\n depth: 2,\n chromaAmount: 0.65,\n scaleX: 0.06,\n scaleY: 0.06,\n sdfBoundary: true,\n edgeFalloff: true,\n domeDepth: 5,\n splayAmount: 0.5,\n blurAmount: 0,\n brightness: 0.06,\n specularStrength: 1.5,\n specularRotation: 45,\n specularDark: false,\n tint: 0,\n glowStrength: 0.4,\n glowSpread: 0.5,\n glowExponent: 1.5,\n edgeStrength: 0,\n edgeWidth: 3,\n edgeExponent: 1.5,\n edgeShadow: \"0 2px 6px rgba(0, 0, 0, 0.16)\",\n edgeInsetShadow: \"0 -4px 10px rgba(0, 0, 0, 0.12)\",\n restEdgeShadow: \"0 1.333px 5.333px var(--lensfx-shadow-strong, rgba(0,0,0,0.3))\",\n};\n\nexport const SLIDER_DARK_OVERRIDES: Partial<LensParams> = {\n scaleX: 0.133,\n scaleY: 0.135,\n brightness: 0.12,\n specularRotation: 45,\n glowExponent: 1.5,\n edgeStrength: 0.5,\n edgeWidth: 1,\n edgeExponent: 1.5,\n};\n\nexport const SLIDER_LIGHT_OVERRIDES: Partial<LensParams> = {\n scaleX: 0.1,\n scaleY: 0.1,\n brightness: -0.02,\n specularRotation: 30,\n glowExponent: 2,\n edgeStrength: 1,\n edgeWidth: 1,\n edgeExponent: 1,\n};\n\nexport const SLIDER_SAFARI_OVERRIDES: Partial<LensParams> = {\n scaleY: 0.25,\n};\n","/**\n * lensfx — WebGL Layer: VideoRefractionRenderer\n *\n * Full WebGL 1 video refraction engine — Safari fallback for live <video> frames\n * which cannot be filtered by SVG feDisplacementMap in WebKit.\n *\n * Features:\n * - Analytical circle and rounded-rect bar SDFs\n * - Multi-control dominant lens tracking with press scaling\n * - Separable 9-tap Gaussian blur pass (two-pass half-res FBO)\n * - Chromatic aberration (R, G, B pass)\n * - Adaptive specular & Apple-style vibrancy luminance correction\n */\n\n/** Options for constructing a VideoRefractionRenderer. */\nexport interface VideoRendererOptions {\n /** Canvas element to render into. */\n canvas: HTMLCanvasElement;\n /** Source video element to sample frames from. */\n video: HTMLVideoElement;\n /** Lens depth strength. Default: 2. */\n depth?: number;\n /** Chromatic aberration amount (0–1). Default: 0.5. */\n chromaAmount?: number;\n /** Angle of specular directional light (degrees). Default: 45. */\n specularRotation?: number;\n /** Specular highlight intensity. Default: 1. */\n specularStrength?: number;\n}\n\nexport const VERTEX_SHADER = `\nattribute vec2 a_pos;\nvarying vec2 v_uv;\nvoid main() {\n // Flip Y so UV (0,0) = top-left, matching HTML/CSS coordinates.\n v_uv = vec2(a_pos.x * 0.5 + 0.5, 0.5 - a_pos.y * 0.5);\n gl_Position = vec4(a_pos, 0.0, 1.0);\n}\n`;\n\nexport const BLUR_FRAGMENT_SHADER = `\nprecision highp float;\nuniform sampler2D u_source;\nuniform vec2 u_dir;\nvarying vec2 v_uv;\n\nvoid main() {\n vec4 c = texture2D(u_source, v_uv) * 0.2042;\n c += (texture2D(u_source, v_uv + 1.0 * u_dir) + texture2D(u_source, v_uv - 1.0 * u_dir)) * 0.1801;\n c += (texture2D(u_source, v_uv + 2.0 * u_dir) + texture2D(u_source, v_uv - 2.0 * u_dir)) * 0.1240;\n c += (texture2D(u_source, v_uv + 3.0 * u_dir) + texture2D(u_source, v_uv - 3.0 * u_dir)) * 0.0663;\n c += (texture2D(u_source, v_uv + 4.0 * u_dir) + texture2D(u_source, v_uv - 4.0 * u_dir)) * 0.0276;\n gl_FragColor = c;\n}\n`;\n\nexport const REFRACTION_FRAGMENT_SHADER = `\n#extension GL_OES_standard_derivatives : enable\nprecision highp float;\n\nuniform sampler2D u_video;\nuniform sampler2D u_map;\nuniform sampler2D u_blurred;\nuniform float u_baseScale[3];\nuniform float u_ratioX[3];\nuniform float u_ratioY[3];\nuniform float u_chromaAmount;\nuniform float u_specStrength;\nuniform float u_adaptStrength;\nuniform float u_specLumaLow;\nuniform float u_specLumaHigh;\nuniform float u_hasBlur;\nuniform vec4 u_bbox; // (x, y, w, h) normalised, y=0 at top\nuniform vec3 u_circles[3]; // (cx, cy, radius) in bbox pixel space\nuniform float u_scale[3]; // per-circle geometric press scale (1 = unscaled)\nuniform vec4 u_bar; // (cx, cy, w, h) in bbox pixel space; w<=0 means inactive\nuniform float u_barRadius; // corner radius for the rounded-rect bar lens\nuniform float u_barBaseScale;\nuniform float u_barRatioX;\nuniform float u_barRatioY;\nuniform vec2 u_bboxSize; // bbox (width, height) in pixels\n\nvarying vec2 v_uv;\n\nvoid main() {\n vec2 uv = v_uv;\n vec2 bMin = u_bbox.xy;\n vec2 bSize = u_bbox.zw;\n vec2 bMax = bMin + bSize;\n\n // Outside bounding box -> pass-through video\n if (uv.x < bMin.x || uv.x > bMax.x || uv.y < bMin.y || uv.y > bMax.y) {\n gl_FragColor = texture2D(u_video, uv);\n return;\n }\n\n // Map fragment UV -> displacement texture UV\n vec2 mUV = (uv - bMin) / bSize;\n\n // Analytical SDF mask (pixel-perfect at any resolution). Tracks the\n // dominant region so per-region scale/ratio can be picked up via the\n // loop-constant index (safe in WebGL 1). After the circle loop we test the\n // rounded-rect \"bar\" region (when active) and take whichever has the\n // larger mask value. domCenter/domScale track the dominant lens so the\n // displacement map is sampled in its (press-)scaled space below.\n vec2 pxPos = mUV * u_bboxSize;\n float mask = 0.0;\n float baseScale = 0.0;\n float ratioX = 0.0;\n float ratioY = 0.0;\n\n // Map-sample scale assignment, tracked SEPARATELY from the tight SDF mask: a\n // pixel adopts a circle's press scale across the union of its original and\n // scaled radius (R * max(1, s)). That way the annulus a shrunk lens vacates\n // samples empty space instead of leaving the original rim stuck behind.\n // domScale = 1 (bar + background) -> identity sample.\n vec2 domCenter = pxPos;\n float domScale = 1.0;\n float domDist = 1.0; // nearest normalised assignment distance (<1 = inside)\n\n for (int i = 0; i < 3; i++) {\n if (u_circles[i].z < 0.1) continue; // skip inactive circles\n float s = max(u_scale[i], 0.001);\n float R = u_circles[i].z;\n float rho = length(pxPos - u_circles[i].xy);\n\n // Visible lens SDF at the scaled radius -> blur / specular gating.\n float dist = rho - R * s;\n float aa = fwidth(dist);\n float m = 1.0 - smoothstep(-aa, aa, dist);\n if (m > mask) {\n mask = m;\n baseScale = u_baseScale[i];\n ratioX = u_ratioX[i];\n ratioY = u_ratioY[i];\n }\n\n // Scale assignment over max(original, scaled) radius, PLUS a small FIXED\n // pixel margin so the region boundary clears the map's hard content edge at\n // r = R. A *fractional* margin scales with R, so a big lens (play) would\n // swallow its neighbours' regions and drag their rings in. 4px clears the\n // edge's AA band without ever reaching the gap to the next control.\n float nd = rho / (R * max(1.0, s) + 4.0);\n if (nd < domDist) {\n domDist = nd;\n domCenter = u_circles[i].xy;\n domScale = s;\n }\n }\n\n // Bar (rounded-rect) SDF - only when u_bar.zw > 0. The bar never scales, so\n // it keeps the identity map sample (domScale stays 1 for bar + background).\n if (u_bar.z > 0.1 && u_bar.w > 0.1) {\n vec2 q = abs(pxPos - u_bar.xy) - u_bar.zw * 0.5 + vec2(u_barRadius);\n float barDist =\n length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - u_barRadius;\n float aaBar = fwidth(barDist);\n float mBar = 1.0 - smoothstep(-aaBar, aaBar, barDist);\n if (mBar > mask) {\n mask = mBar;\n baseScale = u_barBaseScale;\n ratioX = u_barRatioX;\n ratioY = u_barRatioY;\n }\n }\n\n // Sample the displacement map at the dominant lens's scaled coordinate, so a\n // per-lens press scale shrinks the baked pattern around its center in\n // lockstep with the SDF radius above. domScale = 1 -> identity (unscaled).\n vec2 scaledPx = domCenter + (pxPos - domCenter) / domScale;\n vec4 d = texture2D(u_map, scaledPx / u_bboxSize);\n\n // mapMatrix (feColorMatrix equivalent)\n float sr = d.r * ratioX + 0.5 * (1.0 - ratioX);\n float sg = d.g * ratioY + 0.5 * (1.0 - ratioY);\n\n // Displacement offset in full-video UV space\n vec2 off = vec2(sr - 0.5, sg - 0.5) * baseScale;\n\n // Choose source: blurred or raw video\n // Inside lens -> blurred (if blur active), outside lens -> raw\n // Blend by mask so the transition at edges is clean\n vec4 color;\n if (u_chromaAmount > 0.001) {\n float sR = 1.0 + u_chromaAmount * 0.2;\n float sG = 1.0 + u_chromaAmount * 0.1;\n if (u_hasBlur > 0.5) {\n color.r = mix(\n texture2D(u_video, clamp(uv + off * sR, 0.0, 1.0)).r,\n texture2D(u_blurred, clamp(uv + off * sR, 0.0, 1.0)).r,\n mask\n );\n color.g = mix(\n texture2D(u_video, clamp(uv + off * sG, 0.0, 1.0)).g,\n texture2D(u_blurred, clamp(uv + off * sG, 0.0, 1.0)).g,\n mask\n );\n color.b = mix(\n texture2D(u_video, clamp(uv + off, 0.0, 1.0)).b,\n texture2D(u_blurred, clamp(uv + off, 0.0, 1.0)).b,\n mask\n );\n } else {\n color.r = texture2D(u_video, clamp(uv + off * sR, 0.0, 1.0)).r;\n color.g = texture2D(u_video, clamp(uv + off * sG, 0.0, 1.0)).g;\n color.b = texture2D(u_video, clamp(uv + off, 0.0, 1.0)).b;\n }\n color.a = 1.0;\n } else {\n vec2 duv = clamp(uv + off, 0.0, 1.0);\n if (u_hasBlur > 0.5) {\n color = mix(texture2D(u_video, duv), texture2D(u_blurred, duv), mask);\n } else {\n color = texture2D(u_video, duv);\n }\n }\n\n // Adaptive specular + brightness (Apple-style vibrancy)\n // Compute perceptual luminance of the displaced video sample\n float luma = dot(color.rgb, vec3(0.299, 0.587, 0.114));\n\n // Specular: blend between additive (dark bg) and multiplicative (bright bg)\n float spec = d.b - 0.502;\n float lumaLo = min(u_specLumaLow, u_specLumaHigh);\n float lumaHi = max(u_specLumaLow, u_specLumaHigh);\n float darkBlend = smoothstep(lumaLo, lumaHi, luma);\n vec3 specAdd = color.rgb + spec * u_specStrength;\n vec3 specMul = color.rgb * (1.0 - spec * u_specStrength);\n color.rgb = mix(specAdd, specMul, darkBlend);\n color.rgb = max(color.rgb, vec3(0.0));\n\n // Brightness: pull toward mid-gray - darkens bright areas, brightens dark\n float correction = (0.5 - luma) * u_adaptStrength * mask;\n color.rgb += correction;\n\n gl_FragColor = color;\n}\n`;\n\nfunction createShader(gl: WebGLRenderingContext, type: number, src: string): WebGLShader | null {\n const shader = gl.createShader(type);\n if (!shader) return null;\n gl.shaderSource(shader, src);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n console.error(\"Shader compile error:\", gl.getShaderInfoLog(shader));\n gl.deleteShader(shader);\n return null;\n }\n return shader;\n}\n\nfunction createProgram(\n gl: WebGLRenderingContext,\n vsSrc: string,\n fsSrc: string\n): WebGLProgram | null {\n const vs = createShader(gl, gl.VERTEX_SHADER, vsSrc);\n const fs = createShader(gl, gl.FRAGMENT_SHADER, fsSrc);\n if (!vs || !fs) return null;\n\n const prog = gl.createProgram();\n if (!prog) return null;\n\n gl.attachShader(prog, vs);\n gl.attachShader(prog, fs);\n gl.linkProgram(prog);\n\n gl.detachShader(prog, vs);\n gl.detachShader(prog, fs);\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {\n console.error(\"Program link error:\", gl.getProgramInfoLog(prog));\n gl.deleteProgram(prog);\n return null;\n }\n return prog;\n}\n\nexport interface VideoLensConfig {\n circles: Array<{ cx: number; cy: number; radius: number; scale: number; baseScale: number; ratioX: number; ratioY: number }>;\n bar?: { cx: number; cy: number; w: number; h: number; radius: number; baseScale: number; ratioX: number; ratioY: number };\n bbox: { x: number; y: number; w: number; h: number };\n bboxSize: { w: number; h: number };\n chromaAmount: number;\n specStrength: number;\n adaptStrength: number;\n specLumaLow: number;\n specLumaHigh: number;\n hasBlur: boolean;\n}\n\nexport class VideoRefractionRenderer {\n private gl: WebGLRenderingContext;\n private quadBuffer: WebGLBuffer;\n private blurProgram: WebGLProgram;\n private refractionProgram: WebGLProgram;\n\n private videoTexture: WebGLTexture;\n private mapTexture: WebGLTexture;\n private blurFboA: WebGLFramebuffer | null = null;\n private blurTexA: WebGLTexture | null = null;\n private blurFboB: WebGLFramebuffer | null = null;\n private blurTexB: WebGLTexture | null = null;\n private fboWidth = 0;\n private fboHeight = 0;\n\n constructor(canvas: HTMLCanvasElement) {\n const gl = canvas.getContext(\"webgl\", { alpha: false, antialias: false, premultipliedAlpha: false });\n if (!gl) throw new Error(\"WebGL not supported\");\n this.gl = gl;\n\n // Enable OES_standard_derivatives for fwidth()\n gl.getExtension(\"OES_standard_derivatives\");\n\n // Quad geometry covering NDC [-1, 1]\n const quad = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);\n this.quadBuffer = gl.createBuffer()!;\n gl.bindBuffer(gl.ARRAY_BUFFER, this.quadBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, quad, gl.STATIC_DRAW);\n\n this.blurProgram = createProgram(gl, VERTEX_SHADER, BLUR_FRAGMENT_SHADER)!;\n this.refractionProgram = createProgram(gl, VERTEX_SHADER, REFRACTION_FRAGMENT_SHADER)!;\n\n this.videoTexture = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, this.videoTexture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\n this.mapTexture = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, this.mapTexture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n }\n\n public setDisplacementMap(image: HTMLImageElement | HTMLCanvasElement) {\n const gl = this.gl;\n gl.bindTexture(gl.TEXTURE_2D, this.mapTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n }\n\n private initBlurFBO(width: number, height: number) {\n const gl = this.gl;\n const halfW = width >> 1;\n const halfH = height >> 1;\n\n if (this.fboWidth === halfW && this.fboHeight === halfH) return;\n this.fboWidth = halfW;\n this.fboHeight = halfH;\n\n const createFBO = () => {\n const tex = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, halfW, halfH, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n\n const fbo = gl.createFramebuffer()!;\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);\n return { fbo, tex };\n };\n\n const resA = createFBO();\n this.blurFboA = resA.fbo;\n this.blurTexA = resA.tex;\n\n const resB = createFBO();\n this.blurFboB = resB.fbo;\n this.blurTexB = resB.tex;\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n\n public render(video: HTMLVideoElement, config: VideoLensConfig) {\n const gl = this.gl;\n const width = gl.canvas.width;\n const height = gl.canvas.height;\n\n // 1. Upload Video Frame\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this.videoTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video);\n\n // 2. Perform 2-Pass Separable Gaussian Blur if active\n if (config.hasBlur) {\n this.initBlurFBO(width, height);\n\n // Pass 1: Horizontal Blur -> FBO A\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.blurFboA);\n gl.viewport(0, 0, this.fboWidth, this.fboHeight);\n gl.useProgram(this.blurProgram);\n\n const aPosBlur = gl.getAttribLocation(this.blurProgram, \"a_pos\");\n gl.bindBuffer(gl.ARRAY_BUFFER, this.quadBuffer);\n gl.enableVertexAttribArray(aPosBlur);\n gl.vertexAttribPointer(aPosBlur, 2, gl.FLOAT, false, 0, 0);\n\n gl.uniform1i(gl.getUniformLocation(this.blurProgram, \"u_source\"), 0);\n gl.uniform2f(gl.getUniformLocation(this.blurProgram, \"u_dir\"), 1.0 / this.fboWidth, 0.0);\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n\n // Pass 2: Vertical Blur -> FBO B\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.blurFboB);\n gl.activeTexture(gl.TEXTURE2);\n gl.bindTexture(gl.TEXTURE_2D, this.blurTexA);\n gl.uniform1i(gl.getUniformLocation(this.blurProgram, \"u_source\"), 2);\n gl.uniform2f(gl.getUniformLocation(this.blurProgram, \"u_dir\"), 0.0, 1.0 / this.fboHeight);\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n }\n\n // 3. Final Refraction Pass -> Screen Canvas\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.viewport(0, 0, width, height);\n gl.useProgram(this.refractionProgram);\n\n const aPos = gl.getAttribLocation(this.refractionProgram, \"a_pos\");\n gl.bindBuffer(gl.ARRAY_BUFFER, this.quadBuffer);\n gl.enableVertexAttribArray(aPos);\n gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);\n\n // Bind textures\n gl.uniform1i(gl.getUniformLocation(this.refractionProgram, \"u_video\"), 0);\n\n gl.activeTexture(gl.TEXTURE1);\n gl.bindTexture(gl.TEXTURE_2D, this.mapTexture);\n gl.uniform1i(gl.getUniformLocation(this.refractionProgram, \"u_map\"), 1);\n\n if (config.hasBlur && this.blurTexB) {\n gl.activeTexture(gl.TEXTURE2);\n gl.bindTexture(gl.TEXTURE_2D, this.blurTexB);\n gl.uniform1i(gl.getUniformLocation(this.refractionProgram, \"u_blurred\"), 2);\n gl.uniform1f(gl.getUniformLocation(this.refractionProgram, \"u_hasBlur\"), 1.0);\n } else {\n gl.uniform1f(gl.getUniformLocation(this.refractionProgram, \"u_hasBlur\"), 0.0);\n }\n\n // Pass Circle Uniforms\n const circlesArr = new Float32Array(9);\n const scaleArr = new Float32Array(3);\n const baseScaleArr = new Float32Array(3);\n const ratioXArr = new Float32Array(3);\n const ratioYArr = new Float32Array(3);\n\n for (let i = 0; i < 3; i++) {\n if (i < config.circles.length) {\n const c = config.circles[i];\n circlesArr[i * 3 + 0] = c.cx;\n circlesArr[i * 3 + 1] = c.cy;\n circlesArr[i * 3 + 2] = c.radius;\n scaleArr[i] = c.scale;\n baseScaleArr[i] = c.baseScale;\n ratioXArr[i] = c.ratioX;\n ratioYArr[i] = c.ratioY;\n }\n }\n\n gl.uniform3fv(gl.getUniformLocation(this.refractionProgram, \"u_circles\"), circlesArr);\n gl.uniform1fv(gl.getUniformLocation(this.refractionProgram, \"u_scale\"), scaleArr);\n gl.uniform1fv(gl.getUniformLocation(this.refractionProgram, \"u_baseScale\"), baseScaleArr);\n gl.uniform1fv(gl.getUniformLocation(this.refractionProgram, \"u_ratioX\"), ratioXArr);\n gl.uniform1fv(gl.getUniformLocation(this.refractionProgram, \"u_ratioY\"), ratioYArr);\n\n // Pass Bar Uniforms\n if (config.bar) {\n gl.uniform4f(\n gl.getUniformLocation(this.refractionProgram, \"u_bar\"),\n config.bar.cx,\n config.bar.cy,\n config.bar.w,\n config.bar.h\n );\n gl.uniform1f(gl.getUniformLocation(this.refractionProgram, \"u_barRadius\"), config.bar.radius);\n gl.uniform1f(gl.getUniformLocation(this.refractionProgram, \"u_barBaseScale\"), config.bar.baseScale);\n gl.uniform1f(gl.getUniformLocation(this.refractionProgram, \"u_barRatioX\"), config.bar.ratioX);\n gl.uniform1f(gl.getUniformLocation(this.refractionProgram, \"u_barRatioY\"), config.bar.ratioY);\n } else {\n gl.uniform4f(gl.getUniformLocation(this.refractionProgram, \"u_bar\"), 0, 0, -1, -1);\n }\n\n // Global Lens Uniforms\n gl.uniform4f(\n gl.getUniformLocation(this.refractionProgram, \"u_bbox\"),\n config.bbox.x,\n config.bbox.y,\n config.bbox.w,\n config.bbox.h\n );\n gl.uniform2f(\n gl.getUniformLocation(this.refractionProgram, \"u_bboxSize\"),\n config.bboxSize.w,\n config.bboxSize.h\n );\n gl.uniform1f(gl.getUniformLocation(this.refractionProgram, \"u_chromaAmount\"), config.chromaAmount);\n gl.uniform1f(gl.getUniformLocation(this.refractionProgram, \"u_specStrength\"), config.specStrength);\n gl.uniform1f(gl.getUniformLocation(this.refractionProgram, \"u_adaptStrength\"), config.adaptStrength);\n gl.uniform1f(gl.getUniformLocation(this.refractionProgram, \"u_specLumaLow\"), config.specLumaLow);\n gl.uniform1f(gl.getUniformLocation(this.refractionProgram, \"u_specLumaHigh\"), config.specLumaHigh);\n\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n }\n\n public dispose() {\n const gl = this.gl;\n gl.deleteBuffer(this.quadBuffer);\n gl.deleteProgram(this.blurProgram);\n gl.deleteProgram(this.refractionProgram);\n gl.deleteTexture(this.videoTexture);\n gl.deleteTexture(this.mapTexture);\n if (this.blurFboA) gl.deleteFramebuffer(this.blurFboA);\n if (this.blurTexA) gl.deleteTexture(this.blurTexA);\n if (this.blurFboB) gl.deleteFramebuffer(this.blurFboB);\n if (this.blurTexB) gl.deleteTexture(this.blurTexB);\n }\n}\n","/**\n * lensfx — WebGL Layer: QRRefractionRenderer\n *\n * Full WebGL 2 (#version 300 es) interactive QR code refraction engine.\n * Uses an O(1) uniform texture occupancy grid for real-time liquid distortion\n * through a 33×33 QR matrix.\n *\n * Features:\n * - WebGL 2 (#version 300 es)\n * - O(1) dot occupancy texture lookup\n * - Analytical eye rounded-rect SDFs with hover scaling\n * - Attenuated displacement for eye corner anchors\n * - Chromatic aberration (scaleR = 1 + 2*chroma, scaleG = 1 + 1*chroma, scaleB = 1)\n */\n\n/** Options for constructing a QRRefractionRenderer. */\nexport interface QRRendererOptions {\n /** Canvas element to render into. */\n canvas: HTMLCanvasElement;\n /** QR matrix data (boolean 33×33 grid, row-major). */\n qrMatrix: boolean[][];\n /** Lens depth strength. Default: 2. */\n depth?: number;\n /** Chromatic aberration amount (0–1). Default: 0.3. */\n chromaAmount?: number;\n /** Dot radius as a fraction of cell size. Default: 0.4. */\n dotRadius?: number;\n}\n\nexport const QR_VERTEX_SHADER = `#version 300 es\nin vec2 a_position;\nout vec2 v_uv;\n\nvoid main() {\n v_uv = (a_position * 0.5) + 0.5;\n gl_Position = vec4(a_position, 0.0, 1.0);\n}\n`;\n\nexport const QR_FRAGMENT_SHADER = `#version 300 es\nprecision highp float;\nprecision highp sampler2D;\n\nin vec2 v_uv;\nout vec4 fragColor;\n\nuniform float u_dotRadius;\nuniform vec3 u_backgroundColor;\nuniform sampler2D u_PaintingTexture;\n\n// QR dot grid for the O(1) occupancy lookup (replaces a per-pixel scan over\n// every dot). Occupancy is matrixLength x matrixLength, R8, 0/1 per module.\nuniform sampler2D u_occupancyTexture;\nuniform float u_gridOriginUV; // padding / size, in UV\nuniform float u_cellUV; // cellSize / size, in UV\nuniform float u_invCellUV; // 1 / cellUV - avoids a per-pixel divide\nuniform int u_matrixLength;\n\nuniform sampler2D u_displacementMap;\nuniform sampler2D u_paintingColorTexture;\nuniform int u_displacementActive;\nuniform vec2 u_lensOrigin;\nuniform vec2 u_lensSize;\nuniform vec2 u_displacementScale;\nuniform float u_chromaAmount;\n\n// Eye uniforms (3 corner finder groups)\nuniform vec2 u_eyeCenter[3];\nuniform vec3 u_eyeHalf[3]; // x=outer, y=mid, z=inner half-size\nuniform vec3 u_eyeRadius[3]; // x=outer, y=mid, z=inner corner radius\nuniform vec3 u_eyeColor[3]; // fill color per group (animated)\nuniform float u_eyeScale[3]; // hover scale per group\nuniform float u_eyeRefractionScale; // 0-1 multiplier for eye displacement\n\n// QR dots sit on a uniform grid, and the radius (~0.35 of a cell) never\n// spills past a cell boundary, so the nearest dot is always the one in pos's\n// own cell. Map pos -> module (i,j), check occupancy, then test distance to\n// that module's center.\nfloat testDot(vec2 pos, float r2) {\n int i = int(floor((pos.x - u_gridOriginUV) * u_invCellUV));\n int j = int(floor((pos.y - u_gridOriginUV) * u_invCellUV));\n if (i < 0 || i >= u_matrixLength || j < 0 || j >= u_matrixLength)\n return 1.0;\n if (texelFetch(u_occupancyTexture, ivec2(i, j), 0).r < 0.5)\n return 1.0;\n vec2 c = vec2(u_gridOriginUV) + (vec2(float(i), float(j)) + 0.5) * u_cellUV;\n vec2 d = pos - c;\n return dot(d, d) < r2 ? 0.0 : 1.0;\n}\n\nfloat roundedRectSDF(vec2 p, float half_, float radius) {\n vec2 d = abs(p) - vec2(half_) + vec2(radius);\n return length(max(d, vec2(0.0))) + min(max(d.x, d.y), 0.0) - radius;\n}\n\n// Test all eye groups. Returns vec4(color, 1.0) if inside an eye, vec4(0) if not.\nvec4 testEyes(vec2 pos) {\n for (int g = 0; g < 3; g++) {\n vec2 local = (pos - u_eyeCenter[g]) / u_eyeScale[g];\n if (roundedRectSDF(local, u_eyeHalf[g].z, u_eyeRadius[g].z) < 0.0)\n return vec4(u_eyeColor[g], 1.0);\n if (roundedRectSDF(local, u_eyeHalf[g].y, u_eyeRadius[g].y) < 0.0)\n return vec4(u_backgroundColor, 1.0);\n if (roundedRectSDF(local, u_eyeHalf[g].x, u_eyeRadius[g].x) < 0.0)\n return vec4(u_eyeColor[g], 1.0);\n }\n return vec4(0.0);\n}\n\n// Test scene (eyes + dots) at a position, returning color for a non-displaced pixel.\n// Returns vec4(color, 1.0) for solid, vec4(0, 0, 0, -1.0) for dot hole (discard).\nvec4 sampleStatic(vec2 pos, float r2) {\n vec4 eye = testEyes(pos);\n if (eye.a > 0.5) return eye;\n float hole = testDot(pos, r2);\n if (hole < 0.5) return vec4(0.0, 0.0, 0.0, -1.0);\n return vec4(u_backgroundColor, 1.0);\n}\n\nvoid main() {\n vec2 uv = vec2(v_uv.x, 1.0 - v_uv.y);\n float paint = texture(u_PaintingTexture, uv).r;\n float r2 = pow(u_dotRadius * (1.0 - paint), 2.0);\n\n if (u_displacementActive == 0) {\n vec4 s = sampleStatic(uv, r2);\n if (s.a < 0.0) discard;\n fragColor = s;\n return;\n }\n\n vec2 lensUV = (uv - u_lensOrigin) / u_lensSize;\n bool insideLens = lensUV.x >= 0.0 && lensUV.x <= 1.0 &&\n lensUV.y >= 0.0 && lensUV.y <= 1.0;\n\n if (!insideLens) {\n vec4 s = sampleStatic(uv, r2);\n if (s.a < 0.0) discard;\n fragColor = s;\n return;\n }\n\n vec4 dispSample = texture(u_displacementMap, lensUV);\n if (dispSample.a < 0.01) {\n vec4 s = sampleStatic(uv, r2);\n if (s.a < 0.0) discard;\n fragColor = s;\n return;\n }\n vec2 disp = (dispSample.rg - 0.5) * u_displacementScale;\n\n float scaleR = 1.0 + u_chromaAmount * 2.0;\n float scaleG = 1.0 + u_chromaAmount * 1.0;\n\n vec2 uvR = uv + disp * scaleR;\n vec2 uvG = uv + disp * scaleG;\n vec2 uvB = uv + disp;\n\n // Attenuated displacement for eyes\n vec2 eyeDisp = disp * u_eyeRefractionScale;\n vec2 eyeUvR = uv + eyeDisp * scaleR;\n vec2 eyeUvG = uv + eyeDisp * scaleG;\n vec2 eyeUvB = uv + eyeDisp;\n\n // Per-channel: test eyes at attenuated displacement, dots at full displacement\n vec4 eyeR = testEyes(eyeUvR);\n vec4 eyeG = testEyes(eyeUvG);\n vec4 eyeB = testEyes(eyeUvB);\n\n float r, g, b;\n\n if (eyeR.a > 0.5) {\n r = eyeR.r;\n } else {\n float holeR = testDot(uvR, r2);\n float paintR = texture(u_paintingColorTexture, uvR).r;\n r = mix(paintR, u_backgroundColor.r, holeR);\n }\n\n if (eyeG.a > 0.5) {\n g = eyeG.g;\n } else {\n float holeG = testDot(uvG, r2);\n float paintG = texture(u_paintingColorTexture, uvG).g;\n g = mix(paintG, u_backgroundColor.g, holeG);\n }\n\n if (eyeB.a > 0.5) {\n b = eyeB.b;\n } else {\n float holeB = testDot(uvB, r2);\n float paintB = texture(u_paintingColorTexture, uvB).b;\n b = mix(paintB, u_backgroundColor.b, holeB);\n }\n\n fragColor = vec4(r, g, b, 1.0);\n}\n`;\n\nfunction createShader300(gl: WebGL2RenderingContext, type: number, src: string): WebGLShader {\n const shader = gl.createShader(type);\n if (!shader) throw new Error(\"Failed to create shader\");\n gl.shaderSource(shader, src);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader);\n gl.deleteShader(shader);\n throw new Error(`Shader compilation error: ${info ?? \"\"}`);\n }\n return shader;\n}\n\nexport interface QREyeConfig {\n center: [number, number];\n half: [number, number, number];\n radius: [number, number, number];\n color: [number, number, number];\n scale: number;\n}\n\nexport interface QRRendererInit {\n canvas: HTMLCanvasElement;\n size: number;\n matrixLength: number;\n occupancyMatrix: Uint8Array;\n gridOriginUV: number;\n cellUV: number;\n dotRadius: number;\n backgroundColor?: [number, number, number];\n}\n\nexport class QRRefractionRenderer {\n private gl: WebGL2RenderingContext;\n private program: WebGLProgram;\n private quadBuffer: WebGLBuffer;\n\n private occupancyTexture: WebGLTexture;\n private displacementTexture: WebGLTexture;\n private paintingTexture: WebGLTexture;\n private paintingColorTexture: WebGLTexture;\n\n private matrixLength: number;\n private gridOriginUV: number;\n private cellUV: number;\n private dotRadius: number;\n private backgroundColor: [number, number, number];\n\n constructor(init: QRRendererInit) {\n const gl = init.canvas.getContext(\"webgl2\", { alpha: true, antialias: false, premultipliedAlpha: false });\n if (!gl) throw new Error(\"WebGL 2 not supported\");\n this.gl = gl;\n\n this.matrixLength = init.matrixLength;\n this.gridOriginUV = init.gridOriginUV;\n this.cellUV = init.cellUV;\n this.dotRadius = init.dotRadius;\n this.backgroundColor = init.backgroundColor ?? [1, 1, 1];\n\n const vs = createShader300(gl, gl.VERTEX_SHADER, QR_VERTEX_SHADER);\n const fs = createShader300(gl, gl.FRAGMENT_SHADER, QR_FRAGMENT_SHADER);\n const prog = gl.createProgram()!;\n gl.attachShader(prog, vs);\n gl.attachShader(prog, fs);\n gl.linkProgram(prog);\n\n if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {\n throw new Error(`QR Program link error: ${gl.getProgramInfoLog(prog) ?? \"\"}`);\n }\n this.program = prog;\n\n const quad = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);\n this.quadBuffer = gl.createBuffer()!;\n gl.bindBuffer(gl.ARRAY_BUFFER, this.quadBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, quad, gl.STATIC_DRAW);\n\n // Occupancy Texture (R8)\n this.occupancyTexture = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, this.occupancyTexture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n gl.R8,\n this.matrixLength,\n this.matrixLength,\n 0,\n gl.RED,\n gl.UNSIGNED_BYTE,\n init.occupancyMatrix\n );\n\n // Displacement Map Texture\n this.displacementTexture = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, this.displacementTexture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\n // Painting Textures (1x1 fallback)\n const blank1x1 = new Uint8Array([0, 0, 0, 0]);\n this.paintingTexture = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, this.paintingTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, blank1x1);\n\n this.paintingColorTexture = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, this.paintingColorTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, blank1x1);\n }\n\n public setDisplacementMap(image: HTMLImageElement | HTMLCanvasElement) {\n const gl = this.gl;\n gl.bindTexture(gl.TEXTURE_2D, this.displacementTexture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n }\n\n public render(params: {\n displacementActive: boolean;\n lensOrigin: [number, number];\n lensSize: [number, number];\n displacementScale: [number, number];\n chromaAmount: number;\n eyes: QREyeConfig[];\n eyeRefractionScale?: number;\n }) {\n const gl = this.gl;\n gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);\n gl.useProgram(this.program);\n\n const aPos = gl.getAttribLocation(this.program, \"a_position\");\n gl.bindBuffer(gl.ARRAY_BUFFER, this.quadBuffer);\n gl.enableVertexAttribArray(aPos);\n gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);\n\n // Bind Occupancy\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this.occupancyTexture);\n gl.uniform1i(gl.getUniformLocation(this.program, \"u_occupancyTexture\"), 0);\n\n // Bind Displacement Map\n gl.activeTexture(gl.TEXTURE1);\n gl.bindTexture(gl.TEXTURE_2D, this.displacementTexture);\n gl.uniform1i(gl.getUniformLocation(this.program, \"u_displacementMap\"), 1);\n\n // Bind Painting Textures\n gl.activeTexture(gl.TEXTURE2);\n gl.bindTexture(gl.TEXTURE_2D, this.paintingTexture);\n gl.uniform1i(gl.getUniformLocation(this.program, \"u_PaintingTexture\"), 2);\n\n gl.activeTexture(gl.TEXTURE3);\n gl.bindTexture(gl.TEXTURE_2D, this.paintingColorTexture);\n gl.uniform1i(gl.getUniformLocation(this.program, \"u_paintingColorTexture\"), 3);\n\n // Uniforms\n gl.uniform1f(gl.getUniformLocation(this.program, \"u_dotRadius\"), this.dotRadius);\n gl.uniform3fv(gl.getUniformLocation(this.program, \"u_backgroundColor\"), this.backgroundColor);\n gl.uniform1f(gl.getUniformLocation(this.program, \"u_gridOriginUV\"), this.gridOriginUV);\n gl.uniform1f(gl.getUniformLocation(this.program, \"u_cellUV\"), this.cellUV);\n gl.uniform1f(gl.getUniformLocation(this.program, \"u_invCellUV\"), 1.0 / this.cellUV);\n gl.uniform1i(gl.getUniformLocation(this.program, \"u_matrixLength\"), this.matrixLength);\n\n gl.uniform1i(gl.getUniformLocation(this.program, \"u_displacementActive\"), params.displacementActive ? 1 : 0);\n gl.uniform2f(gl.getUniformLocation(this.program, \"u_lensOrigin\"), params.lensOrigin[0], params.lensOrigin[1]);\n gl.uniform2f(gl.getUniformLocation(this.program, \"u_lensSize\"), params.lensSize[0], params.lensSize[1]);\n gl.uniform2f(gl.getUniformLocation(this.program, \"u_displacementScale\"), params.displacementScale[0], params.displacementScale[1]);\n gl.uniform1f(gl.getUniformLocation(this.program, \"u_chromaAmount\"), params.chromaAmount);\n gl.uniform1f(gl.getUniformLocation(this.program, \"u_eyeRefractionScale\"), params.eyeRefractionScale ?? 0.2);\n\n // Eyes\n const centers = new Float32Array(6);\n const halfs = new Float32Array(9);\n const radii = new Float32Array(9);\n const colors = new Float32Array(9);\n const scales = new Float32Array(3);\n\n for (let i = 0; i < 3; i++) {\n if (i < params.eyes.length) {\n const e = params.eyes[i];\n centers[i * 2 + 0] = e.center[0];\n centers[i * 2 + 1] = e.center[1];\n halfs[i * 3 + 0] = e.half[0];\n halfs[i * 3 + 1] = e.half[1];\n halfs[i * 3 + 2] = e.half[2];\n radii[i * 3 + 0] = e.radius[0];\n radii[i * 3 + 1] = e.radius[1];\n radii[i * 3 + 2] = e.radius[2];\n colors[i * 3 + 0] = e.color[0];\n colors[i * 3 + 1] = e.color[1];\n colors[i * 3 + 2] = e.color[2];\n scales[i] = e.scale;\n }\n }\n\n gl.uniform2fv(gl.getUniformLocation(this.program, \"u_eyeCenter\"), centers);\n gl.uniform3fv(gl.getUniformLocation(this.program, \"u_eyeHalf\"), halfs);\n gl.uniform3fv(gl.getUniformLocation(this.program, \"u_eyeRadius\"), radii);\n gl.uniform3fv(gl.getUniformLocation(this.program, \"u_eyeColor\"), colors);\n gl.uniform1fv(gl.getUniformLocation(this.program, \"u_eyeScale\"), scales);\n\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n }\n\n public dispose() {\n const gl = this.gl;\n gl.deleteBuffer(this.quadBuffer);\n gl.deleteProgram(this.program);\n gl.deleteTexture(this.occupancyTexture);\n gl.deleteTexture(this.displacementTexture);\n gl.deleteTexture(this.paintingTexture);\n gl.deleteTexture(this.paintingColorTexture);\n }\n}\n"],"mappings":"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","names":["vanilla_exports","__export","DEFAULT_LENS_PARAMS","QRRefractionRenderer","SLIDER_DARK_OVERRIDES","SLIDER_GLASS_DEFAULTS","SLIDER_LIGHT_OVERRIDES","SLIDER_SAFARI_OVERRIDES","SWITCH_DARK_OVERRIDES","SWITCH_GLASS_DEFAULTS","SWITCH_LIGHT_OVERRIDES","VideoRefractionRenderer","colorMatrixValues","computeDomeConstants","createDisplacementMapGeneratorSync","createLens","domeGradient","erf","generateDisplacementMapAsync","getSvgMaskDataUri","erf","x","integrateDome","R","t","sum","n","a","slope","computeDomeConstants","domeDepth","halfW","halfH","Rx","Ry","intX","intY","domeGradient","pos","scale","p","colorMatrixValues","ratioX","ratioY","maskCache","getSvgMaskDataUri","width","height","radius","l","i","key","cached","w","h","r","svg","uri","createDisplacementMapGeneratorSync","mapSize","canvas","ctx","imgData","domeConstants","cachedDomeDepth","cachedHalfW","cachedHalfH","xLookup","cachedF","dirtyDome","input","y","b","M","S","A","v","E","$","C","k","I","T","F","D","L","H","O","hasSpecular","W","U","G","N","q","z","Y","X","V","K","hasDome","hasSplay","r2","clampVal","col","ox","clamped","domeX","minHalf","invMinHalf","startTime","rowOpposite","oy","iy","oSdfY","gy","rawGy","splayY","colOpposite","ix","gxMax","gyMax","dist2","sdf","idxTL","idxTR","idxBL","idxBR","specTL","specTR","specBL","specBR","curGx","curGy","splayFac","effY","effX","prevGx","prevGy","prevMag","newMag","norm","falloff","fx","fy","mx","my","falloffSdf","hx","hy","rTL","rTR","gTL","gBL","rawGx","rawGyProj","dot1","dot2","absDot1","absDot2","edgeAtten","glow1","glow2","s1","s2","idx","loopMs","encodeStart","dataUrl","encodeMs","generateDisplacementMapAsync","params","o","u","c","f","d","g","m","xx","bv","imgD","j","II","TT","Lv","Bv","rowBatch","endRow","row","absX","absY","Mv","Cy","clampX","clampY","gx","effGx","effGy","attenY","attenX","oldGx","oldGy","oldMag","innerX","innerY","innerSdf","dot","glow","spread","edgeVal","resolve","blob","SVG_NS","nextId","createLens","target","options","resolved","container","currentOptions","targetEl","customTarget","computedStyle","originalPosition","filterId","svgEl","defsEl","filterEl","overlayEl","mapDataUrl","currentMapSize","generator","createDisplacementMapGeneratorSync","feImageEl","currentMaskKey","isDestroyed","curX","curY","getDimensions","width","height","radius","renderMap","mapSize","depth","buildFilterPipeline","chroma","scaleX","scaleY","maxScale","scaleRatioX","scaleRatioY","needsMatrix","matrixString","colorMatrixValues","feFlood","feComp","feMat","mapSource","sourceGraphic","feBlur","cRect","bw","bh","dispR","matR","dispG","matG","dispB","matB","compRG","compRGB","dispSingle","specStrength","specMat","specComp","lensMask","holeComp","finalComp","updateLayout","rect","cw","ch","px","py","pyCoordinate","val","containerH","lensLeft","lensTop","tintColor","tintBlur","blurCss","uri","key","getSvgMaskDataUri","maskCss","filterStyle","isPointerActive","onPointerMove","e","x","y","setPosition","setInteractive","interactive","update","newOptions","prev","needsRegen","resizeObserver","destroy","DEFAULT_LENS_PARAMS","SWITCH_GLASS_DEFAULTS","SWITCH_DARK_OVERRIDES","SWITCH_LIGHT_OVERRIDES","SLIDER_GLASS_DEFAULTS","SLIDER_DARK_OVERRIDES","SLIDER_LIGHT_OVERRIDES","SLIDER_SAFARI_OVERRIDES","VERTEX_SHADER","BLUR_FRAGMENT_SHADER","REFRACTION_FRAGMENT_SHADER","createShader","gl","type","src","shader","createProgram","vsSrc","fsSrc","vs","fs","prog","VideoRefractionRenderer","canvas","quad","image","width","height","halfW","halfH","createFBO","tex","fbo","resA","resB","video","config","aPosBlur","aPos","circlesArr","scaleArr","baseScaleArr","ratioXArr","ratioYArr","i","c","QR_VERTEX_SHADER","QR_FRAGMENT_SHADER","createShader300","gl","type","src","shader","info","QRRefractionRenderer","init","vs","fs","prog","quad","blank1x1","image","params","aPos","centers","halfs","radii","colors","scales","i","e"]}