{"version":3,"file":"palette-shader.umd.cjs","sources":["../src/palette.ts","../src/webgl.ts","../src/shaders/srgb2rgb.frag.glsl?raw","../src/shaders/oklab.frag.glsl?raw","../src/shaders/hsl2rgb.frag.glsl?raw","../src/shaders/hsv2rgb.frag.glsl?raw","../src/shaders/lch2rgb.frag.glsl?raw","../src/shaders/hwb2rgb.frag.glsl?raw","../src/shaders/cielab2rgb.frag.glsl?raw","../src/shaders/cam16ucs.frag.glsl?raw","../src/shaders/deltaE.frag.glsl?raw","../src/shaders/closestColor.frag.glsl?raw","../src/shaderSrc.ts","../src/rendererShared.ts","../src/PaletteViz.ts","../src/mesh.ts","../src/math.ts","../src/PaletteViz3D.ts"],"sourcesContent":["import { ColorRGB, ColorList } from './types.ts';\n\n// Returns the palette as a flat RGBA Uint8Array (sRGB, 1×N texture row).\n// Useful for building your own WebGL texture or inspecting raw color data.\nexport const paletteToRGBA = (palette: ColorList): Uint8Array => {\n  const data = new Uint8Array(palette.length * 4);\n  palette.forEach((color, i) => {\n    data[i * 4 + 0] = Math.round(color[0] * 255);\n    data[i * 4 + 1] = Math.round(color[1] * 255);\n    data[i * 4 + 2] = Math.round(color[2] * 255);\n    data[i * 4 + 3] = 255;\n  });\n  return data;\n};\n\n// Backwards-compatible alias (previously returned a Three.js DataTexture)\nexport const paletteToTexture = paletteToRGBA;\n\nexport const randomPalette = (size = 20): ColorList =>\n  Array.from({ length: size }, () => [Math.random(), Math.random(), Math.random()] as ColorRGB);\n","import { ColorList } from './types.ts';\n\nexport type Defines = Record<string, number | false>;\n\n// ── CPU-side color math (mirrors GLSL conversions) ──────────────────────────\n\n// Sign-mirrored (extended sRGB), matching the GLSL srgb_transfer_function_inv.\nfunction _srgbToLinear(c: number): number {\n  const s = c < 0 ? -1 : 1;\n  c = Math.abs(c);\n  return s * (c > 0.04045 ? ((c + 0.055) / 1.055) ** 2.4 : c / 12.92);\n}\n\nfunction _linearToOklab(r: number, g: number, b: number): [number, number, number] {\n  const l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;\n  const m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b;\n  const s = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b;\n  const l_ = Math.cbrt(l);\n  const m_ = Math.cbrt(m);\n  const s_ = Math.cbrt(s);\n  return [\n    0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_,\n    1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_,\n    0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_,\n  ];\n}\n\nfunction _toe(x: number): number {\n  const k1 = 0.206,\n    k2 = 0.03,\n    k3 = (1 + k1) / (1 + k2);\n  return 0.5 * (k3 * x - k1 + Math.sqrt((k3 * x - k1) ** 2 + 4 * k2 * k3 * x));\n}\n\nfunction _labF(t: number): number {\n  const delta = 6 / 29;\n  return t > delta ** 3 ? Math.cbrt(t) : t / (3 * delta * delta) + 4 / 29;\n}\n\nfunction _xyzToLab(\n  x: number,\n  y: number,\n  z: number,\n  wx: number,\n  wy: number,\n  wz: number,\n): [number, number, number] {\n  const fx = _labF(x / wx);\n  const fy = _labF(y / wy);\n  const fz = _labF(z / wz);\n  return [116 * fy - 16, 500 * (fx - fy), 200 * (fy - fz)];\n}\n\nfunction _srgbToCielabD65(r: number, g: number, b: number): [number, number, number] {\n  const lr = _srgbToLinear(r),\n    lg = _srgbToLinear(g),\n    lb = _srgbToLinear(b);\n  return _xyzToLab(\n    0.4124564 * lr + 0.3575761 * lg + 0.1804375 * lb,\n    0.2126729 * lr + 0.7151522 * lg + 0.072175 * lb,\n    0.0193339 * lr + 0.119192 * lg + 0.9503041 * lb,\n    0.95047,\n    1.0,\n    1.08883,\n  );\n}\n\nfunction _srgbToCielabD50(r: number, g: number, b: number): [number, number, number] {\n  const lr = _srgbToLinear(r),\n    lg = _srgbToLinear(g),\n    lb = _srgbToLinear(b);\n  return _xyzToLab(\n    0.4360747 * lr + 0.3850649 * lg + 0.1430804 * lb,\n    0.2225045 * lr + 0.7168786 * lg + 0.0606169 * lb,\n    0.0139322 * lr + 0.0971045 * lg + 0.7141733 * lb,\n    0.96422,\n    1.0,\n    0.82521,\n  );\n}\n\nconst CAM16_D65 = {\n  Sc: 0.59,\n  SN_c: 0.9,\n  D_R: 1.0187728717648556,\n  D_G: 0.9878630004321435,\n  D_B: 0.941466578136544,\n  F_L: 0.2731305366732074,\n  n: 0.2,\n  z: 1.9272135954999579,\n  N_bb: 1.0003040045593807,\n  N_cb: 1.0003040045593807,\n  A_w: 25.510345681082327,\n} as const;\n\nfunction _xyzToCam16ucsD65(x: number, y: number, z: number): [number, number, number] {\n  const R = 0.401288 * x + 0.650173 * y - 0.051461 * z;\n  const G = -0.250268 * x + 1.204414 * y + 0.045854 * z;\n  const B = -0.002079 * x + 0.048952 * y + 0.953127 * z;\n\n  const R_c = R * CAM16_D65.D_R;\n  const G_c = G * CAM16_D65.D_G;\n  const B_c = B * CAM16_D65.D_B;\n\n  const adapt = (value: number): number => {\n    const base = (CAM16_D65.F_L * Math.abs(value)) / 100;\n    const power = base ** 0.42;\n    return (400 * Math.sign(value) * power) / (power + 27.13) + 0.1;\n  };\n\n  const R_a = adapt(R_c);\n  const G_a = adapt(G_c);\n  const B_a = adapt(B_c);\n\n  const a = R_a - (12 * G_a) / 11 + B_a / 11;\n  const b = (R_a + G_a - 2 * B_a) / 9;\n\n  let h = (Math.atan2(b, a) / (2 * Math.PI)) % 1;\n  if (h < 0) h += 1;\n  h *= 360;\n  const hh = h < 20.14 ? h + 360 : h;\n\n  const e_t = 0.25 * (Math.cos((hh / 180) * Math.PI + 2) + 3.8);\n  const A = CAM16_D65.N_bb * (2 * R_a + G_a + 0.05 * B_a - 0.305);\n  const J = 100 * Math.max(A / CAM16_D65.A_w, 0) ** (CAM16_D65.Sc * CAM16_D65.z);\n  const denom = R_a + G_a + (21 / 20) * B_a;\n  const t =\n    denom === 0\n      ? 0\n      : ((50000 / 13) * CAM16_D65.SN_c * CAM16_D65.N_cb * e_t * Math.hypot(a, b)) / denom;\n  const C =\n    Math.max(t, 0) ** 0.9 * Math.sqrt(Math.max(J, 0) / 100) * (1.64 - 0.29 ** CAM16_D65.n) ** 0.73;\n  const M = C * CAM16_D65.F_L ** 0.25;\n  const Jp = (J * 1.7) / (1 + 0.007 * J);\n  const Mp = Math.log(1 + 0.0228 * M) / 0.0228;\n  const hRad = (h / 180) * Math.PI;\n  return [Jp, Mp * Math.cos(hRad), Mp * Math.sin(hRad)];\n}\n\n// FCC 1953 NTSC YIQ, on gamma-encoded sRGB (mirrors srgb_to_yiq in deltaE.frag.glsl)\nfunction _srgbToYiq(r: number, g: number, b: number): [number, number, number] {\n  return [\n    0.299 * r + 0.587 * g + 0.114 * b,\n    0.595716 * r - 0.274453 * g - 0.321263 * b,\n    0.211456 * r - 0.522591 * g + 0.311135 * b,\n  ];\n}\n\nfunction _srgbToCam16ucsD65(r: number, g: number, b: number): [number, number, number] {\n  const lr = _srgbToLinear(r);\n  const lg = _srgbToLinear(g);\n  const lb = _srgbToLinear(b);\n  return _xyzToCam16ucsD65(\n    (0.4124564 * lr + 0.3575761 * lg + 0.1804375 * lb) * 100,\n    (0.2126729 * lr + 0.7151522 * lg + 0.072175 * lb) * 100,\n    (0.0193339 * lr + 0.119192 * lg + 0.9503041 * lb) * 100,\n  );\n}\n\n/** Pre-convert palette to the colour space used by DISTANCE_METRIC on CPU.\n *  Returns RGBA Float32Array (1×N) suitable for upload as a texture. */\nexport function computeMetricPalette(palette: ColorList, metricCode: number): Float32Array {\n  const n = palette.length;\n  const out = new Float32Array(n * 4);\n  for (let i = 0; i < n; i++) {\n    const [r, g, b] = palette[i];\n    let c: [number, number, number];\n    switch (metricCode) {\n      case 1:\n      case 8:\n      case 9: {\n        // oklab, okLightness, liMatch\n        c = _linearToOklab(_srgbToLinear(r), _srgbToLinear(g), _srgbToLinear(b));\n        break;\n      }\n      case 6: {\n        // oklrab\n        const lab = _linearToOklab(_srgbToLinear(r), _srgbToLinear(g), _srgbToLinear(b));\n        c = [_toe(lab[0]), lab[1], lab[2]];\n        break;\n      }\n      case 2:\n      case 3:\n      case 5: // deltaE76, deltaE2000, deltaE94\n        c = _srgbToCielabD65(r, g, b);\n        break;\n      case 7: // cielabD50\n        c = _srgbToCielabD50(r, g, b);\n        break;\n      case 10: // cam16ucsD65\n        c = _srgbToCam16ucsD65(r, g, b);\n        break;\n      case 11: // kotsarenkoRamosYIQ\n        c = _srgbToYiq(r, g, b);\n        break;\n      default: // 0 (rgb), 4 (redmean)\n        c = [r, g, b];\n    }\n    out[i * 4] = c[0];\n    out[i * 4 + 1] = c[1];\n    out[i * 4 + 2] = c[2];\n    out[i * 4 + 3] = 1.0;\n  }\n  return out;\n}\n\nexport function uploadMetricTexture(\n  gl: WebGL2RenderingContext,\n  tex: WebGLTexture,\n  data: Float32Array,\n  count: number,\n): void {\n  gl.bindTexture(gl.TEXTURE_2D, tex);\n  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, count, 1, 0, gl.RGBA, gl.FLOAT, data);\n}\n\nexport function compileShader(gl: WebGL2RenderingContext, type: number, src: string): WebGLShader {\n  const shader = gl.createShader(type)!;\n  gl.shaderSource(shader, src);\n  gl.compileShader(shader);\n  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n    const log = gl.getShaderInfoLog(shader);\n    gl.deleteShader(shader);\n    throw new Error(`Shader compile error:\\n${log}`);\n  }\n  return shader;\n}\n\nexport function buildProgram(\n  gl: WebGL2RenderingContext,\n  defines: Defines,\n  fragSrc: string,\n  vertSrc: string,\n): WebGLProgram {\n  // #version 300 es must be the very first line — prepend it before defines.\n  const defineStr =\n    Object.entries(defines)\n      .filter(([, v]) => v !== false)\n      .map(([k, v]) => `#define ${k} ${v}`)\n      .join('\\n') + '\\n';\n  const prefix = '#version 300 es\\n' + defineStr;\n\n  const vert = compileShader(gl, gl.VERTEX_SHADER, prefix + vertSrc);\n  const frag = compileShader(gl, gl.FRAGMENT_SHADER, prefix + fragSrc);\n\n  const prog = gl.createProgram()!;\n  gl.attachShader(prog, vert);\n  gl.attachShader(prog, frag);\n  gl.linkProgram(prog);\n  gl.deleteShader(vert);\n  gl.deleteShader(frag);\n\n  if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {\n    const log = gl.getProgramInfoLog(prog);\n    gl.deleteProgram(prog);\n    throw new Error(`Program link error:\\n${log}`);\n  }\n  return prog;\n}\n\nexport function initTexture(gl: WebGL2RenderingContext, tex: WebGLTexture): void {\n  gl.bindTexture(gl.TEXTURE_2D, tex);\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.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}\n\nexport function uploadPaletteTexture(\n  gl: WebGL2RenderingContext,\n  tex: WebGLTexture,\n  palette: ColorList,\n): void {\n  if (palette.length === 0) throw new Error('Palette must contain at least one color');\n  const data = new Float32Array(palette.length * 4);\n  palette.forEach(([r, g, b], i) => {\n    data[i * 4] = r;\n    data[i * 4 + 1] = g;\n    data[i * 4 + 2] = b;\n    data[i * 4 + 3] = 1.0;\n  });\n  gl.bindTexture(gl.TEXTURE_2D, tex);\n  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, palette.length, 1, 0, gl.RGBA, gl.FLOAT, data);\n}\n","export default \"// sRGB→linear using srgb_transfer_function_inv from oklab.frag.glsl (included before this file)\\nvec3 srgb2rgb(const in vec3 srgb) { return vec3(srgb_transfer_function_inv(srgb.r), srgb_transfer_function_inv(srgb.g), srgb_transfer_function_inv(srgb.b)); }\\nvec4 srgb2rgb(const in vec4 srgb) { return vec4(srgb2rgb(srgb.rgb), srgb.a); }\\n\"","export default \"// Copyright(c) 2021 Björn Ottosson\\n//\\n// Permission is hereby granted, free of charge, to any person obtaining a copy of\\n// this softwareand associated documentation files(the \\\"Software\\\"), to deal in\\n// the Software without restriction, including without limitation the rights to\\n// use, copy, modify, merge, publish, distribute, sublicense, and /or sell copies\\n// of the Software, and to permit persons to whom the Software is furnished to do\\n// so, subject to the following conditions :\\n// The above copyright noticeand this permission notice shall be included in all\\n// copies or substantial portions of the Software.\\n// THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE\\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\n// SOFTWARE.\\n\\n#define M_PI 3.1415926535897932384626433832795\\n\\nfloat cbrt( float x )\\n{\\n    // GPU pow (exp2·log2) is loose; one Newton step polishes the result to\\n    // f32 ulp so GPU-converted pixels agree with the CPU-converted palette\\n    // entries in computeMetricPalette (which use exact Math.cbrt).\\n    float y = sign(x) * pow(abs(x), 0.3333333333333333f);\\n    y -= (y * y * y - x) / (3.0f * y * y + 1e-30f);\\n    return y;\\n}\\n\\n// Both transfer functions are sign-mirrored (extended sRGB, as in CSS Color 4)\\n// so out-of-gamut linear values survive an encode/decode round-trip — needed\\n// by the OUTPUT_LINEAR readback path, harmless for in-gamut [0,1] input.\\nfloat srgb_transfer_function(float a)\\n{\\n\\tfloat s = a < 0.0f ? -1.0f : 1.0f;\\n\\ta = abs(a);\\n\\treturn s * (.0031308f >= a ? 12.92f * a : 1.055f * pow(a, .4166666666666667f) - .055f);\\n}\\n\\nfloat srgb_transfer_function_inv(float a)\\n{\\n\\tfloat s = a < 0.0f ? -1.0f : 1.0f;\\n\\ta = abs(a);\\n\\treturn s * (.04045f < a ? pow((a + .055f) / 1.055f, 2.4f) : a / 12.92f);\\n}\\n\\nvec3 linear_srgb_to_oklab(vec3 c)\\n{\\n\\tfloat l = 0.4122214708f * c.r + 0.5363325363f * c.g + 0.0514459929f * c.b;\\n\\tfloat m = 0.2119034982f * c.r + 0.6806995451f * c.g + 0.1073969566f * c.b;\\n\\tfloat s = 0.0883024619f * c.r + 0.2817188376f * c.g + 0.6299787005f * c.b;\\n\\n\\tfloat l_ = cbrt(l);\\n\\tfloat m_ = cbrt(m);\\n\\tfloat s_ = cbrt(s);\\n\\n\\treturn vec3(\\n\\t\\t0.2104542553f * l_ + 0.7936177850f * m_ - 0.0040720468f * s_,\\n\\t\\t1.9779984951f * l_ - 2.4285922050f * m_ + 0.4505937099f * s_,\\n\\t\\t0.0259040371f * l_ + 0.7827717662f * m_ - 0.8086757660f * s_\\n\\t);\\n}\\n\\nvec3 oklab_to_linear_srgb(vec3 c)\\n{\\n\\tfloat l_ = c.x + 0.3963377774f * c.y + 0.2158037573f * c.z;\\n\\tfloat m_ = c.x - 0.1055613458f * c.y - 0.0638541728f * c.z;\\n\\tfloat s_ = c.x - 0.0894841775f * c.y - 1.2914855480f * c.z;\\n\\n\\tfloat l = l_ * l_ * l_;\\n\\tfloat m = m_ * m_ * m_;\\n\\tfloat s = s_ * s_ * s_;\\n\\n\\treturn vec3(\\n\\t\\t+4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s,\\n\\t\\t-1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s,\\n\\t\\t-0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s\\n\\t);\\n}\\n\\n// Finds the maximum saturation possible for a given hue that fits in sRGB\\n// Saturation here is defined as S = C/L\\n// a and b must be normalized so a^2 + b^2 == 1\\nfloat compute_max_saturation(float a, float b)\\n{\\n\\t// Max saturation will be when one of r, g or b goes below zero.\\n\\n\\t// Select different coefficients depending on which component goes below zero first\\n\\tfloat k0, k1, k2, k3, k4, wl, wm, ws;\\n\\n\\tif (-1.88170328f * a - 0.80936493f * b > 1.f)\\n\\t{\\n\\t\\t// Red component\\n\\t\\tk0 = +1.19086277f; k1 = +1.76576728f; k2 = +0.59662641f; k3 = +0.75515197f; k4 = +0.56771245f;\\n\\t\\twl = +4.0767416621f; wm = -3.3077115913f; ws = +0.2309699292f;\\n\\t}\\n\\telse if (1.81444104f * a - 1.19445276f * b > 1.f)\\n\\t{\\n\\t\\t// Green component\\n\\t\\tk0 = +0.73956515f; k1 = -0.45954404f; k2 = +0.08285427f; k3 = +0.12541070f; k4 = +0.14503204f;\\n\\t\\twl = -1.2684380046f; wm = +2.6097574011f; ws = -0.3413193965f;\\n\\t}\\n\\telse\\n\\t{\\n\\t\\t// Blue component\\n\\t\\tk0 = +1.35733652f; k1 = -0.00915799f; k2 = -1.15130210f; k3 = -0.50559606f; k4 = +0.00692167f;\\n\\t\\twl = -0.0041960863f; wm = -0.7034186147f; ws = +1.7076147010f;\\n\\t}\\n\\n\\t// Approximate max saturation using a polynomial:\\n\\tfloat S = k0 + k1 * a + k2 * b + k3 * a * a + k4 * a * b;\\n\\n\\t// Do one step Halley's method to get closer\\n\\t// this gives an error less than 10e6, except for some blue hues where the dS/dh is close to infinite\\n\\t// this should be sufficient for most applications, otherwise do two/three steps \\n\\n\\tfloat k_l = +0.3963377774f * a + 0.2158037573f * b;\\n\\tfloat k_m = -0.1055613458f * a - 0.0638541728f * b;\\n\\tfloat k_s = -0.0894841775f * a - 1.2914855480f * b;\\n\\n\\t{\\n\\t\\tfloat l_ = 1.f + S * k_l;\\n\\t\\tfloat m_ = 1.f + S * k_m;\\n\\t\\tfloat s_ = 1.f + S * k_s;\\n\\n\\t\\tfloat l = l_ * l_ * l_;\\n\\t\\tfloat m = m_ * m_ * m_;\\n\\t\\tfloat s = s_ * s_ * s_;\\n\\n\\t\\tfloat l_dS = 3.f * k_l * l_ * l_;\\n\\t\\tfloat m_dS = 3.f * k_m * m_ * m_;\\n\\t\\tfloat s_dS = 3.f * k_s * s_ * s_;\\n\\n\\t\\tfloat l_dS2 = 6.f * k_l * k_l * l_;\\n\\t\\tfloat m_dS2 = 6.f * k_m * k_m * m_;\\n\\t\\tfloat s_dS2 = 6.f * k_s * k_s * s_;\\n\\n\\t\\tfloat f = wl * l + wm * m + ws * s;\\n\\t\\tfloat f1 = wl * l_dS + wm * m_dS + ws * s_dS;\\n\\t\\tfloat f2 = wl * l_dS2 + wm * m_dS2 + ws * s_dS2;\\n\\n\\t\\tS = S - f * f1 / (f1 * f1 - 0.5f * f * f2);\\n\\t}\\n\\n\\treturn S;\\n}\\n\\n// finds L_cusp and C_cusp for a given hue\\n// a and b must be normalized so a^2 + b^2 == 1\\nvec2 find_cusp(float a, float b)\\n{\\n\\t// First, find the maximum saturation (saturation S = C/L)\\n\\tfloat S_cusp = compute_max_saturation(a, b);\\n\\n\\t// Convert to linear sRGB to find the first point where at least one of r,g or b >= 1:\\n\\tvec3 rgb_at_max = oklab_to_linear_srgb(vec3( 1, S_cusp * a, S_cusp * b ));\\n\\tfloat L_cusp = cbrt(1.f / max(max(rgb_at_max.r, rgb_at_max.g), rgb_at_max.b));\\n\\tfloat C_cusp = L_cusp * S_cusp;\\n\\n\\treturn vec2( L_cusp , C_cusp );\\n}\\n\\n// Finds intersection of the line defined by \\n// L = L0 * (1 - t) + t * L1;\\n// C = t * C1;\\n// a and b must be normalized so a^2 + b^2 == 1\\nfloat find_gamut_intersection(float a, float b, float L1, float C1, float L0, vec2 cusp)\\n{\\n\\t// Find the intersection for upper and lower half seprately\\n\\tfloat t;\\n\\tif (((L1 - L0) * cusp.y - (cusp.x - L0) * C1) <= 0.f)\\n\\t{\\n\\t\\t// Lower half\\n\\n\\t\\tt = cusp.y * L0 / (C1 * cusp.x + cusp.y * (L0 - L1));\\n\\t}\\n\\telse\\n\\t{\\n\\t\\t// Upper half\\n\\n\\t\\t// First intersect with triangle\\n\\t\\tt = cusp.y * (L0 - 1.f) / (C1 * (cusp.x - 1.f) + cusp.y * (L0 - L1));\\n\\n\\t\\t// Then one step Halley's method\\n\\t\\t{\\n\\t\\t\\tfloat dL = L1 - L0;\\n\\t\\t\\tfloat dC = C1;\\n\\n\\t\\t\\tfloat k_l = +0.3963377774f * a + 0.2158037573f * b;\\n\\t\\t\\tfloat k_m = -0.1055613458f * a - 0.0638541728f * b;\\n\\t\\t\\tfloat k_s = -0.0894841775f * a - 1.2914855480f * b;\\n\\n\\t\\t\\tfloat l_dt = dL + dC * k_l;\\n\\t\\t\\tfloat m_dt = dL + dC * k_m;\\n\\t\\t\\tfloat s_dt = dL + dC * k_s;\\n\\n\\n\\t\\t\\t// If higher accuracy is required, 2 or 3 iterations of the following block can be used:\\n\\t\\t\\t{\\n\\t\\t\\t\\tfloat L = L0 * (1.f - t) + t * L1;\\n\\t\\t\\t\\tfloat C = t * C1;\\n\\n\\t\\t\\t\\tfloat l_ = L + C * k_l;\\n\\t\\t\\t\\tfloat m_ = L + C * k_m;\\n\\t\\t\\t\\tfloat s_ = L + C * k_s;\\n\\n\\t\\t\\t\\tfloat l = l_ * l_ * l_;\\n\\t\\t\\t\\tfloat m = m_ * m_ * m_;\\n\\t\\t\\t\\tfloat s = s_ * s_ * s_;\\n\\n\\t\\t\\t\\tfloat ldt = 3.f * l_dt * l_ * l_;\\n\\t\\t\\t\\tfloat mdt = 3.f * m_dt * m_ * m_;\\n\\t\\t\\t\\tfloat sdt = 3.f * s_dt * s_ * s_;\\n\\n\\t\\t\\t\\tfloat ldt2 = 6.f * l_dt * l_dt * l_;\\n\\t\\t\\t\\tfloat mdt2 = 6.f * m_dt * m_dt * m_;\\n\\t\\t\\t\\tfloat sdt2 = 6.f * s_dt * s_dt * s_;\\n\\n\\t\\t\\t\\tfloat r = 4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s - 1.f;\\n\\t\\t\\t\\tfloat r1 = 4.0767416621f * ldt - 3.3077115913f * mdt + 0.2309699292f * sdt;\\n\\t\\t\\t\\tfloat r2 = 4.0767416621f * ldt2 - 3.3077115913f * mdt2 + 0.2309699292f * sdt2;\\n\\n\\t\\t\\t\\tfloat u_r = r1 / (r1 * r1 - 0.5f * r * r2);\\n\\t\\t\\t\\tfloat t_r = -r * u_r;\\n\\n\\t\\t\\t\\tfloat g = -1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s - 1.f;\\n\\t\\t\\t\\tfloat g1 = -1.2684380046f * ldt + 2.6097574011f * mdt - 0.3413193965f * sdt;\\n\\t\\t\\t\\tfloat g2 = -1.2684380046f * ldt2 + 2.6097574011f * mdt2 - 0.3413193965f * sdt2;\\n\\n\\t\\t\\t\\tfloat u_g = g1 / (g1 * g1 - 0.5f * g * g2);\\n\\t\\t\\t\\tfloat t_g = -g * u_g;\\n\\n\\t\\t\\t\\tfloat b = -0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s - 1.f;\\n\\t\\t\\t\\tfloat b1 = -0.0041960863f * ldt - 0.7034186147f * mdt + 1.7076147010f * sdt;\\n\\t\\t\\t\\tfloat b2 = -0.0041960863f * ldt2 - 0.7034186147f * mdt2 + 1.7076147010f * sdt2;\\n\\n\\t\\t\\t\\tfloat u_b = b1 / (b1 * b1 - 0.5f * b * b2);\\n\\t\\t\\t\\tfloat t_b = -b * u_b;\\n\\n\\t\\t\\t\\tt_r = u_r >= 0.f ? t_r : 10000.f;\\n\\t\\t\\t\\tt_g = u_g >= 0.f ? t_g : 10000.f;\\n\\t\\t\\t\\tt_b = u_b >= 0.f ? t_b : 10000.f;\\n\\n\\t\\t\\t\\tt += min(t_r, min(t_g, t_b));\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\treturn t;\\n}\\n\\nfloat find_gamut_intersection(float a, float b, float L1, float C1, float L0)\\n{\\n\\t// Find the cusp of the gamut triangle\\n\\tvec2 cusp = find_cusp(a, b);\\n\\n\\treturn find_gamut_intersection(a, b, L1, C1, L0, cusp);\\n}\\n\\nvec3 gamut_clip_preserve_chroma(vec3 rgb)\\n{\\n\\tif (rgb.r < 1.f && rgb.g < 1.f && rgb.b < 1.f && rgb.r > 0.f && rgb.g > 0.f && rgb.b > 0.f)\\n\\t\\treturn rgb;\\n\\n\\tvec3 lab = linear_srgb_to_oklab(rgb);\\n\\n\\tfloat L = lab.x;\\n\\tfloat eps = 0.00001f;\\n\\tfloat C = max(eps, sqrt(lab.y * lab.y + lab.z * lab.z));\\n\\tfloat a_ = lab.y / C;\\n\\tfloat b_ = lab.z / C;\\n\\n\\tfloat L0 = clamp(L, 0.f, 1.f);\\n\\n\\tfloat t = find_gamut_intersection(a_, b_, L, C, L0);\\n\\tfloat L_clipped = L0 * (1.f - t) + t * L;\\n\\tfloat C_clipped = t * C;\\n\\n\\treturn oklab_to_linear_srgb(vec3( L_clipped, C_clipped * a_, C_clipped * b_ ));\\n}\\n\\nvec3 gamut_clip_project_to_0_5(vec3 rgb)\\n{\\n\\tif (rgb.r < 1.f && rgb.g < 1.f && rgb.b < 1.f && rgb.r > 0.f && rgb.g > 0.f && rgb.b > 0.f)\\n\\t\\treturn rgb;\\n\\n\\tvec3 lab = linear_srgb_to_oklab(rgb);\\n\\n\\tfloat L = lab.x;\\n\\tfloat eps = 0.00001f;\\n\\tfloat C = max(eps, sqrt(lab.y * lab.y + lab.z * lab.z));\\n\\tfloat a_ = lab.y / C;\\n\\tfloat b_ = lab.z / C;\\n\\n\\tfloat L0 = 0.5;\\n\\n\\tfloat t = find_gamut_intersection(a_, b_, L, C, L0);\\n\\tfloat L_clipped = L0 * (1.f - t) + t * L;\\n\\tfloat C_clipped = t * C;\\n\\n\\treturn oklab_to_linear_srgb(vec3( L_clipped, C_clipped * a_, C_clipped * b_ ));\\n}\\n\\nvec3 gamut_clip_project_to_L_cusp(vec3 rgb)\\n{\\n\\tif (rgb.r < 1.f && rgb.g < 1.f && rgb.b < 1.f && rgb.r > 0.f && rgb.g > 0.f && rgb.b > 0.f)\\n\\t\\treturn rgb;\\n\\n\\tvec3 lab = linear_srgb_to_oklab(rgb);\\n\\n\\tfloat L = lab.x;\\n\\tfloat eps = 0.00001f;\\n\\tfloat C = max(eps, sqrt(lab.y * lab.y + lab.z * lab.z));\\n\\tfloat a_ = lab.y / C;\\n\\tfloat b_ = lab.z / C;\\n\\n\\t// The cusp is computed here and in find_gamut_intersection, an optimized solution would only compute it once.\\n\\tvec2 cusp = find_cusp(a_, b_);\\n\\n\\tfloat L0 = cusp.x;\\n\\n\\tfloat t = find_gamut_intersection(a_, b_, L, C, L0);\\n\\n\\tfloat L_clipped = L0 * (1.f - t) + t * L;\\n\\tfloat C_clipped = t * C;\\n\\n\\treturn oklab_to_linear_srgb(vec3( L_clipped, C_clipped * a_, C_clipped * b_ ));\\n}\\n\\nvec3 gamut_clip_adaptive_L0_0_5(vec3 rgb, float alpha)\\n{\\n\\tif (rgb.r < 1.f && rgb.g < 1.f && rgb.b < 1.f && rgb.r > 0.f && rgb.g > 0.f && rgb.b > 0.f)\\n\\t\\treturn rgb;\\n\\n\\tvec3 lab = linear_srgb_to_oklab(rgb);\\n\\n\\tfloat L = lab.x;\\n\\tfloat eps = 0.00001f;\\n\\tfloat C = max(eps, sqrt(lab.y * lab.y + lab.z * lab.z));\\n\\tfloat a_ = lab.y / C;\\n\\tfloat b_ = lab.z / C;\\n\\n\\tfloat Ld = L - 0.5f;\\n\\tfloat e1 = 0.5f + abs(Ld) + alpha * C;\\n\\tfloat L0 = 0.5f * (1.f + sign(Ld) * (e1 - sqrt(e1 * e1 - 2.f * abs(Ld))));\\n\\n\\tfloat t = find_gamut_intersection(a_, b_, L, C, L0);\\n\\tfloat L_clipped = L0 * (1.f - t) + t * L;\\n\\tfloat C_clipped = t * C;\\n\\n\\treturn oklab_to_linear_srgb(vec3( L_clipped, C_clipped * a_, C_clipped * b_ ));\\n}\\n\\nvec3 gamut_clip_adaptive_L0_L_cusp(vec3 rgb, float alpha)\\n{\\n\\tif (rgb.r < 1.f && rgb.g < 1.f && rgb.b < 1.f && rgb.r > 0.f && rgb.g > 0.f && rgb.b > 0.f)\\n\\t\\treturn rgb;\\n\\n\\tvec3 lab = linear_srgb_to_oklab(rgb);\\n\\n\\tfloat L = lab.x;\\n\\tfloat eps = 0.00001f;\\n\\tfloat C = max(eps, sqrt(lab.y * lab.y + lab.z * lab.z));\\n\\tfloat a_ = lab.y / C;\\n\\tfloat b_ = lab.z / C;\\n\\n\\t// The cusp is computed here and in find_gamut_intersection, an optimized solution would only compute it once.\\n\\tvec2 cusp = find_cusp(a_, b_);\\n\\n\\tfloat Ld = L - cusp.x;\\n\\tfloat k = 2.f * (Ld > 0.f ? 1.f - cusp.x : cusp.x);\\n\\n\\tfloat e1 = 0.5f * k + abs(Ld) + alpha * C / k;\\n\\tfloat L0 = cusp.x + 0.5f * (sign(Ld) * (e1 - sqrt(e1 * e1 - 2.f * k * abs(Ld))));\\n\\n\\tfloat t = find_gamut_intersection(a_, b_, L, C, L0);\\n\\tfloat L_clipped = L0 * (1.f - t) + t * L;\\n\\tfloat C_clipped = t * C;\\n\\n\\treturn oklab_to_linear_srgb(vec3( L_clipped, C_clipped * a_, C_clipped * b_ ));\\n}\\n\\nfloat toe(float x)\\n{\\n\\tfloat k_1 = 0.206f;\\n\\tfloat k_2 = 0.03f;\\n\\tfloat k_3 = (1.f + k_1) / (1.f + k_2);\\n\\treturn 0.5f * (k_3 * x - k_1 + sqrt((k_3 * x - k_1) * (k_3 * x - k_1) + 4.f * k_2 * k_3 * x));\\n}\\n\\nfloat toe_inv(float x)\\n{\\n\\tfloat k_1 = 0.206f;\\n\\tfloat k_2 = 0.03f;\\n\\tfloat k_3 = (1.f + k_1) / (1.f + k_2);\\n\\treturn (x * x + k_1 * x) / (k_3 * (x + k_2));\\n}\\n\\nvec2 to_ST(vec2 cusp)\\n{\\n\\tfloat L = cusp.x;\\n\\tfloat C = cusp.y;\\n\\treturn vec2( C / L, C / (1.f - L) );\\n}\\n\\n// Returns a smooth approximation of the location of the cusp\\n// This polynomial was created by an optimization process\\n// It has been designed so that S_mid < S_max and T_mid < T_max\\nvec2 get_ST_mid(float a_, float b_)\\n{\\n\\tfloat S = 0.11516993f + 1.f / (\\n\\t\\t+7.44778970f + 4.15901240f * b_\\n\\t\\t+ a_ * (-2.19557347f + 1.75198401f * b_\\n\\t\\t\\t+ a_ * (-2.13704948f - 10.02301043f * b_\\n\\t\\t\\t\\t+ a_ * (-4.24894561f + 5.38770819f * b_ + 4.69891013f * a_\\n\\t\\t\\t\\t\\t)))\\n\\t\\t);\\n\\n\\tfloat T = 0.11239642f + 1.f / (\\n\\t\\t+1.61320320f - 0.68124379f * b_\\n\\t\\t+ a_ * (+0.40370612f + 0.90148123f * b_\\n\\t\\t\\t+ a_ * (-0.27087943f + 0.61223990f * b_\\n\\t\\t\\t\\t+ a_ * (+0.00299215f - 0.45399568f * b_ - 0.14661872f * a_\\n\\t\\t\\t\\t\\t)))\\n\\t\\t);\\n\\n\\treturn vec2( S, T );\\n}\\n\\nvec3 get_Cs(float L, float a_, float b_)\\n{\\n\\tvec2 cusp = find_cusp(a_, b_);\\n\\n\\tfloat C_max = find_gamut_intersection(a_, b_, L, 1.f, L, cusp);\\n\\tvec2 ST_max = to_ST(cusp);\\n\\t\\n\\t// Scale factor to compensate for the curved part of gamut shape:\\n\\tfloat k = C_max / min((L * ST_max.x), (1.f - L) * ST_max.y);\\n\\n\\tfloat C_mid;\\n\\t{\\n\\t\\tvec2 ST_mid = get_ST_mid(a_, b_);\\n\\n\\t\\t// Use a soft minimum function, instead of a sharp triangle shape to get a smooth value for chroma.\\n\\t\\tfloat C_a = L * ST_mid.x;\\n\\t\\tfloat C_b = (1.f - L) * ST_mid.y;\\n\\t\\tC_mid = 0.9f * k * sqrt(sqrt(1.f / (1.f / (C_a * C_a * C_a * C_a) + 1.f / (C_b * C_b * C_b * C_b))));\\n\\t}\\n\\n\\tfloat C_0;\\n\\t{\\n\\t\\t// for C_0, the shape is independent of hue, so vec2 are constant. Values picked to roughly be the average values of vec2.\\n\\t\\tfloat C_a = L * 0.4f;\\n\\t\\tfloat C_b = (1.f - L) * 0.8f;\\n\\n\\t\\t// Use a soft minimum function, instead of a sharp triangle shape to get a smooth value for chroma.\\n\\t\\tC_0 = sqrt(1.f / (1.f / (C_a * C_a) + 1.f / (C_b * C_b)));\\n\\t}\\n\\n\\treturn vec3( C_0, C_mid, C_max );\\n}\\n\\nvec3 okhsl_to_srgb(vec3 hsl)\\n{\\n\\tfloat h = hsl.x;\\n\\tfloat s = hsl.y;\\n\\tfloat l = hsl.z;\\n\\n\\tif (l == 1.0f)\\n\\t{\\n\\t\\treturn vec3( 1.f, 1.f, 1.f );\\n\\t}\\n\\n\\telse if (l == 0.f)\\n\\t{\\n\\t\\treturn vec3( 0.f, 0.f, 0.f );\\n\\t}\\n\\n\\tfloat a_ = cos(2.f * M_PI * h);\\n\\tfloat b_ = sin(2.f * M_PI * h);\\n\\tfloat L = toe_inv(l);\\n\\n\\tvec3 cs = get_Cs(L, a_, b_);\\n\\tfloat C_0 = cs.x;\\n\\tfloat C_mid = cs.y;\\n\\tfloat C_max = cs.z;\\n\\n\\tfloat mid = 0.8f;\\n\\tfloat mid_inv = 1.25f;\\n\\n\\tfloat C, t, k_0, k_1, k_2;\\n\\n\\tif (s < mid)\\n\\t{\\n\\t\\tt = mid_inv * s;\\n\\n\\t\\tk_1 = mid * C_0;\\n\\t\\tk_2 = (1.f - k_1 / C_mid);\\n\\n\\t\\tC = t * k_1 / (1.f - k_2 * t);\\n\\t}\\n\\telse\\n\\t{\\n\\t\\tt = (s - mid)/ (1.f - mid);\\n\\n\\t\\tk_0 = C_mid;\\n\\t\\tk_1 = (1.f - mid) * C_mid * C_mid * mid_inv * mid_inv / C_0;\\n\\t\\tk_2 = (1.f - (k_1) / (C_max - C_mid));\\n\\n\\t\\tC = k_0 + t * k_1 / (1.f - k_2 * t);\\n\\t}\\n\\n\\tvec3 rgb = oklab_to_linear_srgb(vec3( L, C * a_, C * b_ ));\\n\\treturn vec3(\\n\\t\\tsrgb_transfer_function(rgb.r),\\n\\t\\tsrgb_transfer_function(rgb.g),\\n\\t\\tsrgb_transfer_function(rgb.b)\\n\\t);\\n}\\n\\nvec3 srgb_to_okhsl(vec3 rgb)\\n{\\n\\tvec3 lab = linear_srgb_to_oklab(vec3(\\n\\t\\tsrgb_transfer_function_inv(rgb.r),\\n\\t\\tsrgb_transfer_function_inv(rgb.g),\\n\\t\\tsrgb_transfer_function_inv(rgb.b)\\n\\t\\t));\\n\\n\\tfloat C = sqrt(lab.y * lab.y + lab.z * lab.z);\\n\\tfloat a_ = lab.y / C;\\n\\tfloat b_ = lab.z / C;\\n\\n\\tfloat L = lab.x;\\n\\tfloat h = 0.5f + 0.5f * atan(-lab.z, -lab.y) / M_PI;\\n\\n\\tvec3 cs = get_Cs(L, a_, b_);\\n\\tfloat C_0 = cs.x;\\n\\tfloat C_mid = cs.y;\\n\\tfloat C_max = cs.z;\\n\\n\\t// Inverse of the interpolation in okhsl_to_srgb:\\n\\n\\tfloat mid = 0.8f;\\n\\tfloat mid_inv = 1.25f;\\n\\n\\tfloat s;\\n\\tif (C < C_mid)\\n\\t{\\n\\t\\tfloat k_1 = mid * C_0;\\n\\t\\tfloat k_2 = (1.f - k_1 / C_mid);\\n\\n\\t\\tfloat t = C / (k_1 + k_2 * C);\\n\\t\\ts = t * mid;\\n\\t}\\n\\telse\\n\\t{\\n\\t\\tfloat k_0 = C_mid;\\n\\t\\tfloat k_1 = (1.f - mid) * C_mid * C_mid * mid_inv * mid_inv / C_0;\\n\\t\\tfloat k_2 = (1.f - (k_1) / (C_max - C_mid));\\n\\n\\t\\tfloat t = (C - k_0) / (k_1 + k_2 * (C - k_0));\\n\\t\\ts = mid + (1.f - mid) * t;\\n\\t}\\n\\n\\tfloat l = toe(L);\\n\\treturn vec3( h, s, l );\\n}\\n\\n\\nvec3 okhsv_to_srgb(vec3 hsv)\\n{\\n\\tfloat h = hsv.x;\\n\\tfloat s = hsv.y;\\n\\tfloat v = hsv.z;\\n\\n\\tfloat a_ = cos(2.f * M_PI * h);\\n\\tfloat b_ = sin(2.f * M_PI * h);\\n\\t\\n\\tvec2 cusp = find_cusp(a_, b_);\\n\\tvec2 ST_max = to_ST(cusp);\\n\\tfloat S_max = ST_max.x;\\n\\tfloat T_max = ST_max.y;\\n\\tfloat S_0 = 0.5f;\\n\\tfloat k = 1.f- S_0 / S_max;\\n\\n\\t// first we compute L and V as if the gamut is a perfect triangle:\\n\\n\\t// L, C when v==1:\\n\\tfloat L_v = 1.f   - s * S_0 / (S_0 + T_max - T_max * k * s);\\n\\tfloat C_v = s * T_max * S_0 / (S_0 + T_max - T_max * k * s);\\n\\n\\tfloat L = v * L_v;\\n\\tfloat C = v * C_v;\\n\\n\\t// then we compensate for both toe and the curved top part of the triangle:\\n\\tfloat L_vt = toe_inv(L_v);\\n\\tfloat C_vt = C_v * L_vt / L_v;\\n\\n\\tfloat L_new = toe_inv(L);\\n\\tC = C * L_new / L;\\n\\tL = L_new;\\n\\n\\tvec3 rgb_scale = oklab_to_linear_srgb(vec3( L_vt, a_ * C_vt, b_ * C_vt ));\\n\\tfloat scale_L = cbrt(1.f / max(max(rgb_scale.r, rgb_scale.g), max(rgb_scale.b, 0.f)));\\n\\n\\tL = L * scale_L;\\n\\tC = C * scale_L;\\n\\n\\tvec3 rgb = oklab_to_linear_srgb(vec3( L, C * a_, C * b_ ));\\n\\treturn vec3(\\n\\t\\tsrgb_transfer_function(rgb.r),\\n\\t\\tsrgb_transfer_function(rgb.g),\\n\\t\\tsrgb_transfer_function(rgb.b)\\n\\t);\\n}\\n\\nvec3 srgb_to_okhsv(vec3 rgb)\\n{\\n\\tvec3 lab = linear_srgb_to_oklab(vec3(\\n\\t\\tsrgb_transfer_function_inv(rgb.r),\\n\\t\\tsrgb_transfer_function_inv(rgb.g),\\n\\t\\tsrgb_transfer_function_inv(rgb.b)\\n\\t\\t));\\n\\n\\tfloat C = sqrt(lab.y * lab.y + lab.z * lab.z);\\n\\tfloat a_ = lab.y / C;\\n\\tfloat b_ = lab.z / C;\\n\\n\\tfloat L = lab.x;\\n\\tfloat h = 0.5f + 0.5f * atan(-lab.z, -lab.y) / M_PI;\\n\\n\\tvec2 cusp = find_cusp(a_, b_);\\n\\tvec2 ST_max = to_ST(cusp);\\n\\tfloat S_max = ST_max.x;\\n\\tfloat T_max = ST_max.y;\\n\\tfloat S_0 = 0.5f;\\n\\tfloat k = 1.f - S_0 / S_max;\\n\\n\\t// first we find L_v, C_v, L_vt and C_vt\\n\\n\\tfloat t = T_max / (C + L * T_max);\\n\\tfloat L_v = t * L;\\n\\tfloat C_v = t * C;\\n\\n\\tfloat L_vt = toe_inv(L_v);\\n\\tfloat C_vt = C_v * L_vt / L_v;\\n\\n\\t// we can then use these to invert the step that compensates for the toe and the curved top part of the triangle:\\n\\tvec3 rgb_scale = oklab_to_linear_srgb(vec3( L_vt, a_ * C_vt, b_ * C_vt ));\\n\\tfloat scale_L = cbrt(1.f / max(max(rgb_scale.r, rgb_scale.g), max(rgb_scale.b, 0.f)));\\n\\n\\tL = L / scale_L;\\n\\tC = C / scale_L;\\n\\n\\tC = C * toe(L) / L;\\n\\tL = toe(L);\\n\\n\\t// we can now compute v and s:\\n\\n\\tfloat v = L / L_v;\\n\\tfloat s = (S_0 + T_max) * C_v / ((T_max * S_0) + T_max * k * C_v);\\n\\n\\treturn vec3 (h, s, v );\\n}\"","export default \"vec3 hsl2rgb( in vec3 c ) {\\n  vec3 rgb = clamp( abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0 );\\n  return c.z + c.y * (rgb-0.5)*(1.0-abs(2.0*c.z-1.0));\\n}\"","export default \"vec3 hsv2rgb(vec3 c) {\\n  vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\\n  vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);\\n  return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);\\n}\"","export default \"// slightly rearranged vector components so it matches with LCH\\n// M_PI and srgb_transfer_function are provided by oklab.frag.glsl (included before this file)\\n\\n// Display bound for OKLCH chroma: C=1.0 on the input axis maps to this value.\\n// Deliberately gamut-fitted (max sRGB chroma is ~0.323), NOT the CSS oklch()\\n// reference range of 0.4 — a wider bound would waste a third of the axis on\\n// colors that clip.\\nconst float OKLCH_MAX_C = 0.34;\\n\\nvec3 lch2rgb(vec3 lch) {\\n    lch.y *= OKLCH_MAX_C;\\n\\n    vec3 lab = vec3(\\n        lch.x,\\n        lch.y * cos(lch.z * M_PI*2.0),\\n        lch.y * sin(lch.z * M_PI*2.0)\\n    );\\n\\n    vec3 lms = vec3(\\n        lab.x + 0.3963377774f * lab.y + 0.2158037573f * lab.z,\\n        lab.x - 0.1055613458f * lab.y - 0.0638541728f * lab.z,\\n        lab.x - 0.0894841775f * lab.y - 1.2914855480f * lab.z\\n    );\\n\\n    lms = lms * lms * lms;\\n\\n    vec3 rgb = vec3(\\n        +4.0767416621f * lms.x - 3.3077115913f * lms.y + 0.2309699292f * lms.z,\\n        -1.2684380046f * lms.x + 2.6097574011f * lms.y - 0.3413193965f * lms.z,\\n        -0.0041960863f * lms.x - 0.7034186147f * lms.y + 1.7076147010f * lms.z\\n    );\\n\\n    return vec3(\\n        srgb_transfer_function(rgb.r),\\n        srgb_transfer_function(rgb.g),\\n        srgb_transfer_function(rgb.b)\\n    );\\n}\\n\"","export default \"// HWB (Hue-Whiteness-Blackness) to sRGB\\n// c.x = hue [0,1], c.y = whiteness [0,1], c.z = blackness [0,1]\\nvec3 hwb2rgb(vec3 c) {\\n  float wb = c.y + c.z;\\n  if (wb >= 1.0) return vec3(c.y / max(wb, 1e-7)); // achromatic grey\\n  // Pure hue (hsv with s=1, v=1) inlined to avoid full hsv2rgb call\\n  vec3 hue = clamp(abs(fract(c.xxx + vec3(0.0, 2.0/3.0, 1.0/3.0)) * 6.0 - 3.0) - 1.0, 0.0, 1.0);\\n  return hue * (1.0 - wb) + c.y;\\n}\\n\"","export default \"// CIELab ↔ sRGB conversions (D65 and D50)\\n// Requires: srgb2rgb, srgb_transfer_function, cbrt from oklab.frag.glsl\\n\\n// ── Shared Lab↔XYZ helpers ───────────────────────────────────────────────────\\n\\n// Forward: t → f(t) used in XYZ→Lab encode\\nfloat _lab_f(float t) {\\n  const float delta = 6.0 / 29.0;\\n  return t > delta * delta * delta\\n    ? cbrt(t)\\n    : t / (3.0 * delta * delta) + 4.0 / 29.0;\\n}\\n\\n// Inverse: f⁻¹(t) used in Lab→XYZ decode\\nfloat _cielab_finv(float t) {\\n  const float delta = 6.0 / 29.0;\\n  return t > delta\\n    ? t * t * t\\n    : 3.0 * delta * delta * (t - 4.0 / 29.0);\\n}\\n\\n// Lab→XYZ, white-point-normalised\\nvec3 _lab_to_xyz(vec3 lab, vec3 white) {\\n  float fy = (lab.x + 16.0) / 116.0;\\n  return vec3(\\n    _cielab_finv(lab.y / 500.0 + fy) * white.x,\\n    _cielab_finv(fy)                  * white.y,\\n    _cielab_finv(fy - lab.z / 200.0)  * white.z\\n  );\\n}\\n\\n// XYZ→Lab, white-point-normalised\\nvec3 _xyz_to_lab(vec3 xyz, vec3 white) {\\n  float fx = _lab_f(xyz.x / white.x);\\n  float fy = _lab_f(xyz.y / white.y);\\n  float fz = _lab_f(xyz.z / white.z);\\n  return vec3(116.0 * fy - 16.0, 500.0 * (fx - fy), 200.0 * (fy - fz));\\n}\\n\\n// ── sRGB → CIELab (forward, used by distance metrics and closestColor) ───────\\n\\n// sRGB → CIELab D65\\nvec3 srgb_to_cielab(vec3 srgb) {\\n  vec3 lin = srgb2rgb(srgb);\\n  vec3 xyz = vec3(\\n    0.4124564 * lin.r + 0.3575761 * lin.g + 0.1804375 * lin.b,\\n    0.2126729 * lin.r + 0.7151522 * lin.g + 0.0721750 * lin.b,\\n    0.0193339 * lin.r + 0.1191920 * lin.g + 0.9503041 * lin.b\\n  );\\n  return _xyz_to_lab(xyz, vec3(0.95047, 1.0, 1.08883));\\n}\\n\\n// sRGB → CIELab D50 (Bradford-adapted)\\nvec3 srgb_to_cielab_d50(vec3 srgb) {\\n  vec3 lin = srgb2rgb(srgb);\\n  vec3 xyz = vec3(\\n    0.4360747 * lin.r + 0.3850649 * lin.g + 0.1430804 * lin.b,\\n    0.2225045 * lin.r + 0.7168786 * lin.g + 0.0606169 * lin.b,\\n    0.0139322 * lin.r + 0.0971045 * lin.g + 0.7141733 * lin.b\\n  );\\n  return _xyz_to_lab(xyz, vec3(0.96422, 1.0, 0.82521));\\n}\\n\\n// ── CIELab → sRGB (inverse, used by color models) ────────────────────────────\\n\\n// CIELab D65 → sRGB  (L: [0,100], a,b: typically [-128,128])\\nvec3 cielab_d65_to_rgb(vec3 lab) {\\n  vec3 xyz = _lab_to_xyz(lab, vec3(0.95047, 1.0, 1.08883));\\n  vec3 lin = vec3(\\n     3.2404542 * xyz.x - 1.5371385 * xyz.y - 0.4985314 * xyz.z,\\n    -0.9692660 * xyz.x + 1.8760108 * xyz.y + 0.0415560 * xyz.z,\\n     0.0556434 * xyz.x - 0.2040259 * xyz.y + 1.0572252 * xyz.z\\n  );\\n  return vec3(\\n    srgb_transfer_function(lin.r),\\n    srgb_transfer_function(lin.g),\\n    srgb_transfer_function(lin.b)\\n  );\\n}\\n\\n// CIELab D50 → sRGB  (L: [0,100], a,b: typically [-128,128])\\n// XYZ→sRGB matrix includes Bradford chromatic adaptation back to D65\\nvec3 cielab_d50_to_rgb(vec3 lab) {\\n  vec3 xyz = _lab_to_xyz(lab, vec3(0.96422, 1.0, 0.82521));\\n  vec3 lin = vec3(\\n     3.1338561 * xyz.x - 1.6168667 * xyz.y - 0.4906146 * xyz.z,\\n    -0.9787684 * xyz.x + 1.9161415 * xyz.y + 0.0334540 * xyz.z,\\n     0.0719453 * xyz.x - 0.2289914 * xyz.y + 1.4052427 * xyz.z\\n  );\\n  return vec3(\\n    srgb_transfer_function(lin.r),\\n    srgb_transfer_function(lin.g),\\n    srgb_transfer_function(lin.b)\\n  );\\n}\\n\"","export default \"#ifndef M_PI\\n#define M_PI 3.1415926535897932384626433832795\\n#endif\\n\\nconst float CAM16_SC = 0.59;\\nconst float CAM16_SN_C = 0.9;\\nconst float CAM16_D_R = 1.0187728717648556;\\nconst float CAM16_D_G = 0.9878630004321435;\\nconst float CAM16_D_B = 0.941466578136544;\\nconst float CAM16_F_L = 0.2731305366732074;\\nconst float CAM16_N = 0.2;\\nconst float CAM16_Z = 1.9272135954999579;\\nconst float CAM16_N_BB = 1.0003040045593807;\\nconst float CAM16_N_CB = 1.0003040045593807;\\nconst float CAM16_A_W = 25.510345681082327;\\nconst float CAM16_INV_CAT16_00 = 1.8620678550872327;\\nconst float CAM16_INV_CAT16_01 = -1.0112546305316843;\\nconst float CAM16_INV_CAT16_02 = 0.14918677544445175;\\nconst float CAM16_INV_CAT16_10 = 0.3875265432361371;\\nconst float CAM16_INV_CAT16_11 = 0.6214474419314753;\\nconst float CAM16_INV_CAT16_12 = -0.00897398516761252;\\nconst float CAM16_INV_CAT16_20 = -0.015841498849333856;\\nconst float CAM16_INV_CAT16_21 = -0.03412293802851556;\\nconst float CAM16_INV_CAT16_22 = 1.0499644368778493;\\nconst float CAM16_MAX_JP = 100.0;\\nconst float CAM16_MAX_AB = 50.0;\\n\\nfloat cam16_adapt_component(float value) {\\n  float base = CAM16_F_L * abs(value) / 100.0;\\n  float power = pow(base, 0.42);\\n  return 400.0 * sign(value) * power / (power + 27.13) + 0.1;\\n}\\n\\nfloat cam16_unadapt_component(float value) {\\n  float delta = abs(value - 0.1);\\n  return sign(value - 0.1)\\n    * 100.0\\n    / CAM16_F_L\\n    * pow((27.13 * delta) / max(400.0 - delta, 1e-6), 1.0 / 0.42);\\n}\\n\\nvec3 xyz_to_cam16ucs(vec3 xyz) {\\n  float R = 0.401288 * xyz.x + 0.650173 * xyz.y - 0.051461 * xyz.z;\\n  float G = -0.250268 * xyz.x + 1.204414 * xyz.y + 0.045854 * xyz.z;\\n  float B = -0.002079 * xyz.x + 0.048952 * xyz.y + 0.953127 * xyz.z;\\n\\n  float R_c = R * CAM16_D_R;\\n  float G_c = G * CAM16_D_G;\\n  float B_c = B * CAM16_D_B;\\n\\n  float R_a = cam16_adapt_component(R_c);\\n  float G_a = cam16_adapt_component(G_c);\\n  float B_a = cam16_adapt_component(B_c);\\n\\n  float a = R_a - 12.0 * G_a / 11.0 + B_a / 11.0;\\n  float b = (R_a + G_a - 2.0 * B_a) / 9.0;\\n\\n  // Guard atan(0,0): undefined in GLSL ES (NaN on some drivers). Achromatic\\n  // colors have a=b=0 exactly; their hue is meaningless, any finite value works.\\n  bool achromatic = abs(a) < 1e-9 && abs(b) < 1e-9;\\n  float h = achromatic ? 0.0 : atan(b, a) / TWO_PI;\\n  if (h < 0.0) h += 1.0;\\n  float hDeg = h * 360.0;\\n  float hh = hDeg + (hDeg < 20.14 ? 360.0 : 0.0);\\n\\n  float e_t = 0.25 * (cos(hh / 180.0 * M_PI + 2.0) + 3.8);\\n  float A = CAM16_N_BB * (2.0 * R_a + G_a + 0.05 * B_a - 0.305);\\n  float J = 100.0 * pow(max(A / CAM16_A_W, 0.0), CAM16_SC * CAM16_Z);\\n  float denom = R_a + G_a + 21.0 / 20.0 * B_a;\\n  float t = denom == 0.0\\n    ? 0.0\\n    : (50000.0 / 13.0 * CAM16_SN_C * CAM16_N_CB * e_t * length(vec2(a, b))) / denom;\\n  float C = pow(max(t, 0.0), 0.9) * sqrt(max(J, 0.0) / 100.0) * pow(1.64 - pow(0.29, CAM16_N), 0.73);\\n  float M = C * pow(CAM16_F_L, 0.25);\\n  float Jp = J * 1.7 / (1.0 + 0.007 * J);\\n  float Mp = log(1.0 + 0.0228 * M) / 0.0228;\\n  float hRad = hDeg / 180.0 * M_PI;\\n\\n  return vec3(Jp, Mp * cos(hRad), Mp * sin(hRad));\\n}\\n\\nvec3 srgb_to_cam16ucs(vec3 srgb) {\\n  vec3 lin = srgb2rgb(srgb);\\n  vec3 xyz = vec3(\\n    0.4124564 * lin.r + 0.3575761 * lin.g + 0.1804375 * lin.b,\\n    0.2126729 * lin.r + 0.7151522 * lin.g + 0.0721750 * lin.b,\\n    0.0193339 * lin.r + 0.1191920 * lin.g + 0.9503041 * lin.b\\n  ) * 100.0;\\n  return xyz_to_cam16ucs(xyz);\\n}\\n\\nvec3 cam16ucs_to_xyz(vec3 jab) {\\n  float Jp = clamp(jab.x, 0.0, CAM16_MAX_JP);\\n  float ap = jab.y;\\n  float bp = jab.z;\\n\\n  float J = Jp / max(1.7 - 0.007 * Jp, 1e-6);\\n  // J=0 is always black regardless of a'/b'; non-zero a'/b' at J=0 cause\\n  // t to blow up (divides by sqrt(J/100)~0) producing garbage XYZ.\\n  if (J < 1e-4) return vec3(0.0);\\n\\n  float Mp = length(vec2(ap, bp));\\n  float M = (exp(0.0228 * Mp) - 1.0) / 0.0228;\\n  float C = M / pow(CAM16_F_L, 0.25);\\n\\n  float hRad = atan(bp, ap);\\n  float hDeg = degrees(hRad);\\n  if (hDeg < 0.0) hDeg += 360.0;\\n  float hh = hDeg + (hDeg < 20.14 ? 360.0 : 0.0);\\n\\n  float t = pow(\\n    C / (sqrt(J / 100.0) * pow(1.64 - pow(0.29, CAM16_N), 0.73)),\\n    1.0 / 0.9\\n  );\\n  float e_t = 0.25 * (cos(hh / 180.0 * M_PI + 2.0) + 3.8);\\n  float A = CAM16_A_W * pow(J / 100.0, 1.0 / (CAM16_SC * CAM16_Z));\\n  float P1 = ((50000.0 / 13.0) * CAM16_SN_C * CAM16_N_CB * e_t) / max(t, 1e-6);\\n  float P2 = A / CAM16_N_BB + 0.305;\\n  float P3 = 21.0 / 20.0;\\n\\n  float sin_h = sin(hRad);\\n  float cos_h = cos(hRad);\\n  float n = P2 * (2.0 + P3) * (460.0 / 1403.0);\\n  float a = 0.0;\\n  float b = 0.0;\\n\\n  if (t > 0.0) {\\n    if (abs(sin_h) >= abs(cos_h)) {\\n      float safeSin = abs(sin_h) < 1e-6 ? (sin_h < 0.0 ? -1e-6 : 1e-6) : sin_h;\\n      float P4 = P1 / safeSin;\\n      b = n / (\\n        P4 + (2.0 + P3) * (220.0 / 1403.0) * (cos_h / safeSin)\\n        - (27.0 / 1403.0)\\n        + P3 * (6300.0 / 1403.0)\\n      );\\n      a = b * (cos_h / safeSin);\\n    } else {\\n      float safeCos = abs(cos_h) < 1e-6 ? (cos_h < 0.0 ? -1e-6 : 1e-6) : cos_h;\\n      float P5 = P1 / safeCos;\\n      a = n / (\\n        P5 + (2.0 + P3) * (220.0 / 1403.0)\\n        - ((27.0 / 1403.0) - P3 * (6300.0 / 1403.0)) * (sin_h / safeCos)\\n      );\\n      b = a * (sin_h / safeCos);\\n    }\\n  }\\n\\n  vec3 rgb_a = vec3(\\n    (460.0 * P2 + 451.0 * a + 288.0 * b) / 1403.0,\\n    (460.0 * P2 - 891.0 * a - 261.0 * b) / 1403.0,\\n    (460.0 * P2 - 220.0 * a - 6300.0 * b) / 1403.0\\n  );\\n\\n  vec3 rgb_c = vec3(\\n    cam16_unadapt_component(rgb_a.r),\\n    cam16_unadapt_component(rgb_a.g),\\n    cam16_unadapt_component(rgb_a.b)\\n  );\\n  vec3 rgb = vec3(rgb_c.r / CAM16_D_R, rgb_c.g / CAM16_D_G, rgb_c.b / CAM16_D_B);\\n\\n  return vec3(\\n    CAM16_INV_CAT16_00 * rgb.r + CAM16_INV_CAT16_01 * rgb.g + CAM16_INV_CAT16_02 * rgb.b,\\n    CAM16_INV_CAT16_10 * rgb.r + CAM16_INV_CAT16_11 * rgb.g + CAM16_INV_CAT16_12 * rgb.b,\\n    CAM16_INV_CAT16_20 * rgb.r + CAM16_INV_CAT16_21 * rgb.g + CAM16_INV_CAT16_22 * rgb.b\\n  );\\n}\\n\\nvec3 xyz_to_srgb(vec3 xyz) {\\n  vec3 lin = vec3(\\n    3.2404542 * xyz.x - 1.5371385 * xyz.y - 0.4985314 * xyz.z,\\n    -0.9692660 * xyz.x + 1.8760108 * xyz.y + 0.0415560 * xyz.z,\\n    0.0556434 * xyz.x - 0.2040259 * xyz.y + 1.0572252 * xyz.z\\n  ) / 100.0;\\n  return vec3(\\n    srgb_transfer_function(lin.r),\\n    srgb_transfer_function(lin.g),\\n    srgb_transfer_function(lin.b)\\n  );\\n}\\n\\nvec3 cam16ucs_to_srgb(vec3 jab) {\\n  return xyz_to_srgb(cam16ucs_to_xyz(jab));\\n}\"","export default \"#ifndef M_PI\\n#define M_PI 3.1415926535897932384626433832795\\n#endif\\n\\n// \\\"Redmean\\\" weighted RGB distance (Thiadmer Riemersma,\\n// https://www.compuphase.com/cmetric.htm), rescaled from 0–255 to 0–1.\\n// Operates on sRGB values directly (no linearisation needed).\\n// Weights red and blue channels by the mean red value, which improves\\n// perceptual uniformity compared to plain Euclidean RGB at minimal cost.\\nfloat redmean(vec3 c1, vec3 c2) {\\n    float rMean = (c1.r + c2.r) * 0.5;\\n    vec3 d = c1 - c2;\\n    return sqrt((2.0 + rMean) * d.r*d.r + 4.0 * d.g*d.g + (3.0 - rMean) * d.b*d.b);\\n}\\n\\n// Kotsarenko & Ramos (2010): weighted Euclidean distance in YIQ.\\n// \\\"Measuring perceived color difference using YIQ NTSC transmission color\\n// space in mobile applications\\\" — operates on gamma-encoded sRGB, like the\\n// paper. FCC 1953 NTSC matrix; weights from the paper's optimization.\\nvec3 srgb_to_yiq(vec3 c) {\\n    return vec3(\\n        0.299    * c.r + 0.587    * c.g + 0.114    * c.b,\\n        0.595716 * c.r - 0.274453 * c.g - 0.321263 * c.b,\\n        0.211456 * c.r - 0.522591 * c.g + 0.311135 * c.b\\n    );\\n}\\n\\nfloat kotsarenkoRamosYIQ(vec3 yiq1, vec3 yiq2) {\\n    vec3 d = yiq1 - yiq2;\\n    return sqrt(0.5053 * d.x * d.x + 0.299 * d.y * d.y + 0.1957 * d.z * d.z);\\n}\\n\\n// srgb_to_cielab / srgb_to_cielab_d50 live in cielab2rgb.frag.glsl (included before this file)\\n\\n// CIE76: plain Euclidean distance in CIELab\\nfloat deltaE76(vec3 lab1, vec3 lab2) {\\n    return distance(lab1, lab2);\\n}\\n\\n// CIE94: weighted chroma/hue corrections, cheaper than CIEDE2000\\n// Uses graphics application constants: kL=1, K1=0.045, K2=0.015\\nfloat deltaE94(vec3 lab1, vec3 lab2) {\\n    float dL = lab1.x - lab2.x;\\n    float da = lab1.y - lab2.y;\\n    float db = lab1.z - lab2.z;\\n    float C1 = sqrt(lab1.y * lab1.y + lab1.z * lab1.z);\\n    float C2 = sqrt(lab2.y * lab2.y + lab2.z * lab2.z);\\n    float dC = C1 - C2;\\n    float dH = sqrt(max(0.0, da*da + db*db - dC*dC));\\n    float SC = 1.0 + 0.045 * C1;\\n    float SH = 1.0 + 0.015 * C1;\\n    return sqrt(dL*dL + (dC/SC)*(dC/SC) + (dH/SH)*(dH/SH));\\n}\\n\\n// CIEDE2000\\nfloat deltaE2000(vec3 lab1, vec3 lab2) {\\n    float L1 = lab1.x, a1 = lab1.y, b1 = lab1.z;\\n    float L2 = lab2.x, a2 = lab2.y, b2 = lab2.z;\\n\\n    // Chroma\\n    float C1 = sqrt(a1*a1 + b1*b1);\\n    float C2 = sqrt(a2*a2 + b2*b2);\\n    float Cavg = (C1 + C2) * 0.5;\\n    float Cavg7 = pow(Cavg, 7.0);\\n\\n    // G factor: adjustment to a* axis\\n    float G = 0.5 * (1.0 - sqrt(Cavg7 / (Cavg7 + 6103515625.0))); // 25^7\\n\\n    float a1p = a1 * (1.0 + G);\\n    float a2p = a2 * (1.0 + G);\\n    float C1p = sqrt(a1p*a1p + b1*b1);\\n    float C2p = sqrt(a2p*a2p + b2*b2);\\n\\n    // Guard atan(0,0): GLSL ES leaves that undefined, so skip it for achromatic colors.\\n    // When a color has no chroma its hue angle is meaningless — we just need it to\\n    // be a well-defined number so it doesn't corrupt the rest of the formula.\\n    bool c1Achromatic = C1p < 1e-6;\\n    bool c2Achromatic = C2p < 1e-6;\\n\\n    float h1p = c1Achromatic ? 0.0 : atan(b1, a1p);\\n    if (h1p < 0.0) h1p += TWO_PI;\\n    float h2p = c2Achromatic ? 0.0 : atan(b2, a2p);\\n    if (h2p < 0.0) h2p += TWO_PI;\\n\\n    // Deltas\\n    float dLp = L2 - L1;\\n    float dCp = C2p - C1p;\\n\\n    float dhp = 0.0;\\n    if (!c1Achromatic && !c2Achromatic) {\\n        dhp = h2p - h1p;\\n        if      (dhp >  M_PI) dhp -= TWO_PI;\\n        else if (dhp < -M_PI) dhp += TWO_PI;\\n    }\\n    float dHp = 2.0 * sqrt(C1p * C2p) * sin(dhp * 0.5);\\n\\n    // Averages\\n    float Lp = (L1 + L2) * 0.5;\\n    float Cp = (C1p + C2p) * 0.5;\\n\\n    // When one color is achromatic, its hue is 0 and the average is simply the other's hue\\n    float hp;\\n    if (c1Achromatic || c2Achromatic) {\\n        hp = h1p + h2p;\\n    } else if (abs(h1p - h2p) <= M_PI) {\\n        hp = (h1p + h2p) * 0.5;\\n    } else if (h1p + h2p < TWO_PI) {\\n        hp = (h1p + h2p + TWO_PI) * 0.5;\\n    } else {\\n        hp = (h1p + h2p - TWO_PI) * 0.5;\\n    }\\n\\n    float T = 1.0\\n        - 0.17 * cos(hp - radians(30.0))\\n        + 0.24 * cos(2.0 * hp)\\n        + 0.32 * cos(3.0 * hp + radians(6.0))\\n        - 0.20 * cos(4.0 * hp - radians(63.0));\\n\\n    // Weighting functions\\n    float Lpm50sq = (Lp - 50.0) * (Lp - 50.0);\\n    float SL = 1.0 + 0.015 * Lpm50sq / sqrt(20.0 + Lpm50sq);\\n    float SC = 1.0 + 0.045 * Cp;\\n    float SH = 1.0 + 0.015 * Cp * T;\\n\\n    // Rotation term\\n    float Cp7 = pow(Cp, 7.0);\\n    float RC = 2.0 * sqrt(Cp7 / (Cp7 + 6103515625.0));\\n    float hpDeg = degrees(hp);\\n    float dTheta = radians(30.0) * exp(-((hpDeg - 275.0) / 25.0) * ((hpDeg - 275.0) / 25.0));\\n    float RT = -sin(2.0 * dTheta) * RC;\\n\\n    float dLn = dLp / SL;\\n    float dCn = dCp / SC;\\n    float dHn = dHp / SH;\\n\\n    return sqrt(dLn*dLn + dCn*dCn + dHn*dHn + RT * dCn * dHn);\\n}\\n\"","export default \"// DISTANCE_METRIC define: 0=rgb, 1=oklab, 2=deltaE76, 3=deltaE2000, 4=redmean, 5=deltaE94, 6=oklrab, 7=cielabD50, 8=okLightness, 9=liMatch, 10=cam16ucsD65, 11=kotsarenkoRamosYIQ\\n\\nuniform sampler2D paletteMetricTexture;\\nuniform int uPaletteSize;\\n\\nvec3 closestColor(vec3 color, sampler2D paletteTexture) {\\n  float minDist = 1000000.0;\\n  vec3 closest = vec3(0.0);\\n\\n  // Pre-convert the input color once (palette entries pre-converted on CPU).\\n  #if DISTANCE_METRIC == 1\\n    vec3 colorConverted = linear_srgb_to_oklab(srgb2rgb(color));\\n  #elif DISTANCE_METRIC == 6\\n    vec3 _lab6 = linear_srgb_to_oklab(srgb2rgb(color));\\n    vec3 colorConverted = vec3(toe(_lab6.x), _lab6.y, _lab6.z);\\n  #elif DISTANCE_METRIC == 7\\n    vec3 colorConverted = srgb_to_cielab_d50(color);\\n  #elif DISTANCE_METRIC == 8 || DISTANCE_METRIC == 9\\n    vec3 colorConverted = linear_srgb_to_oklab(srgb2rgb(color));\\n  #elif DISTANCE_METRIC == 10\\n    vec3 colorConverted = srgb_to_cam16ucs(color);\\n  #elif DISTANCE_METRIC == 11\\n    vec3 colorConverted = srgb_to_yiq(color);\\n  #elif DISTANCE_METRIC == 2 || DISTANCE_METRIC == 3 || DISTANCE_METRIC == 5\\n    vec3 colorConverted = srgb_to_cielab(color);\\n  #else\\n    vec3 colorConverted = color;\\n  #endif\\n\\n  for (int i = 0; i < uPaletteSize; i++) {\\n    vec3 paletteColor = texelFetch(paletteTexture, ivec2(i, 0), 0).rgb;\\n\\n    float dist;\\n    #if DISTANCE_METRIC == 3\\n      dist = deltaE2000(colorConverted, texelFetch(paletteMetricTexture, ivec2(i, 0), 0).rgb);\\n    #elif DISTANCE_METRIC == 4\\n      dist = redmean(color, paletteColor);\\n    #elif DISTANCE_METRIC == 5\\n      // CIE94 is asymmetric (SC/SH derive from the first argument's chroma);\\n      // the palette entry is the reference, so it goes first.\\n      dist = deltaE94(texelFetch(paletteMetricTexture, ivec2(i, 0), 0).rgb, colorConverted);\\n    #elif DISTANCE_METRIC == 8\\n      dist = abs(colorConverted.x - texelFetch(paletteMetricTexture, ivec2(i, 0), 0).x);\\n    #elif DISTANCE_METRIC == 9\\n      vec3 _pm9 = texelFetch(paletteMetricTexture, ivec2(i, 0), 0).rgb;\\n      float _t9 = LI_MATCH_T;\\n      dist = distance(colorConverted, _pm9) * (1.0 - _t9) + abs(colorConverted.x - _pm9.x) * _t9;\\n    #elif DISTANCE_METRIC == 11\\n      dist = kotsarenkoRamosYIQ(colorConverted, texelFetch(paletteMetricTexture, ivec2(i, 0), 0).rgb);\\n    #else\\n      dist = distance(colorConverted, texelFetch(paletteMetricTexture, ivec2(i, 0), 0).rgb);\\n    #endif\\n\\n    if (dist < minDist) {\\n      minDist = dist;\\n      closest = paletteColor;\\n    }\\n  }\\n\\n  return closest;\\n}\\n\"","// @ts-ignore\nimport shaderSRGB2RGB from './shaders/srgb2rgb.frag.glsl?raw' assert { type: 'raw' };\n// @ts-ignore\nimport shaderOKLab from './shaders/oklab.frag.glsl?raw' assert { type: 'raw' };\n// @ts-ignore\nimport shaderHSL2RGB from './shaders/hsl2rgb.frag.glsl?raw' assert { type: 'raw' };\n// @ts-ignore\nimport shaderHSV2RGB from './shaders/hsv2rgb.frag.glsl?raw' assert { type: 'raw' };\n// @ts-ignore\nimport shaderLCH2RGB from './shaders/lch2rgb.frag.glsl?raw' assert { type: 'raw' };\n// @ts-ignore\nimport shaderHWB2RGB from './shaders/hwb2rgb.frag.glsl?raw' assert { type: 'raw' };\n// @ts-ignore\nimport shaderCIELab2RGB from './shaders/cielab2rgb.frag.glsl?raw' assert { type: 'raw' };\n// @ts-ignore\nimport shaderCAM16UCS from './shaders/cam16ucs.frag.glsl?raw' assert { type: 'raw' };\n// @ts-ignore\nimport shaderDeltaE from './shaders/deltaE.frag.glsl?raw' assert { type: 'raw' };\n// @ts-ignore\nimport shaderClosestColor from './shaders/closestColor.frag.glsl?raw' assert { type: 'raw' };\n\n// Include order matters:\n//   oklab        – M_PI, cbrt(), srgb_transfer_function(), srgb_transfer_function_inv(), okhsv/okhsl_to_srgb(), …\n//   srgb2rgb     – srgb2rgb() wraps srgb_transfer_function_inv from oklab\n//   hsl2rgb, hsv2rgb, lch2rgb – color model conversions (lch2rgb uses M_PI + srgb_transfer_function)\n//   cam16ucsD65  – srgb_to_cam16ucs() under fixed D65 CAT16 viewing conditions\n//   deltaE       – srgb_to_cielab(), deltaE76/94/2000() (uses srgb2rgb, cbrt, M_PI, TWO_PI)\n//   closestColor – branches on DISTANCE_METRIC define; uses everything above\n//\n// Defines (compile-time, prepended to shader source — trigger recompile, no runtime branching):\n//   DISTANCE_METRIC  int  0=rgb 1=oklab 2=deltaE76(=cielabD65) 3=deltaE2000 4=redmean 5=deltaE94 6=oklrab 7=cielabD50 8=okLightness 9=liMatch 10=cam16ucsD65 11=kotsarenkoRamosYIQ\n//   COLOR_MODEL      int  0=rgb 1=rgb12bit 2=rgb8bit 3=oklab 4=okhsv 5=okhsvPolar\n//                         6=okhsl 7=okhslPolar 8=oklch 9=oklchPolar 10=hsv 11=hsvPolar\n//                         12=hsl 13=hslPolar 14=hwb 15=hwbPolar 16=oklrab 17=oklrch\n//                         18=oklrchPolar 19=cielab 20=cielch 21=cielchPolar\n//                         22=cielabD50 23=cielchD50 24=cielchD50Polar 25=rgb18bit 26=rgb6bit\n//                         27=rgb15bit 28=spectrum 29=oklchDiag 30=oklrchDiag 31=cam16ucsD65 32=cam16ucsD65Polar\n//   PROGRESS_AXIS    int  0=x 1=y 2=z\n//   INVERT_X         flag (defined = true)\n//   INVERT_Y         flag (defined = true)\n//   INVERT_Z         flag (defined = true)\n//   AUTO_FLIP_Y      flag (defined = true)\n//   SHOW_RAW         flag (defined = true)\n\nexport const vertexShaderSrc = `\nprecision highp float;\nlayout(location = 0) in vec2 a_position;\nout vec2 vUv;\nvoid main() {\n  vUv = a_position * 0.5 + 0.5;\n  gl_Position = vec4(a_position, 0.0, 1.0);\n}`;\n\n// modelToRGB and main are separated so the selective assembler can reuse them.\nexport const modelToRGBSrc = `\n// Display bounds for the unbounded axes of each model.\n// CIELab values follow the CSS Color 4 reference ranges\n// (https://www.w3.org/TR/css-color-4/); the OKLab bound is deliberately wider\n// than CSS's ±0.4 so the full P3/Rec2020 a/b extent stays on-axis.\n// (OKLCH chroma has its own gamut-fitted bound: OKLCH_MAX_C in lch2rgb.frag.glsl.)\nconst float OKLAB_MAX_AB = 0.5;   // wider than the CSS oklab() ±0.4 reference range\nconst float CIELAB_MAX_AB = 125.0; // CSS lab() a/b reference range\nconst float CIELCH_MAX_C  = 150.0; // CSS lch() C reference range\n\nvec3 cam16D65CoordsToJab(vec3 colorCoords) {\n  #if COLOR_MODEL == 31\n    return vec3(\n      colorCoords.z * CAM16_MAX_JP,\n      (colorCoords.x - 0.5) * 2.0 * CAM16_MAX_AB,\n      (colorCoords.y - 0.5) * 2.0 * CAM16_MAX_AB\n    );\n  #elif COLOR_MODEL == 32\n    float angle31 = colorCoords.x * TWO_PI;\n    float radius31 = colorCoords.y * CAM16_MAX_AB;\n    return vec3(\n      colorCoords.z * CAM16_MAX_JP,\n      cos(angle31) * radius31,\n      sin(angle31) * radius31\n    );\n  #else\n    return vec3(0.0);\n  #endif\n}\n\n#if COLOR_MODEL == 1\nvec3 quantizeRGB444(vec3 colorCoords) {\n  vec3 rgb = clamp(colorCoords, 0.0, 1.0);\n  vec3 levels = min(floor(rgb * 16.0), vec3(15.0));\n  return levels / 15.0;\n}\n#endif\n\n#if COLOR_MODEL == 2\nvec3 quantizeRGB332(vec3 colorCoords) {\n  vec3 rgb = clamp(colorCoords, 0.0, 1.0);\n  float r = min(floor(rgb.r * 8.0), 7.0) / 7.0;\n  float g = min(floor(rgb.g * 8.0), 7.0) / 7.0;\n  float b = min(floor(rgb.b * 4.0), 3.0) / 3.0;\n  return vec3(r, g, b);\n}\n#endif\n\n#if COLOR_MODEL == 25\nvec3 quantizeRGB666(vec3 colorCoords) {\n  vec3 rgb = clamp(colorCoords, 0.0, 1.0);\n  vec3 levels = min(floor(rgb * 64.0), vec3(63.0));\n  return levels / 63.0;\n}\n#endif\n\n#if COLOR_MODEL == 26\nvec3 quantizeRGB222(vec3 colorCoords) {\n  vec3 rgb = clamp(colorCoords, 0.0, 1.0);\n  vec3 levels = min(floor(rgb * 4.0), vec3(3.0));\n  return levels / 3.0;\n}\n#endif\n\n#if COLOR_MODEL == 27\nvec3 quantizeRGB555(vec3 colorCoords) {\n  vec3 rgb = clamp(colorCoords, 0.0, 1.0);\n  vec3 levels = min(floor(rgb * 32.0), vec3(31.0));\n  return levels / 31.0;\n}\n#endif\n\n#if COLOR_MODEL == 28\n// CIE 1931 XYZ color matching function approximation (Wyman et al. 2013)\nfloat cie_x(float w) {\n  float t1 = (w - 442.0) * ((w < 442.0) ? 0.0624 : 0.0374);\n  float t2 = (w - 599.8) * ((w < 599.8) ? 0.0264 : 0.0323);\n  float t3 = (w - 501.1) * ((w < 501.1) ? 0.0490 : 0.0382);\n  return 0.362 * exp(-0.5*t1*t1) + 1.056 * exp(-0.5*t2*t2) - 0.065 * exp(-0.5*t3*t3);\n}\nfloat cie_y(float w) {\n  float t1 = (w - 568.8) * ((w < 568.8) ? 0.0213 : 0.0247);\n  float t2 = (w - 530.9) * ((w < 530.9) ? 0.0613 : 0.0322);\n  return 0.821 * exp(-0.5*t1*t1) + 0.286 * exp(-0.5*t2*t2);\n}\nfloat cie_z(float w) {\n  float t1 = (w - 437.0) * ((w < 437.0) ? 0.0845 : 0.0278);\n  float t2 = (w - 459.0) * ((w < 459.0) ? 0.0385 : 0.0725);\n  return 1.217 * exp(-0.5*t1*t1) + 0.681 * exp(-0.5*t2*t2);\n}\n// Wavelength → OKLab (via XYZ → linear sRGB → OKLab)\nvec3 wavelength_to_oklab(float nm) {\n  float x = cie_x(nm), y = cie_y(nm), z = cie_z(nm);\n  // XYZ → linear sRGB (D65)\n  vec3 lin = vec3(\n     3.2404542 * x - 1.5371385 * y - 0.4985314 * z,\n    -0.9692660 * x + 1.8760108 * y + 0.0415560 * z,\n     0.0556434 * x - 0.2040259 * y + 1.0572252 * z\n  );\n  lin = max(lin, vec3(0.0));\n  return linear_srgb_to_oklab(lin);\n}\n#endif\n\nvec3 modelToRGB(vec3 colorCoords) {\n  #if COLOR_MODEL == 0\n    return colorCoords;\n  #elif COLOR_MODEL == 1\n    return quantizeRGB444(colorCoords);\n  #elif COLOR_MODEL == 2\n    return quantizeRGB332(colorCoords);\n  #elif COLOR_MODEL == 3\n    vec3 linear = oklab_to_linear_srgb(vec3(colorCoords.z, (colorCoords.x - 0.5) * OKLAB_MAX_AB * 2.0, (colorCoords.y - 0.5) * OKLAB_MAX_AB * 2.0));\n    return vec3(srgb_transfer_function(linear.r), srgb_transfer_function(linear.g), srgb_transfer_function(linear.b));\n  #elif COLOR_MODEL == 4 || COLOR_MODEL == 5\n    return okhsv_to_srgb(colorCoords);\n  #elif COLOR_MODEL == 6 || COLOR_MODEL == 7\n    return okhsl_to_srgb(colorCoords);\n  #elif COLOR_MODEL == 8 || COLOR_MODEL == 9 || COLOR_MODEL == 29\n    return lch2rgb(vec3(colorCoords.z, colorCoords.y, colorCoords.x));\n  #elif COLOR_MODEL == 30\n    return lch2rgb(vec3(toe_inv(colorCoords.z), colorCoords.y, colorCoords.x));\n  #elif COLOR_MODEL == 10 || COLOR_MODEL == 11\n    return hsv2rgb(colorCoords);\n  #elif COLOR_MODEL == 12 || COLOR_MODEL == 13\n    return hsl2rgb(colorCoords);\n  #elif COLOR_MODEL == 14 || COLOR_MODEL == 15\n    return hwb2rgb(colorCoords);\n  #elif COLOR_MODEL == 16\n    vec3 linear14 = oklab_to_linear_srgb(vec3(toe_inv(colorCoords.z), (colorCoords.x - 0.5) * OKLAB_MAX_AB * 2.0, (colorCoords.y - 0.5) * OKLAB_MAX_AB * 2.0));\n    return vec3(srgb_transfer_function(linear14.r), srgb_transfer_function(linear14.g), srgb_transfer_function(linear14.b));\n  #elif COLOR_MODEL == 17 || COLOR_MODEL == 18\n    return lch2rgb(vec3(toe_inv(colorCoords.z), colorCoords.y, colorCoords.x));\n  #elif COLOR_MODEL == 19\n    return cielab_d65_to_rgb(vec3(colorCoords.z * 100.0, (colorCoords.x - 0.5) * CIELAB_MAX_AB * 2.0, (colorCoords.y - 0.5) * CIELAB_MAX_AB * 2.0));\n  #elif COLOR_MODEL == 20 || COLOR_MODEL == 21\n    return cielab_d65_to_rgb(vec3(colorCoords.z * 100.0, colorCoords.y * CIELCH_MAX_C * cos(colorCoords.x * TWO_PI), colorCoords.y * CIELCH_MAX_C * sin(colorCoords.x * TWO_PI)));\n  #elif COLOR_MODEL == 22\n    return cielab_d50_to_rgb(vec3(colorCoords.z * 100.0, (colorCoords.x - 0.5) * CIELAB_MAX_AB * 2.0, (colorCoords.y - 0.5) * CIELAB_MAX_AB * 2.0));\n  #elif COLOR_MODEL == 23 || COLOR_MODEL == 24\n    return cielab_d50_to_rgb(vec3(colorCoords.z * 100.0, colorCoords.y * CIELCH_MAX_C * cos(colorCoords.x * TWO_PI), colorCoords.y * CIELCH_MAX_C * sin(colorCoords.x * TWO_PI)));\n  #elif COLOR_MODEL == 25\n    return quantizeRGB666(colorCoords);\n  #elif COLOR_MODEL == 26\n    return quantizeRGB222(colorCoords);\n  #elif COLOR_MODEL == 27\n    return quantizeRGB555(colorCoords);\n  #elif COLOR_MODEL == 28\n    // X = spectral position, Y = lightness modulation, Z = chroma scale\n    // All modulation in OKLab for perceptually uniform results (like censor's CAM16UCS approach)\n    float sx = colorCoords.x;\n    vec3 labSpec;\n    if (sx < 0.8) {\n      // 0..0.8 → wavelengths 410..665nm (visible range)\n      labSpec = wavelength_to_oklab(410.0 + (sx / 0.8) * 255.0);\n    } else {\n      // 0.8..1.0 → purple line (red to violet, mixed in OKLab)\n      float pt = (sx - 0.8) / 0.2;\n      labSpec = mix(wavelength_to_oklab(665.0), wavelength_to_oklab(410.0), pt);\n    }\n    // Y: t in [-1,1] — center = natural lightness, bottom = black, top = white\n    float st = 2.0 * colorCoords.y - 1.0;\n    // Modulate L toward 0 (black) or 1 (white)\n    float L = (st < 0.0)\n      ? mix(labSpec.x, 0.0, -st)\n      : mix(labSpec.x, 1.0,  st);\n    // Chroma fades parabolically toward extremes, scaled by Z\n    float chromaScale = (1.0 - st * st) * colorCoords.z;\n    float a = labSpec.y * chromaScale;\n    float b = labSpec.z * chromaScale;\n    // OKLab → linear sRGB → sRGB\n    vec3 linOut = oklab_to_linear_srgb(vec3(L, a, b));\n    return vec3(\n      srgb_transfer_function(max(linOut.r, 0.0)),\n      srgb_transfer_function(max(linOut.g, 0.0)),\n      srgb_transfer_function(max(linOut.b, 0.0))\n    );\n  #elif COLOR_MODEL == 31 || COLOR_MODEL == 32\n    return cam16ucs_to_srgb(cam16D65CoordsToJab(colorCoords));\n  #else\n    return colorCoords;\n  #endif\n}\n`;\n\nconst mainSrc = `\nvoid main(){\n  #ifdef OUTPUT_LINEAR\n    vec2 uv = uvOverride;\n  #else\n    vec2 uv = vUv;\n  #endif\n  #ifdef AUTO_FLIP_Y\n    uv.y = 1. - uv.y;\n  #endif\n\n  #if PROGRESS_AXIS == 1\n    vec3 colorCoords = vec3(uv.x, progress, uv.y);\n  #elif PROGRESS_AXIS == 2\n    vec3 colorCoords = vec3(uv.x, uv.y, 1. - progress);\n  #else\n    vec3 colorCoords = vec3(progress, uv.x, uv.y);\n  #endif\n\n  #if COLOR_MODEL == 5 || COLOR_MODEL == 7 || COLOR_MODEL == 9 || COLOR_MODEL == 11 || COLOR_MODEL == 13 || COLOR_MODEL == 18 || COLOR_MODEL == 21 || COLOR_MODEL == 24 || COLOR_MODEL == 32\n    vec2 toCenter = uv - 0.5;\n    float angle = atan(toCenter.y, toCenter.x);\n    float radius = length(toCenter) * 2.0;\n\n    #if PROGRESS_AXIS == 2\n      if (radius > 1.0) { discard; }\n      colorCoords = vec3((angle / TWO_PI), radius, 1. - progress);\n    #elif PROGRESS_AXIS == 1\n      colorCoords = vec3((angle / TWO_PI), 1. - progress, radius);\n      if (radius > 1.0) { discard; }\n    #else\n      float hue = 1.0 - abs(0.5 - progress * .5) * 2.0;\n      if (uv.x > 0.5) { hue += 0.5; }\n      colorCoords = vec3(hue, abs(0.5 - uv.x) * 2.0, uv.y);\n    #endif\n  #elif COLOR_MODEL == 15\n    vec2 toCenter = uv - 0.5;\n    float angle = atan(toCenter.y, toCenter.x);\n    float radius = length(toCenter) * 2.0;\n\n    #if PROGRESS_AXIS == 2\n      if (radius > 1.0) { discard; }\n      colorCoords = vec3(angle / TWO_PI, 1.0 - radius, progress);\n    #elif PROGRESS_AXIS == 1\n      if (radius > 1.0) { discard; }\n      colorCoords = vec3(angle / TWO_PI, radius, progress);\n    #else\n      float hue = 1.0 - abs(0.5 - progress * .5) * 2.0;\n      if (uv.x > 0.5) { hue += 0.5; }\n      colorCoords = vec3(hue, 1.0 - abs(0.5 - uv.x) * 2.0, uv.y);\n    #endif\n  #elif COLOR_MODEL == 29 || COLOR_MODEL == 30\n    // Diagonal complementary: x=hue, y&z form the diagonal.\n    // colorCoords already handles the axis permutation.\n    float compD29 = colorCoords.z - colorCoords.y;\n    float compHue29 = colorCoords.x * 0.5;\n    if (compD29 < 0.0) compHue29 += 0.5;\n    colorCoords = vec3(compHue29, abs(compD29), (colorCoords.y + colorCoords.z) * 0.5);\n  #endif\n\n  #ifdef INVERT_X\n    colorCoords.x = 1. - colorCoords.x;\n  #endif\n\n  #ifdef INVERT_Y\n    colorCoords.y = 1. - colorCoords.y;\n  #endif\n\n  #ifdef INVERT_Z\n    colorCoords.z = 1. - colorCoords.z;\n  #endif\n\n  vec3 rgb = modelToRGB(colorCoords);\n\n  #ifdef OUTPUT_LINEAR\n    // Float readback path: output unclamped linear RGB.\n    // modelToRGB returns sRGB — undo the transfer function to get linear.\n    #ifdef SHOW_RAW\n      fragColor = vec4(\n        srgb_transfer_function_inv(rgb.r),\n        srgb_transfer_function_inv(rgb.g),\n        srgb_transfer_function_inv(rgb.b),\n        1.0);\n    #else\n      vec3 matched = closestColor(clamp(rgb, 0.0, 1.0), paletteTexture);\n      fragColor = vec4(\n        srgb_transfer_function_inv(matched.r),\n        srgb_transfer_function_inv(matched.g),\n        srgb_transfer_function_inv(matched.b),\n        1.0);\n    #endif\n  #else\n    #ifdef GAMUT_CLIP\n    if (any(lessThan(rgb, vec3(0.0))) || any(greaterThan(rgb, vec3(1.0)))) {\n      fragColor = vec4(0.0);\n      return;\n    }\n    #endif\n\n    rgb = clamp(rgb, 0.0, 1.0);\n    #ifdef SHOW_RAW\n      fragColor = vec4(rgb, 1.);\n    #else\n      fragColor = vec4(closestColor(rgb, paletteTexture), 1.);\n    #endif\n  #endif\n}`;\n\n// Full fragment shader source with all includes — exported for users who want\n// to inspect or reuse the complete GLSL source.\nexport const fragmentShader =\n  `\nprecision highp float;\nprecision highp sampler2D;\nprecision highp sampler3D;\n#define TWO_PI 6.28318530718\n#define LI_MATCH_T vUv.x\nin vec2 vUv;\nout vec4 fragColor;\nuniform float progress;\nuniform sampler2D paletteTexture;\n\n${shaderOKLab}\n${shaderSRGB2RGB}\n${shaderHSL2RGB}\n${shaderHSV2RGB}\n${shaderLCH2RGB}\n${shaderHWB2RGB}\n${shaderCIELab2RGB}\n${shaderCAM16UCS}\n${shaderDeltaE}\n${shaderClosestColor}\n` +\n  modelToRGBSrc +\n  mainSrc;\n\n// ── Selective shader assembly ────────────────────────────────────────────────\n// Instead of compiling ALL shader includes every time, pick only the chunks\n// needed for the current colorModel + distanceMetric. This dramatically\n// reduces compiled shader size and speeds up recompiles.\n\ntype ShaderNeeds = {\n  oklab: boolean;\n  srgb2rgb: boolean;\n  hsl2rgb: boolean;\n  hsv2rgb: boolean;\n  lch2rgb: boolean;\n  hwb2rgb: boolean;\n  cielab2rgb: boolean;\n  cam16ucs: boolean;\n  deltaE: boolean;\n  closestColor: boolean;\n};\n\nfunction shaderNeedsForModel(model: number): Partial<ShaderNeeds> {\n  switch (model) {\n    case 0:\n    case 1:\n    case 2:\n    case 25:\n    case 26:\n    case 27:\n      return {}; // rgb, rgb12bit, rgb8bit, rgb18bit, rgb6bit, rgb15bit, rgb16bit\n    case 3:\n    case 16:\n      return { oklab: true }; // oklab, oklrab\n    case 4:\n    case 5:\n      return { oklab: true }; // okhsv, okhsvPolar\n    case 6:\n    case 7:\n      return { oklab: true }; // okhsl, okhslPolar\n    case 8:\n    case 9:\n    case 17:\n    case 18:\n      return { oklab: true, lch2rgb: true }; // oklch/oklrch + polar\n    case 10:\n    case 11:\n      return { hsv2rgb: true }; // hsv, hsvPolar\n    case 12:\n    case 13:\n      return { hsl2rgb: true }; // hsl, hslPolar\n    case 14:\n    case 15:\n      return { hwb2rgb: true }; // hwb, hwbPolar\n    case 19:\n    case 20:\n    case 21: // cielab, cielch, cielchPolar\n      return { oklab: true, srgb2rgb: true, cielab2rgb: true };\n    case 22:\n    case 23:\n    case 24: // cielabD50, cielchD50, cielchD50Polar\n      return { oklab: true, srgb2rgb: true, cielab2rgb: true };\n    case 28: // spectrum (uses srgb_transfer_function from oklab)\n      return { oklab: true };\n    case 29: // oklchDiag (same conversion as oklch)\n    case 30: // oklrchDiag (same conversion as oklrch)\n      return { oklab: true, lch2rgb: true };\n    case 31:\n    case 32:\n      return { oklab: true, srgb2rgb: true, cam16ucs: true };\n    default:\n      return {};\n  }\n}\n\nfunction shaderNeedsForMetric(metric: number): Partial<ShaderNeeds> {\n  switch (metric) {\n    case 0:\n      return {}; // rgb\n    case 1:\n    case 6:\n    case 8:\n    case 9:\n      return { oklab: true, srgb2rgb: true }; // oklab, oklrab, okLightness, liMatch\n    case 2:\n    case 3:\n    case 5: // deltaE76, deltaE2000, deltaE94\n      return { oklab: true, srgb2rgb: true, cielab2rgb: true, deltaE: true };\n    case 4:\n    case 11:\n      return { deltaE: true }; // redmean, kotsarenkoRamosYIQ\n    case 7:\n      return { oklab: true, srgb2rgb: true, cielab2rgb: true }; // cielabD50\n    case 10:\n      return { oklab: true, srgb2rgb: true, cam16ucs: true }; // cam16ucsD65\n    default:\n      return {};\n  }\n}\n\nfunction assembleChunks(needs: ShaderNeeds): string {\n  let src = '';\n  // oklab must come before srgb2rgb (srgb2rgb wraps srgb_transfer_function_inv)\n  if (needs.oklab) src += shaderOKLab + '\\n';\n  if (needs.srgb2rgb) src += shaderSRGB2RGB + '\\n';\n  if (needs.hsl2rgb) src += shaderHSL2RGB + '\\n';\n  if (needs.hsv2rgb) src += shaderHSV2RGB + '\\n';\n  if (needs.lch2rgb) src += shaderLCH2RGB + '\\n';\n  if (needs.hwb2rgb) src += shaderHWB2RGB + '\\n';\n  if (needs.cielab2rgb) src += shaderCIELab2RGB + '\\n';\n  if (needs.cam16ucs) src += shaderCAM16UCS + '\\n';\n  if (needs.deltaE) src += shaderDeltaE + '\\n';\n  if (needs.closestColor) src += shaderClosestColor + '\\n';\n  return src;\n}\n\nfunction resolveNeeds(colorModel: number, distanceMetric: number, showRaw: boolean): ShaderNeeds {\n  const modelNeeds = shaderNeedsForModel(colorModel);\n  const metricNeeds = showRaw ? {} : shaderNeedsForMetric(distanceMetric);\n  return {\n    oklab: !!(modelNeeds.oklab || metricNeeds.oklab),\n    srgb2rgb: !!(modelNeeds.srgb2rgb || metricNeeds.srgb2rgb),\n    hsl2rgb: !!modelNeeds.hsl2rgb,\n    hsv2rgb: !!modelNeeds.hsv2rgb,\n    lch2rgb: !!modelNeeds.lch2rgb,\n    hwb2rgb: !!modelNeeds.hwb2rgb,\n    cielab2rgb: !!(modelNeeds.cielab2rgb || metricNeeds.cielab2rgb),\n    cam16ucs: !!(modelNeeds.cam16ucs || metricNeeds.cam16ucs),\n    deltaE: !!metricNeeds.deltaE && !showRaw,\n    closestColor: !showRaw,\n  };\n}\n\nexport function assembleFragShader(\n  colorModel: number,\n  distanceMetric: number,\n  showRaw: boolean,\n  outputLinear = false,\n): string {\n  const needs = resolveNeeds(colorModel, distanceMetric, showRaw);\n  // OUTPUT_LINEAR needs srgb_transfer_function_inv from the oklab chunk\n  if (outputLinear) needs.oklab = true;\n  let src = `\nprecision highp float;\nprecision highp sampler2D;\nprecision highp sampler3D;\n#define TWO_PI 6.28318530718\n#define LI_MATCH_T vUv.x\nin vec2 vUv;\nout vec4 fragColor;\nuniform float progress;\nuniform sampler2D paletteTexture;\n`;\n  if (outputLinear) src += `uniform vec2 uvOverride;\\n`;\n  src += assembleChunks(needs);\n  src += modelToRGBSrc + mainSrc;\n  return src;\n}\n\n// ── 3D-specific shader sources ───────────────────────────────────────────────\n\n// Vertex shader: a unit cube [0,1]^3 projected with a model-view-proj matrix.\n// Passes the 3D position as the color coordinate to the fragment shader.\nexport const vertexShader3DCubeSrc = `\nprecision highp float;\nlayout(location = 0) in vec3 a_position;\nout vec3 vColorCoord;\n\nuniform mat4 uMVP;\nuniform float uPosition;\n#ifdef GAMUT_CLIP\nuniform mat3 uColorRotation;\nuniform float uSliceOffset;\n#endif\n\nvoid main() {\n  vec3 pos = a_position;\n  #ifdef GAMUT_CLIP\n    pos.x += uSliceOffset;\n    vColorCoord = uColorRotation * (pos - 0.5) + 0.5;\n  #else\n    pos.x = min(pos.x, uPosition);\n    vColorCoord = pos;\n  #endif\n  gl_Position = uMVP * vec4(pos - 0.5, 1.0);\n}`;\n\n// Cylinder vertex shader: always uses color-space rotation (ortho + fixed camera).\n// The mesh stores only position (3 floats) — polar conversion happens\n// per-pixel in the fragment shader.\nexport const vertexShader3DCylSrc = `\nprecision highp float;\nlayout(location = 0) in vec3 a_position;\nout vec3 vColorCoord;\n\nuniform mat4 uMVP;\nuniform mat3 uColorRotation;\n\nvoid main() {\n  vColorCoord = uColorRotation * a_position;\n  gl_Position = uMVP * vec4(a_position, 1.0);\n}`;\n\n// Fragment shader for the 3D view.\nconst mainSrc3D = `\nvoid main() {\n  vec3 cc = vColorCoord;\n\n  #ifdef IS_POLAR\n    // Rotated Cartesian → polar per-pixel (avoids atan interpolation artifacts)\n    float hue = atan(cc.z, cc.x) / TWO_PI;\n    if (hue < 0.0) hue += 1.0;\n    float r = length(cc.xz) * 2.0;\n    float h = cc.y + 0.5;\n    // Single discard: height bounds + position + shape envelope\n    #ifdef SHAPE_CONE\n      if (h < 0.0 || h > uPosition || r > h) discard;\n    #elif defined(SHAPE_CONE_INV)\n      if (h < 0.0 || h > uPosition || r > 1.0 - h) discard;\n    #elif defined(SHAPE_BICONE)\n      if (h < 0.0 || h > uPosition || r > 1.0 - abs(2.0 * h - 1.0)) discard;\n    #else\n      if (h < 0.0 || h > uPosition || r > 1.0) discard;\n    #endif\n    cc = vec3(hue, r, h);\n  #else\n    #ifdef GAMUT_CLIP\n      // Discard outside [0,1]³ — padding covers the rotated cube but\n      // out-of-range coords would duplicate via trig periodicity / mirroring.\n      if (any(lessThan(cc, vec3(0.0))) || any(greaterThan(cc, vec3(1.0)))) discard;\n    #endif\n    if (cc.x > uPosition) discard;\n  #endif\n\n  #if COLOR_MODEL == 29 || COLOR_MODEL == 30\n    float dD3 = cc.z - cc.y;\n    float dH3 = cc.x * 0.5;\n    if (dD3 < 0.0) dH3 += 0.5;\n    cc = vec3(dH3, abs(dD3), (cc.y + cc.z) * 0.5);\n  #endif\n\n  #ifdef INVERT_X\n    cc.x = 1.0 - cc.x;\n  #endif\n\n  #ifdef INVERT_Y\n    cc.y = 1.0 - cc.y;\n  #endif\n\n  #ifdef INVERT_Z\n    cc.z = 1.0 - cc.z;\n  #endif\n\n  vec3 rgb = modelToRGB(cc);\n\n  #ifdef GAMUT_CLIP\n    if (any(lessThan(rgb, vec3(-0.0))) || any(greaterThan(rgb, vec3(1.0)))) discard;\n  #endif\n\n  #ifdef SHOW_RAW\n    fragColor = vec4(clamp(rgb, 0.0, 1.0), 1.0);\n  #else\n    fragColor = vec4(closestColor(clamp(rgb, 0.0, 1.0), paletteTexture), 1.0);\n  #endif\n}`;\n\nconst mainSrc3DPrepass = `\nvoid main() {\n  vec3 cc = vColorCoord;\n\n  #ifdef IS_POLAR\n    float hue = atan(cc.z, cc.x) / TWO_PI;\n    if (hue < 0.0) hue += 1.0;\n    float r = length(cc.xz) * 2.0;\n    float h = cc.y + 0.5;\n    #ifdef SHAPE_CONE\n      if (h < 0.0 || h > uPosition || r > h) discard;\n    #elif defined(SHAPE_CONE_INV)\n      if (h < 0.0 || h > uPosition || r > 1.0 - h) discard;\n    #elif defined(SHAPE_BICONE)\n      if (h < 0.0 || h > uPosition || r > 1.0 - abs(2.0 * h - 1.0)) discard;\n    #else\n      if (h < 0.0 || h > uPosition || r > 1.0) discard;\n    #endif\n    cc = vec3(hue, r, h);\n  #else\n    #ifdef GAMUT_CLIP\n      if (any(lessThan(cc, vec3(0.0))) || any(greaterThan(cc, vec3(1.0)))) discard;\n    #endif\n    if (cc.x > uPosition) discard;\n  #endif\n\n  #if COLOR_MODEL == 29 || COLOR_MODEL == 30\n    float dD3p = cc.z - cc.y;\n    float dH3p = cc.x * 0.5;\n    if (dD3p < 0.0) dH3p += 0.5;\n    cc = vec3(dH3p, abs(dD3p), (cc.y + cc.z) * 0.5);\n  #endif\n\n  #ifdef INVERT_X\n    cc.x = 1.0 - cc.x;\n  #endif\n\n  #ifdef INVERT_Y\n    cc.y = 1.0 - cc.y;\n  #endif\n\n  #ifdef INVERT_Z\n    cc.z = 1.0 - cc.z;\n  #endif\n\n  #ifdef GAMUT_CLIP\n    vec3 rgb = modelToRGB(cc);\n    if (any(lessThan(rgb, vec3(-0.0))) || any(greaterThan(rgb, vec3(1.0)))) discard;\n  #endif\n\n  fragColor = vec4(1.0);\n}`;\n\nexport function assembleFragShader3D(\n  colorModel: number,\n  distanceMetric: number,\n  showRaw: boolean,\n): string {\n  const needs = resolveNeeds(colorModel, distanceMetric, showRaw);\n  let src = `\nprecision highp float;\nprecision highp sampler2D;\nprecision highp sampler3D;\n#define TWO_PI 6.28318530718\n#define LI_MATCH_T vColorCoord.x\nin vec3 vColorCoord;\nout vec4 fragColor;\nuniform sampler2D paletteTexture;\nuniform float uPosition;\n`;\n  src += assembleChunks(needs);\n  src += modelToRGBSrc + mainSrc3D;\n  return src;\n}\n\nexport function assembleFragShader3DPrepass(colorModel: number, gamutClip: boolean): string {\n  const needs = {\n    ...resolveNeeds(colorModel, 0, true),\n    closestColor: false,\n  };\n  let src = `\nprecision highp float;\nprecision highp sampler3D;\n#define TWO_PI 6.28318530718\nin vec3 vColorCoord;\nout vec4 fragColor;\nuniform float uPosition;\n`;\n  src += assembleChunks(needs);\n  if (gamutClip) src += modelToRGBSrc;\n  src += mainSrc3DPrepass;\n  return src;\n}\n\n// Pass-2 shader: reads from the FBO color texture, detects edges by comparing\n// N/S/E/W neighbors. Only opaque neighbors (a>0) participate in the comparison\n// so polar-disc edges don't bleed into the outline.\nexport const outlineFragmentShaderSrc = `\nprecision highp float;\nprecision highp sampler2D;\nin vec2 vUv;\nout vec4 fragColor;\nuniform sampler2D colorMap;\nuniform float outlineWidth;\nuniform vec2 resolution;\n\nvoid main() {\n  vec4 center = texture(colorMap, vUv);\n  if (center.a == 0.0) { fragColor = vec4(0.0); return; }\n  vec2 px = outlineWidth / resolution;\n  vec4 n0 = texture(colorMap, vUv + vec2( px.x, 0.0));\n  vec4 n1 = texture(colorMap, vUv + vec2(-px.x, 0.0));\n  vec4 n2 = texture(colorMap, vUv + vec2(0.0,  px.y));\n  vec4 n3 = texture(colorMap, vUv + vec2(0.0, -px.y));\n  if ((n0.a > 0.0 && any(notEqual(n0.rgb, center.rgb))) ||\n      (n1.a > 0.0 && any(notEqual(n1.rgb, center.rgb))) ||\n      (n2.a > 0.0 && any(notEqual(n2.rgb, center.rgb))) ||\n      (n3.a > 0.0 && any(notEqual(n3.rgb, center.rgb)))) {\n    fragColor = vec4(0.0);\n    return;\n  }\n  fragColor = center;\n}`;\n","import { Axis, ColorList } from './types.ts';\nimport {\n  computeMetricPalette,\n  initTexture,\n  uploadMetricTexture,\n  uploadPaletteTexture,\n} from './webgl.ts';\n\nexport const AXIS_MAP = { x: 0, y: 1, z: 2 } as const;\n\nexport const CAM16_UCS_D65_MODEL_ID = 31;\nexport const CAM16_UCS_D65_POLAR_MODEL_ID = 32;\n\nexport const COLOR_MODEL_MAP = {\n  rgb: 0,\n  rgb12bit: 1,\n  rgb8bit: 2,\n  rgb18bit: 25,\n  rgb6bit: 26,\n  rgb15bit: 27,\n  oklab: 3,\n  okhsv: 4,\n  okhsvPolar: 5,\n  okhsl: 6,\n  okhslPolar: 7,\n  oklch: 8,\n  oklchPolar: 9,\n  hsv: 10,\n  hsvPolar: 11,\n  hsl: 12,\n  hslPolar: 13,\n  hwb: 14,\n  hwbPolar: 15,\n  oklrab: 16,\n  oklrch: 17,\n  oklrchPolar: 18,\n  cielab: 19,\n  cielch: 20,\n  cielchPolar: 21,\n  cielabD50: 22,\n  cielchD50: 23,\n  cielchD50Polar: 24,\n  cam16ucsD65: CAM16_UCS_D65_MODEL_ID,\n  cam16ucsD65Polar: CAM16_UCS_D65_POLAR_MODEL_ID,\n  spectrum: 28,\n  oklchDiag: 29,\n  oklrchDiag: 30,\n} as const;\n\nexport const DISTANCE_METRIC_MAP = {\n  rgb: 0,\n  oklab: 1,\n  deltaE76: 2,\n  deltaE2000: 3,\n  redmean: 4,\n  // Deprecated alias: the formula was always Riemersma's \"redmean\", not the\n  // YIQ-based Kotsarenko/Ramos metric. Kept so existing configs keep working.\n  kotsarenkoRamos: 4,\n  deltaE94: 5,\n  oklrab: 6,\n  cielabD50: 7,\n  okLightness: 8,\n  liMatch: 9,\n  cam16ucsD65: 10,\n  // The genuine Kotsarenko & Ramos (2010) metric: weighted Euclidean in YIQ.\n  kotsarenkoRamosYIQ: 11,\n} as const;\n\ntype BaseRendererOptions = {\n  palette: ColorList;\n  width: number;\n  height: number;\n  pixelRatio: number;\n  observeResize: boolean;\n  container?: HTMLElement;\n  canvasClassName: string;\n};\n\nexport abstract class BasePaletteRenderer {\n  protected paletteState: ColorList;\n  protected cssWidth: number;\n  protected cssHeight: number;\n  protected pixelRatioState: number;\n\n  protected readonly canvasElement: HTMLCanvasElement;\n  protected readonly glContext: WebGL2RenderingContext;\n  protected readonly paletteTexture: WebGLTexture;\n  protected readonly metricTexture: WebGLTexture;\n\n  protected metricPaletteDirty = true;\n  protected animationFrameId: number | null = null;\n  protected destroyed = false;\n  protected readonly containerElement?: HTMLElement;\n  protected readonly observeResize: boolean;\n  protected resizeObserver: ResizeObserver | null = null;\n\n  protected constructor({\n    palette,\n    width,\n    height,\n    pixelRatio,\n    observeResize,\n    container,\n    canvasClassName,\n  }: BaseRendererOptions) {\n    this.paletteState = palette;\n    this.cssWidth = width;\n    this.cssHeight = height;\n    this.pixelRatioState = pixelRatio;\n    this.observeResize = observeResize;\n    this.containerElement = container;\n\n    this.canvasElement = document.createElement('canvas');\n    this.canvasElement.classList.add(canvasClassName);\n    const gl = this.canvasElement.getContext('webgl2', { antialias: false });\n    if (!gl) throw new Error('WebGL2 not supported');\n    // Disable dithering so float→8-bit conversion is deterministic across\n    // drivers (matters for getColorAtUV readback; no visual cost for flat fills).\n    gl.disable(gl.DITHER);\n    this.glContext = gl;\n\n    this.paletteTexture = gl.createTexture()!;\n    initTexture(gl, this.paletteTexture);\n    uploadPaletteTexture(gl, this.paletteTexture, this.paletteState);\n\n    this.metricTexture = gl.createTexture()!;\n    initTexture(gl, this.metricTexture);\n  }\n\n  protected normalizeInvertAxes(axes: Axis[]): Axis[] {\n    const uniqueAxes = new Set<Axis>();\n    axes.forEach((axis) => {\n      if (!(axis in AXIS_MAP)) throw new Error(\"invertAxes entries must be 'x', 'y', or 'z'\");\n      uniqueAxes.add(axis);\n    });\n    return [...uniqueAxes];\n  }\n\n  protected syncCanvasSize(width: number, height: number): { pw: number; ph: number } {\n    const nextWidth = Math.max(1, Math.round(width));\n    const nextHeight = Math.max(1, Math.round(height));\n    const pw = Math.max(1, Math.round(nextWidth * this.pixelRatioState));\n    const ph = Math.max(1, Math.round(nextHeight * this.pixelRatioState));\n    this.cssWidth = nextWidth;\n    this.cssHeight = nextHeight;\n    this.canvasElement.width = pw;\n    this.canvasElement.height = ph;\n    this.glContext.viewport(0, 0, pw, ph);\n    return { pw, ph };\n  }\n\n  protected syncCanvasSizeFromLayout(): { pw: number; ph: number; width: number; height: number } {\n    const rect = this.canvasElement.getBoundingClientRect();\n    const width = rect.width > 0 ? rect.width : this.cssWidth;\n    const height = rect.height > 0 ? rect.height : this.cssHeight;\n    const { pw, ph } = this.syncCanvasSize(width, height);\n    return { pw, ph, width: this.cssWidth, height: this.cssHeight };\n  }\n\n  protected schedulePaint(): void {\n    if (this.destroyed) return;\n    if (this.animationFrameId !== null) cancelAnimationFrame(this.animationFrameId);\n    this.animationFrameId = requestAnimationFrame(() => {\n      this.animationFrameId = null;\n      this.renderFrame();\n    });\n  }\n\n  protected flushScheduledPaint(): void {\n    if (this.animationFrameId !== null) {\n      cancelAnimationFrame(this.animationFrameId);\n      this.animationFrameId = null;\n    }\n  }\n\n  protected uploadMetricPalette(paletteSizeUniform: WebGLUniformLocation | null): void {\n    if (!this.metricPaletteDirty) return;\n    uploadMetricTexture(\n      this.glContext,\n      this.metricTexture,\n      computeMetricPalette(this.paletteState, this.currentMetricCode()),\n      this.paletteState.length,\n    );\n    if (paletteSizeUniform) this.glContext.uniform1i(paletteSizeUniform, this.paletteState.length);\n    this.metricPaletteDirty = false;\n  }\n\n  protected attachCanvas(): void {\n    this.containerElement?.appendChild(this.canvasElement);\n    const { pw, ph } = this.observeResize\n      ? this.syncCanvasSizeFromLayout()\n      : this.syncCanvasSize(this.cssWidth, this.cssHeight);\n    this.onSurfaceResized(pw, ph);\n    if (!this.observeResize || typeof ResizeObserver === 'undefined') return;\n    this.resizeObserver = new ResizeObserver(() => {\n      if (this.destroyed) return;\n      const { pw, ph } = this.syncCanvasSizeFromLayout();\n      this.onSurfaceResized(pw, ph);\n      this.schedulePaint();\n    });\n    this.resizeObserver.observe(this.canvasElement);\n  }\n\n  protected beginDestroy(): boolean {\n    if (this.destroyed) return false;\n    this.destroyed = true;\n    this.flushScheduledPaint();\n    return true;\n  }\n\n  protected destroyBaseResources(): void {\n    const gl = this.glContext;\n    this.resizeObserver?.disconnect();\n    this.resizeObserver = null;\n    gl.deleteTexture(this.paletteTexture);\n    gl.deleteTexture(this.metricTexture);\n    this.canvasElement.remove();\n    gl.getExtension('WEBGL_lose_context')?.loseContext();\n  }\n\n  protected onSurfaceResized(_pw: number, _ph: number): void {}\n\n  protected abstract currentMetricCode(): number;\n  protected abstract renderFrame(): void;\n\n  get canvas(): HTMLCanvasElement {\n    return this.canvasElement;\n  }\n\n  get width(): number {\n    return this.cssWidth;\n  }\n\n  get height(): number {\n    return this.cssHeight;\n  }\n\n  resize(width: number, height: number | null = null): void {\n    const { pw, ph } = this.syncCanvasSize(width, height ?? width);\n    this.onSurfaceResized(pw, ph);\n    this.schedulePaint();\n  }\n\n  /** Force a synchronous render immediately, bypassing the rAF schedule.\n   *  Use when the canvas/FBO must reflect the latest state right now — e.g.\n   *  before reading pixels back from the canvas. */\n  render(): void {\n    if (this.destroyed) return;\n    this.flushScheduledPaint();\n    this.renderFrame();\n  }\n\n  set palette(palette: ColorList) {\n    if (palette.length === 0) throw new Error('Palette must contain at least one color');\n    this.paletteState = palette;\n    uploadPaletteTexture(this.glContext, this.paletteTexture, palette);\n    this.metricPaletteDirty = true;\n    this.schedulePaint();\n  }\n\n  get palette(): ColorList {\n    return this.paletteState.slice();\n  }\n\n  set pixelRatio(value: number) {\n    this.pixelRatioState = value;\n    const { pw, ph } = this.observeResize\n      ? this.syncCanvasSizeFromLayout()\n      : this.syncCanvasSize(this.cssWidth, this.cssHeight);\n    this.onSurfaceResized(pw, ph);\n    this.schedulePaint();\n  }\n\n  get pixelRatio(): number {\n    return this.pixelRatioState;\n  }\n}\n","import {\n  ColorRGB,\n  PaletteVizOptions,\n  SupportedColorModels,\n  Axis,\n  DistanceMetric,\n} from './types.ts';\nimport { paletteToRGBA, randomPalette } from './palette.ts';\nimport { Defines, buildProgram, uploadPaletteTexture } from './webgl.ts';\nimport { vertexShaderSrc, assembleFragShader, outlineFragmentShaderSrc } from './shaderSrc.ts';\nimport {\n  AXIS_MAP,\n  BasePaletteRenderer,\n  COLOR_MODEL_MAP,\n  DISTANCE_METRIC_MAP,\n} from './rendererShared.ts';\n\nexport class PaletteViz extends BasePaletteRenderer {\n  // shader state\n  #position = 0.0;\n  #axis: Axis = 'y';\n  #colorModel: SupportedColorModels = 'okhsv';\n  #distanceMetric: DistanceMetric = 'oklab';\n  #invertAxes: Axis[] = [];\n  #showRaw = false;\n  #outlineWidth = 0;\n  #gamutClip = false;\n\n  // WebGL\n  #program: WebGLProgram | null = null;\n  #quadBuffer: WebGLBuffer | null = null;\n  #vao: WebGLVertexArrayObject | null = null;\n  #programDirty = false;\n\n  // cached uniform locations (re-queried after each program rebuild)\n  #uProgress: WebGLUniformLocation | null = null;\n  #uPaletteTexture: WebGLUniformLocation | null = null;\n  #uPaletteMetricTexture: WebGLUniformLocation | null = null;\n  #uPaletteSize: WebGLUniformLocation | null = null;\n\n  // FBO + blit/outline pass (always used — decouples render from display compositor)\n  #fbo: WebGLFramebuffer | null = null;\n  #fboTexture: WebGLTexture | null = null;\n  #blitProgram: WebGLProgram | null = null;\n  #uColorMap: WebGLUniformLocation | null = null;\n  #uOutlineWidth: WebGLUniformLocation | null = null;\n  #uOutlineResolution: WebGLUniformLocation | null = null;\n\n  // 1×1 float FBO for getColorAtUV_float (lazily created)\n  #floatFbo: WebGLFramebuffer | null = null;\n  #floatFboTexture: WebGLTexture | null = null;\n  #linearProgram: WebGLProgram | null = null;\n  #uLinearProgress: WebGLUniformLocation | null = null;\n  #uLinearPaletteTexture: WebGLUniformLocation | null = null;\n  #uLinearPaletteMetricTexture: WebGLUniformLocation | null = null;\n  #uLinearPaletteSize: WebGLUniformLocation | null = null;\n  #uLinearUvOverride: WebGLUniformLocation | null = null;\n  #linearProgramDirty = true;\n\n  constructor({\n    palette = randomPalette(),\n    width = 512,\n    height = 512,\n    pixelRatio = window.devicePixelRatio,\n    observeResize = false,\n    container,\n    colorModel = 'okhsv',\n    distanceMetric = 'oklab',\n    axis = 'y',\n    position = 0.0,\n    invertAxes = [],\n    showRaw = false,\n    outlineWidth = 0,\n    gamutClip = false,\n  }: PaletteVizOptions = {}) {\n    super({\n      palette,\n      width,\n      height,\n      pixelRatio,\n      observeResize,\n      container,\n      canvasClassName: 'palette-viz',\n    });\n    this.#colorModel = colorModel;\n    this.#distanceMetric = distanceMetric;\n    this.#axis = axis;\n    this.#position = position;\n    this.#invertAxes = this.normalizeInvertAxes(invertAxes);\n    this.#showRaw = showRaw;\n    this.#outlineWidth = outlineWidth;\n    this.#gamutClip = gamutClip;\n    const gl = this.glContext;\n\n    // Quad buffer + VAO — set up once, reused every frame.\n    // layout(location=0) in the vertex shader pins a_position to slot 0,\n    // so the VAO remains valid across shader recompiles.\n    this.#quadBuffer = gl.createBuffer()!;\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.#quadBuffer);\n    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);\n\n    this.#vao = gl.createVertexArray()!;\n    gl.bindVertexArray(this.#vao);\n    gl.enableVertexAttribArray(0);\n    gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);\n    gl.bindVertexArray(null);\n\n    this.#rebuildProgram();\n    this.syncCanvasSize(this.width, this.height);\n    this.#buildFBO();\n    this.attachCanvas();\n    this.schedulePaint();\n  }\n\n  #defines(): Defines {\n    const useImplicitPolarFlipY =\n      this.#colorModel.endsWith('Polar') && this.#invertAxes.includes('y');\n    return {\n      DISTANCE_METRIC: DISTANCE_METRIC_MAP[this.#distanceMetric],\n      COLOR_MODEL: COLOR_MODEL_MAP[this.#colorModel],\n      PROGRESS_AXIS: AXIS_MAP[this.#axis],\n      INVERT_X: this.#invertAxes.includes('x') ? 1 : false,\n      INVERT_Y: this.#invertAxes.includes('y') && !useImplicitPolarFlipY ? 1 : false,\n      INVERT_Z: this.#invertAxes.includes('z') ? 1 : false,\n      AUTO_FLIP_Y: useImplicitPolarFlipY ? 1 : false,\n      SHOW_RAW: this.#showRaw ? 1 : false,\n      GAMUT_CLIP: this.#gamutClip ? 1 : false,\n    };\n  }\n\n  #rebuildProgram(): void {\n    const gl = this.glContext;\n    if (this.#program) gl.deleteProgram(this.#program);\n    const fragSrc = assembleFragShader(\n      COLOR_MODEL_MAP[this.#colorModel],\n      DISTANCE_METRIC_MAP[this.#distanceMetric],\n      this.#showRaw,\n    );\n    this.#program = buildProgram(gl, this.#defines(), fragSrc, vertexShaderSrc);\n    this.#uProgress = gl.getUniformLocation(this.#program, 'progress');\n    this.#uPaletteTexture = gl.getUniformLocation(this.#program, 'paletteTexture');\n    this.#uPaletteMetricTexture = gl.getUniformLocation(this.#program, 'paletteMetricTexture');\n    this.#uPaletteSize = gl.getUniformLocation(this.#program, 'uPaletteSize');\n    this.metricPaletteDirty = true;\n    this.#linearProgramDirty = true;\n  }\n\n  #buildFBO(): void {\n    const gl = this.glContext;\n    this.#blitProgram = buildProgram(gl, {}, outlineFragmentShaderSrc, vertexShaderSrc);\n    this.#uColorMap = gl.getUniformLocation(this.#blitProgram, 'colorMap');\n    this.#uOutlineWidth = gl.getUniformLocation(this.#blitProgram, 'outlineWidth');\n    this.#uOutlineResolution = gl.getUniformLocation(this.#blitProgram, 'resolution');\n\n    this.#fboTexture = gl.createTexture()!;\n    this.#fbo = gl.createFramebuffer()!;\n    this.#resizeFBO(this.canvas.width, this.canvas.height);\n  }\n\n  #resizeFBO(pw: number, ph: number): void {\n    const gl = this.glContext;\n    gl.bindTexture(gl.TEXTURE_2D, this.#fboTexture);\n    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, pw, ph, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\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.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.bindTexture(gl.TEXTURE_2D, null);\n    gl.bindFramebuffer(gl.FRAMEBUFFER, this.#fbo);\n    gl.framebufferTexture2D(\n      gl.FRAMEBUFFER,\n      gl.COLOR_ATTACHMENT0,\n      gl.TEXTURE_2D,\n      this.#fboTexture,\n      0,\n    );\n    gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n  }\n\n  protected currentMetricCode(): number {\n    return DISTANCE_METRIC_MAP[this.#distanceMetric];\n  }\n\n  protected onSurfaceResized(pw: number, ph: number): void {\n    if (this.#fboTexture) this.#resizeFBO(pw, ph);\n  }\n\n  protected renderFrame(): void {\n    if (this.#programDirty) {\n      this.#rebuildProgram();\n      this.#programDirty = false;\n    }\n    const gl = this.glContext;\n\n    // ── Pass 1: closest-color render into FBO ────────────────────────────────\n    gl.bindFramebuffer(gl.FRAMEBUFFER, this.#fbo);\n\n    gl.useProgram(this.#program);\n    this.uploadMetricPalette(this.#uPaletteSize);\n    gl.uniform1f(this.#uProgress, this.#position);\n    gl.activeTexture(gl.TEXTURE0);\n    gl.bindTexture(gl.TEXTURE_2D, this.paletteTexture);\n    gl.uniform1i(this.#uPaletteTexture, 0);\n    gl.activeTexture(gl.TEXTURE1);\n    gl.bindTexture(gl.TEXTURE_2D, this.metricTexture);\n    gl.uniform1i(this.#uPaletteMetricTexture, 1);\n\n    gl.clearColor(0, 0, 0, 0);\n    gl.clear(gl.COLOR_BUFFER_BIT);\n    gl.bindVertexArray(this.#vao);\n    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n\n    // ── Pass 2: blit FBO to canvas (outline when enabled) ────────────────────\n    gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n    gl.useProgram(this.#blitProgram);\n    gl.activeTexture(gl.TEXTURE0);\n    gl.bindTexture(gl.TEXTURE_2D, this.#fboTexture);\n    gl.uniform1i(this.#uColorMap, 0);\n    gl.uniform1f(this.#uOutlineWidth, this.#showRaw ? 0 : this.#outlineWidth);\n    gl.uniform2f(this.#uOutlineResolution, this.canvas.width, this.canvas.height);\n\n    gl.clearColor(0, 0, 0, 0);\n    gl.clear(gl.COLOR_BUFFER_BIT);\n    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n    gl.bindVertexArray(null);\n  }\n\n  // ── Public API ──────────────────────────────────────────────────────────────\n\n  destroy(): void {\n    if (!this.beginDestroy()) return;\n    const gl = this.glContext;\n    if (this.#blitProgram) gl.deleteProgram(this.#blitProgram);\n    if (this.#fboTexture) gl.deleteTexture(this.#fboTexture);\n    if (this.#fbo) gl.deleteFramebuffer(this.#fbo);\n    if (this.#linearProgram) gl.deleteProgram(this.#linearProgram);\n    if (this.#floatFboTexture) gl.deleteTexture(this.#floatFboTexture);\n    if (this.#floatFbo) gl.deleteFramebuffer(this.#floatFbo);\n    gl.deleteProgram(this.#program);\n    gl.deleteBuffer(this.#quadBuffer);\n    gl.deleteVertexArray(this.#vao);\n    this.destroyBaseResources();\n  }\n\n  // ── Palette ─────────────────────────────────────────────────────────────────\n\n  setColor(color: ColorRGB, index: number): void {\n    if (index < 0 || index >= this.paletteState.length)\n      throw new Error(`Index ${index} out of range`);\n    this.paletteState[index] = color;\n    uploadPaletteTexture(this.glContext, this.paletteTexture, this.paletteState);\n    this.metricPaletteDirty = true;\n    this.schedulePaint();\n  }\n\n  addColor(color: ColorRGB, index?: number): void {\n    this.paletteState.splice(index ?? this.paletteState.length, 0, color);\n    uploadPaletteTexture(this.glContext, this.paletteTexture, this.paletteState);\n    this.metricPaletteDirty = true;\n    this.schedulePaint();\n  }\n\n  removeColor(index: number): void;\n  removeColor(color: ColorRGB): void;\n  removeColor(indexOrColor: number | ColorRGB): void {\n    const index =\n      typeof indexOrColor === 'number'\n        ? indexOrColor\n        : this.paletteState.findIndex(\n            (c) =>\n              Math.abs(c[0] - indexOrColor[0]) < 1e-9 &&\n              Math.abs(c[1] - indexOrColor[1]) < 1e-9 &&\n              Math.abs(c[2] - indexOrColor[2]) < 1e-9,\n          );\n    if (index === -1) throw new Error('Color not found in palette');\n    if (index < 0 || index >= this.paletteState.length)\n      throw new Error(`Index ${index} out of range`);\n    if (this.paletteState.length === 1) throw new Error('Palette must contain at least one color');\n    this.paletteState.splice(index, 1);\n    uploadPaletteTexture(this.glContext, this.paletteTexture, this.paletteState);\n    this.metricPaletteDirty = true;\n    this.schedulePaint();\n  }\n\n  getColorAtUV(x: number, y: number): ColorRGB {\n    if (!Number.isFinite(x) || !Number.isFinite(y))\n      throw new Error('x and y must be finite numbers');\n    if (x < 0 || x > 1 || y < 0 || y > 1) throw new Error('x and y must be in the range [0, 1]');\n    // The #fbo already holds the current frame from the last scheduled paint;\n    // only re-render when a paint is pending (i.e. state changed since then).\n    if (this.animationFrameId !== null) {\n      this.flushScheduledPaint();\n      this.renderFrame();\n    }\n\n    const gl = this.glContext;\n    const px = Math.min(\n      this.canvas.width - 1,\n      Math.max(0, Math.round(x * (this.canvas.width - 1))),\n    );\n    const py = Math.min(\n      this.canvas.height - 1,\n      Math.max(0, Math.round(y * (this.canvas.height - 1))),\n    );\n    gl.bindFramebuffer(gl.FRAMEBUFFER, this.#fbo);\n    gl.flush();\n    const out = new Uint8Array(4);\n    gl.readPixels(px, py, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, out);\n    gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n    return [out[0] / 255, out[1] / 255, out[2] / 255];\n  }\n\n  getColorAtUV_float(x: number, y: number): ColorRGB {\n    if (!Number.isFinite(x) || !Number.isFinite(y))\n      throw new Error('x and y must be finite numbers');\n    if (x < 0 || x > 1 || y < 0 || y > 1) throw new Error('x and y must be in the range [0, 1]');\n    this.flushScheduledPaint();\n\n    const gl = this.glContext;\n\n    // Lazily create the 1×1 RGBA16F FBO (requires EXT_color_buffer_float)\n    if (!this.#floatFbo) {\n      gl.getExtension('EXT_color_buffer_float');\n\n      this.#floatFboTexture = gl.createTexture()!;\n      gl.bindTexture(gl.TEXTURE_2D, this.#floatFboTexture);\n      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA16F, 1, 1, 0, gl.RGBA, gl.HALF_FLOAT, null);\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.bindTexture(gl.TEXTURE_2D, null);\n\n      this.#floatFbo = gl.createFramebuffer()!;\n      gl.bindFramebuffer(gl.FRAMEBUFFER, this.#floatFbo);\n      gl.framebufferTexture2D(\n        gl.FRAMEBUFFER,\n        gl.COLOR_ATTACHMENT0,\n        gl.TEXTURE_2D,\n        this.#floatFboTexture,\n        0,\n      );\n      gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n    }\n\n    // Rebuild linear program when main program defines have changed\n    if (this.#programDirty) this.#linearProgramDirty = true;\n\n    if (this.#linearProgramDirty) {\n      if (this.#linearProgram) gl.deleteProgram(this.#linearProgram);\n      const defines = { ...this.#defines(), OUTPUT_LINEAR: 1 };\n      const fragSrc = assembleFragShader(\n        COLOR_MODEL_MAP[this.#colorModel],\n        DISTANCE_METRIC_MAP[this.#distanceMetric],\n        this.#showRaw,\n        true,\n      );\n      this.#linearProgram = buildProgram(gl, defines, fragSrc, vertexShaderSrc);\n      this.#uLinearProgress = gl.getUniformLocation(this.#linearProgram, 'progress');\n      this.#uLinearPaletteTexture = gl.getUniformLocation(this.#linearProgram, 'paletteTexture');\n      this.#uLinearPaletteMetricTexture = gl.getUniformLocation(\n        this.#linearProgram,\n        'paletteMetricTexture',\n      );\n      this.#uLinearPaletteSize = gl.getUniformLocation(this.#linearProgram, 'uPaletteSize');\n      this.#uLinearUvOverride = gl.getUniformLocation(this.#linearProgram, 'uvOverride');\n      this.#linearProgramDirty = false;\n    }\n\n    // Save current viewport\n    const savedViewport = gl.getParameter(gl.VIEWPORT) as Int32Array;\n\n    // Render 1 pixel into the float FBO at the requested UV\n    gl.bindFramebuffer(gl.FRAMEBUFFER, this.#floatFbo);\n    gl.viewport(0, 0, 1, 1);\n    gl.useProgram(this.#linearProgram);\n\n    gl.uniform2f(this.#uLinearUvOverride, x, y);\n    gl.uniform1f(this.#uLinearProgress, this.#position);\n    gl.uniform1i(this.#uLinearPaletteSize, this.paletteState.length);\n    gl.activeTexture(gl.TEXTURE0);\n    gl.bindTexture(gl.TEXTURE_2D, this.paletteTexture);\n    gl.uniform1i(this.#uLinearPaletteTexture, 0);\n    gl.activeTexture(gl.TEXTURE1);\n    gl.bindTexture(gl.TEXTURE_2D, this.metricTexture);\n    gl.uniform1i(this.#uLinearPaletteMetricTexture, 1);\n\n    gl.clearColor(0, 0, 0, 0);\n    gl.clear(gl.COLOR_BUFFER_BIT);\n    gl.bindVertexArray(this.#vao);\n    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n    gl.flush();\n\n    // Read back the single float pixel\n    const out = new Float32Array(4);\n    gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT, out);\n\n    // Restore state\n    gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n    gl.bindVertexArray(null);\n    gl.viewport(savedViewport[0], savedViewport[1], savedViewport[2], savedViewport[3]);\n\n    return [out[0], out[1], out[2]];\n  }\n\n  // ── Shader properties ────────────────────────────────────────────────────────\n\n  set position(value: number) {\n    this.#position = value;\n    this.schedulePaint();\n  }\n  get position() {\n    return this.#position;\n  }\n\n  set axis(axis: Axis) {\n    if (!(axis in AXIS_MAP)) throw new Error(\"axis must be 'x', 'y', or 'z'\");\n    this.#axis = axis;\n    this.#programDirty = true;\n    this.schedulePaint();\n  }\n  get axis() {\n    return this.#axis;\n  }\n\n  set colorModel(model: SupportedColorModels) {\n    if (!(model in COLOR_MODEL_MAP)) throw new Error(`colorModel '${model}' is not supported`);\n    this.#colorModel = model;\n    this.#programDirty = true;\n    this.schedulePaint();\n  }\n  get colorModel() {\n    return this.#colorModel;\n  }\n\n  set distanceMetric(metric: DistanceMetric) {\n    if (!(metric in DISTANCE_METRIC_MAP))\n      throw new Error(`distanceMetric '${metric}' is not supported`);\n    this.#distanceMetric = metric;\n    this.#programDirty = true;\n    this.schedulePaint();\n  }\n  get distanceMetric() {\n    return this.#distanceMetric;\n  }\n\n  set invertAxes(value: Axis[]) {\n    this.#invertAxes = this.normalizeInvertAxes(value);\n    this.#programDirty = true;\n    this.schedulePaint();\n  }\n  get invertAxes() {\n    return this.#invertAxes.slice();\n  }\n\n  set showRaw(value: boolean) {\n    this.#showRaw = value;\n    this.#programDirty = true;\n    this.schedulePaint();\n  }\n  get showRaw() {\n    return this.#showRaw;\n  }\n\n  set gamutClip(value: boolean) {\n    this.#gamutClip = value;\n    this.#programDirty = true;\n    this.schedulePaint();\n  }\n  get gamutClip() {\n    return this.#gamutClip;\n  }\n\n  set outlineWidth(value: number) {\n    this.#outlineWidth = value;\n    this.schedulePaint();\n  }\n  get outlineWidth() {\n    return this.#outlineWidth;\n  }\n\n  static paletteToRGBA = paletteToRGBA;\n  /** @deprecated use PaletteViz.paletteToRGBA */\n  static paletteToTexture = paletteToRGBA;\n}\n","// Generate a unit cube mesh as indexed triangles. Returns interleaved positions.\nexport function createCubeMesh(resolution: number): {\n  vertices: Float32Array;\n  indices: Uint32Array;\n} {\n  const verts: number[] = [];\n  const idx: number[] = [];\n  const n = resolution; // quads per face edge\n\n  // 6 faces: for each face we create an (n+1)×(n+1) grid of vertices and n×n×2 triangles\n  // Face mappings: [axis perpendicular, sign, u-axis, v-axis]\n  const faces: [number, number, number, number, number, number][] = [\n    // axisIndex, sign, uAxis, vAxis, uSign, vSign\n    // +X face\n    [0, 1, 2, 1, 1, 1],\n    // -X face\n    [0, 0, 2, 1, -1, 1],\n    // +Y face\n    [1, 1, 0, 2, 1, 1],\n    // -Y face\n    [1, 0, 0, 2, 1, -1],\n    // +Z face\n    [2, 1, 0, 1, 1, 1],\n    // -Z face\n    [2, 0, 0, 1, -1, 1],\n  ];\n\n  for (const [axIdx, sign, uIdx, vIdx, _uSign, _vSign] of faces) {\n    const base = verts.length / 3;\n    for (let j = 0; j <= n; j++) {\n      for (let i = 0; i <= n; i++) {\n        const u = i / n;\n        const v = j / n;\n        const pos = [0, 0, 0];\n        pos[axIdx] = sign;\n        pos[uIdx] = u;\n        pos[vIdx] = v;\n        verts.push(pos[0], pos[1], pos[2]);\n      }\n    }\n    for (let j = 0; j < n; j++) {\n      for (let i = 0; i < n; i++) {\n        const a = base + j * (n + 1) + i;\n        const b = a + 1;\n        const c = a + (n + 1);\n        const d = c + 1;\n        idx.push(a, b, c, b, d, c);\n      }\n    }\n  }\n\n  return { vertices: new Float32Array(verts), indices: new Uint32Array(idx) };\n}\n\n// Stacked X-axis slices filling the cube volume. Each slice is a YZ quad.\n// Used for gamut clipping — out-of-gamut fragments are discarded per-slice,\n// and the dense stack forms the visible gamut body.\nexport function createSlicedCubeMesh(\n  resolution: number,\n  slices: number,\n  padding = 0,\n): { vertices: Float32Array; indices: Uint32Array } {\n  const verts: number[] = [];\n  const idx: number[] = [];\n  const n = resolution;\n  const lo = -padding;\n  const hi = 1 + padding;\n  const span = hi - lo;\n\n  // Iterate near-to-far so the draw order is front-to-back.\n  // With depth test on, early-Z rejects occluded fragments → huge perf win.\n  for (let s = slices; s >= 0; s--) {\n    const x = lo + (span * s) / slices;\n    const base = verts.length / 3;\n    for (let j = 0; j <= n; j++) {\n      for (let i = 0; i <= n; i++) {\n        verts.push(x, lo + (span * j) / n, lo + (span * i) / n);\n      }\n    }\n    for (let j = 0; j < n; j++) {\n      for (let i = 0; i < n; i++) {\n        const a = base + j * (n + 1) + i;\n        const b = a + 1;\n        const c = a + (n + 1);\n        const d = c + 1;\n        idx.push(a, b, c, b, d, c);\n      }\n    }\n  }\n\n  return { vertices: new Float32Array(verts), indices: new Uint32Array(idx) };\n}\n\n// Stacked height slices filling the cylinder volume. Each slice is a full disc.\n// Only position (3 floats) is stored per vertex — polar conversion happens\n// per-pixel in the fragment shader via the color-rotation matrix.\nexport function createSlicedCylinderMesh(\n  radialSegments: number,\n  slices: number,\n  padding = 0,\n): { vertices: Float32Array; indices: Uint32Array } {\n  const verts: number[] = [];\n  const idx: number[] = [];\n  const TWO_PI = Math.PI * 2;\n  const capSegs = Math.max(1, Math.floor(radialSegments / 4));\n  const maxR = 0.5 + padding; // radius extent\n  const hLo = -padding; // height range: [-padding, 1+padding]\n  const hHi = 1 + padding;\n\n  // Iterate near-to-far so the draw order is front-to-back.\n  for (let s = slices; s >= 0; s--) {\n    const h = hLo + ((hHi - hLo) * s) / slices;\n    const py = h - 0.5;\n    const discBase = verts.length / 3;\n    for (let ring = 0; ring <= capSegs; ring++) {\n      const r01 = ring / capSegs;\n      const rPos = r01 * maxR;\n      for (let i = 0; i <= radialSegments; i++) {\n        const u = i / radialSegments;\n        const angle = u * TWO_PI;\n        verts.push(rPos * Math.cos(angle), py, rPos * Math.sin(angle));\n      }\n    }\n    const stride = radialSegments + 1;\n    for (let ring = 0; ring < capSegs; ring++) {\n      for (let i = 0; i < radialSegments; i++) {\n        const a = discBase + ring * stride + i;\n        const b = a + 1;\n        const c = a + stride;\n        const d = c + 1;\n        idx.push(a, b, c, b, d, c);\n      }\n    }\n  }\n\n  return { vertices: new Float32Array(verts), indices: new Uint32Array(idx) };\n}\n\n// Polar model IDs that should use a cylinder (or cone/bicone variant)\nexport const POLAR_MODEL_IDS = new Set([5, 7, 9, 11, 13, 15, 18, 21, 24, 32]); // all *Polar models\n\n// Cone: HSV-type polar models (radius = value, point at bottom)\nexport const CONE_MODEL_IDS = new Set([5, 11]); // okhsvPolar, hsvPolar\n\n// Bicone: HSL-type polar models (radius = 1-|2L-1|, points at top and bottom)\nexport const BICONE_MODEL_IDS = new Set([7, 13]); // okhslPolar, hslPolar\n\n// Inverted cone: HWB-type polar models (radius = 1-height, wide at bottom, point at top)\nexport const CONE_INV_MODEL_IDS = new Set([15]); // hwbPolar\n","// Simple 4×4 matrix helpers (column-major) — exported so consumers can build\n// their own orbit / trackball controls.\n\nexport function mat4Perspective(\n  fov: number,\n  aspect: number,\n  near: number,\n  far: number,\n): Float32Array {\n  const f = 1.0 / Math.tan(fov / 2);\n  const nf = 1 / (near - far);\n  // prettier-ignore\n  return new Float32Array([\n    f / aspect, 0, 0, 0,\n    0, f, 0, 0,\n    0, 0, (far + near) * nf, -1,\n    0, 0, 2 * far * near * nf, 0,\n  ]);\n}\n\nexport function mat4Multiply(a: Float32Array, b: Float32Array): Float32Array {\n  const out = new Float32Array(16);\n  for (let i = 0; i < 4; i++) {\n    for (let j = 0; j < 4; j++) {\n      out[j * 4 + i] =\n        a[0 * 4 + i] * b[j * 4 + 0] +\n        a[1 * 4 + i] * b[j * 4 + 1] +\n        a[2 * 4 + i] * b[j * 4 + 2] +\n        a[3 * 4 + i] * b[j * 4 + 3];\n    }\n  }\n  return out;\n}\n\nexport function mat4RotateY(angle: number): Float32Array {\n  const c = Math.cos(angle),\n    s = Math.sin(angle);\n  // prettier-ignore\n  return new Float32Array([\n    c, 0, s, 0,\n    0, 1, 0, 0,\n    -s, 0, c, 0,\n    0, 0, 0, 1,\n  ]);\n}\n\nexport function mat4RotateZ(angle: number): Float32Array {\n  const c = Math.cos(angle),\n    s = Math.sin(angle);\n  // prettier-ignore\n  return new Float32Array([\n    c, s, 0, 0,\n    -s, c, 0, 0,\n    0, 0, 1, 0,\n    0, 0, 0, 1,\n  ]);\n}\n\nexport function mat4RotateX(angle: number): Float32Array {\n  const c = Math.cos(angle),\n    s = Math.sin(angle);\n  // prettier-ignore\n  return new Float32Array([\n    1, 0, 0, 0,\n    0, c, -s, 0,\n    0, s, c, 0,\n    0, 0, 0, 1,\n  ]);\n}\n\nexport function mat4Ortho(\n  left: number,\n  right: number,\n  bottom: number,\n  top: number,\n  near: number,\n  far: number,\n): Float32Array {\n  const lr = 1 / (left - right);\n  const bt = 1 / (bottom - top);\n  const nf = 1 / (near - far);\n  // prettier-ignore\n  return new Float32Array([\n    -2 * lr, 0, 0, 0,\n    0, -2 * bt, 0, 0,\n    0, 0, 2 * nf, 0,\n    (left + right) * lr, (top + bottom) * bt, (far + near) * nf, 1,\n  ]);\n}\n\nexport function mat4Translate(x: number, y: number, z: number): Float32Array {\n  // prettier-ignore\n  return new Float32Array([\n    1, 0, 0, 0,\n    0, 1, 0, 0,\n    0, 0, 1, 0,\n    x, y, z, 1,\n  ]);\n}\n","import { PaletteViz3DOptions, SupportedColorModels, DistanceMetric, Axis } from './types.ts';\nimport { randomPalette } from './palette.ts';\nimport { Defines, buildProgram } from './webgl.ts';\nimport {\n  vertexShaderSrc,\n  vertexShader3DCubeSrc,\n  vertexShader3DCylSrc,\n  assembleFragShader3D,\n  assembleFragShader3DPrepass,\n  outlineFragmentShaderSrc,\n} from './shaderSrc.ts';\nimport {\n  createCubeMesh,\n  createSlicedCubeMesh,\n  createSlicedCylinderMesh,\n  POLAR_MODEL_IDS,\n  CONE_MODEL_IDS,\n  BICONE_MODEL_IDS,\n  CONE_INV_MODEL_IDS,\n} from './mesh.ts';\nimport {\n  mat4Perspective,\n  mat4Ortho,\n  mat4Multiply,\n  mat4RotateX,\n  mat4RotateY,\n  mat4Translate,\n} from './math.ts';\nimport { BasePaletteRenderer, COLOR_MODEL_MAP, DISTANCE_METRIC_MAP } from './rendererShared.ts';\n\nconst GUTTERED_CLIP_PADDING = 0.42;\nconst SETTLED_CLIP_PASS_COUNT = 2;\n\nexport class PaletteViz3D extends BasePaletteRenderer {\n  #position = 1.0;\n  #modelMatrix = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);\n\n  #colorModel: SupportedColorModels = 'okhsv';\n  #distanceMetric: DistanceMetric = 'oklab';\n  #invertAxes: Axis[] = [];\n  #showRaw = false;\n  #outlineWidth = 0;\n  #gamutClip = false;\n\n  #program: WebGLProgram | null = null;\n  #depthProgram: WebGLProgram | null = null;\n  #vao: WebGLVertexArrayObject | null = null;\n  #vbo: WebGLBuffer | null = null;\n  #ibo: WebGLBuffer | null = null;\n  #indexCount = 0;\n  #programDirty = false;\n  #meshDirty = false;\n  #isPolar = false;\n  #sliceCount = 0;\n  #interactiveUntil = 0;\n  #refineTimer: number | null = null;\n\n  #uMVP: WebGLUniformLocation | null = null;\n  #uDepthMVP: WebGLUniformLocation | null = null;\n  #uPosition: WebGLUniformLocation | null = null;\n  #uDepthPosition: WebGLUniformLocation | null = null;\n  #uPaletteTexture: WebGLUniformLocation | null = null;\n  #uPaletteMetricTexture: WebGLUniformLocation | null = null;\n  #uPaletteSize: WebGLUniformLocation | null = null;\n  #uColorRotation: WebGLUniformLocation | null = null;\n  #uDepthColorRotation: WebGLUniformLocation | null = null;\n  #uSliceOffset: WebGLUniformLocation | null = null;\n  #uDepthSliceOffset: WebGLUniformLocation | null = null;\n  #rot3x3 = new Float32Array(9);\n\n  #fbo: WebGLFramebuffer | null = null;\n  #fboTexture: WebGLTexture | null = null;\n  #fboDepth: WebGLRenderbuffer | null = null;\n  #blitProgram: WebGLProgram | null = null;\n  #blitVao: WebGLVertexArrayObject | null = null;\n  #blitQuadBuf: WebGLBuffer | null = null;\n  #uColorMap: WebGLUniformLocation | null = null;\n  #uOutlineWidth: WebGLUniformLocation | null = null;\n  #uOutlineResolution: WebGLUniformLocation | null = null;\n\n  constructor({\n    palette = randomPalette(),\n    width = 512,\n    height = 512,\n    pixelRatio = window.devicePixelRatio,\n    observeResize = false,\n    container,\n    colorModel = 'okhsv',\n    distanceMetric = 'oklab',\n    invertAxes = [],\n    showRaw = false,\n    outlineWidth = 0,\n    gamutClip = false,\n    position = 1.0,\n    modelMatrix,\n  }: PaletteViz3DOptions = {}) {\n    super({\n      palette,\n      width,\n      height,\n      pixelRatio,\n      observeResize,\n      container,\n      canvasClassName: 'palette-viz-3d',\n    });\n\n    this.#colorModel = colorModel;\n    this.#distanceMetric = distanceMetric;\n    this.#invertAxes = this.normalizeInvertAxes(invertAxes);\n    this.#showRaw = showRaw;\n    this.#outlineWidth = outlineWidth;\n    this.#gamutClip = gamutClip;\n    this.#position = position;\n    this.#isPolar = POLAR_MODEL_IDS.has(COLOR_MODEL_MAP[this.#colorModel]);\n\n    if (modelMatrix) {\n      this.#modelMatrix = new Float32Array(modelMatrix);\n    } else {\n      this.#modelMatrix = new Float32Array(mat4Multiply(mat4RotateX(0.45), mat4RotateY(0.65)));\n    }\n\n    this.#buildMesh();\n    this.#rebuildProgram();\n    this.syncCanvasSize(this.width, this.height);\n    this.#syncSliceBudget();\n    this.glContext.enable(this.glContext.DEPTH_TEST);\n    this.#buildFBO();\n    this.attachCanvas();\n    this.schedulePaint();\n  }\n\n  #buildMesh(): void {\n    const gl = this.glContext;\n    if (this.#vbo) gl.deleteBuffer(this.#vbo);\n    if (this.#ibo) gl.deleteBuffer(this.#ibo);\n    if (this.#vao) gl.deleteVertexArray(this.#vao);\n\n    if (this.#isPolar) {\n      this.#sliceCount = this.#desiredSliceCount();\n      const { vertices, indices } = createSlicedCylinderMesh(32, this.#sliceCount, 0.25);\n      this.#indexCount = indices.length;\n\n      this.#vbo = gl.createBuffer()!;\n      gl.bindBuffer(gl.ARRAY_BUFFER, this.#vbo);\n      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n\n      this.#ibo = gl.createBuffer()!;\n      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.#ibo);\n      gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);\n\n      this.#vao = gl.createVertexArray()!;\n      gl.bindVertexArray(this.#vao);\n      gl.bindBuffer(gl.ARRAY_BUFFER, this.#vbo);\n      gl.enableVertexAttribArray(0);\n      gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);\n      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.#ibo);\n      gl.bindVertexArray(null);\n      return;\n    }\n\n    this.#sliceCount = this.#gamutClip ? this.#desiredSliceCount() : 0;\n    const { vertices, indices } = this.#gamutClip\n      ? createSlicedCubeMesh(2, this.#sliceCount, GUTTERED_CLIP_PADDING)\n      : createCubeMesh(64);\n    this.#indexCount = indices.length;\n\n    this.#vbo = gl.createBuffer()!;\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.#vbo);\n    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n\n    this.#ibo = gl.createBuffer()!;\n    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.#ibo);\n    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);\n\n    this.#vao = gl.createVertexArray()!;\n    gl.bindVertexArray(this.#vao);\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.#vbo);\n    gl.enableVertexAttribArray(0);\n    gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);\n    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.#ibo);\n    gl.bindVertexArray(null);\n  }\n\n  #desiredSliceCount(): number {\n    if (!(this.#gamutClip || this.#isPolar)) return 0;\n    const diagonal = Math.hypot(this.canvas.width, this.canvas.height);\n    const settled = Math.max(320, Math.min(640, Math.round(diagonal * 0.9)));\n    return this.#isInteractive()\n      ? Math.max(160, Math.min(320, Math.round(settled * 0.4)))\n      : settled;\n  }\n\n  #isInteractive(): boolean {\n    return performance.now() < this.#interactiveUntil;\n  }\n\n  #markInteractive(): void {\n    this.#interactiveUntil = performance.now() + 140;\n    if (this.#refineTimer !== null) window.clearTimeout(this.#refineTimer);\n    this.#refineTimer = window.setTimeout(() => {\n      this.#refineTimer = null;\n      this.schedulePaint();\n    }, 150);\n  }\n\n  #syncSliceBudget(): void {\n    if (!(this.#gamutClip || this.#isPolar)) {\n      this.#sliceCount = 0;\n      return;\n    }\n    const desired = this.#desiredSliceCount();\n    if (desired !== this.#sliceCount) this.#meshDirty = true;\n  }\n\n  #clipPassCount(): number {\n    return this.#gamutClip && !this.#isInteractive() ? SETTLED_CLIP_PASS_COUNT : 1;\n  }\n\n  #clipSliceOffset(passIndex: number, passCount: number): number {\n    if (!this.#gamutClip || passCount <= 1 || this.#sliceCount <= 0) return 0;\n    const span = 1 + GUTTERED_CLIP_PADDING * 2;\n    const step = span / this.#sliceCount;\n    return ((passIndex + 0.5) / passCount - 0.5) * step;\n  }\n\n  #drawClipPasses(\n    program: WebGLProgram,\n    mvp: WebGLUniformLocation | null,\n    position: WebGLUniformLocation | null,\n    colorRotation: WebGLUniformLocation | null,\n    sliceOffset: WebGLUniformLocation | null,\n  ): void {\n    const gl = this.glContext;\n    const passCount = this.#clipPassCount();\n    this.#applySharedUniforms(program, mvp, position, colorRotation);\n    gl.bindVertexArray(this.#vao);\n    for (let passIndex = 0; passIndex < passCount; passIndex++) {\n      if (sliceOffset) gl.uniform1f(sliceOffset, this.#clipSliceOffset(passIndex, passCount));\n      gl.drawElements(gl.TRIANGLES, this.#indexCount, gl.UNSIGNED_INT, 0);\n    }\n    gl.bindVertexArray(null);\n  }\n\n  #defines(): Defines {\n    const modelId = COLOR_MODEL_MAP[this.#colorModel];\n    return {\n      COLOR_MODEL: modelId,\n      DISTANCE_METRIC: DISTANCE_METRIC_MAP[this.#distanceMetric],\n      INVERT_X: this.#invertAxes.includes('x') ? 1 : false,\n      INVERT_Y: this.#invertAxes.includes('y') ? 1 : false,\n      INVERT_Z: this.#invertAxes.includes('z') ? 1 : false,\n      SHOW_RAW: this.#showRaw ? 1 : false,\n      GAMUT_CLIP: this.#gamutClip ? 1 : false,\n      IS_POLAR: this.#isPolar ? 1 : false,\n      SHAPE_CONE: this.#isPolar && CONE_MODEL_IDS.has(modelId) ? 1 : false,\n      SHAPE_CONE_INV: this.#isPolar && CONE_INV_MODEL_IDS.has(modelId) ? 1 : false,\n      SHAPE_BICONE: this.#isPolar && BICONE_MODEL_IDS.has(modelId) ? 1 : false,\n    };\n  }\n\n  #rebuildProgram(): void {\n    const gl = this.glContext;\n    if (this.#program) gl.deleteProgram(this.#program);\n    if (this.#depthProgram) gl.deleteProgram(this.#depthProgram);\n\n    const fragSrc = assembleFragShader3D(\n      COLOR_MODEL_MAP[this.#colorModel],\n      DISTANCE_METRIC_MAP[this.#distanceMetric],\n      this.#showRaw,\n    );\n    const prepassFragSrc = assembleFragShader3DPrepass(\n      COLOR_MODEL_MAP[this.#colorModel],\n      this.#gamutClip,\n    );\n    const vertSrc = this.#isPolar ? vertexShader3DCylSrc : vertexShader3DCubeSrc;\n    this.#program = buildProgram(gl, this.#defines(), fragSrc, vertSrc);\n    this.#depthProgram = buildProgram(gl, this.#defines(), prepassFragSrc, vertSrc);\n    this.#uMVP = gl.getUniformLocation(this.#program, 'uMVP');\n    this.#uDepthMVP = gl.getUniformLocation(this.#depthProgram, 'uMVP');\n    this.#uPosition = gl.getUniformLocation(this.#program, 'uPosition');\n    this.#uDepthPosition = gl.getUniformLocation(this.#depthProgram, 'uPosition');\n    this.#uPaletteTexture = gl.getUniformLocation(this.#program, 'paletteTexture');\n    this.#uPaletteMetricTexture = gl.getUniformLocation(this.#program, 'paletteMetricTexture');\n    this.#uPaletteSize = gl.getUniformLocation(this.#program, 'uPaletteSize');\n    this.#uColorRotation = gl.getUniformLocation(this.#program, 'uColorRotation');\n    this.#uDepthColorRotation = gl.getUniformLocation(this.#depthProgram, 'uColorRotation');\n    this.#uSliceOffset = gl.getUniformLocation(this.#program, 'uSliceOffset');\n    this.#uDepthSliceOffset = gl.getUniformLocation(this.#depthProgram, 'uSliceOffset');\n    this.metricPaletteDirty = true;\n  }\n\n  #applySharedUniforms(\n    program: WebGLProgram,\n    mvp: WebGLUniformLocation | null,\n    position: WebGLUniformLocation | null,\n    colorRotation: WebGLUniformLocation | null,\n  ): void {\n    const gl = this.glContext;\n    gl.useProgram(program);\n    gl.uniformMatrix4fv(mvp, false, this.#buildMVP());\n    gl.uniform1f(position, this.#position);\n    if ((this.#gamutClip || this.#isPolar) && colorRotation) {\n      const m = this.#modelMatrix;\n      const r = this.#rot3x3;\n      r[0] = m[0];\n      r[1] = m[1];\n      r[2] = m[2];\n      r[3] = m[4];\n      r[4] = m[5];\n      r[5] = m[6];\n      r[6] = m[8];\n      r[7] = m[9];\n      r[8] = m[10];\n      gl.uniformMatrix3fv(colorRotation, false, r);\n    }\n  }\n\n  #buildFBO(): void {\n    const gl = this.glContext;\n\n    this.#fboTexture = gl.createTexture()!;\n    this.#fboDepth = gl.createRenderbuffer()!;\n    this.#fbo = gl.createFramebuffer()!;\n    this.#resizeFBO(this.canvas.width, this.canvas.height);\n\n    this.#blitQuadBuf = gl.createBuffer()!;\n    gl.bindBuffer(gl.ARRAY_BUFFER, this.#blitQuadBuf);\n    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]), gl.STATIC_DRAW);\n\n    this.#blitVao = gl.createVertexArray()!;\n    gl.bindVertexArray(this.#blitVao);\n    gl.enableVertexAttribArray(0);\n    gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);\n    gl.bindVertexArray(null);\n\n    this.#blitProgram = buildProgram(gl, {}, outlineFragmentShaderSrc, vertexShaderSrc);\n    this.#uColorMap = gl.getUniformLocation(this.#blitProgram, 'colorMap');\n    this.#uOutlineWidth = gl.getUniformLocation(this.#blitProgram, 'outlineWidth');\n    this.#uOutlineResolution = gl.getUniformLocation(this.#blitProgram, 'resolution');\n  }\n\n  #resizeFBO(pw: number, ph: number): void {\n    const gl = this.glContext;\n    gl.bindTexture(gl.TEXTURE_2D, this.#fboTexture);\n    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, pw, ph, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\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.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.bindTexture(gl.TEXTURE_2D, null);\n\n    gl.bindRenderbuffer(gl.RENDERBUFFER, this.#fboDepth);\n    gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, pw, ph);\n    gl.bindRenderbuffer(gl.RENDERBUFFER, null);\n\n    gl.bindFramebuffer(gl.FRAMEBUFFER, this.#fbo);\n    gl.framebufferTexture2D(\n      gl.FRAMEBUFFER,\n      gl.COLOR_ATTACHMENT0,\n      gl.TEXTURE_2D,\n      this.#fboTexture,\n      0,\n    );\n    gl.framebufferRenderbuffer(\n      gl.FRAMEBUFFER,\n      gl.DEPTH_ATTACHMENT,\n      gl.RENDERBUFFER,\n      this.#fboDepth,\n    );\n    gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n  }\n\n  #buildMVP(): Float32Array {\n    const aspect = this.canvas.width / this.canvas.height;\n    if (this.#gamutClip || this.#isPolar) {\n      const s = 1.0;\n      const proj = mat4Ortho(-s * aspect, s * aspect, -s, s, 0.1, 100);\n      const view = mat4Translate(0, 0, -3);\n      const fixedOrientation = this.#isPolar ? mat4RotateX(Math.PI / 2) : mat4RotateY(-Math.PI / 2);\n      return mat4Multiply(proj, mat4Multiply(view, fixedOrientation));\n    }\n    const proj = mat4Perspective(Math.PI / 5, aspect, 0.1, 100);\n    const view = mat4Translate(0, 0, -3);\n    return mat4Multiply(proj, mat4Multiply(view, this.#modelMatrix));\n  }\n\n  protected currentMetricCode(): number {\n    return DISTANCE_METRIC_MAP[this.#distanceMetric];\n  }\n\n  protected onSurfaceResized(pw: number, ph: number): void {\n    this.#syncSliceBudget();\n    if (this.#fboTexture) this.#resizeFBO(pw, ph);\n  }\n\n  protected renderFrame(): void {\n    this.#syncSliceBudget();\n    if (this.#meshDirty) {\n      this.#isPolar = POLAR_MODEL_IDS.has(COLOR_MODEL_MAP[this.#colorModel]);\n      this.#buildMesh();\n      this.#meshDirty = false;\n    }\n    if (this.#programDirty) {\n      this.#rebuildProgram();\n      this.#programDirty = false;\n    }\n\n    const gl = this.glContext;\n    gl.bindFramebuffer(gl.FRAMEBUFFER, this.#fbo);\n\n    gl.clearColor(0, 0, 0, 0);\n    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);\n\n    if (this.#gamutClip || this.#isPolar) {\n      gl.colorMask(false, false, false, false);\n      if (this.#gamutClip) {\n        this.#drawClipPasses(\n          this.#depthProgram!,\n          this.#uDepthMVP,\n          this.#uDepthPosition,\n          this.#uDepthColorRotation,\n          this.#uDepthSliceOffset,\n        );\n      } else {\n        this.#applySharedUniforms(\n          this.#depthProgram!,\n          this.#uDepthMVP,\n          this.#uDepthPosition,\n          this.#uDepthColorRotation,\n        );\n        gl.bindVertexArray(this.#vao);\n        gl.drawElements(gl.TRIANGLES, this.#indexCount, gl.UNSIGNED_INT, 0);\n        gl.bindVertexArray(null);\n      }\n      gl.colorMask(true, true, true, true);\n      gl.clear(gl.COLOR_BUFFER_BIT);\n      gl.depthFunc(gl.EQUAL);\n      gl.depthMask(false);\n    }\n\n    if (this.#gamutClip) {\n      gl.useProgram(this.#program!);\n    } else {\n      this.#applySharedUniforms(this.#program!, this.#uMVP, this.#uPosition, this.#uColorRotation);\n    }\n    this.uploadMetricPalette(this.#uPaletteSize);\n    gl.activeTexture(gl.TEXTURE0);\n    gl.bindTexture(gl.TEXTURE_2D, this.paletteTexture);\n    gl.uniform1i(this.#uPaletteTexture, 0);\n    gl.activeTexture(gl.TEXTURE1);\n    gl.bindTexture(gl.TEXTURE_2D, this.metricTexture);\n    gl.uniform1i(this.#uPaletteMetricTexture, 1);\n\n    if (this.#gamutClip) {\n      this.#drawClipPasses(\n        this.#program!,\n        this.#uMVP,\n        this.#uPosition,\n        this.#uColorRotation,\n        this.#uSliceOffset,\n      );\n    } else {\n      gl.bindVertexArray(this.#vao);\n      gl.drawElements(gl.TRIANGLES, this.#indexCount, gl.UNSIGNED_INT, 0);\n      gl.bindVertexArray(null);\n    }\n    if (this.#gamutClip || this.#isPolar) {\n      gl.depthMask(true);\n      gl.depthFunc(gl.LESS);\n    }\n\n    gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n    gl.disable(gl.DEPTH_TEST);\n    gl.useProgram(this.#blitProgram);\n    gl.activeTexture(gl.TEXTURE0);\n    gl.bindTexture(gl.TEXTURE_2D, this.#fboTexture);\n    gl.uniform1i(this.#uColorMap, 0);\n    gl.uniform1f(this.#uOutlineWidth, this.#showRaw ? 0 : this.#outlineWidth);\n    gl.uniform2f(this.#uOutlineResolution, this.canvas.width, this.canvas.height);\n\n    gl.clearColor(0, 0, 0, 0);\n    gl.clear(gl.COLOR_BUFFER_BIT);\n    gl.bindVertexArray(this.#blitVao);\n    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n    gl.bindVertexArray(null);\n    gl.enable(gl.DEPTH_TEST);\n  }\n\n  getColorAtUV(x: number, y: number): [number, number, number] | null {\n    if (!Number.isFinite(x) || !Number.isFinite(y)) {\n      throw new Error('x and y must be finite numbers');\n    }\n    if (x < 0 || x > 1 || y < 0 || y > 1) throw new Error('x and y must be in the range [0, 1]');\n    // The #fbo already holds the current frame from the last scheduled paint;\n    // only re-render when a paint is pending (i.e. state changed since then).\n    if (this.animationFrameId !== null) {\n      this.flushScheduledPaint();\n      this.renderFrame();\n    }\n\n    const gl = this.glContext;\n    const px = Math.min(\n      this.canvas.width - 1,\n      Math.max(0, Math.round(x * (this.canvas.width - 1))),\n    );\n    const py = Math.min(\n      this.canvas.height - 1,\n      Math.max(0, Math.round((1 - y) * (this.canvas.height - 1))),\n    );\n    gl.bindFramebuffer(gl.FRAMEBUFFER, this.#fbo);\n    const out = new Uint8Array(4);\n    gl.readPixels(px, py, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, out);\n    gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n    if (out[3] === 0) return null;\n    return [out[0] / 255, out[1] / 255, out[2] / 255];\n  }\n\n  override resize(width: number, height: number | null = null): void {\n    super.resize(width, height);\n    this.#markInteractive();\n  }\n\n  destroy(): void {\n    if (!this.beginDestroy()) return;\n    if (this.#refineTimer !== null) {\n      window.clearTimeout(this.#refineTimer);\n      this.#refineTimer = null;\n    }\n\n    const gl = this.glContext;\n    if (this.#blitProgram) gl.deleteProgram(this.#blitProgram);\n    if (this.#depthProgram) gl.deleteProgram(this.#depthProgram);\n    if (this.#blitVao) gl.deleteVertexArray(this.#blitVao);\n    if (this.#blitQuadBuf) gl.deleteBuffer(this.#blitQuadBuf);\n    if (this.#fboTexture) gl.deleteTexture(this.#fboTexture);\n    if (this.#fboDepth) gl.deleteRenderbuffer(this.#fboDepth);\n    if (this.#fbo) gl.deleteFramebuffer(this.#fbo);\n    if (this.#program) gl.deleteProgram(this.#program);\n    if (this.#vbo) gl.deleteBuffer(this.#vbo);\n    if (this.#ibo) gl.deleteBuffer(this.#ibo);\n    if (this.#vao) gl.deleteVertexArray(this.#vao);\n    this.destroyBaseResources();\n  }\n\n  set colorModel(model: SupportedColorModels) {\n    if (!(model in COLOR_MODEL_MAP)) throw new Error(`colorModel '${model}' is not supported`);\n    this.#colorModel = model;\n    this.#programDirty = true;\n    this.#meshDirty = true;\n    this.schedulePaint();\n  }\n  get colorModel(): SupportedColorModels {\n    return this.#colorModel;\n  }\n\n  set distanceMetric(metric: DistanceMetric) {\n    if (!(metric in DISTANCE_METRIC_MAP)) {\n      throw new Error(`distanceMetric '${metric}' is not supported`);\n    }\n    this.#distanceMetric = metric;\n    this.#programDirty = true;\n    this.schedulePaint();\n  }\n  get distanceMetric(): DistanceMetric {\n    return this.#distanceMetric;\n  }\n\n  set invertAxes(value: Axis[]) {\n    this.#invertAxes = this.normalizeInvertAxes(value);\n    this.#programDirty = true;\n    this.schedulePaint();\n  }\n  get invertAxes(): Axis[] {\n    return this.#invertAxes.slice();\n  }\n\n  set showRaw(value: boolean) {\n    this.#showRaw = value;\n    this.#programDirty = true;\n    this.schedulePaint();\n  }\n  get showRaw(): boolean {\n    return this.#showRaw;\n  }\n\n  set position(value: number) {\n    this.#position = Math.max(0, Math.min(1, value));\n    this.#markInteractive();\n    this.schedulePaint();\n  }\n  get position(): number {\n    return this.#position;\n  }\n\n  rotate(dx: number, dy: number): void {\n    if (this.#gamutClip || this.#isPolar) {\n      const fixed = this.#isPolar ? mat4RotateX(Math.PI / 2) : mat4RotateY(-Math.PI / 2);\n      const fixedInverse = this.#isPolar ? mat4RotateX(-Math.PI / 2) : mat4RotateY(Math.PI / 2);\n      const screenIncrement = mat4Multiply(mat4RotateY(dx), mat4RotateX(dy));\n      const colorIncrement = mat4Multiply(fixedInverse, mat4Multiply(screenIncrement, fixed));\n      this.#modelMatrix = new Float32Array(mat4Multiply(this.#modelMatrix, colorIncrement));\n    } else {\n      const increment = mat4Multiply(mat4RotateX(-dy), mat4RotateY(-dx));\n      this.#modelMatrix = new Float32Array(mat4Multiply(increment, this.#modelMatrix));\n    }\n    this.#markInteractive();\n    this.schedulePaint();\n  }\n\n  set modelMatrix(matrix: Float32Array) {\n    this.#modelMatrix = new Float32Array(matrix);\n    this.#markInteractive();\n    this.schedulePaint();\n  }\n  get modelMatrix(): Float32Array {\n    return new Float32Array(this.#modelMatrix);\n  }\n\n  set gamutClip(value: boolean) {\n    this.#gamutClip = value;\n    this.#programDirty = true;\n    this.#meshDirty = true;\n    this.schedulePaint();\n  }\n  get gamutClip(): boolean {\n    return this.#gamutClip;\n  }\n\n  set outlineWidth(value: number) {\n    this.#outlineWidth = value;\n    this.schedulePaint();\n  }\n  get outlineWidth(): number {\n    return this.#outlineWidth;\n  }\n\n  override set pixelRatio(value: number) {\n    super.pixelRatio = value;\n    this.#markInteractive();\n  }\n\n  override get pixelRatio(): number {\n    return super.pixelRatio;\n  }\n}\n"],"names":["paletteToRGBA","palette","data","color","i","paletteToTexture","randomPalette","size","_srgbToLinear","c","s","_linearToOklab","g","b","l","m","l_","m_","s_","_toe","x","k3","_labF","t","delta","_xyzToLab","y","z","wx","wy","wz","fx","fy","fz","_srgbToCielabD65","lr","lg","lb","_srgbToCielabD50","CAM16_D65","_xyzToCam16ucsD65","R","G","B","R_c","G_c","B_c","adapt","value","power","R_a","G_a","B_a","a","h","hh","e_t","A","J","denom","M","Jp","Mp","hRad","_srgbToYiq","_srgbToCam16ucsD65","computeMetricPalette","metricCode","out","r","lab","uploadMetricTexture","gl","tex","count","compileShader","type","src","shader","log","buildProgram","defines","fragSrc","vertSrc","prefix","v","k","vert","frag","prog","initTexture","uploadPaletteTexture","shaderSRGB2RGB","shaderOKLab","shaderHSL2RGB","shaderHSV2RGB","shaderLCH2RGB","shaderHWB2RGB","shaderCIELab2RGB","shaderCAM16UCS","shaderDeltaE","shaderClosestColor","vertexShaderSrc","modelToRGBSrc","mainSrc","fragmentShader","shaderNeedsForModel","model","shaderNeedsForMetric","metric","assembleChunks","needs","resolveNeeds","colorModel","distanceMetric","showRaw","modelNeeds","metricNeeds","assembleFragShader","outputLinear","vertexShader3DCubeSrc","vertexShader3DCylSrc","mainSrc3D","mainSrc3DPrepass","assembleFragShader3D","assembleFragShader3DPrepass","gamutClip","outlineFragmentShaderSrc","AXIS_MAP","COLOR_MODEL_MAP","DISTANCE_METRIC_MAP","BasePaletteRenderer","width","height","pixelRatio","observeResize","container","canvasClassName","axes","uniqueAxes","axis","nextWidth","nextHeight","pw","ph","rect","paletteSizeUniform","_pw","_ph","PaletteViz","#position","#axis","#colorModel","#distanceMetric","#invertAxes","#showRaw","#outlineWidth","#gamutClip","#program","#quadBuffer","#vao","#programDirty","#uProgress","#uPaletteTexture","#uPaletteMetricTexture","#uPaletteSize","#fbo","#fboTexture","#blitProgram","#uColorMap","#uOutlineWidth","#uOutlineResolution","#floatFbo","#floatFboTexture","#linearProgram","#uLinearProgress","#uLinearPaletteTexture","#uLinearPaletteMetricTexture","#uLinearPaletteSize","#uLinearUvOverride","#linearProgramDirty","position","invertAxes","outlineWidth","#rebuildProgram","#buildFBO","#defines","useImplicitPolarFlipY","#resizeFBO","index","indexOrColor","px","py","savedViewport","createCubeMesh","resolution","verts","idx","n","faces","axIdx","sign","uIdx","vIdx","_uSign","_vSign","base","j","u","pos","d","createSlicedCubeMesh","slices","padding","lo","span","createSlicedCylinderMesh","radialSegments","TWO_PI","capSegs","maxR","hLo","hHi","discBase","ring","rPos","angle","stride","POLAR_MODEL_IDS","CONE_MODEL_IDS","BICONE_MODEL_IDS","CONE_INV_MODEL_IDS","mat4Perspective","fov","aspect","near","far","f","nf","mat4Multiply","mat4RotateY","mat4RotateX","mat4Ortho","left","right","bottom","top","bt","mat4Translate","GUTTERED_CLIP_PADDING","SETTLED_CLIP_PASS_COUNT","PaletteViz3D","#modelMatrix","#depthProgram","#vbo","#ibo","#indexCount","#meshDirty","#isPolar","#sliceCount","#interactiveUntil","#refineTimer","#uMVP","#uDepthMVP","#uPosition","#uDepthPosition","#uColorRotation","#uDepthColorRotation","#uSliceOffset","#uDepthSliceOffset","#rot3x3","#fboDepth","#blitVao","#blitQuadBuf","modelMatrix","#buildMesh","#syncSliceBudget","#desiredSliceCount","vertices","indices","diagonal","settled","#isInteractive","#markInteractive","#clipPassCount","#clipSliceOffset","passIndex","passCount","step","#drawClipPasses","program","mvp","colorRotation","sliceOffset","#applySharedUniforms","modelId","prepassFragSrc","#buildMVP","proj","view","fixedOrientation","dx","dy","fixed","fixedInverse","screenIncrement","colorIncrement","increment","matrix"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCAfC,EAAe;AAAA;AAAA;AAAA,GCAfC,EAAe;AAAA;AAAA;AAAA;AAAA,GCAfC,EAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ECAfC,EAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ECAfC,EAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ECAfC,EAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GCAfC,EAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,ECAfC,EAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EC4CFC,EAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAUlBC,EAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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"}