{"version":3,"sources":["../src/index.ts","../src/utils/guards.ts","../src/utils/asserts.ts","../src/utils/collections/arrayQueue.ts","../src/utils/collections/doubleLinkedList.ts","../src/utils/collections/priorityQueue.ts","../src/utils/cache/lfu.ts","../src/math/distance/euclidean.ts","../src/math/vector.ts","../src/math/clustering/cluster.ts","../src/math/neighbor/kdtree/node.ts","../src/math/neighbor/kdtree/index.ts","../src/math/clustering/dbscan/algorithm.ts","../src/math/clustering/dbscanpp/algorithm.ts","../src/math/clustering/kmeans/algorithm.ts","../src/math/clustering/kmeans/strategy.ts","../src/math/sampling/fps.ts","../src/math/utils.ts","../src/color/difference/cie76.ts","../src/color/difference/cie94.ts","../src/color/difference/ciede2000.ts","../src/color/space/hsl.ts","../src/color/space/rgb.ts","../src/color/space/lab.ts","../src/color/space/xyz.ts","../src/color/name/colors.ts","../src/color/name/names.ts","../src/color/name/index.ts","../src/color/index.ts","../src/filter.ts","../src/extractor.ts","../src/utils/env.ts","../src/image.ts","../src/theme/basic.ts","../src/theme/dark.ts","../src/theme/light.ts","../src/theme/muted.ts","../src/theme/vivid.ts","../src/theme/index.ts","../src/palette.ts"],"sourcesContent":["export {\n  cie76,\n  cie94,\n  ciede2000,\n  Color,\n  type ColorDelta,\n  type ColorDeltaMeasure,\n  type RGB,\n  type HSL,\n  type XYZ,\n  type LAB,\n} from './color';\nexport { type ColorFilter, opacityFilter, luminanceFilter } from './filter';\nexport type { ImageSource } from './image';\nexport { type Algorithm, type Options, Palette } from './palette';\nexport type { NamedSwatch, Swatch } from './swatch';\nexport type { Theme } from './theme';\n","/**\n * Check if value is a number\n *\n * @param value - The value to check.\n * @returns True if the value is a number, false otherwise.\n */\nexport function isNumber(value: unknown): value is number {\n  return typeof value === 'number';\n}\n\n/**\n * Check if value is a string\n *\n * @param value - The value to check.\n * @returns True if the value is a string, false otherwise.\n */\nexport function isString(value: unknown): value is string {\n  return typeof value === 'string';\n}\n","import { isNumber } from './guards';\n\n/**\n * AssertionError is thrown when an assertion fails.\n */\nexport class AssertionError extends Error {\n  /**\n   * Create an AssertionError instance.\n   *\n   * @param message - The error message.\n   */\n  constructor(message: string) {\n    super(message);\n    this.name = 'AssertionError';\n  }\n}\n\n/**\n * Assert the given condition is true.\n *\n * @param condition - The condition to check.\n * @param message - The error message.\n * @throws {AssertionError} if the condition is false.\n */\nexport function assert(condition: boolean, message: string): asserts condition {\n  if (!condition) {\n    throw new AssertionError(message);\n  }\n}\n\n/**\n * Assert the given value is not null or undefined.\n *\n * @param value - The value to check.\n * @param message - The error message.\n */\nexport function assertDefined<T>(value: T, message: string): asserts value is NonNullable<T> {\n  assert(value !== undefined && value !== null, message);\n}\n\n/**\n * Assert the given value is a finite number.\n *\n * @param value - The value to check.\n * @param message - The error message.\n * @throws {AssertionError} if the value is not a finite number.\n */\nexport function assertFiniteNumber(value: unknown, message: string): asserts value is number {\n  assert(isNumber(value) && Number.isFinite(value), message);\n}\n\n/**\n * Assert the given value is an integer.\n *\n * @param value - The value to check.\n * @param message - The error message.\n * @throws {AssertionError} if the value is not an integer.\n */\nexport function assertInteger(value: unknown, message: string): asserts value is number {\n  assert(isNumber(value) && Number.isSafeInteger(value), message);\n}\n\n/**\n * Assert the given value is a positive integer.\n *\n * @param value - The value to check.\n * @param message - The error message.\n * @throws {AssertionError} if the value is not a positive integer.\n */\nexport function assertPositiveInteger(value: unknown, message: string): asserts value is number {\n  assertInteger(value, message);\n  assert(value > 0, message);\n}\n\n/**\n * Assert the given value is a number in the range [min, max].\n *\n * @param value - The value to check.\n * @param min - The minimum value.\n * @param max - The maximum value.\n * @param message - The error message.\n * @throws {AssertionError} if the value is not a number in the range [min, max].\n */\nexport function assertRange(value: unknown, min: number, max: number, message: string): asserts value is number {\n  assertFiniteNumber(value, message);\n  assert(min <= value && value <= max, message);\n}\n","import type { Queue } from './queue';\n\n/**\n * Array based queue implementation.\n *\n * @param E The type of elements.\n */\nexport class ArrayQueue<E> implements Queue<E> {\n  private readonly elements: E[];\n\n  /**\n   * Create a new ArrayQueue.\n   *\n   * @param elements The initial elements to be enqueued.\n   */\n  public constructor(...elements: E[]) {\n    this.elements = [...elements];\n  }\n\n  /**\n   * The size of this queue.\n   */\n  get size(): number {\n    return this.elements.length;\n  }\n\n  /**\n   * {@inheritDoc Queue.isEmpty}\n   */\n  isEmpty(): boolean {\n    return this.elements.length === 0;\n  }\n\n  /**\n   * {@inheritDoc Queue.push}\n   */\n  push(element: E): void {\n    this.elements.push(element);\n  }\n\n  /**\n   * {@inheritDoc Queue.pop}\n   */\n  pop(): E | undefined {\n    return this.elements.shift();\n  }\n\n  /**\n   * {@inheritDoc Queue.peek}\n   */\n  peek(): E | undefined {\n    return this.elements[0];\n  }\n\n  /**\n   * {@inheritDoc Queue.toArray}\n   */\n  toArray(): E[] {\n    return [...this.elements];\n  }\n}\n","/**\n * A node in a double linked list.\n */\nexport interface DoubleLinkedListNode<T> {\n  /**\n   * The value of the node.\n   */\n  value: T;\n\n  /**\n   * The previous node in the list.\n   */\n  prev: DoubleLinkedListNode<T> | undefined;\n\n  /**\n   * The next node in the list.\n   */\n  next: DoubleLinkedListNode<T> | undefined;\n}\n\n/**\n * Double linked list implementation.\n *\n * @typeParam T - The type of the value in the list.\n */\nexport class DoubleLinkedList<T> {\n  private first: DoubleLinkedListNode<T> | undefined;\n  private last: DoubleLinkedListNode<T> | undefined;\n  private size: number;\n\n  /**\n   * Create a new DoubleLinkedList.\n   */\n  constructor() {\n    this.first = undefined;\n    this.last = undefined;\n    this.size = 0;\n  }\n\n  /**\n   * The length of the list.\n   *\n   * @returns The length of the list.\n   */\n  get length() {\n    return this.size;\n  }\n\n  getFirst(): DoubleLinkedListNode<T> | undefined {\n    return this.first;\n  }\n\n  getLast(): DoubleLinkedListNode<T> | undefined {\n    return this.last;\n  }\n\n  /**\n   * Add a node to the first of the list.\n   *\n   * @param node - The node to add.\n   */\n  addFirst(node: DoubleLinkedListNode<T>) {\n    if (!this.last) {\n      this.last = node;\n    } else if (this.first) {\n      this.first.prev = node;\n      node.next = this.first;\n    }\n    this.first = node;\n    this.size++;\n  }\n\n  /**\n   * Remove a node from the list.\n   *\n   * @param node - The node to remove.\n   */\n  remove(node: DoubleLinkedListNode<T>) {\n    if (!node.next) {\n      if (!node.prev) {\n        if (this.first !== node || this.last !== node) {\n          // The node is not in the list\n          return;\n        }\n        // The only node\n        this.first = undefined;\n        this.last = undefined;\n      } else {\n        // The last node but not the first node\n        const last = node.prev;\n        last.next = undefined;\n        node.prev = undefined;\n        this.last = last;\n      }\n    } else if (!node.prev) {\n      // The first node but not the last node\n      const first = node.next;\n      first.prev = undefined;\n      node.next = undefined;\n      this.first = first;\n    } else {\n      // Neither the first nor the last node\n      node.prev.next = node.next;\n      node.next.prev = node.prev;\n      node.prev = undefined;\n      node.next = undefined;\n    }\n    this.size--;\n  }\n\n  /**\n   * Remove the last node from the list.\n   *\n   * @returns The last node if found, undefined otherwise.\n   */\n  removeLast(): DoubleLinkedListNode<T> | undefined {\n    const last = this.last;\n    if (last) {\n      this.remove(last);\n    }\n    return last;\n  }\n}\n","import type { Comparator } from './comparator';\nimport type { Queue } from './queue';\n\n/**\n * Binary heap based priority queue implementation.\n *\n * @param E The type of elements.\n */\nexport class PriorityQueue<E> implements Queue<E> {\n  private readonly elements: E[];\n\n  /**\n   * Create a PriorityQueue with the score function.\n   *\n   * @param comparator The comparator function to compare the elements.\n   */\n  constructor(private readonly comparator: Comparator<E>) {\n    this.elements = [];\n  }\n\n  /**\n   * The size of this queue.\n   */\n  get size(): number {\n    return this.elements.length;\n  }\n\n  /**\n   * {@inheritDoc Queue.isEmpty}\n   */\n  isEmpty(): boolean {\n    return this.elements.length === 0;\n  }\n\n  /**\n   * {@inheritDoc Queue.push}\n   */\n  push(element: E): void {\n    this.elements.push(element);\n\n    let index = this.elements.length - 1;\n    // If the index is 0, the element is root element.\n    while (index > 0) {\n      const parentIndex = Math.floor((index - 1) / 2);\n      const parentElement = this.elements[parentIndex];\n      if (this.comparator(element, parentElement) >= 0) {\n        break;\n      }\n\n      this.swap(index, parentIndex);\n      index = parentIndex;\n    }\n  }\n\n  /**\n   * {@inheritDoc Queue.pop}\n   */\n  pop(): E | undefined {\n    const rootElement = this.elements[0];\n    const lastElement = this.elements.pop();\n    // If the last element is undefined, this queue is empty.\n    if (!lastElement || this.elements.length === 0) {\n      return rootElement;\n    }\n\n    this.elements[0] = lastElement;\n\n    let index = 0;\n    const limit = this.elements.length;\n    while (index < limit) {\n      const leftChildIndex = index * 2 + 1;\n      const rightChildIndex = leftChildIndex + 1;\n\n      const leftChild = this.elements[leftChildIndex];\n      const rightChild = this.elements[rightChildIndex];\n      // If both child elements are not present, stop reordering this binary tree.\n      if (!leftChild && !rightChild) {\n        break;\n      }\n\n      if (!rightChild) {\n        if (this.comparator(lastElement, leftChild) <= 0) {\n          break;\n        }\n\n        this.swap(index, leftChildIndex);\n        index = leftChildIndex;\n        continue;\n      }\n\n      if (this.comparator(lastElement, leftChild) < 0 && this.comparator(lastElement, rightChild) < 0) {\n        break;\n      }\n\n      if (this.comparator(leftChild, rightChild) < 0) {\n        this.swap(index, leftChildIndex);\n        index = leftChildIndex;\n      } else {\n        this.swap(index, rightChildIndex);\n        index = rightChildIndex;\n      }\n    }\n    return rootElement;\n  }\n\n  /**\n   * {@inheritDoc Queue.peek}\n   */\n  peek(): E | undefined {\n    return this.elements[0];\n  }\n\n  /**\n   * {@inheritDoc Queue.toArray}\n   */\n  toArray(): E[] {\n    return [...this.elements];\n  }\n\n  private swap(index1: number, index2: number) {\n    const temporary = this.elements[index1];\n    this.elements[index1] = this.elements[index2];\n    this.elements[index2] = temporary;\n  }\n}\n","import { assertDefined, assertPositiveInteger } from '../asserts';\nimport { DoubleLinkedList, type DoubleLinkedListNode } from '../collections';\nimport type { Cache } from './cache';\n\n/**\n * Entry interface for LFU cache.\n *\n * @typeParam K - The type of the keys in the cache.\n * @typeParam V - The type of the values in the cache.\n */\ninterface Entry<K, V> {\n  /**\n   * The key of the entry.\n   */\n  readonly key: K;\n\n  /**\n   * The value of the entry.\n   */\n  readonly value: V;\n\n  /**\n   * The frequency of the entry.\n   */\n  frequency: number;\n}\n\n/**\n * LFU(Least Frequently Used) cache implementation.\n *\n * @typeParam K - The type of the keys in the cache.\n * @typeParam V - The type of the values in the cache.\n */\nexport class LFUCache<K, V> implements Cache<K, V> {\n  private readonly cache: Map<K, DoubleLinkedListNode<Entry<K, V>>>;\n  private readonly frequencyMap: Map<number, DoubleLinkedList<Entry<K, V>>>;\n  private minFrequency: number;\n\n  /**\n   * Create a new LFUCache instance.\n   *\n   * @param capacity - The capacity of the cache.\n   * @returns The LFUCache instance.\n   * @throws {AssertionError} If the capacity is not a positive integer.\n   */\n  constructor(readonly capacity: number) {\n    assertPositiveInteger(capacity, `The capacity(${capacity}) must be a positive integer`);\n    this.cache = new Map();\n    this.frequencyMap = new Map();\n    this.minFrequency = 0;\n  }\n\n  /**\n   * {@inheritDoc Cache.size}\n   */\n  get size() {\n    return this.cache.size;\n  }\n\n  /**\n   * {@inheritDoc Cache.get}\n   */\n  get(key: K): V | undefined {\n    const cached = this.cache.get(key);\n    if (!cached) {\n      return undefined;\n    }\n\n    this.updateFrequency(cached);\n    return cached.value.value;\n  }\n\n  /**\n   * {@inheritDoc Cache.put}\n   */\n  put(key: K, value: V): V | undefined {\n    const cached = this.cache.get(key);\n    // If the entry exists, update the value and increase the frequency.\n    if (cached) {\n      const previousValue = cached.value.value;\n      cached.value = { ...cached.value, value };\n      this.updateFrequency(cached);\n      return previousValue;\n    }\n\n    // If the cache is full, remove the least frequently used entry.\n    if (this.cache.size >= this.capacity) {\n      const frequencyList = this.retrieveFrequencyList(this.minFrequency);\n      const lastNode = frequencyList.removeLast();\n      assertDefined(lastNode, `The last node for frequency(${this.minFrequency}) must be defined`);\n      this.cache.delete(lastNode.value.key);\n    }\n\n    const entry: Entry<K, V> = { key, value, frequency: 1 };\n    this.minFrequency = entry.frequency;\n\n    const newNode: DoubleLinkedListNode<Entry<K, V>> = { value: entry, prev: undefined, next: undefined };\n    const frequencyList = this.retrieveFrequencyList(entry.frequency);\n    frequencyList.addFirst(newNode);\n    this.cache.set(key, newNode);\n    return undefined;\n  }\n\n  /**\n   * {@inheritDoc Cache.remove}\n   */\n  remove(key: K): boolean {\n    const node = this.cache.get(key);\n    if (!node) {\n      return false;\n    }\n\n    const frequencyList = this.retrieveFrequencyList(node.value.frequency);\n    frequencyList.remove(node);\n    this.cache.delete(key);\n    return true;\n  }\n\n  /**\n   * {@inheritDoc Cache.clear}\n   */\n  clear(): void {\n    this.cache.clear();\n    this.frequencyMap.clear();\n    this.minFrequency = 0;\n  }\n\n  private updateFrequency(node: DoubleLinkedListNode<Entry<K, V>>) {\n    const entry = node.value;\n    const oldFrequencyList = this.retrieveFrequencyList(entry.frequency);\n    oldFrequencyList.remove(node);\n\n    if (entry.frequency === this.minFrequency && oldFrequencyList.length === 0) {\n      this.minFrequency++;\n    }\n    entry.frequency++;\n\n    const newFrequencyList = this.retrieveFrequencyList(entry.frequency);\n    const newNode: DoubleLinkedListNode<Entry<K, V>> = { value: entry, prev: undefined, next: undefined };\n    newFrequencyList.addFirst(newNode);\n  }\n\n  private retrieveFrequencyList(frequency: number): DoubleLinkedList<Entry<K, V>> {\n    let frequencyList = this.frequencyMap.get(frequency);\n    if (!frequencyList) {\n      frequencyList = new DoubleLinkedList<Entry<K, V>>();\n      this.frequencyMap.set(frequency, frequencyList);\n    }\n    return frequencyList;\n  }\n}\n","import type { Point } from '../point';\n\nimport { assertFiniteNumber } from '../../utils';\nimport type { Distance, DistanceMeasure } from './function';\n\n/**\n * Calculate the Euclidean distance between two points.\n *\n * @param point1  The first point.\n * @param point2 The second point.\n * @return The Euclidean distance between two points.\n */\nexport const euclidean: DistanceMeasure = <P extends Point>(point1: P, point2: P): Distance => {\n  const squared = squaredEuclidean(point1, point2);\n  return Math.sqrt(squared) as Distance;\n};\n\n/**\n * Calculate the squared Euclidean distance between two points.\n *\n * @param point1 The first point.\n * @param point2 The second point.\n * @return The squared Euclidean distance between two points.\n */\nexport const squaredEuclidean: DistanceMeasure = <P extends Point>(point1: P, point2: P): Distance => {\n  const distance = point1.reduce((total: number, value: number, index: number): number => {\n    const delta = point2[index] - value;\n    return total + delta * delta;\n  }, 0.0);\n  assertFiniteNumber(distance, 'Either point1 or point2 contains infinite number');\n  return distance as Distance;\n};\n","import { assert, assertFiniteNumber } from '../utils';\nimport { type Distance, type DistanceMeasure, euclidean } from './distance';\nimport type { Point } from './point';\n\nconst NO_INDEX = -1;\n\nexport class Vector<P extends Point> {\n  private readonly components: P;\n\n  /**\n   * Create a new Vector instance\n   *\n   * @param source The source point.\n   */\n  constructor(source: P) {\n    const invalidIndex = source.findIndex((value: number): boolean => !Number.isFinite(value));\n    assert(invalidIndex === NO_INDEX, `The source point contain infinite number at ${invalidIndex}`);\n    this.components = [...source];\n  }\n\n  /**\n   * Return the dimension of this vector.\n   */\n  get dimension(): number {\n    return this.components.length;\n  }\n\n  /**\n   * Return a string representation of this vector.\n   *\n   * @return The string representation.\n   */\n  toString(): string {\n    return `Vector(${this.components.join(', ')})`;\n  }\n\n  /**\n   * Return an array representation of this vector.\n   *\n   * @return The array representation.\n   */\n  toArray(): P {\n    return [...this.components];\n  }\n\n  /**\n   * Clone this vector.\n   *\n   * @return The cloned vector.\n   */\n  clone(): Vector<P> {\n    return new Vector<P>(this.components);\n  }\n\n  /**\n   * Set this vector to zero vector.\n   *\n   * @return The current vector.\n   */\n  setZero(): this {\n    for (let i = 0; i < this.dimension; i++) {\n      this.components[i] = 0.0;\n    }\n    return this;\n  }\n\n  /**\n   * Add the vector or point to this vector.\n   *\n   * @param other The other vector or point.\n   * @return The current vector.\n   */\n  add(other: Vector<P> | P): this {\n    const components = other instanceof Vector ? other.components : other;\n    for (let i = 0; i < this.dimension; i++) {\n      assertFiniteNumber(components[i], `The component(${components[i]}) at ${i} is not finite number`);\n      this.components[i] += components[i];\n    }\n    return this;\n  }\n\n  /**\n   * Scale this vector by the scalar.\n   *\n   * @param scalar The scalar.\n   * @return The current vector.\n   */\n  scale(scalar: number): this {\n    assertFiniteNumber(scalar, `The scalar(${scalar}) must be a finite number`);\n    for (let i = 0; i < this.dimension; i++) {\n      this.components[i] *= scalar;\n    }\n    return this;\n  }\n\n  /**\n   * Compute the distance to the other vector or point.\n   *\n   * @param other - The other vector or point.\n   * @param distanceMeasure - The distance measure.\n   * @return The distance to the other vector or point.\n   */\n  distanceTo(other: Vector<P> | P, distanceMeasure: DistanceMeasure = euclidean): Distance {\n    const components = other instanceof Vector ? other.components : other;\n    return distanceMeasure(this.components, components);\n  }\n}\n","import { assert } from '../../utils';\nimport type { Point } from '../point';\nimport { Vector } from '../vector';\n\n/**\n * Class representing a cluster.\n *\n * @param P The type of point.\n */\nexport class Cluster<P extends Point> {\n  protected readonly centroid: Vector<P>;\n  protected readonly memberships: Set<number>;\n\n  /**\n   * Create a new Cluster instance.\n   *\n   * @param initialCentroid The initial centroid point.\n   */\n  constructor(initialCentroid: P | Vector<P>) {\n    this.centroid = initialCentroid instanceof Vector ? initialCentroid.clone() : new Vector(initialCentroid);\n    this.memberships = new Set();\n  }\n\n  /**\n   * The number of points in this cluster.\n   */\n  get size(): number {\n    return this.memberships.size;\n  }\n\n  /**\n   * Whether the cluster is empty.\n   */\n  get isEmpty(): boolean {\n    return this.memberships.size === 0;\n  }\n\n  /**\n   * Return the centroid of the cluster.\n   *\n   * @return The centroid of the cluster.\n   */\n  getCentroid(): P {\n    return this.centroid.toArray();\n  }\n\n  /**\n   * Return the indices of points in this cluster.\n   *\n   * @return The set of indices of points in this cluster.\n   */\n  getMemberships(): Set<number> {\n    return new Set(this.memberships);\n  }\n\n  /**\n   * Add a point to this cluster by index.\n   *\n   * @param index The index of the point.\n   * @param point The point to add.\n   */\n  addMember(index: number, point: P): void {\n    assert(index >= 0, `The index(${index}) is less than 0`);\n    if (this.memberships.has(index)) {\n      return;\n    }\n\n    this.centroid.scale(this.memberships.size);\n    this.centroid.add(point);\n    this.centroid.scale(1 / (this.memberships.size + 1));\n\n    // Set the membership of the point to this cluster.\n    this.memberships.add(index);\n  }\n\n  /**\n   * Clear this cluster.\n   */\n  clear(): void {\n    this.centroid.setZero();\n    this.memberships.clear();\n  }\n}\n","import { assert } from '../../../utils';\n\n/**\n * The node of KDTree\n */\nexport class Node {\n  /**\n   * Create a new Node instance.\n   *\n   * @param axis The index of the coordinate axis used to split.\n   * @param indices The indices of the points in the node.\n   * @param left The left child node.\n   * @param right The right child node.\n   *\n   * @throws {RangeError} The axis is negative\n   */\n  private constructor(\n    readonly axis: number,\n    readonly indices: Uint32Array,\n    readonly left: Node | undefined,\n    readonly right: Node | undefined,\n  ) {\n    assert(axis >= 0, `The axis must be non-negative: ${axis}`);\n    assert(indices.length > 0, 'The indices must not be empty');\n  }\n\n  get index(): number {\n    return this.indices[0];\n  }\n\n  /**\n   * Return whether the node is a leaf node.\n   *\n   * @return True if the node is a leaf node, false otherwise.\n   */\n  isLeaf(): boolean {\n    return !this.left && !this.right;\n  }\n\n  /**\n   * Create a node with the given axis, index, left and right child nodes.\n   *\n   * @param axis - The index of the coordinate axis used to split.\n   * @param index - The index of the point in the node.\n   * @param left - The left child node.\n   * @param right - The right child node.\n   * @return The created node.\n   */\n  static createNode(axis: number, index: number, left: Node | undefined, right: Node | undefined): Node {\n    return new Node(axis, Uint32Array.of(index), left, right);\n  }\n\n  /**\n   * Create a leaf node with the given indices.\n   *\n   * @param axis - The index of the coordinate axis used to split.\n   * @param indices - The indices of the points in the node.\n   * @return The created leaf node.\n   */\n  static createLeaf(axis: number, indices: Uint32Array): Node {\n    return new Node(axis, indices, undefined, undefined);\n  }\n}\n","import { assert, type Mutable, PriorityQueue, type Queue, assertDefined, assertPositiveInteger } from '../../../utils';\nimport { type DistanceMeasure, euclidean } from '../../distance';\nimport type { Point } from '../../point';\nimport type { Neighbor, NeighborSearch } from '../search';\n\nimport { Node } from './node';\n\n/**\n * The default leaf size of the KD-tree.\n */\nconst DEFAULT_LEAF_SIZE = 10;\n\n/**\n * Implementation of nearest neighbor search using a KD-tree.\n *\n * @typeParam P - The type of the point.\n */\nexport class KDTreeSearch<P extends Point> implements NeighborSearch<P> {\n  private readonly points: P[];\n\n  /**\n   * Create a new KDTreeSearch instance.\n   *\n   * @private\n   * @param root - The root node of the KD-Tree.\n   * @param points - The points to be searched.\n   * @param distanceMeasure - The function to measure the distance between two points.\n   * @see build\n   */\n  private constructor(\n    private readonly root: Node,\n    points: P[],\n    private readonly distanceMeasure: DistanceMeasure,\n  ) {\n    // Copy the points array to avoid side effects.\n    this.points = Array.from(points);\n  }\n\n  /**\n   * {@inheritDoc NeighborSearch.search}\n   */\n  search(query: P, k: number): Neighbor[] {\n    assert(k >= 1, `The number of neighbors to be searched(${k}) must be greater than or equal to 1`);\n    const neighbors = new PriorityQueue((neighbor1: Neighbor, neighbor2: Neighbor): number => {\n      return neighbor2.distance - neighbor1.distance;\n    });\n    this.searchRecursively(this.root, query, k, neighbors);\n    return neighbors.toArray().sort((neighbor1: Neighbor, neighbor2: Neighbor): number => {\n      return neighbor1.distance - neighbor2.distance;\n    });\n  }\n\n  /**\n   * {@inheritDoc NeighborSearch.searchNearest}\n   */\n  searchNearest(query: P): Neighbor {\n    // Do not need to check whether the points are empty, since size of points is checked when constructing the Index.\n    const point = this.points[0];\n    const distance = this.distanceMeasure(query, point);\n    const result: Mutable<Neighbor> = { index: 0, distance };\n    this.nearestRecursively(this.root, query, result);\n    return result;\n  }\n\n  /**\n   * {@inheritDoc NeighborSearch.searchRadius}\n   */\n  searchRadius(query: P, radius: number): Neighbor[] {\n    assert(radius > 0.0, `The radius(${radius}) must be greater than 0.0`);\n    const result = new Array<Neighbor>();\n    this.rangeRecursively(this.root, query, radius, result);\n    return result;\n  }\n\n  /**\n   * Recursively searches for the nearest neighbor in the KD-tree.\n   *\n   * @private\n   * @param node - The current node.\n   * @param query - The query point.\n   * @param neighbor - The current nearest neighbor.\n   */\n  private nearestRecursively(node: Node | undefined, query: P, neighbor: Mutable<Neighbor>) {\n    if (!node) {\n      return;\n    }\n\n    if (node.isLeaf()) {\n      for (const index of node.indices) {\n        const point = this.points[index];\n        const distance = this.distanceMeasure(query, point);\n        if (distance < neighbor.distance) {\n          neighbor.index = index;\n          neighbor.distance = distance;\n        }\n      }\n      return;\n    }\n\n    const index = node.index;\n    const point = this.points[index];\n    const distance = this.distanceMeasure(query, point);\n    if (distance < neighbor.distance) {\n      neighbor.index = index;\n      neighbor.distance = distance;\n    }\n\n    const delta = query[node.axis] - point[node.axis];\n    if (delta < 0) {\n      this.nearestRecursively(node.left, query, neighbor);\n      if (neighbor.distance >= Math.abs(delta)) {\n        this.nearestRecursively(node.right, query, neighbor);\n      }\n    } else {\n      this.nearestRecursively(node.right, query, neighbor);\n      if (neighbor.distance >= Math.abs(delta)) {\n        this.nearestRecursively(node.left, query, neighbor);\n      }\n    }\n  }\n\n  /**\n   * Recursively searches for the k nearest neighbors in the KD-tree.\n   *\n   * @private\n   * @param node - The current node.\n   * @param query - The query point.\n   * @param k - The number of nearest neighbors to find.\n   * @param neighbors - The current nearest neighbors.\n   */\n  private searchRecursively(node: Node | undefined, query: P, k: number, neighbors: Queue<Neighbor>) {\n    if (!node) {\n      return;\n    }\n\n    if (node.isLeaf()) {\n      for (const index of node.indices) {\n        const point = this.points[index];\n        const distance = this.distanceMeasure(query, point);\n        neighbors.push({ index, distance });\n        if (neighbors.size > k) {\n          neighbors.pop();\n        }\n      }\n      return;\n    }\n\n    const index = node.index;\n    const point = this.points[index];\n    const distance = this.distanceMeasure(query, point);\n\n    const maxDistance = neighbors.peek()?.distance || Number.MAX_VALUE;\n    if (neighbors.size < k || distance < maxDistance) {\n      neighbors.push({ index, distance });\n      // Keep the size of the priority queue to k\n      if (neighbors.size > k) {\n        neighbors.pop();\n      }\n    }\n\n    const delta = query[node.axis] - point[node.axis];\n    const neighbor = neighbors.peek();\n    if (neighbors.size < k || (neighbor && Math.abs(delta) <= neighbor.distance)) {\n      this.searchRecursively(node.left, query, k, neighbors);\n      this.searchRecursively(node.right, query, k, neighbors);\n    } else if (delta < 0) {\n      this.searchRecursively(node.left, query, k, neighbors);\n    } else {\n      this.searchRecursively(node.right, query, k, neighbors);\n    }\n  }\n\n  /**\n   * Recursively searches for neighbors within a given radius in the KD-tree.\n   *\n   * @private\n   * @param node The current node.\n   * @param query The query point.\n   * @param radius The search radius.\n   * @param neighbors The current neighbors within the radius.\n   */\n  private rangeRecursively(node: Node | undefined, query: P, radius: number, neighbors: Neighbor[]) {\n    if (!node) {\n      return;\n    }\n\n    if (node.isLeaf()) {\n      for (const index of node.indices) {\n        const point = this.points[index];\n        const distance = this.distanceMeasure(query, point);\n        if (distance <= radius) {\n          neighbors.push({ index, distance });\n        }\n      }\n      return;\n    }\n\n    const point = this.points[node.index];\n    const distance = this.distanceMeasure(query, point);\n    if (distance <= radius) {\n      neighbors.push({ index: node.index, distance });\n    }\n\n    const delta = query[node.axis] - point[node.axis];\n    if (Math.abs(delta) <= radius) {\n      this.rangeRecursively(node.left, query, radius, neighbors);\n      this.rangeRecursively(node.right, query, radius, neighbors);\n    } else if (delta < 0) {\n      this.rangeRecursively(node.left, query, radius, neighbors);\n    } else {\n      this.rangeRecursively(node.right, query, radius, neighbors);\n    }\n  }\n\n  /**\n   * Build a KDTreeSearch instance from the given points array.\n   *\n   * @param points - The points to be searched.\n   * @param leafSize - The maximum number of points in a leaf node.\n   * @param distanceMeasure - The function to measure the distance between two points.\n   * @return The built KDTreeSearch instance.\n   */\n  static build<P extends Point>(\n    points: P[],\n    leafSize: number = DEFAULT_LEAF_SIZE,\n    distanceMeasure: DistanceMeasure = euclidean,\n  ): KDTreeSearch<P> {\n    assertPositiveInteger(leafSize, 'The leaf size must be a positive integer');\n    const indices = new Uint32Array(points.length).map((_: number, index: number) => index);\n    const root = KDTreeSearch.buildNode(points, indices, leafSize, 0);\n    assertDefined(root, 'The given points array is empty');\n    return new KDTreeSearch<P>(root, points, distanceMeasure);\n  }\n\n  /**\n   * Recursively builds a node of the KD-tree.\n   *\n   * @private\n   * @param points - The points to be searched.\n   * @param indices - The indices of the points.\n   * @param leafSize - The maximum number of points in a leaf node.\n   * @param depth - The current depth of the tree.\n   * @return The created node.\n   */\n  private static buildNode<P extends Point>(\n    points: ReadonlyArray<P>,\n    indices: Uint32Array,\n    leafSize: number,\n    depth: number,\n  ): Node | undefined {\n    if (indices.length <= 0) {\n      return undefined;\n    }\n\n    const dimension = points[0].length;\n    const axis = depth % dimension;\n\n    // Stop node construction if the number of points is less than or equal to the leaf size.\n    if (indices.length <= leafSize) {\n      return Node.createLeaf(axis, indices);\n    }\n\n    const median = Math.floor(indices.length / 2);\n\n    // Sort indices by the value corresponding to the current axis.\n    indices.sort((index1: number, index2: number): number => {\n      return points[index1][axis] - points[index2][axis];\n    });\n\n    const left = KDTreeSearch.buildNode(points, indices.slice(0, median), leafSize, depth + 1);\n    const right = KDTreeSearch.buildNode(points, indices.slice(median + 1), leafSize, depth + 1);\n    return Node.createNode(axis, indices[median], left, right);\n  }\n}\n","import { assert, ArrayQueue } from '../../../utils';\nimport type { DistanceMeasure } from '../../distance';\nimport { KDTreeSearch, type Neighbor, type NeighborSearch } from '../../neighbor';\nimport type { Point } from '../../point';\nimport { Vector } from '../../vector';\nimport type { ClusteringAlgorithm } from '../algorithm';\nimport { Cluster } from '../cluster';\n\ntype Label = number;\n\nconst OUTLIER: Label = -1;\nconst MARKED: Label = -2;\nconst UNDEFINED: Label = -3;\n\n/**\n * Implementation of the DBSCAN (Density-Based Spatial Clustering of Applications with Noise) algorithm.\n *\n * @template P The type of points to be clustered, extending the `Point` interface.\n * @implements {ClusteringAlgorithm<P>}\n * @see [Wikipedia - DBSCAN](https://en.wikipedia.org/wiki/DBSCAN)\n */\nexport class DBSCAN<P extends Point> implements ClusteringAlgorithm<P> {\n  /**\n   * Create a new DBSCAN instance.\n   *\n   * @param minPoints - The minimum number of points required to form a cluster.\n   * @param epsilon - The radius within which to search for neighboring points.\n   * @param distanceMeasure - The function to measure the distance between two points.\n   */\n  constructor(\n    private readonly minPoints: number,\n    private readonly epsilon: number,\n    private readonly distanceMeasure: DistanceMeasure,\n  ) {\n    assert(this.minPoints >= 1, `The minimum size of cluster(${this.minPoints}) is not greater than or equal to 1`);\n    assert(this.epsilon >= 0.0, `The epsilon(${this.epsilon}) is not greater than 0.0`);\n  }\n\n  /**\n   * {@inheritDoc ClusteringAlgorithm.fit}\n   */\n  fit(points: P[]): Cluster<P>[] {\n    if (points.length === 0) {\n      return [];\n    }\n\n    let label: Label = 0;\n    const labels = new Array<Label>(points.length).fill(UNDEFINED);\n    const clusters = new Array<Cluster<P>>();\n    const neighborSearch = KDTreeSearch.build(points, 16, this.distanceMeasure);\n    for (let i = 0; i < points.length; i++) {\n      // Skip if the point has already been visited.\n      if (labels[i] !== UNDEFINED) {\n        continue;\n      }\n\n      const point = points[i];\n      const neighbors = neighborSearch.searchRadius(point, this.epsilon);\n      // Mark as noise point if there are not enough neighbors.\n      if (neighbors.length < this.minPoints) {\n        labels[i] = OUTLIER;\n        continue;\n      }\n\n      DBSCAN.markNeighbors(neighbors, labels);\n\n      const cluster = this.expandCluster(label, labels, points, neighbors, neighborSearch);\n      if (cluster.size >= this.minPoints) {\n        clusters.push(cluster);\n      }\n      label++;\n    }\n    return clusters;\n  }\n\n  /**\n   * Expand the cluster and update the labels of the points.\n   *\n   * @private\n   * @param label The label of the current cluster.\n   * @param labels The labels of the points.\n   * @param points The points to be clustered.\n   * @param neighbors The neighbors of the current point.\n   * @param neighborSearch The neighbor search instance.\n   */\n  private expandCluster(\n    label: Label,\n    labels: Label[],\n    points: P[],\n    neighbors: Neighbor[],\n    neighborSearch: NeighborSearch<P>,\n  ): Cluster<P> {\n    const centroid = new Vector(points[0]).setZero();\n    const cluster = new Cluster<P>(centroid);\n    const queue = new ArrayQueue(...neighbors);\n    while (!queue.isEmpty()) {\n      const neighbor = queue.pop();\n      if (!neighbor) {\n        continue;\n      }\n\n      const neighborIndex = neighbor.index;\n      const neighborPoint = points[neighborIndex];\n      if (labels[neighborIndex] > 0) {\n        // Skip if the point has already been assigned a label.\n        continue;\n      }\n\n      if (labels[neighborIndex] === OUTLIER) {\n        labels[neighborIndex] = label;\n        cluster.addMember(neighborIndex, neighborPoint);\n        continue;\n      }\n\n      labels[neighborIndex] = label;\n      cluster.addMember(neighborIndex, neighborPoint);\n\n      const secondaryNeighbors = neighborSearch.searchRadius(neighborPoint, this.epsilon);\n      if (secondaryNeighbors.length < this.minPoints) {\n        continue;\n      }\n\n      for (let i = 0; i < secondaryNeighbors.length; i++) {\n        const secondaryNeighbor = secondaryNeighbors[i];\n        const secondaryNeighborIndex = secondaryNeighbor.index;\n        const secondaryNeighborLabel = labels[secondaryNeighborIndex];\n        if (secondaryNeighborLabel === UNDEFINED) {\n          labels[secondaryNeighborIndex] = MARKED;\n          queue.push(secondaryNeighbor);\n        } else if (secondaryNeighborLabel === OUTLIER) {\n          queue.push(secondaryNeighbor);\n        }\n      }\n    }\n    return cluster;\n  }\n\n  /**\n   * Mark the neighbors of a point as marked.\n   *\n   * @param neighbors The neighbors to mark.\n   * @param labels The labels of the points.\n   */\n  private static markNeighbors(neighbors: Neighbor[], labels: Label[]): void {\n    for (let i = 0; i < neighbors.length; i++) {\n      const neighbor = neighbors[i];\n      const neighborIndex = neighbor.index;\n      labels[neighborIndex] = MARKED;\n    }\n  }\n}\n","import { assert, ArrayQueue } from '../../../utils';\nimport type { DistanceMeasure } from '../../distance';\nimport { KDTreeSearch, type Neighbor } from '../../neighbor';\nimport type { Point } from '../../point';\nimport { Vector } from '../../vector';\nimport type { ClusteringAlgorithm } from '../algorithm';\nimport { Cluster } from '../cluster';\n\ntype Label = number;\n\nconst OUTLIER: Label = -1;\nconst MARKED: Label = -2;\nconst UNDEFINED: Label = -3;\n\n/**\n * Implementation of the DBSCAN++ algorithm that is an extension of the DBSCAN algorithm.\n *\n * @template P The type of points to be clustered, extending the `Point` interface.\n * @implements {ClusteringAlgorithm<P>}\n * @see {@link DBSCAN}\n */\nexport class DBSCANpp<P extends Point> implements ClusteringAlgorithm<P> {\n  /**\n   * Create a new DBSCANpp instance.\n   *\n   * @param probability - The probability of selecting a point as a core point.\n   * @param minPoints - The minimum number of points required to form a cluster.\n   * @param epsilon - The radius within which to search for neighboring points.\n   * @param distanceMeasure - The function to measure the distance between two points.\n   */\n  constructor(\n    readonly probability: number,\n    readonly minPoints: number,\n    readonly epsilon: number,\n    readonly distanceMeasure: DistanceMeasure,\n  ) {\n    assert(\n      this.probability > 0 && this.probability <= 1,\n      `The probability(${this.probability}) is not in the range (0, 1]`,\n    );\n    assert(this.minPoints >= 1, `The minimum size of cluster(${this.minPoints}) is not greater than or equal to 1`);\n    assert(this.epsilon >= 0.0, `The epsilon(${this.epsilon}) is not greater than 0.0`);\n  }\n\n  /**\n   * {@inheritDoc ClusteringAlgorithm.fit}\n   */\n  fit(points: P[]): Cluster<P>[] {\n    if (points.length === 0) {\n      return [];\n    }\n\n    const pointsSearch = KDTreeSearch.build(points, 16, this.distanceMeasure);\n    const corePoints = this.findCorePoints(points, pointsSearch);\n    const corePointsSearch = KDTreeSearch.build(corePoints, 16, this.distanceMeasure);\n    const coreLabels = this.labelCorePoints(corePoints, corePointsSearch);\n    return this.assignClusters(points, coreLabels, corePointsSearch);\n  }\n\n  private findCorePoints(points: P[], neighborSearch: KDTreeSearch<P>): P[] {\n    const step = Math.round(1 / this.probability);\n    const corePoints = new Array<P>();\n    for (let i = 0; i < points.length; i += step) {\n      const point = points[i];\n      const neighbors = neighborSearch.searchRadius(point, this.epsilon);\n      if (neighbors.length >= this.minPoints) {\n        corePoints.push(point);\n      }\n    }\n    return corePoints;\n  }\n\n  private labelCorePoints(corePoints: P[], corePointsSearch: KDTreeSearch<P>): Label[] {\n    let label: Label = 0;\n    const labels = new Array<Label>(corePoints.length).fill(UNDEFINED);\n    for (let i = 0; i < corePoints.length; i++) {\n      if (labels[i] !== UNDEFINED) {\n        continue;\n      }\n\n      const point = corePoints[i];\n      const neighbors = corePointsSearch.searchRadius(point, this.epsilon);\n      if (neighbors.length < this.minPoints) {\n        labels[i] = OUTLIER;\n        continue;\n      }\n\n      for (const neighbor of neighbors) {\n        if (labels[neighbor.index] !== UNDEFINED) {\n          continue;\n        }\n        labels[neighbor.index] = MARKED;\n      }\n\n      this.expandCluster(label, labels, corePoints, neighbors, corePointsSearch);\n      label++;\n    }\n    return labels;\n  }\n\n  private expandCluster(\n    label: Label,\n    labels: Label[],\n    points: P[],\n    neighbors: Neighbor[],\n    neighborSearch: KDTreeSearch<P>,\n  ) {\n    const queue = new ArrayQueue(...neighbors);\n    while (!queue.isEmpty()) {\n      const neighbor = queue.pop();\n      if (!neighbor) {\n        continue;\n      }\n\n      const neighborIndex = neighbor.index;\n      const neighborPoint = points[neighborIndex];\n\n      // Skip if the point has already been assigned a label.\n      if (labels[neighborIndex] > 0) {\n        continue;\n      }\n\n      if (labels[neighborIndex] === OUTLIER) {\n        labels[neighborIndex] = label;\n        continue;\n      }\n\n      labels[neighborIndex] = label;\n\n      const secondaryNeighbors = neighborSearch.searchRadius(neighborPoint, this.epsilon);\n      if (secondaryNeighbors.length < this.minPoints) {\n        continue;\n      }\n\n      for (let i = 0; i < secondaryNeighbors.length; i++) {\n        const secondaryNeighbor = secondaryNeighbors[i];\n        const secondaryNeighborIndex = secondaryNeighbor.index;\n        const secondaryNeighborLabel = labels[secondaryNeighborIndex];\n        if (secondaryNeighborLabel === UNDEFINED) {\n          labels[secondaryNeighborIndex] = MARKED;\n          queue.push(secondaryNeighbor);\n        } else if (secondaryNeighborLabel === OUTLIER) {\n          queue.push(secondaryNeighbor);\n        }\n      }\n    }\n  }\n\n  private assignClusters(points: P[], coreLabels: Label[], corePointsSearch: KDTreeSearch<P>): Cluster<P>[] {\n    const clusters = new Map<Label, Cluster<P>>();\n    for (let i = 0; i < points.length; i++) {\n      const point = points[i];\n      const nearest = corePointsSearch.searchNearest(point);\n      if (nearest.distance > this.epsilon) {\n        continue;\n      }\n\n      const coreLabel = coreLabels[nearest.index];\n      if (coreLabel < 0) {\n        continue;\n      }\n\n      const cluster = clusters.get(coreLabel);\n      if (cluster) {\n        cluster.addMember(i, point);\n      } else {\n        const centroid = new Vector(point).setZero();\n        const newCluster = new Cluster<P>(centroid);\n        newCluster.addMember(i, point);\n        clusters.set(coreLabel, newCluster);\n      }\n    }\n    return Array.from(clusters.values());\n  }\n}\n","import type { DistanceMeasure } from '../../distance';\nimport { KDTreeSearch } from '../../neighbor';\nimport type { Point } from '../../point';\nimport type { ClusteringAlgorithm } from '../algorithm';\nimport { Cluster } from '../cluster';\n\nimport { assert, assertPositiveInteger } from '../../../utils';\nimport type { InitializationStrategy } from './strategy';\n\n/**\n * Implementation of the k-means clustering algorithm.\n *\n * @typeParam P - The type of point.\n * @see [Wikipedia - k-means clustering](https://en.wikipedia.org/wiki/K-means_clustering)\n */\nexport class Kmeans<P extends Point> implements ClusteringAlgorithm<P> {\n  /**\n   * Create a new Kmeans instance.\n   *\n   * @param k - The number of clusters.\n   * @param maxIterations - The maximum number of iterations.\n   * @param tolerance - The tolerance for convergence conditions.\n   * @param distanceMeasure - The function to measure the distance between two points.\n   * @param initializationStrategy - The strategy to initialize center points.\n   */\n  constructor(\n    private readonly k: number,\n    private readonly maxIterations: number,\n    private readonly tolerance: number,\n    private readonly distanceMeasure: DistanceMeasure,\n    private readonly initializationStrategy: InitializationStrategy<P>,\n  ) {\n    assertPositiveInteger(k, `The number of cluster must be a positive integer: ${k}`);\n    assert(maxIterations > 0, `The maximum number of iterations must be a positive integer: ${maxIterations}`);\n    assert(tolerance >= 0.0, `The tolerance must be a positive number: ${tolerance}`);\n  }\n\n  /**\n   * {@inheritDoc Clustering.fit}\n   */\n  fit(points: P[]): Cluster<P>[] {\n    if (points.length === 0) {\n      return [];\n    }\n\n    if (points.length <= this.k) {\n      return points.map((point: P, index: number): Cluster<P> => {\n        const cluster = new Cluster(point);\n        cluster.addMember(index, point);\n        return cluster;\n      });\n    }\n\n    const clusters = this.initializationStrategy\n      .initialize(points, this.k)\n      .map((centroid: P): Cluster<P> => new Cluster(centroid));\n    for (let i = 0; i < this.maxIterations; i++) {\n      const updated = this.iterate(clusters, points);\n      if (!updated) {\n        break;\n      }\n    }\n    return clusters;\n  }\n\n  /**\n   * Performs one iteration of the Kmeans algorithm.\n   *\n   * @param clusters - The current clusters.\n   * @param points - The points to cluster.\n   * @returns Whether any cluster was updated.\n   */\n  private iterate(clusters: Cluster<P>[], points: P[]): boolean {\n    const centroids = new Array<P>(clusters.length);\n    for (let i = 0; i < clusters.length; i++) {\n      const cluster = clusters[i];\n      centroids[i] = cluster.getCentroid();\n      cluster.clear();\n    }\n    this.assignPoints(clusters, centroids, points);\n\n    let updated = false;\n    for (let i = 0; i < clusters.length; i++) {\n      const oldCentroid = centroids[i];\n      const newCentroid = clusters[i].getCentroid();\n      const difference = this.distanceMeasure(oldCentroid, newCentroid);\n      if (difference >= this.tolerance) {\n        updated = true;\n      }\n    }\n    return updated;\n  }\n\n  /**\n   * Assigns each point to the nearest cluster.\n   *\n   * @param clusters - The clusters to which to assign points.\n   * @param centroids - The centroids of the clusters.\n   * @param points - The points to assign.\n   */\n  private assignPoints(clusters: Cluster<P>[], centroids: P[], points: P[]): void {\n    const neighborSearch = KDTreeSearch.build(centroids, 16, this.distanceMeasure);\n    for (let i = 0; i < points.length; i++) {\n      const point = points[i];\n      const neighbor = neighborSearch.searchNearest(point);\n      const nearestCluster = clusters[neighbor.index];\n      nearestCluster.addMember(i, point);\n    }\n  }\n}\n","import { assertPositiveInteger } from '../../../utils';\nimport type { Distance, DistanceMeasure, Point } from '../../index';\n\n/**\n * Interface for initializing center points for Kmeans algorithm.\n *\n * @typeParam P - The type of the point.\n */\nexport interface InitializationStrategy<P extends Point> {\n  /**\n   * Initialize center points.\n   *\n   * @param points - The candidate points.\n   * @param k - The number of center points to initialize.\n   * @return The initial center points.\n   */\n  initialize(points: P[], k: number): P[];\n}\n\nconst NO_INDEX = -1;\n\n/**\n * Kmeans++ center points initialization strategy.\n *\n * @typeParam P - The type of the point.\n */\nexport class KmeansPlusPlusInitializer<P extends Point> implements InitializationStrategy<P> {\n  /**\n   * Create a new Kmeans++ center initializer\n   *\n   * @param distanceMeasure - The distance measure.\n   */\n  constructor(private readonly distanceMeasure: DistanceMeasure) {}\n\n  /**\n   * {@inheritDoc CenterInitializer.initialize}\n   */\n  initialize(points: P[], k: number): P[] {\n    assertPositiveInteger(k, `The number of center points is not positive integer: ${k}`);\n    if (points.length <= k) {\n      return [...points];\n    }\n\n    const selected = new Map<number, P>();\n    this.selectRecursively(points, k, selected);\n    return Array.from(selected.values());\n  }\n\n  private selectRecursively(data: P[], k: number, selected: Map<number, P>) {\n    if (selected.size === k) {\n      return;\n    }\n\n    if (selected.size === 0) {\n      KmeansPlusPlusInitializer.selectRandomly(data, selected);\n    } else {\n      this.selectBest(data, selected);\n    }\n    this.selectRecursively(data, k, selected);\n  }\n\n  private selectBest(data: P[], selected: Map<number, P>) {\n    const dataSize = data.length;\n    const totalDistanceCache = new Float32Array(dataSize);\n    let totalDistance = 0.0;\n    for (let i = 0; i < dataSize; i++) {\n      if (selected.has(i)) {\n        continue;\n      }\n\n      const point = data[i];\n      const nearestDistance = this.computeNearestDistance(point, selected);\n      totalDistance += nearestDistance;\n      totalDistanceCache[i] = totalDistance;\n    }\n\n    const targetDistance = Math.random() * totalDistance;\n    const targetIndex = data.findIndex((_: P, index: number): boolean => {\n      if (selected.has(index)) {\n        return false;\n      }\n\n      const distance = totalDistanceCache[index];\n      if (!distance) {\n        return false;\n      }\n      return distance > targetDistance;\n    });\n\n    if (targetIndex === NO_INDEX) {\n      KmeansPlusPlusInitializer.selectRandomly(data, selected);\n      return;\n    }\n    selected.set(targetIndex, data[targetIndex]);\n  }\n\n  private computeNearestDistance(point: P, selected: Map<number, P>): Distance {\n    let minDistance: Distance = Number.MAX_VALUE as Distance;\n    for (const selectedPoint of selected.values()) {\n      const distance = this.distanceMeasure(point, selectedPoint);\n      if (distance < minDistance) {\n        minDistance = distance;\n      }\n    }\n    return minDistance;\n  }\n\n  private static selectRandomly<P extends Point>(data: P[], selected: Map<number, P>) {\n    let index = NO_INDEX;\n    do {\n      index = Math.floor(Math.random() * data.length);\n    } while (selected.has(index));\n    selected.set(index, data[index]);\n  }\n}\n","import { assert } from '../../utils';\nimport type { DistanceMeasure } from '../distance';\nimport type { Point } from '../point';\nimport type { SamplingStrategy } from './strategy';\n\n/**\n * FarthestPointSampling class represents a strategy for sampling a set of data points by selecting the farthest data points from the sampled data points.\n *\n * @typeParam P - The type of the point.\n */\nexport class FarthestPointSampling<P extends Point> implements SamplingStrategy<P> {\n  /**\n   * Create a new FarthestPointSampling instance.\n   *\n   * @param distanceMeasure - The distance measure to measure the distance between two points.\n   */\n  constructor(private readonly distanceMeasure: DistanceMeasure) {}\n\n  /**\n   * {@inheritDoc SamplingStrategy.sample}\n   */\n  sample(points: P[], n: number): Set<number> {\n    assert(n > 0, `The number of data points to downsample(${n}) must be greater than 0`);\n    if (n >= points.length) {\n      return new Set(points.keys());\n    }\n\n    const sampled = new Set<number>();\n    const distances = new Array(points.length);\n\n    const initialIndex = this.findInitialIndex();\n    assert(initialIndex >= 0, 'No data point can be selected as the initial data point');\n    sampled.add(initialIndex);\n\n    for (let i = 0; i < distances.length; i++) {\n      distances[i] = this.distance(points, initialIndex, i);\n    }\n\n    while (sampled.size < n) {\n      const farthestIndex = this.findFarthestIndex(distances, sampled);\n      assert(farthestIndex >= 0, 'No data point can be selected as the farthest data point');\n\n      sampled.add(farthestIndex);\n      distances[farthestIndex] = 0.0;\n\n      for (let i = 0; i < points.length; i++) {\n        if (sampled.has(i)) {\n          continue;\n        }\n\n        const previousDistance = distances[i];\n        const currentDistance = this.distance(points, farthestIndex, i);\n        distances[i] = Math.min(previousDistance, currentDistance);\n      }\n    }\n    return sampled;\n  }\n\n  /**\n   * Measure the distance between two data points.\n   *\n   * @param points - The data points.\n   * @param i - The index of the 1st data point.\n   * @param j - The index of the 2nd data point.\n   * @returns The distance between the two data points.\n   */\n  protected distance(points: P[], i: number, j: number): number {\n    return this.distanceMeasure(points[i], points[j]);\n  }\n\n  /**\n   * Find the index of the initial data point.\n   * @protected\n   * @returns The index of the initial data point.\n   */\n  protected findInitialIndex(): number {\n    return 0;\n  }\n\n  /**\n   * Find the index of the farthest data point from the sampled data points.\n   *\n   * @param distances - The distances from the sampled data points.\n   * @param sampled - The sampled data points.\n   * @returns The index of the farthest data point. If no data point can be selected, returns -1.\n   */\n  private findFarthestIndex(distances: number[], sampled: Set<number>): number {\n    let farthestIndex = -1;\n    let farthestDistance = 0.0;\n    for (let i = 0; i < distances.length; i++) {\n      if (sampled.has(i)) {\n        continue;\n      }\n\n      const distance = distances[i];\n      if (distance > farthestDistance) {\n        farthestDistance = distance;\n        farthestIndex = i;\n      }\n    }\n    return farthestIndex;\n  }\n}\n","import { assertFiniteNumber } from '../utils';\n\n/**\n * Clamp the given value.\n *\n * @param value The value to be clamped.\n * @param min The minimum value.\n * @param max The maximum value.\n * @return The clamped value.\n */\nexport function clamp(value: number, min: number, max: number): number {\n  assertFiniteNumber(value, `The value(${value}) must be finite number`);\n  assertFiniteNumber(min, `The minimum value(${min}) must be finite number`);\n  assertFiniteNumber(max, `The maximum value(${max}) must be finite number`);\n  return Math.max(Math.min(value, max), min);\n}\n\n/**\n * Normalize the given value.\n *\n * @param value - The value to be normalized.\n * @param min - The minimum value in the range.\n * @param max - The maximum value in the range.\n * @returns The normalized value.\n * @throws {RangeError} if the min is greater than the max.\n * @see {@link denormalize}\n */\nexport function normalize(value: number, min: number, max: number): number {\n  assertFiniteNumber(value, `The value(${value}) must be finite number`);\n  assertFiniteNumber(min, `The minimum value(${min}) must be finite number`);\n  assertFiniteNumber(max, `The maximum value(${max}) must be finite number`);\n\n  if (min >= max) {\n    throw new RangeError(`The minimum value(${min}) is greater than the maximum value(${max})`);\n  }\n  return Math.max(Math.min((value - min) / (max - min), 1.0), 0.0);\n}\n\n/**\n * Denormalize the given value.\n *\n * @param value - The normalized value to be denormalized.\n * @param min - The minimum value in the range.\n * @param max - The maximum value in the range.\n * @returns The denormalized value.\n * @throws {TypeError} if the value, min or max is not finite number.\n * @throws {RangeError} if the min is greater than the max.\n * @see {@link normalize}\n */\nexport function denormalize(value: number, min: number, max: number): number {\n  assertFiniteNumber(value, `The value(${value}) must be finite number`);\n  assertFiniteNumber(min, `The minimum value(${min}) must be finite number`);\n  assertFiniteNumber(max, `The maximum value(${max}) must be finite number`);\n\n  if (min >= max) {\n    throw new RangeError(`The minimum value(${min}) is greater than the maximum value(${max})`);\n  }\n  return value * (max - min) + min;\n}\n\n/**\n * Convert the given value from degrees to radians.\n *\n * @param degree The value in degrees.\n * @return The converted value in radians.\n */\nexport function degreeToRadian(degree: number): number {\n  assertFiniteNumber(degree, `The degree(${degree}) must be finite number`);\n  return degree * (Math.PI / 180.0);\n}\n\n/**\n * Convert the given value from radians to degrees.\n *\n * @param radian The value in radians.\n * @return The converted value in degrees.\n */\nexport function radianToDegree(radian: number): number {\n  assertFiniteNumber(radian, `The radian(${radian}) must be finite number`);\n  return radian * (180.0 / Math.PI);\n}\n","import type { LAB } from '../types';\n\nimport type { ColorDelta, ColorDeltaMeasure } from './function';\n\n/**\n * Calculate the color difference between two colors using the CIE76 formula.\n *\n * @param color1 - The 1st color.\n * @param color2 - The 2nd color.\n * @returns The color difference.\n * @see [CIE75 - Color difference](https://en.wikipedia.org/wiki/Color_difference#CIE76)\n */\nexport const cie76: ColorDeltaMeasure<LAB> = (color1: LAB, color2: LAB): ColorDelta => {\n  const deltaL = color1.l - color2.l;\n  const deltaA = color1.a - color2.a;\n  const deltaB = color1.b - color2.b;\n  return Math.sqrt(deltaL ** 2 + deltaA ** 2 + deltaB ** 2) as ColorDelta;\n};\n","import type { LAB } from '../types';\n\nimport type { ColorDelta, ColorDeltaMeasure } from './function';\n\n// kL, K1 and K2 are constants. The values are taken from the wikipedia page:\n// https://en.wikipedia.org/wiki/Color_difference#CIE94\nconst kL = 1.0;\nconst K1 = 0.045;\nconst K2 = 0.015;\n\n// kC and kH are constants, The values are usually both unity.\nconst kC = 1.0;\nconst kH = 1.0;\n\n/**\n * Calculate the color difference between two colors using the CIE94 formula.\n *\n * @param color1 - The 1st color.\n * @param color2 - The 2nd color.\n * @returns The color difference.\n * @see [CIE94 - Color difference](https://en.wikipedia.org/wiki/Color_difference#CIE94)\n */\nexport const cie94: ColorDeltaMeasure<LAB> = (color1: LAB, color2: LAB): ColorDelta => {\n  const deltaL = color1.l - color2.l;\n  const deltaA = color1.a - color2.a;\n  const deltaB = color1.b - color2.b;\n\n  const c1 = Math.sqrt(color1.a ** 2 + color1.b ** 2);\n  const c2 = Math.sqrt(color2.a ** 2 + color2.b ** 2);\n  const deltaC = c1 - c2;\n  const deltaH = Math.sqrt(deltaA ** 2 + deltaB ** 2 - deltaC ** 2);\n\n  const sL = 1;\n  const sC = 1 + K1 * c1;\n  const sH = 1 + K2 * c1;\n\n  const squared = (deltaL / (kL * sL)) ** 2 + (deltaC / (kC * sC)) ** 2 + (deltaH / (kH * sH)) ** 2;\n  return Math.sqrt(squared) as ColorDelta;\n};\n","import { degreeToRadian, radianToDegree } from '../../math';\nimport type { LAB } from '../types';\n\nimport type { ColorDelta, ColorDeltaMeasure } from './function';\n\n// Constants for the CIEDE2000 color difference formula.\n// kL, kC and kH are usually both unity.\nconst kL = 1.0;\nconst kC = 1.0;\nconst kH = 1.0;\nconst POW7_25 = 25 ** 7;\n\n/**\n * Calculate the hue prime for the given x and y values.\n *\n * @param x - The x component.\n * @param y - The y component.\n * @returns The hue prime.\n */\nfunction toHPrime(x: number, y: number): number {\n  if (x === 0.0 && y === 0.0) {\n    return 0.0;\n  }\n\n  const angle = radianToDegree(Math.atan2(x, y));\n  if (angle >= 0.0) {\n    return angle;\n  }\n  return angle + 360.0;\n}\n\n/**\n * Calculate the average hue prime for the given hue primes.\n *\n * @param hPrime1 - The 1st hue prime.\n * @param hPrime2 - The 2nd hue prime.\n * @returns The average hue prime.\n */\nfunction toHBarPrime(hPrime1: number, hPrime2: number): number {\n  const deltaHPrime = Math.abs(hPrime1 - hPrime2);\n  if (deltaHPrime > 180.0) {\n    return (hPrime1 + hPrime2 + 360.0) / 2.0;\n  }\n  return (hPrime1 + hPrime2) / 2.0;\n}\n\n/**\n * Calculate the difference in hue prime for the given hues and chromas.\n *\n * @param c1 - The 1st chroma.\n * @param c2 - The 2nd chroma.\n * @param h1 - The 1st hue.\n * @param h2 - The 2nd hue.\n * @returns The difference in hue prime.\n */\nfunction toDeltaHPrime(c1: number, c2: number, h1: number, h2: number): number {\n  if (c1 === 0.0 || c2 === 0.0) {\n    return 0.0;\n  }\n\n  const deltaH = h2 - h1;\n  if (Math.abs(deltaH) <= 180.0) {\n    return deltaH;\n  }\n\n  if (h2 <= h1) {\n    return deltaH + 360.0;\n  }\n  return deltaH - 360.0;\n}\n\n/**\n * Calculate the color difference between two colors using the CIEDE2000 formula.\n *\n * @param color1 - The 1st color.\n * @param color2 - The 2nd color.\n * @returns The color difference.\n * @see [CIEDE2000 - Color difference](https://en.wikipedia.org/wiki/Color_difference#CIEDE2000)\n */\nexport const ciede2000: ColorDeltaMeasure<LAB> = (color1: LAB, color2: LAB): ColorDelta => {\n  const deltaLPrime = color2.l - color1.l;\n  const lBar = (color1.l + color2.l) / 2.0;\n\n  const c1 = Math.sqrt(color1.a ** 2 + color1.b ** 2);\n  const c2 = Math.sqrt(color2.a ** 2 + color2.b ** 2);\n  const cBar = (c1 + c2) / 2.0;\n\n  const g = Math.sqrt(cBar ** 7.0 / (cBar ** 7.0 + POW7_25));\n  const aPrime1 = color1.a + (color1.a / 2.0) * (1.0 - g);\n  const aPrime2 = color2.a + (color2.a / 2.0) * (1.0 - g);\n\n  const cPrime1 = Math.sqrt(aPrime1 * aPrime1 + color1.b * color1.b);\n  const cPrime2 = Math.sqrt(aPrime2 * aPrime2 + color2.b * color2.b);\n  const cBarPrime = (cPrime1 + cPrime2) / 2.0;\n  const deltaCPrime = cPrime2 - cPrime1;\n\n  const hPrime1 = toHPrime(color1.b, aPrime1);\n  const hPrime2 = toHPrime(color2.b, aPrime2);\n  let deltaHPrime = toDeltaHPrime(c1, c2, hPrime1, hPrime2);\n  deltaHPrime = 2.0 * Math.sqrt(cPrime1 * cPrime2) * Math.sin(degreeToRadian(deltaHPrime) / 2.0);\n\n  const hBarPrime = toHBarPrime(hPrime1, hPrime2);\n  const t =\n    1.0 -\n    0.17 * Math.cos(degreeToRadian(hBarPrime - 30.0)) +\n    0.24 * Math.cos(degreeToRadian(2.0 * hBarPrime)) +\n    0.32 * Math.cos(degreeToRadian(3.0 * hBarPrime + 6.0)) -\n    0.2 * Math.cos(degreeToRadian(4.0 * hBarPrime - 63.0));\n\n  const sL = 1.0 + (0.015 * (lBar - 50.0) ** 2) / Math.sqrt(20.0 + (lBar - 50.0) ** 2);\n  const sC = 1.0 + 0.045 * cBarPrime;\n  const sH = 1.0 + 0.015 * cBarPrime * t;\n\n  const pow7CBarPrime = cBarPrime ** 7;\n  const rT =\n    -2.0 *\n    Math.sqrt(pow7CBarPrime / (pow7CBarPrime + POW7_25)) *\n    Math.sin(degreeToRadian(60.0 * Math.exp(-1.0 * ((hBarPrime - 275.0) / 25.0) ** 2)));\n\n  const l = deltaLPrime / (kL * sL);\n  const c = deltaCPrime / (kC * sC);\n  const h = deltaHPrime / (kH * sH);\n\n  const squared = l ** 2 + c ** 2 + h ** 2 + rT * c * h;\n  return Math.sqrt(squared) as ColorDelta;\n};\n","import { clamp } from '../../math';\nimport type { HSL, RGB } from '../types';\n\nimport { assertFiniteNumber, assertInteger } from '../../utils';\nimport { MAX_RGB, clampValue } from './rgb';\n\n/**\n * The minimum value of the 'hue' component.\n *\n * @see {@link MAX_HUE}\n * @see {@link normalizeHue}\n */\nconst MIN_HUE = 0.0;\n\n/**\n * The maximum value of the 'hue' component.\n *\n * @see {@link MIN_HUE}\n * @see {@link normalizeHue}\n */\nconst MAX_HUE = 360.0;\n\n/**\n * The minimum value of the 'saturation' component.\n *\n * @see {@link MAX_SATURATION}\n * @see {@link clampSaturation}\n */\nconst MIN_SATURATION = 0.0;\n\n/**\n * The maximum value of the 'saturation' component.\n *\n * @see {@link MIN_SATURATION}\n * @see {@link clampSaturation}\n */\nconst MAX_SATURATION = 1.0;\n\n/**\n * The minimum value of the 'lightness' component.\n *\n * @see {@link MAX_LIGHTNESS}\n * @see {@link clampLightness}\n */\nconst MIN_LIGHTNESS = 0.0;\n\n/**\n * The maximum value of the 'lightness' component.\n *\n * @see {@link MIN_LIGHTNESS}\n * @see {@link clampLightness}\n */\nconst MAX_LIGHTNESS = 1.0;\n\n/**\n * Normalize the hue component of the color.\n * The hue component is normalized to the range [0, 360).\n *\n * @param value The hue component of the color.\n * @returns The normalized hue component.\n * @see {@link clampSaturation}\n * @see {@link clampLightness}\n */\nexport function normalizeHue(value: number): number {\n  return ((value % MAX_HUE) + MAX_HUE) % MAX_HUE;\n}\n\n/**\n * Clamp the saturation component of the color.\n * The saturation component is clamped to the range [0, 1].\n *\n * @param value The saturation component of the color.\n * @returns The clamped saturation component.\n * @see {@link normalizeHue}\n * @see {@link clampLightness}\n */\nexport function clampSaturation(value: number): number {\n  return clamp(value, MIN_SATURATION, MAX_SATURATION);\n}\n\n/**\n * Clamp the lightness component of the color.\n * The lightness component is clamped to the range [0, 1].\n *\n * @param value The lightness component of the color.\n * @returns The clamped lightness component.\n * @see {@link normalizeHue}\n * @see {@link clampSaturation}\n */\nexport function clampLightness(value: number): number {\n  return clamp(value, MIN_LIGHTNESS, MAX_LIGHTNESS);\n}\n\n/**\n * Convert a color from the HSL color space to the RGB color space.\n *\n * @param rgb - The color in the RGB color space.\n * @returns The converted color in the RGB color space.\n * @throws {TypeError} If the r, g, or b is not finite number.\n * @see {@link toRGB}\n */\nexport function fromRGB(rgb: RGB): HSL {\n  assertInteger(rgb.r, `The r(${rgb.r}) must be an integer`);\n  assertInteger(rgb.g, `The g(${rgb.g}) must be an integer`);\n  assertInteger(rgb.b, `The b(${rgb.b}) must be an integer`);\n\n  // Normalize the RGB values.\n  const r = clampValue(rgb.r) / MAX_RGB;\n  const g = clampValue(rgb.g) / MAX_RGB;\n  const b = clampValue(rgb.b) / MAX_RGB;\n\n  const max = Math.max(r, g, b);\n  const min = Math.min(r, g, b);\n  const delta = max - min;\n\n  let hue: number;\n  if (delta === 0) {\n    hue = 0;\n  } else if (max === r) {\n    hue = 60 * (((g - b) / delta) % 6);\n  } else if (max === g) {\n    hue = 60 * ((b - r) / delta + 2);\n  } else {\n    hue = 60 * ((r - g) / delta + 4);\n  }\n\n  const lightness = (max + min) / 2.0;\n\n  let saturation = 0.0;\n  if (delta !== 0) {\n    saturation = delta / (1.0 - Math.abs(2.0 * lightness - 1.0));\n  }\n\n  return {\n    h: normalizeHue(hue),\n    s: clampSaturation(saturation),\n    l: clampLightness(lightness),\n  };\n}\n\n/**\n * Convert a color from the HSL color space to the RGB color space.\n *\n * @param hsl - The color in the HSL color space.\n * @returns The converted color in the RGB color space.\n * @throws {TypeError} If the h, s, or l is not finite number.\n * @see {@link fromRGB}\n */\nexport function toRGB({ h, s, l }: HSL): RGB {\n  assertFiniteNumber(h, `The h(${h}) must be a finite number`);\n  assertFiniteNumber(s, `The s(${s}) must be a finite number`);\n  assertFiniteNumber(l, `The l(${l}) must be a finite number`);\n\n  const hue = normalizeHue(h);\n  const saturation = clampSaturation(s);\n  const lightness = clampLightness(l);\n\n  const c = (1.0 - Math.abs(2.0 * lightness - 1.0)) * saturation;\n  const x = (1.0 - Math.abs(((hue / 60) % 2) - 1.0)) * c;\n  const m = lightness - c / 2.0;\n\n  let [r, g, b] = [0.0, 0.0, 0.0];\n  if (0 <= hue && hue < 60) {\n    r = c;\n    g = x;\n  } else if (60 <= hue && hue < 120) {\n    r = x;\n    g = c;\n  } else if (120 <= hue && hue < 180) {\n    g = c;\n    b = x;\n  } else if (180 <= hue && hue < 240) {\n    g = x;\n    b = c;\n  } else if (240 <= hue && hue < 300) {\n    r = x;\n    b = c;\n  } else if (300 <= hue && hue < 360) {\n    r = c;\n    b = x;\n  }\n\n  return {\n    r: clampValue((r + m) * MAX_RGB),\n    g: clampValue((g + m) * MAX_RGB),\n    b: clampValue((b + m) * MAX_RGB),\n  };\n}\n","import { clamp } from '../../math';\nimport { assert, assertInteger } from '../../utils';\nimport type { RGB } from '../types';\n\n/**\n * The minimum value of the RGB component.\n *\n * @see {@link MAX_RGB}\n * @see {@link clampValue}\n */\nconst MIN_RGB = 0x00;\n\n/**\n * The maximum value of the RGB component.\n *\n * @see {@link MIN_RGB}\n * @see {@link clampValue}\n */\nexport const MAX_RGB = 0xff;\n\n/**\n * Clamp the RGB component of the color.\n *\n * @param value The RGB component of the color.\n * @returns The clamped RGB component.\n */\nexport function clampValue(value: number): number {\n  return clamp(value, MIN_RGB, MAX_RGB);\n}\n/**\n * Convert a color from the hexadecimal string to the RGB color space.\n *\n * @param value - The color in hexadecimal string.\n * @returns The color in RGB color space.\n */\nexport function fromHexString(value: string): RGB {\n  assert(value.startsWith('#'), `The value(${value}) is not a valid hexadecimal color string`);\n\n  let r = Number.NaN;\n  let g = Number.NaN;\n  let b = Number.NaN;\n\n  if (value.length === 4) {\n    // #rgb\n    r = Number.parseInt(value[1], 16) * 0x11;\n    g = Number.parseInt(value[2], 16) * 0x11;\n    b = Number.parseInt(value[3], 16) * 0x11;\n  } else if (value.length === 7) {\n    // #rrggbb\n    r = Number.parseInt(value.slice(1, 3), 16);\n    g = Number.parseInt(value.slice(3, 5), 16);\n    b = Number.parseInt(value.slice(5, 7), 16);\n  }\n\n  assertInteger(r, `The value(${value}) is not a valid hexadecimal color string`);\n  assertInteger(g, `The value(${value}) is not a valid hexadecimal color string`);\n  assertInteger(b, `The value(${value}) is not a valid hexadecimal color string`);\n  return { r, g, b };\n}\n\n/**\n * Convert a color from the RGB color space to the hexadecimal string.\n *\n * @param r The red component of the color.\n * @param g The green component of the color.\n * @param b The blue component of the color.\n * @returns The hexadecimal string.\n */\nexport function toHexString({ r, g, b }: RGB): string {\n  return [r, g, b].reduce((string, value) => {\n    assert(Number.isFinite(value), `The r, g, and b components must be finite numbers: ${r}, ${g}, ${b}`);\n    const hex = clampValue(value).toString(16).padStart(2, '0').toUpperCase();\n    return string + hex;\n  }, '#');\n}\n","import { clamp } from '../../math';\nimport type { LAB, XYZ } from '../types';\n\nimport { assertFiniteNumber } from '../../utils';\nimport { D65, clampX, clampY, clampZ } from './xyz';\n\n/**\n * The minimum value of the 'l' component.\n *\n * @public\n * @see {@link MAX_L}\n * @see {@link clampL}\n */\nexport const MIN_L = 0;\n\n/**\n * The maximum value of the 'l' component.\n *\n * @public\n * @see {@link MIN_L}\n * @see {@link clampL}\n */\nexport const MAX_L = 100;\n\n/**\n * The minimum value of the 'a' component.\n *\n * @public\n * @see {@link MAX_A}\n * @see {@link clampA}\n */\nexport const MIN_A = -128;\n\n/**\n * The maximum value of the 'a' component.\n *\n * @public\n * @see {@link MIN_A}\n * @see {@link clampA}\n */\nexport const MAX_A = 128;\n\n/**\n * The minimum value of the 'b' component.\n *\n * @public\n * @see {@link MAX_B}\n * @see {@link clampB}\n */\nexport const MIN_B = -128;\n\n/**\n * The maximum value of the 'b' component.\n *\n * @public\n * @see {@link MIN_B}\n * @see {@link clampB}\n */\nexport const MAX_B = 128;\n\n/**\n * Clamp the 'l' component of the color.\n *\n * @param value The 'l' component of the color.\n * @returns The clamped 'l' component.\n * @see {@link clampA}\n * @see {@link clampB}\n */\nexport function clampL(value: number): number {\n  return clamp(value, MIN_L, MAX_L);\n}\n\n/**\n * Clamp the 'a' component of the color.\n *\n * @param value The 'a' component of the color.\n * @returns The clamped 'a' component.\n * @see {@link clampL}\n * @see {@link clampB}\n */\nexport function clampA(value: number): number {\n  return clamp(value, MIN_A, MAX_A);\n}\n\n/**\n * Clamp the 'b' component of the color.\n *\n * @param value The 'b' component of the color.\n * @returns The clamped 'b' component.\n * @see {@link clampL}\n * @see {@link clampA}\n */\nexport function clampB(value: number): number {\n  return clamp(value, MIN_B, MAX_B);\n}\n\n/**\n * Convert a color from the XYZ color space to the CIELab color space.\n *\n * @param xyz - The color in the XYZ color space.\n * @returns The converted color in the CIELab color space.\n * @throws {TypeError} If any of the XYZ components is not a finite number.\n * @see {@link toXYZ}\n */\nexport function fromXYZ({ x, y, z }: XYZ): LAB {\n  assertFiniteNumber(x, `The x(${x}) must be a finite number`);\n  assertFiniteNumber(y, `The y(${y}) must be a finite number`);\n  assertFiniteNumber(z, `The z(${z}) must be a finite number`);\n\n  // Function to covert a component of XYZ to CIELab.\n  const epsilon = (6.0 / 29.0) ** 3.0;\n  const kappa = 841.0 / 108.0;\n  const delta = 4.0 / 29.0;\n  const f = (t: number): number => {\n    if (t > epsilon) {\n      return Math.cbrt(t);\n    }\n    return kappa * t + delta;\n  };\n\n  const fx = f(x / D65.x);\n  const fy = f(y / D65.y);\n  const fz = f(z / D65.z);\n\n  const l = clampL(116.0 * fy - 16.0);\n  const a = clampA(500.0 * (fx - fy));\n  const b = clampB(200.0 * (fy - fz));\n  return { l, a, b };\n}\n\n/**\n * Convert a color from CIELab color space to the RGB color space.\n *\n * @param lab - The color in the CIELab color space.\n * @returns The converted color in the RGB color space.\n * @throws {TypeError} If any of the CIELab components is not a finite number.\n * @see {@link fromXYZ}\n */\nexport function toXYZ({ l, a, b }: LAB): XYZ {\n  assertFiniteNumber(l, `The l(${l}) must be a finite number`);\n  assertFiniteNumber(a, `The a(${a}) must be a finite number`);\n  assertFiniteNumber(b, `The b(${b}) must be a finite number`);\n\n  // Function to covert a component of CIELab to XYZ.\n  const epsilon = 6.0 / 29.0;\n  const kappa = 108.0 / 841.0;\n  const delta = 4.0 / 29.0;\n  const f = (t: number): number => {\n    if (t > epsilon) {\n      return t ** 3.0;\n    }\n    return kappa * (t - delta);\n  };\n\n  const l2 = (clampL(l) + 16.0) / 116.0;\n  const a2 = clampA(a) / 500.0;\n  const b2 = clampB(b) / 200.0;\n\n  const x = clampX(D65.x * f(l2 + a2));\n  const y = clampY(D65.y * f(l2));\n  const z = clampZ(D65.z * f(l2 - b2));\n  return { x, y, z };\n}\n","import { clamp } from '../../math';\nimport type { RGB, XYZ } from '../types';\n\nimport { assertFiniteNumber, assertInteger } from '../../utils';\nimport { MAX_RGB, clampValue } from './rgb';\n\n/**\n * The minimum value of the 'x' component.\n *\n * @see {@link MAX_X}\n * @see {@link clampX}\n */\nconst MIN_X = 0.0;\n\n/**\n * The maximum value of the 'x' component.\n *\n * @see {@link MIN_X}\n * @see {@link clampX}\n */\nconst MAX_X = 0.950456;\n\n/**\n * The minimum value of the 'y' component.\n *\n * @see {@link MAX_Y}\n * @see {@link clampY}\n */\nconst MIN_Y = 0.0;\n\n/**\n * The maximum value of the 'y' component.\n *\n * @see {@link MIN_Y}\n * @see {@link clampY}\n */\nconst MAX_Y = 1.0;\n\n/**\n * The minimum value of the 'z' component.\n *\n * @see {@link MAX_Z}\n * @see {@link clampZ}\n */\nconst MIN_Z = 0.0;\n\n/**\n * The maximum value of the 'z' component.\n *\n * @see {@link MIN_Z}\n * @see {@link clampZ}\n */\nconst MAX_Z = 1.088644;\n\n/**\n * Clamp the 'x' component of the color.\n *\n * @param value The x component of the color.\n * @returns The clamped x component.\n * @see {@link clampY}\n * @see {@link clampZ}\n */\nexport function clampX(value: number): number {\n  return clamp(value, MIN_X, MAX_X);\n}\n\n/**\n * Clamp the 'y' component of the color.\n *\n * @param value The y component of the color.\n * @returns The clamped y component.\n * @see {@link clampX}\n * @see {@link clampZ}\n */\nexport function clampY(value: number): number {\n  return clamp(value, MIN_Y, MAX_Y);\n}\n\n/**\n * Clamp the 'z' component of the color.\n *\n * @param value The z component of the color.\n * @returns The clamped z component.\n * @see {@link clampX}\n * @see {@link clampY}\n */\nexport function clampZ(value: number): number {\n  return clamp(value, MIN_Z, MAX_Z);\n}\n\n/**\n * The D65 illuminant in the CIE XYZ color space.\n *\n * @see [Illuminant D65 - Wikipedia](https://en.wikipedia.org/wiki/Illuminant_D65#Definition)\n */\nexport const D65: XYZ = {\n  x: 0.95047,\n  y: 1.0,\n  z: 1.08883,\n} as const;\n\n/**\n * Convert a color from the RGB color space to the XYZ color space.\n *\n * @param rgb - The color in the RGB color space.\n * @returns The converted color in the XYZ color space.\n * @see {@link toRGB}\n */\nexport function fromRGB({ r, g, b }: RGB): XYZ {\n  assertInteger(r, `The r(${r}) must be an integer`);\n  assertInteger(g, `The g(${g}) must be an integer`);\n  assertInteger(b, `The b(${b}) must be an integer`);\n\n  const f = (value: number): number => {\n    if (value <= 0.04045) {\n      return value / 12.92;\n    }\n    return ((value + 0.055) / 1.055) ** 2.4;\n  };\n\n  const fr = f(r / MAX_RGB);\n  const fg = f(g / MAX_RGB);\n  const fb = f(b / MAX_RGB);\n\n  const x = clampX(0.412391 * fr + 0.357584 * fg + 0.180481 * fb);\n  const y = clampY(0.212639 * fr + 0.715169 * fg + 0.072192 * fb);\n  const z = clampZ(0.019331 * fr + 0.119195 * fg + 0.950532 * fb);\n  return { x, y, z };\n}\n\n/**\n * Convert a color from the XYZ color space to the RGB color space.\n *\n * @param xyz - The color in the XYZ color space.\n * @returns The converted color in the RGB color space.\n * @throws {TypeError} If any of the XYZ components is not a finite number.\n * @see {@link fromRGB}\n */\nexport function toRGB({ x, y, z }: XYZ): RGB {\n  assertFiniteNumber(x, `The x(${x}) must be a finite number`);\n  assertFiniteNumber(y, `The y(${y}) must be a finite number`);\n  assertFiniteNumber(z, `The z(${z}) must be a finite number`);\n\n  const f = (value: number): number => {\n    if (value <= 0.0031308) {\n      return 12.92 * value;\n    }\n    return 1.055 * value ** (1.0 / 2.4) - 0.055;\n  };\n\n  const fr = f(3.24097 * x - 1.537383 * y - 0.498611 * z);\n  const fg = f(-0.969244 * x + 1.875968 * y + 0.041555 * z);\n  const fb = f(0.05563 * x - 0.203977 * y + 1.056972 * z);\n\n  const r = clampValue(Math.round(fr * MAX_RGB));\n  const g = clampValue(Math.round(fg * MAX_RGB));\n  const b = clampValue(Math.round(fb * MAX_RGB));\n  return { r, g, b };\n}\n","import type { LAB, NamedColor } from '../types';\n\n/**\n * A list of named colors from the CSS3 specification.\n *\n * @see [Color keywords - W3C Wiki](https://www.w3.org/wiki/CSS/Properties/color/keywords)\n */\nexport const COLORS: NamedColor<LAB>[] = [\n  {\n    name: 'AliceBlue',\n    color: { l: 97.179, a: -1.35, b: -4.277 },\n  },\n  {\n    name: 'AntiqueWhite',\n    color: { l: 93.731, a: 1.835, b: 11.514 },\n  },\n  {\n    name: 'Aqua',\n    color: { l: 91.115, a: -48.081, b: -14.143 },\n  },\n  {\n    name: 'Aquamarine',\n    color: { l: 92.035, a: -45.523, b: 9.708 },\n  },\n  {\n    name: 'Azure',\n    color: { l: 98.933, a: -4.882, b: -1.702 },\n  },\n  {\n    name: 'Beige',\n    color: { l: 95.949, a: -4.196, b: 12.037 },\n  },\n  {\n    name: 'Bisque',\n    color: { l: 92.013, a: 4.426, b: 19 },\n  },\n  {\n    name: 'Black',\n    color: { l: 0, a: 0, b: 0 },\n  },\n  {\n    name: 'BlanchedAlmond',\n    color: { l: 93.92, a: 2.126, b: 17.014 },\n  },\n  {\n    name: 'Blue',\n    color: { l: 32.301, a: 79.194, b: -107.869 },\n  },\n  {\n    name: 'BlueViolet',\n    color: { l: 42.189, a: 69.849, b: -74.776 },\n  },\n  {\n    name: 'Brown',\n    color: { l: 37.524, a: 49.687, b: 30.537 },\n  },\n  {\n    name: 'BurlyWood',\n    color: { l: 77.018, a: 7.044, b: 30.01 },\n  },\n  {\n    name: 'CadetBlue',\n    color: { l: 61.154, a: -19.678, b: -7.43 },\n  },\n  {\n    name: 'Chartreuse',\n    color: { l: 89.873, a: -68.07, b: 85.78 },\n  },\n  {\n    name: 'Chocolate',\n    color: { l: 55.988, a: 37.046, b: 56.737 },\n  },\n  {\n    name: 'Coral',\n    color: { l: 67.293, a: 45.348, b: 47.485 },\n  },\n  {\n    name: 'CornflowerBlue',\n    color: { l: 61.927, a: 9.339, b: -49.31 },\n  },\n  {\n    name: 'Cornsilk',\n    color: { l: 97.455, a: -2.222, b: 14.281 },\n  },\n  {\n    name: 'Crimson',\n    color: { l: 47.033, a: 70.918, b: 33.591 },\n  },\n  {\n    name: 'Cyan',\n    color: { l: 91.115, a: -48.081, b: -14.143 },\n  },\n  {\n    name: 'DarkBlue',\n    color: { l: 14.756, a: 50.428, b: -68.687 },\n  },\n  {\n    name: 'DarkCyan',\n    color: { l: 52.206, a: -30.616, b: -9.006 },\n  },\n  {\n    name: 'DarkGoldenRod',\n    color: { l: 59.22, a: 9.858, b: 62.728 },\n  },\n  {\n    name: 'DarkGray',\n    color: { l: 69.238, a: -0.002, b: -0.01 },\n  },\n  {\n    name: 'DarkGreen',\n    color: { l: 36.203, a: -43.37, b: 41.859 },\n  },\n  {\n    name: 'DarkGrey',\n    color: { l: 69.238, a: -0.002, b: -0.01 },\n  },\n  {\n    name: 'DarkKhaki',\n    color: { l: 73.382, a: -8.793, b: 39.285 },\n  },\n  {\n    name: 'DarkMagenta',\n    color: { l: 32.599, a: 62.552, b: -38.742 },\n  },\n  {\n    name: 'DarkOliveGreen',\n    color: { l: 42.234, a: -18.831, b: 30.595 },\n  },\n  {\n    name: 'DarkOrange',\n    color: { l: 69.483, a: 36.818, b: 75.484 },\n  },\n  {\n    name: 'DarkOrchid',\n    color: { l: 43.38, a: 65.156, b: -60.11 },\n  },\n  {\n    name: 'DarkRed',\n    color: { l: 28.087, a: 50.997, b: 41.288 },\n  },\n  {\n    name: 'DarkSalmon',\n    color: { l: 69.855, a: 28.168, b: 27.702 },\n  },\n  {\n    name: 'DarkSeaGreen',\n    color: { l: 72.087, a: -23.821, b: 18.03 },\n  },\n  {\n    name: 'DarkSlateBlue',\n    color: { l: 30.829, a: 26.054, b: -42.091 },\n  },\n  {\n    name: 'DarkSlateGray',\n    color: { l: 31.256, a: -11.719, b: -3.729 },\n  },\n  {\n    name: 'DarkSlateGrey',\n    color: { l: 31.256, a: -11.719, b: -3.729 },\n  },\n  {\n    name: 'DarkTurquoise',\n    color: { l: 75.292, a: -40.038, b: -13.523 },\n  },\n  {\n    name: 'DarkViolet',\n    color: { l: 39.58, a: 76.325, b: -70.379 },\n  },\n  {\n    name: 'DeepPink',\n    color: { l: 55.958, a: 84.536, b: -5.714 },\n  },\n  {\n    name: 'DeepSkyBlue',\n    color: { l: 72.548, a: -17.65, b: -42.553 },\n  },\n  {\n    name: 'DimGray',\n    color: { l: 54.365, a: -0.002, b: -0.01 },\n  },\n  {\n    name: 'DimGrey',\n    color: { l: 54.365, a: -0.002, b: -0.01 },\n  },\n  {\n    name: 'DodgerBlue',\n    color: { l: 59.38, a: 9.967, b: -63.399 },\n  },\n  {\n    name: 'FireBrick',\n    color: { l: 39.115, a: 55.913, b: 37.643 },\n  },\n  {\n    name: 'FloralWhite',\n    color: { l: 98.402, a: -0.04, b: 5.363 },\n  },\n  {\n    name: 'ForestGreen',\n    color: { l: 50.594, a: -49.586, b: 45.015 },\n  },\n  {\n    name: 'Fuchsia',\n    color: { l: 60.323, a: 98.236, b: -60.842 },\n  },\n  {\n    name: 'Gainsboro',\n    color: { l: 87.761, a: -0.002, b: -0.012 },\n  },\n  {\n    name: 'GhostWhite',\n    color: { l: 97.757, a: 1.245, b: -3.359 },\n  },\n  {\n    name: 'Gold',\n    color: { l: 86.929, a: -1.932, b: 87.13 },\n  },\n  {\n    name: 'GoldenRod',\n    color: { l: 70.817, a: 8.517, b: 68.759 },\n  },\n  {\n    name: 'Gray',\n    color: { l: 53.585, a: -0.001, b: -0.008 },\n  },\n  {\n    name: 'Green',\n    color: { l: 46.228, a: -51.699, b: 49.897 },\n  },\n  {\n    name: 'GreenYellow',\n    color: { l: 91.957, a: -52.486, b: 81.863 },\n  },\n  {\n    name: 'Grey',\n    color: { l: 53.585, a: -0.001, b: -0.008 },\n  },\n  {\n    name: 'HoneyDew',\n    color: { l: 98.566, a: -7.567, b: 5.462 },\n  },\n  {\n    name: 'HotPink',\n    color: { l: 65.484, a: 64.235, b: -10.66 },\n  },\n  {\n    name: 'IndianRed',\n    color: { l: 53.393, a: 44.823, b: 22.108 },\n  },\n  {\n    name: 'Indigo',\n    color: { l: 20.47, a: 51.688, b: -53.321 },\n  },\n  {\n    name: 'Ivory',\n    color: { l: 99.64, a: -2.555, b: 7.149 },\n  },\n  {\n    name: 'Khaki',\n    color: { l: 90.328, a: -9.016, b: 44.971 },\n  },\n  {\n    name: 'Lavender',\n    color: { l: 91.828, a: 3.707, b: -9.675 },\n  },\n  {\n    name: 'LavenderBlush',\n    color: { l: 96.069, a: 5.885, b: -0.608 },\n  },\n  {\n    name: 'LawnGreen',\n    color: { l: 88.877, a: -67.86, b: 84.953 },\n  },\n  {\n    name: 'LemonChiffon',\n    color: { l: 97.648, a: -5.431, b: 22.222 },\n  },\n  {\n    name: 'LightBlue',\n    color: { l: 83.814, a: -10.891, b: -11.489 },\n  },\n  {\n    name: 'LightCoral',\n    color: { l: 66.155, a: 42.805, b: 19.546 },\n  },\n  {\n    name: 'LightCyan',\n    color: { l: 97.868, a: -9.945, b: -3.389 },\n  },\n  {\n    name: 'LightGoldenRodYellow',\n    color: { l: 97.369, a: -6.485, b: 19.225 },\n  },\n  {\n    name: 'LightGray',\n    color: { l: 84.556, a: -0.002, b: -0.012 },\n  },\n  {\n    name: 'LightGreen',\n    color: { l: 86.549, a: -46.33, b: 36.942 },\n  },\n  {\n    name: 'LightGrey',\n    color: { l: 84.556, a: -0.002, b: -0.012 },\n  },\n  {\n    name: 'LightPink',\n    color: { l: 81.054, a: 27.958, b: 5.023 },\n  },\n  {\n    name: 'LightSalmon',\n    color: { l: 74.705, a: 31.471, b: 34.539 },\n  },\n  {\n    name: 'LightSeaGreen',\n    color: { l: 65.786, a: -37.51, b: -6.34 },\n  },\n  {\n    name: 'LightSkyBlue',\n    color: { l: 79.724, a: -10.827, b: -28.514 },\n  },\n  {\n    name: 'LightSlateGray',\n    color: { l: 55.917, a: -2.247, b: -11.117 },\n  },\n  {\n    name: 'LightSlateGrey',\n    color: { l: 55.917, a: -2.247, b: -11.117 },\n  },\n  {\n    name: 'LightSteelBlue',\n    color: { l: 78.452, a: -1.281, b: -15.223 },\n  },\n  {\n    name: 'LightYellow',\n    color: { l: 99.285, a: -5.111, b: 14.825 },\n  },\n  {\n    name: 'Lime',\n    color: { l: 87.736, a: -86.184, b: 83.18 },\n  },\n  {\n    name: 'LimeGreen',\n    color: { l: 72.607, a: -67.126, b: 61.436 },\n  },\n  {\n    name: 'Linen',\n    color: { l: 95.311, a: 1.674, b: 6.009 },\n  },\n  {\n    name: 'Magenta',\n    color: { l: 60.323, a: 98.236, b: -60.842 },\n  },\n  {\n    name: 'Maroon',\n    color: { l: 25.533, a: 48.043, b: 38.054 },\n  },\n  {\n    name: 'MediumAquaMarine',\n    color: { l: 75.692, a: -38.334, b: 8.299 },\n  },\n  {\n    name: 'MediumBlue',\n    color: { l: 24.975, a: 67.182, b: -91.508 },\n  },\n  {\n    name: 'MediumOrchid',\n    color: { l: 53.643, a: 59.061, b: -47.416 },\n  },\n  {\n    name: 'MediumPurple',\n    color: { l: 54.975, a: 36.8, b: -50.102 },\n  },\n  {\n    name: 'MediumSeaGreen',\n    color: { l: 65.272, a: -48.217, b: 24.284 },\n  },\n  {\n    name: 'MediumSlateBlue',\n    color: { l: 52.157, a: 41.073, b: -65.408 },\n  },\n  {\n    name: 'MediumSpringGreen',\n    color: { l: 87.34, a: -70.684, b: 32.456 },\n  },\n  {\n    name: 'MediumTurquoise',\n    color: { l: 76.882, a: -37.356, b: -8.365 },\n  },\n  {\n    name: 'MediumVioletRed',\n    color: { l: 44.764, a: 70.991, b: -15.182 },\n  },\n  {\n    name: 'MidnightBlue',\n    color: { l: 15.859, a: 31.718, b: -49.581 },\n  },\n  {\n    name: 'MintCream',\n    color: { l: 99.156, a: -4.165, b: 1.233 },\n  },\n  {\n    name: 'MistyRose',\n    color: { l: 92.656, a: 8.744, b: 4.823 },\n  },\n  {\n    name: 'Moccasin',\n    color: { l: 91.723, a: 2.434, b: 26.349 },\n  },\n  {\n    name: 'NavajoWhite',\n    color: { l: 90.101, a: 4.505, b: 28.261 },\n  },\n  {\n    name: 'Navy',\n    color: { l: 12.974, a: 47.506, b: -64.707 },\n  },\n  {\n    name: 'OldLace',\n    color: { l: 96.78, a: 0.168, b: 8.153 },\n  },\n  {\n    name: 'Olive',\n    color: { l: 51.869, a: -12.935, b: 56.674 },\n  },\n  {\n    name: 'OliveDrab',\n    color: { l: 54.65, a: -28.226, b: 49.689 },\n  },\n  {\n    name: 'Orange',\n    color: { l: 74.934, a: 23.925, b: 78.947 },\n  },\n  {\n    name: 'OrangeRed',\n    color: { l: 57.579, a: 67.777, b: 68.955 },\n  },\n  {\n    name: 'Orchid',\n    color: { l: 62.802, a: 55.282, b: -34.419 },\n  },\n  {\n    name: 'PaleGoldenRod',\n    color: { l: 91.141, a: -7.354, b: 30.961 },\n  },\n  {\n    name: 'PaleGreen',\n    color: { l: 90.75, a: -48.299, b: 38.52 },\n  },\n  {\n    name: 'PaleTurquoise',\n    color: { l: 90.061, a: -19.638, b: -6.412 },\n  },\n  {\n    name: 'PaleVioletRed',\n    color: { l: 60.567, a: 45.515, b: 0.391 },\n  },\n  {\n    name: 'PapayaWhip',\n    color: { l: 95.076, a: 1.267, b: 14.513 },\n  },\n  {\n    name: 'PeachPuff',\n    color: { l: 89.349, a: 8.08, b: 21.011 },\n  },\n  {\n    name: 'Peru',\n    color: { l: 61.753, a: 21.389, b: 47.913 },\n  },\n  {\n    name: 'Pink',\n    color: { l: 83.586, a: 24.139, b: 3.313 },\n  },\n  {\n    name: 'Plum',\n    color: { l: 73.373, a: 32.529, b: -21.999 },\n  },\n  {\n    name: 'PowderBlue',\n    color: { l: 86.133, a: -14.092, b: -8.02 },\n  },\n  {\n    name: 'Purple',\n    color: { l: 29.784, a: 58.929, b: -36.498 },\n  },\n  {\n    name: 'RebeccaPurple',\n    color: { l: 32.903, a: 42.885, b: -47.158 },\n  },\n  {\n    name: 'Red',\n    color: { l: 53.237, a: 80.088, b: 67.199 },\n  },\n  {\n    name: 'RosyBrown',\n    color: { l: 63.607, a: 17.009, b: 6.6 },\n  },\n  {\n    name: 'RoyalBlue',\n    color: { l: 47.832, a: 26.27, b: -65.274 },\n  },\n  {\n    name: 'SaddleBrown',\n    color: { l: 37.468, a: 26.438, b: 40.981 },\n  },\n  {\n    name: 'Salmon',\n    color: { l: 67.262, a: 45.22, b: 29.084 },\n  },\n  {\n    name: 'SandyBrown',\n    color: { l: 73.953, a: 23.02, b: 46.784 },\n  },\n  {\n    name: 'SeaGreen',\n    color: { l: 51.534, a: -39.715, b: 20.047 },\n  },\n  {\n    name: 'SeaShell',\n    color: { l: 97.121, a: 2.159, b: 4.541 },\n  },\n  {\n    name: 'Sienna',\n    color: { l: 43.798, a: 29.317, b: 35.633 },\n  },\n  {\n    name: 'Silver',\n    color: { l: 77.704, a: -0.002, b: -0.011 },\n  },\n  {\n    name: 'SkyBlue',\n    color: { l: 79.208, a: -14.836, b: -21.288 },\n  },\n  {\n    name: 'SlateBlue',\n    color: { l: 45.337, a: 36.044, b: -57.783 },\n  },\n  {\n    name: 'SlateGray',\n    color: { l: 52.836, a: -2.143, b: -10.58 },\n  },\n  {\n    name: 'SlateGrey',\n    color: { l: 52.836, a: -2.143, b: -10.58 },\n  },\n  {\n    name: 'Snow',\n    color: { l: 98.644, a: 1.654, b: 0.574 },\n  },\n  {\n    name: 'SpringGreen',\n    color: { l: 88.471, a: -76.901, b: 47.022 },\n  },\n  {\n    name: 'SteelBlue',\n    color: { l: 52.467, a: -4.073, b: -32.201 },\n  },\n  {\n    name: 'Tan',\n    color: { l: 74.975, a: 5.016, b: 24.419 },\n  },\n  {\n    name: 'Teal',\n    color: { l: 48.255, a: -28.842, b: -8.484 },\n  },\n  {\n    name: 'Thistle',\n    color: { l: 80.078, a: 13.216, b: -9.242 },\n  },\n  {\n    name: 'Tomato',\n    color: { l: 62.204, a: 57.845, b: 46.412 },\n  },\n  {\n    name: 'Turquoise',\n    color: { l: 81.266, a: -44.078, b: -4.038 },\n  },\n  {\n    name: 'Violet',\n    color: { l: 69.695, a: 56.356, b: -36.825 },\n  },\n  {\n    name: 'Wheat',\n    color: { l: 89.351, a: 1.506, b: 23.997 },\n  },\n  {\n    name: 'White',\n    color: { l: 100, a: -0.002, b: 0.011 },\n  },\n  {\n    name: 'WhiteSmoke',\n    color: { l: 96.537, a: -0.002, b: -0.014 },\n  },\n  {\n    name: 'Yellow',\n    color: { l: 97.139, a: -21.562, b: 94.477 },\n  },\n  {\n    name: 'YellowGreen',\n    color: { l: 76.535, a: -37.993, b: 66.583 },\n  },\n] as const;\n","import { KDTreeSearch, type NeighborSearch, type Point3 } from '../../math';\nimport type { Cache } from '../../utils';\nimport { toXYZ as labToXYZ } from '../space/lab';\nimport { toRGB as xyzToRGB } from '../space/xyz';\nimport type { LAB, NamedColor } from '../types';\n\n/**\n * ColorNames class is used to find the name of a color.\n */\nexport class ColorNames {\n  private readonly neighborSearch: NeighborSearch<Point3>;\n  /**\n   * Create a new ColorNames instance.\n   *\n   * @param colors The list of named colors.\n   * @param cache The cache to store the results.\n   * @returns A new ColorNames instance.\n   */\n  constructor(\n    private readonly colors: ReadonlyArray<NamedColor<LAB>>,\n    private readonly cache: Cache<number, NamedColor<LAB>>,\n  ) {\n    const points = colors.map((named): Point3 => {\n      const color = named.color;\n      return [color.l, color.a, color.b];\n    });\n    this.neighborSearch = KDTreeSearch.build(points, 4);\n  }\n\n  /**\n   * Find the most similar color name to the given color.\n   *\n   * @param color The color to find.\n   * @returns The most similar color name.\n   */\n  find(color: LAB): string {\n    const key = ColorNames.createCacheKey(color);\n    const cached = this.cache.get(key);\n    if (cached) {\n      return cached.name;\n    }\n\n    const point: Point3 = [color.l, color.a, color.b];\n    const nearest = this.neighborSearch.searchNearest(point);\n    const namedColor = this.colors[nearest.index];\n    this.cache.put(key, namedColor);\n    return namedColor.name;\n  }\n\n  private static createCacheKey(lab: LAB): number {\n    const xyz = labToXYZ(lab);\n    const rgb = xyzToRGB(xyz);\n    return (rgb.r << 16) | (rgb.g << 8) | rgb.b;\n  }\n}\n","import { LFUCache } from '../../utils';\nimport { COLORS } from './colors';\nimport { ColorNames } from './names';\n\nconst CACHE_CAPACITY = 64;\n\nlet colorNameFinder: ColorNames | null = null;\n\n/**\n * Retrieve the ColorNames instance.\n *\n * @returns The ColorNames instance.\n */\nexport function retrieveColorNames(): ColorNames {\n  if (!colorNameFinder) {\n    colorNameFinder = new ColorNames(COLORS, new LFUCache(CACHE_CAPACITY));\n  }\n  return colorNameFinder;\n}\n","import { radianToDegree } from '../math';\n\nimport { assert, assertFiniteNumber } from '../utils';\nimport { type ColorDelta, type ColorDeltaMeasure, ciede2000 } from './difference';\nimport { CIELabSpace, HSLSpace, RGBSpace, XYZSpace } from './space';\nimport type { HSL, LAB, RGB } from './types';\n\nexport * from './difference';\nexport * from './name';\nexport * from './space';\nexport * from './types';\n\n/**\n * Color class represents a color in any color space.\n */\nexport class Color {\n  /**\n   * Create a new color instance.\n   *\n   * @private\n   * @param l The lightness component of the color.\n   * @param a The a component of the color.\n   * @param b The b component of the color.\n   */\n  private constructor(\n    private readonly l: number,\n    private readonly a: number,\n    private readonly b: number,\n  ) {\n    assertFiniteNumber(l, `The l(${l}) must be a finite number`);\n    assertFiniteNumber(a, `The a(${a}) must be a finite number`);\n    assertFiniteNumber(b, `The b(${b}) must be a finite number`);\n    this.l = CIELabSpace.clampL(l);\n    this.a = CIELabSpace.clampA(a);\n    this.b = CIELabSpace.clampB(b);\n  }\n\n  /**\n   * Clone the color.\n   *\n   * @returns The cloned color.\n   */\n  clone(): Color {\n    return new Color(this.l, this.a, this.b);\n  }\n\n  /**\n   * Check if the color is light.\n   *\n   * @returns True if the color is light, false otherwise.\n   * @see {@link Color.isDark}\n   */\n  isLight(): boolean {\n    return this.l > 50;\n  }\n\n  /**\n   * Check if the color is dark.\n   *\n   * @returns True if the color is dark, false otherwise.\n   * @see {@link Color.isLight}\n   */\n  isDark(): boolean {\n    return !this.isLight();\n  }\n\n  /**\n   * Calculate the lightness of the color.\n   *\n   * @returns The lightness of the color.\n   * @see {@link Color.chroma}\n   * @see {@link Color.hue}\n   */\n  lightness(): number {\n    return this.l;\n  }\n\n  /**\n   * Calculate the chroma of the color.\n   *\n   * @returns The chroma of the color.\n   * @see {@link Color.lightness}\n   * @see {@link Color.hue}\n   */\n  chroma(): number {\n    return Math.sqrt(this.a ** 2 + this.b ** 2);\n  }\n\n  /**\n   * Calculate the hue of the color.\n   *\n   * @returns The hue of the color.\n   * @see {@link Color.lightness}\n   * @see {@link Color.chroma}\n   */\n  hue(): number {\n    return radianToDegree(Math.atan2(this.b, this.a));\n  }\n\n  /**\n   * Compute the color difference between this color and the other color.\n   *\n   * @param other The other color.\n   * @param formula The formula to use to compute the color difference. Default is CIEDE2000.\n   * @returns The color difference.\n   */\n  differenceTo(other: Color, formula: ColorDeltaMeasure<LAB> = ciede2000): ColorDelta {\n    return formula({ l: this.l, a: this.a, b: this.b }, { l: other.l, a: other.a, b: other.b });\n  }\n\n  /**\n   * Return the string representation of the color.\n   *\n   * @returns The string representation of the color.\n   * @see {@link Color.fromString}\n   */\n  toString(): string {\n    const rgb = this.toRGB();\n    return RGBSpace.toHexString(rgb);\n  }\n\n  /**\n   * Convert the color to RGB color space.\n   *\n   * @returns The color in RGB color space.\n   * @see {@link Color.fromRGB}\n   */\n  toRGB(): RGB {\n    const xyz = CIELabSpace.toXYZ({ l: this.l, a: this.a, b: this.b });\n    return XYZSpace.toRGB(xyz);\n  }\n\n  /**\n   * Convert the color to HSL color space.\n   *\n   * @returns The color in HSL color space.\n   * @see {@link Color.fromHSL}\n   */\n  toHSL(): HSL {\n    const rgb = this.toRGB();\n    return HSLSpace.fromRGB(rgb);\n  }\n\n  /**\n   * Convert the color to CIELAB color space.\n   *\n   * @returns The color in CIELAB color space.\n   * @see {@link Color.fromLAB}\n   */\n  toLAB(): LAB {\n    return { l: this.l, a: this.a, b: this.b };\n  }\n\n  /**\n   * The minimum lightness of the color.\n   * @internal\n   */\n  static MIN_LIGHTNESS = 0;\n\n  /**\n   * The maximum lightness of the color.\n   * @internal\n   */\n  static MAX_LIGHTNESS = 100;\n\n  /**\n   * The minimum chroma of the color.\n   * @internal\n   */\n  static MIN_CHROMA = 0;\n\n  /**\n   * The maximum chroma of the color.\n   * @internal\n   */\n  static MAX_CHROMA = 180;\n\n  /**\n   * Create a new Color instance from the given RGB color.\n   *\n   * @param rgb - The RGB color.\n   * @returns The new Color instance.\n   * @see {@link Color.toRGB}\n   */\n  static fromRGB(rgb: RGB): Color {\n    const xyz = XYZSpace.fromRGB(rgb);\n    const lab = CIELabSpace.fromXYZ(xyz);\n    return new Color(lab.l, lab.a, lab.b);\n  }\n\n  /**\n   * Create a new Color instance from the given HSL color.\n   *\n   * @param hsl - The HSL color.\n   * @returns The new Color instance.\n   * @see {@link Color.toHSL}\n   */\n  static fromHSL(hsl: HSL): Color {\n    const rgb = HSLSpace.toRGB(hsl);\n    const xyz = XYZSpace.fromRGB(rgb);\n    const lab = CIELabSpace.fromXYZ(xyz);\n    return new Color(lab.l, lab.a, lab.b);\n  }\n\n  /**\n   * Create a new Color instance from the given CIELAB color.\n   *\n   * @param lab - The CIELAB color.\n   * @returns The new Color instance.\n   * @see {@link Color.toLAB}\n   */\n  static fromLAB(lab: LAB): Color {\n    return new Color(lab.l, lab.a, lab.b);\n  }\n\n  /**\n   * Create a new Color instance from the given string.\n   *\n   * @param value - The string to parse.\n   * @returns The new Color instance.\n   * @see {@link Color.toString}\n   */\n  static fromString(value: string): Color {\n    assert(value.startsWith('#'), `The value(${value}) is not a valid hexadecimal color string`);\n    const rgb = RGBSpace.fromHexString(value);\n    const xyz = XYZSpace.fromRGB(rgb);\n    const lab = CIELabSpace.fromXYZ(xyz);\n    return new Color(lab.l, lab.a, lab.b);\n  }\n}\n","import { type RGBA, RGBSpace } from './color';\nimport { assertRange } from './utils';\n\n/**\n * Color filter function that filters colors.\n *\n * @param color - The color to test.\n * @returns True if the color passes the filter, false otherwise.\n */\nexport type ColorFilter = (color: RGBA) => boolean;\n\n/**\n * Create a new color filter function that checks the opacity of the color.\n *\n * @param threshold - The minimum alpha value to pass the filter. The value must be in [0.0, 1.0].\n * @returns The color filter function.\n * @throws {AssertionError} If the threshold is not within the range [0.0, 1.0].\n */\nexport function opacityFilter(threshold = 1.0): ColorFilter {\n  assertRange(threshold, 0.0, 1.0, `The threshold(${threshold}) must be in [0.0, 1.0]`);\n\n  return (color: RGBA) => {\n    const alpha = color.a / 255;\n    return alpha >= threshold;\n  };\n}\n\n// @see {@link BasicThemeStrategy.filter}\nconst DEFAULT_MIN_LUMINANCE = 0.25;\nconst DEFAULT_MAX_LUMINANCE = 0.85;\n\n/**\n * Create a new color filter function that checks the luminance of the color.\n *\n * @param minThreshold - The minimum luminance value to pass the filter. The value must be in [0.0, 1.0].\n * @param maxThreshold - The maximum luminance value to pass the filter. The value must be in [0.0, 1.0].\n * @returns The color filter function.\n * @throws {AssertionError} If the minThreshold or maxThreshold is not within the range [0.0, 1.0].\n * @throws {RangeError} If the minThreshold is greater than the maxThreshold.\n */\nexport function luminanceFilter(\n  minThreshold: number = DEFAULT_MIN_LUMINANCE,\n  maxThreshold: number = DEFAULT_MAX_LUMINANCE,\n): ColorFilter {\n  assertRange(minThreshold, 0.0, 1.0, `The minThreshold(${minThreshold}) must be in [0.0, 1.0]`);\n  assertRange(maxThreshold, 0.0, 1.0, `The maxThreshold(${maxThreshold}) must be in [0.0, 1.0]`);\n\n  if (minThreshold > maxThreshold) {\n    throw new RangeError(\n      `The minThreshold(${minThreshold}) must be less than or equal to maxThreshold(${maxThreshold})`,\n    );\n  }\n\n  // The relative luminance calculation is based on the WCAG 2.0 definition:\n  // https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests\n  return (color: RGBA) => {\n    const normalized = [color.r / RGBSpace.MAX_RGB, color.g / RGBSpace.MAX_RGB, color.b / RGBSpace.MAX_RGB];\n\n    const r = normalized[0] <= 0.03928 ? normalized[0] / 12.92 : ((normalized[0] + 0.055) / 1.055) ** 2.4;\n    const g = normalized[1] <= 0.03928 ? normalized[1] / 12.92 : ((normalized[1] + 0.055) / 1.055) ** 2.4;\n    const b = normalized[2] <= 0.03928 ? normalized[2] / 12.92 : ((normalized[2] + 0.055) / 1.055) ** 2.4;\n    const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;\n    return luminance >= minThreshold && luminance <= maxThreshold;\n  };\n}\n\n/**\n * Composite multiple color filter functions into a single color filter function.\n *\n * @param filters - The color filter functions to be composed.\n * @returns The composite color filter function.\n */\nexport function composeFilters(...filters: ColorFilter[]): ColorFilter {\n  return (color: RGBA) => {\n    return filters.every((filter) => filter(color));\n  };\n}\n","import { CIELabSpace, Color, type RGBA, RGBSpace, XYZSpace } from './color';\nimport { type ColorFilter, composeFilters } from './filter';\nimport {\n  type Cluster,\n  type ClusteringAlgorithm,\n  DBSCAN,\n  type Point3,\n  type Point5,\n  denormalize,\n  euclidean,\n  normalize,\n} from './math';\nimport type { Swatch } from './swatch';\n\n/**\n * The color similarity threshold to deduplicate colors.\n *\n * @see {@link https://zschuessler.github.io/DeltaE/learn/#toc-delta-e-101}\n */\nconst COLOR_DIFFERENCE_THRESHOLD = 2.5;\n\n/**\n * SwatchExtractor class extracts swatches from an image.\n */\nexport class SwatchExtractor {\n  private readonly filter: ColorFilter;\n\n  /**\n   * Create a new SwatchExtractor instance.\n   *\n   * @param algorithm - The clustering algorithm to use.\n   * @param filters - The color filter functions to use.\n   */\n  constructor(\n    private readonly algorithm: ClusteringAlgorithm<Point5>,\n    filters: ColorFilter[],\n  ) {\n    this.filter = composeFilters(...filters);\n  }\n\n  /**\n   * Extract swatches from the given image data.\n   *\n   * @param imageData - The image data to extract swatches from.\n   * @param samplingRate - The sampling rate to sample pixels from the image.\n   * @return The extracted swatches. If no swatches are extracted, an empty array is returned.\n   */\n  extract(imageData: ImageData, samplingRate: number): Swatch[] {\n    const { data, width, height } = imageData;\n    if (data.length === 0 || width === 0 || height === 0) {\n      return [];\n    }\n\n    const pixels = this.convertToPixels(imageData, samplingRate);\n    if (pixels.length === 0) {\n      return [];\n    }\n\n    const pixelClusters = this.algorithm.fit(pixels);\n    if (pixelClusters.length === 0) {\n      return [];\n    }\n\n    const colors = this.convertToColors(pixelClusters);\n    const dbscan = new DBSCAN<Point3>(1, COLOR_DIFFERENCE_THRESHOLD, euclidean);\n    const colorClusters = dbscan.fit(colors);\n    return colorClusters.reduce((swatches: Swatch[], cluster: Cluster<Point3>): Swatch[] => {\n      const swatch = SwatchExtractor.createSwatch(cluster, pixelClusters, width, height);\n      if (swatch.population !== 0) {\n        swatches.push(swatch);\n      }\n      return swatches;\n    }, []);\n  }\n\n  private convertToPixels(imageData: ImageData, samplingRate: number): Point5[] {\n    const { data, width, height } = imageData;\n    const steps = Math.max(1, Math.floor(1 / samplingRate));\n    const pixels: Point5[] = [];\n    const channels = Math.floor(data.length / (width * height)); // 4 for RGBA, 3 for RGB\n    for (let i = 0; i < data.length; i += channels * steps) {\n      const rgba: RGBA = {\n        r: data[i],\n        g: data[i + 1],\n        b: data[i + 2],\n        a: channels === 4 ? data[i + 3] : RGBSpace.MAX_RGB,\n      };\n\n      // Exclude colors that do not meet the filter criteria.\n      if (!this.filter(rgba)) {\n        continue;\n      }\n\n      const xyz = XYZSpace.fromRGB(rgba);\n      const lab = CIELabSpace.fromXYZ(xyz);\n      const x = Math.floor((i / 4) % width);\n      const y = Math.floor((i / 4 / width) % height);\n\n      pixels.push([\n        normalize(lab.l, CIELabSpace.MIN_L, CIELabSpace.MAX_L),\n        normalize(lab.a, CIELabSpace.MIN_A, CIELabSpace.MAX_A),\n        normalize(lab.b, CIELabSpace.MIN_B, CIELabSpace.MAX_B),\n        x / width,\n        y / height,\n      ]);\n    }\n    return pixels;\n  }\n\n  private convertToColors(pixelClusters: Cluster<Point5>[]): Point3[] {\n    return pixelClusters.reduce((colors: Point3[], cluster: Cluster<Point5>): Point3[] => {\n      if (cluster.size === 0) {\n        return colors;\n      }\n\n      const pixel = cluster.getCentroid();\n      const color: Point3 = [\n        denormalize(pixel[0], CIELabSpace.MIN_L, CIELabSpace.MAX_L), // L\n        denormalize(pixel[1], CIELabSpace.MIN_A, CIELabSpace.MAX_A), // a\n        denormalize(pixel[2], CIELabSpace.MIN_B, CIELabSpace.MAX_B), // b\n      ];\n      colors.push(color);\n      return colors;\n    }, []);\n  }\n\n  /**\n   * Create optimal swatch from the given color cluster and pixel clusters.\n   *\n   * @param colorCluster - The color cluster to create a swatch from.\n   * @param pixelClusters - The pixel clusters to create a swatch from.\n   * @param width - The width of the source image.\n   * @param height - The height of the source image.\n   * @returns The optimal swatch.\n   */\n  private static createSwatch(\n    colorCluster: Cluster<Point3>,\n    pixelClusters: Cluster<Point5>[],\n    width: number,\n    height: number,\n  ): Swatch {\n    const optimalSwatch = {\n      l: 0.0,\n      a: 0.0,\n      b: 0.0,\n      x: 0.0,\n      y: 0.0,\n      size: 0,\n      population: 0,\n    };\n    for (const index of colorCluster.getMemberships().values()) {\n      const pixelCluster = pixelClusters[index];\n      if (pixelCluster.size === 0) {\n        continue;\n      }\n\n      const fraction = pixelCluster.size / (pixelCluster.size + optimalSwatch.size);\n      const [l, a, b, x, y] = pixelCluster.getCentroid();\n      optimalSwatch.l += (l - optimalSwatch.l) * fraction;\n      optimalSwatch.a += (a - optimalSwatch.a) * fraction;\n      optimalSwatch.b += (b - optimalSwatch.b) * fraction;\n\n      if (fraction >= 0.5) {\n        optimalSwatch.x = x;\n        optimalSwatch.y = y;\n        optimalSwatch.size = pixelCluster.size;\n      }\n      optimalSwatch.population += pixelCluster.size;\n    }\n\n    const color = Color.fromLAB({\n      l: denormalize(optimalSwatch.l, CIELabSpace.MIN_L, CIELabSpace.MAX_L),\n      a: denormalize(optimalSwatch.a, CIELabSpace.MIN_A, CIELabSpace.MAX_A),\n      b: denormalize(optimalSwatch.b, CIELabSpace.MIN_B, CIELabSpace.MAX_B),\n    });\n    const position = {\n      x: Math.floor(optimalSwatch.x * width),\n      y: Math.floor(optimalSwatch.y * height),\n    };\n    const population = optimalSwatch.population;\n    return { color, position, population };\n  }\n}\n","/**\n * Check if the current environment is a browser.\n *\n * @return True if the current environment is a browser, false otherwise.\n */\nexport function isBrowser(): boolean {\n  return typeof window !== 'undefined';\n}\n\n/**\n * Check if the current environment is a web worker.\n *\n * @return True if the current environment is a web worker, false otherwise.\n */\nexport function isWebWorker(): boolean {\n  return typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope;\n}\n","import { assertDefined } from './utils';\nimport { isBrowser, isWebWorker } from './utils/env';\n\n/**\n * Image source represents the source of a supported image.\n */\nexport type ImageSource =\n  | HTMLCanvasElement\n  | HTMLImageElement\n  | ImageData\n  | {\n      readonly data: Uint8ClampedArray;\n      readonly width: number;\n      readonly height: number;\n    };\n\n/**\n * Check if the given value is a canvas element.\n *\n * @param value - The value to check.\n * @return True if the value is a canvas element, false otherwise.\n */\nexport function isCanvasElement(value: ImageSource): value is HTMLCanvasElement {\n  return isBrowser() && !isWebWorker() && value instanceof HTMLCanvasElement;\n}\n\n/**\n * Check if the given value is an image element.\n *\n * @param value - The value to check.\n * @return True if the value is an image element, false otherwise.\n */\nexport function isImageElement(value: ImageSource): value is HTMLImageElement {\n  return isBrowser() && !isWebWorker() && value instanceof HTMLImageElement;\n}\n\n/**\n * Check if the given value is an ImageData object.\n *\n * @param value - The value to check.\n * @return True if the value is an ImageData object, false otherwise.\n */\nexport function isImageData(value: ImageSource): value is ImageData {\n  // Check required properties of ImageData\n  return 'data' in value && 'width' in value && 'height' in value;\n}\n\n/**\n * Create an ImageData object from the given source.\n *\n * @param source - The source of the image.\n * @return The ImageData object.\n * @throws {TypeError} If the source is not supported.\n */\nexport function createImageData(source: ImageSource): ImageData {\n  if (isCanvasElement(source)) {\n    return fromCanvasElement(source);\n  }\n  if (isImageElement(source)) {\n    return fromImageElement(source);\n  }\n  if (isImageData(source)) {\n    return source;\n  }\n  throw new TypeError('The source of the image is not supported');\n}\n\n/**\n * Ensure a 2D context from the given canvas element.\n *\n * @param canvas - The source canvas element.\n * @return The 2D rendering context.\n * @throws {Error} if the 2D context is not supported in the current environment.\n */\nfunction ensureContext2D(canvas: HTMLCanvasElement): CanvasRenderingContext2D {\n  const context = canvas.getContext('2d');\n  assertDefined(context, 'The 2D context might not supported in this environment');\n  return context;\n}\n\n/**\n * Create an ImageData object from the given canvas element.\n *\n * @param canvas - The source canvas element.\n * @return The ImageData object.\n */\nfunction fromCanvasElement(canvas: HTMLCanvasElement): ImageData {\n  const context = ensureContext2D(canvas);\n  return context.getImageData(0, 0, canvas.width, canvas.height);\n}\n\n/**\n * Create an ImageData object from the given image element.\n *\n * @param image - The source image element.\n * @return The ImageData object.\n * @throws {Error} If the image element is not loaded.\n */\nfunction fromImageElement(image: HTMLImageElement): ImageData {\n  if (!image.complete) {\n    throw new Error(`The image element is not loaded: ${image.src}`);\n  }\n\n  const canvasElement = document.createElement('canvas');\n  canvasElement.width = image.width;\n  canvasElement.height = image.height;\n  const context = ensureContext2D(canvasElement);\n  context.drawImage(image, 0, 0, canvasElement.width, canvasElement.height);\n  return context.getImageData(0, 0, canvasElement.width, canvasElement.height);\n}\n","import { Color } from '../color';\nimport { normalize } from '../math';\nimport type { Swatch } from '../swatch';\nimport { assertPositiveInteger } from '../utils';\nimport type { ThemeStrategy } from './strategy';\n\n// The `MIN_LIGHTNESS` and `MAX_LIGHTNESS` values are derived from the following paper:\n// \"Colorgorical: Creating discriminable and preferable color palettes for information visualization\"\n// The paper can be found at the following URL:\n// http://vrl.cs.brown.edu/color/pdf/colorgorical.pdf?v=5dd92af6d1e6c5584236275adc769e82\nconst MIN_LIGHTNESS = 25;\nconst MAX_LIGHTNESS = 85;\n\nconst WEIGHT_CHROMA = 0.25;\nconst WEIGHT_LIGHTNESS = 0.25;\nconst WEIGHT_POPULATION = 0.5;\n\n/**\n * The ThemeStrategy implementation for the basic theme.\n */\nexport class BasicThemeStrategy implements ThemeStrategy {\n  /**\n   * Create a new DefaultThemeStrategy instance.\n   *\n   * @param maxPopulation - The maximum population of the palette.\n   * @throws {AssertionError} If the maxPopulation is not a positive integer.\n   */\n  constructor(private readonly maxPopulation: number) {\n    assertPositiveInteger(maxPopulation, `The maximum population must be a positive integer: ${maxPopulation}`);\n  }\n\n  /**\n   * {@inheritDoc ThemeStrategy.filter}\n   */\n  filter(swatch: Swatch): boolean {\n    const lightness = swatch.color.lightness();\n    return lightness >= MIN_LIGHTNESS && lightness <= MAX_LIGHTNESS;\n  }\n\n  /**\n   * {@inheritDoc ThemeStrategy.score}\n   */\n  score(swatch: Swatch): number {\n    const chroma = normalize(swatch.color.chroma(), Color.MIN_CHROMA, Color.MAX_CHROMA);\n    const lightness = normalize(swatch.color.lightness(), Color.MIN_LIGHTNESS, Color.MAX_LIGHTNESS);\n    const population = normalize(swatch.population, 0, this.maxPopulation);\n    return WEIGHT_CHROMA * chroma + WEIGHT_LIGHTNESS * lightness + WEIGHT_POPULATION * population;\n  }\n}\n","import { Color } from '../color';\nimport { normalize } from '../math';\nimport type { Swatch } from '../swatch';\nimport { assertRange } from '../utils';\nimport type { ThemeStrategy } from './strategy';\n\nconst DEFAULT_MAX_LIGHTNESS = 50;\n\n/**\n * The ThemeStrategy implementation for the dark theme.\n */\nexport class DarkThemeStrategy implements ThemeStrategy {\n  /**\n   * Create a new DarkThemeStrategy instance.\n   *\n   * @param maxLightness - The maximum lightness of the theme. The default value is 50.\n   * @throws {AssertionError} If the maxLightness is not in the range [0, 100].\n   */\n  constructor(private readonly maxLightness: number = DEFAULT_MAX_LIGHTNESS) {\n    assertRange(\n      maxLightness,\n      Color.MIN_LIGHTNESS,\n      Color.MAX_LIGHTNESS,\n      `The maximum lightness must be in the range [${Color.MIN_LIGHTNESS}, ${Color.MAX_LIGHTNESS}]: ${maxLightness}`,\n    );\n  }\n\n  /**\n   * {@inheritDoc ThemeStrategy.filter}\n   */\n  filter(swatch: Swatch): boolean {\n    const lightness = swatch.color.lightness();\n    return lightness <= this.maxLightness;\n  }\n\n  /**\n   * {@inheritDoc ThemeStrategy.score}\n   */\n  score(swatch: Swatch): number {\n    const lightness = swatch.color.lightness();\n    return 1 - normalize(lightness, Color.MIN_LIGHTNESS, Color.MAX_LIGHTNESS);\n  }\n}\n","import { Color } from '../color';\nimport { normalize } from '../math';\nimport type { Swatch } from '../swatch';\nimport { assertRange } from '../utils';\nimport type { ThemeStrategy } from './strategy';\n\nconst DEFAULT_MIN_LIGHTNESS = 50;\n\n/**\n * The ThemeStrategy implementation for the light theme.\n */\nexport class LightThemeStrategy implements ThemeStrategy {\n  /**\n   * Create a new LightThemeStrategy instance.\n   *\n   * @param minLightness - The minimum lightness of the theme. The default value is 50.\n   * @throws {AssertionError} If the minLightness is not in the range [0, 100].\n   */\n  constructor(private readonly minLightness: number = DEFAULT_MIN_LIGHTNESS) {\n    assertRange(\n      minLightness,\n      Color.MIN_LIGHTNESS,\n      Color.MAX_LIGHTNESS,\n      `The minimum lightness must be in the range [${Color.MIN_LIGHTNESS}, ${Color.MAX_LIGHTNESS}]: ${minLightness}`,\n    );\n  }\n\n  /**\n   * {@inheritDoc ThemeStrategy.filter}\n   */\n  filter(swatch: Swatch): boolean {\n    const lightness = swatch.color.lightness();\n    return lightness >= this.minLightness;\n  }\n\n  /**\n   * {@inheritDoc ThemeStrategy.score}\n   */\n  score(swatch: Swatch): number {\n    const lightness = swatch.color.lightness();\n    return normalize(lightness, Color.MIN_LIGHTNESS, Color.MAX_LIGHTNESS);\n  }\n}\n","import { Color } from '../color';\nimport { normalize } from '../math';\nimport type { Swatch } from '../swatch';\nimport { assertRange } from '../utils';\nimport type { ThemeStrategy } from './strategy';\n\nconst DEFAULT_MAX_CHROMA = 80;\n\n/**\n * The ThemeStrategy implementation for the muted theme.\n */\nexport class MutedThemeStrategy implements ThemeStrategy {\n  /**\n   * Create a new MutedThemeStrategy instance.\n   *\n   * @param maxChroma - The maximum chroma of the palette. The default value is 80.\n   * @throws {AssertionError} If the maxChroma is not in the range [0, 180].\n   */\n  constructor(private readonly maxChroma: number = DEFAULT_MAX_CHROMA) {\n    assertRange(\n      maxChroma,\n      Color.MIN_CHROMA,\n      Color.MAX_CHROMA,\n      `The maximum chroma must be in the range [${Color.MIN_CHROMA}, ${Color.MAX_CHROMA}]: ${maxChroma}`,\n    );\n  }\n\n  /**\n   * {@inheritDoc ThemeStrategy.filter}\n   */\n  filter(swatch: Swatch): boolean {\n    const chroma = swatch.color.chroma();\n    return chroma <= this.maxChroma;\n  }\n\n  /**\n   * {@inheritDoc ThemeStrategy.score}\n   */\n  score(swatch: Swatch): number {\n    const chroma = swatch.color.chroma();\n    return 1.0 - normalize(chroma, Color.MIN_CHROMA, Color.MAX_CHROMA);\n  }\n}\n","import { Color } from '../color';\nimport { normalize } from '../math';\nimport type { Swatch } from '../swatch';\nimport { assertRange } from '../utils';\nimport type { ThemeStrategy } from './strategy';\n\nconst DEFAULT_MIN_CHROMA = 60;\n\n/**\n * The ThemeStrategy implementation for the vivid theme.\n */\nexport class VividThemeStrategy implements ThemeStrategy {\n  /**\n   * Create a new VividThemeStrategy instance.\n   *\n   * @param minChroma - The minimum chroma of the theme. The default value is 60.\n   * @throws {AssertionError} If the minChroma is not in the range [0, 180].\n   */\n  constructor(private readonly minChroma: number = DEFAULT_MIN_CHROMA) {\n    assertRange(\n      minChroma,\n      Color.MIN_CHROMA,\n      Color.MAX_CHROMA,\n      `The minimum chroma must be in the range [${Color.MIN_CHROMA}, ${Color.MAX_CHROMA}]: ${minChroma}`,\n    );\n  }\n\n  /**\n   * {@inheritDoc ThemeStrategy.filter}\n   */\n  filter(swatch: Swatch): boolean {\n    const chroma = swatch.color.chroma();\n    return chroma >= this.minChroma;\n  }\n\n  /**\n   * {@inheritDoc ThemeStrategy.score}\n   */\n  score(swatch: Swatch): number {\n    const chroma = swatch.color.chroma();\n    return normalize(chroma, Color.MIN_CHROMA, Color.MAX_CHROMA);\n  }\n}\n","import type { ThemeStrategy } from './strategy';\nimport type { ThemeVisitor } from './visitor';\n\n/**\n * Theme type represents a color theme.\n * - basic: The theme with basic colors.\n * - vivid: The theme with vivid colors.\n * - muted: The theme with muted colors.\n * - light: The theme with light colors.\n * - dark: The theme with dark colors.\n */\nexport type Theme = 'basic' | 'vivid' | 'muted' | 'light' | 'dark';\n\nexport type { ThemeStrategy, ThemeVisitor };\n\nexport { BasicThemeStrategy } from './basic';\nexport { DarkThemeStrategy } from './dark';\nexport { LightThemeStrategy } from './light';\nexport { MutedThemeStrategy } from './muted';\nexport { VividThemeStrategy } from './vivid';\n\nconst visitors: Record<Theme, <P, R>(visitor: ThemeVisitor<P, R>, parameters: P) => R> = {\n  basic: (visitor, parameters) => visitor.visitBasic(parameters),\n  vivid: (visitor, parameters) => visitor.visitVivid(parameters),\n  muted: (visitor, parameters) => visitor.visitMuted(parameters),\n  light: (visitor, parameters) => visitor.visitLight(parameters),\n  dark: (visitor, parameters) => visitor.visitDark(parameters),\n} as const;\n\n/**\n * Visit the theme with the visitor.\n *\n * @param theme - The theme to visit.\n * @param visitor - The visitor to visit the theme.\n * @param parameters - The parameters to visit the theme.\n * @returns The result of the visitor.\n */\nexport function visit<P, R>(theme: Theme, visitor: ThemeVisitor<P, R>, parameters: P): R {\n  return visitors[theme](visitor, parameters);\n}\n","import { type Color, retrieveColorNames } from './color';\nimport { SwatchExtractor } from './extractor';\nimport { type ColorFilter, opacityFilter } from './filter';\nimport { type ImageSource, createImageData } from './image';\nimport {\n  DBSCAN,\n  DBSCANpp,\n  FarthestPointSampling,\n  KDTreeSearch,\n  Kmeans,\n  KmeansPlusPlusInitializer,\n  type Neighbor,\n  type NeighborSearch,\n  type Point3,\n  type Point5,\n  type SamplingStrategy,\n  euclidean,\n  squaredEuclidean,\n} from './math';\nimport type { NamedSwatch, Swatch } from './swatch';\nimport {\n  BasicThemeStrategy,\n  DarkThemeStrategy,\n  LightThemeStrategy,\n  MutedThemeStrategy,\n  type Theme,\n  type ThemeStrategy,\n  VividThemeStrategy,\n  visit,\n} from './theme';\nimport { assert, assertPositiveInteger } from './utils';\n\n/**\n * The algorithm to use for palette extraction.\n * dbscan: Density-based spatial clustering of applications with noise(DBSCAN) clustering.\n * kmeans: K-means clustering.\n *\n * @see [DBSCAN - Wikipedia](https://en.wikipedia.org/wiki/DBSCAN)\n * @see [k-means clustering - Wikipedia](https://en.wikipedia.org/wiki/K-means_clustering)\n */\nexport type Algorithm = 'dbscan' | 'dbscan++' | 'kmeans';\n\n/**\n * Options interface for palette extraction.\n *\n * @see {@link Palette.extract}\n */\nexport interface Options {\n  /**\n   * The algorithm to use for palette extraction. Default is dbscan.\n   */\n  readonly algorithm?: Algorithm;\n\n  /**\n   * The sampling rate to sample pixels from the image in the range of (0, 1]. Default is 1.0.\n   */\n  readonly samplingRate?: number;\n\n  /**\n   * The maximum number of swatches to extract. Default is 256.\n   */\n  readonly maxSwatches?: number;\n\n  /**\n   * The color filter functions. Default is [opacityFilter()].\n   *\n   * @see {@link opacityFilter}\n   */\n  readonly filters?: ColorFilter[];\n}\n\nconst SIMILAR_COLOR_THRESHOLD = 20.0;\n\nconst MIN_SCORE_COEFFICIENT = 0.0;\nconst MAX_SCORE_COEFFICIENT = 1.0;\nconst REDUCED_SCORE_COEFFICIENT = 0.5;\n\nconst LOWER_SAMPLING_RATE = 0.0;\nconst UPPER_SAMPLING_RATE = 1.0;\n\nconst DEFAULT_OPTIONS: Required<Options> = {\n  algorithm: 'dbscan',\n  samplingRate: 1.0,\n  maxSwatches: 256,\n  filters: [opacityFilter()],\n};\n\n/**\n * Palette class represents a color palette.\n */\nexport class Palette {\n  private readonly swatches: Swatch[];\n  private readonly samplingStrategy: SamplingStrategy<Point3>;\n\n  /**\n   * Create a new Palette instance.\n   *\n   * @param swatches - The swatches of the palette.\n   * @see {@link Palette.extract}\n   */\n  constructor(swatches: Swatch[]) {\n    this.swatches = Array.from(swatches);\n    this.samplingStrategy = new FarthestPointSampling<Point3>(euclidean);\n  }\n\n  /**\n   * Return the number of swatches.\n   *\n   * @return The number of swatches.\n   * @see {@link Palette.isEmpty}\n   */\n  size(): number {\n    return this.swatches.length;\n  }\n\n  /**\n   * Check whether the palette is empty.\n   *\n   * @return True if the palette is empty, false otherwise.\n   * @see {@link Palette.size}\n   */\n  isEmpty(): boolean {\n    return this.swatches.length === 0;\n  }\n\n  /**\n   * Find the best swatches from the palette.\n   *\n   * @param n The number of swatches to find.\n   * @param theme The theme of the swatches. Default is basic.\n   * @return The best swatches. If the palette is empty, an empty array is returned.\n   * @throws {TypeError} If the number of swatches to find is not an integer or less than 0.\n   */\n  findSwatches(n: number, theme: Theme = 'basic'): NamedSwatch[] {\n    assertPositiveInteger(n, `The number of swatches to find must be a positive integer: ${n}`);\n    if (n >= this.swatches.length) {\n      return this.swatches.map((swatch: Swatch): NamedSwatch => {\n        const name = Palette.findColorName(swatch.color);\n        return { name, ...swatch };\n      });\n    }\n\n    const themeStrategy = this.createThemeStrategy(theme);\n    const candidates = this.swatches.filter((swatch: Swatch) => themeStrategy.filter(swatch));\n    if (candidates.length === 0) {\n      return [];\n    }\n\n    const colors = candidates.map((swatch: Swatch): Point3 => {\n      const { l, a, b } = swatch.color.toLAB();\n      return [l, a, b];\n    });\n\n    const neighborSearch = KDTreeSearch.build(colors, 4, euclidean);\n    const coefficients = new Array<number>(colors.length).fill(MAX_SCORE_COEFFICIENT);\n    const sampledIndices = this.samplingStrategy.sample(colors, n);\n    const swatches: NamedSwatch[] = [];\n    for (const index of sampledIndices) {\n      const color = colors[index];\n      const swatch = Palette.findOptimalSwatch(candidates, color, neighborSearch, coefficients, themeStrategy);\n      const name = Palette.findColorName(swatch.color);\n      swatches.push({ name, ...swatch });\n    }\n    return swatches;\n  }\n\n  private createThemeStrategy(theme: Theme): ThemeStrategy {\n    return visit<Swatch, ThemeStrategy>(\n      theme,\n      {\n        visitBasic(swatch: Swatch): ThemeStrategy {\n          // The swatch at the first index is the dominant swatch and has the largest population.\n          return new BasicThemeStrategy(swatch.population);\n        },\n        visitVivid(_swatch: Swatch): ThemeStrategy {\n          return new VividThemeStrategy();\n        },\n        visitMuted(_swatch: Swatch): ThemeStrategy {\n          return new MutedThemeStrategy();\n        },\n        visitLight(_swatch: Swatch): ThemeStrategy {\n          return new LightThemeStrategy();\n        },\n        visitDark(_swatch: Swatch): ThemeStrategy {\n          return new DarkThemeStrategy();\n        },\n      },\n      this.swatches[0],\n    );\n  }\n\n  private static findOptimalSwatch(\n    swatches: Swatch[],\n    color: Point3,\n    neighborSearch: NeighborSearch<Point3>,\n    coefficients: number[],\n    strategy: ThemeStrategy,\n  ): Swatch {\n    // Find the neighbors of the color within the radius of 20.0 in the LAB color space.\n    // The radius is determined by the experiment.\n    const neighbors = neighborSearch.searchRadius(color, SIMILAR_COLOR_THRESHOLD);\n\n    // Find the best neighbor which has the largest score.\n    const bestNeighbor = neighbors.reduce((optimal: Neighbor, neighbor: Neighbor): Neighbor => {\n      const optimalSwatch = swatches[optimal.index];\n      const currentSwatch = swatches[neighbor.index];\n\n      const optimalCoefficient = coefficients[optimal.index];\n      const currentCoefficient = coefficients[neighbor.index];\n\n      // Reduce the score coefficient of the current swatch to avoid selecting the same color.\n      coefficients[neighbor.index] = currentCoefficient * REDUCED_SCORE_COEFFICIENT;\n\n      const optimalWeight = strategy.score(optimalSwatch) * optimalCoefficient;\n      const currentWeight = strategy.score(currentSwatch) * currentCoefficient;\n      if (optimalWeight > currentWeight) {\n        return optimal;\n      }\n      return neighbor;\n    });\n    coefficients[bestNeighbor.index] = MIN_SCORE_COEFFICIENT;\n    return swatches[bestNeighbor.index];\n  }\n\n  /**\n   * Extract a color palette from the given image source.\n   *\n   * @param source The source of the image.\n   * @param options The options for palette extraction.\n   * @return A new Palette instance containing the extracted swatches.\n   */\n  static extract(source: ImageSource, options: Partial<Options> = {}): Palette {\n    const { algorithm, samplingRate, maxSwatches, filters } = {\n      ...DEFAULT_OPTIONS,\n      ...options,\n    };\n    assert(\n      Number.isFinite(samplingRate) && samplingRate > LOWER_SAMPLING_RATE && samplingRate <= UPPER_SAMPLING_RATE,\n      `The sampling rate must be in the range of (${LOWER_SAMPLING_RATE}, ${UPPER_SAMPLING_RATE}]: ${samplingRate}`,\n    );\n    assertPositiveInteger(maxSwatches, `The maximum number of swatches must be a positive integer: ${maxSwatches}`);\n\n    const extractor = Palette.createExtractor(algorithm, filters);\n    const imageData = createImageData(source);\n    const swatches = extractor.extract(imageData, samplingRate);\n    swatches.sort((swatch1: Swatch, swatch2: Swatch): number => {\n      return swatch2.population - swatch1.population;\n    });\n    return new Palette(swatches.slice(0, maxSwatches));\n  }\n\n  /**\n   * Create a new SwatchExtractor instance with the given algorithm and filters.\n   *\n   * @param algorithm - The clustering algorithm to use.\n   * @param filters - The color filter functions to use.\n   * @return A new SwatchExtractor instance.\n   */\n  private static createExtractor(algorithm: Algorithm, filters: ColorFilter[]): SwatchExtractor {\n    if (algorithm === 'dbscan') {\n      const dbscan = new DBSCAN<Point5>(16, 0.0016, squaredEuclidean);\n      return new SwatchExtractor(dbscan, [...filters]);\n    }\n\n    if (algorithm === 'dbscan++') {\n      const dbscan = new DBSCANpp<Point5>(0.1, 16, 0.0016, squaredEuclidean);\n      return new SwatchExtractor(dbscan, [...filters]);\n    }\n\n    const strategy = new KmeansPlusPlusInitializer<Point5>(squaredEuclidean);\n    const kmeans = new Kmeans<Point5>(32, 10, 0.0001, squaredEuclidean, strategy);\n    return new SwatchExtractor(kmeans, [...filters]);\n  }\n\n  /**\n   * Find the most similar color name to the given color.\n   *\n   * @param color - The color to find.\n   * @returns The most similar color name.\n   */\n  private static findColorName(color: Color): string {\n    const lab = color.toLAB();\n    return retrieveColorNames().find(lab);\n  }\n}\n"],"mappings":"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","names":["src_exports","__export","Color","Palette","cie76","cie94","ciede2000","luminanceFilter","opacityFilter","__toCommonJS","isNumber","value","AssertionError","message","assert","condition","assertDefined","value","assertFiniteNumber","isNumber","assertInteger","assertPositiveInteger","assertRange","min","max","ArrayQueue","elements","element","DoubleLinkedList","node","first","last","PriorityQueue","comparator","element","index","parentIndex","parentElement","rootElement","lastElement","limit","leftChildIndex","rightChildIndex","leftChild","rightChild","index1","index2","temporary","LFUCache","capacity","assertPositiveInteger","key","cached","value","previousValue","lastNode","assertDefined","entry","newNode","node","oldFrequencyList","newFrequencyList","frequency","frequencyList","DoubleLinkedList","euclidean","point1","point2","squared","squaredEuclidean","distance","total","value","index","delta","assertFiniteNumber","NO_INDEX","Vector","_Vector","source","invalidIndex","value","assert","i","other","components","assertFiniteNumber","scalar","distanceMeasure","euclidean","Cluster","initialCentroid","Vector","index","point","assert","Node","_Node","axis","indices","left","right","assert","index","DEFAULT_LEAF_SIZE","KDTreeSearch","_KDTreeSearch","root","points","distanceMeasure","query","k","assert","neighbors","PriorityQueue","neighbor1","neighbor2","point","result","radius","node","neighbor","index","distance","delta","maxDistance","leafSize","euclidean","assertPositiveInteger","indices","_","assertDefined","depth","dimension","axis","Node","median","index1","index2","left","right","OUTLIER","MARKED","UNDEFINED","DBSCAN","_DBSCAN","minPoints","epsilon","distanceMeasure","assert","points","label","labels","clusters","neighborSearch","KDTreeSearch","i","point","neighbors","cluster","centroid","Vector","Cluster","queue","ArrayQueue","neighbor","neighborIndex","neighborPoint","secondaryNeighbors","secondaryNeighbor","secondaryNeighborIndex","secondaryNeighborLabel","OUTLIER","MARKED","UNDEFINED","DBSCANpp","probability","minPoints","epsilon","distanceMeasure","assert","points","pointsSearch","KDTreeSearch","corePoints","corePointsSearch","coreLabels","neighborSearch","step","point","label","labels","neighbors","neighbor","queue","ArrayQueue","neighborIndex","neighborPoint","secondaryNeighbors","i","secondaryNeighbor","secondaryNeighborIndex","secondaryNeighborLabel","clusters","nearest","coreLabel","cluster","centroid","Vector","newCluster","Cluster","Kmeans","k","maxIterations","tolerance","distanceMeasure","initializationStrategy","assertPositiveInteger","assert","points","point","index","cluster","Cluster","clusters","centroid","i","centroids","updated","oldCentroid","newCentroid","neighborSearch","KDTreeSearch","neighbor","NO_INDEX","KmeansPlusPlusInitializer","_KmeansPlusPlusInitializer","distanceMeasure","points","k","assertPositiveInteger","selected","data","dataSize","totalDistanceCache","totalDistance","i","point","nearestDistance","targetDistance","targetIndex","_","index","distance","minDistance","selectedPoint","FarthestPointSampling","distanceMeasure","points","n","assert","sampled","distances","initialIndex","i","farthestIndex","previousDistance","currentDistance","j","farthestDistance","distance","clamp","value","min","max","assertFiniteNumber","normalize","denormalize","degreeToRadian","degree","radianToDegree","radian","cie76","color1","color2","deltaL","deltaA","deltaB","cie94","color1","color2","deltaL","deltaA","deltaB","c1","c2","deltaC","deltaH","sL","sC","sH","squared","kL","kC","kH","POW7_25","toHPrime","x","y","angle","radianToDegree","toHBarPrime","hPrime1","hPrime2","toDeltaHPrime","c1","c2","h1","h2","deltaH","ciede2000","color1","color2","deltaLPrime","lBar","cBar","g","aPrime1","aPrime2","cPrime1","cPrime2","cBarPrime","deltaCPrime","deltaHPrime","degreeToRadian","hBarPrime","t","sL","sC","sH","pow7CBarPrime","rT","l","c","h","squared","hsl_exports","__export","clampLightness","clampSaturation","fromRGB","normalizeHue","toRGB","rgb_exports","__export","MAX_RGB","clampValue","fromHexString","toHexString","MIN_RGB","MAX_RGB","clampValue","value","clamp","fromHexString","assert","r","g","b","assertInteger","toHexString","string","hex","MAX_HUE","MIN_SATURATION","MAX_SATURATION","MIN_LIGHTNESS","MAX_LIGHTNESS","normalizeHue","value","clampSaturation","clamp","clampLightness","fromRGB","rgb","assertInteger","r","clampValue","MAX_RGB","g","b","max","min","delta","hue","lightness","saturation","toRGB","h","s","l","assertFiniteNumber","c","x","m","lab_exports","__export","MAX_A","MAX_B","MAX_L","MIN_A","MIN_B","MIN_L","clampA","clampB","clampL","fromXYZ","toXYZ","xyz_exports","__export","D65","clampX","clampY","clampZ","fromRGB","toRGB","MIN_X","MAX_X","MIN_Y","MAX_Y","MIN_Z","MAX_Z","clampX","value","clamp","clampY","clampZ","D65","fromRGB","r","g","b","assertInteger","f","fr","MAX_RGB","fg","fb","x","y","z","toRGB","assertFiniteNumber","clampValue","MIN_L","MAX_L","MIN_A","MAX_A","MIN_B","MAX_B","clampL","value","clamp","clampA","clampB","fromXYZ","x","y","z","assertFiniteNumber","epsilon","kappa","delta","f","t","fx","D65","fy","fz","l","a","b","toXYZ","l2","a2","b2","clampX","clampY","clampZ","COLORS","ColorNames","_ColorNames","colors","cache","points","named","color","KDTreeSearch","key","cached","point","nearest","namedColor","lab","xyz","toXYZ","rgb","toRGB","CACHE_CAPACITY","colorNameFinder","retrieveColorNames","ColorNames","COLORS","LFUCache","Color","_Color","l","a","b","assertFiniteNumber","lab_exports","radianToDegree","other","formula","ciede2000","rgb","rgb_exports","xyz","xyz_exports","hsl_exports","lab","hsl","value","assert","opacityFilter","threshold","assertRange","color","DEFAULT_MIN_LUMINANCE","DEFAULT_MAX_LUMINANCE","luminanceFilter","minThreshold","maxThreshold","normalized","rgb_exports","r","g","b","luminance","composeFilters","filters","filter","COLOR_DIFFERENCE_THRESHOLD","SwatchExtractor","_SwatchExtractor","algorithm","filters","composeFilters","imageData","samplingRate","data","width","height","pixels","pixelClusters","colors","DBSCAN","euclidean","swatches","cluster","swatch","steps","channels","i","rgba","rgb_exports","xyz","xyz_exports","lab","lab_exports","x","y","normalize","pixel","color","denormalize","colorCluster","optimalSwatch","index","pixelCluster","fraction","l","a","b","Color","position","population","isBrowser","isWebWorker","isCanvasElement","value","isBrowser","isWebWorker","isImageElement","isImageData","createImageData","source","fromCanvasElement","fromImageElement","ensureContext2D","canvas","context","assertDefined","image","canvasElement","MIN_LIGHTNESS","MAX_LIGHTNESS","WEIGHT_CHROMA","WEIGHT_LIGHTNESS","WEIGHT_POPULATION","BasicThemeStrategy","maxPopulation","assertPositiveInteger","swatch","lightness","chroma","normalize","Color","population","DEFAULT_MAX_LIGHTNESS","DarkThemeStrategy","maxLightness","assertRange","Color","swatch","lightness","normalize","DEFAULT_MIN_LIGHTNESS","LightThemeStrategy","minLightness","assertRange","Color","swatch","lightness","normalize","DEFAULT_MAX_CHROMA","MutedThemeStrategy","maxChroma","assertRange","Color","swatch","chroma","normalize","DEFAULT_MIN_CHROMA","VividThemeStrategy","minChroma","assertRange","Color","swatch","chroma","normalize","visitors","visitor","parameters","visit","theme","SIMILAR_COLOR_THRESHOLD","MIN_SCORE_COEFFICIENT","MAX_SCORE_COEFFICIENT","REDUCED_SCORE_COEFFICIENT","LOWER_SAMPLING_RATE","UPPER_SAMPLING_RATE","DEFAULT_OPTIONS","opacityFilter","Palette","_Palette","swatches","FarthestPointSampling","euclidean","n","theme","assertPositiveInteger","swatch","themeStrategy","candidates","colors","l","a","b","neighborSearch","KDTreeSearch","coefficients","sampledIndices","index","color","name","visit","BasicThemeStrategy","_swatch","VividThemeStrategy","MutedThemeStrategy","LightThemeStrategy","DarkThemeStrategy","strategy","bestNeighbor","optimal","neighbor","optimalSwatch","currentSwatch","optimalCoefficient","currentCoefficient","optimalWeight","currentWeight","source","options","algorithm","samplingRate","maxSwatches","filters","assert","extractor","imageData","createImageData","swatch1","swatch2","dbscan","DBSCAN","squaredEuclidean","SwatchExtractor","DBSCANpp","KmeansPlusPlusInitializer","kmeans","Kmeans","lab","retrieveColorNames"]}