"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const common = require("./common.cjs");
const util = require("./util.cjs");
const constant = require("./constant.cjs");
const VAL_MIX = "mixValue";
const PPTH = 1e-3;
const HALF = 0.5;
const DUO = 2;
const TRIA = 3;
const QUAT = 4;
const OCT = 8;
const DEC = 10;
const DOZ = 12;
const HEX = 16;
const SEXA = 60;
const DEG = 360;
const MAX_PCT = 100;
const MAX_RGB = 255;
const POW_SQR = 2;
const POW_CUBE = 3;
const POW_LINEAR = 2.4;
const LINEAR_COEF = 12.92;
const LINEAR_OFFSET = 0.055;
const LAB_L = 116;
const LAB_A = 500;
const LAB_B = 200;
const LAB_EPSILON = 216 / 24389;
const LAB_KAPPA = 24389 / 27;
const D50 = [0.3457 / 0.3585, 1, (1 - 0.3457 - 0.3585) / 0.3585];
const MATRIX_D50_TO_D65 = [
  [0.955473421488075, -0.02309845494876471, 0.06325924320057072],
  [-0.0283697093338637, 1.0099953980813041, 0.021041441191917323],
  [0.012314014864481998, -0.020507649298898964, 1.330365926242124]
];
const MATRIX_D65_TO_D50 = [
  [1.0479297925449969, 0.022946870601609652, -0.05019226628920524],
  [0.02962780877005599, 0.9904344267538799, -0.017073799063418826],
  [-0.009243040646204504, 0.015055191490298152, 0.7518742814281371]
];
const MATRIX_L_RGB_TO_XYZ = [
  [506752 / 1228815, 87881 / 245763, 12673 / 70218],
  [87098 / 409605, 175762 / 245763, 12673 / 175545],
  [7918 / 409605, 87881 / 737289, 1001167 / 1053270]
];
const MATRIX_XYZ_TO_L_RGB = [
  [12831 / 3959, -329 / 214, -1974 / 3959],
  [-851781 / 878810, 1648619 / 878810, 36519 / 878810],
  [705 / 12673, -2585 / 12673, 705 / 667]
];
const MATRIX_XYZ_TO_LMS = [
  [0.819022437996703, 0.3619062600528904, -0.1288737815209879],
  [0.0329836539323885, 0.9292868615863434, 0.0361446663506424],
  [0.0481771893596242, 0.2642395317527308, 0.6335478284694309]
];
const MATRIX_LMS_TO_XYZ = [
  [1.2268798758459243, -0.5578149944602171, 0.2813910456659647],
  [-0.0405757452148008, 1.112286803280317, -0.0717110580655164],
  [-0.0763729366746601, -0.4214933324022432, 1.5869240198367816]
];
const MATRIX_OKLAB_TO_LMS = [
  [1, 0.3963377773761749, 0.2158037573099136],
  [1, -0.1055613458156586, -0.0638541728258133],
  [1, -0.0894841775298119, -1.2914855480194092]
];
const MATRIX_LMS_TO_OKLAB = [
  [0.210454268309314, 0.7936177747023054, -0.0040720430116193],
  [1.9779985324311684, -2.42859224204858, 0.450593709617411],
  [0.0259040424655478, 0.7827717124575296, -0.8086757549230774]
];
const MATRIX_P3_TO_XYZ = [
  [608311 / 1250200, 189793 / 714400, 198249 / 1000160],
  [35783 / 156275, 247089 / 357200, 198249 / 2500400],
  [0 / 1, 32229 / 714400, 5220557 / 5000800]
];
const MATRIX_REC2020_TO_XYZ = [
  [63426534 / 99577255, 20160776 / 139408157, 47086771 / 278816314],
  [26158966 / 99577255, 472592308 / 697040785, 8267143 / 139408157],
  [0 / 1, 19567812 / 697040785, 295819943 / 278816314]
];
const MATRIX_A98_TO_XYZ = [
  [573536 / 994567, 263643 / 1420810, 187206 / 994567],
  [591459 / 1989134, 6239551 / 9945670, 374412 / 4972835],
  [53769 / 1989134, 351524 / 4972835, 4929758 / 4972835]
];
const MATRIX_PROPHOTO_TO_XYZ_D50 = [
  [0.7977666449006423, 0.13518129740053308, 0.0313477341283922],
  [0.2880748288194013, 0.711835234241873, 8993693872564e-17],
  [0, 0, 0.8251046025104602]
];
const REG_COLOR = new RegExp(`^(?:${constant.SYN_COLOR_TYPE})$`);
const REG_CS_HUE = new RegExp(`^${constant.CS_HUE_CAPT}$`);
const REG_CS_XYZ = /^xyz(?:-d(?:50|65))?$/;
const REG_CURRENT = /^currentColor$/i;
const REG_FN_COLOR = new RegExp(`^color\\(\\s*(${constant.SYN_FN_COLOR})\\s*\\)$`);
const REG_HSL = new RegExp(`^hsla?\\(\\s*(${constant.SYN_HSL}|${constant.SYN_HSL_LV3})\\s*\\)$`);
const REG_HWB = new RegExp(`^hwb\\(\\s*(${constant.SYN_HSL})\\s*\\)$`);
const REG_LAB = new RegExp(`^lab\\(\\s*(${constant.SYN_MOD})\\s*\\)$`);
const REG_LCH = new RegExp(`^lch\\(\\s*(${constant.SYN_LCH})\\s*\\)$`);
const REG_MIX = new RegExp(`^${constant.SYN_MIX}$`);
const REG_MIX_CAPT = new RegExp(`^${constant.SYN_MIX_CAPT}$`);
const REG_MIX_NEST = new RegExp(`${constant.SYN_MIX}`, "g");
const REG_OKLAB = new RegExp(`^oklab\\(\\s*(${constant.SYN_MOD})\\s*\\)$`);
const REG_OKLCH = new RegExp(`^oklch\\(\\s*(${constant.SYN_LCH})\\s*\\)$`);
const REG_SPEC = /^(?:specifi|comput)edValue$/;
const NAMED_COLORS = {
  aliceblue: [240, 248, 255],
  antiquewhite: [250, 235, 215],
  aqua: [0, 255, 255],
  aquamarine: [127, 255, 212],
  azure: [240, 255, 255],
  beige: [245, 245, 220],
  bisque: [255, 228, 196],
  black: [0, 0, 0],
  blanchedalmond: [255, 235, 205],
  blue: [0, 0, 255],
  blueviolet: [138, 43, 226],
  brown: [165, 42, 42],
  burlywood: [222, 184, 135],
  cadetblue: [95, 158, 160],
  chartreuse: [127, 255, 0],
  chocolate: [210, 105, 30],
  coral: [255, 127, 80],
  cornflowerblue: [100, 149, 237],
  cornsilk: [255, 248, 220],
  crimson: [220, 20, 60],
  cyan: [0, 255, 255],
  darkblue: [0, 0, 139],
  darkcyan: [0, 139, 139],
  darkgoldenrod: [184, 134, 11],
  darkgray: [169, 169, 169],
  darkgreen: [0, 100, 0],
  darkgrey: [169, 169, 169],
  darkkhaki: [189, 183, 107],
  darkmagenta: [139, 0, 139],
  darkolivegreen: [85, 107, 47],
  darkorange: [255, 140, 0],
  darkorchid: [153, 50, 204],
  darkred: [139, 0, 0],
  darksalmon: [233, 150, 122],
  darkseagreen: [143, 188, 143],
  darkslateblue: [72, 61, 139],
  darkslategray: [47, 79, 79],
  darkslategrey: [47, 79, 79],
  darkturquoise: [0, 206, 209],
  darkviolet: [148, 0, 211],
  deeppink: [255, 20, 147],
  deepskyblue: [0, 191, 255],
  dimgray: [105, 105, 105],
  dimgrey: [105, 105, 105],
  dodgerblue: [30, 144, 255],
  firebrick: [178, 34, 34],
  floralwhite: [255, 250, 240],
  forestgreen: [34, 139, 34],
  fuchsia: [255, 0, 255],
  gainsboro: [220, 220, 220],
  ghostwhite: [248, 248, 255],
  gold: [255, 215, 0],
  goldenrod: [218, 165, 32],
  gray: [128, 128, 128],
  green: [0, 128, 0],
  greenyellow: [173, 255, 47],
  grey: [128, 128, 128],
  honeydew: [240, 255, 240],
  hotpink: [255, 105, 180],
  indianred: [205, 92, 92],
  indigo: [75, 0, 130],
  ivory: [255, 255, 240],
  khaki: [240, 230, 140],
  lavender: [230, 230, 250],
  lavenderblush: [255, 240, 245],
  lawngreen: [124, 252, 0],
  lemonchiffon: [255, 250, 205],
  lightblue: [173, 216, 230],
  lightcoral: [240, 128, 128],
  lightcyan: [224, 255, 255],
  lightgoldenrodyellow: [250, 250, 210],
  lightgray: [211, 211, 211],
  lightgreen: [144, 238, 144],
  lightgrey: [211, 211, 211],
  lightpink: [255, 182, 193],
  lightsalmon: [255, 160, 122],
  lightseagreen: [32, 178, 170],
  lightskyblue: [135, 206, 250],
  lightslategray: [119, 136, 153],
  lightslategrey: [119, 136, 153],
  lightsteelblue: [176, 196, 222],
  lightyellow: [255, 255, 224],
  lime: [0, 255, 0],
  limegreen: [50, 205, 50],
  linen: [250, 240, 230],
  magenta: [255, 0, 255],
  maroon: [128, 0, 0],
  mediumaquamarine: [102, 205, 170],
  mediumblue: [0, 0, 205],
  mediumorchid: [186, 85, 211],
  mediumpurple: [147, 112, 219],
  mediumseagreen: [60, 179, 113],
  mediumslateblue: [123, 104, 238],
  mediumspringgreen: [0, 250, 154],
  mediumturquoise: [72, 209, 204],
  mediumvioletred: [199, 21, 133],
  midnightblue: [25, 25, 112],
  mintcream: [245, 255, 250],
  mistyrose: [255, 228, 225],
  moccasin: [255, 228, 181],
  navajowhite: [255, 222, 173],
  navy: [0, 0, 128],
  oldlace: [253, 245, 230],
  olive: [128, 128, 0],
  olivedrab: [107, 142, 35],
  orange: [255, 165, 0],
  orangered: [255, 69, 0],
  orchid: [218, 112, 214],
  palegoldenrod: [238, 232, 170],
  palegreen: [152, 251, 152],
  paleturquoise: [175, 238, 238],
  palevioletred: [219, 112, 147],
  papayawhip: [255, 239, 213],
  peachpuff: [255, 218, 185],
  peru: [205, 133, 63],
  pink: [255, 192, 203],
  plum: [221, 160, 221],
  powderblue: [176, 224, 230],
  purple: [128, 0, 128],
  rebeccapurple: [102, 51, 153],
  red: [255, 0, 0],
  rosybrown: [188, 143, 143],
  royalblue: [65, 105, 225],
  saddlebrown: [139, 69, 19],
  salmon: [250, 128, 114],
  sandybrown: [244, 164, 96],
  seagreen: [46, 139, 87],
  seashell: [255, 245, 238],
  sienna: [160, 82, 45],
  silver: [192, 192, 192],
  skyblue: [135, 206, 235],
  slateblue: [106, 90, 205],
  slategray: [112, 128, 144],
  slategrey: [112, 128, 144],
  snow: [255, 250, 250],
  springgreen: [0, 255, 127],
  steelblue: [70, 130, 180],
  tan: [210, 180, 140],
  teal: [0, 128, 128],
  thistle: [216, 191, 216],
  tomato: [255, 99, 71],
  turquoise: [64, 224, 208],
  violet: [238, 130, 238],
  wheat: [245, 222, 179],
  white: [255, 255, 255],
  whitesmoke: [245, 245, 245],
  yellow: [255, 255, 0],
  yellowgreen: [154, 205, 50]
};
const validateColorComponents = (arr, opt = {}) => {
  if (!Array.isArray(arr)) {
    throw new TypeError(`${arr} is not an array.`);
  }
  const {
    alpha = false,
    minLength = TRIA,
    maxLength = QUAT,
    minRange = 0,
    maxRange = 1,
    validateRange = true
  } = opt;
  if (!Number.isFinite(minLength)) {
    throw new TypeError(`${minLength} is not a number.`);
  }
  if (!Number.isFinite(maxLength)) {
    throw new TypeError(`${maxLength} is not a number.`);
  }
  if (!Number.isFinite(minRange)) {
    throw new TypeError(`${minRange} is not a number.`);
  }
  if (!Number.isFinite(maxRange)) {
    throw new TypeError(`${maxRange} is not a number.`);
  }
  const l = arr.length;
  if (l < minLength || l > maxLength) {
    throw new Error(`Unexpected array length ${l}.`);
  }
  let i = 0;
  while (i < l) {
    const v = arr[i];
    if (!Number.isFinite(v)) {
      throw new TypeError(`${v} is not a number.`);
    } else if (i < TRIA && validateRange && (v < minRange || v > maxRange)) {
      throw new RangeError(`${v} is not between ${minRange} and ${maxRange}.`);
    } else if (i === TRIA && (v < 0 || v > 1)) {
      throw new RangeError(`${v} is not between 0 and 1.`);
    }
    i++;
  }
  if (alpha && l === TRIA) {
    arr.push(1);
  }
  return arr;
};
const transformMatrix = (mtx, vct, skip = false) => {
  if (!Array.isArray(mtx)) {
    throw new TypeError(`${mtx} is not an array.`);
  } else if (mtx.length !== TRIA) {
    throw new Error(`Unexpected array length ${mtx.length}.`);
  } else if (!skip) {
    for (let i of mtx) {
      i = validateColorComponents(i, {
        maxLength: TRIA,
        validateRange: false
      });
    }
  }
  const [[r1c1, r1c2, r1c3], [r2c1, r2c2, r2c3], [r3c1, r3c2, r3c3]] = mtx;
  let v1, v2, v3;
  if (skip) {
    [v1, v2, v3] = vct;
  } else {
    [v1, v2, v3] = validateColorComponents(vct, {
      maxLength: TRIA,
      validateRange: false
    });
  }
  const p1 = r1c1 * v1 + r1c2 * v2 + r1c3 * v3;
  const p2 = r2c1 * v1 + r2c2 * v2 + r2c3 * v3;
  const p3 = r3c1 * v1 + r3c2 * v2 + r3c3 * v3;
  return [p1, p2, p3];
};
const normalizeColorComponents = (colorA, colorB, skip = false) => {
  if (!Array.isArray(colorA)) {
    throw new TypeError(`${colorA} is not an array.`);
  } else if (colorA.length !== QUAT) {
    throw new Error(`Unexpected array length ${colorA.length}.`);
  }
  if (!Array.isArray(colorB)) {
    throw new TypeError(`${colorB} is not an array.`);
  } else if (colorB.length !== QUAT) {
    throw new Error(`Unexpected array length ${colorB.length}.`);
  }
  let i = 0;
  while (i < QUAT) {
    if (colorA[i] === constant.NONE && colorB[i] === constant.NONE) {
      colorA[i] = 0;
      colorB[i] = 0;
    } else if (colorA[i] === constant.NONE) {
      colorA[i] = colorB[i];
    } else if (colorB[i] === constant.NONE) {
      colorB[i] = colorA[i];
    }
    i++;
  }
  if (!skip) {
    colorA = validateColorComponents(colorA, {
      minLength: QUAT,
      validateRange: false
    });
    colorB = validateColorComponents(colorB, {
      minLength: QUAT,
      validateRange: false
    });
  }
  return [colorA, colorB];
};
const numberToHexString = (value) => {
  if (!Number.isFinite(value)) {
    throw new TypeError(`${value} is not a number.`);
  } else {
    value = Math.round(value);
    if (value < 0 || value > MAX_RGB) {
      throw new RangeError(`${value} is not between 0 and ${MAX_RGB}.`);
    }
  }
  let hex = value.toString(HEX);
  if (hex.length === 1) {
    hex = `0${hex}`;
  }
  return hex;
};
const angleToDeg = (angle) => {
  if (common.isString(angle)) {
    angle = angle.trim();
  } else {
    throw new TypeError(`${angle} is not a string.`);
  }
  const GRAD = DEG / 400;
  const RAD = DEG / (Math.PI * DUO);
  const reg = new RegExp(`^(${constant.NUM})(${constant.ANGLE})?$`);
  if (!reg.test(angle)) {
    throw new SyntaxError(`Invalid property value: ${angle}`);
  }
  const [, val, unit] = angle.match(reg);
  const value = val[0] === "." ? `0${val}` : val;
  let deg;
  switch (unit) {
    case "grad":
      deg = parseFloat(value) * GRAD;
      break;
    case "rad":
      deg = parseFloat(value) * RAD;
      break;
    case "turn":
      deg = parseFloat(value) * DEG;
      break;
    default:
      deg = parseFloat(value);
  }
  deg %= DEG;
  if (deg < 0) {
    deg += DEG;
  } else if (Object.is(deg, -0)) {
    deg = 0;
  }
  return deg;
};
const parseAlpha = (_alpha) => {
  let alpha = _alpha;
  if (common.isString(alpha)) {
    alpha = alpha.trim();
    if (!alpha) {
      alpha = 1;
    } else if (alpha === constant.NONE) {
      alpha = 0;
    } else {
      if (alpha[0] === ".") {
        alpha = `0${alpha}`;
      }
      if (alpha.endsWith("%")) {
        alpha = parseFloat(alpha) / MAX_PCT;
      } else {
        alpha = parseFloat(alpha);
      }
      if (!Number.isFinite(alpha)) {
        throw new TypeError(`${alpha} is not a number.`);
      }
      if (alpha < PPTH) {
        alpha = 0;
      } else if (alpha > 1) {
        alpha = 1;
      } else {
        alpha = parseFloat(alpha.toFixed(3));
      }
    }
  } else {
    alpha = 1;
  }
  return alpha;
};
const parseHexAlpha = (value) => {
  if (common.isString(value)) {
    if (value === "") {
      throw new SyntaxError("Invalid property value: (empty string)");
    }
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  let alpha = parseInt(value, HEX);
  if (alpha <= 0) {
    return 0;
  }
  if (alpha >= MAX_RGB) {
    return 1;
  }
  const alphaMap = /* @__PURE__ */ new Map();
  for (let i = 1; i < MAX_PCT; i++) {
    alphaMap.set(Math.round(i * MAX_RGB / MAX_PCT), i);
  }
  if (alphaMap.has(alpha)) {
    alpha = alphaMap.get(alpha) / MAX_PCT;
  } else {
    alpha = Math.round(alpha / MAX_RGB / PPTH) * PPTH;
  }
  return parseFloat(alpha.toFixed(3));
};
const convertRgbToLinearRgb = (rgb, skip = false) => {
  let rr, gg, bb;
  if (skip) {
    [rr, gg, bb] = rgb;
  } else {
    [rr, gg, bb] = validateColorComponents(rgb, {
      maxLength: TRIA,
      maxRange: MAX_RGB
    });
  }
  let r = rr / MAX_RGB;
  let g = gg / MAX_RGB;
  let b = bb / MAX_RGB;
  const COND_POW = 0.04045;
  if (r > COND_POW) {
    r = Math.pow((r + LINEAR_OFFSET) / (1 + LINEAR_OFFSET), POW_LINEAR);
  } else {
    r /= LINEAR_COEF;
  }
  if (g > COND_POW) {
    g = Math.pow((g + LINEAR_OFFSET) / (1 + LINEAR_OFFSET), POW_LINEAR);
  } else {
    g /= LINEAR_COEF;
  }
  if (b > COND_POW) {
    b = Math.pow((b + LINEAR_OFFSET) / (1 + LINEAR_OFFSET), POW_LINEAR);
  } else {
    b /= LINEAR_COEF;
  }
  return [r, g, b];
};
const convertRgbToXyz = (rgb, skip = false) => {
  let r, g, b, alpha;
  if (skip) {
    [r, g, b, alpha] = rgb;
  } else {
    [r, g, b, alpha] = validateColorComponents(rgb, {
      alpha: true,
      maxRange: MAX_RGB
    });
  }
  const [rr, gg, bb] = convertRgbToLinearRgb([r, g, b], true);
  const [x, y, z] = transformMatrix(MATRIX_L_RGB_TO_XYZ, [rr, gg, bb], true);
  return [x, y, z, alpha];
};
const convertRgbToHex = (rgb) => {
  const [r, g, b, alpha] = validateColorComponents(rgb, {
    alpha: true,
    maxRange: MAX_RGB
  });
  const rr = numberToHexString(r);
  const gg = numberToHexString(g);
  const bb = numberToHexString(b);
  const aa = numberToHexString(alpha * MAX_RGB);
  let hex;
  if (aa === "ff") {
    hex = `#${rr}${gg}${bb}`;
  } else {
    hex = `#${rr}${gg}${bb}${aa}`;
  }
  return hex;
};
const convertLinearRgbToRgb = (rgb, round = false) => {
  let [r, g, b] = validateColorComponents(rgb, {
    maxLength: TRIA
  });
  const COND_POW = 809 / 258400;
  if (r > COND_POW) {
    r = Math.pow(r, 1 / POW_LINEAR) * (1 + LINEAR_OFFSET) - LINEAR_OFFSET;
  } else {
    r *= LINEAR_COEF;
  }
  r *= MAX_RGB;
  if (g > COND_POW) {
    g = Math.pow(g, 1 / POW_LINEAR) * (1 + LINEAR_OFFSET) - LINEAR_OFFSET;
  } else {
    g *= LINEAR_COEF;
  }
  g *= MAX_RGB;
  if (b > COND_POW) {
    b = Math.pow(b, 1 / POW_LINEAR) * (1 + LINEAR_OFFSET) - LINEAR_OFFSET;
  } else {
    b *= LINEAR_COEF;
  }
  b *= MAX_RGB;
  return [
    round ? Math.round(r) : r,
    round ? Math.round(g) : g,
    round ? Math.round(b) : b
  ];
};
const convertXyzToRgb = (xyz, skip = false) => {
  let x, y, z, alpha;
  if (skip) {
    [x, y, z, alpha] = xyz;
  } else {
    [x, y, z, alpha] = validateColorComponents(xyz, {
      validateRange: false
    });
  }
  let [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, [x, y, z], true);
  [r, g, b] = convertLinearRgbToRgb(
    [
      Math.min(Math.max(r, 0), 1),
      Math.min(Math.max(g, 0), 1),
      Math.min(Math.max(b, 0), 1)
    ],
    true
  );
  return [r, g, b, alpha];
};
const convertXyzToHsl = (xyz, skip = false) => {
  const [rr, gg, bb, alpha] = convertXyzToRgb(xyz, skip);
  const r = rr / MAX_RGB;
  const g = gg / MAX_RGB;
  const b = bb / MAX_RGB;
  const max = Math.max(r, g, b);
  const min = Math.min(r, g, b);
  const d = max - min;
  const l = (max + min) * HALF * MAX_PCT;
  let h, s;
  if (Math.round(l) === 0 || Math.round(l) === MAX_PCT) {
    h = constant.NONE;
    s = constant.NONE;
  } else {
    s = d / (1 - Math.abs(max + min - 1)) * MAX_PCT;
    if (s === 0) {
      h = constant.NONE;
    } else {
      switch (max) {
        case r:
          h = (g - b) / d;
          break;
        case g:
          h = (b - r) / d + DUO;
          break;
        case b:
        default:
          h = (r - g) / d + QUAT;
          break;
      }
      h = h * SEXA % DEG;
      if (h < 0) {
        h += DEG;
      }
    }
  }
  return [h, s, l, alpha];
};
const convertXyzToHwb = (xyz, skip = false) => {
  const [r, g, b, alpha] = convertXyzToRgb(xyz, skip);
  const w = Math.min(r, g, b) / MAX_RGB;
  const bk = 1 - Math.max(r, g, b) / MAX_RGB;
  let h;
  if (w + bk === 1) {
    h = constant.NONE;
  } else {
    [h] = convertXyzToHsl(xyz);
  }
  return [h, w * MAX_PCT, bk * MAX_PCT, alpha];
};
const convertXyzToOklab = (xyz, skip = false) => {
  let x, y, z, alpha;
  if (skip) {
    [x, y, z, alpha] = xyz;
  } else {
    [x, y, z, alpha] = validateColorComponents(xyz, {
      validateRange: false
    });
  }
  const lms = transformMatrix(MATRIX_XYZ_TO_LMS, [x, y, z], true);
  const xyzLms = lms.map((c) => Math.cbrt(c));
  let [l, a, b] = transformMatrix(MATRIX_LMS_TO_OKLAB, xyzLms, true);
  l = Math.min(Math.max(l, 0), 1);
  const lPct = Math.round(parseFloat(l.toFixed(QUAT)) * MAX_PCT);
  if (lPct === 0 || lPct === MAX_PCT) {
    a = constant.NONE;
    b = constant.NONE;
  }
  return [l, a, b, alpha];
};
const convertXyzToOklch = (xyz, skip = false) => {
  const [l, a, b, aa] = convertXyzToOklab(xyz, skip);
  let c, h;
  const lPct = Math.round(parseFloat(l.toFixed(QUAT)) * MAX_PCT);
  if (lPct === 0 || lPct === MAX_PCT) {
    c = constant.NONE;
    h = constant.NONE;
  } else {
    c = Math.max(Math.sqrt(Math.pow(a, POW_SQR) + Math.pow(b, POW_SQR)), 0);
    if (parseFloat(c.toFixed(QUAT)) === 0) {
      h = constant.NONE;
    } else {
      h = Math.atan2(b, a) * DEG * HALF / Math.PI;
      if (h < 0) {
        h += DEG;
      }
    }
  }
  return [l, c, h, aa];
};
const convertXyzD50ToRgb = (xyz, skip = false) => {
  let x, y, z, alpha;
  if (skip) {
    [x, y, z, alpha] = xyz;
  } else {
    [x, y, z, alpha] = validateColorComponents(xyz, {
      minLength: QUAT,
      validateRange: false
    });
  }
  const xyzD65 = transformMatrix(MATRIX_D50_TO_D65, [x, y, z], true);
  const [r, g, b] = convertXyzToRgb(xyzD65, true);
  return [r, g, b, alpha];
};
const convertXyzD50ToLab = (xyz, skip = false) => {
  let x, y, z, alpha;
  if (skip) {
    [x, y, z, alpha] = xyz;
  } else {
    [x, y, z, alpha] = validateColorComponents(xyz, {
      validateRange: false
    });
  }
  const xyzD50 = [x, y, z].map((val, i) => val / D50[i]);
  const [f0, f1, f2] = xyzD50.map(
    (val) => val > LAB_EPSILON ? Math.cbrt(val) : (val * LAB_KAPPA + HEX) / LAB_L
  );
  const l = Math.min(Math.max(LAB_L * f1 - HEX, 0), MAX_PCT);
  let a, b;
  if (l === 0 || l === MAX_PCT) {
    a = constant.NONE;
    b = constant.NONE;
  } else {
    a = (f0 - f1) * LAB_A;
    b = (f1 - f2) * LAB_B;
  }
  return [l, a, b, alpha];
};
const convertXyzD50ToLch = (xyz, skip = false) => {
  const [l, a, b, alpha] = convertXyzD50ToLab(xyz, skip);
  let c, h;
  if (l === 0 || l === MAX_PCT) {
    c = constant.NONE;
    h = constant.NONE;
  } else {
    c = Math.max(Math.sqrt(Math.pow(a, POW_SQR) + Math.pow(b, POW_SQR)), 0);
    h = Math.atan2(b, a) * DEG * HALF / Math.PI;
    if (h < 0) {
      h += DEG;
    }
  }
  return [l, c, h, alpha];
};
const convertHexToRgb = (value) => {
  if (common.isString(value)) {
    value = value.toLowerCase().trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  if (!(/^#[\da-f]{6}$/.test(value) || /^#[\da-f]{3}$/.test(value) || /^#[\da-f]{8}$/.test(value) || /^#[\da-f]{4}$/.test(value))) {
    throw new SyntaxError(`Invalid property value: ${value}`);
  }
  const arr = [];
  if (/^#[\da-f]{6}$/.test(value)) {
    const [, r, g, b] = value.match(
      /^#([\da-f]{2})([\da-f]{2})([\da-f]{2})$/
    );
    arr.push(parseInt(r, HEX), parseInt(g, HEX), parseInt(b, HEX), 1);
  } else if (/^#[\da-f]{3}$/.test(value)) {
    const [, r, g, b] = value.match(/^#([\da-f])([\da-f])([\da-f])$/);
    arr.push(
      parseInt(`${r}${r}`, HEX),
      parseInt(`${g}${g}`, HEX),
      parseInt(`${b}${b}`, HEX),
      1
    );
  } else if (/^#[\da-f]{8}$/.test(value)) {
    const [, r, g, b, alpha] = value.match(
      /^#([\da-f]{2})([\da-f]{2})([\da-f]{2})([\da-f]{2})$/
    );
    arr.push(
      parseInt(r, HEX),
      parseInt(g, HEX),
      parseInt(b, HEX),
      parseHexAlpha(alpha)
    );
  } else if (/^#[\da-f]{4}$/.test(value)) {
    const [, r, g, b, alpha] = value.match(
      /^#([\da-f])([\da-f])([\da-f])([\da-f])$/
    );
    arr.push(
      parseInt(`${r}${r}`, HEX),
      parseInt(`${g}${g}`, HEX),
      parseInt(`${b}${b}`, HEX),
      parseHexAlpha(`${alpha}${alpha}`)
    );
  }
  return arr;
};
const convertHexToLinearRgb = (value) => {
  const [rr, gg, bb, alpha] = convertHexToRgb(value);
  const [r, g, b] = convertRgbToLinearRgb([rr, gg, bb], true);
  return [r, g, b, alpha];
};
const convertHexToXyz = (value) => {
  const [r, g, b, alpha] = convertHexToLinearRgb(value);
  const [x, y, z] = transformMatrix(MATRIX_L_RGB_TO_XYZ, [r, g, b], true);
  return [x, y, z, alpha];
};
const parseRgb = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.toLowerCase().trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { format } = opt;
  const reg = new RegExp(`^rgba?\\(\\s*(${constant.SYN_MOD}|${constant.SYN_RGB_LV3})\\s*\\)$`);
  if (!reg.test(value)) {
    switch (format) {
      case VAL_MIX: {
        return null;
      }
      case constant.VAL_SPEC: {
        return "";
      }
      default: {
        return ["rgb", 0, 0, 0, 0];
      }
    }
  }
  const [, val] = value.match(reg);
  let [v1, v2, v3, v4] = val.replace(/[,/]/g, " ").split(/\s+/);
  let r, g, b;
  if (v1 === constant.NONE) {
    r = 0;
  } else {
    if (v1[0] === ".") {
      v1 = `0${v1}`;
    }
    if (v1.endsWith("%")) {
      r = parseFloat(v1) * MAX_RGB / MAX_PCT;
    } else {
      r = parseFloat(v1);
    }
    r = Math.min(Math.max(util.roundToPrecision(r, OCT), 0), MAX_RGB);
  }
  if (v2 === constant.NONE) {
    g = 0;
  } else {
    if (v2[0] === ".") {
      v2 = `0${v2}`;
    }
    if (v2.endsWith("%")) {
      g = parseFloat(v2) * MAX_RGB / MAX_PCT;
    } else {
      g = parseFloat(v2);
    }
    g = Math.min(Math.max(util.roundToPrecision(g, OCT), 0), MAX_RGB);
  }
  if (v3 === constant.NONE) {
    b = 0;
  } else {
    if (v3[0] === ".") {
      v3 = `0${v3}`;
    }
    if (v3.endsWith("%")) {
      b = parseFloat(v3) * MAX_RGB / MAX_PCT;
    } else {
      b = parseFloat(v3);
    }
    b = Math.min(Math.max(util.roundToPrecision(b, OCT), 0), MAX_RGB);
  }
  const alpha = parseAlpha(v4);
  return ["rgb", r, g, b, format === VAL_MIX && v4 === constant.NONE ? constant.NONE : alpha];
};
const parseHsl = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { format } = opt;
  if (!REG_HSL.test(value)) {
    switch (format) {
      case "hsl":
      case VAL_MIX: {
        return null;
      }
      case constant.VAL_SPEC: {
        return "";
      }
      default: {
        return ["rgb", 0, 0, 0, 0];
      }
    }
  }
  const [, val] = value.match(REG_HSL);
  let [h, s, l, alpha] = val.replace(/[,/]/g, " ").split(/\s+/);
  if (h === constant.NONE) {
    if (format !== "hsl") {
      h = 0;
    }
  } else {
    h = angleToDeg(h);
  }
  if (s === constant.NONE) {
    if (format !== "hsl") {
      s = 0;
    }
  } else {
    if (s[0] === ".") {
      s = `0${s}`;
    }
    s = Math.min(Math.max(parseFloat(s), 0), MAX_PCT);
  }
  if (l === constant.NONE) {
    if (format !== "hsl") {
      l = 0;
    }
  } else {
    if (l[0] === ".") {
      l = `0${l}`;
    }
    l = Math.min(Math.max(parseFloat(l), 0), MAX_PCT);
  }
  if (alpha !== constant.NONE || format !== "hsl") {
    alpha = parseAlpha(alpha);
  }
  if (format === "hsl") {
    return [format, h, s, l, alpha];
  }
  const ll = l / MAX_PCT;
  const sa = s / MAX_PCT * Math.min(ll, 1 - ll);
  const rk = h / DEG * DOZ % DOZ;
  const gk = (8 + h / DEG * DOZ) % DOZ;
  const bk = (4 + h / DEG * DOZ) % DOZ;
  const r = ll - sa * Math.max(-1, Math.min(rk - TRIA, TRIA ** POW_SQR - rk, 1));
  const g = ll - sa * Math.max(-1, Math.min(gk - TRIA, TRIA ** POW_SQR - gk, 1));
  const b = ll - sa * Math.max(-1, Math.min(bk - TRIA, TRIA ** POW_SQR - bk, 1));
  return [
    "rgb",
    Math.min(Math.max(util.roundToPrecision(r * MAX_RGB, OCT), 0), MAX_RGB),
    Math.min(Math.max(util.roundToPrecision(g * MAX_RGB, OCT), 0), MAX_RGB),
    Math.min(Math.max(util.roundToPrecision(b * MAX_RGB, OCT), 0), MAX_RGB),
    alpha
  ];
};
const parseHwb = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { format } = opt;
  if (!REG_HWB.test(value)) {
    switch (format) {
      case "hwb":
      case VAL_MIX: {
        return null;
      }
      case constant.VAL_SPEC: {
        return "";
      }
      default: {
        return ["rgb", 0, 0, 0, 0];
      }
    }
  }
  const [, val] = value.match(REG_HWB);
  let [h, w, b, alpha] = val.replace("/", " ").split(/\s+/);
  if (h === constant.NONE) {
    if (format !== "hwb") {
      h = 0;
    }
  } else {
    h = angleToDeg(h);
  }
  if (w === constant.NONE) {
    if (format !== "hwb") {
      w = 0;
    }
  } else {
    if (w[0] === ".") {
      w = `0${w}`;
    }
    w = Math.min(Math.max(parseFloat(w), 0), MAX_PCT) / MAX_PCT;
  }
  if (b === constant.NONE) {
    if (format !== "hwb") {
      b = 0;
    }
  } else {
    if (b[0] === ".") {
      b = `0${b}`;
    }
    b = Math.min(Math.max(parseFloat(b), 0), MAX_PCT) / MAX_PCT;
  }
  if (alpha !== constant.NONE || format !== "hwb") {
    alpha = parseAlpha(alpha);
  }
  if (format === "hwb") {
    return [
      format,
      h,
      w === constant.NONE ? w : w * MAX_PCT,
      b === constant.NONE ? b : b * MAX_PCT,
      alpha
    ];
  }
  if (w + b >= 1) {
    const v = util.roundToPrecision(
      w / (w + b) * MAX_RGB,
      OCT
    );
    return ["rgb", v, v, v, alpha];
  }
  const factor = (1 - w - b) / MAX_RGB;
  let [, rr, gg, bb] = parseHsl(`hsl(${h} 100 50)`);
  rr = util.roundToPrecision(
    (rr * factor + w) * MAX_RGB,
    OCT
  );
  gg = util.roundToPrecision(
    (gg * factor + w) * MAX_RGB,
    OCT
  );
  bb = util.roundToPrecision(
    (bb * factor + w) * MAX_RGB,
    OCT
  );
  return [
    "rgb",
    Math.min(Math.max(rr, 0), MAX_RGB),
    Math.min(Math.max(gg, 0), MAX_RGB),
    Math.min(Math.max(bb, 0), MAX_RGB),
    alpha
  ];
};
const parseLab = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { format } = opt;
  if (!REG_LAB.test(value)) {
    switch (format) {
      case VAL_MIX: {
        return null;
      }
      case constant.VAL_SPEC: {
        return "";
      }
      default: {
        return ["rgb", 0, 0, 0, 0];
      }
    }
  }
  const COEF_PCT = 1.25;
  const COND_POW = 8;
  const [, val] = value.match(REG_LAB);
  let [l, a, b, alpha] = val.replace("/", " ").split(/\s+/);
  if (l === constant.NONE) {
    if (!REG_SPEC.test(format)) {
      l = 0;
    }
  } else {
    if (l[0] === ".") {
      l = `0${l}`;
    }
    if (l.endsWith("%")) {
      l = parseFloat(l);
      if (l > MAX_PCT) {
        l = MAX_PCT;
      }
    } else {
      l = parseFloat(l);
    }
    if (l < 0) {
      l = 0;
    }
  }
  if (a === constant.NONE) {
    if (!REG_SPEC.test(format)) {
      a = 0;
    }
  } else {
    if (a[0] === ".") {
      a = `0${a}`;
    }
    if (a.endsWith("%")) {
      a = parseFloat(a) * COEF_PCT;
    } else {
      a = parseFloat(a);
    }
  }
  if (b === constant.NONE) {
    if (!REG_SPEC.test(format)) {
      b = 0;
    }
  } else {
    if (b.endsWith("%")) {
      b = parseFloat(b) * COEF_PCT;
    } else {
      b = parseFloat(b);
    }
  }
  if (alpha !== constant.NONE || !REG_SPEC.test(format)) {
    alpha = parseAlpha(alpha);
  }
  if (REG_SPEC.test(format)) {
    return [
      "lab",
      l === constant.NONE ? l : util.roundToPrecision(l, HEX),
      a === constant.NONE ? a : util.roundToPrecision(a, HEX),
      b === constant.NONE ? b : util.roundToPrecision(b, HEX),
      alpha
    ];
  }
  const fl = (l + HEX) / LAB_L;
  const fa = a / LAB_A + fl;
  const fb = fl - b / LAB_B;
  const powFl = Math.pow(fl, POW_CUBE);
  const powFa = Math.pow(fa, POW_CUBE);
  const powFb = Math.pow(fb, POW_CUBE);
  const xyz = [
    powFa > LAB_EPSILON ? powFa : (fa * LAB_L - HEX) / LAB_KAPPA,
    l > COND_POW ? powFl : l / LAB_KAPPA,
    powFb > LAB_EPSILON ? powFb : (fb * LAB_L - HEX) / LAB_KAPPA
  ];
  const [x, y, z] = xyz.map((val2, i) => val2 * D50[i]);
  return [
    "xyz-d50",
    util.roundToPrecision(x, HEX),
    util.roundToPrecision(y, HEX),
    util.roundToPrecision(z, HEX),
    alpha
  ];
};
const parseLch = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { format } = opt;
  if (!REG_LCH.test(value)) {
    switch (format) {
      case VAL_MIX: {
        return null;
      }
      case constant.VAL_SPEC: {
        return "";
      }
      default: {
        return ["rgb", 0, 0, 0, 0];
      }
    }
  }
  const COEF_PCT = 1.5;
  const [, val] = value.match(REG_LCH);
  let [l, c, h, alpha] = val.replace("/", " ").split(/\s+/);
  if (l === constant.NONE) {
    if (!REG_SPEC.test(format)) {
      l = 0;
    }
  } else {
    if (l[0] === ".") {
      l = `0${l}`;
    }
    l = parseFloat(l);
    if (l < 0) {
      l = 0;
    }
  }
  if (c === constant.NONE) {
    if (!REG_SPEC.test(format)) {
      c = 0;
    }
  } else {
    if (c[0] === ".") {
      c = `0${c}`;
    }
    if (c.endsWith("%")) {
      c = parseFloat(c) * COEF_PCT;
    } else {
      c = parseFloat(c);
    }
  }
  if (h === constant.NONE) {
    if (!REG_SPEC.test(format)) {
      h = 0;
    }
  } else {
    h = angleToDeg(h);
  }
  if (alpha !== constant.NONE || !REG_SPEC.test(format)) {
    alpha = parseAlpha(alpha);
  }
  if (REG_SPEC.test(format)) {
    return [
      "lch",
      l === constant.NONE ? l : util.roundToPrecision(l, HEX),
      c === constant.NONE ? c : util.roundToPrecision(c, HEX),
      h === constant.NONE ? h : util.roundToPrecision(h, HEX),
      alpha
    ];
  }
  const a = c * Math.cos(h * Math.PI / (DEG * HALF));
  const b = c * Math.sin(h * Math.PI / (DEG * HALF));
  const [, x, y, z] = parseLab(`lab(${l} ${a} ${b})`);
  return [
    "xyz-d50",
    util.roundToPrecision(x, HEX),
    util.roundToPrecision(y, HEX),
    util.roundToPrecision(z, HEX),
    alpha
  ];
};
const parseOklab = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { format } = opt;
  if (!REG_OKLAB.test(value)) {
    switch (format) {
      case VAL_MIX: {
        return null;
      }
      case constant.VAL_SPEC: {
        return "";
      }
      default: {
        return ["rgb", 0, 0, 0, 0];
      }
    }
  }
  const COEF_PCT = 0.4;
  const [, val] = value.match(REG_OKLAB);
  let [l, a, b, alpha] = val.replace("/", " ").split(/\s+/);
  if (l === constant.NONE) {
    if (!REG_SPEC.test(format)) {
      l = 0;
    }
  } else {
    if (l[0] === ".") {
      l = `0${l}`;
    }
    if (l.endsWith("%")) {
      l = parseFloat(l) / MAX_PCT;
    } else {
      l = parseFloat(l);
    }
    if (l < 0) {
      l = 0;
    }
  }
  if (a === constant.NONE) {
    if (!REG_SPEC.test(format)) {
      a = 0;
    }
  } else {
    if (a[0] === ".") {
      a = `0${a}`;
    }
    if (a.endsWith("%")) {
      a = parseFloat(a) * COEF_PCT / MAX_PCT;
    } else {
      a = parseFloat(a);
    }
  }
  if (b === constant.NONE) {
    if (!REG_SPEC.test(format)) {
      b = 0;
    }
  } else {
    if (b.endsWith("%")) {
      b = parseFloat(b) * COEF_PCT / MAX_PCT;
    } else {
      b = parseFloat(b);
    }
  }
  if (alpha !== constant.NONE || !REG_SPEC.test(format)) {
    alpha = parseAlpha(alpha);
  }
  if (REG_SPEC.test(format)) {
    return [
      "oklab",
      l === constant.NONE ? l : util.roundToPrecision(l, HEX),
      a === constant.NONE ? a : util.roundToPrecision(a, HEX),
      b === constant.NONE ? b : util.roundToPrecision(b, HEX),
      alpha
    ];
  }
  const lms = transformMatrix(MATRIX_OKLAB_TO_LMS, [
    l,
    a,
    b
  ]);
  const xyzLms = lms.map((c) => Math.pow(c, POW_CUBE));
  const [x, y, z] = transformMatrix(MATRIX_LMS_TO_XYZ, xyzLms, true);
  return [
    "xyz-d65",
    util.roundToPrecision(x, HEX),
    util.roundToPrecision(y, HEX),
    util.roundToPrecision(z, HEX),
    alpha
  ];
};
const parseOklch = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { format } = opt;
  if (!REG_OKLCH.test(value)) {
    switch (format) {
      case VAL_MIX: {
        return null;
      }
      case constant.VAL_SPEC: {
        return "";
      }
      default: {
        return ["rgb", 0, 0, 0, 0];
      }
    }
  }
  const COEF_PCT = 0.4;
  const [, val] = value.match(REG_OKLCH);
  let [l, c, h, alpha] = val.replace("/", " ").split(/\s+/);
  if (l === constant.NONE) {
    if (!REG_SPEC.test(format)) {
      l = 0;
    }
  } else {
    if (l[0] === ".") {
      l = `0${l}`;
    }
    if (l.endsWith("%")) {
      l = parseFloat(l) / MAX_PCT;
    } else {
      l = parseFloat(l);
    }
    if (l < 0) {
      l = 0;
    }
  }
  if (c === constant.NONE) {
    if (!REG_SPEC.test(format)) {
      c = 0;
    }
  } else {
    if (c[0] === ".") {
      c = `0${c}`;
    }
    if (c.endsWith("%")) {
      c = parseFloat(c) * COEF_PCT / MAX_PCT;
    } else {
      c = parseFloat(c);
    }
    if (c < 0) {
      c = 0;
    }
  }
  if (h === constant.NONE) {
    if (!REG_SPEC.test(format)) {
      h = 0;
    }
  } else {
    h = angleToDeg(h);
  }
  if (alpha !== constant.NONE || !REG_SPEC.test(format)) {
    alpha = parseAlpha(alpha);
  }
  if (REG_SPEC.test(format)) {
    return [
      "oklch",
      l === constant.NONE ? l : util.roundToPrecision(l, HEX),
      c === constant.NONE ? c : util.roundToPrecision(c, HEX),
      h === constant.NONE ? h : util.roundToPrecision(h, HEX),
      alpha
    ];
  }
  const a = c * Math.cos(h * Math.PI / (DEG * HALF));
  const b = c * Math.sin(h * Math.PI / (DEG * HALF));
  const lms = transformMatrix(MATRIX_OKLAB_TO_LMS, [l, a, b]);
  const xyzLms = lms.map((cl) => Math.pow(cl, POW_CUBE));
  const [x, y, z] = transformMatrix(MATRIX_LMS_TO_XYZ, xyzLms, true);
  return [
    "xyz-d65",
    util.roundToPrecision(x, HEX),
    util.roundToPrecision(y, HEX),
    util.roundToPrecision(z, HEX),
    alpha
  ];
};
const parseColorFunc = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { colorSpace, d50, format } = opt;
  if (!REG_FN_COLOR.test(value)) {
    switch (format) {
      case VAL_MIX: {
        return null;
      }
      case constant.VAL_SPEC: {
        return "";
      }
      default: {
        return ["rgb", 0, 0, 0, 0];
      }
    }
  }
  const [, val] = value.match(REG_FN_COLOR);
  let [cs, v1, v2, v3, v4] = val.replace("/", " ").split(/\s+/);
  let r, g, b;
  if (cs === "xyz") {
    cs = "xyz-d65";
  }
  if (v1 === constant.NONE) {
    r = 0;
  } else {
    if (v1[0] === ".") {
      v1 = `0${v1}`;
    }
    r = v1.endsWith("%") ? parseFloat(v1) / MAX_PCT : parseFloat(v1);
  }
  if (v2 === constant.NONE) {
    g = 0;
  } else {
    if (v2[0] === ".") {
      v2 = `0${v2}`;
    }
    g = v2.endsWith("%") ? parseFloat(v2) / MAX_PCT : parseFloat(v2);
  }
  if (v3 === constant.NONE) {
    b = 0;
  } else {
    if (v3[0] === ".") {
      v3 = `0${v3}`;
    }
    b = v3.endsWith("%") ? parseFloat(v3) / MAX_PCT : parseFloat(v3);
  }
  const alpha = parseAlpha(v4);
  if (REG_SPEC.test(format) || format === VAL_MIX && cs === colorSpace) {
    return [
      cs,
      v1 === constant.NONE ? constant.NONE : util.roundToPrecision(r, DEC),
      v2 === constant.NONE ? constant.NONE : util.roundToPrecision(g, DEC),
      v3 === constant.NONE ? constant.NONE : util.roundToPrecision(b, DEC),
      v4 === constant.NONE ? constant.NONE : alpha
    ];
  }
  let x, y, z;
  if (cs === "srgb") {
    [x, y, z] = convertRgbToXyz([r * MAX_RGB, g * MAX_RGB, b * MAX_RGB]);
    if (d50) {
      [x, y, z] = transformMatrix(
        MATRIX_D65_TO_D50,
        [x, y, z],
        true
      );
    }
  } else if (cs === "srgb-linear") {
    [x, y, z] = transformMatrix(MATRIX_L_RGB_TO_XYZ, [r, g, b]);
    if (d50) {
      [x, y, z] = transformMatrix(
        MATRIX_D65_TO_D50,
        [x, y, z],
        true
      );
    }
  } else if (cs === "display-p3") {
    const linearRgb = convertRgbToLinearRgb([
      r * MAX_RGB,
      g * MAX_RGB,
      b * MAX_RGB
    ]);
    [x, y, z] = transformMatrix(MATRIX_P3_TO_XYZ, linearRgb);
    if (d50) {
      [x, y, z] = transformMatrix(
        MATRIX_D65_TO_D50,
        [x, y, z],
        true
      );
    }
  } else if (cs === "rec2020") {
    const ALPHA = 1.09929682680944;
    const BETA = 0.018053968510807;
    const REC_COEF = 0.45;
    const rgb = [r, g, b].map((c) => {
      let cl;
      if (c < BETA * REC_COEF * DEC) {
        cl = c / (REC_COEF * DEC);
      } else {
        cl = Math.pow((c + ALPHA - 1) / ALPHA, 1 / REC_COEF);
      }
      return cl;
    });
    [x, y, z] = transformMatrix(MATRIX_REC2020_TO_XYZ, rgb);
    if (d50) {
      [x, y, z] = transformMatrix(
        MATRIX_D65_TO_D50,
        [x, y, z],
        true
      );
    }
  } else if (cs === "a98-rgb") {
    const POW_A98 = 563 / 256;
    const rgb = [r, g, b].map((c) => {
      const cl = Math.pow(c, POW_A98);
      return cl;
    });
    [x, y, z] = transformMatrix(MATRIX_A98_TO_XYZ, rgb);
    if (d50) {
      [x, y, z] = transformMatrix(
        MATRIX_D65_TO_D50,
        [x, y, z],
        true
      );
    }
  } else if (cs === "prophoto-rgb") {
    const POW_PROPHOTO = 1.8;
    const rgb = [r, g, b].map((c) => {
      let cl;
      if (c > 1 / (HEX * DUO)) {
        cl = Math.pow(c, POW_PROPHOTO);
      } else {
        cl = c / HEX;
      }
      return cl;
    });
    [x, y, z] = transformMatrix(MATRIX_PROPHOTO_TO_XYZ_D50, rgb);
    if (!d50) {
      [x, y, z] = transformMatrix(
        MATRIX_D50_TO_D65,
        [x, y, z],
        true
      );
    }
  } else if (/^xyz(?:-d(?:50|65))?$/.test(cs)) {
    [x, y, z] = [r, g, b];
    if (cs === "xyz-d50") {
      if (!d50) {
        [x, y, z] = transformMatrix(MATRIX_D50_TO_D65, [x, y, z]);
      }
    } else if (d50) {
      [x, y, z] = transformMatrix(MATRIX_D65_TO_D50, [x, y, z], true);
    }
  }
  return [
    d50 ? "xyz-d50" : "xyz-d65",
    util.roundToPrecision(x, HEX),
    util.roundToPrecision(y, HEX),
    util.roundToPrecision(z, HEX),
    format === VAL_MIX && v4 === constant.NONE ? constant.NONE : alpha
  ];
};
const parseColorValue = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.toLowerCase().trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { d50, format } = opt;
  if (!REG_COLOR.test(value)) {
    switch (format) {
      case VAL_MIX: {
        return null;
      }
      case constant.VAL_SPEC: {
        return "";
      }
      default: {
        return ["rgb", 0, 0, 0, 0];
      }
    }
  }
  let x, y, z, alpha;
  if (REG_CURRENT.test(value)) {
    if (format === constant.VAL_COMP) {
      return ["rgb", 0, 0, 0, 0];
    }
    if (format === constant.VAL_SPEC) {
      return value;
    }
    x = 0;
    y = 0;
    z = 0;
    alpha = 0;
  } else if (/^[a-z]+$/.test(value)) {
    if (Object.prototype.hasOwnProperty.call(NAMED_COLORS, value)) {
      if (format === constant.VAL_SPEC) {
        return value;
      }
      const [r, g, b] = NAMED_COLORS[value];
      alpha = 1;
      if (format === constant.VAL_COMP) {
        return ["rgb", r, g, b, alpha];
      }
      [x, y, z] = convertRgbToXyz([r, g, b], true);
      if (d50) {
        [x, y, z] = transformMatrix(
          MATRIX_D65_TO_D50,
          [x, y, z],
          true
        );
      }
    } else {
      if (format === constant.VAL_COMP) {
        return ["rgb", 0, 0, 0, 0];
      }
      if (format === constant.VAL_SPEC) {
        if (value === "transparent") {
          return value;
        }
        return "";
      }
      if (format === VAL_MIX) {
        if (value === "transparent") {
          return ["rgb", 0, 0, 0, 0];
        }
        return null;
      }
      x = 0;
      y = 0;
      z = 0;
      alpha = 0;
    }
  } else if (value[0] === "#") {
    if (REG_SPEC.test(format)) {
      const rgb = convertHexToRgb(value);
      return ["rgb", ...rgb];
    }
    [x, y, z, alpha] = convertHexToXyz(value);
    if (d50) {
      [x, y, z] = transformMatrix(
        MATRIX_D65_TO_D50,
        [x, y, z],
        true
      );
    }
  } else if (value.startsWith("lab")) {
    if (REG_SPEC.test(format)) {
      return parseLab(value, opt);
    }
    [, x, y, z, alpha] = parseLab(value);
    if (!d50) {
      [x, y, z] = transformMatrix(
        MATRIX_D50_TO_D65,
        [x, y, z],
        true
      );
    }
  } else if (value.startsWith("lch")) {
    if (REG_SPEC.test(format)) {
      return parseLch(value, opt);
    }
    [, x, y, z, alpha] = parseLch(value);
    if (!d50) {
      [x, y, z] = transformMatrix(
        MATRIX_D50_TO_D65,
        [x, y, z],
        true
      );
    }
  } else if (value.startsWith("oklab")) {
    if (REG_SPEC.test(format)) {
      return parseOklab(value, opt);
    }
    [, x, y, z, alpha] = parseOklab(value);
    if (d50) {
      [x, y, z] = transformMatrix(
        MATRIX_D65_TO_D50,
        [x, y, z],
        true
      );
    }
  } else if (value.startsWith("oklch")) {
    if (REG_SPEC.test(format)) {
      return parseOklch(value, opt);
    }
    [, x, y, z, alpha] = parseOklch(value);
    if (d50) {
      [x, y, z] = transformMatrix(
        MATRIX_D65_TO_D50,
        [x, y, z],
        true
      );
    }
  } else {
    let r, g, b;
    if (value.startsWith("hsl")) {
      [, r, g, b, alpha] = parseHsl(value);
    } else if (value.startsWith("hwb")) {
      [, r, g, b, alpha] = parseHwb(value);
    } else {
      [, r, g, b, alpha] = parseRgb(value, opt);
    }
    if (REG_SPEC.test(format)) {
      return [
        "rgb",
        Math.round(r),
        Math.round(g),
        Math.round(b),
        alpha
      ];
    }
    [x, y, z] = convertRgbToXyz([r, g, b]);
    if (d50) {
      [x, y, z] = transformMatrix(
        MATRIX_D65_TO_D50,
        [x, y, z],
        true
      );
    }
  }
  return [
    d50 ? "xyz-d50" : "xyz-d65",
    util.roundToPrecision(x, HEX),
    util.roundToPrecision(y, HEX),
    util.roundToPrecision(z, HEX),
    alpha
  ];
};
const resolveColorValue = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.toLowerCase().trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { colorSpace, format } = opt;
  if (!REG_COLOR.test(value)) {
    switch (format) {
      case VAL_MIX: {
        return null;
      }
      case constant.VAL_SPEC: {
        return "";
      }
      default: {
        return ["rgb", 0, 0, 0, 0];
      }
    }
  }
  let cs, r, g, b, alpha;
  if (REG_CURRENT.test(value)) {
    if (format === constant.VAL_SPEC) {
      return value;
    }
    r = 0;
    g = 0;
    b = 0;
    alpha = 0;
  } else if (/^[a-z]+$/.test(value)) {
    if (Object.prototype.hasOwnProperty.call(NAMED_COLORS, value)) {
      if (format === constant.VAL_SPEC) {
        return value;
      }
      [r, g, b] = NAMED_COLORS[value];
      alpha = 1;
    } else {
      if (format === constant.VAL_SPEC) {
        if (value === "transparent") {
          return value;
        }
        return "";
      }
      if (format === VAL_MIX) {
        if (value === "transparent") {
          return ["rgb", 0, 0, 0, 0];
        }
        return null;
      }
      r = 0;
      g = 0;
      b = 0;
      alpha = 0;
    }
  } else if (value[0] === "#") {
    [r, g, b, alpha] = convertHexToRgb(value);
  } else if (value.startsWith("rgb")) {
    [, r, g, b, alpha] = parseRgb(value, opt);
  } else if (value.startsWith("hsl")) {
    [, r, g, b, alpha] = parseHsl(value, opt);
  } else if (value.startsWith("hwb")) {
    [, r, g, b, alpha] = parseHwb(value, opt);
  } else if (/^l(?:ab|ch)/.test(value)) {
    let x, y, z;
    if (value.startsWith("lab")) {
      [cs, x, y, z, alpha] = parseLab(value, opt);
    } else {
      [cs, x, y, z, alpha] = parseLch(value, opt);
    }
    if (REG_SPEC.test(format)) {
      return [cs, x, y, z, alpha];
    }
    [r, g, b, alpha] = convertXyzD50ToRgb([
      x,
      y,
      z,
      alpha
    ]);
  } else if (/^okl(?:ab|ch)/.test(value)) {
    let x, y, z;
    if (value.startsWith("oklab")) {
      [cs, x, y, z, alpha] = parseOklab(value, opt);
    } else {
      [cs, x, y, z, alpha] = parseOklch(value, opt);
    }
    if (REG_SPEC.test(format)) {
      return [cs, x, y, z, alpha];
    }
    [r, g, b, alpha] = convertXyzToRgb([
      x,
      y,
      z,
      alpha
    ]);
  }
  if (format === VAL_MIX && colorSpace === "srgb") {
    return [
      "srgb",
      r / MAX_RGB,
      g / MAX_RGB,
      b / MAX_RGB,
      alpha
    ];
  }
  return [
    "rgb",
    Math.round(r),
    Math.round(g),
    Math.round(b),
    alpha
  ];
};
const resolveColorFunc = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.toLowerCase().trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { colorSpace, format } = opt;
  if (!REG_FN_COLOR.test(value)) {
    switch (format) {
      case VAL_MIX: {
        return null;
      }
      case constant.VAL_SPEC: {
        return "";
      }
      default: {
        return ["rgb", 0, 0, 0, 0];
      }
    }
  }
  const [cs, x, y, z, alpha] = parseColorFunc(value, opt);
  if (REG_SPEC.test(format) || format === VAL_MIX && cs === colorSpace) {
    return [cs, x, y, z, alpha];
  }
  const [r, g, b] = convertXyzToRgb([
    x,
    y,
    z
  ], true);
  return ["rgb", r, g, b, alpha];
};
const convertColorToLinearRgb = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { colorSpace, format } = opt;
  let cs, r, g, b, alpha, x, y, z;
  if (format === VAL_MIX) {
    let xyz;
    if (value.startsWith(constant.FN_COLOR)) {
      xyz = parseColorFunc(value, opt);
    } else {
      xyz = parseColorValue(value, opt);
    }
    if (xyz === null) {
      return xyz;
    }
    [cs, x, y, z, alpha] = xyz;
    if (cs === colorSpace) {
      return [x, y, z, alpha];
    }
    [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, [x, y, z], true);
  } else if (value.startsWith(constant.FN_COLOR)) {
    const [, val] = value.match(REG_FN_COLOR);
    const [cs2] = val.replace("/", " ").split(/\s+/);
    if (cs2 === "srgb-linear") {
      [, r, g, b, alpha] = resolveColorFunc(value, {
        format: constant.VAL_COMP
      });
    } else {
      [, x, y, z, alpha] = parseColorFunc(value);
      [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, [x, y, z], true);
    }
  } else {
    [, x, y, z, alpha] = parseColorValue(value);
    [r, g, b] = transformMatrix(MATRIX_XYZ_TO_L_RGB, [x, y, z], true);
  }
  return [
    Math.min(Math.max(r, 0), 1),
    Math.min(Math.max(g, 0), 1),
    Math.min(Math.max(b, 0), 1),
    alpha
  ];
};
const convertColorToRgb = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { format } = opt;
  let r, g, b, alpha;
  if (format === VAL_MIX) {
    let rgb;
    if (value.startsWith(constant.FN_COLOR)) {
      rgb = resolveColorFunc(value, opt);
    } else {
      rgb = resolveColorValue(value, opt);
    }
    if (rgb === null) {
      return rgb;
    }
    [, r, g, b, alpha] = rgb;
  } else if (value.startsWith(constant.FN_COLOR)) {
    const [, val] = value.match(REG_FN_COLOR);
    const [cs] = val.replace("/", " ").split(/\s+/);
    if (cs === "srgb") {
      [, r, g, b, alpha] = resolveColorFunc(value, {
        format: constant.VAL_COMP
      });
      r *= MAX_RGB;
      g *= MAX_RGB;
      b *= MAX_RGB;
    } else {
      [, r, g, b, alpha] = resolveColorFunc(value);
    }
  } else if (/^(?:ok)?l(?:ab|ch)/.test(value)) {
    [r, g, b, alpha] = convertColorToLinearRgb(value);
    [r, g, b] = convertLinearRgbToRgb([r, g, b]);
  } else {
    [, r, g, b, alpha] = resolveColorValue(value, {
      format: constant.VAL_COMP
    });
  }
  return [r, g, b, alpha];
};
const convertColorToXyz = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { d50, format } = opt;
  let x, y, z, alpha;
  if (format === VAL_MIX) {
    let xyz;
    if (value.startsWith(constant.FN_COLOR)) {
      xyz = parseColorFunc(value, opt);
    } else {
      xyz = parseColorValue(value, opt);
    }
    if (xyz === null) {
      return xyz;
    }
    [, x, y, z, alpha] = xyz;
  } else if (value.startsWith(constant.FN_COLOR)) {
    const [, val] = value.match(REG_FN_COLOR);
    const [cs] = val.replace("/", " ").split(/\s+/);
    if (d50) {
      if (cs === "xyz-d50") {
        [, x, y, z, alpha] = resolveColorFunc(value, {
          format: constant.VAL_COMP
        });
      } else {
        [, x, y, z, alpha] = parseColorFunc(value, opt);
      }
    } else if (/^xyz(?:-d65)?$/.test(cs)) {
      [, x, y, z, alpha] = resolveColorFunc(value, {
        format: constant.VAL_COMP
      });
    } else {
      [, x, y, z, alpha] = parseColorFunc(value);
    }
  } else {
    [, x, y, z, alpha] = parseColorValue(value, opt);
  }
  return [x, y, z, alpha];
};
const convertColorToHsl = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { format } = opt;
  let h, s, l, alpha, x, y, z;
  if (REG_HSL.test(value)) {
    [, h, s, l, alpha] = parseHsl(value, {
      format: "hsl"
    });
    if (format === "hsl") {
      return [
        Math.round(h),
        Math.round(s),
        Math.round(l),
        alpha
      ];
    }
    return [h, s, l, alpha];
  }
  if (format === VAL_MIX) {
    let xyz;
    if (value.startsWith(constant.FN_COLOR)) {
      xyz = parseColorFunc(value, opt);
    } else {
      xyz = parseColorValue(value, opt);
    }
    if (xyz === null) {
      return xyz;
    }
    [, x, y, z, alpha] = xyz;
  } else if (value.startsWith(constant.FN_COLOR)) {
    [, x, y, z, alpha] = parseColorFunc(value);
  } else {
    [, x, y, z, alpha] = parseColorValue(value);
  }
  [h, s, l] = convertXyzToHsl([x, y, z], true);
  if (format === "hsl") {
    return [Math.round(h), Math.round(s), Math.round(l), alpha];
  }
  return [h, s, l, alpha];
};
const convertColorToHwb = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { format } = opt;
  let h, w, b, alpha, x, y, z;
  if (REG_HWB.test(value)) {
    [, h, w, b, alpha] = parseHwb(value, {
      format: "hwb"
    });
    if (format === "hwb") {
      return [Math.round(h), Math.round(w), Math.round(b), alpha];
    }
    return [h, w, b, alpha];
  }
  if (format === VAL_MIX) {
    let xyz;
    if (value.startsWith(constant.FN_COLOR)) {
      xyz = parseColorFunc(value, opt);
    } else {
      xyz = parseColorValue(value, opt);
    }
    if (xyz === null) {
      return xyz;
    }
    [, x, y, z, alpha] = xyz;
  } else if (value.startsWith(constant.FN_COLOR)) {
    [, x, y, z, alpha] = parseColorFunc(value);
  } else {
    [, x, y, z, alpha] = parseColorValue(value);
  }
  [h, w, b] = convertXyzToHwb([x, y, z], true);
  if (format === "hwb") {
    return [Math.round(h), Math.round(w), Math.round(b), alpha];
  }
  return [h, w, b, alpha];
};
const convertColorToLab = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { format } = opt;
  let l, a, b, alpha, x, y, z;
  if (REG_LAB.test(value)) {
    [, l, a, b, alpha] = parseLab(value, {
      format: constant.VAL_COMP
    });
    return [l, a, b, alpha];
  }
  if (format === VAL_MIX) {
    let xyz;
    opt.d50 = true;
    if (value.startsWith(constant.FN_COLOR)) {
      xyz = parseColorFunc(value, opt);
    } else {
      xyz = parseColorValue(value, opt);
    }
    if (xyz === null) {
      return xyz;
    }
    [, x, y, z, alpha] = xyz;
  } else if (value.startsWith(constant.FN_COLOR)) {
    [, x, y, z, alpha] = parseColorFunc(value, {
      d50: true
    });
  } else {
    [, x, y, z, alpha] = parseColorValue(value, {
      d50: true
    });
  }
  [l, a, b] = convertXyzD50ToLab([x, y, z], true);
  return [l, a, b, alpha];
};
const convertColorToLch = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { format } = opt;
  let l, c, h, alpha, x, y, z;
  if (REG_LCH.test(value)) {
    [, l, c, h, alpha] = parseLch(value, {
      format: constant.VAL_COMP
    });
    return [l, c, h, alpha];
  }
  if (format === VAL_MIX) {
    let xyz;
    opt.d50 = true;
    if (value.startsWith(constant.FN_COLOR)) {
      xyz = parseColorFunc(value, opt);
    } else {
      xyz = parseColorValue(value, opt);
    }
    if (xyz === null) {
      return xyz;
    }
    [, x, y, z, alpha] = xyz;
  } else if (value.startsWith(constant.FN_COLOR)) {
    [, x, y, z, alpha] = parseColorFunc(value, {
      d50: true
    });
  } else {
    [, x, y, z, alpha] = parseColorValue(value, {
      d50: true
    });
  }
  [l, c, h] = convertXyzD50ToLch([x, y, z], true);
  return [l, c, h, alpha];
};
const convertColorToOklab = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { format } = opt;
  let l, a, b, alpha, x, y, z;
  if (REG_OKLAB.test(value)) {
    [, l, a, b, alpha] = parseOklab(value, {
      format: constant.VAL_COMP
    });
    return [l, a, b, alpha];
  }
  if (format === VAL_MIX) {
    let xyz;
    if (value.startsWith(constant.FN_COLOR)) {
      xyz = parseColorFunc(value, opt);
    } else {
      xyz = parseColorValue(value, opt);
    }
    if (xyz === null) {
      return xyz;
    }
    [, x, y, z, alpha] = xyz;
  } else if (value.startsWith(constant.FN_COLOR)) {
    [, x, y, z, alpha] = parseColorFunc(value);
  } else {
    [, x, y, z, alpha] = parseColorValue(value);
  }
  [l, a, b] = convertXyzToOklab([x, y, z], true);
  return [l, a, b, alpha];
};
const convertColorToOklch = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { format } = opt;
  let l, c, h, alpha, x, y, z;
  if (REG_OKLCH.test(value)) {
    [, l, c, h, alpha] = parseOklch(value, {
      format: constant.VAL_COMP
    });
    return [l, c, h, alpha];
  }
  if (format === VAL_MIX) {
    let xyz;
    if (value.startsWith(constant.FN_COLOR)) {
      xyz = parseColorFunc(value, opt);
    } else {
      xyz = parseColorValue(value, opt);
    }
    if (xyz === null) {
      return xyz;
    }
    [, x, y, z, alpha] = xyz;
  } else if (value.startsWith(constant.FN_COLOR)) {
    [, x, y, z, alpha] = parseColorFunc(value);
  } else {
    [, x, y, z, alpha] = parseColorValue(value);
  }
  [l, c, h] = convertXyzToOklch([x, y, z], true);
  return [l, c, h, alpha];
};
const resolveColorMix = (value, opt = {}) => {
  if (common.isString(value)) {
    value = value.toLowerCase().trim();
  } else {
    throw new TypeError(`${value} is not a string.`);
  }
  const { format } = opt;
  const nestedItems = [];
  if (!REG_MIX.test(value)) {
    if (value.startsWith(constant.FN_MIX) && REG_MIX_NEST.test(value)) {
      const regColorSpace = new RegExp(`^(?:${constant.CS_RGB}|${constant.CS_XYZ})$`);
      const items = value.match(REG_MIX_NEST);
      for (const item of items) {
        let val = resolveColorMix(item, {
          format: format === constant.VAL_SPEC ? format : constant.VAL_COMP
        });
        if (Array.isArray(val)) {
          const [v1, v2, v3, v4, v5] = val;
          if (v2 === 0 && v3 === 0 && v4 === 0 && v5 === 0) {
            value = "";
            break;
          }
          if (regColorSpace.test(v1)) {
            if (v5 === 1) {
              val = `color(${v1} ${v2} ${v3} ${v4})`;
            } else {
              val = `color(${v1} ${v2} ${v3} ${v4} / ${v5})`;
            }
          } else if (v5 === 1) {
            val = `${v1}(${v2} ${v3} ${v4})`;
          } else {
            val = `${v1}(${v2} ${v3} ${v4} / ${v5})`;
          }
        } else if (!REG_MIX.test(val)) {
          value = "";
          break;
        }
        nestedItems.push(val);
        value = value.replace(item, val);
      }
      if (!value) {
        if (format === constant.VAL_SPEC) {
          return "";
        }
        return ["rgb", 0, 0, 0, 0];
      }
    } else if (format === constant.VAL_SPEC) {
      return "";
    } else {
      return ["rgb", 0, 0, 0, 0];
    }
  }
  let colorSpace, hueArc, colorA, pctA, colorB, pctB;
  if (nestedItems.length && format === constant.VAL_SPEC) {
    const regColorSpace = new RegExp(`^color-mix\\(\\s*in\\s+(${constant.CS_MIX})\\s*,`);
    const [, cs] = value.match(regColorSpace);
    if (REG_CS_HUE.test(cs)) {
      [, colorSpace, hueArc] = cs.match(REG_CS_HUE);
    } else {
      colorSpace = cs;
    }
    if (nestedItems.length === 2) {
      const itemA = nestedItems[0].replace(/(?=[()])/g, "\\");
      const regA = new RegExp(`(${itemA})(?:\\s+(${constant.PCT}))?`);
      [, colorA, pctA] = value.match(regA);
      const itemB = nestedItems[1].replace(/(?=[()])/g, "\\");
      const regB = new RegExp(`(${itemB})(?:\\s+(${constant.PCT}))?`);
      [, colorB, pctB] = value.match(regB);
    } else {
      const colorPart = `(?:${constant.SYN_COLOR_TYPE})(?:\\s+${constant.PCT})?`;
      const item = nestedItems[0].replace(/(?=[()])/g, "\\");
      const itemPart = `${item}(?:\\s+${constant.PCT})?`;
      const itemPartCapt = `(${item})(?:\\s+(${constant.PCT}))?`;
      const regColorPart = new RegExp(`^(${constant.SYN_COLOR_TYPE})(?:\\s+(${constant.PCT}))?$`);
      const regItemPart = new RegExp(`^${itemPartCapt}$`);
      const regPosition = new RegExp(`${itemPartCapt}\\s*\\)$`);
      if (regPosition.test(value)) {
        const reg = new RegExp(`(${colorPart})\\s*,\\s*(${itemPart})\\s*\\)$`);
        const [, colorPartA, colorPartB] = value.match(reg);
        [, colorA, pctA] = colorPartA.match(regColorPart);
        [, colorB, pctB] = colorPartB.match(regItemPart);
      } else {
        const reg = new RegExp(`(${itemPart})\\s*,\\s*(${colorPart})\\s*\\)$`);
        const [, colorPartA, colorPartB] = value.match(reg);
        [, colorA, pctA] = colorPartA.match(regItemPart);
        [, colorB, pctB] = colorPartB.match(regColorPart);
      }
    }
  } else {
    const [, cs, colorPartA, colorPartB] = value.match(REG_MIX_CAPT);
    const reg = new RegExp(`^(${constant.SYN_COLOR_TYPE})(?:\\s+(${constant.PCT}))?$`);
    [, colorA, pctA] = colorPartA.match(reg);
    [, colorB, pctB] = colorPartB.match(reg);
    if (REG_CS_HUE.test(cs)) {
      [, colorSpace, hueArc] = REG_CS_HUE.exec(cs);
    } else {
      colorSpace = cs;
    }
  }
  let pA, pB, m;
  if (pctA && pctB) {
    const p1 = parseFloat(pctA) / MAX_PCT;
    const p2 = parseFloat(pctB) / MAX_PCT;
    if (p1 < 0 || p1 > 1 || p2 < 0 || p2 > 1) {
      if (format === constant.VAL_SPEC) {
        return "";
      }
      return ["rgb", 0, 0, 0, 0];
    }
    const factor = p1 + p2;
    if (factor === 0) {
      if (format === constant.VAL_SPEC) {
        return "";
      }
      return ["rgb", 0, 0, 0, 0];
    }
    pA = p1 / factor;
    pB = p2 / factor;
    m = factor < 1 ? factor : 1;
  } else {
    if (pctA) {
      pA = parseFloat(pctA) / MAX_PCT;
      if (pA < 0 || pA > 1) {
        if (format === constant.VAL_SPEC) {
          return "";
        }
        return ["rgb", 0, 0, 0, 0];
      }
      pB = 1 - pA;
    } else if (pctB) {
      pB = parseFloat(pctB) / MAX_PCT;
      if (pB < 0 || pB > 1) {
        if (format === constant.VAL_SPEC) {
          return "";
        }
        return ["rgb", 0, 0, 0, 0];
      }
      pA = 1 - pB;
    } else {
      pA = HALF;
      pB = HALF;
    }
    m = 1;
  }
  if (colorSpace === "xyz") {
    colorSpace = "xyz-d65";
  }
  if (format === constant.VAL_SPEC) {
    let valueA, valueB;
    if (colorA.startsWith(constant.FN_MIX)) {
      valueA = colorA;
    } else if (colorA.startsWith(constant.FN_COLOR)) {
      valueA = parseColorFunc(colorA, opt);
      if (Array.isArray(valueA)) {
        const [v1, v2, v3, v4, v5] = [...valueA];
        if (v5 === 1) {
          valueA = `color(${v1} ${v2} ${v3} ${v4})`;
        } else {
          valueA = `color(${v1} ${v2} ${v3} ${v4} / ${v5})`;
        }
      }
    } else {
      valueA = parseColorValue(colorA, opt);
      if (valueA === "") {
        return valueA;
      }
      if (Array.isArray(valueA)) {
        const [v1, v2, v3, v4, v5] = [...valueA];
        if (v5 === 1) {
          if (v1 === "rgb") {
            valueA = `${v1}(${v2}, ${v3}, ${v4})`;
          } else {
            valueA = `${v1}(${v2} ${v3} ${v4})`;
          }
        } else if (v1 === "rgb") {
          valueA = `${v1}a(${v2}, ${v3}, ${v4}, ${v5})`;
        } else {
          valueA = `${v1}(${v2} ${v3} ${v4} / ${v5})`;
        }
      }
    }
    if (colorB.startsWith(constant.FN_MIX)) {
      valueB = colorB;
    } else if (colorB.startsWith(constant.FN_COLOR)) {
      valueB = parseColorFunc(colorB, opt);
      if (Array.isArray(valueB)) {
        const [v1, v2, v3, v4, v5] = [...valueB];
        if (v5 === 1) {
          valueB = `color(${v1} ${v2} ${v3} ${v4})`;
        } else {
          valueB = `color(${v1} ${v2} ${v3} ${v4} / ${v5})`;
        }
      }
    } else {
      valueB = parseColorValue(colorB, opt);
      if (valueB === "") {
        return valueB;
      }
      if (Array.isArray(valueB)) {
        const [v1, v2, v3, v4, v5] = [...valueB];
        if (v5 === 1) {
          if (v1 === "rgb") {
            valueB = `${v1}(${v2}, ${v3}, ${v4})`;
          } else {
            valueB = `${v1}(${v2} ${v3} ${v4})`;
          }
        } else if (v1 === "rgb") {
          valueB = `${v1}a(${v2}, ${v3}, ${v4}, ${v5})`;
        } else {
          valueB = `${v1}(${v2} ${v3} ${v4} / ${v5})`;
        }
      }
    }
    if (pctA && pctB) {
      valueA += ` ${parseFloat(pctA)}%`;
      valueB += ` ${parseFloat(pctB)}%`;
    } else if (pctA) {
      const pA2 = parseFloat(pctA);
      if (pA2 !== MAX_PCT * HALF) {
        valueA += ` ${pA2}%`;
      }
    } else if (pctB) {
      const pA2 = MAX_PCT - parseFloat(pctB);
      if (pA2 !== MAX_PCT * HALF) {
        valueA += ` ${pA2}%`;
      }
    }
    if (hueArc) {
      return `color-mix(in ${colorSpace} ${hueArc} hue, ${valueA}, ${valueB})`;
    } else {
      return `color-mix(in ${colorSpace}, ${valueA}, ${valueB})`;
    }
  }
  let r, g, b, alpha;
  if (/^srgb(?:-linear)?$/.test(colorSpace)) {
    let rgbA, rgbB;
    if (colorSpace === "srgb") {
      if (REG_CURRENT.test(colorA)) {
        rgbA = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
      } else {
        rgbA = convertColorToRgb(colorA, {
          colorSpace,
          format: VAL_MIX
        });
      }
      if (REG_CURRENT.test(colorB)) {
        rgbB = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
      } else {
        rgbB = convertColorToRgb(colorB, {
          colorSpace,
          format: VAL_MIX
        });
      }
    } else {
      if (REG_CURRENT.test(colorA)) {
        rgbA = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
      } else {
        rgbA = convertColorToLinearRgb(colorA, {
          colorSpace,
          format: VAL_MIX
        });
      }
      if (REG_CURRENT.test(colorB)) {
        rgbB = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
      } else {
        rgbB = convertColorToLinearRgb(colorB, {
          colorSpace,
          format: VAL_MIX
        });
      }
    }
    if (rgbA === null || rgbB === null) {
      return ["rgb", 0, 0, 0, 0];
    }
    let [rA, gA, bA, alphaA] = rgbA;
    let [rB, gB, bB, alphaB] = rgbB;
    const rNone = rA === constant.NONE && rB === constant.NONE;
    const gNone = gA === constant.NONE && gB === constant.NONE;
    const bNone = bA === constant.NONE && bB === constant.NONE;
    const alphaNone = alphaA === constant.NONE && alphaB === constant.NONE;
    [[rA, gA, bA, alphaA], [rB, gB, bB, alphaB]] = normalizeColorComponents(
      [rA, gA, bA, alphaA],
      [rB, gB, bB, alphaB],
      true
    );
    const factorA = alphaA * pA;
    const factorB = alphaB * pB;
    alpha = factorA + factorB;
    if (alpha === 0) {
      r = rA * pA + rB * pB;
      g = gA * pA + gB * pB;
      b = bA * pA + bB * pB;
    } else {
      r = (rA * factorA + rB * factorB) / alpha;
      g = (gA * factorA + gB * factorB) / alpha;
      b = (bA * factorA + bB * factorB) / alpha;
      alpha = parseFloat(alpha.toFixed(3));
    }
    if (format === constant.VAL_COMP) {
      return [
        colorSpace,
        rNone ? constant.NONE : util.roundToPrecision(r, HEX),
        gNone ? constant.NONE : util.roundToPrecision(g, HEX),
        bNone ? constant.NONE : util.roundToPrecision(b, HEX),
        alphaNone ? constant.NONE : alpha * m
      ];
    }
    r *= MAX_RGB;
    g *= MAX_RGB;
    b *= MAX_RGB;
  } else if (REG_CS_XYZ.test(colorSpace)) {
    let xyzA, xyzB;
    if (REG_CURRENT.test(colorA)) {
      xyzA = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
    } else {
      xyzA = convertColorToXyz(colorA, {
        colorSpace,
        d50: colorSpace === "xyz-d50",
        format: VAL_MIX
      });
    }
    if (REG_CURRENT.test(colorB)) {
      xyzB = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
    } else {
      xyzB = convertColorToXyz(colorB, {
        colorSpace,
        d50: colorSpace === "xyz-d50",
        format: VAL_MIX
      });
    }
    if (xyzA === null || xyzB === null) {
      return ["rgb", 0, 0, 0, 0];
    }
    let [xA, yA, zA, alphaA] = xyzA;
    let [xB, yB, zB, alphaB] = xyzB;
    const xNone = xA === constant.NONE && xB === constant.NONE;
    const yNone = yA === constant.NONE && yB === constant.NONE;
    const zNone = zA === constant.NONE && zB === constant.NONE;
    const alphaNone = alphaA === constant.NONE && alphaB === constant.NONE;
    [[xA, yA, zA, alphaA], [xB, yB, zB, alphaB]] = normalizeColorComponents(
      [xA, yA, zA, alphaA],
      [xB, yB, zB, alphaB],
      true
    );
    const factorA = alphaA * pA;
    const factorB = alphaB * pB;
    alpha = factorA + factorB;
    let x, y, z;
    if (alpha === 0) {
      x = xA * pA + xB * pB;
      y = yA * pA + yB * pB;
      z = zA * pA + zB * pB;
    } else {
      x = (xA * factorA + xB * factorB) / alpha;
      y = (yA * factorA + yB * factorB) / alpha;
      z = (zA * factorA + zB * factorB) / alpha;
      alpha = parseFloat(alpha.toFixed(3));
    }
    if (format === constant.VAL_COMP) {
      return [
        colorSpace,
        xNone ? constant.NONE : util.roundToPrecision(x, HEX),
        yNone ? constant.NONE : util.roundToPrecision(y, HEX),
        zNone ? constant.NONE : util.roundToPrecision(z, HEX),
        alphaNone ? constant.NONE : alpha * m
      ];
    }
    if (colorSpace === "xyz-d50") {
      [r, g, b] = convertXyzD50ToRgb([x, y, z], true);
    } else {
      [r, g, b] = convertXyzToRgb([x, y, z], true);
    }
  } else if (/^h(?:sl|wb)$/.test(colorSpace)) {
    let hslA, hslB;
    if (colorSpace === "hsl") {
      if (REG_CURRENT.test(colorA)) {
        hslA = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
      } else {
        hslA = convertColorToHsl(colorA, {
          colorSpace,
          format: VAL_MIX
        });
      }
      if (REG_CURRENT.test(colorB)) {
        hslB = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
      } else {
        hslB = convertColorToHsl(colorB, {
          colorSpace,
          format: VAL_MIX
        });
      }
    } else {
      if (REG_CURRENT.test(colorA)) {
        hslA = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
      } else {
        hslA = convertColorToHwb(colorA, {
          colorSpace,
          format: VAL_MIX
        });
      }
      if (REG_CURRENT.test(colorB)) {
        hslB = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
      } else {
        hslB = convertColorToHwb(colorB, {
          colorSpace,
          format: VAL_MIX
        });
      }
    }
    if (hslA === null || hslB === null) {
      return ["rgb", 0, 0, 0, 0];
    }
    let [hA, sA, lA, alphaA] = hslA;
    let [hB, sB, lB, alphaB] = hslB;
    const alphaNone = alphaA === constant.NONE && alphaB === constant.NONE;
    [[hA, sA, lA, alphaA], [hB, sB, lB, alphaB]] = normalizeColorComponents(
      [hA, sA, lA, alphaA],
      [hB, sB, lB, alphaB],
      true
    );
    if (hueArc) {
      [hA, hB] = util.interpolateHue(hA, hB, hueArc);
    }
    const factorA = alphaA * pA;
    const factorB = alphaB * pB;
    alpha = factorA + factorB;
    const h = (hA * pA + hB * pB) % DEG;
    let s, l;
    if (alpha === 0) {
      s = sA * pA + sB * pB;
      l = lA * pA + lB * pB;
    } else {
      s = (sA * factorA + sB * factorB) / alpha;
      l = (lA * factorA + lB * factorB) / alpha;
      alpha = parseFloat(alpha.toFixed(3));
    }
    [r, g, b] = convertColorToRgb(`${colorSpace}(${h} ${s} ${l})`);
    if (format === constant.VAL_COMP) {
      return [
        "srgb",
        util.roundToPrecision(r / MAX_RGB, HEX),
        util.roundToPrecision(g / MAX_RGB, HEX),
        util.roundToPrecision(b / MAX_RGB, HEX),
        alphaNone ? constant.NONE : alpha * m
      ];
    }
  } else if (/^(?:ok)?lab$/.test(colorSpace)) {
    let labA, labB;
    if (colorSpace === "lab") {
      if (REG_CURRENT.test(colorA)) {
        labA = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
      } else {
        labA = convertColorToLab(colorA, {
          colorSpace,
          format: VAL_MIX
        });
      }
      if (REG_CURRENT.test(colorB)) {
        labB = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
      } else {
        labB = convertColorToLab(colorB, {
          colorSpace,
          format: VAL_MIX
        });
      }
    } else {
      if (REG_CURRENT.test(colorA)) {
        labA = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
      } else {
        labA = convertColorToOklab(colorA, {
          colorSpace,
          format: VAL_MIX
        });
      }
      if (REG_CURRENT.test(colorB)) {
        labB = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
      } else {
        labB = convertColorToOklab(colorB, {
          colorSpace,
          format: VAL_MIX
        });
      }
    }
    if (labA === null || labB === null) {
      return ["rgb", 0, 0, 0, 0];
    }
    let [lA, aA, bA, alphaA] = labA;
    let [lB, aB, bB, alphaB] = labB;
    const lNone = lA === constant.NONE && lB === constant.NONE;
    const aNone = aA === constant.NONE && aB === constant.NONE;
    const bNone = bA === constant.NONE && bB === constant.NONE;
    const alphaNone = alphaA === constant.NONE && alphaB === constant.NONE;
    [[lA, aA, bA, alphaA], [lB, aB, bB, alphaB]] = normalizeColorComponents(
      [lA, aA, bA, alphaA],
      [lB, aB, bB, alphaB],
      true
    );
    const factorA = alphaA * pA;
    const factorB = alphaB * pB;
    alpha = factorA + factorB;
    let l, aO, bO;
    if (alpha === 0) {
      l = lA * pA + lB * pB;
      aO = aA * pA + aB * pB;
      bO = bA * pA + bB * pB;
    } else {
      l = (lA * factorA + lB * factorB) / alpha;
      aO = (aA * factorA + aB * factorB) / alpha;
      bO = (bA * factorA + bB * factorB) / alpha;
      alpha = parseFloat(alpha.toFixed(3));
    }
    if (format === constant.VAL_COMP) {
      return [
        colorSpace,
        lNone ? constant.NONE : util.roundToPrecision(l, HEX),
        aNone ? constant.NONE : util.roundToPrecision(aO, HEX),
        bNone ? constant.NONE : util.roundToPrecision(bO, HEX),
        alphaNone ? constant.NONE : alpha * m
      ];
    }
    [, r, g, b] = resolveColorValue(`${colorSpace}(${l} ${aO} ${bO})`);
  } else if (/^(?:ok)?lch$/.test(colorSpace)) {
    let lchA, lchB;
    if (colorSpace === "lch") {
      if (REG_CURRENT.test(colorA)) {
        lchA = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
      } else {
        lchA = convertColorToLch(colorA, {
          colorSpace,
          format: VAL_MIX
        });
      }
      if (REG_CURRENT.test(colorB)) {
        lchB = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
      } else {
        lchB = convertColorToLch(colorB, {
          colorSpace,
          format: VAL_MIX
        });
      }
    } else {
      if (REG_CURRENT.test(colorA)) {
        lchA = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
      } else {
        lchA = convertColorToOklch(colorA, {
          colorSpace,
          format: VAL_MIX
        });
      }
      if (REG_CURRENT.test(colorB)) {
        lchB = [constant.NONE, constant.NONE, constant.NONE, constant.NONE];
      } else {
        lchB = convertColorToOklch(colorB, {
          colorSpace,
          format: VAL_MIX
        });
      }
    }
    if (lchA === null || lchB === null) {
      return ["rgb", 0, 0, 0, 0];
    }
    let [lA, cA, hA, alphaA] = lchA;
    let [lB, cB, hB, alphaB] = lchB;
    const lNone = lA === constant.NONE && lB === constant.NONE;
    const cNone = cA === constant.NONE && cB === constant.NONE;
    const hNone = hA === constant.NONE && hB === constant.NONE;
    const alphaNone = alphaA === constant.NONE && alphaB === constant.NONE;
    [[lA, cA, hA, alphaA], [lB, cB, hB, alphaB]] = normalizeColorComponents(
      [lA, cA, hA, alphaA],
      [lB, cB, hB, alphaB],
      true
    );
    if (hueArc) {
      [hA, hB] = util.interpolateHue(hA, hB, hueArc);
    }
    const factorA = alphaA * pA;
    const factorB = alphaB * pB;
    alpha = factorA + factorB;
    const h = (hA * pA + hB * pB) % DEG;
    let l, c;
    if (alpha === 0) {
      l = lA * pA + lB * pB;
      c = cA * pA + cB * pB;
    } else {
      l = (lA * factorA + lB * factorB) / alpha;
      c = (cA * factorA + cB * factorB) / alpha;
      alpha = parseFloat(alpha.toFixed(3));
    }
    if (format === constant.VAL_COMP) {
      return [
        colorSpace,
        lNone ? constant.NONE : util.roundToPrecision(l, HEX),
        cNone ? constant.NONE : util.roundToPrecision(c, HEX),
        hNone ? constant.NONE : util.roundToPrecision(h, HEX),
        alphaNone ? constant.NONE : alpha * m
      ];
    }
    [, r, g, b] = resolveColorValue(`${colorSpace}(${l} ${c} ${h})`);
  }
  return [
    "rgb",
    Math.round(r),
    Math.round(g),
    Math.round(b),
    parseFloat((alpha * m).toFixed(3))
  ];
};
exports.NAMED_COLORS = NAMED_COLORS;
exports.angleToDeg = angleToDeg;
exports.convertColorToHsl = convertColorToHsl;
exports.convertColorToHwb = convertColorToHwb;
exports.convertColorToLab = convertColorToLab;
exports.convertColorToLch = convertColorToLch;
exports.convertColorToLinearRgb = convertColorToLinearRgb;
exports.convertColorToOklab = convertColorToOklab;
exports.convertColorToOklch = convertColorToOklch;
exports.convertColorToRgb = convertColorToRgb;
exports.convertColorToXyz = convertColorToXyz;
exports.convertHexToLinearRgb = convertHexToLinearRgb;
exports.convertHexToRgb = convertHexToRgb;
exports.convertHexToXyz = convertHexToXyz;
exports.convertLinearRgbToRgb = convertLinearRgbToRgb;
exports.convertRgbToHex = convertRgbToHex;
exports.convertRgbToLinearRgb = convertRgbToLinearRgb;
exports.convertRgbToXyz = convertRgbToXyz;
exports.convertXyzD50ToLab = convertXyzD50ToLab;
exports.convertXyzD50ToLch = convertXyzD50ToLch;
exports.convertXyzD50ToRgb = convertXyzD50ToRgb;
exports.convertXyzToHsl = convertXyzToHsl;
exports.convertXyzToHwb = convertXyzToHwb;
exports.convertXyzToOklab = convertXyzToOklab;
exports.convertXyzToOklch = convertXyzToOklch;
exports.convertXyzToRgb = convertXyzToRgb;
exports.normalizeColorComponents = normalizeColorComponents;
exports.numberToHexString = numberToHexString;
exports.parseAlpha = parseAlpha;
exports.parseColorFunc = parseColorFunc;
exports.parseColorValue = parseColorValue;
exports.parseHexAlpha = parseHexAlpha;
exports.parseHsl = parseHsl;
exports.parseHwb = parseHwb;
exports.parseLab = parseLab;
exports.parseLch = parseLch;
exports.parseOklab = parseOklab;
exports.parseOklch = parseOklch;
exports.parseRgb = parseRgb;
exports.resolveColorFunc = resolveColorFunc;
exports.resolveColorMix = resolveColorMix;
exports.resolveColorValue = resolveColorValue;
exports.transformMatrix = transformMatrix;
exports.validateColorComponents = validateColorComponents;
//# sourceMappingURL=color.cjs.map
