{"version":3,"file":"index.mjs","names":[],"sources":["../src/dither/data/default-palettes.json","../src/dither/functions/palette-order.ts","../src/replaceColors/replaceColors.ts","../src/dither/data/diffusion-maps.ts","../src/dither/functions/bayer-matrix.ts","../src/dither/functions/color-helpers.ts","../src/dither/functions/utilities.ts","../src/dither/processing.ts","../src/dither/functions/find-closest-palette-color.ts","../src/dither/wasm-error-diffusion-rgb.ts","../src/utils/blue-noise-texture.ts","../src/utils/oklab.ts","../node_modules/rgbquant/src/rgbquant.js","../src/utils/dithering.ts","../src/dither/adjustment-async.ts","../src/dither/dither.ts","../src/image-style.ts","../src/auto-processing.ts","../src/index.ts"],"sourcesContent":["{\n  \"default\": [\n    { \"name\": \"black\", \"color\": \"#000\", \"deviceColor\": \"#212121\" },\n    { \"name\": \"white\", \"color\": \"#fff\", \"deviceColor\": \"#e6e6e6\" }\n  ],\n  \"generic-2-color-eink\": [\n    { \"name\": \"black\", \"color\": \"#000000\", \"deviceColor\": \"#000000\" },\n    { \"name\": \"white\", \"color\": \"#FFFFFF\", \"deviceColor\": \"#FFFFFF\" }\n  ],\n  \"generic-4-grayscale\": [\n    { \"name\": \"black\", \"color\": \"#000000\", \"deviceColor\": \"#000000\" },\n    { \"name\": \"gray1\", \"color\": \"#555555\", \"deviceColor\": \"#555555\" },\n    { \"name\": \"gray2\", \"color\": \"#AAAAAA\", \"deviceColor\": \"#AAAAAA\" },\n    { \"name\": \"white\", \"color\": \"#FFFFFF\", \"deviceColor\": \"#FFFFFF\" }\n  ],\n  \"trmnl-seeed-16-grayscale\": [\n    { \"name\": \"black\", \"color\": \"#000000\", \"deviceColor\": \"#000000\" },\n    { \"name\": \"gray1\", \"color\": \"#111111\", \"deviceColor\": \"#111111\" },\n    { \"name\": \"gray2\", \"color\": \"#222222\", \"deviceColor\": \"#222222\" },\n    { \"name\": \"gray3\", \"color\": \"#333333\", \"deviceColor\": \"#333333\" },\n    { \"name\": \"gray4\", \"color\": \"#444444\", \"deviceColor\": \"#444444\" },\n    { \"name\": \"gray5\", \"color\": \"#555555\", \"deviceColor\": \"#555555\" },\n    { \"name\": \"gray6\", \"color\": \"#666666\", \"deviceColor\": \"#666666\" },\n    { \"name\": \"gray7\", \"color\": \"#777777\", \"deviceColor\": \"#777777\" },\n    { \"name\": \"gray8\", \"color\": \"#888888\", \"deviceColor\": \"#888888\" },\n    { \"name\": \"gray9\", \"color\": \"#999999\", \"deviceColor\": \"#999999\" },\n    { \"name\": \"gray10\", \"color\": \"#AAAAAA\", \"deviceColor\": \"#AAAAAA\" },\n    { \"name\": \"gray11\", \"color\": \"#BBBBBB\", \"deviceColor\": \"#BBBBBB\" },\n    { \"name\": \"gray12\", \"color\": \"#CCCCCC\", \"deviceColor\": \"#CCCCCC\" },\n    { \"name\": \"gray13\", \"color\": \"#DDDDDD\", \"deviceColor\": \"#DDDDDD\" },\n    { \"name\": \"gray14\", \"color\": \"#EEEEEE\", \"deviceColor\": \"#EEEEEE\" },\n    { \"name\": \"white\", \"color\": \"#FFFFFF\", \"deviceColor\": \"#FFFFFF\" }\n  ],\n  \"aitjcize-spectra6\": [\n    { \"name\": \"black\", \"color\": \"#020202\", \"deviceColor\": \"#000000\" },\n    { \"name\": \"white\", \"color\": \"#BEC8C8\", \"deviceColor\": \"#FFFFFF\" },\n    { \"name\": \"blue\", \"color\": \"#05409E\", \"deviceColor\": \"#0000FF\" },\n    { \"name\": \"green\", \"color\": \"#27663C\", \"deviceColor\": \"#00FF00\" },\n    { \"name\": \"red\", \"color\": \"#871300\", \"deviceColor\": \"#FF0000\" },\n    { \"name\": \"yellow\", \"color\": \"#CDCA00\", \"deviceColor\": \"#FFFF00\" }\n  ],\n  \"gameboy\": [\n    { \"name\": \"gameboy0\", \"color\": \"#0f380f\", \"deviceColor\": \"#0F0\" },\n    { \"name\": \"gameboy1\", \"color\": \"#306230\", \"deviceColor\": \"#3F0\" },\n    { \"name\": \"gameboy2\", \"color\": \"#8bac0f\", \"deviceColor\": \"#7F0\" },\n    { \"name\": \"gameboy3\", \"color\": \"#9bbc0f\", \"deviceColor\": \"#FF0\" }\n  ],\n  \"spectra6legacy\": [\n    { \"name\": \"black\", \"color\": \"#191E21\", \"deviceColor\": \"#000000\" },\n    { \"name\": \"white\", \"color\": \"#e8e8e8\", \"deviceColor\": \"#FFFFFF\" },\n    { \"name\": \"blue\", \"color\": \"#2157ba\", \"deviceColor\": \"#0000FF\" },\n    { \"name\": \"green\", \"color\": \"#125f20\", \"deviceColor\": \"#00FF00\" },\n    { \"name\": \"red\", \"color\": \"#b21318\", \"deviceColor\": \"#FF0000\" },\n    { \"name\": \"yellow\", \"color\": \"#efde44\", \"deviceColor\": \"#FFFF00\" }\n  ],\n  \"spectra6\": [\n    { \"name\": \"black\", \"color\": \"#1F2226\", \"deviceColor\": \"#000000\" },\n    { \"name\": \"white\", \"color\": \"#B9C7C9\", \"deviceColor\": \"#FFFFFF\" },\n    { \"name\": \"blue\", \"color\": \"#233F8E\", \"deviceColor\": \"#0000FF\" },\n    { \"name\": \"green\", \"color\": \"#35563A\", \"deviceColor\": \"#00FF00\" },\n    { \"name\": \"red\", \"color\": \"#62201E\", \"deviceColor\": \"#FF0000\" },\n    { \"name\": \"yellow\", \"color\": \"#C1BB1E\", \"deviceColor\": \"#FFFF00\" }\n  ],\n  \"spectra6-boeber\": [\n    { \"name\": \"black\", \"color\": \"#1f2226\", \"deviceColor\": \"#000000\" },\n    { \"name\": \"white\", \"color\": \"#d6d6d6\", \"deviceColor\": \"#FFFFFF\" },\n    { \"name\": \"blue\", \"color\": \"#416ce1\", \"deviceColor\": \"#0000FF\" },\n    { \"name\": \"green\", \"color\": \"#067406\", \"deviceColor\": \"#00FF00\" },\n    { \"name\": \"red\", \"color\": \"#ea4843\", \"deviceColor\": \"#FF0000\" },\n    { \"name\": \"yellow\", \"color\": \"#dbd529\", \"deviceColor\": \"#FFFF00\" }\n  ],\n  \"spectra6-original\": [\n    { \"name\": \"black\", \"color\": \"#000000\", \"deviceColor\": \"#000000\" },\n    { \"name\": \"white\", \"color\": \"#FFFFFF\", \"deviceColor\": \"#FFFFFF\" },\n    { \"name\": \"blue\", \"color\": \"#0000FF\", \"deviceColor\": \"#0000FF\" },\n    { \"name\": \"green\", \"color\": \"#00FF00\", \"deviceColor\": \"#00FF00\" },\n    { \"name\": \"red\", \"color\": \"#FF0000\", \"deviceColor\": \"#FF0000\" },\n    { \"name\": \"yellow\", \"color\": \"#FFFF00\", \"deviceColor\": \"#FFFF00\" }\n  ],\n  \"spectra6-original-preview\": [\n    { \"name\": \"black\", \"color\": \"#000000\", \"deviceColor\": \"#1F2226\" },\n    { \"name\": \"white\", \"color\": \"#FFFFFF\", \"deviceColor\": \"#B9C7C9\" },\n    { \"name\": \"blue\", \"color\": \"#0000FF\", \"deviceColor\": \"#233F8E\" },\n    { \"name\": \"green\", \"color\": \"#00FF00\", \"deviceColor\": \"#35563A\" },\n    { \"name\": \"red\", \"color\": \"#FF0000\", \"deviceColor\": \"#62201E\" },\n    { \"name\": \"yellow\", \"color\": \"#FFFF00\", \"deviceColor\": \"#C1BB1E\" }\n  ],\n  \"acep\": [\n    { \"name\": \"black\", \"color\": \"#191E21\", \"deviceColor\": \"#000\" },\n    { \"name\": \"white\", \"color\": \"#F1F1F1\", \"deviceColor\": \"#fff\" },\n    { \"name\": \"blue\", \"color\": \"#31318F\", \"deviceColor\": \"#0000FF\" },\n    { \"name\": \"green\", \"color\": \"#53A428\", \"deviceColor\": \"#00FF00\" },\n    { \"name\": \"red\", \"color\": \"#D20E13\", \"deviceColor\": \"#FF0000\" },\n    { \"name\": \"orange\", \"color\": \"#B85E1C\", \"deviceColor\": \"#FF8000\" },\n    { \"name\": \"yellow\", \"color\": \"#F3CF11\", \"deviceColor\": \"#FFFF00\" }\n  ]\n}\n","const CANONICAL_COLOR_ORDER = [\n  \"black\",\n  \"gray1\",\n  \"gray2\",\n  \"gray3\",\n  \"gray4\",\n  \"gray5\",\n  \"gray6\",\n  \"gray7\",\n  \"gray8\",\n  \"gray9\",\n  \"gray10\",\n  \"gray11\",\n  \"gray12\",\n  \"gray13\",\n  \"gray14\",\n  \"white\",\n  \"blue\",\n  \"green\",\n  \"red\",\n  \"orange\",\n  \"yellow\",\n  \"gameboy0\",\n  \"gameboy1\",\n  \"gameboy2\",\n  \"gameboy3\",\n];\n\nexport interface PaletteColorEntry {\n  name: string;\n  color: string;\n  deviceColor: string;\n}\n\nexport type PaletteRegistry = Record<string, PaletteColorEntry[]>;\n\nconst roleRank = (role: string, index: number) => {\n  const rank = CANONICAL_COLOR_ORDER.indexOf(role);\n  return rank === -1 ? CANONICAL_COLOR_ORDER.length + index : rank;\n};\n\nexport const normalizePaletteKey = (name: string | undefined) =>\n  (name || \"default\").toLowerCase();\n\nexport const getNamedEntries = (registry: PaletteRegistry, name: string) => {\n  const key = normalizePaletteKey(name);\n  const entries = registry[key] || registry.default || [];\n  return entries\n    .map((entry, index) => ({ entry, index }))\n    .sort(\n      (a, b) =>\n        roleRank(a.entry.name, a.index) - roleRank(b.entry.name, b.index)\n    )\n    .map(({ entry }) => entry);\n};\n\nexport const getNamedColors = (registry: PaletteRegistry, name: string) =>\n  getNamedEntries(registry, name).map((entry) => entry.color);\n\nexport const getNamedDeviceColors = (\n  registry: PaletteRegistry,\n  name: string\n) => getNamedEntries(registry, name).map((entry) => entry.deviceColor);\n\nexport const getNamedRoles = (registry: PaletteRegistry, name: string) =>\n  getNamedEntries(registry, name).map((entry) => entry.name);\n\nexport const alignReplacementColors = (\n  sourceColors: string[],\n  sourceRoles: string[],\n  replacementColors: string[],\n  replacementRoles: string[]\n) => {\n  const replacementByRole = new Map<string, string>();\n  replacementRoles.forEach((role, index) => {\n    replacementByRole.set(role, replacementColors[index]);\n  });\n\n  return sourceRoles.map(\n    (role, index) =>\n      replacementByRole.get(role) ?? sourceColors[index] ?? replacementColors[index]\n  );\n};\n","import type { CanvasLike } from \"../dither/dither\";\nimport type { PaletteColorEntry } from \"../dither/functions/palette-order\";\n\ntype RGB = [number, number, number];\n\nexport interface ReplaceColorsOptions {\n  originalColors: string[];\n  replaceColors: string[];\n}\n\nexport type ReplaceColorsPalette = Pick<\n  PaletteColorEntry,\n  \"color\" | \"deviceColor\"\n>[];\n\nconst hexToRgb = (h: string): RGB => {\n  const rgb = h\n    .replace(\n      /^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i,\n      (_, r, g, b) => \"#\" + r + r + g + g + b + b\n    )\n    .substring(1)\n    .match(/.{2}/g)\n    ?.map((x) => parseInt(x, 16));\n\n  if (!rgb || rgb.length !== 3 || rgb.some((channel) => Number.isNaN(channel))) {\n    throw new Error(`Invalid hex color: ${h}`);\n  }\n\n  return rgb as RGB;\n};\n\nconst colorKey = (rgb: RGB) => (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];\n\nconst isPaletteEntryArray = (\n  palette: ReplaceColorsPalette | ReplaceColorsOptions\n): palette is ReplaceColorsPalette =>\n  Array.isArray(palette) &&\n  palette.every(\n    (entry) =>\n      typeof entry === \"object\" &&\n      entry !== null &&\n      \"color\" in entry &&\n      \"deviceColor\" in entry\n  );\n\nconst createReplacementMap = (\n  palette: ReplaceColorsPalette | ReplaceColorsOptions\n) => {\n  const entries = isPaletteEntryArray(palette)\n    ? palette\n    : palette.originalColors.map((color, index) => ({\n        color,\n        deviceColor: palette.replaceColors[index],\n      }));\n\n  return new Map<number, RGB>(\n    entries\n      .filter((entry) => Boolean(entry.deviceColor))\n      .map((entry) => [\n        colorKey(hexToRgb(entry.color)),\n        hexToRgb(entry.deviceColor),\n      ])\n  );\n};\n\nexport const replaceColors = (\n  fromCanvas: CanvasLike,\n  destCanvas: CanvasLike,\n  palette: ReplaceColorsPalette | ReplaceColorsOptions\n) => {\n  const fromCtx = fromCanvas.getContext(\"2d\");\n  if (!fromCtx) return;\n\n  const width = fromCanvas.width;\n  const height = fromCanvas.height;\n\n  const destCtx = destCanvas.getContext(\"2d\");\n  if (!destCtx) return;\n\n  const imageData = fromCtx.getImageData(0, 0, width, height);\n  const data = imageData.data;\n  let errorColors = 0;\n  const replacementMap = createReplacementMap(palette);\n\n  for (let i = 0; i < data.length; i += 4) {\n    const replacement = replacementMap.get(\n      (data[i] << 16) | (data[i + 1] << 8) | data[i + 2]\n    );\n\n    if (!replacement) {\n      errorColors++;\n      continue;\n    }\n\n    data[i] = replacement[0];\n    data[i + 1] = replacement[1];\n    data[i + 2] = replacement[2];\n  }\n\n  if (errorColors > 0) {\n    console.warn(\n      `replaceColors: ${errorColors} pixels were not replaced. Check if the colors match exactly.`\n    );\n  }\n\n  destCanvas.width = width;\n  destCanvas.height = height;\n  destCtx.putImageData(imageData, 0, 0);\n};\n","const maps = {\n  floydSteinberg: () => [\n    { offset: [1, 0], factor: 7 / 16 },\n    { offset: [-1, 1], factor: 3 / 16 },\n    { offset: [0, 1], factor: 5 / 16 },\n    { offset: [1, 1], factor: 1 / 16 },\n  ],\n  falseFloydSteinberg: () => [\n    { offset: [1, 0], factor: 3 / 8 },\n    { offset: [0, 1], factor: 3 / 8 },\n    { offset: [1, 1], factor: 2 / 8 },\n  ],\n  atkinson: () => [\n    { offset: [1, 0], factor: 1 / 8 },\n    { offset: [2, 0], factor: 1 / 8 },\n    { offset: [-1, 1], factor: 1 / 8 },\n    { offset: [0, 1], factor: 1 / 8 },\n    { offset: [1, 1], factor: 1 / 8 },\n    { offset: [0, 2], factor: 1 / 8 },\n  ],\n  jarvis: () => [\n    { offset: [1, 0], factor: 7 / 48 },\n    { offset: [2, 0], factor: 5 / 48 },\n\n    { offset: [-2, 1], factor: 3 / 48 },\n    { offset: [-1, 1], factor: 5 / 48 },\n    { offset: [0, 1], factor: 7 / 48 },\n    { offset: [1, 1], factor: 5 / 48 },\n    { offset: [2, 1], factor: 3 / 48 },\n\n    { offset: [-2, 2], factor: 1 / 48 },\n    { offset: [-1, 2], factor: 3 / 48 },\n    { offset: [0, 2], factor: 4 / 48 },\n    { offset: [1, 2], factor: 3 / 48 },\n    { offset: [2, 2], factor: 1 / 48 },\n  ],\n  stucki: () => [\n    { offset: [1, 0], factor: 8 / 42 },\n    { offset: [2, 0], factor: 4 / 42 },\n\n    { offset: [-2, 1], factor: 2 / 42 },\n    { offset: [-1, 1], factor: 4 / 42 },\n    { offset: [0, 1], factor: 8 / 42 },\n    { offset: [1, 1], factor: 4 / 42 },\n    { offset: [2, 1], factor: 2 / 42 },\n\n    { offset: [-2, 2], factor: 1 / 42 },\n    { offset: [-1, 2], factor: 2 / 42 },\n    { offset: [0, 2], factor: 4 / 42 },\n    { offset: [1, 2], factor: 2 / 42 },\n    { offset: [2, 2], factor: 1 / 42 },\n  ],\n  burkes: () => [\n    { offset: [1, 0], factor: 8 / 32 },\n    { offset: [2, 0], factor: 4 / 32 },\n\n    { offset: [-2, 1], factor: 2 / 32 },\n    { offset: [-1, 1], factor: 4 / 32 },\n    { offset: [0, 1], factor: 8 / 32 },\n    { offset: [1, 1], factor: 4 / 32 },\n    { offset: [2, 1], factor: 2 / 32 },\n  ],\n  sierra3: () => [\n    { offset: [1, 0], factor: 5 / 32 },\n    { offset: [2, 0], factor: 3 / 32 },\n\n    { offset: [-2, 1], factor: 2 / 32 },\n    { offset: [-1, 1], factor: 4 / 32 },\n    { offset: [0, 1], factor: 5 / 32 },\n    { offset: [1, 1], factor: 4 / 32 },\n    { offset: [2, 1], factor: 2 / 32 },\n\n    { offset: [-1, 2], factor: 2 / 32 },\n    { offset: [0, 2], factor: 3 / 32 },\n    { offset: [1, 2], factor: 2 / 32 },\n  ],\n  sierra2: () => [\n    { offset: [1, 0], factor: 4 / 16 },\n    { offset: [2, 0], factor: 3 / 16 },\n\n    { offset: [-2, 1], factor: 1 / 16 },\n    { offset: [-1, 1], factor: 2 / 16 },\n    { offset: [0, 1], factor: 3 / 16 },\n    { offset: [1, 1], factor: 2 / 16 },\n    { offset: [2, 1], factor: 1 / 16 },\n  ],\n  \"sierra2-4a\": () => [\n    { offset: [1, 0], factor: 2 / 4 },\n    { offset: [-1, 1], factor: 1 / 4 },\n    { offset: [0, 1], factor: 1 / 4 },\n  ],\n  fan: () => [\n    { offset: [1, 0], factor: 7 / 16 },\n    { offset: [-2, 1], factor: 1 / 16 },\n    { offset: [-1, 1], factor: 3 / 16 },\n    { offset: [0, 1], factor: 5 / 16 },\n  ],\n  shiauFan: () => [\n    { offset: [1, 0], factor: 4 / 8 },\n    { offset: [-2, 1], factor: 1 / 8 },\n    { offset: [-1, 1], factor: 1 / 8 },\n    { offset: [0, 1], factor: 2 / 8 },\n  ],\n  shiauFan2: () => [\n    { offset: [1, 0], factor: 7 / 14 },\n    { offset: [-3, 1], factor: 1 / 14 },\n    { offset: [-2, 1], factor: 1 / 14 },\n    { offset: [-1, 1], factor: 2 / 14 },\n    { offset: [0, 1], factor: 3 / 14 },\n  ],\n  jarvisJudiceNinke: () => [\n    { offset: [1, 0], factor: 7 / 48 },\n    { offset: [2, 0], factor: 5 / 48 },\n\n    { offset: [-2, 1], factor: 3 / 48 },\n    { offset: [-1, 1], factor: 5 / 48 },\n    { offset: [0, 1], factor: 7 / 48 },\n    { offset: [1, 1], factor: 5 / 48 },\n    { offset: [2, 1], factor: 3 / 48 },\n\n    { offset: [-2, 2], factor: 1 / 48 },\n    { offset: [-1, 2], factor: 3 / 48 },\n    { offset: [0, 2], factor: 5 / 48 },\n    { offset: [1, 2], factor: 3 / 48 },\n    { offset: [2, 2], factor: 1 / 48 },\n  ],\n  Fan: () => maps.fan(),\n  ShiauFan: () => maps.shiauFan(),\n  ShiauFan2: () => maps.shiauFan2(),\n  \"Sierra2-4A\": () => maps[\"sierra2-4a\"](),\n};\n\nexport default maps;\n","const generateBayerIndex = (size: number): number[][] => {\n  if (size <= 2) {\n    return [\n      [0, 2],\n      [3, 1],\n    ];\n  }\n\n  const half = size / 2;\n  const subMatrix = generateBayerIndex(half);\n  const matrix = Array.from({ length: size }, () => new Array<number>(size));\n\n  for (let y = 0; y < half; y += 1) {\n    for (let x = 0; x < half; x += 1) {\n      const value = subMatrix[y][x] * 4;\n      matrix[y][x] = value;\n      matrix[y][half + x] = value + 2;\n      matrix[half + y][x] = value + 3;\n      matrix[half + y][half + x] = value + 1;\n    }\n  }\n\n  return matrix;\n};\n\nconst normalizeBayerSize = (value: number) => {\n  if (value <= 2) return 2;\n  if (value <= 4) return 4;\n  if (value <= 8) return 8;\n  return 16;\n};\n\nconst reindexMatrixValues = (matrix: number[][]) => {\n  const sortedValues = matrix\n    .flat()\n    .sort((left, right) => left - right);\n  const valueIndex = new Map<number, number>();\n  sortedValues.forEach((value, index) => valueIndex.set(value, index));\n\n  return matrix.map((row) =>\n    row.map((value) => valueIndex.get(value) ?? value)\n  );\n};\n\nconst createBayerMatrix = (size: [number, number] | number[]) => {\n  const width = normalizeBayerSize(size[0] ?? 4);\n  const height = normalizeBayerSize(size[1] ?? width);\n  const matrixSize = Math.max(width, height);\n  const matrix = generateBayerIndex(matrixSize);\n\n  if (width === matrixSize && height === matrixSize) return matrix;\n\n  return reindexMatrixValues(\n    matrix.slice(0, height).map((row) => row.slice(0, width))\n  );\n};\n\nexport default createBayerMatrix;\n","export function hexToRgb(hex) {\n  const shorthandRegex = /^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i;\n  hex = hex.replace(shorthandRegex, (_match, r, g, b) => {\n    return r + r + g + g + b + b;\n  });\n\n  const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n  return result\n    ? [\n        parseInt(result[1], 16),\n        parseInt(result[2], 16),\n        parseInt(result[3], 16),\n      ]\n    : null;\n}\n\nconst colorHelper = { hexToRgb };\n\nexport default colorHelper;\n","export function randomInteger(min, max) {\n  return Math.floor(Math.random() * (max - min + 1)) + min;\n}\nconst utilities = { randomInteger };\n\nexport default utilities;\n","export type RGB = [number, number, number];\nexport type RGBA = [number, number, number, number];\n\nexport type ToneMappingMode = \"off\" | \"contrast\" | \"scurve\";\nexport type ColorMatchingMode = \"rgb\" | \"lab\" | \"chroma\";\nexport type DynamicRangeCompressionMode = \"off\" | \"display\" | \"auto\";\nexport type LevelCompressionMode = \"off\" | \"perChannel\" | \"luma\";\nexport type PaperNormalizationMode = \"off\" | \"warmPaper\";\nexport type AdjustmentQuality = \"fast\" | \"accurate\";\n\nexport type LevelRGB = number | RGB;\n\nexport interface PercentileClip {\n  low: number;\n  high: number;\n}\n\nexport interface LevelCompressionOptions {\n  mode?: LevelCompressionMode;\n  black?: LevelRGB;\n  white?: LevelRGB;\n  auto?: boolean;\n  autoThreshold?: number;\n  percentileClip?: PercentileClip;\n}\n\nexport interface ClarityOptions {\n  amount?: number;\n  radius?: number;\n  midtone?: number;\n}\n\nexport interface ToneMappingOptions {\n  mode?: ToneMappingMode;\n  /**\n   * Exposure adjustment in stops. `0` is neutral, `1` doubles brightness.\n   */\n  exposure?: number;\n  /**\n   * Saturation adjustment. `0` is neutral, `0.5` means 1.5x, `-1` removes saturation.\n   */\n  saturation?: number;\n  /**\n   * Contrast adjustment. `0` is neutral, `0.25` means 1.25x, `-1` means 0.5x.\n   */\n  contrast?: number;\n  strength?: number;\n  shadowBoost?: number;\n  highlightCompress?: number;\n  midpoint?: number;\n}\n\nexport interface DynamicRangeCompressionOptions {\n  mode?: DynamicRangeCompressionMode;\n  black?: LevelRGB;\n  white?: LevelRGB;\n  strength?: number;\n  lowPercentile?: number;\n  highPercentile?: number;\n  quality?: AdjustmentQuality;\n  preserveWhite?: boolean;\n  whitePreservePercentile?: number;\n  whitePreserveMinLuma?: number;\n  whitePreserveMaxSaturation?: number;\n}\n\nexport interface PaperNormalizationOptions {\n  mode?: PaperNormalizationMode;\n  strength?: number;\n  minLuma?: number;\n  saturationThreshold?: number;\n  warmBiasThreshold?: number;\n  blackAnchor?: number;\n  preserveRed?: number;\n  paperWhite?: LevelRGB;\n}\n\nexport interface ImageProcessingOptions {\n  paperNormalization?: PaperNormalizationOptions;\n  clarity?: ClarityOptions;\n  toneMapping?: ToneMappingOptions;\n  dynamicRangeCompression?: DynamicRangeCompressionOptions | boolean;\n  levelCompression?: LevelCompressionOptions;\n  previewMode?: \"fast\" | \"final\";\n}\n\nexport type ProcessingPresetName =\n  | \"balanced\"\n  | \"dynamic\"\n  | \"vivid\"\n  | \"soft\"\n  | \"grayscale\"\n  | \"restore\"\n  | \"posterScan\"\n  | (string & {});\n\nexport interface ProcessingPreset {\n  name: ProcessingPresetName;\n  title: string;\n  description: string;\n  paperNormalization?: PaperNormalizationOptions;\n  toneMapping: ToneMappingOptions;\n  dynamicRangeCompression?: DynamicRangeCompressionOptions;\n  colorMatching?: ColorMatchingMode;\n  errorDiffusionMatrix?: string;\n}\n\nexport interface ImageDataLike {\n  width: number;\n  height: number;\n  data: Uint8ClampedArray;\n}\n\nconst exposureAdjustmentFromMultiplier = (multiplier: number) =>\n  Number(Math.log2(multiplier).toFixed(3));\n\nconst linearAdjustmentFromMultiplier = (multiplier: number) =>\n  Number((multiplier - 1).toFixed(3));\n\nconst exposureAdjustmentToMultiplier = (adjustment: number) =>\n  Math.pow(2, adjustment);\n\nconst linearAdjustmentToMultiplier = (adjustment: number) =>\n  Math.max(0, adjustment + 1);\n\nconst contrastAdjustmentToMultiplier = (adjustment: number) =>\n  adjustment < 0 ? Math.max(0.5, 1 + adjustment * 0.5) : adjustment + 1;\n\nexport const PROCESSING_PRESETS: Record<string, ProcessingPreset> = {\n  balanced: {\n    name: \"balanced\",\n    title: \"Balanced\",\n    description:\n      \"Compresses display luminance range for general photo conversion.\",\n    toneMapping: {\n      mode: \"contrast\",\n      exposure: 0,\n      saturation: 0,\n      contrast: 0,\n    },\n    dynamicRangeCompression: {\n      mode: \"display\",\n      strength: 1,\n    },\n    colorMatching: \"rgb\",\n    errorDiffusionMatrix: \"floydSteinberg\",\n  },\n  dynamic: {\n    name: \"dynamic\",\n    title: \"Dynamic\",\n    description:\n      \"Uses S-curve tone mapping for brighter, punchier photographic output.\",\n    toneMapping: {\n      mode: \"scurve\",\n      exposure: 0,\n      saturation: linearAdjustmentFromMultiplier(1.3),\n      strength: 0.9,\n      shadowBoost: 0,\n      highlightCompress: -1.5,\n      midpoint: 0.5,\n    },\n    dynamicRangeCompression: {\n      mode: \"off\",\n    },\n    colorMatching: \"rgb\",\n    errorDiffusionMatrix: \"floydSteinberg\",\n  },\n  vivid: {\n    name: \"vivid\",\n    title: \"Vivid\",\n    description: \"Boosts color and applies a gentler S-curve for illustrations.\",\n    toneMapping: {\n      mode: \"scurve\",\n      exposure: exposureAdjustmentFromMultiplier(1.1),\n      saturation: linearAdjustmentFromMultiplier(1.6),\n      strength: 0.7,\n      shadowBoost: 0.1,\n      highlightCompress: -1.3,\n      midpoint: 0.5,\n    },\n    dynamicRangeCompression: {\n      mode: \"off\",\n    },\n    colorMatching: \"rgb\",\n    errorDiffusionMatrix: \"floydSteinberg\",\n  },\n  soft: {\n    name: \"soft\",\n    title: \"Soft\",\n    description: \"Reduces contrast and uses Stucki diffusion for smoother tones.\",\n    toneMapping: {\n      mode: \"contrast\",\n      exposure: 0,\n      saturation: linearAdjustmentFromMultiplier(1.1),\n      contrast: linearAdjustmentFromMultiplier(0.9),\n    },\n    dynamicRangeCompression: {\n      mode: \"display\",\n      strength: 1,\n    },\n    colorMatching: \"rgb\",\n    errorDiffusionMatrix: \"stucki\",\n  },\n  grayscale: {\n    name: \"grayscale\",\n    title: \"Grayscale\",\n    description: \"Removes saturation and uses LAB matching for monochrome work.\",\n    toneMapping: {\n      mode: \"scurve\",\n      exposure: 0,\n      saturation: linearAdjustmentFromMultiplier(0),\n      strength: 0.8,\n      shadowBoost: 0.1,\n      highlightCompress: -1.4,\n      midpoint: 0.5,\n    },\n    dynamicRangeCompression: {\n      mode: \"display\",\n      strength: 1,\n    },\n    colorMatching: \"lab\",\n    errorDiffusionMatrix: \"floydSteinberg\",\n  },\n  restore: {\n    name: \"restore\",\n    title: \"Restore\",\n    description:\n      \"Expands faded scans and paintings before mapping them to the display range.\",\n    toneMapping: {\n      mode: \"scurve\",\n      exposure: exposureAdjustmentFromMultiplier(1.08),\n      saturation: linearAdjustmentFromMultiplier(0.9),\n      strength: 1,\n      shadowBoost: 0.25,\n      highlightCompress: -0.75,\n      midpoint: 0.46,\n    },\n    dynamicRangeCompression: {\n      mode: \"auto\",\n      strength: 0.9,\n      lowPercentile: 0.02,\n      highPercentile: 0.98,\n    },\n    colorMatching: \"lab\",\n    errorDiffusionMatrix: \"floydSteinberg\",\n  },\n  posterscan: {\n    name: \"posterScan\",\n    title: \"Poster Scan\",\n    description:\n      \"Neutralizes warm paper, anchors black ink, and preserves strong poster colors.\",\n    paperNormalization: {\n      mode: \"warmPaper\",\n      strength: 0.95,\n      minLuma: 82,\n      saturationThreshold: 0.56,\n      warmBiasThreshold: 8,\n      blackAnchor: 0.95,\n      preserveRed: 0.85,\n      paperWhite: [248, 248, 246],\n    },\n    toneMapping: {\n      mode: \"scurve\",\n      exposure: exposureAdjustmentFromMultiplier(1.04),\n      saturation: linearAdjustmentFromMultiplier(1.05),\n      strength: 0.92,\n      shadowBoost: 0.08,\n      highlightCompress: -0.55,\n      midpoint: 0.44,\n    },\n    dynamicRangeCompression: {\n      mode: \"auto\",\n      strength: 1,\n      lowPercentile: 0.015,\n      highPercentile: 0.985,\n    },\n    colorMatching: \"rgb\",\n    errorDiffusionMatrix: \"floydSteinberg\",\n  },\n};\n\nexport const getProcessingPreset = (\n  name: ProcessingPresetName\n): ProcessingPreset | null => {\n  const preset = PROCESSING_PRESETS[String(name).toLowerCase()];\n  return preset\n    ? {\n        ...preset,\n        paperNormalization: preset.paperNormalization\n          ? { ...preset.paperNormalization }\n          : undefined,\n        toneMapping: { ...preset.toneMapping },\n        dynamicRangeCompression: preset.dynamicRangeCompression\n          ? { ...preset.dynamicRangeCompression }\n          : undefined,\n      }\n    : null;\n};\n\nexport const getProcessingPresetNames = () =>\n  Object.values(PROCESSING_PRESETS).map(({ name }) => name);\n\nexport const getProcessingPresetOptions = () =>\n  Object.values(PROCESSING_PRESETS).map(({ name, title, description }) => ({\n    value: name,\n    title,\n    description,\n  }));\n\nconst clamp = (value: number, min: number, max: number) =>\n  value < min ? min : value > max ? max : value;\n\nconst SHADOW_TONE_RESPONSE = 1.5;\n\nexport const clampByte = (value: number) => {\n  if (!Number.isFinite(value)) return 0;\n  return Math.round(clamp(value, 0, 255));\n};\n\nexport const luma709 = (r: number, g: number, b: number) =>\n  0.2126 * r + 0.7152 * g + 0.0722 * b;\n\nconst srgbToLinear = (() => {\n  const values = new Float64Array(256);\n  for (let value = 0; value < values.length; value += 1) {\n    const normalized = value / 255;\n    values[value] =\n      normalized > 0.04045\n        ? Math.pow((normalized + 0.055) / 1.055, 2.4)\n        : normalized / 12.92;\n  }\n  return values;\n})();\n\nconst labForwardPivot = (value: number) =>\n  value > 0.008856 ? Math.cbrt(value) : 7.787 * value + 16 / 116;\n\nconst rgbToLabLightness = (r: number, g: number, b: number) => {\n  const y =\n    srgbToLinear[r] * 0.2126729 +\n    srgbToLinear[g] * 0.7151522 +\n    srgbToLinear[b] * 0.072175;\n\n  return 116 * labForwardPivot(y) - 16;\n};\n\nexport const toRGB = (value: LevelRGB | undefined, fallback: number): RGB => {\n  if (Array.isArray(value)) {\n    return [\n      value[0] ?? fallback,\n      value[1] ?? fallback,\n      value[2] ?? fallback,\n    ];\n  }\n  const v = typeof value === \"number\" ? value : fallback;\n  return [v, v, v];\n};\n\nexport const toScalar = (value: LevelRGB | undefined, fallback: number) => {\n  if (Array.isArray(value)) {\n    return luma709(\n      value[0] ?? fallback,\n      value[1] ?? fallback,\n      value[2] ?? fallback\n    );\n  }\n  return typeof value === \"number\" ? value : fallback;\n};\n\nconst rgbToXyz = (r: number, g: number, b: number) => {\n  const rn = srgbToLinear[r];\n  const gn = srgbToLinear[g];\n  const bn = srgbToLinear[b];\n\n  return [\n    (rn * 0.4124564 + gn * 0.3575761 + bn * 0.1804375) * 100,\n    (rn * 0.2126729 + gn * 0.7151522 + bn * 0.072175) * 100,\n    (rn * 0.0193339 + gn * 0.119192 + bn * 0.9503041) * 100,\n  ] as RGB;\n};\n\nconst xyzToLab = (x: number, y: number, z: number) => {\n  const xn = labForwardPivot(x / 95.047);\n  const yn = labForwardPivot(y / 100);\n  const zn = labForwardPivot(z / 108.883);\n\n  return [116 * yn - 16, 500 * (xn - yn), 200 * (yn - zn)] as RGB;\n};\n\nexport const rgbToLab = (r: number, g: number, b: number) => {\n  const [x, y, z] = rgbToXyz(r, g, b);\n  return xyzToLab(x, y, z);\n};\n\nconst labToXyz = (l: number, a: number, b: number) => {\n  let y = (l + 16) / 116;\n  let x = a / 500 + y;\n  let z = y - b / 200;\n\n  x = x > 0.206897 ? Math.pow(x, 3) : (x - 16 / 116) / 7.787;\n  y = y > 0.206897 ? Math.pow(y, 3) : (y - 16 / 116) / 7.787;\n  z = z > 0.206897 ? Math.pow(z, 3) : (z - 16 / 116) / 7.787;\n\n  return [x * 95.047, y * 100, z * 108.883] as RGB;\n};\n\nconst xyzToRgb = (x: number, y: number, z: number) => {\n  const xn = x / 100;\n  const yn = y / 100;\n  const zn = z / 100;\n\n  let r = xn * 3.2404542 + yn * -1.5371385 + zn * -0.4985314;\n  let g = xn * -0.969266 + yn * 1.8760108 + zn * 0.041556;\n  let b = xn * 0.0556434 + yn * -0.2040259 + zn * 1.0572252;\n\n  r = r > 0.0031308 ? 1.055 * Math.pow(r, 1 / 2.4) - 0.055 : 12.92 * r;\n  g = g > 0.0031308 ? 1.055 * Math.pow(g, 1 / 2.4) - 0.055 : 12.92 * g;\n  b = b > 0.0031308 ? 1.055 * Math.pow(b, 1 / 2.4) - 0.055 : 12.92 * b;\n\n  return [clampByte(r * 255), clampByte(g * 255), clampByte(b * 255)] as RGB;\n};\n\nexport const labToRgb = (l: number, a: number, b: number) => {\n  const [x, y, z] = labToXyz(l, a, b);\n  return xyzToRgb(x, y, z);\n};\n\nexport const deltaE = (lab1: RGB, lab2: RGB) => {\n  const dl = lab1[0] - lab2[0];\n  const da = lab1[1] - lab2[1];\n  const db = lab1[2] - lab2[2];\n  return Math.sqrt(dl * dl + da * da + db * db);\n};\n\nconst getSaturation = (r: number, g: number, b: number) => {\n  const max = Math.max(r, g, b) / 255;\n  const min = Math.min(r, g, b) / 255;\n  return max === 0 ? 0 : (max - min) / max;\n};\n\nconst normalize = (value: number, min: number, max: number) =>\n  clamp((value - min) / (max - min), 0, 1);\n\nconst smoothstep = (edge0: number, edge1: number, value: number) => {\n  if (edge1 <= edge0) return value >= edge1 ? 1 : 0;\n  const x = normalize(value, edge0, edge1);\n  return x * x * (3 - 2 * x);\n};\n\nconst getDynamicRangeChromaProtection = (r: number, g: number, b: number) =>\n  smoothstep(0.18, 0.68, getSaturation(r, g, b)) * 0.85;\n\nconst isRedInk = (r: number, g: number, b: number, saturation: number) =>\n  saturation >= 0.34 && r >= g + 24 && r >= b + 28;\n\nconst applyPaperNormalization = (\n  image: ImageDataLike,\n  options: PaperNormalizationOptions | undefined\n) => {\n  if (!options || options.mode === \"off\") return;\n\n  const strength = clamp(options.strength ?? 1, 0, 1);\n  if (strength === 0) return;\n\n  const data = image.data;\n  const minLuma = options.minLuma ?? 86;\n  const saturationThreshold = options.saturationThreshold ?? 0.44;\n  const warmBiasThreshold = options.warmBiasThreshold ?? 8;\n  const blackAnchor = clamp(options.blackAnchor ?? 0.85, 0, 1);\n  const preserveRed = clamp(options.preserveRed ?? 0.75, 0, 1);\n  const paperWhite = toRGB(options.paperWhite, 248);\n\n  for (let i = 0; i < data.length; i += 4) {\n    const r = data[i];\n    const g = data[i + 1];\n    const b = data[i + 2];\n    const luma = luma709(r, g, b);\n    const saturation = getSaturation(r, g, b);\n    const redInk = isRedInk(r, g, b, saturation);\n\n    if (redInk) {\n      const redBoost = strength * preserveRed;\n      data[i] = clampByte(r + (255 - r) * 0.08 * redBoost);\n      data[i + 1] = clampByte(g * (1 - 0.08 * redBoost));\n      data[i + 2] = clampByte(b * (1 - 0.12 * redBoost));\n      continue;\n    }\n\n    const darkNeutralMask =\n      normalize(112 - luma, 0, 72) * normalize(0.42 - saturation, 0, 0.32);\n    if (darkNeutralMask > 0) {\n      const amount = darkNeutralMask * blackAnchor * strength;\n      data[i] = clampByte(r * (1 - 0.72 * amount));\n      data[i + 1] = clampByte(g * (1 - 0.72 * amount));\n      data[i + 2] = clampByte(b * (1 - 0.72 * amount));\n      continue;\n    }\n\n    const warmBias = Math.min(r - b, (r + g) / 2 - b);\n    const warmPaperMask =\n      normalize(luma, minLuma, 210) *\n      normalize(245 - luma, 0, 80) *\n      normalize(saturationThreshold - saturation, 0, saturationThreshold) *\n      normalize(warmBias, warmBiasThreshold, 34);\n\n    if (warmPaperMask <= 0) continue;\n\n    const amount = warmPaperMask * strength;\n    const targetLuma = Math.min(\n      252,\n      luma + (paperWhite[0] - luma) * (0.72 + 0.2 * strength)\n    );\n    const neutralR = targetLuma + (paperWhite[0] - 248) * 0.4;\n    const neutralG = targetLuma + (paperWhite[1] - 248) * 0.4;\n    const neutralB = targetLuma + (paperWhite[2] - 248) * 0.4;\n\n    data[i] = clampByte(r + (neutralR - r) * amount);\n    data[i + 1] = clampByte(g + (neutralG - g) * amount);\n    data[i + 2] = clampByte(b + (neutralB - b) * amount);\n  }\n};\n\nconst applyClarity = (\n  image: ImageDataLike,\n  options: ClarityOptions | undefined,\n  previewMode: \"fast\" | \"final\" = \"final\"\n) => {\n  if (!options) return;\n\n  const amount = clamp(options.amount ?? 0, -1, 1);\n  if (amount === 0) return;\n  if (previewMode === \"fast\") return;\n\n  const effectiveAmount = amount * 2;\n  const radius = clamp(Math.round(options.radius ?? 2), 1, 4);\n  const midtone = Math.max(0.1, options.midtone ?? 1.2);\n  const { data, width, height } = image;\n  const { source, temp } = getClarityScratch(data.length);\n  source.set(data);\n  const kernelSize = radius * 2 + 1;\n\n  for (let y = 0; y < height; y += 1) {\n    const row = y * width;\n    let sumR = 0;\n    let sumG = 0;\n    let sumB = 0;\n    for (let k = -radius; k <= radius; k += 1) {\n      const xi = clamp(k, 0, width - 1);\n      const index = (row + xi) * 4;\n      sumR += source[index];\n      sumG += source[index + 1];\n      sumB += source[index + 2];\n    }\n\n    for (let x = 0; x < width; x += 1) {\n      const output = (y * width + x) * 4;\n      temp[output] = sumR / kernelSize;\n      temp[output + 1] = sumG / kernelSize;\n      temp[output + 2] = sumB / kernelSize;\n\n      const removeX = clamp(x - radius, 0, width - 1);\n      const addX = clamp(x + radius + 1, 0, width - 1);\n      const removeIndex = (row + removeX) * 4;\n      const addIndex = (row + addX) * 4;\n      sumR += source[addIndex] - source[removeIndex];\n      sumG += source[addIndex + 1] - source[removeIndex + 1];\n      sumB += source[addIndex + 2] - source[removeIndex + 2];\n    }\n  }\n\n  for (let x = 0; x < width; x += 1) {\n    let sumR = 0;\n    let sumG = 0;\n    let sumB = 0;\n    for (let k = -radius; k <= radius; k += 1) {\n      const yi = clamp(k, 0, height - 1);\n      const index = (yi * width + x) * 4;\n      sumR += temp[index];\n      sumG += temp[index + 1];\n      sumB += temp[index + 2];\n    }\n\n    for (let y = 0; y < height; y += 1) {\n      const output = (y * width + x) * 4;\n      const blurredR = sumR / kernelSize;\n      const blurredG = sumG / kernelSize;\n      const blurredB = sumB / kernelSize;\n      const r = source[output];\n      const g = source[output + 1];\n      const b = source[output + 2];\n      const lightness = luma709(r, g, b) / 255;\n      const midtoneWeight = Math.pow(\n        clamp(1 - Math.abs(2 * lightness - 1), 0, 1),\n        midtone\n      );\n\n      data[output] = clampByte(\n        r + effectiveAmount * (r - blurredR) * midtoneWeight\n      );\n      data[output + 1] = clampByte(\n        g + effectiveAmount * (g - blurredG) * midtoneWeight\n      );\n      data[output + 2] = clampByte(\n        b + effectiveAmount * (b - blurredB) * midtoneWeight\n      );\n\n      const removeY = clamp(y - radius, 0, height - 1);\n      const addY = clamp(y + radius + 1, 0, height - 1);\n      const removeIndex = (removeY * width + x) * 4;\n      const addIndex = (addY * width + x) * 4;\n      sumR += temp[addIndex] - temp[removeIndex];\n      sumG += temp[addIndex + 1] - temp[removeIndex + 1];\n      sumB += temp[addIndex + 2] - temp[removeIndex + 2];\n    }\n  }\n};\n\nlet clarityScratch:\n  | {\n      length: number;\n      source: Uint8ClampedArray;\n      temp: Uint8ClampedArray;\n    }\n  | undefined;\n\nconst getClarityScratch = (length: number) => {\n  if (!clarityScratch || clarityScratch.length < length) {\n    clarityScratch = {\n      length,\n      source: new Uint8ClampedArray(length),\n      temp: new Uint8ClampedArray(length),\n    };\n  }\n  return clarityScratch;\n};\n\nconst buildScurveLookup = (\n  strength: number,\n  shadowBoost: number,\n  highlightBoost: number,\n  midpoint: number\n) => {\n  const mid = clamp(midpoint, 0.01, 0.99);\n  const shadowExponent = clamp(\n    1 - strength * shadowBoost * SHADOW_TONE_RESPONSE,\n    0.15,\n    3\n  );\n  const highlightExponent = clamp(1 - strength * highlightBoost, 0.15, 3);\n  const lookup = new Uint8ClampedArray(256);\n\n  for (let value = 0; value < lookup.length; value += 1) {\n    const normalized = value / 255;\n    let result: number;\n\n    if (normalized <= mid) {\n      const shadowValue = normalized / mid;\n      result = Math.pow(shadowValue, shadowExponent) * mid;\n    } else {\n      const highlightValue = (normalized - mid) / (1 - mid);\n      result =\n        mid + Math.pow(highlightValue, highlightExponent) * (1 - mid);\n    }\n\n    lookup[value] = clampByte(result * 255);\n  }\n\n  return lookup;\n};\n\nconst LIGHTNESS_HISTOGRAM_SCALE = 100;\nconst LIGHTNESS_HISTOGRAM_BINS = 100 * LIGHTNESS_HISTOGRAM_SCALE + 1;\n\nconst percentileFromHistogram = (\n  histogram: Uint32Array,\n  count: number,\n  p: number\n) => {\n  if (count <= 0) return 0;\n\n  const target = clamp(Math.round((count - 1) * p), 0, count - 1);\n  let seen = 0;\n\n  for (let index = 0; index < histogram.length; index += 1) {\n    seen += histogram[index];\n    if (seen > target) return index / LIGHTNESS_HISTOGRAM_SCALE;\n  }\n\n  return 100;\n};\n\nconst BYTE_HISTOGRAM_BINS = 256;\n\nconst percentileFromByteHistogram = (\n  histogram: Uint32Array,\n  count: number,\n  p: number\n) => {\n  if (count <= 0) return 0;\n\n  const target = clamp(Math.round((count - 1) * p), 0, count - 1);\n  let seen = 0;\n\n  for (let index = 0; index < histogram.length; index += 1) {\n    seen += histogram[index];\n    if (seen > target) return index;\n  }\n\n  return 255;\n};\n\nconst CHROMA_GUARD_STEPS = 5;\n\nconst isProtectedChromaFit = (\n  sourceLuma: number,\n  resultR: number,\n  resultG: number,\n  resultB: number,\n  sourceSaturation: number\n) => {\n  if (sourceSaturation < 0.16) return true;\n\n  const resultSaturation = getSaturation(resultR, resultG, resultB);\n  const minimumSaturation = Math.max(0.12, sourceSaturation * 0.72);\n  if (resultSaturation >= minimumSaturation) return true;\n\n  return luma709(resultR, resultG, resultB) <= sourceLuma + 4;\n};\n\nconst labToRgbWithChromaGuard = (\n  sourceR: number,\n  sourceG: number,\n  sourceB: number,\n  sourceL: number,\n  a: number,\n  b: number,\n  targetL: number,\n  amount: number\n) => {\n  const sourceSaturation = getSaturation(sourceR, sourceG, sourceB);\n  const sourceLuma = luma709(sourceR, sourceG, sourceB);\n  const toRgb = (fitAmount: number) =>\n    labToRgb(sourceL + (targetL - sourceL) * fitAmount, a, b);\n  const result = toRgb(amount);\n\n  if (\n    targetL <= sourceL ||\n    isProtectedChromaFit(\n      sourceLuma,\n      result[0],\n      result[1],\n      result[2],\n      sourceSaturation\n    )\n  ) {\n    return result;\n  }\n\n  let low = 0;\n  let high = amount;\n  let protectedResult: RGB = [sourceR, sourceG, sourceB];\n\n  for (let step = 0; step < CHROMA_GUARD_STEPS; step += 1) {\n    const mid = (low + high) / 2;\n    const candidate = toRgb(mid);\n\n    if (\n      isProtectedChromaFit(\n        sourceLuma,\n        candidate[0],\n        candidate[1],\n        candidate[2],\n        sourceSaturation\n      )\n    ) {\n      low = mid;\n      protectedResult = candidate;\n    } else {\n      high = mid;\n    }\n  }\n\n  return protectedResult;\n};\n\nconst getPaletteEndpoints = (\n  palette: RGB[] | undefined,\n  black: LevelRGB | undefined,\n  white: LevelRGB | undefined\n) => {\n  if (black !== undefined && white !== undefined) {\n    return {\n      black: toRGB(black, 0),\n      white: toRGB(white, 255),\n    };\n  }\n\n  if (!palette || palette.length === 0) {\n    return {\n      black: toRGB(black, 0),\n      white: toRGB(white, 255),\n    };\n  }\n\n  let darkest = palette[0];\n  let lightest = palette[0];\n  for (const color of palette) {\n    if (luma709(...color) < luma709(...darkest)) darkest = color;\n    if (luma709(...color) > luma709(...lightest)) lightest = color;\n  }\n\n  return {\n    black: black !== undefined ? toRGB(black, 0) : darkest,\n    white: white !== undefined ? toRGB(white, 255) : lightest,\n  };\n};\n\nconst normalizeDynamicRangeOptions = (\n  options: DynamicRangeCompressionOptions | boolean | undefined\n): DynamicRangeCompressionOptions | undefined => {\n  if (options === true) return { mode: \"display\", strength: 1 };\n  if (!options || options.mode === \"off\") return undefined;\n  return options;\n};\n\nconst applyDynamicRangeCompression = (\n  image: ImageDataLike,\n  options: DynamicRangeCompressionOptions | boolean | undefined,\n  palette: RGB[] | undefined\n) => {\n  const normalized = normalizeDynamicRangeOptions(options);\n  if (!normalized) return;\n\n  const mode = normalized.mode ?? \"display\";\n  const strength = clamp(normalized.strength ?? 1, 0, 1);\n  if (strength === 0) return;\n\n  if (normalized.quality === \"fast\") {\n    applyFastDynamicRangeCompression(image, normalized, palette);\n    return;\n  }\n\n  const { black, white } = getPaletteEndpoints(\n    palette,\n    normalized.black,\n    normalized.white\n  );\n  const [blackL] = rgbToLab(...black);\n  const [whiteL] = rgbToLab(...white);\n  const targetRange = whiteL - blackL;\n  if (targetRange <= 0) return;\n\n  const data = image.data;\n  let sourceBlackL = 0;\n  let sourceWhiteL = 100;\n\n  if (mode === \"auto\") {\n    const lightnessHistogram = new Uint32Array(LIGHTNESS_HISTOGRAM_BINS);\n    let lightnessCount = 0;\n\n    for (let i = 0; i < data.length; i += 4) {\n      const l = rgbToLabLightness(data[i], data[i + 1], data[i + 2]);\n      const bin = clamp(\n        Math.round(l * LIGHTNESS_HISTOGRAM_SCALE),\n        0,\n        LIGHTNESS_HISTOGRAM_BINS - 1\n      );\n      lightnessHistogram[bin] += 1;\n      lightnessCount += 1;\n    }\n    sourceBlackL = percentileFromHistogram(\n      lightnessHistogram,\n      lightnessCount,\n      normalized.lowPercentile ?? 0.01\n    );\n    sourceWhiteL = percentileFromHistogram(\n      lightnessHistogram,\n      lightnessCount,\n      normalized.highPercentile ?? 0.99\n    );\n  }\n\n  const sourceRange = sourceWhiteL - sourceBlackL;\n  if (sourceRange <= 0.0001) return;\n\n  for (let i = 0; i < data.length; i += 4) {\n    const r = data[i];\n    const g = data[i + 1];\n    const blue = data[i + 2];\n    const [l, a, b] = rgbToLab(r, g, blue);\n    const normalizedL = clamp((l - sourceBlackL) / sourceRange, 0, 1);\n    const compressedL = blackL + normalizedL * targetRange;\n    const chromaProtection = getDynamicRangeChromaProtection(r, g, blue);\n    const effectiveStrength = strength * (1 - chromaProtection);\n    const [newR, newG, newBlue] = labToRgbWithChromaGuard(\n      r,\n      g,\n      blue,\n      l,\n      a,\n      b,\n      compressedL,\n      effectiveStrength\n    );\n\n    data[i] = newR;\n    data[i + 1] = newG;\n    data[i + 2] = newBlue;\n  }\n};\n\nconst applyFastDynamicRangeCompression = (\n  image: ImageDataLike,\n  options: DynamicRangeCompressionOptions,\n  palette: RGB[] | undefined\n) => {\n  const mode = options.mode ?? \"display\";\n  const strength = clamp(options.strength ?? 1, 0, 1);\n  if (strength === 0) return;\n\n  const { black, white } = getPaletteEndpoints(\n    palette,\n    options.black,\n    options.white\n  );\n  const blackY = luma709(...black);\n  const whiteY = luma709(...white);\n  const targetRange = whiteY - blackY;\n  if (targetRange <= 0) return;\n\n  const data = image.data;\n  let sourceBlackY = 0;\n  let sourceWhiteY = 255;\n\n  if (mode === \"auto\") {\n    const histogram = new Uint32Array(BYTE_HISTOGRAM_BINS);\n    let count = 0;\n    for (let i = 0; i < data.length; i += 4) {\n      histogram[clampByte(luma709(data[i], data[i + 1], data[i + 2]))] += 1;\n      count += 1;\n    }\n    sourceBlackY = percentileFromByteHistogram(\n      histogram,\n      count,\n      options.lowPercentile ?? 0.01\n    );\n    sourceWhiteY = percentileFromByteHistogram(\n      histogram,\n      count,\n      options.highPercentile ?? 0.99\n    );\n  }\n\n  const sourceRange = sourceWhiteY - sourceBlackY;\n  if (sourceRange <= 0.0001) return;\n\n  for (let i = 0; i < data.length; i += 4) {\n    const r = data[i];\n    const g = data[i + 1];\n    const b = data[i + 2];\n    const y = luma709(r, g, b);\n    const normalizedY = clamp((y - sourceBlackY) / sourceRange, 0, 1);\n    const targetY = blackY + normalizedY * targetRange;\n    const chromaProtection = getDynamicRangeChromaProtection(r, g, b);\n    const effectiveStrength = strength * (1 - chromaProtection);\n    const nextY = y + (targetY - y) * effectiveStrength;\n    let ratio = y > 0 ? nextY / y : 0;\n    const maxChannel = Math.max(r, g, b);\n    if (maxChannel > 0) ratio = Math.min(ratio, 255 / maxChannel);\n\n    data[i] = clampByte(r * ratio);\n    data[i + 1] = clampByte(g * ratio);\n    data[i + 2] = clampByte(b * ratio);\n  }\n};\n\nconst shouldEnableLevelCompression = (\n  image: ImageDataLike,\n  mode: Exclude<LevelCompressionMode, \"off\">,\n  black: LevelRGB | undefined,\n  white: LevelRGB | undefined,\n  autoThreshold: number\n) => {\n  const data = image.data;\n  const pixelCount = Math.floor(data.length / 4);\n  if (pixelCount <= 0) return false;\n\n  let outOfRange = 0;\n  if (mode === \"perChannel\") {\n    const b = toRGB(black, 0);\n    const w = toRGB(white, 255);\n    const bR = b[0];\n    const bG = b[1];\n    const bB = b[2];\n    const wR = w[0];\n    const wG = w[1];\n    const wB = w[2];\n\n    for (let i = 0; i < data.length; i += 4) {\n      const r = data[i];\n      const g = data[i + 1];\n      const bch = data[i + 2];\n      if (r < bR || r > wR || g < bG || g > wG || bch < bB || bch > wB) {\n        outOfRange += 1;\n      }\n    }\n  } else {\n    const b = toScalar(black, 0);\n    const w = toScalar(white, 255);\n    for (let i = 0; i < data.length; i += 4) {\n      const y = luma709(data[i], data[i + 1], data[i + 2]);\n      if (y < b || y > w) outOfRange += 1;\n    }\n  }\n\n  return outOfRange / pixelCount >= autoThreshold;\n};\n\nconst shouldApplyLevelCompression = (\n  image: ImageDataLike,\n  options: LevelCompressionOptions | undefined\n) => {\n  if (!options) return false;\n  const mode: LevelCompressionMode = options.mode ?? \"perChannel\";\n  if (mode === \"off\") return false;\n\n  if (options.auto === true) {\n    const autoThreshold =\n      typeof options.autoThreshold === \"number\" ? options.autoThreshold : 0.01;\n    return shouldEnableLevelCompression(\n      image,\n      mode,\n      options.black,\n      options.white,\n      autoThreshold\n    );\n  }\n\n  return true;\n};\n\nconst applyLevelCompression = (\n  image: ImageDataLike,\n  options: LevelCompressionOptions | undefined\n) => {\n  if (!shouldApplyLevelCompression(image, options) || !options) return;\n\n  const mode: LevelCompressionMode = options.mode ?? \"perChannel\";\n  const data = image.data;\n  if (mode === \"perChannel\") {\n    const black = toRGB(options.black, 0);\n    const white = toRGB(options.white, 255);\n\n    const bR = black[0];\n    const bG = black[1];\n    const bB = black[2];\n    const wR = white[0];\n    const wG = white[1];\n    const wB = white[2];\n\n    const dR = wR - bR;\n    const dG = wG - bG;\n    const dB = wB - bB;\n    if (dR <= 0 || dG <= 0 || dB <= 0) return;\n\n    for (let i = 0; i < data.length; i += 4) {\n      data[i] = clampByte(bR + (data[i] * dR) / 255);\n      data[i + 1] = clampByte(bG + (data[i + 1] * dG) / 255);\n      data[i + 2] = clampByte(bB + (data[i + 2] * dB) / 255);\n    }\n    return;\n  }\n\n  const blackL = toScalar(options.black, 0);\n  const whiteL = toScalar(options.white, 255);\n  const dL = whiteL - blackL;\n  if (dL <= 0) return;\n\n  for (let i = 0; i < data.length; i += 4) {\n    const r = data[i];\n    const g = data[i + 1];\n    const b = data[i + 2];\n    const y = luma709(r, g, b);\n    const yNew = blackL + (y * dL) / 255;\n    let ratio = y > 0 ? yNew / y : 0;\n    const maxChannel = Math.max(r, g, b);\n    if (maxChannel > 0) ratio = Math.min(ratio, 255 / maxChannel);\n\n    data[i] = clampByte(r * ratio);\n    data[i + 1] = clampByte(g * ratio);\n    data[i + 2] = clampByte(b * ratio);\n  }\n};\n\nexport const applyToneMapping = (\n  image: ImageDataLike,\n  options: ToneMappingOptions | undefined,\n  levelCompression?: LevelCompressionOptions\n) => {\n  if (!options && !levelCompression) return;\n\n  let applyLevel =\n    levelCompression &&\n    shouldApplyLevelCompression(image, levelCompression) &&\n    levelCompression.auto !== true &&\n    (levelCompression.mode ?? \"perChannel\") === \"perChannel\";\n  const exposure = exposureAdjustmentToMultiplier(options?.exposure ?? 0);\n  const saturation = linearAdjustmentToMultiplier(options?.saturation ?? 0);\n  const contrast = contrastAdjustmentToMultiplier(options?.contrast ?? 0);\n  const mode = options?.mode;\n  const exposureLookup = new Uint8ClampedArray(256);\n  const toneLookup = new Uint8ClampedArray(256);\n  const levelLookupR = new Uint8ClampedArray(256);\n  const levelLookupG = new Uint8ClampedArray(256);\n  const levelLookupB = new Uint8ClampedArray(256);\n  const scurveLookup =\n    (!mode || mode === \"scurve\") &&\n    (options?.strength ?? (mode === \"scurve\" ? 0.9 : 0)) !== 0\n      ? buildScurveLookup(\n          options?.strength ?? (mode === \"scurve\" ? 0.9 : 0),\n          options?.shadowBoost ?? 0,\n          options?.highlightCompress ?? -1.5,\n          options?.midpoint ?? 0.5\n        )\n      : undefined;\n\n  for (let value = 0; value < 256; value += 1) {\n    exposureLookup[value] = clampByte(value * exposure);\n    let toneValue = value;\n    if (mode !== \"off\") {\n      if (!mode || mode === \"contrast\") {\n        toneValue = clampByte((toneValue - 128) * contrast + 128);\n      }\n      if (scurveLookup) {\n        toneValue = scurveLookup[toneValue];\n      }\n    }\n    toneLookup[value] = toneValue;\n  }\n\n  if (applyLevel && levelCompression) {\n    const black = toRGB(levelCompression.black, 0);\n    const white = toRGB(levelCompression.white, 255);\n    const ranges = [\n      white[0] - black[0],\n      white[1] - black[1],\n      white[2] - black[2],\n    ];\n    if (ranges[0] <= 0 || ranges[1] <= 0 || ranges[2] <= 0) {\n      applyLevel = false;\n    }\n\n    for (let value = 0; value < 256; value += 1) {\n      levelLookupR[value] = clampByte(black[0] + (value * ranges[0]) / 255);\n      levelLookupG[value] = clampByte(black[1] + (value * ranges[1]) / 255);\n      levelLookupB[value] = clampByte(black[2] + (value * ranges[2]) / 255);\n    }\n  }\n\n  const data = image.data;\n  for (let i = 0; i < data.length; i += 4) {\n    if (saturation === 1) {\n      const r = toneLookup[exposureLookup[data[i]]];\n      const g = toneLookup[exposureLookup[data[i + 1]]];\n      const b = toneLookup[exposureLookup[data[i + 2]]];\n      data[i] = applyLevel ? levelLookupR[r] : r;\n      data[i + 1] = applyLevel ? levelLookupG[g] : g;\n      data[i + 2] = applyLevel ? levelLookupB[b] : b;\n      continue;\n    }\n\n    const r0 = exposureLookup[data[i]] / 255;\n    const g0 = exposureLookup[data[i + 1]] / 255;\n    const b0 = exposureLookup[data[i + 2]] / 255;\n\n    const max = Math.max(r0, g0, b0);\n    const min = Math.min(r0, g0, b0);\n    const lightness = (max + min) / 2;\n    let r = r0;\n    let g = g0;\n    let b = b0;\n\n    if (max !== min) {\n      const delta = max - min;\n      const sat =\n        lightness > 0.5\n          ? delta / (2 - max - min)\n          : delta / Math.max(max + min, 0.000001);\n      let hue: number;\n      if (max === r0) {\n        hue = ((g0 - b0) / delta + (g0 < b0 ? 6 : 0)) / 6;\n      } else if (max === g0) {\n        hue = ((b0 - r0) / delta + 2) / 6;\n      } else {\n        hue = ((r0 - g0) / delta + 4) / 6;\n      }\n\n      const newSat = clamp(sat * saturation, 0, 1);\n      const c = (1 - Math.abs(2 * lightness - 1)) * newSat;\n      const x = c * (1 - Math.abs(((hue * 6) % 2) - 1));\n      const m = lightness - c / 2;\n      const sector = Math.floor(hue * 6);\n\n      if (sector === 0) [r, g, b] = [c + m, x + m, m];\n      else if (sector === 1) [r, g, b] = [x + m, c + m, m];\n      else if (sector === 2) [r, g, b] = [m, c + m, x + m];\n      else if (sector === 3) [r, g, b] = [m, x + m, c + m];\n      else if (sector === 4) [r, g, b] = [x + m, m, c + m];\n      else [r, g, b] = [c + m, m, x + m];\n    }\n\n    const nextR = toneLookup[clampByte(r * 255)];\n    const nextG = toneLookup[clampByte(g * 255)];\n    const nextB = toneLookup[clampByte(b * 255)];\n    data[i] = applyLevel ? levelLookupR[nextR] : nextR;\n    data[i + 1] = applyLevel ? levelLookupG[nextG] : nextG;\n    data[i + 2] = applyLevel ? levelLookupB[nextB] : nextB;\n  }\n\n  if (levelCompression && !applyLevel) {\n    applyLevelCompression(image, levelCompression);\n  }\n};\n\nexport const applyImageProcessing = (\n  image: ImageDataLike,\n  options: ImageProcessingOptions | undefined,\n  palette?: RGB[]\n) => {\n  if (!options) return;\n  applyPaperNormalization(image, options.paperNormalization);\n  applyClarity(image, options.clarity, options.previewMode);\n  const canFuseLevel =\n    !normalizeDynamicRangeOptions(options.dynamicRangeCompression) &&\n    options.levelCompression?.auto !== true;\n  applyToneMapping(\n    image,\n    options.toneMapping,\n    canFuseLevel ? options.levelCompression : undefined\n  );\n  applyDynamicRangeCompression(\n    image,\n    options.dynamicRangeCompression,\n    palette\n  );\n  if (!canFuseLevel) {\n    applyLevelCompression(image, options.levelCompression);\n  }\n};\n","import {\n  deltaE,\n  rgbToLab,\n  type ColorMatchingMode,\n  type RGB,\n  type RGBA,\n} from \"../processing\";\n\nconst withAlpha = (color: RGB | RGBA): RGBA => [\n  color[0],\n  color[1],\n  color[2],\n  (color as RGBA)[3] ?? 255,\n];\n\nconst findClosestPaletteColor = (\n  pixel: RGB | RGBA,\n  colorPalette: RGB[],\n  colorMatching: ColorMatchingMode = \"rgb\",\n  sourcePixel: RGB | RGBA = pixel\n): RGBA => {\n  if (!colorPalette.length) return withAlpha(pixel);\n  const pixelLab =\n    colorMatching === \"lab\" ? rgbToLab(pixel[0], pixel[1], pixel[2]) : null;\n  const sourceSaturation =\n    colorMatching === \"chroma\" ? getSaturation(sourcePixel) : 0;\n  const sourceHue =\n    colorMatching === \"chroma\" && sourceSaturation >= 0.12\n      ? getHue(sourcePixel)\n      : null;\n\n  const colors = colorPalette.map((color) => {\n    const paletteSaturation = getSaturation(color);\n    return {\n      distance:\n        colorMatching === \"lab\" && pixelLab\n          ? deltaE(rgbToLab(...color), pixelLab)\n          : distanceInColorSpace(color, pixel) +\n            getChromaPenalty(\n              sourceSaturation,\n              paletteSaturation,\n              colorMatching\n            ) +\n            getHuePenalty(sourceHue, color, paletteSaturation, colorMatching),\n      color,\n    };\n  });\n\n  let closestColor: { distance: number; color: RGB };\n  colors.forEach((color) => {\n    if (!closestColor) {\n      closestColor = color;\n    } else {\n      if (color.distance < closestColor.distance) {\n        closestColor = color;\n      }\n    }\n  });\n\n  return withAlpha(closestColor.color);\n};\n\nconst getChromaPenalty = (\n  pixelSaturation: number,\n  paletteSaturation: number,\n  colorMatching: ColorMatchingMode\n) => {\n  if (colorMatching !== \"chroma\") return 0;\n  if (pixelSaturation < 0.12 || paletteSaturation > 0.12) return 0;\n\n  return Math.min(330, pixelSaturation * 1300);\n};\n\nconst getHuePenalty = (\n  sourceHue: number | null,\n  color: RGB,\n  paletteSaturation: number,\n  colorMatching: ColorMatchingMode\n) => {\n  if (colorMatching !== \"chroma\" || sourceHue === null) return 0;\n  if (paletteSaturation <= 0.12) return 0;\n\n  return getHueDistance(sourceHue, getHue(color)) * 3;\n};\n\nconst getSaturation = (color: RGB | RGBA) => {\n  const max = Math.max(color[0], color[1], color[2]) / 255;\n  const min = Math.min(color[0], color[1], color[2]) / 255;\n\n  return max === 0 ? 0 : (max - min) / max;\n};\n\nconst getHue = (color: RGB | RGBA) => {\n  const red = color[0] / 255;\n  const green = color[1] / 255;\n  const blue = color[2] / 255;\n  const max = Math.max(red, green, blue);\n  const min = Math.min(red, green, blue);\n  const delta = max - min;\n\n  if (delta === 0) return 0;\n\n  let hue: number;\n  if (max === red) {\n    hue = 60 * (((green - blue) / delta) % 6);\n  } else if (max === green) {\n    hue = 60 * ((blue - red) / delta + 2);\n  } else {\n    hue = 60 * ((red - green) / delta + 4);\n  }\n\n  return hue < 0 ? hue + 360 : hue;\n};\n\nconst getHueDistance = (hueA: number, hueB: number) => {\n  const delta = Math.abs(hueA - hueB) % 360;\n  return Math.min(delta, 360 - delta);\n};\n\nconst distanceInColorSpace = (color1: RGB, color2: RGB | RGBA) => {\n  // Currenlty ignores alpha\n\n  // Luminosity needs to be accounted for, for better results.\n  // var lumR = .2126,\n  //     lumG = .7152,\n  //     lumB = .0722\n\n  // const max = 255\n\n  // const averageMax = Math.sqrt(lumR * max * max + lumG * max * max + lumB * max * max) // I Dont understand this\n\n  const r = color1[0] - color2[0];\n  const g = color1[1] - color2[1];\n  const b = color1[2] - color2[2];\n\n  const distance = Math.sqrt(r * r + g * g + b * b);\n  return distance;\n};\n\nexport default findClosestPaletteColor;\n","import type { ImageDataLike, RGB } from \"./processing\";\n\ninterface DiffusionEntry {\n  offset: number[];\n  factor: number;\n}\n\ninterface WasmExports {\n  memory: WebAssembly.Memory;\n  ditherRgbErrorDiffusion: (\n    dataPtr: number,\n    palettePtr: number,\n    paletteLength: number,\n    width: number,\n    height: number,\n    matrixPtr: number,\n    matrixLength: number,\n    serpentine: number\n  ) => void;\n}\n\nconst WASM_BASE64 =\n  \"AGFzbQEAAAABDAFgCH9/f39/f39/AAMCAQAFAwEAAAckAhdkaXRoZXJSZ2JFcnJvckRpZmZ1c2lvbgAABm1lbW9yeQIACtAFAc0FAgx/BnwgAkEATARADwsDQCAEIA1KBEAgB0EARyIJBEAgDUEBcSEJC0F/IAMgCRshEkF/QQEgCRshEyADQQFrQQAgCRshDgNAIA4gEkcEQCADIA1sIA5qQQJ0IABqIgwtAAAhDyAMLQABIRAgDC0AAiERQQAhCET////////vfyEVQQAhCwNAIAIgC0oEQCABIAtBA2xqIgotAAC4IA+4oSIUIBSiIAotAAG4IBC4oSIUIBSioCAKLQACuCARuKEiFCAUoqCfIhQgFWMEQCAUIRUgCyEICyALQQFqIQsMAQsLIAEgCEEDbGoiCC0AACELIAgtAAEhCiAILQACIQggDCALOgAAIAwgCjoAASAMIAg6AAIgDEH/AToAAyAPuCALuKEhGCAQuCAKuKEhFiARuCAIuKEhF0EAIQgDQCAGIAhKBEAgBSAIQRhsaiIMKwMA/AIhCiAMKwMQIRlBACAKayAKIAkbIA5qIgtBAEggAyALTHIgDCsDCPwCIA1qIgpBAEhyIAQgCkxyRQRAIAAgAyAKbCALakECdGoiCi0AALggGCAZoqAhFSAKAn9BACAVRAAAAAAAAAAAYw0AGkH/ASAVRAAAAAAA4G9AZA0AGiAVmyIUIBREAAAAAAAA8L+gIBREAAAAAAAA4L+gIBVlG/wDCzoAACAKAn9BACAKLQABuCAWIBmioCIVRAAAAAAAAAAAYw0AGkH/ASAVRAAAAAAA4G9AZA0AGiAVmyIUIBREAAAAAAAA8L+gIBREAAAAAAAA4L+gIBVlG/wDCzoAASAKAn9BACAKLQACuCAXIBmioCIVRAAAAAAAAAAAYw0AGkH/ASAVRAAAAAAA4G9AZA0AGiAVmyIUIBREAAAAAAAA8L+gIBREAAAAAAAA4L+gIBVlG/wDCzoAAgsgCEEBaiEIDAELCyAOIBNqIQ4MAQsLIA1BAWohDQwBCwsL\";\n\nlet exportsPromise: Promise<WasmExports | null> | null = null;\n\nconst align = (value: number, boundary: number) =>\n  Math.ceil(value / boundary) * boundary;\n\nconst decodeBase64 = (base64: string) => {\n  if (typeof atob === \"function\") {\n    const binary = atob(base64);\n    const bytes = new Uint8Array(binary.length);\n    for (let index = 0; index < binary.length; index += 1) {\n      bytes[index] = binary.charCodeAt(index);\n    }\n    return bytes;\n  }\n\n  const bufferCtor = (\n    globalThis as unknown as {\n      Buffer?: { from(value: string, encoding: string): Uint8Array };\n    }\n  ).Buffer;\n  if (bufferCtor) return new Uint8Array(bufferCtor.from(base64, \"base64\"));\n\n  throw new Error(\"No base64 decoder is available for the WASM module.\");\n};\n\nconst getWasmExports = async (): Promise<WasmExports | null> => {\n  if (typeof WebAssembly === \"undefined\") return null;\n  if (!exportsPromise) {\n    exportsPromise = WebAssembly.instantiate(decodeBase64(WASM_BASE64), {})\n      .then((result) => result.instance.exports as unknown as WasmExports)\n      .catch(() => null);\n  }\n  return exportsPromise;\n};\n\nconst ensureMemory = (memory: WebAssembly.Memory, byteLength: number) => {\n  const requiredPages = Math.ceil(byteLength / 65536);\n  const currentPages = memory.buffer.byteLength / 65536;\n  if (requiredPages > currentPages) memory.grow(requiredPages - currentPages);\n};\n\nexport const applyWasmRgbErrorDiffusion = async (\n  image: ImageDataLike,\n  colorPalette: RGB[],\n  diffusionMap: DiffusionEntry[],\n  serpentine: boolean\n) => {\n  if (!colorPalette.length) return false;\n\n  const wasmExports = await getWasmExports();\n  if (!wasmExports) return false;\n\n  const { memory, ditherRgbErrorDiffusion } = wasmExports;\n  const dataByteLength = image.data.byteLength;\n  const paletteByteLength = colorPalette.length * 3;\n  const matrixByteLength = diffusionMap.length * 24;\n  const dataPtr = 0;\n  const palettePtr = align(dataPtr + dataByteLength, 8);\n  const matrixPtr = align(palettePtr + paletteByteLength, 8);\n  const totalBytes = matrixPtr + matrixByteLength;\n\n  ensureMemory(memory, totalBytes);\n\n  const bytes = new Uint8Array(memory.buffer);\n  bytes.set(image.data, dataPtr);\n\n  let paletteIndex = palettePtr;\n  for (const color of colorPalette) {\n    bytes[paletteIndex] = color[0];\n    bytes[paletteIndex + 1] = color[1];\n    bytes[paletteIndex + 2] = color[2];\n    paletteIndex += 3;\n  }\n\n  const floats = new Float64Array(memory.buffer);\n  let matrixIndex = matrixPtr / 8;\n  for (const diffusion of diffusionMap) {\n    floats[matrixIndex] = diffusion.offset[0];\n    floats[matrixIndex + 1] = diffusion.offset[1];\n    floats[matrixIndex + 2] = diffusion.factor;\n    matrixIndex += 3;\n  }\n\n  ditherRgbErrorDiffusion(\n    dataPtr,\n    palettePtr,\n    colorPalette.length,\n    image.width,\n    image.height,\n    matrixPtr,\n    diffusionMap.length,\n    serpentine ? 1 : 0\n  );\n\n  image.data.set(bytes.subarray(dataPtr, dataPtr + dataByteLength));\n  return true;\n};\n","// Auto-generated by scripts/generate-blue-noise.js — do not edit manually\n// 64×64 tileable blue noise threshold map (void-and-cluster, Ulichney 1993)\n// Values are uint8 in [0, 255]. Lower value = turns on first (most isolated position).\nexport const BLUE_NOISE_TEXTURE: Uint8Array = new Uint8Array([\n  255, 32, 123, 252, 40, 227, 207, 47, 193, 157, 211, 106, 227, 44, 253, 68, 145, 9, 168, 132, 191, 56, 175, 151, 235, 61, 185, 137, 221, 53, 127, 158, 4, 70, 188, 126, 152, 85, 46, 123, 213, 62, 110, 42, 83, 122, 30, 66, 115, 226, 131, 206, 18, 178, 127, 53, 187, 150, 63, 183, 84, 144, 56, 113,\n  167, 208, 149, 184, 105, 152, 66, 117, 79, 126, 34, 139, 75, 171, 208, 120, 187, 20, 78, 40, 18, 4, 104, 36, 255, 114, 247, 167, 100, 243, 190, 84, 25, 22, 99, 230, 67, 180, 200, 22, 99, 167, 251, 184, 231, 150, 250, 209, 87, 178, 53, 77, 160, 63, 5, 213, 82, 134, 245, 209, 119, 3, 200, 78,\n  48, 235, 82, 56, 7, 238, 179, 220, 3, 236, 185, 254, 242, 150, 102, 230, 50, 95, 206, 223, 146, 85, 220, 204, 164, 83, 42, 202, 70, 152, 214, 49, 172, 121, 27, 195, 246, 107, 137, 0, 77, 144, 207, 130, 69, 196, 102, 167, 137, 248, 196, 237, 117, 221, 146, 34, 114, 173, 45, 103, 236, 36, 152, 224,\n  134, 108, 250, 202, 129, 87, 31, 138, 104, 50, 162, 92, 57, 196, 36, 0, 160, 129, 178, 111, 67, 185, 127, 59, 139, 189, 227, 130, 5, 32, 113, 140, 12, 65, 217, 135, 52, 226, 36, 172, 53, 233, 34, 93, 242, 44, 7, 56, 215, 35, 96, 142, 42, 188, 97, 247, 198, 9, 219, 71, 165, 193, 95, 252,\n  67, 192, 155, 42, 171, 211, 19, 164, 198, 72, 222, 119, 210, 133, 85, 181, 63, 15, 26, 21, 156, 44, 243, 231, 96, 249, 56, 104, 18, 163, 231, 96, 20, 153, 87, 171, 15, 159, 94, 217, 17, 188, 112, 215, 147, 173, 118, 16, 76, 156, 3, 175, 243, 79, 228, 159, 59, 91, 149, 128, 254, 55, 124, 176,\n  30, 241, 89, 226, 73, 120, 55, 94, 14, 149, 239, 29, 167, 24, 19, 117, 220, 142, 76, 25, 9, 203, 114, 172, 29, 207, 155, 179, 86, 193, 59, 202, 42, 210, 4, 110, 72, 204, 117, 60, 128, 83, 161, 249, 64, 226, 88, 189, 127, 223, 107, 67, 205, 113, 50, 132, 238, 184, 30, 228, 206, 84, 239, 214,\n  5, 168, 115, 145, 238, 184, 6, 217, 41, 124, 188, 106, 6, 76, 47, 198, 94, 166, 190, 101, 137, 88, 64, 149, 4, 76, 123, 215, 38, 237, 132, 171, 78, 122, 182, 35, 20, 139, 8, 185, 149, 12, 49, 194, 133, 31, 251, 159, 46, 244, 198, 29, 136, 12, 170, 209, 74, 117, 249, 102, 174, 42, 152, 105,\n  136, 208, 56, 253, 34, 97, 155, 67, 175, 250, 83, 53, 142, 16, 155, 230, 39, 7, 55, 23, 35, 178, 18, 195, 102, 236, 50, 10, 144, 71, 108, 218, 245, 144, 62, 223, 193, 46, 82, 238, 28, 205, 101, 222, 79, 178, 109, 205, 65, 142, 87, 164, 19, 24, 99, 38, 1, 161, 197, 67, 142, 10, 190, 71,\n  47, 181, 83, 162, 213, 129, 251, 203, 103, 137, 210, 233, 194, 114, 64, 177, 133, 108, 18, 154, 209, 128, 24, 41, 132, 162, 184, 111, 19, 160, 13, 26, 189, 99, 236, 155, 102, 170, 209, 108, 164, 71, 21, 120, 155, 243, 228, 95, 255, 175, 235, 115, 58, 82, 192, 146, 221, 89, 45, 244, 121, 90, 222, 245,\n  126, 13, 236, 109, 189, 47, 80, 145, 32, 245, 65, 159, 38, 220, 91, 250, 212, 74, 184, 117, 82, 58, 13, 86, 217, 67, 230, 81, 203, 54, 23, 86, 157, 47, 254, 76, 131, 253, 58, 225, 130, 181, 0, 40, 189, 56, 141, 37, 123, 212, 44, 195, 8, 217, 121, 54, 15, 130, 208, 177, 231, 34, 162, 100,\n  218, 37, 141, 62, 224, 245, 173, 235, 216, 186, 122, 96, 252, 183, 127, 30, 146, 240, 42, 226, 3, 167, 113, 147, 190, 251, 32, 140, 98, 176, 129, 0, 208, 126, 178, 215, 32, 234, 152, 89, 249, 52, 145, 93, 16, 75, 197, 169, 246, 69, 100, 138, 156, 35, 169, 184, 75, 157, 105, 59, 148, 202, 64, 185,\n  81, 168, 202, 91, 153, 122, 58, 111, 89, 50, 1, 174, 136, 78, 243, 202, 103, 173, 65, 134, 193, 28, 205, 240, 49, 120, 173, 212, 237, 41, 197, 72, 111, 247, 59, 96, 196, 113, 184, 38, 201, 114, 219, 167, 209, 126, 6, 87, 151, 232, 182, 248, 79, 234, 102, 19, 25, 26, 24, 12, 87, 241, 113, 2,\n  55, 108, 12, 21, 26, 4, 210, 163, 17, 148, 70, 223, 43, 230, 58, 161, 7, 85, 211, 157, 91, 234, 103, 70, 160, 92, 6, 73, 157, 107, 225, 148, 34, 229, 160, 139, 250, 72, 255, 140, 230, 80, 243, 30, 107, 235, 45, 206, 112, 29, 216, 52, 127, 203, 67, 135, 8, 116, 22, 185, 49, 134, 224, 153,\n  244, 187, 131, 71, 181, 100, 192, 41, 130, 24, 189, 109, 205, 144, 113, 193, 48, 229, 252, 114, 55, 254, 139, 183, 248, 206, 133, 51, 15, 21, 59, 171, 193, 82, 240, 46, 219, 169, 53, 101, 162, 58, 191, 137, 68, 150, 173, 64, 11, 132, 165, 92, 5, 162, 225, 48, 91, 168, 73, 142, 100, 176, 31, 207,\n  95, 39, 216, 160, 234, 142, 64, 219, 80, 10, 27, 164, 87, 23, 15, 80, 123, 141, 33, 191, 169, 216, 43, 224, 114, 36, 233, 190, 147, 89, 124, 8, 101, 207, 118, 180, 92, 128, 237, 197, 246, 123, 10, 177, 250, 220, 99, 244, 186, 74, 16, 195, 110, 33, 186, 148, 215, 234, 40, 208, 7, 230, 74, 126,\n  150, 231, 116, 52, 87, 253, 118, 241, 173, 96, 124, 19, 62, 174, 36, 153, 220, 177, 98, 244, 66, 123, 85, 154, 64, 177, 84, 110, 215, 27, 185, 219, 49, 141, 66, 3, 26, 205, 154, 82, 35, 214, 105, 46, 86, 199, 35, 143, 116, 230, 43, 140, 237, 75, 15, 120, 60, 191, 156, 121, 57, 160, 194, 248,\n  184, 67, 5, 198, 170, 36, 202, 155, 51, 233, 209, 146, 11, 106, 204, 5, 59, 251, 75, 206, 146, 11, 199, 22, 1, 143, 246, 54, 166, 12, 138, 76, 164, 24, 25, 149, 21, 110, 51, 251, 179, 146, 72, 224, 125, 156, 236, 55, 213, 90, 174, 61, 216, 156, 95, 203, 1, 106, 83, 14, 21, 110, 91, 46,\n  18, 165, 104, 138, 226, 245, 103, 71, 136, 191, 40, 77, 186, 49, 134, 90, 190, 115, 161, 235, 39, 108, 173, 27, 100, 193, 120, 225, 203, 67, 231, 113, 20, 37, 98, 14, 80, 184, 221, 130, 93, 2, 193, 164, 17, 63, 103, 178, 5, 154, 206, 126, 254, 183, 52, 139, 28, 242, 181, 135, 35, 200, 220, 133,\n  86, 29, 215, 76, 48, 128, 181, 215, 13, 108, 162, 220, 121, 233, 249, 166, 28, 222, 51, 130, 188, 81, 16, 135, 70, 240, 41, 80, 152, 104, 44, 196, 7, 126, 175, 53, 133, 242, 70, 166, 229, 59, 113, 27, 23, 10, 194, 122, 77, 29, 244, 99, 39, 114, 250, 230, 161, 72, 219, 54, 240, 155, 60, 8,\n  227, 143, 190, 254, 159, 92, 4, 31, 85, 23, 59, 241, 87, 152, 65, 207, 127, 247, 100, 4, 210, 56, 164, 227, 213, 158, 179, 8, 131, 16, 180, 91, 148, 67, 204, 235, 163, 36, 203, 112, 43, 244, 207, 138, 94, 146, 43, 222, 236, 136, 68, 197, 225, 170, 64, 90, 211, 119, 168, 99, 187, 78, 120, 174,\n  102, 244, 55, 110, 238, 210, 66, 173, 151, 17, 133, 199, 33, 175, 108, 228, 74, 149, 179, 87, 143, 233, 118, 88, 45, 127, 92, 21, 33, 201, 157, 56, 223, 246, 86, 116, 220, 101, 150, 11, 180, 129, 79, 183, 238, 69, 172, 91, 158, 190, 15, 152, 79, 134, 243, 187, 148, 42, 255, 231, 139, 253, 208, 42,\n  196, 69, 168, 132, 38, 185, 141, 221, 118, 43, 181, 97, 216, 3, 48, 187, 240, 38, 215, 63, 18, 33, 182, 6, 201, 235, 57, 210, 112, 76, 229, 123, 189, 29, 142, 186, 48, 250, 84, 212, 65, 157, 227, 48, 214, 119, 199, 243, 54, 107, 41, 119, 10, 203, 33, 111, 224, 84, 195, 67, 31, 105, 238, 158,\n  125, 3, 222, 202, 74, 252, 103, 52, 8, 25, 71, 163, 124, 21, 145, 93, 117, 9, 161, 125, 198, 107, 156, 75, 144, 104, 186, 147, 168, 22, 43, 12, 102, 166, 2, 72, 234, 174, 136, 31, 20, 95, 246, 109, 152, 254, 33, 132, 1, 207, 176, 20, 57, 102, 167, 7, 57, 240, 127, 159, 217, 178, 57, 88,\n  18, 32, 150, 94, 235, 122, 170, 200, 95, 25, 115, 12, 56, 80, 200, 170, 54, 204, 79, 14, 49, 239, 221, 59, 12, 26, 20, 68, 2, 97, 141, 203, 60, 221, 128, 210, 113, 60, 198, 5, 119, 188, 38, 173, 61, 93, 230, 78, 165, 66, 94, 213, 157, 228, 76, 199, 140, 176, 95, 4, 116, 245, 141, 219,\n  74, 113, 175, 50, 139, 214, 34, 80, 143, 20, 26, 187, 142, 24, 35, 20, 134, 227, 102, 145, 184, 94, 133, 195, 163, 114, 212, 131, 50, 216, 180, 79, 153, 239, 89, 36, 159, 242, 100, 168, 73, 14, 133, 207, 241, 192, 140, 210, 116, 22, 136, 28, 126, 248, 46, 118, 252, 37, 213, 50, 76, 198, 39, 167,\n  191, 15, 24, 8, 65, 244, 191, 229, 162, 67, 24, 93, 213, 165, 109, 13, 67, 180, 26, 24, 72, 168, 37, 243, 82, 16, 175, 86, 242, 119, 33, 17, 112, 47, 176, 253, 202, 133, 46, 218, 146, 51, 223, 83, 117, 159, 52, 177, 40, 25, 8, 196, 82, 185, 148, 223, 81, 165, 236, 188, 152, 98, 252, 128,\n  45, 85, 105, 186, 154, 86, 112, 55, 125, 16, 174, 134, 47, 6, 83, 192, 153, 118, 199, 3, 19, 208, 119, 225, 54, 142, 39, 203, 153, 193, 234, 163, 6, 211, 145, 107, 74, 249, 88, 236, 196, 102, 165, 3, 26, 19, 101, 23, 84, 17, 63, 164, 107, 237, 66, 194, 106, 135, 62, 121, 249, 226, 63, 210,\n  136, 162, 226, 28, 128, 250, 182, 209, 0, 40, 106, 201, 72, 122, 219, 42, 248, 87, 53, 138, 105, 62, 155, 91, 181, 216, 108, 14, 64, 101, 54, 84, 132, 65, 189, 227, 51, 181, 157, 32, 125, 252, 59, 140, 197, 72, 10, 25, 153, 109, 141, 221, 43, 173, 2, 32, 244, 209, 8, 90, 29, 171, 112, 238,\n  2, 59, 201, 77, 219, 167, 44, 98, 153, 83, 220, 249, 158, 239, 147, 99, 174, 229, 161, 220, 40, 194, 11, 21, 128, 4, 74, 166, 230, 143, 218, 177, 246, 99, 28, 14, 136, 205, 108, 243, 178, 80, 214, 238, 111, 180, 133, 61, 175, 33, 200, 94, 250, 123, 143, 90, 169, 49, 154, 185, 219, 142, 83, 182,\n  98, 18, 147, 117, 238, 62, 137, 18, 230, 190, 142, 52, 182, 31, 204, 60, 243, 125, 71, 250, 176, 134, 78, 32, 163, 50, 192, 124, 29, 9, 111, 41, 198, 223, 118, 167, 91, 1, 68, 217, 48, 153, 188, 38, 86, 219, 44, 24, 121, 14, 229, 55, 189, 71, 227, 202, 116, 232, 77, 126, 242, 57, 206, 36,\n  127, 23, 47, 193, 100, 7, 203, 77, 31, 116, 68, 228, 92, 113, 251, 138, 188, 34, 210, 112, 91, 241, 214, 116, 233, 100, 246, 215, 93, 188, 239, 157, 78, 140, 19, 71, 24, 39, 149, 122, 249, 97, 129, 10, 169, 145, 13, 97, 186, 77, 150, 118, 217, 160, 39, 247, 63, 190, 253, 41, 101, 8, 152, 228,\n  178, 87, 12, 174, 35, 157, 122, 176, 11, 165, 201, 129, 4, 169, 216, 81, 107, 254, 153, 196, 49, 145, 62, 183, 203, 139, 59, 152, 172, 72, 128, 56, 215, 174, 45, 11, 126, 198, 232, 176, 72, 195, 232, 54, 119, 199, 68, 157, 23, 48, 4, 179, 86, 252, 107, 137, 166, 95, 146, 211, 164, 192, 115, 70,\n  201, 160, 62, 134, 225, 85, 246, 48, 218, 89, 241, 39, 18, 67, 45, 162, 228, 55, 78, 4, 232, 169, 251, 88, 41, 254, 83, 240, 44, 251, 199, 3, 92, 237, 111, 153, 182, 95, 57, 110, 6, 28, 158, 213, 77, 227, 32, 17, 132, 210, 109, 27, 143, 231, 51, 209, 5, 30, 229, 61, 82, 221, 48, 238,\n  27, 215, 111, 238, 198, 65, 188, 104, 143, 58, 154, 106, 188, 147, 120, 242, 194, 141, 180, 122, 29, 104, 225, 131, 156, 217, 179, 119, 225, 147, 108, 33, 134, 192, 61, 217, 32, 251, 160, 220, 141, 90, 242, 106, 180, 1, 114, 82, 169, 61, 191, 20, 69, 194, 169, 82, 128, 195, 107, 241, 129, 172, 95, 135,\n  151, 80, 2, 43, 97, 153, 230, 128, 14, 204, 179, 222, 84, 21, 205, 95, 35, 249, 93, 218, 162, 71, 200, 53, 2, 107, 31, 201, 91, 62, 170, 211, 247, 160, 84, 233, 138, 74, 206, 43, 16, 201, 65, 136, 44, 154, 192, 218, 237, 95, 159, 11, 126, 97, 245, 225, 66, 251, 179, 150, 37, 19, 25, 13,\n  22, 120, 182, 139, 248, 209, 27, 79, 23, 42, 74, 131, 26, 7, 58, 177, 132, 211, 62, 11, 137, 184, 14, 121, 176, 73, 243, 132, 253, 189, 234, 74, 101, 49, 253, 108, 189, 244, 125, 83, 180, 115, 161, 252, 232, 97, 53, 128, 37, 247, 117, 45, 212, 148, 35, 114, 159, 45, 88, 207, 3, 73, 109, 53,\n  192, 65, 223, 165, 58, 114, 178, 4, 158, 118, 229, 12, 170, 141, 110, 223, 76, 167, 114, 47, 237, 85, 37, 232, 92, 212, 163, 54, 152, 39, 117, 144, 221, 176, 203, 146, 41, 97, 172, 9, 55, 221, 37, 197, 79, 210, 15, 177, 151, 197, 79, 228, 180, 63, 254, 186, 217, 131, 237, 58, 122, 177, 214, 161,\n  9, 103, 35, 253, 85, 234, 135, 99, 57, 199, 184, 104, 68, 201, 240, 46, 16, 144, 226, 195, 105, 151, 207, 134, 46, 11, 112, 227, 204, 84, 22, 13, 28, 124, 68, 1, 216, 61, 233, 153, 135, 239, 102, 172, 123, 147, 68, 105, 231, 57, 139, 2, 92, 163, 236, 96, 73, 9, 171, 98, 201, 144, 33, 90,\n  207, 147, 185, 123, 216, 191, 41, 25, 18, 86, 147, 47, 250, 88, 154, 183, 101, 1, 31, 175, 245, 57, 251, 170, 195, 147, 67, 182, 100, 10, 163, 63, 184, 240, 90, 165, 131, 187, 110, 30, 194, 86, 4, 57, 241, 28, 7, 21, 88, 211, 167, 28, 200, 122, 44, 141, 205, 27, 149, 222, 47, 250, 236, 133,\n  17, 70, 237, 52, 157, 73, 145, 23, 169, 33, 234, 214, 129, 231, 36, 124, 213, 64, 95, 130, 77, 218, 116, 73, 97, 229, 27, 19, 139, 48, 125, 202, 103, 152, 220, 37, 251, 85, 246, 214, 69, 167, 131, 216, 185, 156, 115, 191, 42, 123, 224, 103, 246, 69, 213, 251, 179, 119, 20, 71, 109, 186, 80, 50,\n  116, 164, 96, 199, 228, 110, 12, 60, 121, 7, 107, 176, 60, 164, 197, 75, 248, 161, 201, 253, 154, 187, 34, 254, 211, 127, 2, 173, 75, 212, 233, 81, 6, 47, 193, 115, 230, 53, 161, 123, 253, 227, 43, 106, 75, 231, 54, 170, 144, 10, 60, 183, 135, 228, 159, 108, 51, 89, 189, 13, 163, 127, 224, 173,\n  7, 40, 23, 134, 27, 175, 91, 211, 160, 74, 141, 204, 92, 9, 106, 238, 136, 39, 231, 112, 50, 241, 138, 168, 55, 155, 88, 117, 244, 155, 34, 175, 143, 23, 134, 68, 177, 137, 205, 39, 101, 149, 197, 248, 138, 204, 96, 245, 206, 80, 17, 154, 88, 37, 193, 75, 220, 1, 135, 39, 234, 61, 204, 89,\n  146, 192, 17, 81, 2, 124, 234, 45, 186, 16, 51, 225, 28, 18, 149, 49, 184, 89, 172, 68, 206, 100, 224, 80, 239, 204, 39, 224, 60, 192, 109, 15, 57, 85, 17, 208, 99, 5, 82, 183, 234, 63, 85, 171, 37, 254, 69, 129, 32, 108, 196, 47, 21, 8, 127, 237, 147, 171, 66, 201, 98, 150, 30, 231,\n  66, 104, 55, 178, 216, 63, 194, 140, 112, 239, 96, 158, 190, 121, 69, 210, 225, 118, 17, 147, 8, 179, 43, 119, 183, 105, 247, 176, 143, 90, 230, 128, 218, 183, 111, 26, 156, 22, 49, 14, 165, 125, 5, 229, 119, 160, 186, 239, 221, 166, 232, 118, 175, 98, 60, 183, 33, 94, 251, 121, 244, 175, 250, 129,\n  219, 162, 209, 143, 98, 156, 19, 83, 33, 201, 127, 3, 81, 235, 170, 99, 6, 57, 197, 27, 125, 88, 244, 150, 6, 70, 129, 51, 203, 5, 69, 168, 41, 146, 9, 223, 64, 197, 142, 109, 218, 30, 208, 59, 99, 214, 46, 148, 92, 56, 141, 71, 24, 151, 202, 247, 114, 229, 193, 50, 218, 73, 112, 188,\n  44, 11, 117, 35, 242, 50, 9, 173, 230, 153, 60, 182, 46, 140, 203, 36, 161, 139, 80, 232, 212, 158, 64, 217, 32, 199, 160, 13, 100, 30, 211, 245, 96, 199, 75, 162, 130, 92, 240, 70, 148, 93, 182, 155, 242, 79, 10, 114, 250, 180, 215, 0, 27, 15, 83, 48, 145, 166, 81, 133, 158, 38, 6, 85,\n  135, 21, 77, 222, 198, 130, 106, 66, 215, 90, 246, 211, 115, 253, 65, 241, 112, 16, 168, 104, 51, 248, 190, 135, 103, 237, 82, 221, 137, 185, 117, 153, 56, 122, 20, 44, 181, 212, 36, 171, 235, 254, 129, 43, 194, 137, 172, 68, 202, 40, 85, 105, 137, 172, 122, 211, 241, 61, 10, 226, 99, 208, 180, 228,\n  165, 97, 184, 148, 72, 237, 164, 245, 120, 141, 38, 165, 96, 219, 178, 88, 196, 42, 207, 2, 178, 116, 79, 253, 50, 182, 121, 61, 167, 248, 74, 224, 172, 11, 25, 25, 107, 2, 120, 190, 54, 204, 75, 224, 106, 20, 28, 226, 124, 242, 158, 194, 233, 64, 224, 93, 186, 110, 29, 176, 248, 144, 116, 63,\n  26, 24, 14, 45, 175, 94, 30, 192, 53, 200, 9, 74, 239, 30, 125, 155, 227, 131, 65, 93, 143, 37, 226, 164, 205, 144, 16, 37, 235, 94, 45, 195, 103, 33, 89, 143, 58, 77, 22, 140, 89, 116, 247, 169, 60, 3, 93, 190, 149, 55, 210, 118, 44, 254, 155, 38, 136, 20, 204, 89, 68, 44, 242, 199,\n  1, 130, 64, 113, 224, 206, 0, 151, 104, 17, 174, 119, 147, 197, 255, 54, 78, 249, 157, 218, 192, 242, 128, 97, 68, 3, 107, 215, 192, 127, 7, 144, 24, 134, 188, 23, 176, 159, 13, 46, 229, 156, 33, 138, 207, 121, 164, 73, 14, 98, 7, 75, 185, 101, 176, 234, 70, 0, 150, 123, 222, 171, 93, 154,\n  105, 213, 166, 236, 138, 76, 124, 60, 233, 84, 45, 224, 61, 100, 170, 243, 111, 181, 31, 13, 77, 55, 211, 248, 30, 177, 85, 151, 69, 163, 208, 62, 15, 79, 52, 9, 122, 26, 220, 103, 199, 252, 181, 81, 239, 43, 246, 214, 136, 34, 168, 218, 241, 131, 82, 198, 116, 166, 52, 187, 11, 131, 207, 71,\n  179, 47, 84, 196, 36, 15, 187, 161, 213, 135, 187, 156, 3, 208, 38, 138, 205, 233, 96, 125, 169, 106, 154, 187, 138, 223, 252, 51, 115, 246, 27, 110, 185, 162, 217, 104, 200, 88, 186, 145, 73, 53, 225, 99, 190, 154, 109, 53, 181, 237, 125, 60, 151, 31, 248, 218, 42, 23, 78, 102, 35, 19, 51, 240,\n  227, 120, 9, 145, 102, 25, 47, 110, 249, 32, 95, 245, 75, 125, 231, 87, 51, 147, 64, 22, 5, 39, 232, 86, 58, 120, 167, 200, 232, 182, 81, 222, 126, 20, 38, 148, 16, 62, 126, 242, 171, 113, 132, 10, 66, 234, 202, 85, 252, 105, 200, 89, 253, 187, 105, 66, 145, 17, 25, 24, 158, 194, 115, 148,\n  31, 204, 22, 68, 183, 21, 83, 170, 70, 226, 194, 113, 49, 181, 151, 247, 191, 216, 173, 25, 135, 199, 117, 254, 205, 244, 78, 39, 137, 96, 1, 151, 54, 94, 208, 75, 171, 233, 213, 35, 2, 202, 41, 174, 143, 31, 126, 227, 150, 41, 223, 163, 49, 212, 136, 171, 192, 109, 6, 124, 65, 89, 8, 75,\n  158, 91, 172, 51, 156, 125, 11, 209, 122, 145, 240, 166, 218, 11, 98, 66, 120, 36, 108, 84, 52, 179, 69, 165, 34, 102, 151, 218, 243, 172, 46, 197, 15, 174, 133, 5, 110, 51, 158, 98, 80, 153, 216, 241, 76, 252, 168, 58, 177, 76, 139, 236, 118, 255, 79, 243, 54, 87, 28, 178, 215, 137, 235, 187,\n  221, 135, 15, 112, 221, 26, 191, 56, 16, 41, 86, 60, 136, 29, 201, 157, 4, 225, 162, 13, 20, 100, 228, 140, 238, 193, 255, 55, 111, 72, 132, 236, 115, 62, 222, 31, 204, 138, 191, 14, 21, 59, 121, 94, 189, 112, 209, 93, 22, 1, 188, 63, 96, 174, 36, 229, 129, 212, 146, 239, 52, 166, 40, 106,\n  21, 45, 78, 196, 1, 90, 142, 104, 159, 183, 208, 249, 103, 232, 78, 19, 49, 142, 70, 186, 26, 149, 208, 48, 121, 87, 169, 129, 190, 13, 207, 34, 88, 189, 152, 19, 89, 236, 70, 107, 132, 180, 228, 48, 246, 151, 40, 13, 133, 111, 29, 243, 206, 144, 194, 104, 163, 11, 199, 97, 116, 249, 195, 63,\n  118, 180, 213, 149, 65, 171, 247, 229, 77, 6, 115, 148, 196, 170, 127, 178, 101, 209, 125, 239, 110, 6, 73, 183, 252, 62, 214, 30, 235, 94, 144, 169, 226, 14, 77, 124, 185, 163, 41, 200, 23, 26, 159, 206, 130, 71, 231, 191, 52, 210, 166, 130, 76, 221, 58, 248, 82, 43, 68, 170, 223, 77, 149, 5,\n  164, 17, 103, 38, 240, 124, 45, 198, 133, 34, 225, 50, 70, 244, 40, 217, 12, 84, 195, 57, 172, 232, 130, 95, 222, 146, 245, 81, 161, 61, 9, 52, 103, 137, 46, 214, 57, 111, 7, 148, 86, 12, 102, 61, 4, 179, 104, 160, 83, 235, 98, 250, 44, 6, 120, 148, 214, 181, 136, 18, 34, 131, 205, 92,\n  30, 72, 131, 224, 189, 98, 212, 69, 163, 101, 177, 18, 94, 159, 117, 66, 144, 34, 223, 151, 90, 43, 198, 155, 35, 105, 200, 132, 186, 223, 120, 240, 182, 202, 0, 157, 17, 23, 170, 66, 217, 140, 232, 195, 86, 225, 32, 140, 247, 63, 196, 151, 183, 88, 166, 31, 239, 115, 2, 90, 187, 235, 54, 222,\n  238, 197, 7, 159, 81, 12, 149, 236, 10, 58, 206, 140, 2, 203, 231, 191, 247, 169, 1, 118, 251, 219, 65, 9, 18, 177, 51, 3, 101, 38, 209, 154, 81, 28, 119, 71, 100, 34, 227, 124, 46, 177, 114, 38, 168, 119, 252, 212, 175, 124, 37, 229, 111, 13, 232, 196, 94, 59, 25, 47, 146, 109, 179, 123,\n  87, 143, 44, 113, 56, 181, 29, 108, 188, 222, 119, 80, 29, 109, 52, 78, 130, 98, 48, 74, 182, 139, 106, 165, 84, 121, 228, 69, 150, 247, 64, 97, 249, 173, 232, 206, 179, 140, 193, 79, 205, 240, 69, 14, 145, 200, 73, 49, 102, 1, 214, 70, 138, 50, 73, 131, 174, 204, 156, 22, 15, 69, 8, 160,\n  62, 247, 170, 234, 201, 246, 128, 73, 142, 42, 171, 237, 154, 249, 182, 161, 241, 198, 226, 156, 212, 29, 248, 195, 45, 245, 158, 205, 115, 174, 197, 141, 213, 56, 134, 90, 239, 58, 106, 10, 150, 91, 130, 22, 53, 96, 238, 135, 191, 81, 150, 172, 238, 200, 155, 220, 40, 111, 78, 126, 195, 99, 40, 211,\n  187, 97, 217, 72, 139, 91, 168, 254, 233, 92, 253, 61, 194, 129, 92, 219, 32, 112, 61, 242, 93, 123, 228, 76, 132, 212, 93, 30, 255, 81, 233, 37, 109, 17, 165, 40, 8, 216, 162, 19, 27, 189, 221, 158, 5, 180, 219, 161, 245, 42, 12, 105, 28, 90, 16, 101, 22, 10, 222, 27, 166, 226, 241, 136\n])\n","// sRGB [0–255] ↔ OKLab (Björn Ottosson, 2020)\n// https://bottosson.github.io/posts/oklab/\n\nfunction srgbToLinear(c: number): number {\n  const v = c / 255\n  return v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4)\n}\n\nfunction linearToSrgb(c: number): number {\n  return c <= 0.0031308 ? 12.92 * c : 1.055 * Math.pow(c, 1 / 2.4) - 0.055\n}\n\nexport function rgbToOklab(r: number, g: number, b: number): [number, number, number] {\n  const rl = srgbToLinear(r)\n  const gl = srgbToLinear(g)\n  const bl = srgbToLinear(b)\n\n  const l = Math.cbrt(0.4122214708 * rl + 0.5363325363 * gl + 0.0514459929 * bl)\n  const m = Math.cbrt(0.2119034982 * rl + 0.6806995451 * gl + 0.1073969566 * bl)\n  const s = Math.cbrt(0.0883024619 * rl + 0.2817188376 * gl + 0.6299787005 * bl)\n\n  return [\n    0.2104542553 * l + 0.7936177850 * m - 0.0040720468 * s,\n    1.9779984951 * l - 2.4285922050 * m + 0.4505937099 * s,\n    0.0259040371 * l + 0.7827717662 * m - 0.8086757660 * s\n  ]\n}\n\nexport function oklabToRgb(L: number, a: number, b: number): [number, number, number] {\n  const l = (L + 0.3963377774 * a + 0.2158037573 * b) ** 3\n  const m = (L - 0.1055613458 * a - 0.0638541728 * b) ** 3\n  const s = (L - 0.0894841775 * a - 1.2914855480 * b) ** 3\n\n  const rl = 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s\n  const gl = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s\n  const bll = -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s\n\n  return [\n    Math.round(Math.max(0, Math.min(255, linearToSrgb(rl) * 255))),\n    Math.round(Math.max(0, Math.min(255, linearToSrgb(gl) * 255))),\n    Math.round(Math.max(0, Math.min(255, linearToSrgb(bll) * 255)))\n  ]\n}\n","/*\n* Copyright (c) 2015, Leon Sorokin\n* All rights reserved. (MIT Licensed)\n*\n* RgbQuant.js - an image quantization lib\n*/\n\n(function(){\n\tfunction RgbQuant(opts) {\n\t\topts = opts || {};\n\n\t\t// 1 = by global population, 2 = subregion population threshold\n\t\tthis.method = opts.method || 2;\n\t\t// desired final palette size\n\t\tthis.colors = opts.colors || 256;\n\t\t// # of highest-frequency colors to start with for palette reduction\n\t\tthis.initColors = opts.initColors || 4096;\n\t\t// color-distance threshold for initial reduction pass\n\t\tthis.initDist = opts.initDist || 0.01;\n\t\t// subsequent passes threshold\n\t\tthis.distIncr = opts.distIncr || 0.005;\n\t\t// palette grouping\n\t\tthis.hueGroups = opts.hueGroups || 10;\n\t\tthis.satGroups = opts.satGroups || 10;\n\t\tthis.lumGroups = opts.lumGroups || 10;\n\t\t// if > 0, enables hues stats and min-color retention per group\n\t\tthis.minHueCols = opts.minHueCols || 0;\n\t\t// HueStats instance\n\t\tthis.hueStats = this.minHueCols ? new HueStats(this.hueGroups, this.minHueCols) : null;\n\n\t\t// subregion partitioning box size\n\t\tthis.boxSize = opts.boxSize || [64,64];\n\t\t// number of same pixels required within box for histogram inclusion\n\t\tthis.boxPxls = opts.boxPxls || 2;\n\t\t// palette locked indicator\n\t\tthis.palLocked = false;\n\t\t// palette sort order\n//\t\tthis.sortPal = ['hue-','lum-','sat-'];\n\n\t\t// dithering/error diffusion kernel name\n\t\tthis.dithKern = opts.dithKern || null;\n\t\t// dither serpentine pattern\n\t\tthis.dithSerp = opts.dithSerp || false;\n\t\t// minimum color difference (0-1) needed to dither\n\t\tthis.dithDelta = opts.dithDelta || 0;\n\n\t\t// accumulated histogram\n\t\tthis.histogram = {};\n\t\t// palette - rgb triplets\n\t\tthis.idxrgb = opts.palette ? opts.palette.slice(0) : [];\n\t\t// palette - int32 vals\n\t\tthis.idxi32 = [];\n\t\t// reverse lookup {i32:idx}\n\t\tthis.i32idx = {};\n\t\t// {i32:rgb}\n\t\tthis.i32rgb = {};\n\t\t// enable color caching (also incurs overhead of cache misses and cache building)\n\t\tthis.useCache = opts.useCache !== false;\n\t\t// min color occurance count needed to qualify for caching\n\t\tthis.cacheFreq = opts.cacheFreq || 10;\n\t\t// allows pre-defined palettes to be re-indexed (enabling palette compacting and sorting)\n\t\tthis.reIndex = opts.reIndex || this.idxrgb.length == 0;\n\t\t// selection of color-distance equation\n\t\tthis.colorDist = opts.colorDist == \"manhattan\" ? distManhattan : distEuclidean;\n\n\t\t// if pre-defined palette, build lookups\n\t\tif (this.idxrgb.length > 0) {\n\t\t\tvar self = this;\n\t\t\tthis.idxrgb.forEach(function(rgb, i) {\n\t\t\t\tvar i32 = (\n\t\t\t\t\t(255    << 24) |\t// alpha\n\t\t\t\t\t(rgb[2] << 16) |\t// blue\n\t\t\t\t\t(rgb[1] <<  8) |\t// green\n\t\t\t\t\t rgb[0]\t\t\t\t// red\n\t\t\t\t) >>> 0;\n\n\t\t\t\tself.idxi32[i]\t\t= i32;\n\t\t\t\tself.i32idx[i32]\t= i;\n\t\t\t\tself.i32rgb[i32]\t= rgb;\n\t\t\t});\n\t\t}\n\t}\n\n\t// gathers histogram info\n\tRgbQuant.prototype.sample = function sample(img, width) {\n\t\tif (this.palLocked)\n\t\t\tthrow \"Cannot sample additional images, palette already assembled.\";\n\n\t\tvar data = getImageData(img, width);\n\n\t\tswitch (this.method) {\n\t\t\tcase 1: this.colorStats1D(data.buf32); break;\n\t\t\tcase 2: this.colorStats2D(data.buf32, data.width); break;\n\t\t}\n\t};\n\n\t// image quantizer\n\t// todo: memoize colors here also\n\t// @retType: 1 - Uint8Array (default), 2 - Indexed array, 3 - Match @img type (unimplemented, todo)\n\tRgbQuant.prototype.reduce = function reduce(img, retType, dithKern, dithSerp) {\n\t\tif (!this.palLocked)\n\t\t\tthis.buildPal();\n\n\t\tdithKern = dithKern || this.dithKern;\n\t\tdithSerp = typeof dithSerp != \"undefined\" ? dithSerp : this.dithSerp;\n\n\t\tretType = retType || 1;\n\n\t\t// reduce w/dither\n\t\tif (dithKern)\n\t\t\tvar out32 = this.dither(img, dithKern, dithSerp);\n\t\telse {\n\t\t\tvar data = getImageData(img),\n\t\t\t\tbuf32 = data.buf32,\n\t\t\t\tlen = buf32.length,\n\t\t\t\tout32 = new Uint32Array(len);\n\n\t\t\tfor (var i = 0; i < len; i++) {\n\t\t\t\tvar i32 = buf32[i];\n\t\t\t\tout32[i] = this.nearestColor(i32);\n\t\t\t}\n\t\t}\n\n\t\tif (retType == 1)\n\t\t\treturn new Uint8Array(out32.buffer);\n\n\t\tif (retType == 2) {\n\t\t\tvar out = [],\n\t\t\t\tlen = out32.length;\n\n\t\t\tfor (var i = 0; i < len; i++) {\n\t\t\t\tvar i32 = out32[i];\n\t\t\t\tout[i] = this.i32idx[i32];\n\t\t\t}\n\n\t\t\treturn out;\n\t\t}\n\t};\n\n\t// adapted from http://jsbin.com/iXofIji/2/edit by PAEz\n\tRgbQuant.prototype.dither = function(img, kernel, serpentine) {\n\t\t// http://www.tannerhelland.com/4660/dithering-eleven-algorithms-source-code/\n\t\tvar kernels = {\n\t\t\tFloydSteinberg: [\n\t\t\t\t[7 / 16, 1, 0],\n\t\t\t\t[3 / 16, -1, 1],\n\t\t\t\t[5 / 16, 0, 1],\n\t\t\t\t[1 / 16, 1, 1]\n\t\t\t],\n\t\t\tAtkinson: [\n\t\t\t\t[1 / 8, 1, 0],\n\t\t\t\t[1 / 8, 2, 0],\n\t\t\t\t[1 / 8, -1, 1],\n\t\t\t\t[1 / 8, 0, 1],\n\t\t\t\t[1 / 8, 1, 1],\n\t\t\t\t[1 / 8, 0, 2]\n\t\t\t],\n\t\t\tSierra24A: [\n\t\t\t\t[2 / 4, 1, 0],\n\t\t\t\t[1 / 4, -1, 1],\n\t\t\t\t[1 / 4, 0, 1]\n\t\t\t],\n\t\t\tFan: [\n\t\t\t\t[7 / 16, 1, 0],\n\t\t\t\t[1 / 16, -2, 1],\n\t\t\t\t[3 / 16, -1, 1],\n\t\t\t\t[5 / 16, 0, 1]\n\t\t\t],\n\t\t\tShiauFan: [\n\t\t\t\t[4 / 8, 1, 0],\n\t\t\t\t[1 / 8, -2, 1],\n\t\t\t\t[1 / 8, -1, 1],\n\t\t\t\t[2 / 8, 0, 1]\n\t\t\t],\n\t\t\tShiauFan2: [\n\t\t\t\t[8 / 16, 1, 0],\n\t\t\t\t[1 / 16, -3, 1],\n\t\t\t\t[1 / 16, -2, 1],\n\t\t\t\t[2 / 16, -1, 1],\n\t\t\t\t[4 / 16, 0, 1]\n\t\t\t],\n\t\t\tJarvisJudiceNinke: [\n\t\t\t\t[7 / 48, 1, 0],\n\t\t\t\t[5 / 48, 2, 0],\n\t\t\t\t[3 / 48, -2, 1],\n\t\t\t\t[5 / 48, -1, 1],\n\t\t\t\t[7 / 48, 0, 1],\n\t\t\t\t[5 / 48, 1, 1],\n\t\t\t\t[3 / 48, 2, 1],\n\t\t\t\t[1 / 48, -2, 2],\n\t\t\t\t[3 / 48, -1, 2],\n\t\t\t\t[5 / 48, 0, 2],\n\t\t\t\t[3 / 48, 1, 2],\n\t\t\t\t[1 / 48, 2, 2]\n\t\t\t],\n\t\t\tStucki: [\n\t\t\t\t[8 / 42, 1, 0],\n\t\t\t\t[4 / 42, 2, 0],\n\t\t\t\t[2 / 42, -2, 1],\n\t\t\t\t[4 / 42, -1, 1],\n\t\t\t\t[8 / 42, 0, 1],\n\t\t\t\t[4 / 42, 1, 1],\n\t\t\t\t[2 / 42, 2, 1],\n\t\t\t\t[1 / 42, -2, 2],\n\t\t\t\t[2 / 42, -1, 2],\n\t\t\t\t[4 / 42, 0, 2],\n\t\t\t\t[2 / 42, 1, 2],\n\t\t\t\t[1 / 42, 2, 2]\n\t\t\t],\n\t\t\tBurkes: [\n\t\t\t\t[8 / 32, 1, 0],\n\t\t\t\t[4 / 32, 2, 0],\n\t\t\t\t[2 / 32, -2, 1],\n\t\t\t\t[4 / 32, -1, 1],\n\t\t\t\t[8 / 32, 0, 1],\n\t\t\t\t[4 / 32, 1, 1],\n\t\t\t\t[2 / 32, 2, 1]\n\t\t\t],\n\t\t\tSierra3: [\n\t\t\t\t[5 / 32, 1, 0],\n\t\t\t\t[3 / 32, 2, 0],\n\t\t\t\t[2 / 32, -2, 1],\n\t\t\t\t[4 / 32, -1, 1],\n\t\t\t\t[5 / 32, 0, 1],\n\t\t\t\t[4 / 32, 1, 1],\n\t\t\t\t[2 / 32, 2, 1],\n\t\t\t\t[2 / 32, -1, 2],\n\t\t\t\t[3 / 32, 0, 2],\n\t\t\t\t[2 / 32, 1, 2]\n\t\t\t],\n\t\t\tSierra2: [\n\t\t\t\t[4 / 16, 1, 0],\n\t\t\t\t[3 / 16, 2, 0],\n\t\t\t\t[1 / 16, -2, 1],\n\t\t\t\t[2 / 16, -1, 1],\n\t\t\t\t[3 / 16, 0, 1],\n\t\t\t\t[2 / 16, 1, 1],\n\t\t\t\t[1 / 16, 2, 1]\n\t\t\t],\n\t\t};\n\n\t\tif (!kernel || !kernels[kernel]) {\n\t\t\tthrow 'Unknown dithering kernel: ' + kernel;\n\t\t}\n\n\t\tvar ds = kernels[kernel];\n\n\t\tvar data = getImageData(img),\n//\t\t\tbuf8 = data.buf8,\n\t\t\tbuf32 = data.buf32,\n\t\t\twidth = data.width,\n\t\t\theight = data.height,\n\t\t\tlen = buf32.length;\n\n\t\tvar dir = serpentine ? -1 : 1;\n\n\t\t// Float error accumulation buffers — avoids clamping bias from writing back to uint8 pixel buffer\n\t\tvar errR = new Float64Array(len),\n\t\t    errG = new Float64Array(len),\n\t\t    errB = new Float64Array(len);\n\n\t\t// Keep track of transparent pixels\n\t\tvar transparentPixels = []\n\t\tfor (var x=0; x < buf32.length; x++){\n\t\t\tif(buf32[x] == 0) {\n\t\t\t\ttransparentPixels.push(x)\n\t\t\t}\n\t\t}\t\t\n\n\t\tfor (var y = 0; y < height; y++) {\n\t\t\tif (serpentine)\n\t\t\t\tdir = dir * -1;\n\n\t\t\tvar lni = y * width;\n\n\t\t\tfor (var x = (dir == 1 ? 0 : width - 1), xend = (dir == 1 ? width : 0); x !== xend; x += dir) {\n\t\t\t\t// Image pixel (add accumulated float error before clamping)\n\t\t\t\tvar idx = lni + x,\n\t\t\t\t\ti32 = buf32[idx],\n\t\t\t\t\tr1r = (i32 & 0xff) + errR[idx],\n\t\t\t\t\tg1r = ((i32 & 0xff00) >> 8) + errG[idx],\n\t\t\t\t\tb1r = ((i32 & 0xff0000) >> 16) + errB[idx],\n\t\t\t\t\tr1 = Math.max(0, Math.min(255, Math.round(r1r))),\n\t\t\t\t\tg1 = Math.max(0, Math.min(255, Math.round(g1r))),\n\t\t\t\t\tb1 = Math.max(0, Math.min(255, Math.round(b1r)));\n\n\t\t\t\t// Reduced pixel\n\t\t\t\tvar i32x = this.nearestColor((255 << 24) | (b1 << 16) | (g1 << 8) | r1),\n\t\t\t\t\tr2 = (i32x & 0xff),\n\t\t\t\t\tg2 = (i32x & 0xff00) >> 8,\n\t\t\t\t\tb2 = (i32x & 0xff0000) >> 16;\n\n\t\t\t\tbuf32[idx] =\n\t\t\t\t\t(255 << 24)\t|\t// alpha\n\t\t\t\t\t(b2  << 16)\t|\t// blue\n\t\t\t\t\t(g2  <<  8)\t|\t// green\n\t\t\t\t\t r2;\n\n\t\t\t\t// dithering strength\n\t\t\t\tif (this.dithDelta) {\n\t\t\t\t\tvar dist = this.colorDist([r1, g1, b1], [r2, g2, b2]);\n\t\t\t\t\tif (dist < this.dithDelta)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Component distance (use unclamped raw values to preserve overflow)\n\t\t\t\tvar er = r1r - r2,\n\t\t\t\t\teg = g1r - g2,\n\t\t\t\t\teb = b1r - b2;\n\n\t\t\t\tfor (var i = (dir == 1 ? 0 : ds.length - 1), end = (dir == 1 ? ds.length : 0); i !== end; i += dir) {\n\t\t\t\t\tvar x1 = ds[i][1] * dir,\n\t\t\t\t\t\ty1 = ds[i][2];\n\n\t\t\t\t\tvar lni2 = y1 * width;\n\n\t\t\t\t\tif (x1 + x >= 0 && x1 + x < width && y1 + y >= 0 && y1 + y < height) {\n\t\t\t\t\t\tvar d = ds[i][0];\n\t\t\t\t\t\tvar idx2 = idx + (lni2 + x1);\n\n\t\t\t\t\t\t// Accumulate error into float buffers (no clamping — preserves overflow)\n\t\t\t\t\t\terrR[idx2] += er * d;\n\t\t\t\t\t\terrG[idx2] += eg * d;\n\t\t\t\t\t\terrB[idx2] += eb * d;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Make transparent pixels transparent again\n\t\tfor (x in transparentPixels) {\n\t\t\tbuf32[transparentPixels[x]] = 0\n\t\t}\t\t\t\t\n\n\t\treturn buf32;\n\t};\n\n\t// reduces histogram to palette, remaps & memoizes reduced colors\n\tRgbQuant.prototype.buildPal = function buildPal(noSort) {\n\t\tif (this.palLocked || this.idxrgb.length > 0 && this.idxrgb.length <= this.colors) return;\n\n\t\tvar histG  = this.histogram,\n\t\t\tsorted = sortedHashKeys(histG, true);\n\n\t\tif (sorted.length == 0)\n\t\t\tthrow \"Nothing has been sampled, palette cannot be built.\";\n\n\t\tswitch (this.method) {\n\t\t\tcase 1:\n\t\t\t\tvar cols = this.initColors,\n\t\t\t\t\tlast = sorted[cols - 1],\n\t\t\t\t\tfreq = histG[last];\n\n\t\t\t\tvar idxi32 = sorted.slice(0, cols);\n\n\t\t\t\t// add any cut off colors with same freq as last\n\t\t\t\tvar pos = cols, len = sorted.length;\n\t\t\t\twhile (pos < len && histG[sorted[pos]] == freq)\n\t\t\t\t\tidxi32.push(sorted[pos++]);\n\n\t\t\t\t// inject min huegroup colors\n\t\t\t\tif (this.hueStats)\n\t\t\t\t\tthis.hueStats.inject(idxi32);\n\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tvar idxi32 = sorted;\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// int32-ify values\n\t\tidxi32 = idxi32.map(function(v){return +v;});\n\n\t\tthis.reducePal(idxi32);\n\n\t\tif (!noSort && this.reIndex)\n\t\t\tthis.sortPal();\n\n\t\t// build cache of top histogram colors\n\t\tif (this.useCache)\n\t\t\tthis.cacheHistogram(idxi32);\n\n\t\tthis.palLocked = true;\n\t};\n\n\tRgbQuant.prototype.palette = function palette(tuples, noSort) {\n\t\tthis.buildPal(noSort);\n\t\treturn tuples ? this.idxrgb : new Uint8Array((new Uint32Array(this.idxi32)).buffer);\n\t};\n\n\tRgbQuant.prototype.prunePal = function prunePal(keep) {\n\t\tvar i32;\n\n\t\tfor (var j = 0; j < this.idxrgb.length; j++) {\n\t\t\tif (!keep[j]) {\n\t\t\t\ti32 = this.idxi32[j];\n\t\t\t\tthis.idxrgb[j] = null;\n\t\t\t\tthis.idxi32[j] = null;\n\t\t\t\tdelete this.i32idx[i32];\n\t\t\t}\n\t\t}\n\n\t\t// compact\n\t\tif (this.reIndex) {\n\t\t\tvar idxrgb = [],\n\t\t\t\tidxi32 = [],\n\t\t\t\ti32idx = {};\n\n\t\t\tfor (var j = 0, i = 0; j < this.idxrgb.length; j++) {\n\t\t\t\tif (this.idxrgb[j]) {\n\t\t\t\t\ti32 = this.idxi32[j];\n\t\t\t\t\tidxrgb[i] = this.idxrgb[j];\n\t\t\t\t\ti32idx[i32] = i;\n\t\t\t\t\tidxi32[i] = i32;\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.idxrgb = idxrgb;\n\t\t\tthis.idxi32 = idxi32;\n\t\t\tthis.i32idx = i32idx;\n\t\t}\n\t};\n\n\t// reduces similar colors from an importance-sorted Uint32 rgba array\n\tRgbQuant.prototype.reducePal = function reducePal(idxi32) {\n\t\t// if pre-defined palette's length exceeds target\n\t\tif (this.idxrgb.length > this.colors) {\n\t\t\t// quantize histogram to existing palette\n\t\t\tvar len = idxi32.length, keep = {}, uniques = 0, idx, pruned = false;\n\n\t\t\tfor (var i = 0; i < len; i++) {\n\t\t\t\t// palette length reached, unset all remaining colors (sparse palette)\n\t\t\t\tif (uniques == this.colors && !pruned) {\n\t\t\t\t\tthis.prunePal(keep);\n\t\t\t\t\tpruned = true;\n\t\t\t\t}\n\n\t\t\t\tidx = this.nearestIndex(idxi32[i]);\n\n\t\t\t\tif (uniques < this.colors && !keep[idx]) {\n\t\t\t\t\tkeep[idx] = true;\n\t\t\t\t\tuniques++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!pruned) {\n\t\t\t\tthis.prunePal(keep);\n\t\t\t\tpruned = true;\n\t\t\t}\n\t\t}\n\t\t// reduce histogram to create initial palette\n\t\telse {\n\t\t\t// build full rgb palette\n\t\t\tvar idxrgb = idxi32.map(function(i32) {\n\t\t\t\treturn [\n\t\t\t\t\t(i32 & 0xff),\n\t\t\t\t\t(i32 & 0xff00) >> 8,\n\t\t\t\t\t(i32 & 0xff0000) >> 16,\n\t\t\t\t];\n\t\t\t});\n\n\t\t\tvar len = idxrgb.length,\n\t\t\t\tpalLen = len,\n\t\t\t\tthold = this.initDist;\n\n\t\t\t// palette already at or below desired length\n\t\t\tif (palLen > this.colors) {\n\t\t\t\twhile (palLen > this.colors) {\n\t\t\t\t\tvar memDist = [];\n\n\t\t\t\t\t// iterate palette\n\t\t\t\t\tfor (var i = 0; i < len; i++) {\n\t\t\t\t\t\tvar pxi = idxrgb[i], i32i = idxi32[i];\n\t\t\t\t\t\tif (!pxi) continue;\n\n\t\t\t\t\t\tfor (var j = i + 1; j < len; j++) {\n\t\t\t\t\t\t\tvar pxj = idxrgb[j], i32j = idxi32[j];\n\t\t\t\t\t\t\tif (!pxj) continue;\n\n\t\t\t\t\t\t\tvar dist = this.colorDist(pxi, pxj);\n\n\t\t\t\t\t\t\tif (dist < thold) {\n\t\t\t\t\t\t\t\t// store index,rgb,dist\n\t\t\t\t\t\t\t\tmemDist.push([j, pxj, i32j, dist]);\n\n\t\t\t\t\t\t\t\t// kill squashed value\n\t\t\t\t\t\t\t\tdelete(idxrgb[j]);\n\t\t\t\t\t\t\t\tpalLen--;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// palette reduction pass\n\t\t\t\t\t// console.log(\"palette length: \" + palLen);\n\n\t\t\t\t\t// if palette is still much larger than target, increment by larger initDist\n\t\t\t\t\tthold += (palLen > this.colors * 3) ? this.initDist : this.distIncr;\n\t\t\t\t}\n\n\t\t\t\t// if palette is over-reduced, re-add removed colors with largest distances from last round\n\t\t\t\tif (palLen < this.colors) {\n\t\t\t\t\t// sort descending\n\t\t\t\t\tsort.call(memDist, function(a,b) {\n\t\t\t\t\t\treturn b[3] - a[3];\n\t\t\t\t\t});\n\n\t\t\t\t\tvar k = 0;\n\t\t\t\t\twhile (palLen < this.colors) {\n\t\t\t\t\t\t// re-inject rgb into final palette\n\t\t\t\t\t\tidxrgb[memDist[k][0]] = memDist[k][1];\n\n\t\t\t\t\t\tpalLen++;\n\t\t\t\t\t\tk++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar len = idxrgb.length;\n\t\t\tfor (var i = 0; i < len; i++) {\n\t\t\t\tif (!idxrgb[i]) continue;\n\n\t\t\t\tthis.idxrgb.push(idxrgb[i]);\n\t\t\t\tthis.idxi32.push(idxi32[i]);\n\n\t\t\t\tthis.i32idx[idxi32[i]] = this.idxi32.length - 1;\n\t\t\t\tthis.i32rgb[idxi32[i]] = idxrgb[i];\n\t\t\t}\n\t\t}\n\t};\n\n\t// global top-population\n\tRgbQuant.prototype.colorStats1D = function colorStats1D(buf32) {\n\t\tvar histG = this.histogram,\n\t\t\tnum = 0, col,\n\t\t\tlen = buf32.length;\n\n\t\tfor (var i = 0; i < len; i++) {\n\t\t\tcol = buf32[i];\n\n\t\t\t// skip transparent\n\t\t\tif ((col & 0xff000000) >> 24 == 0) continue;\n\n\t\t\t// collect hue stats\n\t\t\tif (this.hueStats)\n\t\t\t\tthis.hueStats.check(col);\n\n\t\t\tif (col in histG)\n\t\t\t\thistG[col]++;\n\t\t\telse\n\t\t\t\thistG[col] = 1;\n\t\t}\n\t};\n\n\t// population threshold within subregions\n\t// FIXME: this can over-reduce (few/no colors same?), need a way to keep\n\t// important colors that dont ever reach local thresholds (gradients?)\n\tRgbQuant.prototype.colorStats2D = function colorStats2D(buf32, width) {\n\t\tvar boxW = this.boxSize[0],\n\t\t\tboxH = this.boxSize[1],\n\t\t\tarea = boxW * boxH,\n\t\t\tboxes = makeBoxes(width, buf32.length / width, boxW, boxH),\n\t\t\thistG = this.histogram,\n\t\t\tself = this;\n\n\t\tboxes.forEach(function(box) {\n\t\t\tvar effc = Math.max(Math.round((box.w * box.h) / area) * self.boxPxls, 2),\n\t\t\t\thistL = {}, col;\n\n\t\t\titerBox(box, width, function(i) {\n\t\t\t\tcol = buf32[i];\n\n\t\t\t\t// skip transparent\n\t\t\t\tif ((col & 0xff000000) >> 24 == 0) return;\n\n\t\t\t\t// collect hue stats\n\t\t\t\tif (self.hueStats)\n\t\t\t\t\tself.hueStats.check(col);\n\n\t\t\t\tif (col in histG)\n\t\t\t\t\thistG[col]++;\n\t\t\t\telse if (col in histL) {\n\t\t\t\t\tif (++histL[col] >= effc)\n\t\t\t\t\t\thistG[col] = histL[col];\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\thistL[col] = 1;\n\t\t\t});\n\t\t});\n\n\t\tif (this.hueStats)\n\t\t\tthis.hueStats.inject(histG);\n\t};\n\n\t// TODO: group very low lum and very high lum colors\n\t// TODO: pass custom sort order\n\tRgbQuant.prototype.sortPal = function sortPal() {\n\t\tvar self = this;\n\n\t\tthis.idxi32.sort(function(a,b) {\n\t\t\tvar idxA = self.i32idx[a],\n\t\t\t\tidxB = self.i32idx[b],\n\t\t\t\trgbA = self.idxrgb[idxA],\n\t\t\t\trgbB = self.idxrgb[idxB];\n\n\t\t\tvar hslA = rgb2hsl(rgbA[0],rgbA[1],rgbA[2]),\n\t\t\t\thslB = rgb2hsl(rgbB[0],rgbB[1],rgbB[2]);\n\n\t\t\t// sort all grays + whites together\n\t\t\tvar hueA = (rgbA[0] == rgbA[1] && rgbA[1] == rgbA[2]) ? -1 : hueGroup(hslA.h, self.hueGroups);\n\t\t\tvar hueB = (rgbB[0] == rgbB[1] && rgbB[1] == rgbB[2]) ? -1 : hueGroup(hslB.h, self.hueGroups);\n\n\t\t\tvar hueDiff = hueB - hueA;\n\t\t\tif (hueDiff) return -hueDiff;\n\n\t\t\tvar lumDiff = lumGroup(+hslB.l.toFixed(2)) - lumGroup(+hslA.l.toFixed(2));\n\t\t\tif (lumDiff) return -lumDiff;\n\n\t\t\tvar satDiff = satGroup(+hslB.s.toFixed(2)) - satGroup(+hslA.s.toFixed(2));\n\t\t\tif (satDiff) return -satDiff;\n\t\t});\n\n\t\t// sync idxrgb & i32idx\n\t\tthis.idxi32.forEach(function(i32, i) {\n\t\t\tself.idxrgb[i] = self.i32rgb[i32];\n\t\t\tself.i32idx[i32] = i;\n\t\t});\n\t};\n\n\t// TOTRY: use HUSL - http://boronine.com/husl/\n\tRgbQuant.prototype.nearestColor = function nearestColor(i32) {\n\t\tvar idx = this.nearestIndex(i32);\n\t\treturn idx === null ? 0 : this.idxi32[idx];\n\t};\n\n\t// TOTRY: use HUSL - http://boronine.com/husl/\n\tRgbQuant.prototype.nearestIndex = function nearestIndex(i32) {\n\t\t// alpha 0 returns null index\n\t\tif ((i32 & 0xff000000) >> 24 == 0)\n\t\t\treturn null;\n\n\t\tif (this.useCache && (\"\"+i32) in this.i32idx)\n\t\t\treturn this.i32idx[i32];\n\n\t\tvar min = 1000,\n\t\t\tidx,\n\t\t\trgb = [\n\t\t\t\t(i32 & 0xff),\n\t\t\t\t(i32 & 0xff00) >> 8,\n\t\t\t\t(i32 & 0xff0000) >> 16,\n\t\t\t],\n\t\t\tlen = this.idxrgb.length;\n\n\t\tfor (var i = 0; i < len; i++) {\n\t\t\tif (!this.idxrgb[i]) continue;\t\t// sparse palettes\n\n\t\t\tvar dist = this.colorDist(rgb, this.idxrgb[i]);\n\n\t\t\tif (dist < min) {\n\t\t\t\tmin = dist;\n\t\t\t\tidx = i;\n\t\t\t}\n\t\t}\n\n\t\treturn idx;\n\t};\n\n\tRgbQuant.prototype.cacheHistogram = function cacheHistogram(idxi32) {\n\t\tfor (var i = 0, i32 = idxi32[i]; i < idxi32.length && this.histogram[i32] >= this.cacheFreq; i32 = idxi32[i++])\n\t\t\tthis.i32idx[i32] = this.nearestIndex(i32);\n\t};\n\n\tfunction HueStats(numGroups, minCols) {\n\t\tthis.numGroups = numGroups;\n\t\tthis.minCols = minCols;\n\t\tthis.stats = {};\n\n\t\tfor (var i = -1; i < numGroups; i++)\n\t\t\tthis.stats[i] = {num: 0, cols: []};\n\n\t\tthis.groupsFull = 0;\n\t}\n\n\tHueStats.prototype.check = function checkHue(i32) {\n\t\tif (this.groupsFull == this.numGroups + 1)\n\t\t\tthis.check = function() {return;};\n\n\t\tvar r = (i32 & 0xff),\n\t\t\tg = (i32 & 0xff00) >> 8,\n\t\t\tb = (i32 & 0xff0000) >> 16,\n\t\t\thg = (r == g && g == b) ? -1 : hueGroup(rgb2hsl(r,g,b).h, this.numGroups),\n\t\t\tgr = this.stats[hg],\n\t\t\tmin = this.minCols;\n\n\t\tgr.num++;\n\n\t\tif (gr.num > min)\n\t\t\treturn;\n\t\tif (gr.num == min)\n\t\t\tthis.groupsFull++;\n\n\t\tif (gr.num <= min)\n\t\t\tthis.stats[hg].cols.push(i32);\n\t};\n\n\tHueStats.prototype.inject = function injectHues(histG) {\n\t\tfor (var i = -1; i < this.numGroups; i++) {\n\t\t\tif (this.stats[i].num <= this.minCols) {\n\t\t\t\tswitch (typeOf(histG)) {\n\t\t\t\t\tcase \"Array\":\n\t\t\t\t\t\tthis.stats[i].cols.forEach(function(col){\n\t\t\t\t\t\t\tif (histG.indexOf(col) == -1)\n\t\t\t\t\t\t\t\thistG.push(col);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"Object\":\n\t\t\t\t\t\tthis.stats[i].cols.forEach(function(col){\n\t\t\t\t\t\t\tif (!histG[col])\n\t\t\t\t\t\t\t\thistG[col] = 1;\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\thistG[col]++;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// Rec. 709 (sRGB) luma coef\n\tvar Pr = .2126,\n\t\tPg = .7152,\n\t\tPb = .0722;\n\n\t// http://alienryderflex.com/hsp.html\n\tfunction rgb2lum(r,g,b) {\n\t\treturn Math.sqrt(\n\t\t\tPr * r*r +\n\t\t\tPg * g*g +\n\t\t\tPb * b*b\n\t\t);\n\t}\n\n\tvar rd = 255,\n\t\tgd = 255,\n\t\tbd = 255;\n\n\tvar euclMax = Math.sqrt(Pr*rd*rd + Pg*gd*gd + Pb*bd*bd);\n\t// perceptual Euclidean color distance\n\tfunction distEuclidean(rgb0, rgb1) {\n\t\tvar rd = rgb1[0]-rgb0[0],\n\t\t\tgd = rgb1[1]-rgb0[1],\n\t\t\tbd = rgb1[2]-rgb0[2];\n\n\t\treturn Math.sqrt(Pr*rd*rd + Pg*gd*gd + Pb*bd*bd) / euclMax;\n\t}\n\n\tvar manhMax = Pr*rd + Pg*gd + Pb*bd;\n\t// perceptual Manhattan color distance\n\tfunction distManhattan(rgb0, rgb1) {\n\t\tvar rd = Math.abs(rgb1[0]-rgb0[0]),\n\t\t\tgd = Math.abs(rgb1[1]-rgb0[1]),\n\t\t\tbd = Math.abs(rgb1[2]-rgb0[2]);\n\n\t\treturn (Pr*rd + Pg*gd + Pb*bd) / manhMax;\n\t}\n\n\t// http://rgb2hsl.nichabi.com/javascript-function.php\n\tfunction rgb2hsl(r, g, b) {\n\t\tvar max, min, h, s, l, d;\n\t\tr /= 255;\n\t\tg /= 255;\n\t\tb /= 255;\n\t\tmax = Math.max(r, g, b);\n\t\tmin = Math.min(r, g, b);\n\t\tl = (max + min) / 2;\n\t\tif (max == min) {\n\t\t\th = s = 0;\n\t\t} else {\n\t\t\td = max - min;\n\t\t\ts = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\t\t\tswitch (max) {\n\t\t\t\tcase r: h = (g - b) / d + (g < b ? 6 : 0); break;\n\t\t\t\tcase g:\th = (b - r) / d + 2; break;\n\t\t\t\tcase b:\th = (r - g) / d + 4; break\n\t\t\t}\n\t\t\th /= 6;\n\t\t}\n//\t\th = Math.floor(h * 360)\n//\t\ts = Math.floor(s * 100)\n//\t\tl = Math.floor(l * 100)\n\t\treturn {\n\t\t\th: h,\n\t\t\ts: s,\n\t\t\tl: rgb2lum(r,g,b),\n\t\t};\n\t}\n\n\tfunction hueGroup(hue, segs) {\n\t\tvar seg = 1/segs,\n\t\t\thaf = seg/2;\n\n\t\tif (hue >= 1 - haf || hue <= haf)\n\t\t\treturn 0;\n\n\t\tfor (var i = 1; i < segs; i++) {\n\t\t\tvar mid = i*seg;\n\t\t\tif (hue >= mid - haf && hue <= mid + haf)\n\t\t\t\treturn i;\n\t\t}\n\t}\n\n\tfunction satGroup(sat) {\n\t\treturn sat;\n\t}\n\n\tfunction lumGroup(lum) {\n\t\treturn lum;\n\t}\n\n\tfunction typeOf(val) {\n\t\treturn Object.prototype.toString.call(val).slice(8,-1);\n\t}\n\n\tvar sort = isArrSortStable() ? Array.prototype.sort : stableSort;\n\n\t// must be used via stableSort.call(arr, fn)\n\tfunction stableSort(fn) {\n\t\tvar type = typeOf(this[0]);\n\n\t\tif (type == \"Number\" || type == \"String\") {\n\t\t\tvar ord = {}, len = this.length, val;\n\n\t\t\tfor (var i = 0; i < len; i++) {\n\t\t\t\tval = this[i];\n\t\t\t\tif (ord[val] || ord[val] === 0) continue;\n\t\t\t\tord[val] = i;\n\t\t\t}\n\n\t\t\treturn this.sort(function(a,b) {\n\t\t\t\treturn fn(a,b) || ord[a] - ord[b];\n\t\t\t});\n\t\t}\n\t\telse {\n\t\t\tvar ord = this.map(function(v){return v});\n\n\t\t\treturn this.sort(function(a,b) {\n\t\t\t\treturn fn(a,b) || ord.indexOf(a) - ord.indexOf(b);\n\t\t\t});\n\t\t}\n\t}\n\n\t// test if js engine's Array#sort implementation is stable\n\tfunction isArrSortStable() {\n\t\tvar str = \"abcdefghijklmnopqrstuvwxyz\";\n\n\t\treturn \"xyzvwtursopqmnklhijfgdeabc\" == str.split(\"\").sort(function(a,b) {\n\t\t\treturn ~~(str.indexOf(b)/2.3) - ~~(str.indexOf(a)/2.3);\n\t\t}).join(\"\");\n\t}\n\n\t// returns uniform pixel data from various img\n\t// TODO?: if array is passed, createimagedata, createlement canvas? take a pxlen?\n\tfunction getImageData(img, width) {\n\t\tvar can, ctx, imgd, buf8, buf32, height;\n\n\t\tswitch (typeOf(img)) {\n\t\t\tcase \"HTMLImageElement\":\n\t\t\t\tcan = document.createElement(\"canvas\");\n\t\t\t\tcan.width = img.naturalWidth;\n\t\t\t\tcan.height = img.naturalHeight;\n\t\t\t\tctx = can.getContext(\"2d\");\n\t\t\t\tctx.drawImage(img,0,0);\n\t\t\tcase \"Canvas\":\n\t\t\tcase \"HTMLCanvasElement\":\n\t\t\t\tcan = can || img;\n\t\t\t\tctx = ctx || can.getContext(\"2d\");\n\t\t\tcase \"CanvasRenderingContext2D\":\n\t\t\t\tctx = ctx || img;\n\t\t\t\tcan = can || ctx.canvas;\n\t\t\t\timgd = ctx.getImageData(0, 0, can.width, can.height);\n\t\t\tcase \"ImageData\":\n\t\t\t\timgd = imgd || img;\n\t\t\t\twidth = imgd.width;\n\t\t\t\tif (typeOf(imgd.data) == \"CanvasPixelArray\")\n\t\t\t\t\tbuf8 = new Uint8Array(imgd.data);\n\t\t\t\telse\n\t\t\t\t\tbuf8 = imgd.data;\n\t\t\tcase \"Array\":\n\t\t\tcase \"CanvasPixelArray\":\n\t\t\t\tbuf8 = buf8 || new Uint8Array(img);\n\t\t\tcase \"Uint8Array\":\n\t\t\tcase \"Uint8ClampedArray\":\n\t\t\t\tbuf8 = buf8 || img;\n\t\t\t\tbuf32 = new Uint32Array(buf8.buffer);\n\t\t\tcase \"Uint32Array\":\n\t\t\t\tbuf32 = buf32 || img;\n\t\t\t\tbuf8 = buf8 || new Uint8Array(buf32.buffer);\n\t\t\t\twidth = width || buf32.length;\n\t\t\t\theight = buf32.length / width;\n\t\t}\n\n\t\treturn {\n\t\t\tcan: can,\n\t\t\tctx: ctx,\n\t\t\timgd: imgd,\n\t\t\tbuf8: buf8,\n\t\t\tbuf32: buf32,\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t};\n\t}\n\n\t// partitions a rect of wid x hgt into\n\t// array of bboxes of w0 x h0 (or less)\n\tfunction makeBoxes(wid, hgt, w0, h0) {\n\t\tvar wnum = ~~(wid/w0), wrem = wid%w0,\n\t\t\thnum = ~~(hgt/h0), hrem = hgt%h0,\n\t\t\txend = wid-wrem, yend = hgt-hrem;\n\n\t\tvar bxs = [];\n\t\tfor (var y = 0; y < hgt; y += h0)\n\t\t\tfor (var x = 0; x < wid; x += w0)\n\t\t\t\tbxs.push({x:x, y:y, w:(x==xend?wrem:w0), h:(y==yend?hrem:h0)});\n\n\t\treturn bxs;\n\t}\n\n\t// iterates @bbox within a parent rect of width @wid; calls @fn, passing index within parent\n\tfunction iterBox(bbox, wid, fn) {\n\t\tvar b = bbox,\n\t\t\ti0 = b.y * wid + b.x,\n\t\t\ti1 = (b.y + b.h - 1) * wid + (b.x + b.w - 1),\n\t\t\tcnt = 0, incr = wid - b.w + 1, i = i0;\n\n\t\tdo {\n\t\t\tfn.call(this, i);\n\t\t\ti += (++cnt % b.w == 0) ? incr : 1;\n\t\t} while (i <= i1);\n\t}\n\n\t// returns array of hash keys sorted by their values\n\tfunction sortedHashKeys(obj, desc) {\n\t\tvar keys = [];\n\n\t\tfor (var key in obj)\n\t\t\tkeys.push(key);\n\n\t\treturn sort.call(keys, function(a,b) {\n\t\t\treturn desc ? obj[b] - obj[a] : obj[a] - obj[b];\n\t\t});\n\t}\n\n\t// expose\n\tthis.RgbQuant = RgbQuant;\n\n\t// expose to commonJS\n\tif (typeof module !== 'undefined' && module.exports) {\n\t\tmodule.exports = RgbQuant;\n\t}\n\n}).call(this);\n","import { BLUE_NOISE_TEXTURE } from './blue-noise-texture'\nimport { rgbToOklab } from './oklab'\nimport RgbQuant from 'rgbquant'\n\nexport type BayerSize = 2 | 4 | 8 | 16\n\nexport const BAYER_SIZES = [\n  { label: '2x2', value: 2 },\n  { label: '4x4', value: 4 },\n  { label: '8x8', value: 8 },\n  { label: '16x16', value: 16 }\n] as const\n\nfunction generateBayerIndex(size: number): number[][] {\n  if (size === 2) return [[0, 2], [3, 1]]\n  const half = size / 2\n  const sub = generateBayerIndex(half)\n  const m: number[][] = Array.from({ length: size }, () => new Array(size))\n  for (let si = 0; si < half; si++) {\n    for (let sj = 0; sj < half; sj++) {\n      const v = sub[si]![sj]! * 4\n      m[si]![sj] = v\n      m[si]![half + sj] = v + 2\n      m[half + si]![sj] = v + 3\n      m[half + si]![half + sj] = v + 1\n    }\n  }\n  return m\n}\n\nfunction toBayerThresholds(m: number[][]): number[][] {\n  const n = m.length * m.length\n  return m.map(row => row.map(v => Math.floor((v + 0.5) / n * 256)))\n}\n\nexport const BAYER_MATRICES: Record<BayerSize, number[][]> = {\n  2: toBayerThresholds(generateBayerIndex(2)),\n  4: toBayerThresholds(generateBayerIndex(4)),\n  8: toBayerThresholds(generateBayerIndex(8)),\n  16: toBayerThresholds(generateBayerIndex(16))\n}\n\n// Error diffusion kernels: each entry is [weight, dx, dy]\nexport const DIFFUSION_KERNELS: Record<string, Array<[number, number, number]>> = {\n  FloydSteinberg: [[7 / 16, 1, 0], [3 / 16, -1, 1], [5 / 16, 0, 1], [1 / 16, 1, 1]],\n  Atkinson: [[1 / 8, 1, 0], [1 / 8, 2, 0], [1 / 8, -1, 1], [1 / 8, 0, 1], [1 / 8, 1, 1], [1 / 8, 0, 2]],\n  JarvisJudiceNinke: [[7 / 48, 1, 0], [5 / 48, 2, 0], [3 / 48, -2, 1], [5 / 48, -1, 1], [7 / 48, 0, 1], [5 / 48, 1, 1], [3 / 48, 2, 1], [1 / 48, -2, 2], [3 / 48, -1, 2], [5 / 48, 0, 2], [3 / 48, 1, 2], [1 / 48, 2, 2]],\n  Stucki: [[8 / 42, 1, 0], [4 / 42, 2, 0], [2 / 42, -2, 1], [4 / 42, -1, 1], [8 / 42, 0, 1], [4 / 42, 1, 1], [2 / 42, 2, 1], [1 / 42, -2, 2], [2 / 42, -1, 2], [4 / 42, 0, 2], [2 / 42, 1, 2], [1 / 42, 2, 2]],\n  Burkes: [[8 / 32, 1, 0], [4 / 32, 2, 0], [2 / 32, -2, 1], [4 / 32, -1, 1], [8 / 32, 0, 1], [4 / 32, 1, 1], [2 / 32, 2, 1]],\n  Sierra3: [[5 / 32, 1, 0], [3 / 32, 2, 0], [2 / 32, -2, 1], [4 / 32, -1, 1], [5 / 32, 0, 1], [4 / 32, 1, 1], [2 / 32, 2, 1], [2 / 32, -1, 2], [3 / 32, 0, 2], [2 / 32, 1, 2]],\n  Sierra2: [[4 / 16, 1, 0], [3 / 16, 2, 0], [1 / 16, -2, 1], [2 / 16, -1, 1], [3 / 16, 0, 1], [2 / 16, 1, 1], [1 / 16, 2, 1]],\n  Sierra24A: [[2 / 4, 1, 0], [1 / 4, -1, 1], [1 / 4, 0, 1]],\n  Fan: [[7 / 16, 1, 0], [1 / 16, -2, 1], [3 / 16, -1, 1], [5 / 16, 0, 1]],\n  ShiauFan: [[4 / 8, 1, 0], [1 / 8, -2, 1], [1 / 8, -1, 1], [2 / 8, 0, 1]],\n  ShiauFan2: [[7 / 14, 1, 0], [1 / 14, -3, 1], [1 / 14, -2, 1], [2 / 14, -1, 1], [3 / 14, 0, 1]]\n}\n\nexport function getClosestColor(colors: number[][], [r2, g2, b2]: number[]): number[] {\n  let minDist = Infinity\n  let closest = colors[0]\n  for (let i = 0; i < colors.length; i++) {\n    const [, r1, g1, b1] = colors[i]\n    const dist = (r2 - r1) ** 2 + (g2 - g1) ** 2 + (b2 - b1) ** 2\n    if (dist < minDist) {\n      minDist = dist\n      closest = colors[i]\n    }\n  }\n  return closest\n}\n\nexport function rgbQuantDiffusionDither(\n  ctx: CanvasRenderingContext2D,\n  imageData: ImageData,\n  palette: number[][],\n  blockSize: number,\n  kernelName: string,\n  serpentine: boolean,\n  smoothDownscale = false\n) {\n  const q = new RgbQuant({\n    colors: palette.length || 8,\n    method: 2,\n    boxSize: [8, 8],\n    boxPxls: 2,\n    initColors: 4096,\n    minHueCols: 2000,\n    dithKern: kernelName,\n    dithDelta: 0,\n    dithSerp: serpentine,\n    palette,\n    reIndex: false,\n    useCache: true,\n    cacheFreq: 10,\n    colorDist: 'euclidean'\n  })\n\n  q.sample(imageData)\n  imageData.data.set(q.reduce(imageData, 1, kernelName, serpentine))\n  ctx.putImageData(imageData, 0, 0)\n\n  if (blockSize > 1) {\n    addPixelation(ctx, ctx.canvas, imageData.width, imageData.height, blockSize, smoothDownscale)\n  }\n}\n\nexport function addPixelation(\n  ctx: CanvasRenderingContext2D,\n  sourceCanvas: HTMLCanvasElement,\n  width: number,\n  height: number,\n  blockSize: number,\n  smoothDownscale = false\n) {\n  const tempCanvas = document.createElement('canvas')\n  const tempCtx = tempCanvas.getContext('2d')!\n  tempCanvas.width = width / blockSize\n  tempCanvas.height = height / blockSize\n\n  tempCtx.imageSmoothingEnabled = smoothDownscale\n  tempCtx.drawImage(sourceCanvas, 0, 0, tempCanvas.width, tempCanvas.height)\n\n  ctx.imageSmoothingEnabled = false\n  ctx.drawImage(\n    tempCanvas,\n    0,\n    0,\n    tempCanvas.width,\n    tempCanvas.height,\n    0,\n    0,\n    width,\n    height\n  )\n}\n\nexport function bayerDither(\n  ctx: CanvasRenderingContext2D,\n  imageData: ImageData,\n  palette: number[][],\n  blockSize: number,\n  bayerSize: BayerSize = 4,\n  smoothDownscale = false\n) {\n  const matrix = BAYER_MATRICES[bayerSize]\n  const size = bayerSize\n\n  const imageDataLength = imageData.data.length\n  const w = imageData.width\n\n  const newPalette = palette.map((color, id) => [id, ...color])\n\n  for (let currentPixel = 0; currentPixel <= imageDataLength - 4; currentPixel += 4) {\n    const x = (currentPixel / 4) % w\n    const y = Math.floor(currentPixel / 4 / w)\n\n    const threshold = matrix[y % size]![x % size]!\n\n    const map = Math.max(0, Math.min(255, imageData.data[currentPixel]! + 128 - threshold))\n    const map2 = Math.max(0, Math.min(255, imageData.data[currentPixel + 1]! + 128 - threshold))\n    const map3 = Math.max(0, Math.min(255, imageData.data[currentPixel + 2]! + 128 - threshold))\n\n    const closestColor = getClosestColor(newPalette, [map, map2, map3])\n\n    imageData.data[currentPixel] = closestColor[1]!\n    imageData.data[currentPixel + 1] = closestColor[2]!\n    imageData.data[currentPixel + 2] = closestColor[3]!\n  }\n\n  ctx.putImageData(imageData, 0, 0)\n\n  if (blockSize > 1) {\n    addPixelation(ctx, ctx.canvas, imageData.width, imageData.height, blockSize, smoothDownscale)\n  }\n}\n\n// Kernel-based error diffusion dither. Used for OKLab mode (RGB mode uses q.reduce()).\nexport function kernelDiffusionDither(\n  ctx: CanvasRenderingContext2D,\n  imageData: ImageData,\n  palette: number[][],\n  blockSize: number,\n  kernelName: string,\n  serpentine: boolean,\n  colorSpace: 'rgb' | 'oklab',\n  smoothDownscale = false\n) {\n  const { width, height } = imageData\n  const data = imageData.data\n  const kernel = DIFFUSION_KERNELS[kernelName] ?? DIFFUSION_KERNELS['FloydSteinberg']!\n\n  if (colorSpace === 'oklab') {\n    const paletteOklab = palette.map(([r, g, b]) => rgbToOklab(r!, g!, b!))\n\n    const errL = new Float64Array(width * height)\n    const errA = new Float64Array(width * height)\n    const errB = new Float64Array(width * height)\n\n    for (let y = 0; y < height; y++) {\n      const forward = !serpentine || y % 2 === 0\n      const xStart = forward ? 0 : width - 1\n      const xEnd = forward ? width : -1\n      const xStep = forward ? 1 : -1\n\n      for (let x = xStart; x !== xEnd; x += xStep) {\n        const i = (y * width + x) * 4\n        const idx = y * width + x\n\n        const [pixL, pixA, pixB] = rgbToOklab(data[i]!, data[i + 1]!, data[i + 2]!)\n        const rawL = pixL + errL[idx]!\n        const rawA = pixA + errA[idx]!\n        const rawB = pixB + errB[idx]!\n\n        let minDist = Infinity\n        let closestIdx = 0\n        for (let p = 0; p < paletteOklab.length; p++) {\n          const [pL, pA, pB] = paletteOklab[p]!\n          const dL = rawL - pL!\n          const dA = rawA - pA!\n          const dB = rawB - pB!\n          const dist = dL * dL + dA * dA + dB * dB\n          if (dist < minDist) {\n            minDist = dist\n            closestIdx = p\n          }\n        }\n\n        const chosen = palette[closestIdx]!\n        data[i] = chosen[0]!\n        data[i + 1] = chosen[1]!\n        data[i + 2] = chosen[2]!\n\n        const [chosenL, chosenA, chosenBlab] = paletteOklab[closestIdx]!\n        const eL = rawL - chosenL!\n        const eA = rawA - chosenA!\n        const eB = rawB - chosenBlab!\n\n        for (const [weight, kdx, kdy] of kernel) {\n          const nx = x + (forward ? kdx : -kdx)\n          const ny = y + kdy\n          if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue\n          const nidx = ny * width + nx\n          errL[nidx]! += eL * weight\n          errA[nidx]! += eA * weight\n          errB[nidx]! += eB * weight\n        }\n      }\n    }\n  } else {\n    // RGB branch: Rec. 709 perceptual nearest-color, float error buffers\n    const errR = new Float64Array(width * height)\n    const errG = new Float64Array(width * height)\n    const errBuf = new Float64Array(width * height)\n\n    for (let y = 0; y < height; y++) {\n      const forward = !serpentine || y % 2 === 0\n      const xStart = forward ? 0 : width - 1\n      const xEnd = forward ? width : -1\n      const xStep = forward ? 1 : -1\n\n      for (let x = xStart; x !== xEnd; x += xStep) {\n        const i = (y * width + x) * 4\n        const idx = y * width + x\n\n        const rawR = data[i]! + errR[idx]!\n        const rawG = data[i + 1]! + errG[idx]!\n        const rawB = data[i + 2]! + errBuf[idx]!\n\n        const adjR = Math.max(0, Math.min(255, rawR))\n        const adjG = Math.max(0, Math.min(255, rawG))\n        const adjB = Math.max(0, Math.min(255, rawB))\n\n        let minDist = Infinity\n        let closestIdx = 0\n        for (let p = 0; p < palette.length; p++) {\n          const [pr, pg, pb] = palette[p]!\n          const dr = adjR - pr!\n          const dg = adjG - pg!\n          const db = adjB - pb!\n          const dist = 0.2126 * dr * dr + 0.7152 * dg * dg + 0.0722 * db * db\n          if (dist < minDist) {\n            minDist = dist\n            closestIdx = p\n          }\n        }\n\n        const chosen = palette[closestIdx]!\n        data[i] = chosen[0]!\n        data[i + 1] = chosen[1]!\n        data[i + 2] = chosen[2]!\n\n        const eR = rawR - chosen[0]!\n        const eG = rawG - chosen[1]!\n        const eB = rawB - chosen[2]!\n\n        for (const [weight, kdx, kdy] of kernel) {\n          const nx = x + (forward ? kdx : -kdx)\n          const ny = y + kdy\n          if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue\n          const nidx = ny * width + nx\n          errR[nidx]! += eR * weight\n          errG[nidx]! += eG * weight\n          errBuf[nidx]! += eB * weight\n        }\n      }\n    }\n  }\n\n  ctx.putImageData(imageData, 0, 0)\n\n  if (blockSize > 1) {\n    addPixelation(ctx, ctx.canvas, width, height, blockSize, smoothDownscale)\n  }\n}\n\nexport function simple2DDither(\n  ctx: CanvasRenderingContext2D,\n  imageData: ImageData,\n  palette: number[][],\n  blockSize: number,\n  colorSpace: 'rgb' | 'oklab' = 'rgb',\n  smoothDownscale = false\n) {\n  const { width, height } = imageData\n  const data = imageData.data\n\n  if (colorSpace === 'oklab') {\n    const paletteOklab = palette.map(([r, g, b]) => rgbToOklab(r!, g!, b!))\n\n    const errL = new Float64Array(width * height)\n    const errA = new Float64Array(width * height)\n    const errB = new Float64Array(width * height)\n\n    for (let y = 0; y < height; y++) {\n      for (let x = 0; x < width; x++) {\n        const i = (y * width + x) * 4\n        const idx = y * width + x\n\n        const [pixL, pixA, pixB] = rgbToOklab(data[i]!, data[i + 1]!, data[i + 2]!)\n        const rawL = pixL + errL[idx]!\n        const rawA = pixA + errA[idx]!\n        const rawB = pixB + errB[idx]!\n\n        let minDist = Infinity\n        let closestIdx = 0\n        for (let p = 0; p < paletteOklab.length; p++) {\n          const [pL, pA, pB] = paletteOklab[p]!\n          const dL = rawL - pL!\n          const dA = rawA - pA!\n          const dB = rawB - pB!\n          const dist = dL * dL + dA * dA + dB * dB\n          if (dist < minDist) {\n            minDist = dist\n            closestIdx = p\n          }\n        }\n\n        const chosen = palette[closestIdx]!\n        data[i] = chosen[0]!\n        data[i + 1] = chosen[1]!\n        data[i + 2] = chosen[2]!\n\n        const [chosenL, chosenA, chosenBlab] = paletteOklab[closestIdx]!\n        const eL = rawL - chosenL!\n        const eA = rawA - chosenA!\n        const eB = rawB - chosenBlab!\n\n        if (x + 1 < width) {\n          errL[idx + 1]! += eL * 0.5\n          errA[idx + 1]! += eA * 0.5\n          errB[idx + 1]! += eB * 0.5\n        }\n        if (y + 1 < height) {\n          errL[idx + width]! += eL * 0.5\n          errA[idx + width]! += eA * 0.5\n          errB[idx + width]! += eB * 0.5\n        }\n      }\n    }\n  } else {\n    // RGB branch — float error buffers, clamping bug fixed (error from unclamped raw value)\n    const newPalette = palette.map((color, id) => [id, ...color])\n\n    const errR = new Float64Array(width * height)\n    const errG = new Float64Array(width * height)\n    const errB = new Float64Array(width * height)\n\n    for (let y = 0; y < height; y++) {\n      for (let x = 0; x < width; x++) {\n        const i = (y * width + x) * 4\n        const idx = y * width + x\n\n        const rawR = data[i]! + errR[idx]!\n        const rawG = data[i + 1]! + errG[idx]!\n        const rawB = data[i + 2]! + errB[idx]!\n\n        const adjR = Math.max(0, Math.min(255, rawR))\n        const adjG = Math.max(0, Math.min(255, rawG))\n        const adjB = Math.max(0, Math.min(255, rawB))\n\n        const closest = getClosestColor(newPalette, [adjR, adjG, adjB])\n        const chosenR = closest[1]!\n        const chosenG = closest[2]!\n        const chosenB = closest[3]!\n\n        data[i] = chosenR\n        data[i + 1] = chosenG\n        data[i + 2] = chosenB\n\n        const eR = rawR - chosenR\n        const eG = rawG - chosenG\n        const eB = rawB - chosenB\n\n        if (x + 1 < width) {\n          errR[idx + 1]! += eR * 0.5\n          errG[idx + 1]! += eG * 0.5\n          errB[idx + 1]! += eB * 0.5\n        }\n        if (y + 1 < height) {\n          errR[idx + width]! += eR * 0.5\n          errG[idx + width]! += eG * 0.5\n          errB[idx + width]! += eB * 0.5\n        }\n      }\n    }\n  }\n\n  ctx.putImageData(imageData, 0, 0)\n\n  if (blockSize > 1) {\n    addPixelation(ctx, ctx.canvas, width, height, blockSize, smoothDownscale)\n  }\n}\n\nfunction nextPowerOfTwo(n: number): number {\n  let p = 1; while (p < n) p <<= 1; return p\n}\n\nexport function hilbertD2XY(n: number, d: number): [number, number] {\n  let rx: number, ry: number, t = d, x = 0, y = 0\n  for (let s = 1; s < n; s *= 2) {\n    rx = 1 & Math.floor(t / 2)\n    ry = 1 & (t ^ rx)\n    if (ry === 0) {\n      if (rx === 1) { x = s - 1 - x; y = s - 1 - y }\n      const tmp = x; x = y; y = tmp\n    }\n    x += s * rx; y += s * ry; t = Math.floor(t / 4)\n  }\n  return [x, y]\n}\n\nexport function blueNoiseDither(\n  ctx: CanvasRenderingContext2D,\n  imageData: ImageData,\n  palette: number[][],\n  blockSize: number,\n  smoothDownscale = false\n) {\n  const imageDataLength = imageData.data.length\n  const w = imageData.width\n\n  const newPalette = palette.map((color, id) => [id, ...color])\n  const colorCache = new Map<number, number[]>()\n\n  for (let currentPixel = 0; currentPixel <= imageDataLength - 4; currentPixel += 4) {\n    const x = (currentPixel / 4) % w\n    const y = Math.floor(currentPixel / 4 / w)\n\n    const threshold = BLUE_NOISE_TEXTURE[(y % 64) * 64 + (x % 64)]!\n\n    const r = Math.max(0, Math.min(255, imageData.data[currentPixel]! + 128 - threshold))\n    const g = Math.max(0, Math.min(255, imageData.data[currentPixel + 1]! + 128 - threshold))\n    const b = Math.max(0, Math.min(255, imageData.data[currentPixel + 2]! + 128 - threshold))\n\n    const key = (r << 16) | (g << 8) | b\n    let closest = colorCache.get(key)\n    if (!closest) {\n      closest = getClosestColor(newPalette, [r, g, b])\n      colorCache.set(key, closest)\n    }\n\n    imageData.data[currentPixel] = closest[1]!\n    imageData.data[currentPixel + 1] = closest[2]!\n    imageData.data[currentPixel + 2] = closest[3]!\n  }\n\n  ctx.putImageData(imageData, 0, 0)\n\n  if (blockSize > 1) {\n    addPixelation(ctx, ctx.canvas, imageData.width, imageData.height, blockSize, smoothDownscale)\n  }\n}\n\nexport function riemersmaDither(\n  ctx: CanvasRenderingContext2D,\n  imageData: ImageData,\n  palette: number[][],\n  blockSize: number,\n  colorSpace: 'rgb' | 'oklab' = 'rgb',\n  smoothDownscale = false\n) {\n  const { width, height } = imageData\n  const data = imageData.data\n\n  const N = 32\n  const r = 1 / 8\n  const weights: number[] = []\n  for (let i = 0; i < N; i++) {\n    weights.push(Math.pow(r, i / (N - 1)))\n  }\n\n  const errorBuf: Float64Array = new Float64Array(N * 3)\n  let bufHead = 0\n\n  const side = nextPowerOfTwo(Math.max(width, height))\n\n  if (colorSpace === 'oklab') {\n    const paletteOklab = palette.map(([r, g, b]) => rgbToOklab(r!, g!, b!))\n\n    for (let d = 0; d < side * side; d++) {\n      const [x, y] = hilbertD2XY(side, d)\n      if (x >= width || y >= height) continue\n\n      const i = (y * width + x) * 4\n\n      let eL = 0, eA = 0, eB = 0\n      for (let k = 0; k < N; k++) {\n        const slot = ((bufHead - 1 - k) % N + N) % N\n        eL += weights[k]! * errorBuf[slot * 3]!\n        eA += weights[k]! * errorBuf[slot * 3 + 1]!\n        eB += weights[k]! * errorBuf[slot * 3 + 2]!\n      }\n\n      const [pixL, pixA, pixB] = rgbToOklab(data[i]!, data[i + 1]!, data[i + 2]!)\n      const rawL = pixL + eL\n      const rawA = pixA + eA\n      const rawB = pixB + eB\n\n      let minDist = Infinity\n      let closestIdx = 0\n      for (let p = 0; p < paletteOklab.length; p++) {\n        const [pL, pA, pB] = paletteOklab[p]!\n        const dL = rawL - pL!\n        const dA = rawA - pA!\n        const dB = rawB - pB!\n        const dist = dL * dL + dA * dA + dB * dB\n        if (dist < minDist) {\n          minDist = dist\n          closestIdx = p\n        }\n      }\n\n      const chosen = palette[closestIdx]!\n      data[i] = chosen[0]!\n      data[i + 1] = chosen[1]!\n      data[i + 2] = chosen[2]!\n\n      // Store orig (not raw) minus chosen — raw includes accumulated error which\n      // would create a feedback loop with w_0 = 1 in the weighted sum\n      const [chosenL, chosenA, chosenBlab] = paletteOklab[closestIdx]!\n      errorBuf[bufHead * 3] = pixL - chosenL!\n      errorBuf[bufHead * 3 + 1] = pixA - chosenA!\n      errorBuf[bufHead * 3 + 2] = pixB - chosenBlab!\n      bufHead = (bufHead + 1) % N\n    }\n  } else {\n    const newPalette = palette.map((color, id) => [id, ...color])\n\n    for (let d = 0; d < side * side; d++) {\n      const [x, y] = hilbertD2XY(side, d)\n      if (x >= width || y >= height) continue\n\n      const i = (y * width + x) * 4\n\n      let eR = 0, eG = 0, eB = 0\n      for (let k = 0; k < N; k++) {\n        const slot = ((bufHead - 1 - k) % N + N) % N\n        eR += weights[k]! * errorBuf[slot * 3]!\n        eG += weights[k]! * errorBuf[slot * 3 + 1]!\n        eB += weights[k]! * errorBuf[slot * 3 + 2]!\n      }\n\n      const origR = data[i]!\n      const origG = data[i + 1]!\n      const origB = data[i + 2]!\n\n      const adjR = Math.max(0, Math.min(255, origR + eR))\n      const adjG = Math.max(0, Math.min(255, origG + eG))\n      const adjB = Math.max(0, Math.min(255, origB + eB))\n\n      const closest = getClosestColor(newPalette, [adjR, adjG, adjB])\n      const chosenR = closest[1]!\n      const chosenG = closest[2]!\n      const chosenB = closest[3]!\n\n      data[i] = chosenR\n      data[i + 1] = chosenG\n      data[i + 2] = chosenB\n\n      // Store orig (not raw) minus chosen — including accumulated error in the\n      // stored value would create a feedback loop with w_0 = 1\n      errorBuf[bufHead * 3] = origR - chosenR\n      errorBuf[bufHead * 3 + 1] = origG - chosenG\n      errorBuf[bufHead * 3 + 2] = origB - chosenB\n      bufHead = (bufHead + 1) % N\n    }\n  }\n\n  ctx.putImageData(imageData, 0, 0)\n\n  if (blockSize > 1) {\n    addPixelation(ctx, ctx.canvas, width, height, blockSize, smoothDownscale)\n  }\n}\n","import type {\n  AdjustmentPreviewOptions,\n  DitherImageOptions,\n  ImageDataLike,\n} from \"./dither\";\n\nconst DEFAULT_FAST_PREVIEW_MAX_PIXELS = 786_432;\nconst DEFAULT_FAST_PREVIEW_MAX_LONG_EDGE = 1280;\nconst AUTO_WORKER_MIN_PIXELS = 350_000;\n\nconst normalizePreviewOptions = (\n  preview: AdjustmentPreviewOptions | undefined,\n  defaultMode: \"fast\" | \"final\"\n): Required<AdjustmentPreviewOptions> => {\n  const mode = preview?.mode ?? defaultMode;\n  return {\n    mode,\n    maxPixels:\n      preview?.maxPixels ??\n      (mode === \"final\" ? Infinity : DEFAULT_FAST_PREVIEW_MAX_PIXELS),\n    maxLongEdge:\n      preview?.maxLongEdge ??\n      (mode === \"final\" ? Infinity : DEFAULT_FAST_PREVIEW_MAX_LONG_EDGE),\n  };\n};\n\nconst getPreviewDimensions = (\n  width: number,\n  height: number,\n  preview: Required<AdjustmentPreviewOptions>\n) => {\n  if (preview.mode === \"final\") return { width, height };\n\n  let scale = 1;\n  const longEdge = Math.max(width, height);\n  if (Number.isFinite(preview.maxLongEdge) && longEdge > preview.maxLongEdge) {\n    scale = Math.min(scale, preview.maxLongEdge / longEdge);\n  }\n\n  const pixels = width * height;\n  if (Number.isFinite(preview.maxPixels) && pixels > preview.maxPixels) {\n    scale = Math.min(scale, Math.sqrt(preview.maxPixels / pixels));\n  }\n\n  return {\n    width: Math.max(1, Math.round(width * scale)),\n    height: Math.max(1, Math.round(height * scale)),\n  };\n};\n\nconst createImageDataLike = (\n  data: Uint8ClampedArray,\n  width: number,\n  height: number\n): ImageDataLike => {\n  const ImageDataCtor = globalThis.ImageData;\n  return typeof ImageDataCtor === \"function\"\n    ? new ImageDataCtor(data, width, height)\n    : { data, width, height };\n};\n\nconst resizeImageDataNearest = (\n  image: ImageDataLike,\n  width: number,\n  height: number\n) => {\n  if (width === image.width && height === image.height) return image;\n\n  const source = image.data;\n  const output = new Uint8ClampedArray(width * height * 4);\n  const xRatio = image.width / width;\n  const yRatio = image.height / height;\n\n  for (let y = 0; y < height; y += 1) {\n    const sourceY = Math.min(image.height - 1, Math.floor(y * yRatio));\n    for (let x = 0; x < width; x += 1) {\n      const sourceX = Math.min(image.width - 1, Math.floor(x * xRatio));\n      const sourceIndex = (sourceY * image.width + sourceX) * 4;\n      const outputIndex = (y * width + x) * 4;\n      output[outputIndex] = source[sourceIndex];\n      output[outputIndex + 1] = source[sourceIndex + 1];\n      output[outputIndex + 2] = source[sourceIndex + 2];\n      output[outputIndex + 3] = source[sourceIndex + 3];\n    }\n  }\n\n  return createImageDataLike(output, width, height);\n};\n\nexport const getPreviewImageData = (\n  image: ImageDataLike,\n  previewOptions: AdjustmentPreviewOptions | undefined,\n  defaultMode: \"fast\" | \"final\"\n) => {\n  const preview = normalizePreviewOptions(previewOptions, defaultMode);\n  const dimensions = getPreviewDimensions(image.width, image.height, preview);\n  return resizeImageDataNearest(image, dimensions.width, dimensions.height);\n};\n\ninterface AdjustmentWorkerRequest {\n  id: number;\n  imageData: ImageDataLike;\n  options: DitherImageOptions;\n}\n\ninterface AdjustmentWorkerResponse {\n  id: number;\n  imageData?: ImageDataLike;\n  error?: string;\n}\n\nlet adjustmentWorker: Worker | null | undefined;\nlet adjustmentWorkerNextId = 1;\nconst adjustmentWorkerCallbacks = new Map<\n  number,\n  {\n    resolve(imageData: ImageDataLike): void;\n    reject(error: Error): void;\n  }\n>();\n\nconst getAdjustmentWorker = () => {\n  if (typeof Worker === \"undefined\") return null;\n  if (adjustmentWorker !== undefined) return adjustmentWorker;\n\n  try {\n    adjustmentWorker = new Worker(\n      new URL(\"./adjustment-worker.ts\", import.meta.url),\n      { type: \"module\" }\n    );\n    adjustmentWorker.addEventListener(\n      \"message\",\n      (event: MessageEvent<AdjustmentWorkerResponse>) => {\n        const callback = adjustmentWorkerCallbacks.get(event.data.id);\n        if (!callback) return;\n\n        adjustmentWorkerCallbacks.delete(event.data.id);\n        if (event.data.error) {\n          callback.reject(new Error(event.data.error));\n          return;\n        }\n        if (!event.data.imageData) {\n          callback.reject(new Error(\"Adjustment worker returned no image data.\"));\n          return;\n        }\n\n        callback.resolve(event.data.imageData);\n      }\n    );\n    adjustmentWorker.addEventListener(\"error\", () => {\n      for (const callback of adjustmentWorkerCallbacks.values()) {\n        callback.reject(new Error(\"Adjustment worker failed.\"));\n      }\n      adjustmentWorkerCallbacks.clear();\n      adjustmentWorker?.terminate();\n      adjustmentWorker = null;\n    });\n  } catch {\n    adjustmentWorker = null;\n  }\n\n  return adjustmentWorker;\n};\n\nexport const shouldUseAdjustmentWorker = (\n  options: Pick<DitherImageOptions, \"adjustmentEngine\">,\n  image: ImageDataLike\n) => {\n  const engine = options.adjustmentEngine;\n  if (engine === \"js\" || engine === \"wasm\") return false;\n  if (engine === \"worker\") return getAdjustmentWorker() !== null;\n  return (\n    image.width * image.height >= AUTO_WORKER_MIN_PIXELS &&\n    getAdjustmentWorker() !== null\n  );\n};\n\nexport const applyImageDataAdjustmentsInWorker = (\n  image: ImageDataLike,\n  opts: DitherImageOptions\n) =>\n  new Promise<ImageDataLike>((resolve, reject) => {\n    const worker = getAdjustmentWorker();\n    if (!worker) {\n      reject(new Error(\"Adjustment worker is not available.\"));\n      return;\n    }\n\n    const id = adjustmentWorkerNextId++;\n    adjustmentWorkerCallbacks.set(id, { resolve, reject });\n    const request: AdjustmentWorkerRequest = {\n      id,\n      imageData: image,\n      options: {\n        ...opts,\n        adjustmentEngine: \"js\",\n      },\n    };\n\n    try {\n      worker.postMessage(request, [image.data.buffer as ArrayBuffer]);\n    } catch (error) {\n      adjustmentWorkerCallbacks.delete(id);\n      reject(error instanceof Error ? error : new Error(\"Worker transfer failed.\"));\n    }\n  });\n\nexport const waitForAdjustmentTurn = () =>\n  new Promise<void>((resolve) => {\n    if (typeof setTimeout === \"function\") {\n      setTimeout(resolve, 0);\n    } else {\n      resolve();\n    }\n  });\n","import palettes from \"./data/default-palettes.json\";\nimport diffusionMaps from \"./data/diffusion-maps\";\n//import thresholdMaps from \"./data/threshold-maps.json\";\n\n/* Functions */\nimport bayerMatrix from \"./functions/bayer-matrix\";\nimport colorHelpers from \"./functions/color-helpers\";\n// import colorPaletteFromImage from \"./functions/color-palette-from-image\";\nimport utilities from \"./functions/utilities\";\nimport findClosestPaletteColor from \"./functions/find-closest-palette-color\";\nimport { applyWasmRgbErrorDiffusion } from \"./wasm-error-diffusion-rgb\";\nimport {\n  bayerDither,\n  blueNoiseDither,\n  kernelDiffusionDither,\n  riemersmaDither,\n  rgbQuantDiffusionDither,\n  simple2DDither,\n  type BayerSize,\n} from \"../utils/dithering\";\nimport {\n  applyImageProcessing,\n  clampByte,\n  deltaE,\n  getProcessingPreset,\n  luma709,\n  rgbToLab,\n  type AdjustmentQuality,\n  type ClarityOptions,\n  type ColorMatchingMode,\n  type DynamicRangeCompressionOptions,\n  type ImageProcessingOptions,\n  type LevelCompressionMode,\n  type LevelCompressionOptions,\n  type LevelRGB,\n  type PaperNormalizationOptions,\n  type PercentileClip,\n  type ProcessingPreset,\n  type ProcessingPresetName,\n  type RGB,\n  type RGBA,\n  type ToneMappingMode,\n  type ToneMappingOptions,\n} from \"./processing\";\nimport {\n  getNamedColors,\n  type PaletteColorEntry,\n  type PaletteRegistry,\n} from \"./functions/palette-order\";\nimport {\n  applyImageDataAdjustmentsInWorker,\n  getPreviewImageData,\n  shouldUseAdjustmentWorker,\n  waitForAdjustmentTurn,\n} from \"./adjustment-async\";\n\nexport type DitheringType =\n  | \"errorDiffusion\"\n  | \"ordered\"\n  | \"random\"\n  | \"quantizationOnly\"\n  | \"hueMix\"\n  | \"blueNoise\"\n  | \"simple2D\"\n  | \"riemersma\"\n  | \"ditherItErrorDiffusion\"\n  | \"ditherItOrdered\"\n  | \"ditherItBlueNoise\"\n  | \"ditherItSimple2D\"\n  | \"ditherItRiemersma\"\n  | (string & {});\n\nexport type DitherProcessingEngine = \"js\" | \"wasm\" | \"auto\";\nexport type AdjustmentProcessingEngine = \"auto\" | \"js\" | \"worker\" | \"wasm\";\n\nexport interface AdjustmentPreviewOptions {\n  maxPixels?: number;\n  maxLongEdge?: number;\n  mode?: \"fast\" | \"final\";\n}\n\nexport interface DitherImageOptions {\n  /**\n   * Upstream-style processing preset. Presets fill in tone mapping, dynamic\n   * range compression, color matching, and diffusion defaults unless overridden.\n   */\n  processingPreset?: ProcessingPresetName;\n\n  /** Main dithering algorithm. */\n  ditheringType?: DitheringType;\n\n  /**\n   * Processing engine for supported hot paths.\n   *\n   * Default: \"auto\". \"wasm\" and \"auto\" currently accelerate RGB error diffusion\n   * and fall back to JS for unsupported modes.\n   */\n  processingEngine?: DitherProcessingEngine;\n\n  /**\n   * Processing engine for image adjustments.\n   *\n   * Default: \"auto\". \"worker\" and \"auto\" move supported async adjustment calls\n   * off the main thread where browser Workers are available. \"wasm\" is\n   * reserved for future adjustment kernels and currently falls back to JS.\n   */\n  adjustmentEngine?: AdjustmentProcessingEngine;\n\n  /**\n   * Preview controls for interactive editors. Final mode preserves current\n   * quality; fast mode can downscale and use cheaper adjustment paths.\n   */\n  preview?: AdjustmentPreviewOptions;\n\n  /** Error diffusion kernel (e.g. `floydSteinberg`). */\n  errorDiffusionMatrix?: string;\n\n  /**\n   * Backwards-compatible alias for `errorDiffusionMatrix`.\n   * (The README historically used `algorithm`.)\n   */\n  algorithm?: string;\n\n  serpentine?: boolean;\n\n  orderedDitheringType?: string;\n  /** Tuple preferred; `number[]` accepted for convenience. */\n  orderedDitheringMatrix?: [number, number] | number[];\n\n  randomDitheringType?: \"blackAndWhite\" | \"rgb\" | (string & {});\n\n  /** Palette name, custom hex strings, or combined palette entries. */\n  palette?: string | string[] | PaletteColorEntry[];\n\n  /** Color distance model for palette matching. */\n  colorMatching?: ColorMatchingMode;\n\n  sampleColorsFromImage?: boolean;\n  numberOfSampleColors?: number;\n\n  /** Reserved/ignored by current implementation (kept for UI compatibility). */\n  calibrate?: boolean;\n\n  /**\n   * Optional preprocessing step to remap pixel values into the display’s effective black/white limits.\n   *\n   * Default: undefined (disabled) for backwards compatibility.\n   */\n  levelCompression?: LevelCompressionOptions;\n\n  /**\n   * Exposure/saturation plus contrast or S-curve tone mapping.\n   */\n  toneMapping?: ToneMappingOptions;\n\n  /**\n   * LAB lightness compression into the calibrated display black/white range.\n   */\n  dynamicRangeCompression?: DynamicRangeCompressionOptions | boolean;\n\n  /**\n   * Selective cleanup for scanned paper/poster sources before tone mapping.\n   */\n  paperNormalization?: PaperNormalizationOptions;\n\n  /**\n   * Midtone local-contrast adjustment before tone mapping.\n   */\n  clarity?: ClarityOptions;\n\n  /**\n   * Preserve hard text/line-art edges by replacing strong edge-core pixels with\n   * direct palette quantization after the main dithering pass.\n   */\n  edgePreservation?: EdgePreservationOptions;\n\n  /**\n   * Reduce jagged teeth on antialiased full-color transitions by constraining\n   * edge-band pixels to the two local palette colors on either side of an edge.\n   */\n  edgeAntialiasing?: EdgeAntialiasingOptions;\n}\n\nexport interface EdgePreservationOptions {\n  enabled?: boolean;\n  /**\n   * 0..1. Higher values preserve more edge-core pixels.\n   */\n  strength?: number;\n  /**\n   * Luma-gradient threshold used to detect strong transitions.\n   */\n  threshold?: number;\n  /**\n   * Optional dilation radius for the protected edge core.\n   */\n  radius?: number;\n}\n\nexport interface EdgeAntialiasingOptions {\n  enabled?: boolean;\n  /**\n   * 0..1. Higher values replace more eligible edge-band pixels.\n   */\n  strength?: number;\n  /**\n   * Luma-gradient threshold used to detect antialias transition bands.\n   */\n  threshold?: number;\n  /**\n   * Edge-band dilation radius, in pixels.\n   */\n  bandRadius?: number;\n  /**\n   * Neighborhood radius used to find the two local palette colors.\n   */\n  localRadius?: number;\n}\n\nexport interface ImageDataLike {\n  width: number;\n  height: number;\n  data: Uint8ClampedArray;\n}\n\nexport interface Canvas2DContextLike {\n  getImageData(sx: number, sy: number, sw: number, sh: number): ImageDataLike;\n  putImageData(imageData: ImageDataLike, dx: number, dy: number): void;\n}\n\nexport interface CanvasLike {\n  width: number;\n  height: number;\n  getContext(contextId: \"2d\"): Canvas2DContextLike | null;\n}\n\nexport type {\n  ClarityOptions,\n  AdjustmentQuality,\n  ColorMatchingMode,\n  DynamicRangeCompressionOptions,\n  ImageProcessingOptions,\n  LevelCompressionMode,\n  LevelCompressionOptions,\n  LevelRGB,\n  PaperNormalizationOptions,\n  PercentileClip,\n  ProcessingPreset,\n  ProcessingPresetName,\n  RGB,\n  RGBA,\n  ToneMappingMode,\n  ToneMappingOptions,\n};\n\nconst defaultOptions: Required<\n  Pick<\n    DitherImageOptions,\n    | \"ditheringType\"\n    | \"errorDiffusionMatrix\"\n    | \"serpentine\"\n    | \"orderedDitheringType\"\n    | \"orderedDitheringMatrix\"\n    | \"randomDitheringType\"\n    | \"palette\"\n    | \"colorMatching\"\n    | \"processingEngine\"\n    | \"adjustmentEngine\"\n    | \"sampleColorsFromImage\"\n    | \"numberOfSampleColors\"\n  >\n> = {\n  ditheringType: \"errorDiffusion\",\n\n  errorDiffusionMatrix: \"floydSteinberg\",\n  serpentine: false,\n\n  orderedDitheringType: \"bayer\",\n  orderedDitheringMatrix: [4, 4],\n\n  randomDitheringType: \"blackAndWhite\",\n\n  palette: \"default\",\n  colorMatching: \"rgb\",\n  processingEngine: \"auto\",\n  adjustmentEngine: \"auto\",\n\n  sampleColorsFromImage: false,\n  numberOfSampleColors: 10,\n};\n\ninterface WhitePreservationPlan {\n  sourceLumas: Float64Array;\n  sourceWhiteCandidates: Uint8Array;\n  sourceWhiteLuma: number;\n  targetWhite: RGB;\n  targetWhiteLuma: number;\n}\n\nconst getBytePercentileFromHistogram = (\n  histogram: Uint32Array,\n  count: number,\n  percentile: number\n) => {\n  if (count <= 0) return 0;\n\n  const target = Math.min(\n    count - 1,\n    Math.max(0, Math.round((count - 1) * percentile))\n  );\n  let seen = 0;\n  for (let value = 0; value < histogram.length; value += 1) {\n    seen += histogram[value];\n    if (seen > target) return value;\n  }\n\n  return 255;\n};\n\nconst getPaletteWhite = (palette: RGB[]) => {\n  if (!palette.length) return [255, 255, 255] satisfies RGB;\n\n  return palette.reduce((lightest, color) =>\n    luma709(...color) > luma709(...lightest) ? color : lightest\n  );\n};\n\nconst getWhitePreservationPlan = (\n  image: ImageDataLike,\n  options: DitherImageOptions & typeof defaultOptions,\n  colorPalette: RGB[]\n): WhitePreservationPlan | null => {\n  const rangeOptions = options.dynamicRangeCompression;\n  if (\n    !rangeOptions ||\n    rangeOptions === true ||\n    rangeOptions.preserveWhite !== true\n  ) {\n    return null;\n  }\n\n  const data = image.data;\n  const pixelCount = Math.floor(data.length / 4);\n  if (pixelCount <= 0) return null;\n\n  const sourceLumas = new Float64Array(pixelCount);\n  const sourceWhiteCandidates = new Uint8Array(pixelCount);\n  const whiteCandidateHistogram = new Uint32Array(256);\n  let visibleLumaCount = 0;\n  let whiteCandidateCount = 0;\n  const maxWhiteSaturation = Math.min(\n    1,\n    Math.max(0, rangeOptions.whitePreserveMaxSaturation ?? 0.18)\n  );\n\n  for (let i = 0, pixelIndex = 0; i < data.length; i += 4, pixelIndex++) {\n    if (data[i + 3] <= 16) {\n      sourceLumas[pixelIndex] = -1;\n      continue;\n    }\n\n    const r = data[i];\n    const g = data[i + 1];\n    const b = data[i + 2];\n    const luma = luma709(r, g, b);\n    sourceLumas[pixelIndex] = luma;\n    visibleLumaCount += 1;\n\n    if (getSaturationFromChannels(r, g, b) <= maxWhiteSaturation) {\n      sourceWhiteCandidates[pixelIndex] = 1;\n      whiteCandidateHistogram[clampByte(luma)] += 1;\n      whiteCandidateCount += 1;\n    }\n  }\n\n  if (visibleLumaCount === 0 || whiteCandidateCount === 0) return null;\n\n  const sourceWhiteLuma = getBytePercentileFromHistogram(\n    whiteCandidateHistogram,\n    whiteCandidateCount,\n    rangeOptions.whitePreservePercentile ?? 0.99\n  );\n  if (sourceWhiteLuma < (rangeOptions.whitePreserveMinLuma ?? 150)) {\n    return null;\n  }\n\n  const targetWhite = getPaletteWhite(colorPalette);\n  return {\n    sourceLumas,\n    sourceWhiteCandidates,\n    sourceWhiteLuma,\n    targetWhite,\n    targetWhiteLuma: luma709(...targetWhite),\n  };\n};\n\nconst applyWhitePreservation = (\n  image: ImageDataLike,\n  plan: WhitePreservationPlan | null\n) => {\n  if (!plan) return;\n\n  const data = image.data;\n  const [whiteR, whiteG, whiteB] = plan.targetWhite;\n  for (let i = 0, pixelIndex = 0; i < data.length; i += 4, pixelIndex++) {\n    if (plan.sourceWhiteCandidates[pixelIndex] !== 1) {\n      continue;\n    }\n    if (plan.sourceLumas[pixelIndex] + 0.0001 < plan.sourceWhiteLuma) {\n      continue;\n    }\n    if (luma709(data[i], data[i + 1], data[i + 2]) >= plan.targetWhiteLuma) {\n      continue;\n    }\n\n    data[i] = whiteR;\n    data[i + 1] = whiteG;\n    data[i + 2] = whiteB;\n  }\n};\n\nconst mergeImageProcessingOptions = (\n  options: DitherImageOptions & typeof defaultOptions\n): ImageProcessingOptions | undefined => {\n  const hasToneMapping = options.toneMapping !== undefined;\n  const hasLevelCompression = options.levelCompression !== undefined;\n  const hasClarity = options.clarity !== undefined;\n  const hasPaperNormalization = options.paperNormalization !== undefined;\n  const hasDynamicRangeCompression =\n    options.dynamicRangeCompression !== undefined;\n\n  if (\n    !hasPaperNormalization &&\n    !hasClarity &&\n    !hasToneMapping &&\n    !hasLevelCompression &&\n    !hasDynamicRangeCompression\n  ) {\n    return undefined;\n  }\n\n  const previewMode = options.preview?.mode ?? \"final\";\n  const dynamicRangeCompression =\n    previewMode === \"fast\" &&\n    options.dynamicRangeCompression &&\n    options.dynamicRangeCompression !== true\n      ? {\n          ...options.dynamicRangeCompression,\n          quality: options.dynamicRangeCompression.quality ?? \"fast\",\n        }\n      : options.dynamicRangeCompression;\n\n  return {\n    paperNormalization: options.paperNormalization,\n    clarity: options.clarity,\n    toneMapping: options.toneMapping,\n    dynamicRangeCompression,\n    levelCompression: options.levelCompression,\n    previewMode,\n  };\n};\n\nconst getPresetDefaults = (presetName: ProcessingPresetName | undefined) => {\n  if (!presetName) return {};\n  const preset = getProcessingPreset(presetName);\n  if (!preset) return {};\n\n  return {\n    paperNormalization: preset.paperNormalization,\n    toneMapping: preset.toneMapping,\n    dynamicRangeCompression: preset.dynamicRangeCompression,\n    colorMatching: preset.colorMatching,\n    errorDiffusionMatrix: preset.errorDiffusionMatrix,\n  } satisfies Partial<DitherImageOptions>;\n};\n\nconst getResolvedDitherOptions = (opts: DitherImageOptions = {}) => {\n  const options: DitherImageOptions & typeof defaultOptions = {\n    ...defaultOptions,\n    ...getPresetDefaults(opts.processingPreset),\n    ...opts,\n  };\n\n  // Backwards-compatible alias (README historically used `algorithm`).\n  if (opts.algorithm && !opts.errorDiffusionMatrix) {\n    options.errorDiffusionMatrix = opts.algorithm;\n  }\n\n  return options;\n};\n\nconst getCanvasImageData = (sourceCanvas: CanvasLike) => {\n  const ctx = sourceCanvas.getContext(\"2d\");\n  if (!ctx) return null;\n  return ctx.getImageData(0, 0, sourceCanvas.width, sourceCanvas.height);\n};\n\nconst getColorPaletteFromOptions = (\n  options: DitherImageOptions & typeof defaultOptions\n) => {\n  if (!options.palette || options.sampleColorsFromImage === true) {\n    // return colorPaletteFromImage(image, options.numberOfSampleColors);\n    return [];\n  }\n\n  return setColorPalette(options.palette);\n};\n\nconst applyImageAdjustmentsToImageData = (\n  image: ImageDataLike,\n  options: DitherImageOptions & typeof defaultOptions,\n  colorPalette: RGB[]\n) => {\n  const whitePreservationPlan = getWhitePreservationPlan(\n    image,\n    options,\n    colorPalette\n  );\n\n  applyImageProcessing(image, mergeImageProcessingOptions(options), colorPalette);\n\n  applyWhitePreservation(image, whitePreservationPlan);\n};\n\nconst ditherImageData = async (\n  image: ImageDataLike,\n  options: DitherImageOptions & typeof defaultOptions,\n  colorPalette: RGB[]\n) => {\n  const width = image.width;\n  const height = image.height;\n  const edgeSourceData = shouldApplyEdgeHandling(options, colorPalette)\n    ? new Uint8ClampedArray(image.data)\n    : null;\n\n  function setPixel(pixelIndex: number, pixel: RGBA) {\n    image.data[pixelIndex] = pixel[0];\n    image.data[pixelIndex + 1] = pixel[1];\n    image.data[pixelIndex + 2] = pixel[2];\n    image.data[pixelIndex + 3] = pixel[3] ?? 255;\n  }\n\n  if (isUtilsDitheringType(options.ditheringType)) {\n    applyUtilsDithering(image, options, colorPalette);\n    applyEdgeHandling(image, options, colorPalette, edgeSourceData);\n    return;\n  }\n\n  const thresholdMap = bayerMatrix([\n    options.orderedDitheringMatrix[0],\n    options.orderedDitheringMatrix[1],\n  ]);\n\n  let current: number;\n  let newPixel: RGBA;\n  let oldPixel: RGBA;\n  const hueMixPalette = getHueMixPalette(colorPalette);\n\n  for (current = 0; current < image.data.length; current += 4) {\n    const currentPixel = current;\n    oldPixel = getPixelColorValues(currentPixel, image.data);\n\n    if (\n      !options.ditheringType ||\n      options.ditheringType === \"quantizationOnly\"\n    ) {\n      newPixel = findClosestPaletteColor(\n        oldPixel,\n        colorPalette,\n        options.colorMatching\n      );\n      setPixel(currentPixel, newPixel);\n    }\n\n    if (\n      options.ditheringType === \"random\" &&\n      options.randomDitheringType === \"rgb\"\n    ) {\n      newPixel = randomDitherPixelValue(oldPixel);\n      setPixel(currentPixel, newPixel);\n    }\n\n    if (\n      options.ditheringType === \"random\" &&\n      options.randomDitheringType === \"blackAndWhite\"\n    ) {\n      newPixel = randomDitherBlackAndWhitePixelValue(oldPixel);\n      setPixel(currentPixel, newPixel);\n    }\n\n    if (options.ditheringType === \"ordered\") {\n      const orderedDitherThreshold = 256 / 4;\n      newPixel = orderedDitherPixelValue(\n        oldPixel,\n        pixelXY(currentPixel / 4, width),\n        thresholdMap,\n        orderedDitherThreshold\n      );\n      newPixel = findClosestPaletteColor(\n        newPixel,\n        colorPalette,\n        options.colorMatching\n      );\n      setPixel(currentPixel, newPixel);\n    }\n\n    if (options.ditheringType === \"hueMix\") {\n      newPixel = hueMixDitherPixelValue(\n        oldPixel,\n        pixelXY(currentPixel / 4, width),\n        hueMixPalette,\n        colorPalette,\n        options.colorMatching\n      );\n      setPixel(currentPixel, newPixel);\n    }\n\n    if (options.ditheringType === \"errorDiffusion\") {\n      break;\n    }\n  }\n\n  if (options.ditheringType === \"errorDiffusion\") {\n    const diffusionMap = getDiffusionMap(options.errorDiffusionMatrix);\n    const usedWasm =\n      shouldUseWasmErrorDiffusion(\n        options.processingEngine,\n        options.colorMatching\n      ) &&\n      (await applyWasmRgbErrorDiffusion(\n        image,\n        colorPalette,\n        diffusionMap,\n        options.serpentine\n      ));\n\n    if (!usedWasm) {\n      applyErrorDiffusion(\n        image,\n        width,\n        height,\n        colorPalette,\n        diffusionMap,\n        options.colorMatching,\n        options.serpentine\n      );\n    }\n  }\n\n  applyEdgeHandling(image, options, colorPalette, edgeSourceData);\n};\n\nconst applyImageAdjustments = async (\n  sourceCanvas: CanvasLike,\n  canvas: CanvasLike,\n  opts: DitherImageOptions = {}\n): Promise<CanvasLike | undefined> => {\n  if (!sourceCanvas || !canvas) return;\n\n  const image = getCanvasImageData(sourceCanvas);\n  if (!image) return;\n\n  const options = getResolvedDitherOptions(opts);\n  const colorPalette = getColorPaletteFromOptions(options);\n  applyImageAdjustmentsToImageData(image, options, colorPalette);\n\n  return imageDataToCanvas(image, canvas);\n};\n\nconst applyImageDataAdjustments = (\n  image: ImageDataLike,\n  opts: DitherImageOptions = {}\n): ImageDataLike | undefined => {\n  if (!image) return;\n\n  const options = getResolvedDitherOptions(opts);\n  const colorPalette = getColorPaletteFromOptions(options);\n  applyImageAdjustmentsToImageData(image, options, colorPalette);\n\n  return image;\n};\n\nconst applyImageDataAdjustmentsAsync = async (\n  image: ImageDataLike,\n  opts: DitherImageOptions = {}\n): Promise<ImageDataLike | undefined> => {\n  if (!image) return;\n\n  const previewImage = getPreviewImageData(image, opts.preview, \"final\");\n  const workerOptions = getResolvedDitherOptions(opts);\n  if (shouldUseAdjustmentWorker(workerOptions, previewImage)) {\n    return applyImageDataAdjustmentsInWorker(previewImage, opts);\n  }\n\n  await waitForAdjustmentTurn();\n\n  return applyImageDataAdjustments(previewImage, opts);\n};\n\nconst applyImageAdjustmentsPreview = async (\n  sourceCanvas: CanvasLike,\n  canvas: CanvasLike,\n  opts: DitherImageOptions = {}\n): Promise<CanvasLike | undefined> => {\n  if (!sourceCanvas || !canvas) return;\n\n  const image = getCanvasImageData(sourceCanvas);\n  if (!image) return;\n\n  const previewImage = getPreviewImageData(image, opts.preview, \"fast\");\n  const adjusted = await applyImageDataAdjustmentsAsync(previewImage, {\n    ...opts,\n    preview: {\n      ...opts.preview,\n      mode: opts.preview?.mode ?? \"fast\",\n    },\n  });\n  if (!adjusted) return;\n\n  return imageDataToCanvas(adjusted, canvas);\n};\n\nconst ditherCanvas = async (\n  sourceCanvas: CanvasLike,\n  canvas: CanvasLike,\n  opts: DitherImageOptions = {}\n): Promise<CanvasLike | undefined> => {\n  if (!sourceCanvas || !canvas) return;\n\n  const image = getCanvasImageData(sourceCanvas);\n  if (!image) return;\n\n  const options = getResolvedDitherOptions(opts);\n  const colorPalette = getColorPaletteFromOptions(options);\n  await ditherImageData(image, options, colorPalette);\n\n  return imageDataToCanvas(image, canvas);\n};\n\nconst ditherImage = async (\n  sourceCanvas: CanvasLike,\n  canvas: CanvasLike,\n  opts: DitherImageOptions = {}\n): Promise<CanvasLike | undefined> => {\n  if (!sourceCanvas || !canvas) return;\n\n  const image = getCanvasImageData(sourceCanvas);\n  if (!image) return;\n\n  const options = getResolvedDitherOptions(opts);\n  const colorPalette = getColorPaletteFromOptions(options);\n  applyImageAdjustmentsToImageData(image, options, colorPalette);\n  await ditherImageData(image, options, colorPalette);\n\n  return imageDataToCanvas(image, canvas);\n};\n\nconst getPixelColorValues = (\n  pixelIndex: number,\n  data: Uint8ClampedArray\n): RGBA => {\n  return [\n    data[pixelIndex],\n    data[pixelIndex + 1],\n    data[pixelIndex + 2],\n    data[pixelIndex + 3],\n  ];\n};\n\nconst getDiffusionMap = (matrixName: string) => {\n  const matrixFactory = diffusionMaps[matrixName] || diffusionMaps.floydSteinberg;\n  return matrixFactory();\n};\n\ntype DiffusionMap = ReturnType<typeof getDiffusionMap>;\n\nconst shouldUseWasmErrorDiffusion = (\n  engine: DitherProcessingEngine | undefined,\n  colorMatching: ColorMatchingMode\n) => (engine === \"wasm\" || engine === \"auto\") && colorMatching === \"rgb\";\n\nconst isUtilsDitheringType = (ditheringType: DitheringType | undefined) =>\n  ditheringType === \"blueNoise\" ||\n  ditheringType === \"simple2D\" ||\n  ditheringType === \"riemersma\" ||\n  ditheringType === \"ditherItErrorDiffusion\" ||\n  ditheringType === \"ditherItOrdered\" ||\n  ditheringType === \"ditherItBlueNoise\" ||\n  ditheringType === \"ditherItSimple2D\" ||\n  ditheringType === \"ditherItRiemersma\";\n\ntype UtilsColorSpace = \"rgb\" | \"oklab\";\n\nconst applyUtilsDithering = (\n  image: ImageDataLike,\n  options: DitherImageOptions & typeof defaultOptions,\n  colorPalette: RGB[]\n) => {\n  const context = createUtilsDitherContext(image);\n  const imageData = image as unknown as ImageData;\n  const blockSize = 1;\n  const colorSpace = getUtilsColorSpace(options.colorMatching);\n\n  if (options.ditheringType === \"ditherItOrdered\") {\n    bayerDither(\n      context,\n      imageData,\n      colorPalette,\n      blockSize,\n      getUtilsBayerSize(options.orderedDitheringMatrix)\n    );\n    return;\n  }\n\n  if (\n    options.ditheringType === \"blueNoise\" ||\n    options.ditheringType === \"ditherItBlueNoise\"\n  ) {\n    blueNoiseDither(context, imageData, colorPalette, blockSize);\n    return;\n  }\n\n  if (\n    options.ditheringType === \"simple2D\" ||\n    options.ditheringType === \"ditherItSimple2D\"\n  ) {\n    simple2DDither(context, imageData, colorPalette, blockSize, colorSpace);\n    return;\n  }\n\n  if (\n    options.ditheringType === \"riemersma\" ||\n    options.ditheringType === \"ditherItRiemersma\"\n  ) {\n    riemersmaDither(context, imageData, colorPalette, blockSize, colorSpace);\n    return;\n  }\n\n  if (colorSpace === \"rgb\") {\n    rgbQuantDiffusionDither(\n      context,\n      imageData,\n      colorPalette,\n      blockSize,\n      getUtilsKernelName(options.errorDiffusionMatrix),\n      options.serpentine\n    );\n    return;\n  }\n\n  kernelDiffusionDither(\n    context,\n    imageData,\n    colorPalette,\n    blockSize,\n    getUtilsKernelName(options.errorDiffusionMatrix),\n    options.serpentine,\n    colorSpace\n  );\n};\n\nconst createUtilsDitherContext = (image: ImageDataLike) =>\n  ({\n    canvas: {\n      width: image.width,\n      height: image.height,\n    },\n    putImageData(nextImage: ImageDataLike) {\n      if (nextImage.data !== image.data) {\n        image.data.set(nextImage.data);\n      }\n    },\n  }) as unknown as CanvasRenderingContext2D;\n\nconst getUtilsColorSpace = (\n  colorMatching: ColorMatchingMode\n): UtilsColorSpace => (colorMatching === \"lab\" ? \"oklab\" : \"rgb\");\n\nconst getUtilsBayerSize = (\n  matrixSize: [number, number] | number[]\n): BayerSize => {\n  const size = Math.max(matrixSize[0] ?? 4, matrixSize[1] ?? matrixSize[0] ?? 4);\n  if (size <= 2) return 2;\n  if (size <= 4) return 4;\n  if (size <= 8) return 8;\n  return 16;\n};\n\nconst getUtilsKernelName = (matrixName: string) => {\n  const kernelNames: Record<string, string> = {\n    floydSteinberg: \"FloydSteinberg\",\n    FloydSteinberg: \"FloydSteinberg\",\n    falseFloydSteinberg: \"FloydSteinberg\",\n    atkinson: \"Atkinson\",\n    Atkinson: \"Atkinson\",\n    jarvis: \"JarvisJudiceNinke\",\n    jarvisJudiceNinke: \"JarvisJudiceNinke\",\n    JarvisJudiceNinke: \"JarvisJudiceNinke\",\n    stucki: \"Stucki\",\n    Stucki: \"Stucki\",\n    burkes: \"Burkes\",\n    Burkes: \"Burkes\",\n    sierra3: \"Sierra3\",\n    Sierra3: \"Sierra3\",\n    sierra2: \"Sierra2\",\n    Sierra2: \"Sierra2\",\n    \"sierra2-4a\": \"Sierra24A\",\n    fan: \"Fan\",\n    Fan: \"Fan\",\n    shiauFan: \"ShiauFan\",\n    ShiauFan: \"ShiauFan\",\n    shiauFan2: \"ShiauFan2\",\n    ShiauFan2: \"ShiauFan2\",\n  };\n\n  return kernelNames[matrixName] ?? \"FloydSteinberg\";\n};\n\ninterface PaletteMatcher {\n  hasPalette: boolean;\n  findIndex(\n    r: number,\n    g: number,\n    b: number,\n    sourceR: number,\n    sourceG: number,\n    sourceB: number\n  ): number;\n}\n\nconst createPaletteMatcher = (\n  colorPalette: RGB[],\n  colorMatching: ColorMatchingMode\n): PaletteMatcher => {\n  const paletteLabs =\n    colorMatching === \"lab\"\n      ? colorPalette.map((color) => rgbToLab(color[0], color[1], color[2]))\n      : [];\n  const paletteSaturations =\n    colorMatching === \"chroma\"\n      ? colorPalette.map((color) =>\n          getSaturationFromChannels(color[0], color[1], color[2])\n        )\n      : [];\n  const paletteHues =\n    colorMatching === \"chroma\"\n      ? colorPalette.map((color) =>\n          getHueFromChannels(color[0], color[1], color[2])\n        )\n      : [];\n\n  return {\n    hasPalette: colorPalette.length > 0,\n    findIndex(r, g, b, sourceR, sourceG, sourceB) {\n      if (!colorPalette.length) return -1;\n\n      let closestIndex = 0;\n      let closestDistance = Infinity;\n\n      if (colorMatching === \"lab\") {\n        const pixelLab = rgbToLab(r, g, b);\n        for (let index = 0; index < colorPalette.length; index += 1) {\n          const distance = deltaE(paletteLabs[index], pixelLab);\n          if (distance < closestDistance) {\n            closestDistance = distance;\n            closestIndex = index;\n          }\n        }\n        return closestIndex;\n      }\n\n      const sourceSaturation =\n        colorMatching === \"chroma\"\n          ? getSaturationFromChannels(sourceR, sourceG, sourceB)\n          : 0;\n      const sourceHue =\n        colorMatching === \"chroma\" && sourceSaturation >= 0.12\n          ? getHueFromChannels(sourceR, sourceG, sourceB)\n          : null;\n\n      for (let index = 0; index < colorPalette.length; index += 1) {\n        const color = colorPalette[index];\n        const dr = color[0] - r;\n        const dg = color[1] - g;\n        const db = color[2] - b;\n        let distance = Math.sqrt(dr * dr + dg * dg + db * db);\n\n        if (colorMatching === \"chroma\") {\n          const paletteSaturation = paletteSaturations[index];\n          if (sourceSaturation >= 0.12 && paletteSaturation <= 0.12) {\n            distance += Math.min(330, sourceSaturation * 1300);\n          }\n          if (sourceHue !== null && paletteSaturation > 0.12) {\n            distance += getHueDistance(sourceHue, paletteHues[index]) * 3;\n          }\n        }\n\n        if (distance < closestDistance) {\n          closestDistance = distance;\n          closestIndex = index;\n        }\n      }\n\n      return closestIndex;\n    },\n  };\n};\n\nconst applyErrorDiffusion = (\n  image: ImageDataLike,\n  width: number,\n  height: number,\n  colorPalette: RGB[],\n  diffusionMap: DiffusionMap,\n  colorMatching: ColorMatchingMode,\n  serpentine: boolean\n) => {\n  const sourceData = new Uint8ClampedArray(image.data);\n  const data = image.data;\n  const matcher = createPaletteMatcher(colorPalette, colorMatching);\n\n  for (let y = 0; y < height; y++) {\n    const reverse = serpentine && y % 2 === 1;\n    const xStart = reverse ? width - 1 : 0;\n    const xEnd = reverse ? -1 : width;\n    const xStep = reverse ? -1 : 1;\n\n    for (let x = xStart; x !== xEnd; x += xStep) {\n      const currentPixel = (y * width + x) * 4;\n      const oldR = data[currentPixel];\n      const oldG = data[currentPixel + 1];\n      const oldB = data[currentPixel + 2];\n      const oldA = data[currentPixel + 3];\n      const sourceR = sourceData[currentPixel];\n      const sourceG = sourceData[currentPixel + 1];\n      const sourceB = sourceData[currentPixel + 2];\n      const closestIndex = matcher.findIndex(\n        oldR,\n        oldG,\n        oldB,\n        sourceR,\n        sourceG,\n        sourceB\n      );\n      const newR = matcher.hasPalette ? colorPalette[closestIndex][0] : oldR;\n      const newG = matcher.hasPalette ? colorPalette[closestIndex][1] : oldG;\n      const newB = matcher.hasPalette ? colorPalette[closestIndex][2] : oldB;\n      const newA = matcher.hasPalette ? 255 : oldA;\n\n      data[currentPixel] = newR;\n      data[currentPixel + 1] = newG;\n      data[currentPixel + 2] = newB;\n      data[currentPixel + 3] = newA;\n\n      const errorR = oldR - newR;\n      const errorG = oldG - newG;\n      const errorB = oldB - newB;\n\n      for (let index = 0; index < diffusionMap.length; index += 1) {\n        const diffusion = diffusionMap[index];\n        const dx = reverse ? -diffusion.offset[0] : diffusion.offset[0];\n        const nx = x + dx;\n        const ny = y + diffusion.offset[1];\n        if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue;\n\n        const pixelIndex = (ny * width + nx) * 4;\n        const factor = diffusion.factor;\n        data[pixelIndex] = clampByte(data[pixelIndex] + errorR * factor);\n        data[pixelIndex + 1] = clampByte(\n          data[pixelIndex + 1] + errorG * factor\n        );\n        data[pixelIndex + 2] = clampByte(\n          data[pixelIndex + 2] + errorB * factor\n        );\n      }\n    }\n  }\n};\n\ninterface EdgeMasks {\n  core: Uint8Array;\n  band: Uint8Array;\n}\n\nconst shouldApplyEdgeHandling = (\n  options: DitherImageOptions,\n  colorPalette: RGB[]\n) =>\n  colorPalette.length > 0 &&\n  (options.edgePreservation?.enabled === true ||\n    options.edgeAntialiasing?.enabled === true);\n\nconst applyEdgeHandling = (\n  image: ImageDataLike,\n  options: DitherImageOptions,\n  colorPalette: RGB[],\n  sourceData: Uint8ClampedArray | null\n) => {\n  if (!sourceData || !shouldApplyEdgeHandling(options, colorPalette)) return;\n\n  const preserveOptions = options.edgePreservation;\n  const antialiasOptions = options.edgeAntialiasing;\n  const preserveEnabled = preserveOptions?.enabled === true;\n  const antialiasEnabled = antialiasOptions?.enabled === true;\n  const preserveStrength = clamp(preserveOptions?.strength ?? 0.65, 0, 1);\n  const antialiasStrength = clamp(antialiasOptions?.strength ?? 0.75, 0, 1);\n\n  if (\n    (preserveEnabled && preserveStrength <= 0) ||\n    (antialiasEnabled && antialiasStrength <= 0)\n  ) {\n    if (\n      (!preserveEnabled || preserveStrength <= 0) &&\n      (!antialiasEnabled || antialiasStrength <= 0)\n    ) {\n      return;\n    }\n  }\n\n  const threshold = Math.min(\n    preserveEnabled ? preserveOptions?.threshold ?? 42 : Infinity,\n    antialiasEnabled ? antialiasOptions?.threshold ?? 42 : Infinity\n  );\n  if (!Number.isFinite(threshold)) return;\n\n  const masks = buildEdgeMasks(sourceData, image.width, image.height, {\n    threshold,\n    coreThreshold:\n      threshold *\n      (preserveEnabled ? 1.7 - preserveStrength * 0.7 : 1.45),\n    coreRadius: preserveEnabled ? Math.max(0, preserveOptions?.radius ?? 0) : 0,\n    bandRadius: antialiasEnabled\n      ? Math.max(1, antialiasOptions?.bandRadius ?? 1)\n      : 0,\n  });\n  const quantized = getQuantizedData(\n    sourceData,\n    colorPalette,\n    options.colorMatching\n  );\n\n  if (antialiasEnabled) {\n    applyEdgeAntialiasing(\n      image,\n      sourceData,\n      quantized,\n      masks,\n      antialiasStrength,\n      Math.max(1, antialiasOptions?.localRadius ?? 2)\n    );\n  }\n\n  if (preserveEnabled) {\n    applyEdgePreservation(image, quantized, masks, preserveStrength);\n  }\n};\n\nconst buildEdgeMasks = (\n  data: Uint8ClampedArray,\n  width: number,\n  height: number,\n  options: {\n    threshold: number;\n    coreThreshold: number;\n    coreRadius: number;\n    bandRadius: number;\n  }\n): EdgeMasks => {\n  const rawCore = new Uint8Array(width * height);\n  const core = new Uint8Array(width * height);\n  const band = new Uint8Array(width * height);\n\n  for (let y = 1; y < height - 1; y += 1) {\n    for (let x = 1; x < width - 1; x += 1) {\n      const pixel = (y * width + x) * 4;\n      if (data[pixel + 3] <= 16) continue;\n\n      const left = (y * width + x - 1) * 4;\n      const right = (y * width + x + 1) * 4;\n      const up = ((y - 1) * width + x) * 4;\n      const down = ((y + 1) * width + x) * 4;\n      const dx = luma709(data[right], data[right + 1], data[right + 2]) -\n        luma709(data[left], data[left + 1], data[left + 2]);\n      const dy = luma709(data[down], data[down + 1], data[down + 2]) -\n        luma709(data[up], data[up + 1], data[up + 2]);\n      const magnitude = Math.sqrt(dx * dx + dy * dy);\n      const index = y * width + x;\n\n      if (magnitude >= options.threshold) {\n        dilateMaskAt(band, width, height, x, y, options.bandRadius);\n      }\n\n      if (magnitude >= options.coreThreshold) {\n        rawCore[index] = 1;\n      }\n    }\n  }\n\n  if (options.coreRadius > 0) {\n    for (let index = 0; index < rawCore.length; index += 1) {\n      if (rawCore[index] !== 1) continue;\n      const x = index % width;\n      const y = Math.floor(index / width);\n      dilateMaskAt(core, width, height, x, y, options.coreRadius);\n    }\n  } else {\n    core.set(rawCore);\n  }\n\n  return { core, band };\n};\n\nconst dilateMaskAt = (\n  mask: Uint8Array,\n  width: number,\n  height: number,\n  x: number,\n  y: number,\n  radius: number\n) => {\n  if (radius <= 0) {\n    mask[y * width + x] = 1;\n    return;\n  }\n\n  for (let oy = -radius; oy <= radius; oy += 1) {\n    for (let ox = -radius; ox <= radius; ox += 1) {\n      const nx = x + ox;\n      const ny = y + oy;\n      if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue;\n      mask[ny * width + nx] = 1;\n    }\n  }\n};\n\nconst getQuantizedData = (\n  sourceData: Uint8ClampedArray,\n  colorPalette: RGB[],\n  colorMatching: ColorMatchingMode\n) => {\n  const quantized = new Uint8ClampedArray(sourceData);\n  const matcher = createPaletteMatcher(colorPalette, colorMatching);\n\n  for (let pixel = 0; pixel < quantized.length; pixel += 4) {\n    if (sourceData[pixel + 3] <= 16) continue;\n\n    const r = sourceData[pixel];\n    const g = sourceData[pixel + 1];\n    const b = sourceData[pixel + 2];\n    const closestIndex = matcher.findIndex(r, g, b, r, g, b);\n    if (closestIndex < 0) continue;\n\n    const color = colorPalette[closestIndex];\n    quantized[pixel] = color[0];\n    quantized[pixel + 1] = color[1];\n    quantized[pixel + 2] = color[2];\n    quantized[pixel + 3] = 255;\n  }\n\n  return quantized;\n};\n\nconst applyEdgePreservation = (\n  image: ImageDataLike,\n  quantized: Uint8ClampedArray,\n  masks: EdgeMasks,\n  strength: number\n) => {\n  const data = image.data;\n\n  for (let index = 0; index < masks.core.length; index += 1) {\n    if (masks.core[index] !== 1) continue;\n    const x = index % image.width;\n    const y = Math.floor(index / image.width);\n    if (stableNoiseThreshold(x + 811, y + 3571) > strength) continue;\n\n    const pixel = index * 4;\n    data[pixel] = quantized[pixel];\n    data[pixel + 1] = quantized[pixel + 1];\n    data[pixel + 2] = quantized[pixel + 2];\n    data[pixel + 3] = quantized[pixel + 3];\n  }\n};\n\nconst applyEdgeAntialiasing = (\n  image: ImageDataLike,\n  sourceData: Uint8ClampedArray,\n  quantized: Uint8ClampedArray,\n  masks: EdgeMasks,\n  strength: number,\n  localRadius: number\n) => {\n  const { width, height } = image;\n  const data = image.data;\n\n  for (let y = 1; y < height - 1; y += 1) {\n    for (let x = 1; x < width - 1; x += 1) {\n      const index = y * width + x;\n      if (masks.band[index] !== 1) continue;\n      if (stableNoiseThreshold(x + 2371, y + 593) > strength) continue;\n\n      const pair = getLocalPalettePair(\n        quantized,\n        width,\n        height,\n        x,\n        y,\n        localRadius\n      );\n      if (!pair) continue;\n\n      const pixel = index * 4;\n      const source: RGB = [\n        sourceData[pixel],\n        sourceData[pixel + 1],\n        sourceData[pixel + 2],\n      ];\n      const coverage = getSegmentCoverage(source, pair[0], pair[1]);\n      const residual = getSegmentResidual(source, pair[0], pair[1], coverage);\n\n      if (residual > 95) continue;\n\n      if (coverage <= 0.08 || coverage >= 0.92 || masks.core[index] === 1) {\n        data[pixel] = quantized[pixel];\n        data[pixel + 1] = quantized[pixel + 1];\n        data[pixel + 2] = quantized[pixel + 2];\n        data[pixel + 3] = quantized[pixel + 3];\n        continue;\n      }\n\n      const color =\n        stableNoiseThreshold(x, y) < coverage ? pair[1] : pair[0];\n      data[pixel] = color[0];\n      data[pixel + 1] = color[1];\n      data[pixel + 2] = color[2];\n      data[pixel + 3] = 255;\n    }\n  }\n};\n\ninterface LocalPaletteCandidate {\n  color: RGB;\n  count: number;\n}\n\nconst getLocalPalettePair = (\n  data: Uint8ClampedArray,\n  width: number,\n  height: number,\n  x: number,\n  y: number,\n  radius: number\n): [RGB, RGB] | null => {\n  const counts = new Map<number, LocalPaletteCandidate>();\n\n  for (let oy = -radius; oy <= radius; oy += 1) {\n    for (let ox = -radius; ox <= radius; ox += 1) {\n      const nx = x + ox;\n      const ny = y + oy;\n      if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue;\n\n      const pixel = (ny * width + nx) * 4;\n      if (data[pixel + 3] <= 16) continue;\n\n      const color: RGB = [data[pixel], data[pixel + 1], data[pixel + 2]];\n      const key = (color[0] << 16) | (color[1] << 8) | color[2];\n      const existing = counts.get(key);\n      if (existing) {\n        existing.count += 1;\n      } else {\n        counts.set(key, { color, count: 1 });\n      }\n    }\n  }\n\n  const candidates = Array.from(counts.values())\n    .sort((left, right) => right.count - left.count)\n    .slice(0, 5);\n  if (candidates.length < 2) return null;\n\n  let best: [RGB, RGB] | null = null;\n  let bestScore = -Infinity;\n  for (let leftIndex = 0; leftIndex < candidates.length; leftIndex += 1) {\n    for (\n      let rightIndex = leftIndex + 1;\n      rightIndex < candidates.length;\n      rightIndex += 1\n    ) {\n      const left = candidates[leftIndex];\n      const right = candidates[rightIndex];\n      const distance = colorDistance(left.color, right.color);\n      const score = distance + Math.min(left.count, right.count) * 8;\n      if (score > bestScore) {\n        bestScore = score;\n        best = [left.color, right.color];\n      }\n    }\n  }\n\n  return bestScore >= 45 ? best : null;\n};\n\nconst getSegmentCoverage = (source: RGB, a: RGB, b: RGB) => {\n  const abR = b[0] - a[0];\n  const abG = b[1] - a[1];\n  const abB = b[2] - a[2];\n  const lengthSq = abR * abR + abG * abG + abB * abB;\n  if (lengthSq <= 0.0001) return 0;\n\n  return clamp(\n    ((source[0] - a[0]) * abR +\n      (source[1] - a[1]) * abG +\n      (source[2] - a[2]) * abB) /\n      lengthSq,\n    0,\n    1\n  );\n};\n\nconst getSegmentResidual = (source: RGB, a: RGB, b: RGB, coverage: number) => {\n  const mixed: RGB = [\n    a[0] + (b[0] - a[0]) * coverage,\n    a[1] + (b[1] - a[1]) * coverage,\n    a[2] + (b[2] - a[2]) * coverage,\n  ];\n  return colorDistance(source, mixed);\n};\n\nconst colorDistance = (left: RGB, right: RGB) => {\n  const dr = left[0] - right[0];\n  const dg = left[1] - right[1];\n  const db = left[2] - right[2];\n  return Math.sqrt(dr * dr + dg * dg + db * db);\n};\n\nconst stableNoiseThreshold = (x: number, y: number) => {\n  const value = Math.sin(x * 12.9898 + y * 78.233) * 43758.5453;\n  return value - Math.floor(value);\n};\n\nconst randomDitherPixelValue = (pixel: RGBA): RGBA => {\n  return [\n    pixel[0] < utilities.randomInteger(0, 255) ? 0 : 255,\n    pixel[1] < utilities.randomInteger(0, 255) ? 0 : 255,\n    pixel[2] < utilities.randomInteger(0, 255) ? 0 : 255,\n    pixel[3],\n  ];\n};\n\nconst randomDitherBlackAndWhitePixelValue = (pixel: RGBA): RGBA => {\n  const averageRGB = (pixel[0] + pixel[1] + pixel[2]) / 3;\n  return averageRGB < utilities.randomInteger(0, 255)\n    ? [0, 0, 0, 255]\n    : [255, 255, 255, 255];\n};\n\nconst orderedDitherPixelValue = (\n  pixel: RGBA,\n  coordinates: [number, number],\n  thresholdMap: number[][],\n  threshold: number\n): RGBA => {\n  const factor =\n    thresholdMap[coordinates[1] % thresholdMap.length][\n      coordinates[0] % thresholdMap[0].length\n    ] /\n    (thresholdMap.length * thresholdMap[0].length);\n  return [\n    clampByte(pixel[0] + factor * threshold),\n    clampByte(pixel[1] + factor * threshold),\n    clampByte(pixel[2] + factor * threshold),\n    pixel[3],\n  ];\n};\n\ninterface HueMixColor {\n  color: RGB;\n  hue: number;\n  luma: number;\n  saturation: number;\n}\n\ninterface HueMixPalette {\n  chromatic: HueMixColor[];\n  white: HueMixColor | null;\n}\n\nconst getHueMixPalette = (palette: RGB[]): HueMixPalette => {\n  const colors = palette.map((color) => ({\n    color,\n    hue: getHue(color),\n    luma: luma709(color[0], color[1], color[2]),\n    saturation: getSaturation(color),\n  }));\n  const chromatic = colors\n    .filter((entry) => entry.saturation >= 0.18 && entry.luma >= 24)\n    .sort((left, right) => left.hue - right.hue);\n  const neutralCandidates = colors.filter((entry) => entry.saturation < 0.18);\n  const whiteCandidates = neutralCandidates.length ? neutralCandidates : colors;\n  let white: HueMixColor | null = null;\n  for (const entry of whiteCandidates) {\n    if (!white || entry.luma > white.luma) white = entry;\n  }\n\n  return {\n    chromatic,\n    white,\n  };\n};\n\nconst hueMixDitherPixelValue = (\n  pixel: RGBA,\n  coordinates: [number, number],\n  hueMixPalette: HueMixPalette,\n  colorPalette: RGB[],\n  colorMatching: ColorMatchingMode\n): RGBA => {\n  if (hueMixPalette.chromatic.length < 2 || !hueMixPalette.white) {\n    return findClosestPaletteColor(pixel, colorPalette, colorMatching);\n  }\n\n  const targetSaturation = getSaturation(pixel);\n  if (targetSaturation < 0.08) {\n    return findClosestPaletteColor(pixel, colorPalette, colorMatching);\n  }\n\n  const targetHue = getHue(pixel);\n  const [left, right, t] = getHueNeighbors(targetHue, hueMixPalette.chromatic);\n  const hueMix = smoothstep(0, 1, t);\n  const mixedLuma = left.luma * (1 - hueMix) + right.luma * hueMix;\n  const targetLuma = luma709(pixel[0], pixel[1], pixel[2]);\n  const whiteLuma = hueMixPalette.white.luma;\n  const saturationCoverage = smoothstep(0.08, 0.55, targetSaturation);\n  const lumaCoverage =\n    whiteLuma > mixedLuma\n      ? clamp((whiteLuma - targetLuma) / (whiteLuma - mixedLuma), 0, 1)\n      : 0;\n  const coverage = clamp(Math.max(saturationCoverage, lumaCoverage), 0, 1);\n  const whiteWeight = 1 - coverage;\n  const leftWeight = coverage * (1 - hueMix);\n  const rightWeight = coverage * hueMix;\n  const threshold = hashUnit(coordinates[0], coordinates[1]);\n\n  if (threshold < whiteWeight) return withAlpha(hueMixPalette.white.color, pixel);\n  if (threshold < whiteWeight + leftWeight) return withAlpha(left.color, pixel);\n  if (rightWeight > 0) return withAlpha(right.color, pixel);\n  return withAlpha(left.color, pixel);\n};\n\nconst getHueNeighbors = (\n  targetHue: number,\n  chromatic: HueMixColor[]\n): [HueMixColor, HueMixColor, number] => {\n  for (let index = 0; index < chromatic.length; index += 1) {\n    const left = chromatic[index];\n    const right = chromatic[(index + 1) % chromatic.length];\n    const span = positiveHueDelta(left.hue, right.hue);\n    const offset = positiveHueDelta(left.hue, targetHue);\n    if (offset <= span) {\n      return [left, right, span === 0 ? 0 : offset / span];\n    }\n  }\n\n  return [chromatic[0], chromatic[0], 0];\n};\n\nconst withAlpha = (color: RGB, pixel: RGBA): RGBA => [\n  color[0],\n  color[1],\n  color[2],\n  pixel[3],\n];\n\nconst smoothstep = (edge0: number, edge1: number, value: number) => {\n  const x = clamp((value - edge0) / (edge1 - edge0), 0, 1);\n  return x * x * (3 - 2 * x);\n};\n\nconst clamp = (value: number, min: number, max: number) =>\n  value < min ? min : value > max ? max : value;\n\nconst hashUnit = (x: number, y: number) => {\n  const value = Math.sin(x * 127.1 + y * 311.7) * 43758.5453123;\n  return value - Math.floor(value);\n};\n\nconst getSaturation = (color: RGB | RGBA) =>\n  getSaturationFromChannels(color[0], color[1], color[2]);\n\nconst getSaturationFromChannels = (r: number, g: number, b: number) => {\n  const max = Math.max(r, g, b) / 255;\n  const min = Math.min(r, g, b) / 255;\n\n  return max === 0 ? 0 : (max - min) / max;\n};\n\nconst getHue = (color: RGB | RGBA) =>\n  getHueFromChannels(color[0], color[1], color[2]);\n\nconst getHueFromChannels = (r: number, g: number, b: number) => {\n  const red = r / 255;\n  const green = g / 255;\n  const blue = b / 255;\n  const max = Math.max(red, green, blue);\n  const min = Math.min(red, green, blue);\n  const delta = max - min;\n\n  if (delta === 0) return 0;\n\n  let hue: number;\n  if (max === red) {\n    hue = 60 * (((green - blue) / delta) % 6);\n  } else if (max === green) {\n    hue = 60 * ((blue - red) / delta + 2);\n  } else {\n    hue = 60 * ((red - green) / delta + 4);\n  }\n\n  return hue < 0 ? hue + 360 : hue;\n};\n\nconst getHueDistance = (hueA: number, hueB: number) => {\n  const delta = Math.abs(hueA - hueB) % 360;\n  return Math.min(delta, 360 - delta);\n};\n\nconst positiveHueDelta = (from: number, to: number) => (to - from + 360) % 360;\n\nconst pixelXY = (index: number, width: number): [number, number] => {\n  return [index % width, Math.floor(index / width)];\n};\n\nconst isPaletteColorEntry = (\n  color: string | PaletteColorEntry\n): color is PaletteColorEntry =>\n  typeof color === \"object\" && color !== null && \"color\" in color;\n\nconst setColorPalette = (\n  palette: string | string[] | PaletteColorEntry[]\n): RGB[] => {\n  const paletteArray =\n    typeof palette === \"string\"\n      ? getNamedColors(palettes as PaletteRegistry, palette)\n      : palette;\n  return paletteArray\n    .map((color) =>\n      colorHelpers.hexToRgb(isPaletteColorEntry(color) ? color.color : color)\n    )\n    .filter((color): color is RGB => Array.isArray(color));\n};\n\nconst imageDataToCanvas = (imageData: ImageDataLike, canvas: CanvasLike) => {\n  canvas.width = imageData.width;\n  canvas.height = imageData.height;\n\n  const ctx = canvas.getContext(\"2d\");\n\n  ctx.putImageData(imageData, 0, 0);\n\n  return canvas;\n};\n\nexport {\n  applyImageAdjustments,\n  applyImageAdjustmentsPreview,\n  applyImageDataAdjustments,\n  applyImageDataAdjustmentsAsync,\n  ditherCanvas,\n  ditherImage,\n};\n","import type { CanvasLike, ImageDataLike } from \"./dither/dither\";\n\nexport type ImageStyle = \"photo\" | \"illustration\" | \"unknown\";\nexport type ImageKind =\n  | \"photo\"\n  | \"lowContrastPhoto\"\n  | \"highContrastPhoto\"\n  | \"flatIllustration\"\n  | \"lineArt\"\n  | \"textOrUi\"\n  | \"pixelArt\"\n  | \"unknown\";\n\nexport interface ImageStyleMetrics {\n  sampleCount: number;\n  uniqueColorRatio: number;\n  topColorCoverage: number;\n  paletteEntropy: number;\n  flatRatio: number;\n  softChangeRatio: number;\n  strongEdgeRatio: number;\n  edgeDensity: number;\n  horizontalEdgeRatio: number;\n  verticalEdgeRatio: number;\n  lumaStdDev: number;\n  lumaP05: number;\n  lumaP95: number;\n  lumaRange: number;\n  saturationMean: number;\n  saturationStdDev: number;\n  darkRatio: number;\n  lightRatio: number;\n  grayRatio: number;\n  highSaturationRatio: number;\n  warmPaperRatio: number;\n  redRatio: number;\n  darkNeutralRatio: number;\n  photoTileRatio: number;\n  flatTileRatio: number;\n  textTileRatio: number;\n  gradientTileRatio: number;\n  transparentRatio: number;\n}\n\nexport interface ImageStyleClassification {\n  style: ImageStyle;\n  kind: ImageKind;\n  kindScores: Record<ImageKind, number>;\n  confidence: number;\n  photoScore: number;\n  metrics: ImageStyleMetrics;\n}\n\nexport interface ClassifyImageStyleOptions {\n  /**\n   * Longest side of the internal sample grid. Larger values are slower but can\n   * preserve more detail for tiny repeated patterns.\n   */\n  maxSampleDimension?: number;\n\n  /** Pixels at or below this alpha value are ignored. */\n  transparentAlphaThreshold?: number;\n\n  /**\n   * Decision threshold for `photoScore`. Raise it to classify ambiguous images\n   * as illustrations more often, lower it to classify them as photos more often.\n   */\n  photoThreshold?: number;\n}\n\ninterface Sample {\n  visible: boolean;\n  red: number;\n  green: number;\n  blue: number;\n  luma: number;\n  saturation: number;\n}\n\nconst DEFAULT_MAX_SAMPLE_DIMENSION = 160;\nconst DEFAULT_ALPHA_THRESHOLD = 16;\nconst DEFAULT_PHOTO_THRESHOLD = 0.5;\n\nconst EMPTY_METRICS: ImageStyleMetrics = {\n  sampleCount: 0,\n  uniqueColorRatio: 0,\n  topColorCoverage: 0,\n  paletteEntropy: 0,\n  flatRatio: 0,\n  softChangeRatio: 0,\n  strongEdgeRatio: 0,\n  edgeDensity: 0,\n  horizontalEdgeRatio: 0,\n  verticalEdgeRatio: 0,\n  lumaStdDev: 0,\n  lumaP05: 0,\n  lumaP95: 0,\n  lumaRange: 0,\n  saturationMean: 0,\n  saturationStdDev: 0,\n  darkRatio: 0,\n  lightRatio: 0,\n  grayRatio: 0,\n  highSaturationRatio: 0,\n  warmPaperRatio: 0,\n  redRatio: 0,\n  darkNeutralRatio: 0,\n  photoTileRatio: 0,\n  flatTileRatio: 0,\n  textTileRatio: 0,\n  gradientTileRatio: 0,\n  transparentRatio: 0,\n};\n\nconst EMPTY_KIND_SCORES: Record<ImageKind, number> = {\n  photo: 0,\n  lowContrastPhoto: 0,\n  highContrastPhoto: 0,\n  flatIllustration: 0,\n  lineArt: 0,\n  textOrUi: 0,\n  pixelArt: 0,\n  unknown: 1,\n};\n\n/**\n * Heuristically classify image data as a photo or an illustration.\n *\n * This does not use ML. It looks for signals that usually separate photos from\n * illustrations: color diversity, soft tonal changes, flat-color regions, edge\n * density, and saturation/luminance variation.\n */\nexport function classifyImageStyle(\n  image: ImageDataLike,\n  options: ClassifyImageStyleOptions = {}\n): ImageStyleClassification {\n  validateImageData(image);\n\n  const width = image.width;\n  const height = image.height;\n  const maxSampleDimension = Math.max(\n    1,\n    Math.floor(options.maxSampleDimension ?? DEFAULT_MAX_SAMPLE_DIMENSION)\n  );\n  const alphaThreshold =\n    options.transparentAlphaThreshold ?? DEFAULT_ALPHA_THRESHOLD;\n  const photoThreshold = options.photoThreshold ?? DEFAULT_PHOTO_THRESHOLD;\n\n  const scale = Math.min(1, maxSampleDimension / Math.max(width, height));\n  const sampleWidth = Math.max(1, Math.round(width * scale));\n  const sampleHeight = Math.max(1, Math.round(height * scale));\n  const samples = new Array<Sample>(sampleWidth * sampleHeight);\n  const colorCounts = new Map<number, number>();\n\n  let visibleCount = 0;\n  let transparentCount = 0;\n  let lumaSum = 0;\n  let lumaSquareSum = 0;\n  const lumaValues: number[] = [];\n  let saturationSum = 0;\n  let saturationSquareSum = 0;\n  let darkCount = 0;\n  let lightCount = 0;\n  let grayCount = 0;\n  let highSaturationCount = 0;\n  let warmPaperCount = 0;\n  let redCount = 0;\n  let darkNeutralCount = 0;\n\n  for (let y = 0; y < sampleHeight; y += 1) {\n    const sourceY = Math.min(\n      height - 1,\n      Math.floor((y / sampleHeight) * height)\n    );\n\n    for (let x = 0; x < sampleWidth; x += 1) {\n      const sourceX = Math.min(\n        width - 1,\n        Math.floor((x / sampleWidth) * width)\n      );\n      const sourceIndex = (sourceY * width + sourceX) * 4;\n      const alpha = image.data[sourceIndex + 3] ?? 255;\n\n      if (alpha <= alphaThreshold) {\n        transparentCount += 1;\n        samples[y * sampleWidth + x] = {\n          visible: false,\n          red: 0,\n          green: 0,\n          blue: 0,\n          luma: 0,\n          saturation: 0,\n        };\n        continue;\n      }\n\n      const red = image.data[sourceIndex];\n      const green = image.data[sourceIndex + 1];\n      const blue = image.data[sourceIndex + 2];\n      const luma = red * 0.2126 + green * 0.7152 + blue * 0.0722;\n      const saturation = getSaturation(red, green, blue);\n\n      visibleCount += 1;\n      lumaSum += luma;\n      lumaSquareSum += luma * luma;\n      lumaValues.push(luma);\n      saturationSum += saturation;\n      saturationSquareSum += saturation * saturation;\n      if (luma <= 36) darkCount += 1;\n      if (luma >= 220) lightCount += 1;\n      if (saturation <= 0.08) grayCount += 1;\n      if (saturation >= 0.72) highSaturationCount += 1;\n      if (isWarmPaperPixel(red, green, blue, luma, saturation)) {\n        warmPaperCount += 1;\n      }\n      if (isRedPixel(red, green, blue, saturation)) {\n        redCount += 1;\n      }\n      if (luma <= 88 && saturation <= 0.36) {\n        darkNeutralCount += 1;\n      }\n      const colorKey = getQuantizedColorKey(red, green, blue);\n      colorCounts.set(colorKey, (colorCounts.get(colorKey) ?? 0) + 1);\n\n      samples[y * sampleWidth + x] = {\n        visible: true,\n        red,\n        green,\n        blue,\n        luma,\n        saturation,\n      };\n    }\n  }\n\n  if (visibleCount === 0) {\n    return {\n      style: \"unknown\",\n      kind: \"unknown\",\n      kindScores: { ...EMPTY_KIND_SCORES },\n      confidence: 0,\n      photoScore: 0,\n      metrics: {\n        ...EMPTY_METRICS,\n        transparentRatio: transparentCount / samples.length,\n      },\n    };\n  }\n\n  const neighborMetrics = getNeighborMetrics(samples, sampleWidth, sampleHeight);\n  const colorMetrics = getColorDistributionMetrics(colorCounts, visibleCount);\n  const edgeMetrics = getEdgeMetrics(samples, sampleWidth, sampleHeight);\n  const tileMetrics = getTileMetrics(samples, sampleWidth, sampleHeight);\n  const lumaMean = lumaSum / visibleCount;\n  const lumaP05 = percentile(lumaValues, 0.05);\n  const lumaP95 = percentile(lumaValues, 0.95);\n  const saturationMean = saturationSum / visibleCount;\n  const metrics: ImageStyleMetrics = {\n    sampleCount: visibleCount,\n    uniqueColorRatio: colorCounts.size / visibleCount,\n    topColorCoverage: colorMetrics.topColorCoverage,\n    paletteEntropy: colorMetrics.paletteEntropy,\n    flatRatio: neighborMetrics.flatRatio,\n    softChangeRatio: neighborMetrics.softChangeRatio,\n    strongEdgeRatio: neighborMetrics.strongEdgeRatio,\n    edgeDensity: edgeMetrics.edgeDensity,\n    horizontalEdgeRatio: edgeMetrics.horizontalEdgeRatio,\n    verticalEdgeRatio: edgeMetrics.verticalEdgeRatio,\n    lumaStdDev: Math.sqrt(\n      Math.max(0, lumaSquareSum / visibleCount - lumaMean * lumaMean)\n    ),\n    lumaP05,\n    lumaP95,\n    lumaRange: lumaP95 - lumaP05,\n    saturationMean,\n    saturationStdDev: Math.sqrt(\n      Math.max(\n        0,\n        saturationSquareSum / visibleCount - saturationMean * saturationMean\n      )\n    ),\n    darkRatio: darkCount / visibleCount,\n    lightRatio: lightCount / visibleCount,\n    grayRatio: grayCount / visibleCount,\n    highSaturationRatio: highSaturationCount / visibleCount,\n    warmPaperRatio: warmPaperCount / visibleCount,\n    redRatio: redCount / visibleCount,\n    darkNeutralRatio: darkNeutralCount / visibleCount,\n    photoTileRatio: tileMetrics.photoTileRatio,\n    flatTileRatio: tileMetrics.flatTileRatio,\n    textTileRatio: tileMetrics.textTileRatio,\n    gradientTileRatio: tileMetrics.gradientTileRatio,\n    transparentRatio: transparentCount / samples.length,\n  };\n\n  const photoScore = getPhotoScore(metrics);\n  const confidence = clamp01(Math.abs(photoScore - photoThreshold) * 2);\n  const style = photoScore >= photoThreshold ? \"photo\" : \"illustration\";\n  const kindScores = getImageKindScores(metrics, photoScore);\n  const kind = getBestKind(kindScores);\n\n  return {\n    style,\n    kind,\n    kindScores,\n    confidence,\n    photoScore,\n    metrics,\n  };\n}\n\nexport function classifyCanvasImageStyle(\n  canvas: CanvasLike,\n  options: ClassifyImageStyleOptions = {}\n): ImageStyleClassification {\n  const ctx = canvas.getContext(\"2d\");\n\n  if (!ctx) {\n    throw new Error(\"Unable to read image data from canvas.\");\n  }\n\n  return classifyImageStyle(\n    ctx.getImageData(0, 0, canvas.width, canvas.height),\n    options\n  );\n}\n\nexport function isPhotoImage(\n  image: ImageDataLike,\n  options: ClassifyImageStyleOptions = {}\n): boolean {\n  return classifyImageStyle(image, options).style === \"photo\";\n}\n\nexport function isIllustrationImage(\n  image: ImageDataLike,\n  options: ClassifyImageStyleOptions = {}\n): boolean {\n  return classifyImageStyle(image, options).style === \"illustration\";\n}\n\nfunction validateImageData(image: ImageDataLike) {\n  if (!image || image.width <= 0 || image.height <= 0) {\n    throw new Error(\"Image data must have a positive width and height.\");\n  }\n\n  if (!image.data || image.data.length < image.width * image.height * 4) {\n    throw new Error(\"Image data does not contain enough RGBA pixel data.\");\n  }\n}\n\nfunction getNeighborMetrics(\n  samples: Sample[],\n  width: number,\n  height: number\n): Pick<ImageStyleMetrics, \"flatRatio\" | \"softChangeRatio\" | \"strongEdgeRatio\"> {\n  let neighborCount = 0;\n  let flatCount = 0;\n  let softChangeCount = 0;\n  let strongEdgeCount = 0;\n\n  for (let y = 0; y < height; y += 1) {\n    for (let x = 0; x < width; x += 1) {\n      const sample = samples[y * width + x];\n\n      if (!sample.visible) {\n        continue;\n      }\n\n      if (x + 1 < width) {\n        const neighbor = samples[y * width + x + 1];\n        if (neighbor.visible) {\n          neighborCount += 1;\n          const difference = getColorDifference(sample, neighbor);\n          if (difference <= 4) {\n            flatCount += 1;\n          } else if (difference <= 28) {\n            softChangeCount += 1;\n          } else {\n            strongEdgeCount += 1;\n          }\n        }\n      }\n\n      if (y + 1 < height) {\n        const neighbor = samples[(y + 1) * width + x];\n        if (neighbor.visible) {\n          neighborCount += 1;\n          const difference = getColorDifference(sample, neighbor);\n          if (difference <= 4) {\n            flatCount += 1;\n          } else if (difference <= 28) {\n            softChangeCount += 1;\n          } else {\n            strongEdgeCount += 1;\n          }\n        }\n      }\n    }\n  }\n\n  if (neighborCount === 0) {\n    return {\n      flatRatio: 1,\n      softChangeRatio: 0,\n      strongEdgeRatio: 0,\n    };\n  }\n\n  return {\n    flatRatio: flatCount / neighborCount,\n    softChangeRatio: softChangeCount / neighborCount,\n    strongEdgeRatio: strongEdgeCount / neighborCount,\n  };\n}\n\nfunction getColorDistributionMetrics(\n  colorCounts: Map<number, number>,\n  sampleCount: number\n): Pick<ImageStyleMetrics, \"topColorCoverage\" | \"paletteEntropy\"> {\n  if (sampleCount === 0) {\n    return {\n      topColorCoverage: 0,\n      paletteEntropy: 0,\n    };\n  }\n\n  const counts = [...colorCounts.values()].sort((a, b) => b - a);\n  const topCount = counts\n    .slice(0, 8)\n    .reduce((total, count) => total + count, 0);\n  const entropy = counts.reduce((total, count) => {\n    const probability = count / sampleCount;\n    return total - probability * Math.log2(probability);\n  }, 0);\n  const maxEntropy = Math.log2(Math.max(2, colorCounts.size));\n\n  return {\n    topColorCoverage: topCount / sampleCount,\n    paletteEntropy: maxEntropy === 0 ? 0 : entropy / maxEntropy,\n  };\n}\n\nfunction getEdgeMetrics(\n  samples: Sample[],\n  width: number,\n  height: number\n): Pick<\n  ImageStyleMetrics,\n  \"edgeDensity\" | \"horizontalEdgeRatio\" | \"verticalEdgeRatio\"\n> {\n  let checkedCount = 0;\n  let edgeCount = 0;\n  let horizontalCount = 0;\n  let verticalCount = 0;\n\n  for (let y = 1; y < height - 1; y += 1) {\n    for (let x = 1; x < width - 1; x += 1) {\n      const center = samples[y * width + x];\n      const left = samples[y * width + x - 1];\n      const right = samples[y * width + x + 1];\n      const up = samples[(y - 1) * width + x];\n      const down = samples[(y + 1) * width + x];\n\n      if (\n        !center.visible ||\n        !left.visible ||\n        !right.visible ||\n        !up.visible ||\n        !down.visible\n      ) {\n        continue;\n      }\n\n      checkedCount += 1;\n      const dx = Math.abs(right.luma - left.luma);\n      const dy = Math.abs(down.luma - up.luma);\n      const magnitude = Math.sqrt(dx * dx + dy * dy);\n\n      if (magnitude >= 42) {\n        edgeCount += 1;\n        if (dy > dx * 1.2) {\n          horizontalCount += 1;\n        } else if (dx > dy * 1.2) {\n          verticalCount += 1;\n        }\n      }\n    }\n  }\n\n  if (checkedCount === 0 || edgeCount === 0) {\n    return {\n      edgeDensity: 0,\n      horizontalEdgeRatio: 0,\n      verticalEdgeRatio: 0,\n    };\n  }\n\n  return {\n    edgeDensity: edgeCount / checkedCount,\n    horizontalEdgeRatio: horizontalCount / edgeCount,\n    verticalEdgeRatio: verticalCount / edgeCount,\n  };\n}\n\nfunction getTileMetrics(\n  samples: Sample[],\n  width: number,\n  height: number\n): Pick<\n  ImageStyleMetrics,\n  \"photoTileRatio\" | \"flatTileRatio\" | \"textTileRatio\" | \"gradientTileRatio\"\n> {\n  const tileSize = Math.max(8, Math.floor(Math.min(width, height) / 10));\n  let tileCount = 0;\n  let photoTileCount = 0;\n  let flatTileCount = 0;\n  let textTileCount = 0;\n  let gradientTileCount = 0;\n\n  for (let tileY = 0; tileY < height; tileY += tileSize) {\n    for (let tileX = 0; tileX < width; tileX += tileSize) {\n      const tile = getTileStats(samples, width, height, tileX, tileY, tileSize);\n      if (!tile) continue;\n\n      tileCount += 1;\n\n      if (\n        tile.edgeDensity >= 0.16 &&\n        tile.grayRatio >= 0.55 &&\n        tile.lumaStdDev >= 38\n      ) {\n        textTileCount += 1;\n      }\n\n      if (tile.uniqueColorRatio <= 0.12 && tile.flatRatio >= 0.62) {\n        flatTileCount += 1;\n      }\n\n      if (\n        tile.uniqueColorRatio >= 0.18 &&\n        tile.lumaStdDev >= 18 &&\n        tile.flatRatio <= 0.68\n      ) {\n        photoTileCount += 1;\n      }\n\n      if (\n        tile.softChangeRatio >= 0.38 &&\n        tile.strongEdgeRatio <= 0.16 &&\n        tile.lumaStdDev >= 12\n      ) {\n        gradientTileCount += 1;\n      }\n    }\n  }\n\n  if (tileCount === 0) {\n    return {\n      photoTileRatio: 0,\n      flatTileRatio: 0,\n      textTileRatio: 0,\n      gradientTileRatio: 0,\n    };\n  }\n\n  return {\n    photoTileRatio: photoTileCount / tileCount,\n    flatTileRatio: flatTileCount / tileCount,\n    textTileRatio: textTileCount / tileCount,\n    gradientTileRatio: gradientTileCount / tileCount,\n  };\n}\n\nfunction getTileStats(\n  samples: Sample[],\n  width: number,\n  height: number,\n  tileX: number,\n  tileY: number,\n  tileSize: number\n) {\n  const colors = new Set<number>();\n  let visibleCount = 0;\n  let grayCount = 0;\n  let lumaSum = 0;\n  let lumaSquareSum = 0;\n  let neighborCount = 0;\n  let flatCount = 0;\n  let softChangeCount = 0;\n  let strongEdgeCount = 0;\n\n  const maxY = Math.min(height, tileY + tileSize);\n  const maxX = Math.min(width, tileX + tileSize);\n\n  for (let y = tileY; y < maxY; y += 1) {\n    for (let x = tileX; x < maxX; x += 1) {\n      const sample = samples[y * width + x];\n      if (!sample.visible) continue;\n\n      visibleCount += 1;\n      lumaSum += sample.luma;\n      lumaSquareSum += sample.luma * sample.luma;\n      if (sample.saturation <= 0.08) grayCount += 1;\n      colors.add(getQuantizedColorKey(sample.red, sample.green, sample.blue));\n\n      if (x + 1 < maxX) {\n        const neighbor = samples[y * width + x + 1];\n        if (neighbor.visible) {\n          const difference = getColorDifference(sample, neighbor);\n          neighborCount += 1;\n          if (difference <= 4) flatCount += 1;\n          else if (difference <= 28) softChangeCount += 1;\n          else strongEdgeCount += 1;\n        }\n      }\n\n      if (y + 1 < maxY) {\n        const neighbor = samples[(y + 1) * width + x];\n        if (neighbor.visible) {\n          const difference = getColorDifference(sample, neighbor);\n          neighborCount += 1;\n          if (difference <= 4) flatCount += 1;\n          else if (difference <= 28) softChangeCount += 1;\n          else strongEdgeCount += 1;\n        }\n      }\n    }\n  }\n\n  if (visibleCount < Math.max(12, (tileSize * tileSize) / 4)) return null;\n\n  const lumaMean = lumaSum / visibleCount;\n  const strongEdgeRatio = neighborCount === 0 ? 0 : strongEdgeCount / neighborCount;\n\n  return {\n    uniqueColorRatio: colors.size / visibleCount,\n    grayRatio: grayCount / visibleCount,\n    flatRatio: neighborCount === 0 ? 1 : flatCount / neighborCount,\n    softChangeRatio: neighborCount === 0 ? 0 : softChangeCount / neighborCount,\n    strongEdgeRatio,\n    edgeDensity: strongEdgeRatio,\n    lumaStdDev: Math.sqrt(\n      Math.max(0, lumaSquareSum / visibleCount - lumaMean * lumaMean)\n    ),\n  };\n}\n\nfunction getPhotoScore(metrics: ImageStyleMetrics): number {\n  const uniqueScore = normalize(metrics.uniqueColorRatio, 0.08, 0.35);\n  const softChangeScore = normalize(metrics.softChangeRatio, 0.18, 0.48);\n  const textureScore = normalize(1 - metrics.flatRatio, 0.2, 0.65);\n  const lumaScore = normalize(metrics.lumaStdDev, 24, 72);\n  const saturationSpreadScore = normalize(metrics.saturationStdDev, 0.08, 0.26);\n  const entropyScore = normalize(metrics.paletteEntropy, 0.55, 0.9);\n  const photoTileScore = normalize(metrics.photoTileRatio, 0.18, 0.62);\n  const desaturatedPhotoScore = Math.min(\n    normalize(metrics.grayRatio, 0.45, 0.75),\n    normalize(metrics.photoTileRatio, 0.34, 0.58),\n    normalize(metrics.lumaStdDev, 48, 76),\n    normalize(1 - metrics.flatRatio, 0.34, 0.58),\n    normalize(metrics.paletteEntropy, 0.62, 0.88)\n  );\n  const flatIllustrationPenalty = normalize(metrics.flatRatio, 0.55, 0.88);\n  const topColorPenalty = normalize(metrics.topColorCoverage, 0.45, 0.86);\n  const hardEdgePenalty =\n    metrics.flatRatio > 0.35\n      ? normalize(metrics.strongEdgeRatio, 0.28, 0.58)\n      : 0;\n\n  return clamp01(\n    uniqueScore * 0.34 +\n      softChangeScore * 0.22 +\n      textureScore * 0.16 +\n      lumaScore * 0.1 +\n      saturationSpreadScore * 0.06 +\n      entropyScore * 0.07 +\n      photoTileScore * 0.13 +\n      desaturatedPhotoScore * 0.24 -\n      flatIllustrationPenalty * 0.12 -\n      topColorPenalty * 0.1 -\n      hardEdgePenalty * 0.08\n  );\n}\n\nfunction getImageKindScores(\n  metrics: ImageStyleMetrics,\n  photoScore: number\n): Record<ImageKind, number> {\n  const contrastEndpointRatio = metrics.darkRatio + metrics.lightRatio;\n  const photoTileLineArtPenalty = normalize(metrics.photoTileRatio, 0.32, 0.58);\n  const lowUsableRangeScore = normalize(92 - metrics.lumaRange, 0, 72);\n\n  return {\n    photo: clamp01(\n      photoScore * 0.55 +\n        normalize(metrics.photoTileRatio, 0.12, 0.62) * 0.25 +\n        normalize(metrics.paletteEntropy, 0.55, 0.9) * 0.12 +\n        normalize(metrics.softChangeRatio, 0.22, 0.48) * 0.08\n    ),\n    lowContrastPhoto: clamp01(\n      photoScore * 0.38 +\n        normalize(34 - metrics.lumaStdDev, 0, 22) * 0.24 +\n        lowUsableRangeScore * 0.22 +\n        normalize(metrics.gradientTileRatio, 0.16, 0.55) * 0.18 +\n        normalize(metrics.softChangeRatio, 0.24, 0.5) * 0.1\n    ),\n    highContrastPhoto: clamp01(\n      photoScore * 0.42 +\n        normalize(metrics.lumaStdDev, 58, 92) * 0.3 +\n        normalize(contrastEndpointRatio, 0.18, 0.42) * 0.18 +\n        normalize(metrics.photoTileRatio, 0.18, 0.58) * 0.1\n    ),\n    flatIllustration: clamp01(\n      (1 - photoScore) * 0.32 +\n        normalize(metrics.flatRatio, 0.52, 0.9) * 0.2 +\n        normalize(metrics.topColorCoverage, 0.38, 0.85) * 0.22 +\n        normalize(metrics.flatTileRatio, 0.18, 0.72) * 0.18 +\n        normalize(metrics.highSaturationRatio, 0.08, 0.38) * 0.08\n    ),\n    lineArt: clamp01(\n      normalize(metrics.grayRatio, 0.48, 0.9) * 0.28 +\n        normalize(metrics.edgeDensity, 0.05, 0.22) * 0.24 +\n        normalize(metrics.flatRatio, 0.5, 0.86) * 0.18 +\n        normalize(metrics.topColorCoverage, 0.45, 0.9) * 0.18 +\n        normalize(0.16 - metrics.highSaturationRatio, 0, 0.16) * 0.12 -\n        photoTileLineArtPenalty * 0.14\n    ),\n    textOrUi: clamp01(\n      normalize(metrics.textTileRatio, 0.05, 0.35) * 0.32 +\n        normalize(metrics.edgeDensity, 0.06, 0.24) * 0.22 +\n        normalize(metrics.grayRatio, 0.42, 0.86) * 0.16 +\n        normalize(metrics.topColorCoverage, 0.42, 0.86) * 0.16 +\n        normalize(metrics.flatTileRatio, 0.12, 0.58) * 0.14\n    ),\n    pixelArt: clamp01(\n      normalize(metrics.flatRatio, 0.62, 0.94) * 0.25 +\n        normalize(metrics.topColorCoverage, 0.5, 0.92) * 0.24 +\n        normalize(metrics.flatTileRatio, 0.25, 0.82) * 0.2 +\n        normalize(metrics.highSaturationRatio, 0.08, 0.45) * 0.16 +\n        normalize(0.22 - metrics.softChangeRatio, 0, 0.22) * 0.15\n    ),\n    unknown: 0,\n  };\n}\n\nfunction getBestKind(scores: Record<ImageKind, number>): ImageKind {\n  return Object.entries(scores).reduce(\n    (best, current) => (current[1] > best[1] ? current : best),\n    [\"unknown\", -Infinity]\n  )[0] as ImageKind;\n}\n\nfunction percentile(values: number[], p: number) {\n  if (!values.length) return 0;\n  const sorted = values.slice().sort((a, b) => a - b);\n  const index = Math.min(\n    sorted.length - 1,\n    Math.max(0, Math.round((sorted.length - 1) * p))\n  );\n  return sorted[index];\n}\n\nfunction getColorDifference(a: Sample, b: Sample): number {\n  const red = a.red - b.red;\n  const green = a.green - b.green;\n  const blue = a.blue - b.blue;\n\n  return Math.sqrt(red * red + green * green + blue * blue);\n}\n\nfunction getSaturation(red: number, green: number, blue: number): number {\n  const normalizedRed = red / 255;\n  const normalizedGreen = green / 255;\n  const normalizedBlue = blue / 255;\n  const max = Math.max(normalizedRed, normalizedGreen, normalizedBlue);\n  const min = Math.min(normalizedRed, normalizedGreen, normalizedBlue);\n\n  if (max === 0) {\n    return 0;\n  }\n\n  return (max - min) / max;\n}\n\nfunction isWarmPaperPixel(\n  red: number,\n  green: number,\n  blue: number,\n  luma: number,\n  saturation: number\n) {\n  return (\n    luma >= 92 &&\n    luma <= 230 &&\n    saturation >= 0.06 &&\n    saturation <= 0.56 &&\n    red >= blue + 10 &&\n    green >= blue - 6\n  );\n}\n\nfunction isRedPixel(\n  red: number,\n  green: number,\n  blue: number,\n  saturation: number\n) {\n  return saturation >= 0.34 && red >= green + 24 && red >= blue + 28;\n}\n\nfunction getQuantizedColorKey(red: number, green: number, blue: number): number {\n  return ((red >> 3) << 10) | ((green >> 3) << 5) | (blue >> 3);\n}\n\nfunction normalize(value: number, min: number, max: number): number {\n  if (max <= min) {\n    return value >= max ? 1 : 0;\n  }\n\n  return clamp01((value - min) / (max - min));\n}\n\nfunction clamp01(value: number): number {\n  return Math.min(1, Math.max(0, value));\n}\n","import type {\n  CanvasLike,\n  DitherImageOptions,\n  ImageDataLike,\n} from \"./dither/dither\";\nimport type {\n  ColorMatchingMode,\n  DynamicRangeCompressionOptions,\n  ProcessingPresetName,\n  ToneMappingOptions,\n} from \"./dither/processing\";\nimport { getProcessingPreset } from \"./dither/processing\";\nimport type { PaletteColorEntry } from \"./dither/functions/palette-order\";\nimport {\n  classifyCanvasImageStyle,\n  classifyImageStyle,\n  type ClassifyImageStyleOptions,\n  type ImageKind,\n  type ImageStyleClassification,\n} from \"./image-style\";\n\nexport type AutoProcessingIntent =\n  | \"natural\"\n  | \"vivid\"\n  | \"readable\"\n  | \"faithful\"\n  | \"lowNoise\";\n\nexport interface SuggestProcessingOptionsInput\n  extends ClassifyImageStyleOptions {\n  intent?: AutoProcessingIntent;\n}\n\nexport interface ProcessingSuggestion {\n  classification: ImageStyleClassification;\n  imageKind: ImageKind;\n  intent: AutoProcessingIntent;\n  strategy?: \"legacy\" | \"layered\";\n  ditherOptions: Partial<DitherImageOptions>;\n  reasons: string[];\n  scores: Record<string, number>;\n  pipelineSteps?: ProcessingPipelineStep[];\n}\n\nexport type AutoImageAdjustmentOptions = Pick<\n  Partial<DitherImageOptions>,\n  | \"toneMapping\"\n  | \"clarity\"\n  | \"dynamicRangeCompression\"\n  | \"levelCompression\"\n  | \"paperNormalization\"\n>;\n\nexport type AutoCanvasDitherOptions = Pick<\n  Partial<DitherImageOptions>,\n  | \"colorMatching\"\n  | \"ditheringType\"\n  | \"errorDiffusionMatrix\"\n  | \"serpentine\"\n>;\n\nexport interface AutoImageAdjustmentSuggestion {\n  classification: ImageStyleClassification;\n  imageKind: ImageKind;\n  intent: AutoProcessingIntent;\n  strategy?: ProcessingSuggestion[\"strategy\"];\n  adjustmentOptions: AutoImageAdjustmentOptions;\n  reasons: string[];\n  scores: Record<string, number>;\n}\n\nexport interface AutoCanvasDitherSuggestion {\n  classification: ImageStyleClassification;\n  imageKind: ImageKind;\n  intent: AutoProcessingIntent;\n  strategy?: ProcessingSuggestion[\"strategy\"];\n  presetName?: ProcessingPresetName;\n  ditherOptions: AutoCanvasDitherOptions;\n  reasons: string[];\n  scores: Record<string, number>;\n}\n\nexport interface ProcessingPipelineStep {\n  id: string;\n  title: string;\n  summary: string;\n  ditherOptions?: Partial<DitherImageOptions>;\n}\n\ninterface PaletteProfile {\n  colorCount: number;\n  lumaRange: number;\n  saturationRange: number;\n  averageSaturation: number;\n}\n\ninterface RecommendationBase {\n  processingPreset: ProcessingPresetName;\n  colorMatching: ColorMatchingMode;\n  errorDiffusionMatrix: string;\n  ditheringType?: DitherImageOptions[\"ditheringType\"];\n  toneMapping?: ToneMappingOptions;\n  dynamicRangeCompression?: DynamicRangeCompressionOptions;\n  levelCompression?: DitherImageOptions[\"levelCompression\"];\n  paperNormalization?: DitherImageOptions[\"paperNormalization\"];\n}\n\nconst exposureAdjustmentFromMultiplier = (multiplier: number) =>\n  Number(Math.log2(multiplier).toFixed(3));\n\nconst linearAdjustmentFromMultiplier = (multiplier: number) =>\n  Number((multiplier - 1).toFixed(3));\n\nexport function suggestProcessingOptions(\n  image: ImageDataLike,\n  palette?: PaletteColorEntry[] | string[],\n  options: SuggestProcessingOptionsInput = {}\n): ProcessingSuggestion {\n  const classification = classifyImageStyle(image, options);\n  return buildSuggestion(classification, getPaletteProfile(palette), options);\n}\n\nexport function suggestCanvasProcessingOptions(\n  canvas: CanvasLike,\n  palette?: PaletteColorEntry[] | string[],\n  options: SuggestProcessingOptionsInput = {}\n): ProcessingSuggestion {\n  const classification = classifyCanvasImageStyle(canvas, options);\n  return buildSuggestion(classification, getPaletteProfile(palette), options);\n}\n\nexport function suggestLayeredProcessingOptions(\n  image: ImageDataLike,\n  palette?: PaletteColorEntry[] | string[],\n  options: SuggestProcessingOptionsInput = {}\n): ProcessingSuggestion {\n  const classification = classifyImageStyle(image, options);\n  return buildLayeredSuggestion(\n    classification,\n    getPaletteProfile(palette),\n    options\n  );\n}\n\nexport function suggestLayeredCanvasProcessingOptions(\n  canvas: CanvasLike,\n  palette?: PaletteColorEntry[] | string[],\n  options: SuggestProcessingOptionsInput = {}\n): ProcessingSuggestion {\n  const classification = classifyCanvasImageStyle(canvas, options);\n  return buildLayeredSuggestion(\n    classification,\n    getPaletteProfile(palette),\n    options\n  );\n}\n\nexport function suggestImageAdjustmentOptions(\n  image: ImageDataLike,\n  palette?: PaletteColorEntry[] | string[],\n  options: SuggestProcessingOptionsInput = {}\n): AutoImageAdjustmentSuggestion {\n  return getImageAdjustmentSuggestion(\n    suggestLayeredProcessingOptions(image, palette, options)\n  );\n}\n\nexport function suggestCanvasImageAdjustmentOptions(\n  canvas: CanvasLike,\n  palette?: PaletteColorEntry[] | string[],\n  options: SuggestProcessingOptionsInput = {}\n): AutoImageAdjustmentSuggestion {\n  return getImageAdjustmentSuggestion(\n    suggestLayeredCanvasProcessingOptions(canvas, palette, options)\n  );\n}\n\nexport function suggestDitherOptions(\n  image: ImageDataLike,\n  palette?: PaletteColorEntry[] | string[],\n  options: SuggestProcessingOptionsInput = {}\n): AutoCanvasDitherSuggestion {\n  return getCanvasDitherSuggestion(\n    suggestLayeredProcessingOptions(image, palette, options)\n  );\n}\n\nexport function suggestCanvasDitherOptions(\n  canvas: CanvasLike,\n  palette?: PaletteColorEntry[] | string[],\n  options: SuggestProcessingOptionsInput = {}\n): AutoCanvasDitherSuggestion {\n  return getCanvasDitherSuggestion(\n    suggestLayeredCanvasProcessingOptions(canvas, palette, options)\n  );\n}\n\nfunction getImageAdjustmentSuggestion(\n  suggestion: ProcessingSuggestion\n): AutoImageAdjustmentSuggestion {\n  const { ditherOptions } = suggestion;\n  return {\n    classification: suggestion.classification,\n    imageKind: suggestion.imageKind,\n    intent: suggestion.intent,\n    strategy: suggestion.strategy,\n    adjustmentOptions: {\n      ...(ditherOptions.toneMapping\n        ? { toneMapping: ditherOptions.toneMapping }\n        : {}),\n      ...(ditherOptions.dynamicRangeCompression\n        ? { dynamicRangeCompression: ditherOptions.dynamicRangeCompression }\n        : {}),\n      ...(ditherOptions.levelCompression\n        ? { levelCompression: ditherOptions.levelCompression }\n        : {}),\n      ...(ditherOptions.paperNormalization\n        ? { paperNormalization: ditherOptions.paperNormalization }\n        : {}),\n    },\n    reasons: suggestion.reasons,\n    scores: suggestion.scores,\n  };\n}\n\nfunction getCanvasDitherSuggestion(\n  suggestion: ProcessingSuggestion\n): AutoCanvasDitherSuggestion {\n  const { ditherOptions } = suggestion;\n  const ditherOptionsOnly: AutoCanvasDitherOptions = {\n    ...(ditherOptions.colorMatching\n      ? { colorMatching: ditherOptions.colorMatching }\n      : {}),\n    ...(ditherOptions.ditheringType\n      ? { ditheringType: ditherOptions.ditheringType }\n      : {}),\n    ...(ditherOptions.errorDiffusionMatrix\n      ? { errorDiffusionMatrix: ditherOptions.errorDiffusionMatrix }\n      : {}),\n    ...(typeof ditherOptions.serpentine === \"boolean\"\n      ? { serpentine: ditherOptions.serpentine }\n      : {}),\n  };\n\n  return {\n    classification: suggestion.classification,\n    imageKind: suggestion.imageKind,\n    intent: suggestion.intent,\n    strategy: suggestion.strategy,\n    presetName:\n      typeof ditherOptions.processingPreset === \"string\"\n        ? ditherOptions.processingPreset\n        : undefined,\n    ditherOptions: ditherOptionsOnly,\n    reasons: suggestion.reasons,\n    scores: suggestion.scores,\n  };\n}\n\nfunction buildSuggestion(\n  classification: ImageStyleClassification,\n  paletteProfile: PaletteProfile | null,\n  options: SuggestProcessingOptionsInput\n): ProcessingSuggestion {\n  const intent = options.intent ?? \"natural\";\n  const reasons: string[] = [];\n  const scores = getPresetScores(classification, paletteProfile, intent);\n  const recommendedPreset = getBestScore(scores);\n  const base = getBaseRecommendation(classification.kind, recommendedPreset);\n\n  addClassificationReasons(classification, reasons);\n  addPaletteReasons(paletteProfile, reasons);\n  applyPaletteTuning(base, paletteProfile, reasons);\n  applyLearnedTuning(base, classification, intent, reasons);\n  applyLowContrastRestoreTuning(base, classification, reasons);\n  applyPosterScanTuning(base, classification, reasons);\n  applyIntent(base, intent, reasons);\n  enforceQuantizationGuard(base, classification, reasons);\n  enforceMinimumAutoContrast(base);\n  enforceAutoWhitePreservation(base, reasons);\n  if ((base.ditheringType ?? \"errorDiffusion\") === \"errorDiffusion\") {\n    reasons.push(\"Serpentine diffusion reduces directional dithering artifacts.\");\n  }\n\n  return {\n    classification,\n    imageKind: classification.kind,\n    intent,\n    strategy: \"legacy\",\n    ditherOptions: {\n      processingPreset: base.processingPreset,\n      colorMatching: base.colorMatching,\n      errorDiffusionMatrix: base.errorDiffusionMatrix,\n      ditheringType: base.ditheringType ?? \"errorDiffusion\",\n      ...((base.ditheringType ?? \"errorDiffusion\") === \"errorDiffusion\"\n        ? { serpentine: true }\n        : {}),\n      ...(base.toneMapping ? { toneMapping: base.toneMapping } : {}),\n      ...(base.dynamicRangeCompression\n        ? { dynamicRangeCompression: base.dynamicRangeCompression }\n        : {}),\n      ...(base.levelCompression ? { levelCompression: base.levelCompression } : {}),\n      ...(base.paperNormalization\n        ? { paperNormalization: base.paperNormalization }\n        : {}),\n    },\n    reasons,\n    scores,\n  };\n}\n\nfunction buildLayeredSuggestion(\n  classification: ImageStyleClassification,\n  paletteProfile: PaletteProfile | null,\n  options: SuggestProcessingOptionsInput\n): ProcessingSuggestion {\n  const intent = options.intent ?? \"natural\";\n  const reasons: string[] = [];\n  const scores = getPresetScores(classification, paletteProfile, intent);\n  const base = getLayeredBaseRecommendation(classification.kind);\n  const pipelineSteps: ProcessingPipelineStep[] = [\n    {\n      id: \"detect\",\n      title: \"Detect image kind\",\n      summary: `${classification.kind} from the untouched source image.`,\n    },\n    {\n      id: \"preset\",\n      title: \"Apply image-kind preset\",\n      summary: `${classification.kind} maps directly to ${base.processingPreset}.`,\n      ditherOptions: {\n        processingPreset: base.processingPreset,\n        ditheringType: base.ditheringType,\n        colorMatching: base.colorMatching,\n        errorDiffusionMatrix: base.errorDiffusionMatrix,\n      },\n    },\n  ];\n\n  addClassificationReasons(classification, reasons);\n  applyLayeredAutoAdjustments(base, classification, paletteProfile, reasons);\n  applyLowContrastRestoreTuning(base, classification, reasons);\n  applyPosterScanTuning(base, classification, reasons);\n  addPaletteReasons(paletteProfile, reasons);\n  applyPaletteTuning(base, paletteProfile, reasons);\n  applyIntent(base, intent, reasons);\n  enforceQuantizationGuard(base, classification, reasons);\n  enforceMinimumAutoContrast(base);\n  enforceAutoWhitePreservation(base, reasons);\n  pipelineSteps.push({\n    id: \"adjust\",\n    title: \"Apply auto adjustments\",\n    summary: describeLayeredAdjustments(base),\n    ditherOptions: {\n      toneMapping: base.toneMapping,\n      dynamicRangeCompression: base.dynamicRangeCompression,\n      levelCompression: base.levelCompression,\n      paperNormalization: base.paperNormalization,\n    },\n  });\n  pipelineSteps.push({\n    id: \"output\",\n    title: \"Dither and fit to palette\",\n    summary:\n      (base.ditheringType ?? \"errorDiffusion\") === \"quantizationOnly\"\n        ? \"Use direct palette quantization for sharp flat content.\"\n        : `Use ${base.errorDiffusionMatrix} error diffusion with serpentine scan.`,\n    ditherOptions: {\n      ditheringType: base.ditheringType ?? \"errorDiffusion\",\n      colorMatching: base.colorMatching,\n      errorDiffusionMatrix: base.errorDiffusionMatrix,\n    },\n  });\n\n  if ((base.ditheringType ?? \"errorDiffusion\") === \"errorDiffusion\") {\n    reasons.push(\"Serpentine diffusion reduces directional dithering artifacts.\");\n  }\n\n  return {\n    classification,\n    imageKind: classification.kind,\n    intent,\n    strategy: \"layered\",\n    ditherOptions: {\n      processingPreset: base.processingPreset,\n      colorMatching: base.colorMatching,\n      errorDiffusionMatrix: base.errorDiffusionMatrix,\n      ditheringType: base.ditheringType ?? \"errorDiffusion\",\n      ...((base.ditheringType ?? \"errorDiffusion\") === \"errorDiffusion\"\n        ? { serpentine: true }\n        : {}),\n      ...(base.toneMapping ? { toneMapping: base.toneMapping } : {}),\n      ...(base.dynamicRangeCompression\n        ? { dynamicRangeCompression: base.dynamicRangeCompression }\n        : {}),\n      ...(base.levelCompression ? { levelCompression: base.levelCompression } : {}),\n      ...(base.paperNormalization\n        ? { paperNormalization: base.paperNormalization }\n        : {}),\n    },\n    reasons,\n    scores,\n    pipelineSteps,\n  };\n}\n\nfunction enforceMinimumAutoContrast(recommendation: RecommendationBase) {\n  if (recommendation.toneMapping?.mode === \"contrast\") {\n    recommendation.toneMapping = {\n      ...recommendation.toneMapping,\n      contrast: Math.max(recommendation.toneMapping.contrast ?? 0, 0),\n    };\n    return;\n  }\n\n  if (recommendation.toneMapping) return;\n\n  const preset = getProcessingPreset(recommendation.processingPreset);\n  if (preset?.toneMapping.mode !== \"contrast\") return;\n  if ((preset.toneMapping.contrast ?? 0) >= 0) return;\n\n  recommendation.toneMapping = {\n    ...preset.toneMapping,\n    contrast: 0,\n  };\n}\n\nfunction enforceAutoWhitePreservation(\n  recommendation: RecommendationBase,\n  reasons: string[]\n) {\n  if (\n    !recommendation.dynamicRangeCompression ||\n    recommendation.dynamicRangeCompression.mode === \"off\"\n  ) {\n    return;\n  }\n\n  recommendation.dynamicRangeCompression = {\n    ...recommendation.dynamicRangeCompression,\n    preserveWhite: true,\n    whitePreservePercentile:\n      recommendation.dynamicRangeCompression.whitePreservePercentile ?? 0.99,\n    whitePreserveMinLuma:\n      recommendation.dynamicRangeCompression.whitePreserveMinLuma ?? 150,\n  };\n  reasons.push(\"Detected paper-white highlights are protected during range fitting.\");\n}\n\nfunction getBaseRecommendation(\n  kind: ImageKind,\n  fallbackPreset: ProcessingPresetName\n): RecommendationBase {\n  switch (kind) {\n    case \"textOrUi\":\n      return {\n        processingPreset: \"balanced\",\n        colorMatching: \"lab\",\n        errorDiffusionMatrix: \"floydSteinberg\",\n        ditheringType: \"quantizationOnly\",\n        toneMapping: {\n          mode: \"contrast\",\n          exposure: exposureAdjustmentFromMultiplier(1.05),\n          saturation: 0,\n          contrast: linearAdjustmentFromMultiplier(1.18),\n        },\n        dynamicRangeCompression: { mode: \"display\", strength: 0.75 },\n      };\n    case \"lineArt\":\n      return {\n        processingPreset: \"balanced\",\n        colorMatching: \"lab\",\n        errorDiffusionMatrix: \"floydSteinberg\",\n        ditheringType: \"quantizationOnly\",\n        toneMapping: {\n          mode: \"contrast\",\n          exposure: 0,\n          saturation: linearAdjustmentFromMultiplier(0.8),\n          contrast: linearAdjustmentFromMultiplier(1.25),\n        },\n        dynamicRangeCompression: { mode: \"display\", strength: 0.65 },\n      };\n    case \"pixelArt\":\n      return {\n        processingPreset: \"vivid\",\n        colorMatching: \"rgb\",\n        errorDiffusionMatrix: \"floydSteinberg\",\n        ditheringType: \"quantizationOnly\",\n        toneMapping: { mode: \"off\", exposure: 0, saturation: 0 },\n        dynamicRangeCompression: { mode: \"off\" },\n      };\n    case \"flatIllustration\":\n      return {\n        processingPreset: \"vivid\",\n        colorMatching: \"rgb\",\n        errorDiffusionMatrix: \"floydSteinberg\",\n        ditheringType: \"errorDiffusion\",\n        toneMapping: {\n          mode: \"scurve\",\n          saturation: linearAdjustmentFromMultiplier(1.45),\n          strength: 0.72,\n          shadowBoost: 0.08,\n          highlightCompress: -1.3,\n          midpoint: 0.5,\n        },\n      };\n    case \"unknown\":\n      return {\n        processingPreset: \"balanced\",\n        colorMatching: \"rgb\",\n        errorDiffusionMatrix: \"floydSteinberg\",\n        ditheringType: \"errorDiffusion\",\n      };\n    case \"lowContrastPhoto\":\n      return {\n        processingPreset: \"restore\",\n        colorMatching: \"lab\",\n        errorDiffusionMatrix: \"floydSteinberg\",\n        ditheringType: \"errorDiffusion\",\n        toneMapping: {\n          mode: \"scurve\",\n          exposure: exposureAdjustmentFromMultiplier(1.08),\n          saturation: linearAdjustmentFromMultiplier(0.9),\n          strength: 1,\n          shadowBoost: 0.25,\n          highlightCompress: -0.75,\n          midpoint: 0.46,\n        },\n        dynamicRangeCompression: {\n          mode: \"auto\",\n          strength: 0.9,\n          lowPercentile: 0.02,\n          highPercentile: 0.98,\n        },\n        levelCompression: {\n          mode: \"luma\",\n          black: 8,\n          white: 245,\n        },\n      };\n    case \"highContrastPhoto\":\n      return {\n        processingPreset: \"balanced\",\n        colorMatching: \"rgb\",\n        errorDiffusionMatrix: \"stucki\",\n        ditheringType: \"errorDiffusion\",\n        dynamicRangeCompression: { mode: \"display\", strength: 0.9 },\n      };\n    case \"photo\":\n      return {\n        processingPreset: fallbackPreset,\n        colorMatching: \"rgb\",\n        errorDiffusionMatrix:\n          fallbackPreset === \"soft\" ? \"stucki\" : \"floydSteinberg\",\n        ditheringType: \"errorDiffusion\",\n      };\n    default:\n      return {\n        processingPreset: \"balanced\",\n        colorMatching: \"rgb\",\n        errorDiffusionMatrix: \"floydSteinberg\",\n        ditheringType: \"errorDiffusion\",\n      };\n  }\n}\n\nfunction getLayeredBaseRecommendation(kind: ImageKind): RecommendationBase {\n  const presetName = getImageKindPreset(kind);\n  const preset = getProcessingPreset(presetName);\n\n  return {\n    processingPreset: presetName,\n    colorMatching: getImageKindColorMatching(kind, preset?.colorMatching),\n    errorDiffusionMatrix: getImageKindDiffusionMatrix(\n      kind,\n      preset?.errorDiffusionMatrix\n    ),\n    ditheringType: getImageKindDitheringType(kind),\n    toneMapping: preset?.toneMapping ? { ...preset.toneMapping } : undefined,\n    dynamicRangeCompression: preset?.dynamicRangeCompression\n      ? { ...preset.dynamicRangeCompression }\n      : undefined,\n  };\n}\n\nfunction getImageKindPreset(kind: ImageKind): ProcessingPresetName {\n  switch (kind) {\n    case \"lowContrastPhoto\":\n      return \"restore\";\n    case \"highContrastPhoto\":\n      return \"soft\";\n    case \"flatIllustration\":\n    case \"pixelArt\":\n      return \"vivid\";\n    case \"textOrUi\":\n    case \"lineArt\":\n    case \"photo\":\n    case \"unknown\":\n    default:\n      return \"balanced\";\n  }\n}\n\nfunction getImageKindColorMatching(\n  kind: ImageKind,\n  fallback: ColorMatchingMode | undefined\n): ColorMatchingMode {\n  if (kind === \"lowContrastPhoto\") return \"lab\";\n  if (kind === \"textOrUi\" || kind === \"lineArt\") return \"lab\";\n  return fallback ?? \"rgb\";\n}\n\nfunction getImageKindDiffusionMatrix(\n  kind: ImageKind,\n  fallback: string | undefined\n) {\n  if (kind === \"highContrastPhoto\") {\n    return \"stucki\";\n  }\n  if (kind === \"lowContrastPhoto\") return \"floydSteinberg\";\n  return fallback ?? \"floydSteinberg\";\n}\n\nfunction getImageKindDitheringType(\n  kind: ImageKind\n): DitherImageOptions[\"ditheringType\"] {\n  if (kind === \"textOrUi\" || kind === \"lineArt\" || kind === \"pixelArt\") {\n    return \"quantizationOnly\";\n  }\n  return \"errorDiffusion\";\n}\n\nfunction applyLayeredAutoAdjustments(\n  recommendation: RecommendationBase,\n  classification: ImageStyleClassification,\n  paletteProfile: PaletteProfile | null,\n  reasons: string[]\n) {\n  const { metrics } = classification;\n  if (isRestorableLowContrastSource(classification)) return;\n\n  switch (classification.kind) {\n    case \"lowContrastPhoto\":\n      recommendation.toneMapping = {\n        mode: \"scurve\",\n        exposure: Math.max(\n          recommendation.toneMapping?.exposure ?? 0,\n          exposureAdjustmentFromMultiplier(1.06)\n        ),\n        saturation:\n          metrics.grayRatio >= 0.72\n            ? linearAdjustmentFromMultiplier(0)\n            : Math.min(\n                recommendation.toneMapping?.saturation ??\n                  linearAdjustmentFromMultiplier(0.9),\n                linearAdjustmentFromMultiplier(1.05)\n              ),\n        strength: metrics.lumaRange <= 70 ? 1 : 0.9,\n        shadowBoost: metrics.lumaP05 >= 55 ? 0.2 : 0.28,\n        highlightCompress: -0.75,\n        midpoint: metrics.lumaP95 <= 190 ? 0.44 : 0.46,\n      };\n      recommendation.dynamicRangeCompression = {\n        mode: \"auto\",\n        strength: metrics.lumaRange <= 70 ? 0.96 : 0.88,\n        lowPercentile: 0.02,\n        highPercentile: 0.98,\n      };\n      recommendation.levelCompression = {\n        mode: \"luma\",\n        black: 8,\n        white: 245,\n      };\n      recommendation.colorMatching = metrics.grayRatio >= 0.55 ? \"lab\" : \"rgb\";\n      recommendation.errorDiffusionMatrix = \"floydSteinberg\";\n      reasons.push(\"Low contrast sources use percentile expansion before dithering.\");\n      if (metrics.grayRatio >= 0.55) {\n        reasons.push(\"Faded gray scans use LAB matching to protect tonal readability.\");\n      }\n      break;\n    case \"highContrastPhoto\":\n      recommendation.toneMapping = {\n        mode: \"contrast\",\n        exposure: 0,\n        saturation: linearAdjustmentFromMultiplier(1.05),\n        contrast: 0,\n      };\n      recommendation.dynamicRangeCompression = {\n        mode: \"display\",\n        strength: 0.85,\n      };\n      reasons.push(\"High contrast photos use neutral contrast and display fitting.\");\n      break;\n    case \"photo\":\n      if (metrics.lumaStdDev <= 42) {\n        recommendation.toneMapping = {\n          mode: \"scurve\",\n          exposure: exposureAdjustmentFromMultiplier(1.04),\n          saturation: Math.max(\n            recommendation.toneMapping?.saturation ?? 0,\n            linearAdjustmentFromMultiplier(1.12)\n          ),\n          strength: 0.66,\n          shadowBoost: 0.05,\n          highlightCompress: -1.2,\n          midpoint: 0.49,\n        };\n        recommendation.dynamicRangeCompression = {\n          mode: \"auto\",\n          strength: 0.68,\n          lowPercentile: 0.01,\n          highPercentile: 0.99,\n        };\n        reasons.push(\"Mild source range fitting lifts low-spread photo tones.\");\n      } else if (metrics.lumaStdDev >= 70) {\n        recommendation.dynamicRangeCompression = {\n          mode: \"display\",\n          strength: 0.78,\n        };\n        reasons.push(\"Wide photo luminance gets restrained before dithering.\");\n      } else {\n        recommendation.dynamicRangeCompression = {\n          mode: \"display\",\n          strength: 0.7,\n        };\n      }\n      break;\n    case \"flatIllustration\":\n      recommendation.toneMapping = {\n        mode: \"scurve\",\n        exposure: exposureAdjustmentFromMultiplier(1.06),\n        saturation: linearAdjustmentFromMultiplier(\n          metrics.highSaturationRatio >= 0.28 ? 1.35 : 1.45\n        ),\n        strength: 0.68,\n        shadowBoost: 0.06,\n        highlightCompress: -1.2,\n        midpoint: 0.5,\n      };\n      recommendation.dynamicRangeCompression = { mode: \"off\" };\n      reasons.push(\"Flat artwork starts vivid, then uses gentler curve shaping.\");\n      break;\n    case \"textOrUi\":\n      recommendation.toneMapping = {\n        mode: \"contrast\",\n        exposure: exposureAdjustmentFromMultiplier(1.04),\n        saturation: linearAdjustmentFromMultiplier(\n          metrics.grayRatio >= 0.7 ? 0.85 : 1\n        ),\n        contrast: linearAdjustmentFromMultiplier(1.2),\n      };\n      recommendation.dynamicRangeCompression = {\n        mode: \"display\",\n        strength: 0.72,\n      };\n      reasons.push(\"UI-like content gets readable contrast before quantization.\");\n      break;\n    case \"lineArt\":\n      recommendation.toneMapping = {\n        mode: \"contrast\",\n        exposure: 0,\n        saturation: linearAdjustmentFromMultiplier(0.75),\n        contrast: linearAdjustmentFromMultiplier(\n          metrics.lumaRange <= 96 ? 1.42 : 1.25\n        ),\n      };\n      recommendation.dynamicRangeCompression = {\n        mode: metrics.lumaRange <= 96 ? \"auto\" : \"display\",\n        strength: metrics.lumaRange <= 96 ? 0.9 : 0.65,\n        lowPercentile: 0.02,\n        highPercentile: 0.98,\n      };\n      recommendation.levelCompression =\n        metrics.lumaRange <= 96\n          ? { mode: \"luma\", black: 6, white: 248 }\n          : recommendation.levelCompression;\n      reasons.push(\"Line art gets desaturated contrast for cleaner edges.\");\n      break;\n    case \"pixelArt\":\n      recommendation.toneMapping = { mode: \"off\", exposure: 0, saturation: 0 };\n      recommendation.dynamicRangeCompression = { mode: \"off\" };\n      reasons.push(\"Pixel art avoids tone reshaping and diffusion texture.\");\n      break;\n    case \"unknown\":\n    default:\n      recommendation.dynamicRangeCompression = {\n        mode: \"display\",\n        strength: 0.72,\n      };\n      break;\n  }\n\n  if (\n    paletteProfile &&\n    paletteProfile.lumaRange <= 150 &&\n    recommendation.dynamicRangeCompression?.mode === \"off\"\n  ) {\n    recommendation.dynamicRangeCompression = {\n      mode: \"display\",\n      strength: 0.7,\n    };\n  }\n}\n\nfunction describeLayeredAdjustments(recommendation: RecommendationBase) {\n  const tone = recommendation.toneMapping?.mode ?? \"off\";\n  const range = recommendation.dynamicRangeCompression?.mode ?? \"off\";\n  const level = recommendation.levelCompression?.mode;\n  return `${tone} tone controls with ${range} range fitting${\n    level && level !== \"off\" ? ` and ${level} level containment` : \"\"\n  }.`;\n}\n\nfunction applyLowContrastRestoreTuning(\n  recommendation: RecommendationBase,\n  classification: ImageStyleClassification,\n  reasons: string[]\n) {\n  if (!isRestorableLowContrastSource(classification)) return;\n\n  const { metrics } = classification;\n  recommendation.processingPreset = \"restore\";\n  recommendation.colorMatching = metrics.grayRatio >= 0.55 ? \"lab\" : \"rgb\";\n  recommendation.errorDiffusionMatrix = \"floydSteinberg\";\n  recommendation.ditheringType = \"errorDiffusion\";\n  recommendation.toneMapping = {\n    mode: \"scurve\",\n    exposure: exposureAdjustmentFromMultiplier(\n      metrics.lumaP95 <= 190 ? 1.1 : 1.06\n    ),\n    saturation: linearAdjustmentFromMultiplier(\n      metrics.grayRatio >= 0.72 ? 0 : 0.9\n    ),\n    strength: metrics.lumaRange <= 70 ? 1 : 0.92,\n    shadowBoost: metrics.lumaP05 >= 55 ? 0.2 : 0.28,\n    highlightCompress: -0.75,\n    midpoint: metrics.lumaP95 <= 190 ? 0.44 : 0.46,\n  };\n  recommendation.dynamicRangeCompression = {\n    mode: \"auto\",\n    strength: metrics.lumaRange <= 70 ? 0.96 : 0.9,\n    lowPercentile: 0.02,\n    highPercentile: 0.98,\n  };\n  recommendation.levelCompression = {\n    mode: \"luma\",\n    black: 8,\n    white: 245,\n  };\n  reasons.push(\n    \"Faded low-contrast source uses restore-style range expansion before dithering.\"\n  );\n}\n\nfunction isRestorableLowContrastSource(\n  classification: ImageStyleClassification\n) {\n  const { metrics } = classification;\n  if (classification.kind === \"lowContrastPhoto\") return true;\n  if (metrics.lumaRange > 96 || metrics.lumaStdDev > 32) return false;\n  if (metrics.grayRatio < 0.5 && metrics.saturationMean > 0.18) return false;\n  if (classification.kind === \"pixelArt\") return false;\n\n  const hasRecoverableStructure =\n    metrics.edgeDensity >= 0.015 ||\n    metrics.softChangeRatio >= 0.12 ||\n    metrics.gradientTileRatio >= 0.04 ||\n    metrics.textTileRatio >= 0.04 ||\n    (metrics.lumaRange <= 70 &&\n      metrics.grayRatio >= 0.7 &&\n      metrics.paletteEntropy >= 0.35 &&\n      metrics.topColorCoverage <= 0.92);\n\n  return hasRecoverableStructure;\n}\n\nfunction applyPosterScanTuning(\n  recommendation: RecommendationBase,\n  classification: ImageStyleClassification,\n  reasons: string[]\n) {\n  if (!isWarmPosterScanSource(classification)) return;\n\n  recommendation.processingPreset = \"posterScan\";\n  recommendation.colorMatching = \"rgb\";\n  recommendation.errorDiffusionMatrix = \"floydSteinberg\";\n  recommendation.ditheringType = \"errorDiffusion\";\n  recommendation.paperNormalization = {\n    mode: \"warmPaper\",\n    strength: 0.95,\n    minLuma: 82,\n    saturationThreshold: 0.56,\n    warmBiasThreshold: 8,\n    blackAnchor: 0.95,\n    preserveRed: 0.85,\n    paperWhite: [248, 248, 246],\n  };\n  recommendation.toneMapping = {\n    mode: \"scurve\",\n    exposure: exposureAdjustmentFromMultiplier(1.04),\n    saturation: linearAdjustmentFromMultiplier(1.05),\n    strength: 0.92,\n    shadowBoost: 0.08,\n    highlightCompress: -0.55,\n    midpoint: 0.44,\n  };\n  recommendation.dynamicRangeCompression = {\n    mode: \"auto\",\n    strength: 1,\n    lowPercentile: 0.015,\n    highPercentile: 0.985,\n  };\n  recommendation.levelCompression = {\n    mode: \"luma\",\n    black: 3,\n    white: 252,\n  };\n  reasons.push(\n    \"Warm poster paper is neutralized while black and red ink are preserved.\"\n  );\n}\n\nfunction isWarmPosterScanSource(classification: ImageStyleClassification) {\n  const { metrics } = classification;\n  const hasWarmPaper = metrics.warmPaperRatio >= 0.18;\n  const hasInk =\n    metrics.darkNeutralRatio >= 0.025 ||\n    metrics.redRatio >= 0.008 ||\n    metrics.strongEdgeRatio >= 0.05;\n  const isGraphicOrPosterLike =\n    classification.kind === \"flatIllustration\" ||\n    classification.kind === \"textOrUi\" ||\n    classification.kind === \"lineArt\" ||\n    metrics.flatRatio >= 0.5 ||\n    metrics.topColorCoverage >= 0.36;\n\n  return hasWarmPaper && hasInk && isGraphicOrPosterLike;\n}\n\nfunction getPresetScores(\n  classification: ImageStyleClassification,\n  paletteProfile: PaletteProfile | null,\n  intent: AutoProcessingIntent\n): Record<string, number> {\n  const { metrics } = classification;\n  const { kindScores } = classification;\n  const scores: Record<string, number> = {\n    balanced: 0.52,\n    dynamic: 0.48,\n    vivid: 0.45,\n    soft: 0.44,\n    grayscale: 0.28,\n    restore: 0.34,\n    posterScan: 0.32,\n  };\n\n  if (classification.style === \"photo\") {\n    scores.dynamic += 0.18;\n    scores.balanced += 0.12;\n    scores.soft += metrics.lumaStdDev >= 68 ? 0.2 : 0.06;\n  } else if (classification.style === \"illustration\") {\n    scores.vivid += 0.28;\n    scores.balanced += 0.08;\n  }\n\n  scores.dynamic += kindScores.lowContrastPhoto * 0.24;\n  scores.restore += kindScores.lowContrastPhoto * 0.34;\n  scores.soft += kindScores.highContrastPhoto * 0.26;\n  scores.vivid += kindScores.flatIllustration * 0.24;\n  scores.vivid += kindScores.pixelArt * 0.18;\n  scores.balanced += (kindScores.textOrUi + kindScores.lineArt) * 0.18;\n  scores.grayscale +=\n    (kindScores.textOrUi + kindScores.lineArt) *\n    (metrics.grayRatio >= 0.7 ? 0.24 : 0.08);\n\n  if (metrics.saturationMean <= 0.1 && metrics.grayRatio >= 0.82) {\n    scores.grayscale += 0.22;\n  }\n\n  if (metrics.lumaRange <= 96 && metrics.lumaStdDev <= 38) {\n    scores.restore += 0.2;\n  }\n\n  if (isWarmPosterScanSource(classification)) {\n    scores.posterScan += 0.42;\n  }\n\n  if (paletteProfile && paletteProfile.colorCount <= 2) {\n    scores.grayscale += 0.3;\n    scores.vivid -= 0.1;\n  }\n\n  if (intent === \"vivid\") scores.vivid += 0.18;\n  if (intent === \"faithful\") scores.balanced += 0.16;\n  if (intent === \"lowNoise\") scores.soft += 0.16;\n  if (intent === \"readable\") {\n    scores.balanced += 0.14;\n    scores.grayscale += 0.1;\n  }\n\n  return scores;\n}\n\nfunction addClassificationReasons(\n  classification: ImageStyleClassification,\n  reasons: string[]\n) {\n  const { metrics } = classification;\n  reasons.push(`Detected ${classification.kind}.`);\n\n  if (metrics.flatRatio >= 0.65) {\n    reasons.push(\"Large flat regions suggest graphic-style preservation.\");\n  }\n  if (metrics.softChangeRatio >= 0.38) {\n    reasons.push(\"Soft tonal transitions suggest photo-oriented processing.\");\n  }\n  if (metrics.lumaStdDev <= 28) {\n    reasons.push(\"Low luminance spread benefits from stronger tone shaping.\");\n  }\n  if (metrics.lumaRange > 0 && metrics.lumaRange <= 96) {\n    reasons.push(\"Narrow usable luminance range benefits from percentile expansion.\");\n  }\n  if (metrics.lumaStdDev >= 72) {\n    reasons.push(\"High luminance spread benefits from softer compression.\");\n  }\n  if (metrics.strongEdgeRatio >= 0.22) {\n    reasons.push(\"Strong edges favor sharper edge handling.\");\n  }\n  if (metrics.topColorCoverage >= 0.55) {\n    reasons.push(\"Dominant repeated colors suggest careful palette matching.\");\n  }\n  if (metrics.textTileRatio >= 0.12) {\n    reasons.push(\"Text-like tiles favor readable edge handling.\");\n  }\n  if (metrics.warmPaperRatio >= 0.18) {\n    reasons.push(\"Warm paper-like background should be neutralized before matching.\");\n  }\n  if (metrics.darkNeutralRatio >= 0.025) {\n    reasons.push(\"Dark neutral ink can be anchored harder toward black.\");\n  }\n  if (metrics.photoTileRatio >= 0.4) {\n    reasons.push(\"Photo-like tiles favor smoother tonal processing.\");\n  }\n  if (metrics.edgeDensity >= 0.14) {\n    reasons.push(\"High edge density affects dithering and matching choice.\");\n  }\n}\n\nfunction addPaletteReasons(\n  paletteProfile: PaletteProfile | null,\n  reasons: string[]\n) {\n  if (!paletteProfile) return;\n\n  if (paletteProfile.colorCount <= 2) {\n    reasons.push(\"Two-color palette favors LAB matching and grayscale-safe output.\");\n  } else if (paletteProfile.averageSaturation >= 0.55) {\n    reasons.push(\"Colorful target palette can support vivid color mapping.\");\n  }\n\n  if (paletteProfile.lumaRange <= 150) {\n    reasons.push(\"Limited palette luminance range benefits from range compression.\");\n  }\n}\n\nfunction applyIntent(\n  recommendation: RecommendationBase,\n  intent: AutoProcessingIntent,\n  reasons: string[]\n) {\n  if (intent === \"vivid\") {\n    recommendation.processingPreset = \"vivid\";\n    recommendation.colorMatching = \"rgb\";\n    recommendation.toneMapping = {\n      ...recommendation.toneMapping,\n      mode: \"scurve\",\n      saturation: Math.max(\n        recommendation.toneMapping?.saturation ?? 0,\n        linearAdjustmentFromMultiplier(1.45)\n      ),\n      strength: recommendation.toneMapping?.strength ?? 0.72,\n      shadowBoost: recommendation.toneMapping?.shadowBoost ?? 0.08,\n      highlightCompress: recommendation.toneMapping?.highlightCompress ?? -1.3,\n      midpoint: recommendation.toneMapping?.midpoint ?? 0.5,\n    };\n    reasons.push(\"Vivid intent boosts saturation and color-priority matching.\");\n  } else if (intent === \"readable\") {\n    recommendation.colorMatching = \"lab\";\n    recommendation.ditheringType = \"quantizationOnly\";\n    reasons.push(\"Readable intent favors clear edges over dithering texture.\");\n  } else if (intent === \"lowNoise\") {\n    recommendation.errorDiffusionMatrix = \"stucki\";\n    recommendation.processingPreset = \"soft\";\n    reasons.push(\"Low-noise intent chooses smoother tone handling.\");\n  } else if (intent === \"faithful\") {\n    recommendation.processingPreset = \"balanced\";\n    reasons.push(\"Faithful intent keeps transformations restrained.\");\n  }\n}\n\nfunction applyLearnedTuning(\n  recommendation: RecommendationBase,\n  classification: ImageStyleClassification,\n  intent: AutoProcessingIntent,\n  reasons: string[]\n) {\n  if (intent !== \"natural\") return;\n\n  const { metrics } = classification;\n\n  if (isRestorableLowContrastSource(classification)) return;\n\n  if (\n    classification.kind === \"flatIllustration\" &&\n    metrics.grayRatio >= 0.82 &&\n    metrics.topColorCoverage >= 0.9 &&\n    (metrics.textTileRatio >= 0.1 || metrics.edgeDensity >= 0.16)\n  ) {\n    recommendation.processingPreset = \"balanced\";\n    recommendation.colorMatching = \"lab\";\n    recommendation.ditheringType = \"quantizationOnly\";\n    recommendation.toneMapping = {\n      mode: \"contrast\",\n      exposure: exposureAdjustmentFromMultiplier(1.03),\n      saturation: linearAdjustmentFromMultiplier(0.9),\n      contrast: linearAdjustmentFromMultiplier(1.2),\n    };\n    recommendation.dynamicRangeCompression = {\n      mode: \"display\",\n      strength: 0.75,\n    };\n    reasons.push(\"Pairwise ratings favored readable settings for gray UI-like artwork.\");\n    return;\n  }\n\n  if (classification.kind === \"flatIllustration\") {\n    reasons.push(\"Pairwise ratings favored gentler vivid tone mapping for flat artwork.\");\n  }\n\n  if (classification.kind === \"highContrastPhoto\") {\n    reasons.push(\"Pairwise ratings favored balanced tone handling for high-contrast photos.\");\n  }\n}\n\nfunction applyPaletteTuning(\n  recommendation: RecommendationBase,\n  paletteProfile: PaletteProfile | null,\n  reasons: string[]\n) {\n  if (!paletteProfile) return;\n\n  if (paletteProfile.colorCount <= 2) {\n    recommendation.colorMatching = \"lab\";\n    recommendation.processingPreset = \"grayscale\";\n    recommendation.toneMapping = {\n      mode: \"scurve\",\n      exposure: 0,\n      saturation: linearAdjustmentFromMultiplier(0),\n      strength: 0.8,\n      shadowBoost: 0.1,\n      highlightCompress: -1.4,\n      midpoint: 0.5,\n    };\n    reasons.push(\"Monochrome palette switches to grayscale-oriented settings.\");\n  } else if (paletteProfile.lumaRange <= 150) {\n    recommendation.dynamicRangeCompression = {\n      mode: \"display\",\n      strength: Math.max(\n        recommendation.dynamicRangeCompression?.strength ?? 0,\n        0.8\n      ),\n    };\n  }\n}\n\nfunction enforceQuantizationGuard(\n  recommendation: RecommendationBase,\n  classification: ImageStyleClassification,\n  reasons: string[]\n) {\n  if (recommendation.ditheringType !== \"quantizationOnly\") return;\n\n  if (isClearlyQuantizationFriendly(classification)) {\n    reasons.push(\n      \"Very flat artwork with little photo or gradient detail can skip dithering.\"\n    );\n    return;\n  }\n\n  recommendation.ditheringType = \"errorDiffusion\";\n  reasons.push(\"Photo-like detail or subtle gradients keep dithering enabled.\");\n}\n\nfunction isClearlyQuantizationFriendly(\n  classification: ImageStyleClassification\n) {\n  const { metrics } = classification;\n  const hasPhotoLikeDetail =\n    classification.style === \"photo\" ||\n    classification.photoScore >= 0.34 ||\n    metrics.photoTileRatio >= 0.1 ||\n    metrics.gradientTileRatio >= 0.08 ||\n    metrics.softChangeRatio >= 0.28;\n\n  if (hasPhotoLikeDetail) return false;\n\n  const hasFlatRepeatedColor =\n    metrics.flatRatio >= 0.7 &&\n    metrics.topColorCoverage >= 0.72 &&\n    metrics.paletteEntropy <= 0.72;\n  const hasClearTextOrUi =\n    metrics.textTileRatio >= 0.16 &&\n    metrics.edgeDensity >= 0.1 &&\n    metrics.grayRatio >= 0.5 &&\n    metrics.topColorCoverage >= 0.62;\n  const hasClearLineArt =\n    metrics.grayRatio >= 0.76 &&\n    metrics.edgeDensity >= 0.12 &&\n    metrics.topColorCoverage >= 0.68 &&\n    metrics.highSaturationRatio <= 0.08;\n  const hasClearPixelArt =\n    metrics.flatRatio >= 0.78 &&\n    metrics.flatTileRatio >= 0.44 &&\n    metrics.topColorCoverage >= 0.78 &&\n    metrics.softChangeRatio <= 0.16;\n\n  return (\n    hasFlatRepeatedColor &&\n    (hasClearTextOrUi || hasClearLineArt || hasClearPixelArt)\n  );\n}\n\nfunction getBestScore(scores: Record<string, number>): ProcessingPresetName {\n  return Object.entries(scores).reduce(\n    (best, current) => (current[1] > best[1] ? current : best),\n    [\"balanced\", -Infinity]\n  )[0] as ProcessingPresetName;\n}\n\nfunction getPaletteProfile(\n  palette: PaletteColorEntry[] | string[] | undefined\n): PaletteProfile | null {\n  if (!palette?.length) return null;\n\n  const colors = palette\n    .map((entry) => (typeof entry === \"string\" ? entry : entry.color))\n    .map(hexToRgb)\n    .filter((color): color is [number, number, number] => color !== null);\n\n  if (!colors.length) return null;\n\n  const lumas = colors.map(([r, g, b]) => getLuma(r, g, b));\n  const saturations = colors.map(([r, g, b]) => getSaturation(r, g, b));\n\n  return {\n    colorCount: colors.length,\n    lumaRange: Math.max(...lumas) - Math.min(...lumas),\n    saturationRange: Math.max(...saturations) - Math.min(...saturations),\n    averageSaturation:\n      saturations.reduce((sum, saturation) => sum + saturation, 0) /\n      saturations.length,\n  };\n}\n\nfunction hexToRgb(hex: string): [number, number, number] | null {\n  const normalized = hex.replace(/^#/, \"\");\n  const expanded =\n    normalized.length === 3\n      ? normalized\n          .split(\"\")\n          .map((char) => char + char)\n          .join(\"\")\n      : normalized;\n\n  if (!/^[0-9a-f]{6}$/i.test(expanded)) return null;\n\n  return [\n    parseInt(expanded.slice(0, 2), 16),\n    parseInt(expanded.slice(2, 4), 16),\n    parseInt(expanded.slice(4, 6), 16),\n  ];\n}\n\nfunction getLuma(red: number, green: number, blue: number) {\n  return red * 0.2126 + green * 0.7152 + blue * 0.0722;\n}\n\nfunction getSaturation(red: number, green: number, blue: number): number {\n  const max = Math.max(red, green, blue) / 255;\n  const min = Math.min(red, green, blue) / 255;\n\n  return max === 0 ? 0 : (max - min) / max;\n}\n","import palettes from \"./dither/data/default-palettes.json\";\nimport {\n  getNamedEntries,\n  getNamedColors,\n  getNamedDeviceColors,\n  type PaletteColorEntry,\n  type PaletteRegistry,\n} from \"./dither/functions/palette-order\";\n\nconst paletteRegistry = palettes as PaletteRegistry;\n\n/**\n * Retrieve a named default palette as combined color entries.\n *\n * `color` is the calibrated/display color used for dithering.\n * `deviceColor` is the native device color that should replace it before export.\n */\nfunction getDefaultPalette(\n  name: string,\n  deviceColorsName = name\n): PaletteColorEntry[] {\n  const entries = getNamedEntries(paletteRegistry, name);\n  if (deviceColorsName === name) {\n    return entries.map((entry) => ({ ...entry }));\n  }\n\n  const deviceEntries = getNamedEntries(paletteRegistry, deviceColorsName);\n  const deviceColorByRole = new Map(\n    deviceEntries.map((entry) => [entry.name, entry.deviceColor])\n  );\n\n  return entries.map((entry) => ({\n    ...entry,\n    deviceColor: deviceColorByRole.get(entry.name) ?? entry.deviceColor,\n  }));\n}\n\n/**\n * Retrieve a named default palette (hex codes).\n * This is used for dithering images to fit the eInk display and uses the real colors of the display.\n */\nexport function getDefaultPalettes(name: string): string[] {\n  return getNamedColors(paletteRegistry, name);\n}\n/**\n * Retrieve a named default device color set that is used for displaying the colors on the eInk display.\n */\nexport function getDeviceColors(name: string): string[] {\n  return getNamedDeviceColors(paletteRegistry, name);\n}\n\n/**\n * Retrieve device colors sorted to match the role order of a selected palette.\n */\nexport function getDeviceColorsForPalette(\n  paletteName: string,\n  deviceColorsName: string\n): string[] {\n  return getDefaultPalette(paletteName, deviceColorsName).map(\n    (entry) => entry.deviceColor\n  );\n}\n\nexport const defaultPalette = getDefaultPalette(\"default\");\nexport const genericTwoColorEinkPalette = getDefaultPalette(\n  \"generic-2-color-eink\"\n);\nexport const genericFourGrayscalePalette = getDefaultPalette(\n  \"generic-4-grayscale\"\n);\nexport const trmnlSeeed16GrayscalePalette = getDefaultPalette(\n  \"trmnl-seeed-16-grayscale\"\n);\nexport const gameboyPalette = getDefaultPalette(\"gameboy\");\nexport const spectra6legacyPalette = getDefaultPalette(\"spectra6legacy\");\nexport const spectra6Palette = getDefaultPalette(\"spectra6\");\nexport const spectra6BoeberPalette = getDefaultPalette(\"spectra6-boeber\");\nexport const spectra6OriginalPalette = getDefaultPalette(\"spectra6-original\");\nexport const spectra6OriginalPreviewPalette = getDefaultPalette(\n  \"spectra6-original-preview\"\n);\nexport const aitjcizeSpectra6Palette = getDefaultPalette(\"aitjcize-spectra6\");\nexport const acepPalette = getDefaultPalette(\"acep\");\n\nexport { replaceColors } from \"./replaceColors/replaceColors\";\nexport type {\n  ReplaceColorsOptions,\n  ReplaceColorsPalette,\n} from \"./replaceColors/replaceColors\";\n\nexport {\n  applyImageAdjustments,\n  applyImageAdjustmentsPreview,\n  applyImageDataAdjustments,\n  applyImageDataAdjustmentsAsync,\n  ditherCanvas,\n  ditherImage,\n} from \"./dither/dither\";\nexport {\n  getProcessingPreset,\n  getProcessingPresetNames,\n  getProcessingPresetOptions,\n  PROCESSING_PRESETS,\n} from \"./dither/processing\";\nexport {\n  classifyCanvasImageStyle,\n  classifyImageStyle,\n  isIllustrationImage,\n  isPhotoImage,\n} from \"./image-style\";\nexport {\n  suggestCanvasDitherOptions,\n  suggestCanvasImageAdjustmentOptions,\n  suggestLayeredCanvasProcessingOptions,\n  suggestLayeredProcessingOptions,\n  suggestDitherOptions,\n  suggestImageAdjustmentOptions,\n  suggestCanvasProcessingOptions,\n  suggestProcessingOptions,\n} from \"./auto-processing\";\n\nexport type {\n  AdjustmentPreviewOptions,\n  AdjustmentProcessingEngine,\n  AdjustmentQuality,\n  ClarityOptions,\n  ColorMatchingMode,\n  CanvasLike,\n  DitherImageOptions,\n  DitherProcessingEngine,\n  DitheringType,\n  DynamicRangeCompressionOptions,\n  EdgeAntialiasingOptions,\n  EdgePreservationOptions,\n  ImageDataLike,\n  ImageProcessingOptions,\n  LevelCompressionOptions,\n  LevelCompressionMode,\n  PaperNormalizationOptions,\n  ProcessingPreset,\n  ProcessingPresetName,\n  ToneMappingMode,\n  ToneMappingOptions,\n} from \"./dither/dither\";\nexport type {\n  ClassifyImageStyleOptions,\n  ImageKind,\n  ImageStyle,\n  ImageStyleClassification,\n  ImageStyleMetrics,\n} from \"./image-style\";\nexport type {\n  AutoCanvasDitherOptions,\n  AutoCanvasDitherSuggestion,\n  AutoImageAdjustmentOptions,\n  AutoImageAdjustmentSuggestion,\n  AutoProcessingIntent,\n  ProcessingPipelineStep,\n  ProcessingSuggestion,\n  SuggestProcessingOptionsInput,\n} from \"./auto-processing\";\nexport type { PaletteColorEntry } from \"./dither/functions/palette-order\";\n"],"x_google_ignoreList":[12],"mappings":"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CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAG;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAClS;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAAI;CAAG;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAG;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAG;CAAK;CAChS;CAAI;CAAK;CAAI;CAAI;CAAG;CAAK;CAAK;CAAK;CAAG;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAG;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CACrS;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAG;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAG;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAG;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAG;CAAK;CAAI;CAAK;CAAK;CAAI;CAC3R;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAG;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAChS;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAG;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAG;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAC/R;CAAG;CAAK;CAAK;CAAK;CAAK;CAAK;CAAG;CAAK;CAAI;CAAK;CAAK;CAAK;CAAG;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAG;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAG;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAC9R;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAG;CAAI;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAI;CAAG;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAC3R;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CACzS;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAG;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAG;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAC5R;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAG;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAG;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CACrS;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAG;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAG;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;CAAK;CAAK;CACjS;CAAI;CAAK;CAAI;CAAI;CAAI;CAAG;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAG;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAG;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAG;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAC5R;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAG;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CACpS;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAI;CAAI;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAG;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAG;CAAK;CAAI;CACjS;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAG;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAChS;CAAK;CAAI;CAAG;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAG;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAG;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAG;CAAK;CAAI;CAAI;CAAI;CAAK;CAAI;CAC3R;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAI;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAG;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAG;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CACnS;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAG;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAC/R;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAG;CAAI;CAAI;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAG;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAG;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CACjS;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CACvS;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAG;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAG;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAChS;CAAK;CAAG;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAG;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAG;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAG;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAG;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAG;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAC5R;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAI;CAAI;CAAI;CAAI;CAAI;CAAG;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAG;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAG;CAAK;CAAK;CAAK;CACzR;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CACpS;CAAK;CAAI;CAAI;CAAG;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAG;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAC5R;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAG;CAAI;CAAK;CAAK;CAAK;CAAK;CAAG;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAG;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAG;CAAI;CAAI;CAAK;CAAI;CAAI;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAC9R;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAG;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAG;CAAI;CAAK;CAAK;CAAG;CAAI;CAAI;CAAK;CAAK;CAC9R;CAAG;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAG;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CACnS;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAG;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAG;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAC9R;CAAK;CAAI;CAAI;CAAK;CAAK;CAAG;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAG;CAAK;CACjS;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAG;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAG;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CACpS;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAI;CAAK;CAAK;CAAI;CAAI;CAAG;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAG;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAG;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAG;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CACxR;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAG;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAC3S;CAAK;CAAI;CAAG;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAG;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAC5R;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAAI;CAAI;CAAK;CAAI;CAAG;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAG;CAAI;CAAK;CAChS;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAG;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAG;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CACpS;CAAG;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAAI;CAAK;CAAI;CAAG;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAG;CAAI;CAAK;CAAK;CAAI;CAAI;CAAG;CAAK;CAAI;CAAK;CAAK;CAAI;CAC7R;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAG;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAG;CAAI;CAAK;CAAI;CAAG;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAC/R;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CACpS;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAG;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAG;CAAK;CAAI;CAAK;CAAK;CAAI;CAAG;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CACnS;CAAG;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAG;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAG;CAAK;CAAI;CAAK;CAAI;CAAK;CAC/R;CAAK;CAAK;CAAI;CAAI;CAAG;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAI;CAAI;CAAK;CAAI;CAAG;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAG;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CACxR;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAG;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAG;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CACvS;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAG;CAAI;CAAK;CAAK;CAAI;CAAG;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAG;CAAI;CAAK;CAAI;CAAK;CAAG;CAAI;CAAK;CAAI;CAAK;CAAG;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CACzR;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAG;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAG;CAAI;CAAI;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAG;CAC5R;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CACxS;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAG;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAI;CAAK;CAAG;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CACnS;CAAI;CAAI;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAG;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAG;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CACxR;CAAG;CAAK;CAAI;CAAK;CAAK;CAAK;CAAG;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAG;CAAK;CAAK;CAAK;CAAK;CAAG;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAAG;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAG;CAAK;CAAK;CAAK;CAAK;CAAI;CAC9R;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAI;CAAI;CAAG;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAClS;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAG;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAI;CAAK;CAAI;CAAI;CAAI;CACpS;CAAK;CAAK;CAAG;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAG;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAK;CAC9R;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAG;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAG;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAG;CAAK;CAAI;CAAI;CAAG;CAC9R;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAG;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAClS;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAG;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAG;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAC9R;CAAI;CAAI;CAAI;CAAK;CAAG;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAClS;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAG;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAG;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CACpS;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAG;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAG;CAAK;CAAI;CAAI;CAAK;CAAI;CAAG;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAG;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAC3R;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAG;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAG;CAAI;CAAK;CAAK;CAAI;CAClS;CAAK;CAAK;CAAG;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAG;CAAK;CAAK;CAAK;CAAK;CAAK;CAAG;CAAK;CAAK;CAAK;CAAI;CAAG;CAAI;CAAK;CAAI;CAAG;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAI;CAAI;CAAK;CAAK;CAAK;CAC7R;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAG;CAAK;CAAI;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAI;CAAG;CAC7R;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CACzS;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAK;CAAI;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAK;CAAI;CAAG;CAAK;CAAK;CAAI;CAAI;CAAK;CAAK;CAAK;CAAG;CAAK;CAAK;CAAK;CAAK;CAAI;CAAI;CAAK;CAAI;CAAI;CAAI;CAAK;CAAI;CAAI;CA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"}