import {
  createNumberFormatter
} from "./LR7LBJN3.jsx";

// src/colors/intl.ts
var COLOR_INTL_TRANSLATIONS = {
  hue: "Hue",
  saturation: "Saturation",
  lightness: "Lightness",
  brightness: "Brightness",
  red: "Red",
  green: "Green",
  blue: "Blue",
  alpha: "Alpha",
  colorName: (lightness, chroma, hue) => `${lightness} ${chroma} ${hue}`,
  transparentColorName: (lightness, chroma, hue, percentTransparent) => `${lightness} ${chroma} ${hue}, ${percentTransparent} transparent`,
  "very dark": "very dark",
  dark: "dark",
  light: "light",
  "very light": "very light",
  pale: "pale",
  grayish: "grayish",
  vibrant: "vibrant",
  black: "black",
  white: "white",
  gray: "gray",
  pink: "pink",
  "pink red": "pink red",
  "red orange": "red orange",
  brown: "brown",
  orange: "orange",
  "orange yellow": "orange yellow",
  "brown yellow": "brown yellow",
  yellow: "yellow",
  "yellow green": "yellow green",
  "green cyan": "green cyan",
  cyan: "cyan",
  "cyan blue": "cyan blue",
  "blue purple": "blue purple",
  purple: "purple",
  "purple magenta": "purple magenta",
  magenta: "magenta",
  "magenta pink": "magenta pink"
};

