{"version":3,"file":"extract-colors.cjs","sources":["../src/extract/cleanInputs.ts","../src/color/Color.ts","../src/color/LeafGroup.ts","../src/color/RootGroup.ts","../src/extract/extractor.ts","../src/sort/AverageGroup.ts","../src/sort/AverageManager.ts","../src/sort/sortColors.ts","../src/helpers.ts","../src/color/FinalColor.ts","../src/extractColors.ts"],"sourcesContent":["import { BrowserOptions, OptionsCleaned } from \"../types/Options\";\n\n/**\n * Default extractor values\n */\nexport const EXTRACTOR_PIXELS_DEFAULT = 64000;\nexport const EXTRACTOR_DISTANCE_DEFAULT = 0.22;\n\n/**\n * Default average values\n */\nexport const AVERAGE_HUE_DEFAULT = 1 / 12;\nexport const AVERAGE_SATURATION_DEFAULT = 1 / 5;\nexport const AVERAGE_LIGHTNESS_DEFAULT = 1 / 5;\n\nexport function testInputs({\n  pixels = EXTRACTOR_PIXELS_DEFAULT,\n  distance = EXTRACTOR_DISTANCE_DEFAULT,\n  colorValidator = (\n    _red: number,\n    _green: number,\n    _blue: number,\n    _alpha?: number\n  ) => (_alpha ?? 255) > 250,\n  hueDistance = AVERAGE_HUE_DEFAULT,\n  saturationDistance = AVERAGE_LIGHTNESS_DEFAULT,\n  lightnessDistance = AVERAGE_SATURATION_DEFAULT,\n  crossOrigin = \"\",\n  requestMode = \"cors\",\n}: BrowserOptions = {}) {\n  /**\n   * Test if value is an integer.\n   */\n  const testUint = (\n    label: string,\n    val: number,\n    min = 0,\n    max = Number.MAX_SAFE_INTEGER\n  ) => {\n    if (!Number.isInteger(val)) {\n      throw new Error(`${label} is not a valid number (${val})`);\n    }\n\n    if (val < min) {\n      console.warn(`${label} can not be less than ${min} (it's ${val})`);\n    }\n\n    if (val > max) {\n      console.warn(`${label} can not be more than ${max} (it's ${val})`);\n    }\n\n    return Math.min(Math.max(val, min), max);\n  };\n\n  /**\n   * Test if value is a number.\n   */\n  const testNumber = (\n    label: string,\n    val: number,\n    min = 0,\n    max = Number.MAX_VALUE\n  ) => {\n    if (Number(val) !== val) {\n      throw new Error(`${label} is not a valid number (${val})`);\n    }\n\n    if (val < min) {\n      console.warn(`${label} can not be less than ${min} (it's ${val})`);\n    }\n\n    if (val > max) {\n      console.warn(`${label} can not be more than ${max} (it's ${val})`);\n    }\n\n    return Math.min(Math.max(val, min), max);\n  };\n\n  /**\n   * Test if value is a function.\n   */\n  const testFunction = <T = () => void>(label: string, val: T) => {\n    if (!val || {}.toString.call(val) !== \"[object Function]\") {\n      throw new Error(`${label} is not a function (${val})`);\n    }\n\n    return val;\n  };\n\n  /**\n   * Test if value is in the list of values\n   */\n  const testValueInList = <T>(label: string, val: T, list: T[]) => {\n    if (list.indexOf(val) < 0) {\n      console.warn(\n        `${label} can be one of this values ${list\n          .map((v) => `\"${v}\"`)\n          .join(\", \")} (it's \"${val}\")`\n      );\n    }\n  };\n\n  testUint(\"pixels\", pixels || 0, 1);\n  testNumber(\"distance\", distance, 0, 1);\n  testFunction(\"colorValidator\", colorValidator);\n  testNumber(\"hueDistance\", hueDistance, 0, 1);\n  testNumber(\"saturationDistance\", saturationDistance, 0, 1);\n  testNumber(\"lightnessDistance\", lightnessDistance, 0, 1);\n  testValueInList(\"crossOrigin\", crossOrigin, [\n    \"\",\n    \"anonymous\",\n    \"use-credentials\",\n  ]);\n  testValueInList(\"requestMode\", requestMode, [\n    \"cors\",\n    \"navigate\",\n    \"no-cors\",\n    \"same-origin\",\n  ]);\n}\n\nexport default ({\n  pixels = EXTRACTOR_PIXELS_DEFAULT,\n  distance = EXTRACTOR_DISTANCE_DEFAULT,\n  colorValidator = (\n    _red: number,\n    _green: number,\n    _blue: number,\n    _alpha?: number\n  ) => (_alpha ?? 255) > 250,\n  hueDistance = AVERAGE_HUE_DEFAULT,\n  saturationDistance = AVERAGE_LIGHTNESS_DEFAULT,\n  lightnessDistance = AVERAGE_SATURATION_DEFAULT,\n  crossOrigin = \"\",\n  requestMode = \"cors\",\n}: BrowserOptions = {}): OptionsCleaned => {\n  return [\n    Math.max(pixels, 1),\n    Math.min(Math.max(distance, 0), 1),\n    colorValidator,\n    Math.min(Math.max(hueDistance, 0), 1),\n    Math.min(Math.max(saturationDistance, 0), 1),\n    Math.min(Math.max(lightnessDistance, 0), 1),\n    crossOrigin,\n    requestMode,\n  ];\n};\n","/**\n * Informations like saturation or count of pixels in image.\n *\n * @class\n * @classdesc Calculate some informations and store data about color.\n */\nexport default class Color {\n  _red: number;\n  _green: number;\n  _blue: number;\n  _hex: number;\n  _count = 1;\n\n  private __saturation = -1;\n  private __hue = -1;\n  private __lightness = -1;\n  private __intensity = -1;\n\n  /**\n   * Set red, green and blue colors to create the Color object.\n   */\n  constructor(\n    red: number,\n    green: number,\n    blue: number,\n    hex = (red << 16) | (green << 8) | blue\n  ) {\n    this._red = red;\n    this._green = green;\n    this._blue = blue;\n    this._hex = hex;\n  }\n\n  /**\n   * Distance between two colors.\n   * - Minimum is 0 (between two same colors)\n   * - Maximum is 1 (for example between black and white)\n   */\n  static distance(colorA: Color, colorB: Color) {\n    return (\n      (Math.abs(colorB._red - colorA._red) +\n        Math.abs(colorB._green - colorA._green) +\n        Math.abs(colorB._blue - colorA._blue)) /\n      (3 * 0xff)\n    );\n  }\n\n  clone() {\n    const color = new Color(this._red, this._green, this._blue, this._hex);\n    color._count = this._count;\n    return color;\n  }\n\n  updateHSL() {\n    const red = this._red / 255;\n    const green = this._green / 255;\n    const blue = this._blue / 255;\n\n    const max = Math.max(red, green, blue);\n    const min = Math.min(red, green, blue);\n\n    this.__lightness = (max + min) / 2;\n\n    // achromatic\n    if (max === min) {\n      this.__hue = 0;\n      this.__saturation = 0;\n      this.__intensity = 0;\n    } else {\n      const distance = max - min;\n\n      this.__saturation =\n        this.__lightness > 0.5\n          ? distance / (2 - max - min)\n          : distance / (max + min);\n      this.__intensity =\n        this.__saturation * ((0.5 - Math.abs(0.5 - this.__lightness)) * 2);\n      switch (max) {\n        case red:\n          this.__hue = ((green - blue) / distance + (green < blue ? 6 : 0)) / 6;\n          break;\n        case green:\n          this.__hue = ((blue - red) / distance + 2) / 6;\n          break;\n        case blue:\n          this.__hue = ((red - green) / distance + 4) / 6;\n          break;\n      }\n    }\n  }\n\n  /**\n   * Hue from 0 to 1\n   */\n  get _hue() {\n    if (this.__hue === -1) {\n      this.updateHSL();\n    }\n    return this.__hue;\n  }\n\n  /**\n   * Saturation from 0 to 1\n   */\n  get _saturation() {\n    if (this.__saturation === -1) {\n      this.updateHSL();\n    }\n    return this.__saturation;\n  }\n\n  /**\n   * Lightness from 0 to 1\n   */\n  get _lightness() {\n    if (this.__lightness === -1) {\n      this.updateHSL();\n    }\n    return this.__lightness;\n  }\n\n  /**\n   * Color intensity from 0 to 1\n   */\n  get _intensity() {\n    if (this.__intensity === -1) {\n      this.updateHSL();\n    }\n    return this.__intensity;\n  }\n}\n","import Color from \"./Color\";\n\n/**\n * Manage list of colors to optimize and merge neighbors colors.\n *\n * @export\n * @class LeafGroup\n */\nexport default class LeafGroup {\n  _count: number;\n  _children: Record<number, Color>;\n\n  /**\n   * Store colors or groups and _count similiar groups in the image.\n   */\n  constructor() {\n    this._count = 0;\n    this._children = {};\n  }\n\n  /**\n   * Add color to the group.\n   *\n   * @param _hex Hexadecimal value of the color\n   * @param _red Red chanel amount of the color\n   * @param _green Green chanel amount of the color\n   * @param _blue Blue chanel amount of the color\n   * @returns The color\n   */\n  addColor(_hex: number, _red: number, _green: number, _blue: number) {\n    this._count++;\n    if (this._children[_hex]) {\n      this._children[_hex]._count++;\n    } else {\n      this._children[_hex] = new Color(_red, _green, _blue, _hex);\n    }\n    return this._children[_hex];\n  }\n\n  /**\n   * Get list of groups of list of colors.\n   *\n   * @returns List of colors\n   */\n  getList() {\n    return (Object.keys(this._children) as unknown[] as number[]).map(\n      (key) => this._children[key]\n    );\n  }\n\n  /**\n   * Representative color of leaf.\n   *\n   * @returns Main color of the leaf\n   */\n  createMainColor() {\n    const list = this.getList();\n    const biggest = list.reduce((a, b) => (a._count >= b._count ? a : b));\n    const main = biggest.clone();\n    main._count = this._count;\n    return main;\n  }\n}\n","import Color from \"./Color\";\nimport LeafGroup from \"./LeafGroup\";\n\n/**\n * RootGroup colors with algorithms to optimize and merge neighbors colors.\n *\n * @class\n * @classdesc Manage list of colors or groups.\n */\nexport default class RootGroup {\n  _count: number;\n  _children: Record<number, LeafGroup>;\n\n  /**\n   * Store colors or groups and _count similiar groups in the image.\n   */\n  constructor() {\n    this._count = 0;\n    this._children = {};\n  }\n\n  /**\n   * Get list of groups of list of colors.\n   */\n  getList() {\n    return (Object.keys(this._children) as unknown[] as number[]).map(\n      (key) => this._children[key]\n    );\n  }\n\n  addColor(r: number, g: number, b: number) {\n    const full = (r << 16) | (g << 8) | b;\n    const loss =\n      (((r >> 4) & 0xf) << 8) | (((g >> 4) & 0xf) << 4) | ((b >> 4) & 0xf);\n    this._count++;\n    return this.getLeafGroup(loss).addColor(full, r, g, b);\n  }\n\n  /**\n   * Add a key for a color, this key is a simplification to find neighboring colors.\n   * Neighboring colors has same key.\n   */\n  getLeafGroup(key: number) {\n    if (!this._children[key]) {\n      this._children[key] = new LeafGroup();\n    }\n    return this._children[key] as LeafGroup;\n  }\n\n  /**\n   * List of colors sorted by importance (neighboring hare calculated by distance and removed).\n   * Importance is calculated with the saturation and _count of neighboring colors.\n   */\n  getColors(_distance: number) {\n    const list = this.getList().map((child) => child.createMainColor());\n\n    list.sort((a, b) => b._count - a._count);\n\n    const newList: Color[] = [];\n    while (list.length) {\n      const current = list.shift() as Color;\n      list\n        .filter((color) => Color.distance(current, color) < _distance)\n        .forEach((near) => {\n          current._count += near._count;\n          const i = list.findIndex((color) => color === near);\n          list.splice(i, 1);\n        });\n\n      newList.push(current);\n    }\n\n    return newList;\n  }\n}\n","import RootGroup from \"../color/RootGroup\";\n\n/**\n * Run extract process and get list of colors.\n */\nexport default (\n  {\n    data,\n    width,\n    height,\n  }:\n    | ImageData\n    | { data: Uint8ClampedArray | number[]; width?: number; height?: number },\n  _pixels: number,\n  _distance: number,\n  _colorValidator: (\n    red: number,\n    green: number,\n    blue: number,\n    alpha: number\n  ) => boolean\n) => {\n  const colorGroup = new RootGroup();\n  const reducer =\n    width && height ? Math.floor((width * height) / _pixels) || 1 : 1;\n  let ignoredColorsCount = 0;\n\n  for (let i = 0; i < data.length; i += 4 * reducer) {\n    const r = data[i]; // 0 -> 255\n    const g = data[i + 1];\n    const b = data[i + 2];\n    const a = data[i + 3];\n\n    if (_colorValidator(r, g, b, a)) {\n      colorGroup.addColor(r, g, b);\n    } else {\n      ignoredColorsCount++;\n    }\n  }\n\n  return {\n    colors: colorGroup.getColors(_distance),\n    count: colorGroup._count + ignoredColorsCount,\n  };\n};\n","import Color from \"../color/Color\";\n\nconst distance = (a: number, b: number) => Math.abs(a - b);\nconst hueDistance = (a: number, b: number) =>\n  Math.min(distance(a, b), distance((a + 0.5) % 1, (b + 0.5) % 1));\n\nexport class AverageGroup {\n  colors: Color[] = [];\n  private _average: Color | null = null;\n\n  addColor(color: Color) {\n    this.colors.push(color);\n    this._average = null;\n  }\n\n  isSamePalette(\n    color: Color,\n    hue: number,\n    saturation: number,\n    lightness: number\n  ) {\n    for (const currentColor of this.colors) {\n      const isSame =\n        hueDistance(currentColor._hue, color._hue) < hue &&\n        distance(currentColor._saturation, color._saturation) < saturation &&\n        distance(currentColor._lightness, color._lightness) < lightness;\n\n      if (!isSame) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  get average() {\n    if (!this._average) {\n      const { r, g, b } = this.colors.reduce(\n        (total, color) => {\n          total.r += color._red;\n          total.g += color._green;\n          total.b += color._blue;\n          return total;\n        },\n        { r: 0, g: 0, b: 0 }\n      );\n\n      const total = this.colors.reduce(\n        (_count, color) => _count + color._count,\n        0\n      );\n      this._average = new Color(\n        Math.round(r / this.colors.length),\n        Math.round(g / this.colors.length),\n        Math.round(b / this.colors.length)\n      );\n      this._average._count = total;\n    }\n    return this._average;\n  }\n}\n","import Color from \"../color/Color\";\nimport { AverageGroup } from \"./AverageGroup\";\n\nexport class AverageManager {\n  _hue: number;\n  _saturation: number;\n  _lightness: number;\n\n  private _groups: AverageGroup[] = [];\n\n  constructor(hue: number, saturation: number, lightness: number) {\n    this._hue = hue;\n    this._saturation = saturation;\n    this._lightness = lightness;\n  }\n\n  addColor(color: Color) {\n    const samePalette = this._groups.find((averageGroup) =>\n      averageGroup.isSamePalette(\n        color,\n        this._hue,\n        this._saturation,\n        this._lightness\n      )\n    );\n    if (samePalette) {\n      samePalette.addColor(color);\n    } else {\n      const averageGroup = new AverageGroup();\n      averageGroup.addColor(color);\n      this._groups.push(averageGroup);\n    }\n  }\n\n  getGroups() {\n    return this._groups.map((averageGroup) => averageGroup.average);\n  }\n}\n","import Color from \"../color/Color\";\nimport { AverageManager } from \"./AverageManager\";\n\nexport default (\n  list: Color[],\n  _pixels: number,\n  _hueDistance: number,\n  _saturationDistance: number,\n  _lightnessDistance: number\n) => {\n  const averageManager = new AverageManager(\n    _hueDistance,\n    _saturationDistance,\n    _lightnessDistance\n  );\n  list.forEach((color) => averageManager.addColor(color));\n\n  const sorted = averageManager.getGroups();\n\n  sorted.sort((a, b) => {\n    const bPower = (b._intensity + 0.1) * (0.9 - b._count / _pixels);\n    const aPower = (a._intensity + 0.1) * (0.9 - a._count / _pixels);\n    return bPower - aPower;\n  });\n  return sorted;\n};\n","import Color from \"./color/Color\";\nimport sortColors from \"./sort/sortColors\";\nimport { createFinalColor } from \"./color/FinalColor\";\n\n/**\n * Browser context detection\n *\n * @returns Is a browser context\n */\nexport const checkIsBrowser = () =>\n  typeof window !== \"undefined\" && typeof window.document !== \"undefined\";\n\n/**\n * Worker in Browser context detection\n *\n * @returns Is a worker browser context\n */\nexport const checkIsWorker = () =>\n  typeof self === \"object\" &&\n  self.constructor &&\n  self.constructor.name === \"DedicatedWorkerGlobalScope\";\n\n/**\n * Node.js context detection\n *\n * @returns Is Node.js context\n */\nexport const checkIsNode = () =>\n  typeof window === \"undefined\" &&\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-ignore\n  typeof process !== \"undefined\" &&\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-ignore\n  process.versions != null &&\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-ignore\n  process.versions.node != null;\n\n/**\n * Sort colors and generate standard list of colors.\n *\n * @param _colors List of colors\n * @param _pixels Count of pixels in the image\n * @param _hueDistance Maximal HUE distance between pixel before pixel merging\n * @param _saturationDistance Maximal saturation distance between pixel before pixel merging\n * @param _lightnessDistance Maximal lightness distance between pixel before pixel merging\n * @returns Sorted colors list\n */\nexport const sortFinalColors = (\n  _colors: Color[],\n  _pixels: number,\n  _hueDistance: number,\n  _saturationDistance: number,\n  _lightnessDistance: number,\n) => {\n  const list = sortColors(\n    _colors,\n    _pixels,\n    _hueDistance,\n    _saturationDistance,\n    _lightnessDistance,\n  );\n  return list.map((color) => createFinalColor(color, _pixels));\n};\n\n/**\n * Extract ImageData from image.\n * Reduce image to a pixel count.\n * Browser only\n *\n * @param _image HTML image element or Image Bitmap\n * @param _pixels Count of maximum pixels accepted for the calculation\n * @returns Data of the reduced image\n */\nexport const extractImageData = (\n  _image: HTMLImageElement | ImageBitmap,\n  _pixels: number,\n) => {\n  const currentPixels = _image.width * _image.height;\n  const width =\n    currentPixels < _pixels\n      ? _image.width\n      : Math.round(_image.width * Math.sqrt(_pixels / currentPixels));\n  const height =\n    currentPixels < _pixels\n      ? _image.height\n      : Math.round(_image.height * Math.sqrt(_pixels / currentPixels));\n\n  const canvas = ((width: number, height: number) => {\n    if (checkIsWorker()) {\n      return new OffscreenCanvas(width, height);\n    }\n    const canvas = document.createElement(\"canvas\");\n    canvas.width = width;\n    canvas.height = height;\n    return canvas;\n  })(width, height);\n\n  const context = canvas.getContext(\"2d\") as\n    | CanvasRenderingContext2D\n    | OffscreenCanvasRenderingContext2D;\n  context.drawImage(\n    _image,\n    0,\n    0,\n    _image.width,\n    _image.height,\n    0,\n    0,\n    width,\n    height,\n  );\n\n  return context.getImageData(0, 0, width, height);\n};\n","import { FinalColor } from \"../types/Color\";\nimport Color from \"./Color\";\n\n/**\n * Normalize color\n *\n * @param color Initial color\n * @param pixels Pixel count of this color\n *\n * @returns Normalized color\n */\nexport const createFinalColor = (color: Color, pixels: number): FinalColor => {\n  return {\n    hex: `#${\"0\".repeat(\n      6 - color._hex.toString(16).length\n    )}${color._hex.toString(16)}`,\n    red: color._red,\n    green: color._green,\n    blue: color._blue,\n    area: color._count / pixels,\n    hue: color._hue,\n    saturation: color._saturation,\n    lightness: color._lightness,\n    intensity: color._intensity,\n  };\n};\n","import cleanInputs, { testInputs } from \"./extract/cleanInputs\";\nimport extractor from \"./extract/extractor\";\nimport {\n  checkIsBrowser,\n  checkIsNode,\n  checkIsWorker,\n  extractImageData,\n  sortFinalColors,\n} from \"./helpers\";\nimport { FinalColor } from \"./types/Color\";\nimport { BrowserOptions, ImageDataAlt, NodeOptions } from \"./types/Options\";\n\n/**\n * Extract colors from an ImageData object.\n *\n * @param imageData Data of the image\n * @param options Process configuration\n * @param options.pixels Total pixel number of the resized picture for calculation\n * @param options.distance From 0 to 1 is the color distance to not have near colors (1 distance is between white and black)\n * @param options.colorValidator Test function to enable only some colors\n * @param options.saturationDistance Minimum saturation value between two colors otherwise the colors will be merged (from 0 to 1)\n * @param options.lightnessDistance inimum lightness value between two colors otherwise the colors will be merged (from 0 to 1)\n * @param options.hueDistance inimum hue value between two colors otherwise the colors will be merged (from 0 to 1)\n * @param options.crossOrigin support for CORS (only for browser)\n * @param options.requestMode support for CORS (only for Web Workers in browser)\n *\n * @returns List of extracted colors\n */\nexport const extractColorsFromImageData = (\n  imageData: ImageData | ImageDataAlt,\n  options: NodeOptions | BrowserOptions = {}\n) => {\n  if (__DEV__) {\n    testInputs(options);\n  }\n\n  const [\n    _pixels,\n    _distance,\n    _colorValidator,\n    _hueDistance,\n    _saturationDistance,\n    _lightnessDistance,\n  ] = cleanInputs(options);\n  const { colors, count } = extractor(\n    imageData,\n    _pixels,\n    _distance,\n    _colorValidator\n  );\n  return sortFinalColors(\n    colors,\n    count,\n    _hueDistance,\n    _saturationDistance,\n    _lightnessDistance\n  );\n};\n\n/**\n * Extract colors from an HTMLImageElement.\n * Browser only\n *\n * @param image HTML image element\n * @param options Process configuration\n * @param options.pixels Total pixel number of the resized picture for calculation\n * @param options.distance From 0 to 1 is the color distance to not have near colors (1 distance is between white and black)\n * @param options.colorValidator Test function to enable only some colors\n * @param options.saturationDistance Minimum saturation value between two colors otherwise the colors will be merged (from 0 to 1)\n * @param options.lightnessDistance inimum lightness value between two colors otherwise the colors will be merged (from 0 to 1)\n * @param options.hueDistance inimum hue value between two colors otherwise the colors will be merged (from 0 to 1)\n * @param options.crossOrigin support for CORS (only for browser)\n * @param options.requestMode support for CORS (only for Web Workers in browser)\n *\n * @returns List of extracted colors\n */\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nexport const extractColorsFromImage = async (\n  image: HTMLImageElement,\n  options: BrowserOptions = {}\n): Promise<FinalColor[]> => {\n  // Node.js version\n  if (checkIsNode()) {\n    if (__DEV__) {\n      throw new Error(\n        \"Use extractColors instead extractColorsFromImage for Node.js\"\n      );\n    }\n    return [];\n  }\n\n  if (__DEV__) {\n    testInputs(options);\n  }\n\n  // Browser version\n  const [\n    _pixels,\n    _distance,\n    _colorValidator,\n    _hueDistance,\n    _saturationDistance,\n    _lightnessDistance,\n    _crossOrigin,\n  ] = cleanInputs(options);\n  image.crossOrigin = _crossOrigin;\n  return new Promise((resolve: (value: FinalColor[]) => void) => {\n    const extract = (image: HTMLImageElement) => {\n      const imageData = extractImageData(image, _pixels);\n      const { colors, count } = extractor(\n        imageData,\n        _pixels,\n        _distance,\n        _colorValidator\n      );\n      resolve(\n        sortFinalColors(\n          colors,\n          count,\n          _hueDistance,\n          _saturationDistance,\n          _lightnessDistance\n        )\n      );\n    };\n\n    if (image.complete) {\n      extract(image);\n    } else {\n      const imageLoaded = () => {\n        image.removeEventListener(\"load\", imageLoaded);\n        extract(image);\n      };\n      image.addEventListener(\"load\", imageLoaded);\n    }\n  });\n};\n\nexport const extractColorsFromImageBitmap = async (\n  image: ImageBitmap,\n  options: BrowserOptions = {}\n): Promise<FinalColor[]> => {\n  // Node.js version\n  if (checkIsNode()) {\n    if (__DEV__) {\n      throw new Error(\n        \"Use extractColors instead extractColorsFromImageBitmap for Node.js\"\n      );\n    }\n    return [];\n  }\n\n  if (__DEV__) {\n    testInputs(options);\n  }\n\n  const [\n    _pixels,\n    _distance,\n    _colorValidator,\n    _hueDistance,\n    _saturationDistance,\n    _lightnessDistance,\n  ] = cleanInputs(options);\n\n  const imageData = extractImageData(image, _pixels);\n  const { colors, count } = extractor(\n    imageData,\n    _pixels,\n    _distance,\n    _colorValidator\n  );\n\n  return sortFinalColors(\n    colors,\n    count,\n    _hueDistance,\n    _saturationDistance,\n    _lightnessDistance\n  );\n};\n\n/**\n * Extract colors from a path.\n * The image will be downloaded.\n *\n * @param src Image source\n * @param options Process configuration\n * @param options.pixels Total pixel number of the resized picture for calculation\n * @param options.distance From 0 to 1 is the color distance to not have near colors (1 distance is between white and black)\n * @param options.colorValidator Test function to enable only some colors\n * @param options.saturationDistance Minimum saturation value between two colors otherwise the colors will be merged (from 0 to 1)\n * @param options.lightnessDistance inimum lightness value between two colors otherwise the colors will be merged (from 0 to 1)\n * @param options.hueDistance inimum hue value between two colors otherwise the colors will be merged (from 0 to 1)\n * @param options.crossOrigin support for CORS (only for browser)\n * @param options.requestMode support for CORS (only for Web Workers in browser)\n *\n * @returns List of extracted colors\n */\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nexport const extractColorsFromSrc = async (\n  src: string,\n  options: BrowserOptions = {}\n): Promise<FinalColor[]> => {\n  // Node.js version\n  if (checkIsNode()) {\n    if (__DEV__) {\n      throw new Error(\"Can not use extractColorsFromSrc for Node.js\");\n    }\n    return [];\n  }\n\n  if (__DEV__) {\n    testInputs(options);\n  }\n\n  // Web Worker version\n  if (checkIsWorker()) {\n    const inputs = cleanInputs(options);\n    const response = await fetch(src, { mode: inputs[7] });\n    const blob = await response.blob();\n    const bitmap = await createImageBitmap(blob);\n    const colors = await extractColorsFromImageBitmap(bitmap, options);\n    bitmap.close();\n    return colors;\n  }\n\n  // Browser version\n  const image = new Image();\n  image.src = src;\n  return extractColorsFromImage(image, options);\n};\n\n/**\n * Extract colors from a picture.\n *\n * @param picture Image, image source or image data (node.js context only support image data)\n * @param options Process configuration\n * @param options.pixels Total pixel number of the resized picture for calculation\n * @param options.distance From 0 to 1 is the color distance to not have near colors (1 distance is between white and black)\n * @param options.colorValidator Test function to enable only some colors\n * @param options.saturationDistance Minimum saturation value between two colors otherwise the colors will be merged (from 0 to 1)\n * @param options.lightnessDistance inimum lightness value between two colors otherwise the colors will be merged (from 0 to 1)\n * @param options.hueDistance inimum hue value between two colors otherwise the colors will be merged (from 0 to 1)\n * @param options.crossOrigin support for CORS (only for browser)\n * @param options.requestMode support for CORS (only for Web Workers in browser)\n *\n * @returns List of extracted colors\n */\nexport const extractColors = (\n  picture: string | HTMLImageElement | ImageData | ImageDataAlt,\n  options?: BrowserOptions\n) => {\n  // Browser version\n  if (checkIsBrowser()) {\n    if (__DEV__) {\n      if (options?.requestMode) {\n        console.warn(\n          \"options.requestMode not supported in Browser, use options.crossOrigin instead\"\n        );\n      }\n    }\n\n    if (picture instanceof Image) {\n      return extractColorsFromImage(picture, options);\n    }\n\n    if (\n      picture instanceof ImageData ||\n      (picture instanceof Object && picture.data)\n    ) {\n      return new Promise((resolve: (value: FinalColor[]) => void) => {\n        resolve(extractColorsFromImageData(picture, options));\n      });\n    }\n\n    if (typeof picture === \"string\") {\n      return extractColorsFromSrc(picture, options);\n    }\n  }\n\n  // Worker version\n  if (checkIsWorker()) {\n    if (__DEV__) {\n      if (options?.crossOrigin) {\n        console.warn(\n          \"options.crossOrigin not supported in Web Worker, use options.requestMode instead\"\n        );\n      }\n    }\n\n    if (\n      picture instanceof ImageData ||\n      (picture instanceof Object && (picture as ImageDataAlt).data)\n    ) {\n      return new Promise((resolve: (value: FinalColor[]) => void) => {\n        resolve(\n          extractColorsFromImageData(\n            picture as ImageData | ImageDataAlt,\n            options\n          )\n        );\n      });\n    }\n\n    if (typeof picture === \"string\") {\n      return extractColorsFromSrc(picture, options);\n    }\n\n    // HTMLImageElement not enable on Worker, switch to src fallback\n    if ((picture as HTMLImageElement).src) {\n      if (__DEV__) {\n        console.warn(\n          \"HTMLImageElement not enable on worker, a fallback is used to extract src from your HTMLImageElement, please send 'src' instead HTMLImageElement\"\n        );\n      }\n      return extractColorsFromSrc((picture as HTMLImageElement).src, options);\n    }\n  }\n\n  // Node.js version\n  if (checkIsNode()) {\n    if (__DEV__) {\n      if (picture instanceof String) {\n        throw new Error(\n          \"Send imageData to extractColors (Image src or HTMLImageElement not supported in Nodejs)\"\n        );\n      }\n\n      if (!(picture as ImageData).data) {\n        throw new Error(\"Send imageData to extractColors\");\n      }\n\n      if (options?.crossOrigin) {\n        console.warn(\"options.crossOrigin not supported in Node.js\");\n      }\n    }\n\n    return new Promise((resolve: (value: FinalColor[]) => void) => {\n      resolve(\n        extractColorsFromImageData(picture as ImageData | ImageDataAlt, options)\n      );\n    });\n  }\n\n  throw new Error(`Can not analyse picture`);\n};\n"],"names":["testInputs","pixels","distance","colorValidator","_red","_green","_blue","_alpha","hueDistance","AVERAGE_HUE_DEFAULT","saturationDistance","lightnessDistance","crossOrigin","requestMode","testNumber","label","val","min","max","Number","MAX_VALUE","Error","console","warn","Math","testValueInList","list","indexOf","map","v","join","MAX_SAFE_INTEGER","isInteger","testUint","toString","call","testFunction","cleanInputs","Color","constructor","red","green","blue","hex","this","_count","__saturation","__hue","__lightness","__intensity","_hex","colorA","colorB","abs","clone","color","updateHSL","_hue","_saturation","_lightness","_intensity","LeafGroup","_children","addColor","getList","Object","keys","key","createMainColor","main","reduce","a","b","RootGroup","r","g","full","loss","getLeafGroup","getColors","_distance","child","sort","newList","length","current","shift","filter","forEach","near","i","findIndex","splice","push","extractor","data","width","height","_pixels","_colorValidator","colorGroup","reducer","floor","ignoredColorsCount","colors","count","AverageGroup","_average","isSamePalette","hue","saturation","lightness","currentColor","average","total","round","AverageManager","_groups","samePalette","find","averageGroup","getGroups","checkIsWorker","self","name","checkIsNode","window","process","versions","node","sortFinalColors","_colors","_hueDistance","_saturationDistance","_lightnessDistance","averageManager","sorted","sortColors","repeat","area","intensity","createFinalColor","extractImageData","_image","currentPixels","sqrt","context","OffscreenCanvas","canvas","document","createElement","getContext","drawImage","getImageData","extractColorsFromImageData","imageData","options","__DEV__","S","extractColorsFromImage","async","image","_crossOrigin","Promise","resolve","extract","complete","imageLoaded","removeEventListener","addEventListener","extractColorsFromImageBitmap","extractColorsFromSrc","src","inputs","response","fetch","mode","blob","bitmap","createImageBitmap","close","Image","picture","ImageData","String"],"mappings":"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"}