// src/colors/utils.ts
import { clamp } from "@kobalte/utils";
function parseColor(value) {
  const res = RGBColor.parse(value) || HSBColor.parse(value) || HSLColor.parse(value);
  if (res) {
    return res;
  }
  throw new Error(`Invalid color value: ${value}`);
}
function normalizeColor(v) {
  if (typeof v === "string") {
    return parseColor(v);
  }
  return v;
}
function getColorChannels(colorSpace) {
  switch (colorSpace) {
    case "rgb":
      return RGBColor.colorChannels;
    case "hsl":
      return HSLColor.colorChannels;
    case "hsb":
      return HSBColor.colorChannels;
  }
}
function normalizeHue(hue) {
  if (hue === 360) {
    return hue;
  }
  return (hue % 360 + 360) % 360;
}
var ORANGE_LIGHTNESS_THRESHOLD = 0.68;
var YELLOW_GREEN_LIGHTNESS_THRESHOLD = 0.85;
var MAX_DARK_LIGHTNESS = 0.55;
var GRAY_THRESHOLD = 1e-3;
var OKLCH_HUES = [
  [0, "pink"],
  [15, "red"],
  [48, "orange"],
  [94, "yellow"],
  [135, "green"],
  [175, "cyan"],
  [264, "blue"],
  [284, "purple"],
  [320, "magenta"],
  [349, "pink"]
];
var Color = class {
  toHexInt() {
    return this.toFormat("rgb").toHexInt();
  }
  getChannelValue(channel) {
    if (channel in this) {
      return this[channel];
    }
    throw new Error(`Unsupported color channel: ${channel}`);
  }
  withChannelValue(channel, value) {
    if (channel in this) {
      const x = this.clone();
      x[channel] = value;
      return x;
    }
    throw new Error(`Unsupported color channel: ${channel}`);
  }
  getChannelName(channel, translations) {
    return translations[channel];
  }
  getColorSpaceAxes(xyChannels) {
    const { xChannel, yChannel } = xyChannels;
    const xCh = xChannel || this.getColorChannels().find((c) => c !== yChannel);
    const yCh = yChannel || this.getColorChannels().find((c) => c !== xCh);
    const zCh = this.getColorChannels().find((c) => c !== xCh && c !== yCh);
    return { xChannel: xCh, yChannel: yCh, zChannel: zCh };
  }
  getColorName(translations) {
    let [l, c, h] = toOKLCH(this);
    if (l > 0.999) {
      return translations.white;
    }
    if (l < 1e-3) {
      return translations.black;
    }
    let hue;
    [hue, l] = this.getOklchHue(l, c, h, translations);
    let lightness = "";
    let chroma = "";
    if (c <= 0.1 && c >= GRAY_THRESHOLD) {
      if (l >= 0.7) {
        chroma = "pale";
      } else {
        chroma = "grayish";
      }
    } else if (c >= 0.15) {
      chroma = "vibrant";
    }
    if (l < 0.3) {
      lightness = "very dark";
    } else if (l < MAX_DARK_LIGHTNESS) {
      lightness = "dark";
    } else if (l < 0.7) {
    } else if (l < 0.85) {
      lightness = "light";
    } else {
      lightness = "very light";
    }
    if (chroma) {
      chroma = translations[chroma];
    }
    if (lightness) {
      lightness = translations[lightness];
    }
    const alpha = this.getChannelValue("alpha");
    if (alpha < 1) {
      const percentTransparent = createNumberFormatter(() => ({
        style: "percent"
      }))().format(1 - alpha);
      return translations.transparentColorName(lightness, chroma, hue, percentTransparent).replace(/\s+/g, " ").trim();
    }
    return translations.colorName(lightness, chroma, hue).replace(/\s+/g, " ").trim();
  }
  getOklchHue(l, c, h, translations) {
    if (c < GRAY_THRESHOLD) {
      return [translations.gray, l];
    }
    for (let i = 0; i < OKLCH_HUES.length; i++) {
      let [hue, hueName] = OKLCH_HUES[i];
      const [nextHue, nextHueName] = OKLCH_HUES[i + 1] || [360, "pink"];
      if (h >= hue && h < nextHue) {
        if (hueName === "orange") {
          if (l < ORANGE_LIGHTNESS_THRESHOLD) {
            hueName = "brown";
          } else {
            l = l - ORANGE_LIGHTNESS_THRESHOLD + MAX_DARK_LIGHTNESS;
          }
        }
        if (h > hue + (nextHue - hue) / 2 && hueName !== nextHueName) {
          hueName = `${hueName} ${nextHueName}`;
        } else if (hueName === "yellow" && l < YELLOW_GREEN_LIGHTNESS_THRESHOLD) {
          hueName = "yellow green";
        }
        const name = translations[hueName];
        return [name, l];
      }
    }
    throw new Error("Unexpected hue");
  }
  getHueName(translations) {
    const [l, c, h] = toOKLCH(this);
    const [name] = this.getOklchHue(l, c, h, translations);
    return name;
  }
};
var RGBColor = class _RGBColor extends Color {
  constructor(red, green, blue, alpha) {
    super();
    this.red = red;
    this.green = green;
    this.blue = blue;
    this.alpha = alpha;
  }
  static parse(value) {
    let colors = [];
    if (/^#[\da-f]+$/i.test(value) && [4, 5, 7, 9].includes(value.length)) {
      const values = (value.length < 6 ? value.replace(/[^#]/gi, "$&$&") : value).slice(1).split("");
      while (values.length > 0) {
        colors.push(Number.parseInt(values.splice(0, 2).join(""), 16));
      }
      colors[3] = colors[3] !== void 0 ? colors[3] / 255 : void 0;
    }
    const match = value.match(/^rgba?\((.*)\)$/);
    if (match?.[1]) {
      colors = match[1].replace(
        /(\d+)%$/u,
        (_substring, numberValue) => (Number(numberValue) / 100).toString()
      ).replaceAll(/,|\//gu, " ").replaceAll(/\s{2,}/gu, " ").split(" ").map((value2) => {
        return Number(value2.trim());
      });
      colors = colors.map((num, i) => {
        return clamp(num ?? 0, 0, i < 3 ? 255 : 1);
      });
    }
    if (colors[0] === void 0 || colors[1] === void 0 || colors[2] === void 0) {
      return void 0;
    }
    return colors.length < 3 ? void 0 : new _RGBColor(colors[0], colors[1], colors[2], colors[3] ?? 1);
  }
  toString(format = "css") {
    switch (format) {
      case "hex":
        return `#${(this.red.toString(16).padStart(2, "0") + this.green.toString(16).padStart(2, "0") + this.blue.toString(16).padStart(2, "0")).toUpperCase()}`;
      case "hexa":
        return `#${(this.red.toString(16).padStart(2, "0") + this.green.toString(16).padStart(2, "0") + this.blue.toString(16).padStart(2, "0") + Math.round(this.alpha * 255).toString(16).padStart(2, "0")).toUpperCase()}`;
      case "css":
      case "rgb":
        return `rgb(${this.red}, ${this.green}, ${this.blue}${this.alpha !== 1 && this.alpha !== 100 ? ` / ${this?.alpha}` : ""})`;
      case "rgba":
        return `rgba(${this.red}, ${this.green}, ${this.blue}, ${this.alpha})`;
      default:
        return this.toFormat(format).toString(format);
    }
  }
  toFormat(format) {
    switch (format) {
      case "hex":
      case "hexa":
      case "rgb":
      case "rgba":
        return this;
      case "hsb":
      case "hsba":
        return this.toHSB();
      case "hsl":
      case "hsla":
        return this.toHSL();
      default:
        throw new Error(`Unsupported color conversion: rgb -> ${format}`);
    }
  }
  toHexInt() {
    return this.red << 16 | this.green << 8 | this.blue;
  }
  /**
   * Converts an RGB color value to HSB.
   * Conversion formula adapted from https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB.
   * @returns An HSBColor object.
   */
  toHSB() {
    const red = this.red / 255;
    const green = this.green / 255;
    const blue = this.blue / 255;
    const min = Math.min(red, green, blue);
    const brightness = Math.max(red, green, blue);
    const chroma = brightness - min;
    const saturation = brightness === 0 ? 0 : chroma / brightness;
    let hue = 0;
    if (chroma !== 0) {
      switch (brightness) {
        case red:
          hue = (green - blue) / chroma + (green < blue ? 6 : 0);
          break;
        case green:
          hue = (blue - red) / chroma + 2;
          break;
        case blue:
          hue = (red - green) / chroma + 4;
          break;
      }
      hue /= 6;
    }
    return new HSBColor(
      toFixedNumber(hue * 360, 2),
      toFixedNumber(saturation * 100, 2),
      toFixedNumber(brightness * 100, 2),
      this.alpha
    );
  }
  /**
   * Converts an RGB color value to HSL.
   * Conversion formula adapted from https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB.
   * @returns An HSLColor object.
   */
  toHSL() {
    const red = this.red / 255;
    const green = this.green / 255;
    const blue = this.blue / 255;
    const min = Math.min(red, green, blue);
    const max = Math.max(red, green, blue);
    const lightness = (max + min) / 2;
    const chroma = max - min;
    let hue;
    let saturation;
    if (chroma === 0) {
      hue = saturation = 0;
    } else {
      saturation = chroma / (lightness < 0.5 ? max + min : 2 - max - min);
      switch (max) {
        case red:
          hue = (green - blue) / chroma + (green < blue ? 6 : 0);
          break;
        case green:
          hue = (blue - red) / chroma + 2;
          break;
        default:
          hue = (red - green) / chroma + 4;
          break;
      }
      hue /= 6;
    }
    return new HSLColor(
      toFixedNumber(hue * 360, 2),
      toFixedNumber(saturation * 100, 2),
      toFixedNumber(lightness * 100, 2),
      this.alpha
    );
  }
  clone() {
    return new _RGBColor(this.red, this.green, this.blue, this.alpha);
  }
  getChannelRange(channel) {
    switch (channel) {
      case "red":
      case "green":
      case "blue":
        return { minValue: 0, maxValue: 255, step: 1, pageSize: 17 };
      case "alpha":
        return { minValue: 0, maxValue: 1, step: 0.01, pageSize: 0.1 };
      default:
        throw new Error(`Unknown color channel: ${channel}`);
    }
  }
  getChannelFormatOptions(channel) {
    switch (channel) {
      case "red":
      case "green":
      case "blue":
        return { style: "decimal" };
      case "alpha":
        return { style: "percent", maximumFractionDigits: 2 };
      default:
        throw new Error(`Unknown color channel: ${channel}`);
    }
  }
  formatChannelValue(channel) {
    const options = this.getChannelFormatOptions(channel);
    const value = this.getChannelValue(channel);
    return createNumberFormatter(() => options)().format(value);
  }
  getColorSpace() {
    return "rgb";
  }
  static colorChannels = [
    "red",
    "green",
    "blue"
  ];
  getColorChannels() {
    return _RGBColor.colorChannels;
  }
};
var HSB_REGEX = /hsb\(([-+]?\d+(?:.\d+)?\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d+(?:.\d+)?%)\)|hsba\(([-+]?\d+(?:.\d+)?\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d(.\d+)?)\)/;
var HSBColor = class _HSBColor extends Color {
  constructor(hue, saturation, brightness, alpha) {
    super();
    this.hue = hue;
    this.saturation = saturation;
    this.brightness = brightness;
    this.alpha = alpha;
  }
  static parse(value) {
    let m;
    if (m = value.match(HSB_REGEX)) {
      const [h, s, b, a] = (m[1] ?? m[2]).split(",").map((n) => Number(n.trim().replace("%", "")));
      return new _HSBColor(
        normalizeHue(h),
        clamp(s, 0, 100),
        clamp(b, 0, 100),
        clamp(a ?? 1, 0, 1)
      );
    }
  }
  toString(format = "css") {
    switch (format) {
      case "css":
        return this.toHSL().toString("css");
      case "hex":
        return this.toRGB().toString("hex");
      case "hexa":
        return this.toRGB().toString("hexa");
      case "hsb":
        return `hsb(${this.hue} ${toFixedNumber(this.saturation, 2)}% ${toFixedNumber(this.brightness, 2)}%)`;
      case "hsba":
        return `hsba(${this.hue} ${toFixedNumber(this.saturation, 2)}% ${toFixedNumber(this.brightness, 2)}% ${this.alpha})`;
      default:
        return this.toFormat(format).toString(format);
    }
  }
  toFormat(format) {
    switch (format) {
      case "hsb":
      case "hsba":
        return this;
      case "hsl":
      case "hsla":
        return this.toHSL();
      case "rgb":
      case "rgba":
        return this.toRGB();
      default:
        throw new Error(`Unsupported color conversion: hsb -> ${format}`);
    }
  }
  /**
   * Converts a HSB color to HSL.
   * Conversion formula adapted from https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_HSL.
   * @returns An HSLColor object.
   */
  toHSL() {
    let saturation = this.saturation / 100;
    const brightness = this.brightness / 100;
    const lightness = brightness * (1 - saturation / 2);
    saturation = lightness === 0 || lightness === 1 ? 0 : (brightness - lightness) / Math.min(lightness, 1 - lightness);
    return new HSLColor(
      toFixedNumber(this.hue, 2),
      toFixedNumber(saturation * 100, 2),
      toFixedNumber(lightness * 100, 2),
      this.alpha
    );
  }
  /**
   * Converts a HSV color value to RGB.
   * Conversion formula adapted from https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB_alternative.
   * @returns An RGBColor object.
   */
  toRGB() {
    const hue = this.hue;
    const saturation = this.saturation / 100;
    const brightness = this.brightness / 100;
    const fn = (n, k = (n + hue / 60) % 6) => brightness - saturation * brightness * Math.max(Math.min(k, 4 - k, 1), 0);
    return new RGBColor(
      Math.round(fn(5) * 255),
      Math.round(fn(3) * 255),
      Math.round(fn(1) * 255),
      this.alpha
    );
  }
  clone() {
    return new _HSBColor(this.hue, this.saturation, this.brightness, this.alpha);
  }
  getChannelRange(channel) {
    switch (channel) {
      case "hue":
        return { minValue: 0, maxValue: 360, step: 1, pageSize: 15 };
      case "saturation":
      case "brightness":
        return { minValue: 0, maxValue: 100, step: 1, pageSize: 10 };
      case "alpha":
        return { minValue: 0, maxValue: 1, step: 0.01, pageSize: 0.1 };
      default:
        throw new Error(`Unknown color channel: ${channel}`);
    }
  }
  getChannelFormatOptions(channel) {
    switch (channel) {
      case "hue":
        return { style: "unit", unit: "degree", unitDisplay: "narrow" };
      case "saturation":
      case "brightness":
      case "alpha":
        return { style: "percent", maximumFractionDigits: 2 };
      default:
        throw new Error(`Unknown color channel: ${channel}`);
    }
  }
  formatChannelValue(channel) {
    const options = this.getChannelFormatOptions(channel);
    let value = this.getChannelValue(channel);
    if (channel === "saturation" || channel === "brightness") {
      value /= 100;
    }
    return createNumberFormatter(() => options)().format(value);
  }
  getColorSpace() {
    return "hsb";
  }
  static colorChannels = [
    "hue",
    "saturation",
    "brightness"
  ];
  getColorChannels() {
    return _HSBColor.colorChannels;
  }
};
var HSL_REGEX = /hsl\(([-+]?\d+(?:.\d+)?\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d+(?:.\d+)?%)\)|hsla\(([-+]?\d+(?:.\d+)?\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d(.\d+)?)\)/;
var HSLColor = class _HSLColor extends Color {
  constructor(hue, saturation, lightness, alpha) {
    super();
    this.hue = hue;
    this.saturation = saturation;
    this.lightness = lightness;
    this.alpha = alpha;
  }
  static parse(value) {
    let m;
    if (m = value.match(HSL_REGEX)) {
      const [h, s, l, a] = (m[1] ?? m[2]).split(",").map((n) => Number(n.trim().replace("%", "")));
      return new _HSLColor(
        normalizeHue(h),
        clamp(s, 0, 100),
        clamp(l, 0, 100),
        clamp(a ?? 1, 0, 1)
      );
    }
  }
  toString(format = "css") {
    switch (format) {
      case "hex":
        return this.toRGB().toString("hex");
      case "hexa":
        return this.toRGB().toString("hexa");
      case "hsl":
        return `hsl(${this.hue} ${toFixedNumber(this.saturation, 2)}% ${toFixedNumber(this.lightness, 2)}%${this.alpha !== 1 && this.alpha !== 100 ? ` / ${this.alpha}` : ""})`;
      case "css":
      case "hsla":
        return `hsla(${this.hue} ${toFixedNumber(this.saturation, 2)}% ${toFixedNumber(this.lightness, 2)}% / ${this.alpha})`;
      default:
        return this.toFormat(format).toString(format);
    }
  }
  toFormat(format) {
    switch (format) {
      case "hsl":
      case "hsla":
        return this;
      case "hsb":
      case "hsba":
        return this.toHSB();
      case "rgb":
      case "rgba":
        return this.toRGB();
      default:
        throw new Error(`Unsupported color conversion: hsl -> ${format}`);
    }
  }
  /**
   * Converts a HSL color to HSB.
   * Conversion formula adapted from https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_HSV.
   * @returns An HSBColor object.
   */
  toHSB() {
    let saturation = this.saturation / 100;
    const lightness = this.lightness / 100;
    const brightness = lightness + saturation * Math.min(lightness, 1 - lightness);
    saturation = brightness === 0 ? 0 : 2 * (1 - lightness / brightness);
    return new HSBColor(
      toFixedNumber(this.hue, 2),
      toFixedNumber(saturation * 100, 2),
      toFixedNumber(brightness * 100, 2),
      this.alpha
    );
  }
  /**
   * Converts a HSL color to RGB.
   * Conversion formula adapted from https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB_alternative.
   * @returns An RGBColor object.
   */
  toRGB() {
    const hue = this.hue;
    const saturation = this.saturation / 100;
    const lightness = this.lightness / 100;
    const a = saturation * Math.min(lightness, 1 - lightness);
    const fn = (n, k = (n + hue / 30) % 12) => lightness - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
    return new RGBColor(
      Math.round(fn(0) * 255),
      Math.round(fn(8) * 255),
      Math.round(fn(4) * 255),
      this.alpha
    );
  }
  clone() {
    return new _HSLColor(this.hue, this.saturation, this.lightness, this.alpha);
  }
  getChannelRange(channel) {
    switch (channel) {
      case "hue":
        return { minValue: 0, maxValue: 360, step: 1, pageSize: 15 };
      case "saturation":
      case "lightness":
        return { minValue: 0, maxValue: 100, step: 1, pageSize: 10 };
      case "alpha":
        return { minValue: 0, maxValue: 1, step: 0.01, pageSize: 0.1 };
      default:
        throw new Error(`Unknown color channel: ${channel}`);
    }
  }
  getChannelFormatOptions(channel) {
    switch (channel) {
      case "hue":
        return { style: "unit", unit: "degree", unitDisplay: "narrow" };
      case "saturation":
      case "lightness":
      case "alpha":
        return { style: "percent", maximumFractionDigits: 2 };
      default:
        throw new Error(`Unknown color channel: ${channel}`);
    }
  }
  formatChannelValue(channel) {
    const options = this.getChannelFormatOptions(channel);
    let value = this.getChannelValue(channel);
    if (channel === "saturation" || channel === "lightness") {
      value /= 100;
    }
    return createNumberFormatter(() => options)().format(value);
  }
  getColorSpace() {
    return "hsl";
  }
  static colorChannels = [
    "hue",
    "saturation",
    "lightness"
  ];
  getColorChannels() {
    return _HSLColor.colorChannels;
  }
};
function toOKLCH(color) {
  const rgb = color.toFormat("rgb");
  let red = rgb.getChannelValue("red") / 255;
  let green = rgb.getChannelValue("green") / 255;
  let blue = rgb.getChannelValue("blue") / 255;
  [red, green, blue] = lin_sRGB(red, green, blue);
  const [x, y, z] = lin_sRGB_to_XYZ(red, green, blue);
  const [l, a, b] = XYZ_to_OKLab(x, y, z);
  return OKLab_to_OKLCH(l, a, b);
}
function OKLab_to_OKLCH(l, a, b) {
  const hue = Math.atan2(b, a) * 180 / Math.PI;
  return [
    l,
    Math.sqrt(a ** 2 + b ** 2),
    // Chroma
    hue >= 0 ? hue : hue + 360
    // Hue, in degrees [0 to 360)
  ];
}
function lin_sRGB(r, g, b) {
  return [lin_sRGB_component(r), lin_sRGB_component(g), lin_sRGB_component(b)];
}
function lin_sRGB_component(val) {
  const sign = val < 0 ? -1 : 1;
  const abs = Math.abs(val);
  if (abs <= 0.04045) {
    return val / 12.92;
  }
  return sign * ((abs + 0.055) / 1.055) ** 2.4;
}
function lin_sRGB_to_XYZ(r, g, b) {
  const M = [
    506752 / 1228815,
    87881 / 245763,
    12673 / 70218,
    87098 / 409605,
    175762 / 245763,
    12673 / 175545,
    7918 / 409605,
    87881 / 737289,
    1001167 / 1053270
  ];
  return multiplyMatrix(M, r, g, b);
}
function XYZ_to_OKLab(x, y, z) {
  const XYZtoLMS = [
    0.819022437996703,
    0.3619062600528904,
    -0.1288737815209879,
    0.0329836539323885,
    0.9292868615863434,
    0.0361446663506424,
    0.0481771893596242,
    0.2642395317527308,
    0.6335478284694309
  ];
  const LMStoOKLab = [
    0.210454268309314,
    0.7936177747023054,
    -0.0040720430116193,
    1.9779985324311684,
    -2.42859224204858,
    0.450593709617411,
    0.0259040424655478,
    0.7827717124575296,
    -0.8086757549230774
  ];
  const [a, b, c] = multiplyMatrix(XYZtoLMS, x, y, z);
  return multiplyMatrix(LMStoOKLab, Math.cbrt(a), Math.cbrt(b), Math.cbrt(c));
}
function multiplyMatrix(m, x, y, z) {
  const a = m[0] * x + m[1] * y + m[2] * z;
  const b = m[3] * x + m[4] * y + m[5] * z;
  const c = m[6] * x + m[7] * y + m[8] * z;
  return [a, b, c];
}
function toFixedNumber(value, digits, base = 10) {
  const pow = base ** digits;
  return Math.round(value * pow) / pow;
}

export {
  COLOR_INTL_TRANSLATIONS,
  parseColor,
  normalizeColor,
  getColorChannels,
  normalizeHue
};
