This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greatest.deepsurf.us/scripts/526709/1536234/chroma-js-umd.js
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.chroma = {}));
- })(this, (function (exports) { 'use strict';
-
- const { min: min$5, max: max$5 } = Math;
-
- var limit$1 = (x, low = 0, high = 1) => {
- return min$5(max$5(low, x), high);
- };
-
- var clip_rgb = (rgb) => {
- rgb._clipped = false;
- rgb._unclipped = rgb.slice(0);
- for (let i = 0; i <= 3; i++) {
- if (i < 3) {
- if (rgb[i] < 0 || rgb[i] > 255) rgb._clipped = true;
- rgb[i] = limit$1(rgb[i], 0, 255);
- } else if (i === 3) {
- rgb[i] = limit$1(rgb[i], 0, 1);
- }
- }
- return rgb;
- };
-
- // ported from jQuery's $.type
- const classToType = {};
- for (let name of [
- 'Boolean',
- 'Number',
- 'String',
- 'Function',
- 'Array',
- 'Date',
- 'RegExp',
- 'Undefined',
- 'Null'
- ]) {
- classToType[`[object ${name}]`] = name.toLowerCase();
- }
- function type (obj) {
- return classToType[Object.prototype.toString.call(obj)] || 'object';
- }
-
- var unpack = (args, keyOrder = null) => {
- // if called with more than 3 arguments, we return the arguments
- if (args.length >= 3) return Array.prototype.slice.call(args);
- // with less than 3 args we check if first arg is object
- // and use the keyOrder string to extract and sort properties
- if (type(args[0]) == 'object' && keyOrder) {
- return keyOrder
- .split('')
- .filter((k) => args[0][k] !== undefined)
- .map((k) => args[0][k]);
- }
- // otherwise we just return the first argument
- // (which we suppose is an array of args)
- return args[0].slice(0);
- };
-
- var last = (args) => {
- if (args.length < 2) return null;
- const l = args.length - 1;
- if (type(args[l]) == 'string') return args[l].toLowerCase();
- return null;
- };
-
- var _input = {
- format: {},
- autodetect: []
- };
-
- let Color$3 = class Color {
- constructor(...args) {
- const me = this;
- if (
- type(args[0]) === 'object' &&
- args[0].constructor &&
- args[0].constructor === this.constructor
- ) {
- // the argument is already a Color instance
- return args[0];
- }
- // last argument could be the mode
- let mode = last(args);
- let autodetect = false;
- if (!mode) {
- autodetect = true;
-
- if (!_input.sorted) {
- _input.autodetect = _input.autodetect.sort((a, b) => b.p - a.p);
- _input.sorted = true;
- }
-
- // auto-detect format
- for (let chk of _input.autodetect) {
- mode = chk.test(...args);
- if (mode) break;
- }
- }
- if (_input.format[mode]) {
- const rgb = _input.format[mode].apply(
- null,
- autodetect ? args : args.slice(0, -1)
- );
- me._rgb = clip_rgb(rgb);
- } else {
- throw new Error('unknown format: ' + args);
- }
- // add alpha channel
- if (me._rgb.length === 3) me._rgb.push(1);
- }
- toString() {
- if (type(this.hex) == 'function') return this.hex();
- return `[${this._rgb.join(',')}]`;
- }
- };
-
- // this gets updated automatically
- const version = '3.1.2';
-
- const chroma$2 = (...args) => {
- return new Color$3(...args);
- };
-
- chroma$2.version = version;
-
- let Color$2 = class Color {
- constructor(...args) {
- const me = this;
- if (
- type(args[0]) === 'object' &&
- args[0].constructor &&
- args[0].constructor === this.constructor
- ) {
- // the argument is already a Color instance
- return args[0];
- }
- // last argument could be the mode
- let mode = last(args);
- let autodetect = false;
- if (!mode) {
- autodetect = true;
-
- if (!_input.sorted) {
- _input.autodetect = _input.autodetect.sort((a, b) => b.p - a.p);
- _input.sorted = true;
- }
-
- // auto-detect format
- for (let chk of _input.autodetect) {
- mode = chk.test(...args);
- if (mode) break;
- }
- }
- if (_input.format[mode]) {
- const rgb = _input.format[mode].apply(
- null,
- autodetect ? args : args.slice(0, -1)
- );
- me._rgb = clip_rgb(rgb);
- } else {
- throw new Error('unknown format: ' + args);
- }
- // add alpha channel
- if (me._rgb.length === 3) me._rgb.push(1);
- }
- toString() {
- if (type(this.hex) == 'function') return this.hex();
- return `[${this._rgb.join(',')}]`;
- }
- };
-
- var input$1 = {
- format: {},
- autodetect: []
- };
-
- const { PI: PI$3, min: min$4, max: max$4 } = Math;
-
- const rnd2 = (a) => Math.round(a * 100) / 100;
- const rnd3 = (a) => Math.round(a * 100) / 100;
-
- const TWOPI$1 = PI$3 * 2;
- const PITHIRD = PI$3 / 3;
- const DEG2RAD = PI$3 / 180;
- const RAD2DEG = 180 / PI$3;
-
- /**
- * Reverse the first three elements of an array
- *
- * @param {any[]} arr
- * @returns {any[]}
- */
- function reverse3(arr) {
- return [...arr.slice(0, 3).reverse(), ...arr.slice(3)];
- }
-
- /**
- X11 color names
-
- http://www.w3.org/TR/css3-color/#svg-color
- */
-
- const w3cx11$1 = {
- aliceblue: '#f0f8ff',
- antiquewhite: '#faebd7',
- aqua: '#00ffff',
- aquamarine: '#7fffd4',
- azure: '#f0ffff',
- beige: '#f5f5dc',
- bisque: '#ffe4c4',
- black: '#000000',
- blanchedalmond: '#ffebcd',
- blue: '#0000ff',
- blueviolet: '#8a2be2',
- brown: '#a52a2a',
- burlywood: '#deb887',
- cadetblue: '#5f9ea0',
- chartreuse: '#7fff00',
- chocolate: '#d2691e',
- coral: '#ff7f50',
- cornflowerblue: '#6495ed',
- cornsilk: '#fff8dc',
- crimson: '#dc143c',
- cyan: '#00ffff',
- darkblue: '#00008b',
- darkcyan: '#008b8b',
- darkgoldenrod: '#b8860b',
- darkgray: '#a9a9a9',
- darkgreen: '#006400',
- darkgrey: '#a9a9a9',
- darkkhaki: '#bdb76b',
- darkmagenta: '#8b008b',
- darkolivegreen: '#556b2f',
- darkorange: '#ff8c00',
- darkorchid: '#9932cc',
- darkred: '#8b0000',
- darksalmon: '#e9967a',
- darkseagreen: '#8fbc8f',
- darkslateblue: '#483d8b',
- darkslategray: '#2f4f4f',
- darkslategrey: '#2f4f4f',
- darkturquoise: '#00ced1',
- darkviolet: '#9400d3',
- deeppink: '#ff1493',
- deepskyblue: '#00bfff',
- dimgray: '#696969',
- dimgrey: '#696969',
- dodgerblue: '#1e90ff',
- firebrick: '#b22222',
- floralwhite: '#fffaf0',
- forestgreen: '#228b22',
- fuchsia: '#ff00ff',
- gainsboro: '#dcdcdc',
- ghostwhite: '#f8f8ff',
- gold: '#ffd700',
- goldenrod: '#daa520',
- gray: '#808080',
- green: '#008000',
- greenyellow: '#adff2f',
- grey: '#808080',
- honeydew: '#f0fff0',
- hotpink: '#ff69b4',
- indianred: '#cd5c5c',
- indigo: '#4b0082',
- ivory: '#fffff0',
- khaki: '#f0e68c',
- laserlemon: '#ffff54',
- lavender: '#e6e6fa',
- lavenderblush: '#fff0f5',
- lawngreen: '#7cfc00',
- lemonchiffon: '#fffacd',
- lightblue: '#add8e6',
- lightcoral: '#f08080',
- lightcyan: '#e0ffff',
- lightgoldenrod: '#fafad2',
- lightgoldenrodyellow: '#fafad2',
- lightgray: '#d3d3d3',
- lightgreen: '#90ee90',
- lightgrey: '#d3d3d3',
- lightpink: '#ffb6c1',
- lightsalmon: '#ffa07a',
- lightseagreen: '#20b2aa',
- lightskyblue: '#87cefa',
- lightslategray: '#778899',
- lightslategrey: '#778899',
- lightsteelblue: '#b0c4de',
- lightyellow: '#ffffe0',
- lime: '#00ff00',
- limegreen: '#32cd32',
- linen: '#faf0e6',
- magenta: '#ff00ff',
- maroon: '#800000',
- maroon2: '#7f0000',
- maroon3: '#b03060',
- mediumaquamarine: '#66cdaa',
- mediumblue: '#0000cd',
- mediumorchid: '#ba55d3',
- mediumpurple: '#9370db',
- mediumseagreen: '#3cb371',
- mediumslateblue: '#7b68ee',
- mediumspringgreen: '#00fa9a',
- mediumturquoise: '#48d1cc',
- mediumvioletred: '#c71585',
- midnightblue: '#191970',
- mintcream: '#f5fffa',
- mistyrose: '#ffe4e1',
- moccasin: '#ffe4b5',
- navajowhite: '#ffdead',
- navy: '#000080',
- oldlace: '#fdf5e6',
- olive: '#808000',
- olivedrab: '#6b8e23',
- orange: '#ffa500',
- orangered: '#ff4500',
- orchid: '#da70d6',
- palegoldenrod: '#eee8aa',
- palegreen: '#98fb98',
- paleturquoise: '#afeeee',
- palevioletred: '#db7093',
- papayawhip: '#ffefd5',
- peachpuff: '#ffdab9',
- peru: '#cd853f',
- pink: '#ffc0cb',
- plum: '#dda0dd',
- powderblue: '#b0e0e6',
- purple: '#800080',
- purple2: '#7f007f',
- purple3: '#a020f0',
- rebeccapurple: '#663399',
- red: '#ff0000',
- rosybrown: '#bc8f8f',
- royalblue: '#4169e1',
- saddlebrown: '#8b4513',
- salmon: '#fa8072',
- sandybrown: '#f4a460',
- seagreen: '#2e8b57',
- seashell: '#fff5ee',
- sienna: '#a0522d',
- silver: '#c0c0c0',
- skyblue: '#87ceeb',
- slateblue: '#6a5acd',
- slategray: '#708090',
- slategrey: '#708090',
- snow: '#fffafa',
- springgreen: '#00ff7f',
- steelblue: '#4682b4',
- tan: '#d2b48c',
- teal: '#008080',
- thistle: '#d8bfd8',
- tomato: '#ff6347',
- turquoise: '#40e0d0',
- violet: '#ee82ee',
- wheat: '#f5deb3',
- white: '#ffffff',
- whitesmoke: '#f5f5f5',
- yellow: '#ffff00',
- yellowgreen: '#9acd32'
- };
-
- const RE_HEX$1 = /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
- const RE_HEXA$1 = /^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/;
-
- const hex2rgb$1 = (hex) => {
- if (hex.match(RE_HEX$1)) {
- // remove optional leading #
- if (hex.length === 4 || hex.length === 7) {
- hex = hex.substr(1);
- }
- // expand short-notation to full six-digit
- if (hex.length === 3) {
- hex = hex.split('');
- hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
- }
- const u = parseInt(hex, 16);
- const r = u >> 16;
- const g = (u >> 8) & 0xff;
- const b = u & 0xff;
- return [r, g, b, 1];
- }
-
- // match rgba hex format, eg #FF000077
- if (hex.match(RE_HEXA$1)) {
- if (hex.length === 5 || hex.length === 9) {
- // remove optional leading #
- hex = hex.substr(1);
- }
- // expand short-notation to full eight-digit
- if (hex.length === 4) {
- hex = hex.split('');
- hex =
- hex[0] +
- hex[0] +
- hex[1] +
- hex[1] +
- hex[2] +
- hex[2] +
- hex[3] +
- hex[3];
- }
- const u = parseInt(hex, 16);
- const r = (u >> 24) & 0xff;
- const g = (u >> 16) & 0xff;
- const b = (u >> 8) & 0xff;
- const a = Math.round(((u & 0xff) / 0xff) * 100) / 100;
- return [r, g, b, a];
- }
-
- // we used to check for css colors here
- // if _input.css? and rgb = _input.css hex
- // return rgb
-
- throw new Error(`unknown hex color: ${hex}`);
- };
-
- const { round: round$8 } = Math;
-
- const rgb2hex$1 = (...args) => {
- let [r, g, b, a] = unpack(args, 'rgba');
- let mode = last(args) || 'auto';
- if (a === undefined) a = 1;
- if (mode === 'auto') {
- mode = a < 1 ? 'rgba' : 'rgb';
- }
- r = round$8(r);
- g = round$8(g);
- b = round$8(b);
- const u = (r << 16) | (g << 8) | b;
- let str = '000000' + u.toString(16); //#.toUpperCase();
- str = str.substr(str.length - 6);
- let hxa = '0' + round$8(a * 255).toString(16);
- hxa = hxa.substr(hxa.length - 2);
- switch (mode.toLowerCase()) {
- case 'rgba':
- return `#${str}${hxa}`;
- case 'argb':
- return `#${hxa}${str}`;
- default:
- return `#${str}`;
- }
- };
-
- Color$2.prototype.name = function () {
- const hex = rgb2hex$1(this._rgb, 'rgb');
- for (let n of Object.keys(w3cx11$1)) {
- if (w3cx11$1[n] === hex) return n.toLowerCase();
- }
- return hex;
- };
-
- input$1.format.named = (name) => {
- name = name.toLowerCase();
- if (w3cx11$1[name]) return hex2rgb$1(w3cx11$1[name]);
- throw new Error('unknown color name: ' + name);
- };
-
- input$1.autodetect.push({
- p: 5,
- test: (h, ...rest) => {
- if (!rest.length && type(h) === 'string' && w3cx11$1[h.toLowerCase()]) {
- return 'named';
- }
- }
- });
-
- let Color$1 = class Color {
- constructor(...args) {
- const me = this;
- if (
- type(args[0]) === 'object' &&
- args[0].constructor &&
- args[0].constructor === this.constructor
- ) {
- // the argument is already a Color instance
- return args[0];
- }
- // last argument could be the mode
- let mode = last(args);
- let autodetect = false;
- if (!mode) {
- autodetect = true;
-
- if (!_input.sorted) {
- _input.autodetect = _input.autodetect.sort((a, b) => b.p - a.p);
- _input.sorted = true;
- }
-
- // auto-detect format
- for (let chk of _input.autodetect) {
- mode = chk.test(...args);
- if (mode) break;
- }
- }
- if (_input.format[mode]) {
- const rgb = _input.format[mode].apply(
- null,
- autodetect ? args : args.slice(0, -1)
- );
- me._rgb = clip_rgb(rgb);
- } else {
- throw new Error('unknown format: ' + args);
- }
- // add alpha channel
- if (me._rgb.length === 3) me._rgb.push(1);
- }
- toString() {
- if (type(this.hex) == 'function') return this.hex();
- return `[${this._rgb.join(',')}]`;
- }
- };
-
- const { PI: PI$2} = Math;
-
- const TWOPI = PI$2 * 2;
-
- Color$1.prototype.alpha = function (a, mutate = false) {
- if (a !== undefined && type(a) === 'number') {
- if (mutate) {
- this._rgb[3] = a;
- return this;
- }
- return new Color$1([this._rgb[0], this._rgb[1], this._rgb[2], a], 'rgb');
- }
- return this._rgb[3];
- };
-
- Color$1.prototype.clipped = function () {
- return this._rgb._clipped || false;
- };
-
- const chroma$1 = (...args) => {
- return new Color$3(...args);
- };
-
- chroma$1.version = version;
-
- const labConstants$2 = {
- // D65 standard referent
- labWhitePoint: 'd65',
- Xn: 0.95047,
- Yn: 1,
- Zn: 1.08883,
-
- kE: 216.0 / 24389.0,
- kKE: 8.0,
- kK: 24389.0 / 27.0,
-
- RefWhiteRGB: {
- // sRGB
- X: 0.95047,
- Y: 1,
- Z: 1.08883
- },
-
- MtxRGB2XYZ: {
- m00: 0.4124564390896922,
- m01: 0.21267285140562253,
- m02: 0.0193338955823293,
- m10: 0.357576077643909,
- m11: 0.715152155287818,
- m12: 0.11919202588130297,
- m20: 0.18043748326639894,
- m21: 0.07217499330655958,
- m22: 0.9503040785363679
- },
-
- MtxXYZ2RGB: {
- m00: 3.2404541621141045,
- m01: -0.9692660305051868,
- m02: 0.055643430959114726,
- m10: -1.5371385127977166,
- m11: 1.8760108454466942,
- m12: -0.2040259135167538,
- m20: -0.498531409556016,
- m21: 0.041556017530349834,
- m22: 1.0572251882231791
- },
-
- // used in rgb2xyz
- As: 0.9414285350000001,
- Bs: 1.040417467,
- Cs: 1.089532651,
-
- MtxAdaptMa: {
- m00: 0.8951,
- m01: -0.7502,
- m02: 0.0389,
- m10: 0.2664,
- m11: 1.7135,
- m12: -0.0685,
- m20: -0.1614,
- m21: 0.0367,
- m22: 1.0296
- },
-
- MtxAdaptMaI: {
- m00: 0.9869929054667123,
- m01: 0.43230526972339456,
- m02: -0.008528664575177328,
- m10: -0.14705425642099013,
- m11: 0.5183602715367776,
- m12: 0.04004282165408487,
- m20: 0.15996265166373125,
- m21: 0.0492912282128556,
- m22: 0.9684866957875502
- }
- };
-
- // taken from https://de.mathworks.com/help/images/ref/whitepoint.html
- const ILLUMINANTS$1 = new Map([
- // ASTM E308-01
- ['a', [1.0985, 0.35585]],
- // Wyszecki & Stiles, p. 769
- ['b', [1.0985, 0.35585]],
- // C ASTM E308-01
- ['c', [0.98074, 1.18232]],
- // D50 (ASTM E308-01)
- ['d50', [0.96422, 0.82521]],
- // D55 (ASTM E308-01)
- ['d55', [0.95682, 0.92149]],
- // D65 (ASTM E308-01)
- ['d65', [0.95047, 1.08883]],
- // E (ASTM E308-01)
- ['e', [1, 1, 1]],
- // F2 (ASTM E308-01)
- ['f2', [0.99186, 0.67393]],
- // F7 (ASTM E308-01)
- ['f7', [0.95041, 1.08747]],
- // F11 (ASTM E308-01)
- ['f11', [1.00962, 0.6435]],
- ['icc', [0.96422, 0.82521]]
- ]);
-
- function setLabWhitePoint$1(name) {
- const ill = ILLUMINANTS$1.get(String(name).toLowerCase());
- if (!ill) {
- throw new Error('unknown Lab illuminant ' + name);
- }
- labConstants$2.labWhitePoint = name;
- labConstants$2.Xn = ill[0];
- labConstants$2.Zn = ill[1];
- }
-
- function getLabWhitePoint$1() {
- return labConstants$2.labWhitePoint;
- }
-
- /*
- * L* [0..100]
- * a [-100..100]
- * b [-100..100]
- */
- const lab2rgb$1 = (...args) => {
- args = unpack(args, 'lab');
- const [L, a, b] = args;
- const [x, y, z] = lab2xyz$1(L, a, b);
- const [r, g, b_] = xyz2rgb$1(x, y, z);
- return [r, g, b_, args.length > 3 ? args[3] : 1];
- };
-
- const lab2xyz$1 = (L, a, b) => {
- const { kE, kK, kKE, Xn, Yn, Zn } = labConstants$2;
-
- const fy = (L + 16.0) / 116.0;
- const fx = 0.002 * a + fy;
- const fz = fy - 0.005 * b;
-
- const fx3 = fx * fx * fx;
- const fz3 = fz * fz * fz;
-
- const xr = fx3 > kE ? fx3 : (116.0 * fx - 16.0) / kK;
- const yr = L > kKE ? Math.pow((L + 16.0) / 116.0, 3.0) : L / kK;
- const zr = fz3 > kE ? fz3 : (116.0 * fz - 16.0) / kK;
-
- const x = xr * Xn;
- const y = yr * Yn;
- const z = zr * Zn;
-
- return [x, y, z];
- };
-
- const compand$1 = (linear) => {
- /* sRGB */
- const sign = Math.sign(linear);
- linear = Math.abs(linear);
- return (
- (linear <= 0.0031308
- ? linear * 12.92
- : 1.055 * Math.pow(linear, 1.0 / 2.4) - 0.055) * sign
- );
- };
-
- const xyz2rgb$1 = (x, y, z) => {
- const { MtxAdaptMa, MtxAdaptMaI, MtxXYZ2RGB, RefWhiteRGB, Xn, Yn, Zn } =
- labConstants$2;
-
- const As = Xn * MtxAdaptMa.m00 + Yn * MtxAdaptMa.m10 + Zn * MtxAdaptMa.m20;
- const Bs = Xn * MtxAdaptMa.m01 + Yn * MtxAdaptMa.m11 + Zn * MtxAdaptMa.m21;
- const Cs = Xn * MtxAdaptMa.m02 + Yn * MtxAdaptMa.m12 + Zn * MtxAdaptMa.m22;
-
- const Ad =
- RefWhiteRGB.X * MtxAdaptMa.m00 +
- RefWhiteRGB.Y * MtxAdaptMa.m10 +
- RefWhiteRGB.Z * MtxAdaptMa.m20;
- const Bd =
- RefWhiteRGB.X * MtxAdaptMa.m01 +
- RefWhiteRGB.Y * MtxAdaptMa.m11 +
- RefWhiteRGB.Z * MtxAdaptMa.m21;
- const Cd =
- RefWhiteRGB.X * MtxAdaptMa.m02 +
- RefWhiteRGB.Y * MtxAdaptMa.m12 +
- RefWhiteRGB.Z * MtxAdaptMa.m22;
-
- const X1 =
- (x * MtxAdaptMa.m00 + y * MtxAdaptMa.m10 + z * MtxAdaptMa.m20) *
- (Ad / As);
- const Y1 =
- (x * MtxAdaptMa.m01 + y * MtxAdaptMa.m11 + z * MtxAdaptMa.m21) *
- (Bd / Bs);
- const Z1 =
- (x * MtxAdaptMa.m02 + y * MtxAdaptMa.m12 + z * MtxAdaptMa.m22) *
- (Cd / Cs);
-
- const X2 =
- X1 * MtxAdaptMaI.m00 + Y1 * MtxAdaptMaI.m10 + Z1 * MtxAdaptMaI.m20;
- const Y2 =
- X1 * MtxAdaptMaI.m01 + Y1 * MtxAdaptMaI.m11 + Z1 * MtxAdaptMaI.m21;
- const Z2 =
- X1 * MtxAdaptMaI.m02 + Y1 * MtxAdaptMaI.m12 + Z1 * MtxAdaptMaI.m22;
-
- const r = compand$1(
- X2 * MtxXYZ2RGB.m00 + Y2 * MtxXYZ2RGB.m10 + Z2 * MtxXYZ2RGB.m20
- );
- const g = compand$1(
- X2 * MtxXYZ2RGB.m01 + Y2 * MtxXYZ2RGB.m11 + Z2 * MtxXYZ2RGB.m21
- );
- const b = compand$1(
- X2 * MtxXYZ2RGB.m02 + Y2 * MtxXYZ2RGB.m12 + Z2 * MtxXYZ2RGB.m22
- );
-
- return [r * 255, g * 255, b * 255];
- };
-
- const rgb2lab$1 = (...args) => {
- const [r, g, b, ...rest] = unpack(args, 'rgb');
- const [x, y, z] = rgb2xyz$1(r, g, b);
- const [L, a, b_] = xyz2lab$1(x, y, z);
- return [L, a, b_, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
- };
-
- function xyz2lab$1(x, y, z) {
- const { Xn, Yn, Zn, kE, kK } = labConstants$2;
- const xr = x / Xn;
- const yr = y / Yn;
- const zr = z / Zn;
-
- const fx = xr > kE ? Math.pow(xr, 1.0 / 3.0) : (kK * xr + 16.0) / 116.0;
- const fy = yr > kE ? Math.pow(yr, 1.0 / 3.0) : (kK * yr + 16.0) / 116.0;
- const fz = zr > kE ? Math.pow(zr, 1.0 / 3.0) : (kK * zr + 16.0) / 116.0;
-
- return [116.0 * fy - 16.0, 500.0 * (fx - fy), 200.0 * (fy - fz)];
- }
-
- function gammaAdjustSRGB$1(companded) {
- const sign = Math.sign(companded);
- companded = Math.abs(companded);
- const linear =
- companded <= 0.04045
- ? companded / 12.92
- : Math.pow((companded + 0.055) / 1.055, 2.4);
- return linear * sign;
- }
-
- const rgb2xyz$1 = (r, g, b) => {
- // normalize and gamma adjust
- r = gammaAdjustSRGB$1(r / 255);
- g = gammaAdjustSRGB$1(g / 255);
- b = gammaAdjustSRGB$1(b / 255);
-
- const { MtxRGB2XYZ, MtxAdaptMa, MtxAdaptMaI, Xn, Yn, Zn, As, Bs, Cs } =
- labConstants$2;
-
- let x = r * MtxRGB2XYZ.m00 + g * MtxRGB2XYZ.m10 + b * MtxRGB2XYZ.m20;
- let y = r * MtxRGB2XYZ.m01 + g * MtxRGB2XYZ.m11 + b * MtxRGB2XYZ.m21;
- let z = r * MtxRGB2XYZ.m02 + g * MtxRGB2XYZ.m12 + b * MtxRGB2XYZ.m22;
-
- const Ad = Xn * MtxAdaptMa.m00 + Yn * MtxAdaptMa.m10 + Zn * MtxAdaptMa.m20;
- const Bd = Xn * MtxAdaptMa.m01 + Yn * MtxAdaptMa.m11 + Zn * MtxAdaptMa.m21;
- const Cd = Xn * MtxAdaptMa.m02 + Yn * MtxAdaptMa.m12 + Zn * MtxAdaptMa.m22;
-
- let X = x * MtxAdaptMa.m00 + y * MtxAdaptMa.m10 + z * MtxAdaptMa.m20;
- let Y = x * MtxAdaptMa.m01 + y * MtxAdaptMa.m11 + z * MtxAdaptMa.m21;
- let Z = x * MtxAdaptMa.m02 + y * MtxAdaptMa.m12 + z * MtxAdaptMa.m22;
-
- X *= Ad / As;
- Y *= Bd / Bs;
- Z *= Cd / Cs;
-
- x = X * MtxAdaptMaI.m00 + Y * MtxAdaptMaI.m10 + Z * MtxAdaptMaI.m20;
- y = X * MtxAdaptMaI.m01 + Y * MtxAdaptMaI.m11 + Z * MtxAdaptMaI.m21;
- z = X * MtxAdaptMaI.m02 + Y * MtxAdaptMaI.m12 + Z * MtxAdaptMaI.m22;
-
- return [x, y, z];
- };
-
- Color$2.prototype.lab = function () {
- return rgb2lab$1(this._rgb);
- };
-
- const lab$1 = (...args) => new Color$2(...args, 'lab');
- Object.assign(chroma$1, { lab: lab$1, getLabWhitePoint: getLabWhitePoint$1, setLabWhitePoint: setLabWhitePoint$1 });
-
- input$1.format.lab = lab2rgb$1;
-
- input$1.autodetect.push({
- p: 2,
- test: (...args) => {
- args = unpack(args, 'lab');
- if (type(args) === 'array' && args.length === 3) {
- return 'lab';
- }
- }
- });
-
- const labConstants$1 = {
- // Corresponds roughly to RGB brighter/darker
- Kn: 18};
-
- Color$1.prototype.darken = function (amount = 1) {
- const me = this;
- const lab = me.lab();
- lab[0] -= labConstants$1.Kn * amount;
- return new Color$1(lab, 'lab').alpha(me.alpha(), true);
- };
-
- Color$1.prototype.brighten = function (amount = 1) {
- return this.darken(-amount);
- };
-
- Color$1.prototype.darker = Color$1.prototype.darken;
- Color$1.prototype.brighter = Color$1.prototype.brighten;
-
- Color$1.prototype.get = function (mc) {
- const [mode, channel] = mc.split('.');
- const src = this[mode]();
- if (channel) {
- const i = mode.indexOf(channel) - (mode.substr(0, 2) === 'ok' ? 2 : 0);
- if (i > -1) return src[i];
- throw new Error(`unknown channel ${channel} in mode ${mode}`);
- } else {
- return src;
- }
- };
-
- const { pow: pow$8 } = Math;
-
- const EPS$1 = 1e-7;
- const MAX_ITER$1 = 20;
-
- Color$1.prototype.luminance = function (lum, mode = 'rgb') {
- if (lum !== undefined && type(lum) === 'number') {
- if (lum === 0) {
- // return pure black
- return new Color$1([0, 0, 0, this._rgb[3]], 'rgb');
- }
- if (lum === 1) {
- // return pure white
- return new Color$1([255, 255, 255, this._rgb[3]], 'rgb');
- }
- // compute new color using...
- let cur_lum = this.luminance();
- let max_iter = MAX_ITER$1;
-
- const test = (low, high) => {
- const mid = low.interpolate(high, 0.5, mode);
- const lm = mid.luminance();
- if (Math.abs(lum - lm) < EPS$1 || !max_iter--) {
- // close enough
- return mid;
- }
- return lm > lum ? test(low, mid) : test(mid, high);
- };
-
- const rgb = (
- cur_lum > lum
- ? test(new Color$1([0, 0, 0]), this)
- : test(this, new Color$1([255, 255, 255]))
- ).rgb();
- return new Color$1([...rgb, this._rgb[3]]);
- }
- return rgb2luminance$1(...this._rgb.slice(0, 3));
- };
-
- const rgb2luminance$1 = (r, g, b) => {
- // relative luminance
- // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
- r = luminance_x$1(r);
- g = luminance_x$1(g);
- b = luminance_x$1(b);
- return 0.2126 * r + 0.7152 * g + 0.0722 * b;
- };
-
- const luminance_x$1 = (x) => {
- x /= 255;
- return x <= 0.03928 ? x / 12.92 : pow$8((x + 0.055) / 1.055, 2.4);
- };
-
- var interpolator = {};
-
- var mix$1 = (col1, col2, f = 0.5, ...rest) => {
- let mode = rest[0] || 'lrgb';
- if (!interpolator[mode] && !rest.length) {
- // fall back to the first supported mode
- mode = Object.keys(interpolator)[0];
- }
- if (!interpolator[mode]) {
- throw new Error(`interpolation mode ${mode} is not defined`);
- }
- if (type(col1) !== 'object') col1 = new Color$1(col1);
- if (type(col2) !== 'object') col2 = new Color$1(col2);
- return interpolator[mode](col1, col2, f).alpha(
- col1.alpha() + f * (col2.alpha() - col1.alpha())
- );
- };
-
- Color$1.prototype.mix = Color$1.prototype.interpolate = function (
- col2,
- f = 0.5,
- ...rest
- ) {
- return mix$1(this, col2, f, ...rest);
- };
-
- Color$1.prototype.premultiply = function (mutate = false) {
- const rgb = this._rgb;
- const a = rgb[3];
- if (mutate) {
- this._rgb = [rgb[0] * a, rgb[1] * a, rgb[2] * a, a];
- return this;
- } else {
- return new Color$1([rgb[0] * a, rgb[1] * a, rgb[2] * a, a], 'rgb');
- }
- };
-
- const { sin: sin$4, cos: cos$5 } = Math;
-
- const lch2lab$1 = (...args) => {
- /*
- Convert from a qualitative parameter h and a quantitative parameter l to a 24-bit pixel.
- These formulas were invented by David Dalrymple to obtain maximum contrast without going
- out of gamut if the parameters are in the range 0-1.
-
- A saturation multiplier was added by Gregor Aisch
- */
- let [l, c, h] = unpack(args, 'lch');
- if (isNaN(h)) h = 0;
- h = h * DEG2RAD;
- return [l, cos$5(h) * c, sin$4(h) * c];
- };
-
- /*
- * L* [0..100]
- * a [-100..100]
- * b [-100..100]
- */
- const lab2rgb = (...args) => {
- args = unpack(args, 'lab');
- const [L, a, b] = args;
- const [x, y, z] = lab2xyz(L, a, b);
- const [r, g, b_] = xyz2rgb(x, y, z);
- return [r, g, b_, args.length > 3 ? args[3] : 1];
- };
-
- const lab2xyz = (L, a, b) => {
- const { kE, kK, kKE, Xn, Yn, Zn } = labConstants$2;
-
- const fy = (L + 16.0) / 116.0;
- const fx = 0.002 * a + fy;
- const fz = fy - 0.005 * b;
-
- const fx3 = fx * fx * fx;
- const fz3 = fz * fz * fz;
-
- const xr = fx3 > kE ? fx3 : (116.0 * fx - 16.0) / kK;
- const yr = L > kKE ? Math.pow((L + 16.0) / 116.0, 3.0) : L / kK;
- const zr = fz3 > kE ? fz3 : (116.0 * fz - 16.0) / kK;
-
- const x = xr * Xn;
- const y = yr * Yn;
- const z = zr * Zn;
-
- return [x, y, z];
- };
-
- const compand = (linear) => {
- /* sRGB */
- const sign = Math.sign(linear);
- linear = Math.abs(linear);
- return (
- (linear <= 0.0031308
- ? linear * 12.92
- : 1.055 * Math.pow(linear, 1.0 / 2.4) - 0.055) * sign
- );
- };
-
- const xyz2rgb = (x, y, z) => {
- const { MtxAdaptMa, MtxAdaptMaI, MtxXYZ2RGB, RefWhiteRGB, Xn, Yn, Zn } =
- labConstants$2;
-
- const As = Xn * MtxAdaptMa.m00 + Yn * MtxAdaptMa.m10 + Zn * MtxAdaptMa.m20;
- const Bs = Xn * MtxAdaptMa.m01 + Yn * MtxAdaptMa.m11 + Zn * MtxAdaptMa.m21;
- const Cs = Xn * MtxAdaptMa.m02 + Yn * MtxAdaptMa.m12 + Zn * MtxAdaptMa.m22;
-
- const Ad =
- RefWhiteRGB.X * MtxAdaptMa.m00 +
- RefWhiteRGB.Y * MtxAdaptMa.m10 +
- RefWhiteRGB.Z * MtxAdaptMa.m20;
- const Bd =
- RefWhiteRGB.X * MtxAdaptMa.m01 +
- RefWhiteRGB.Y * MtxAdaptMa.m11 +
- RefWhiteRGB.Z * MtxAdaptMa.m21;
- const Cd =
- RefWhiteRGB.X * MtxAdaptMa.m02 +
- RefWhiteRGB.Y * MtxAdaptMa.m12 +
- RefWhiteRGB.Z * MtxAdaptMa.m22;
-
- const X1 =
- (x * MtxAdaptMa.m00 + y * MtxAdaptMa.m10 + z * MtxAdaptMa.m20) *
- (Ad / As);
- const Y1 =
- (x * MtxAdaptMa.m01 + y * MtxAdaptMa.m11 + z * MtxAdaptMa.m21) *
- (Bd / Bs);
- const Z1 =
- (x * MtxAdaptMa.m02 + y * MtxAdaptMa.m12 + z * MtxAdaptMa.m22) *
- (Cd / Cs);
-
- const X2 =
- X1 * MtxAdaptMaI.m00 + Y1 * MtxAdaptMaI.m10 + Z1 * MtxAdaptMaI.m20;
- const Y2 =
- X1 * MtxAdaptMaI.m01 + Y1 * MtxAdaptMaI.m11 + Z1 * MtxAdaptMaI.m21;
- const Z2 =
- X1 * MtxAdaptMaI.m02 + Y1 * MtxAdaptMaI.m12 + Z1 * MtxAdaptMaI.m22;
-
- const r = compand(
- X2 * MtxXYZ2RGB.m00 + Y2 * MtxXYZ2RGB.m10 + Z2 * MtxXYZ2RGB.m20
- );
- const g = compand(
- X2 * MtxXYZ2RGB.m01 + Y2 * MtxXYZ2RGB.m11 + Z2 * MtxXYZ2RGB.m21
- );
- const b = compand(
- X2 * MtxXYZ2RGB.m02 + Y2 * MtxXYZ2RGB.m12 + Z2 * MtxXYZ2RGB.m22
- );
-
- return [r * 255, g * 255, b * 255];
- };
-
- const lch2rgb$1 = (...args) => {
- args = unpack(args, 'lch');
- const [l, c, h] = args;
- const [L, a, b_] = lch2lab$1(l, c, h);
- const [r, g, b] = lab2rgb(L, a, b_);
- return [r, g, b, args.length > 3 ? args[3] : 1];
- };
-
- const hcl2rgb = (...args) => {
- const hcl = reverse3(unpack(args, 'hcl'));
- return lch2rgb$1(...hcl);
- };
-
- const rgb2lab = (...args) => {
- const [r, g, b, ...rest] = unpack(args, 'rgb');
- const [x, y, z] = rgb2xyz(r, g, b);
- const [L, a, b_] = xyz2lab(x, y, z);
- return [L, a, b_, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
- };
-
- function xyz2lab(x, y, z) {
- const { Xn, Yn, Zn, kE, kK } = labConstants$2;
- const xr = x / Xn;
- const yr = y / Yn;
- const zr = z / Zn;
-
- const fx = xr > kE ? Math.pow(xr, 1.0 / 3.0) : (kK * xr + 16.0) / 116.0;
- const fy = yr > kE ? Math.pow(yr, 1.0 / 3.0) : (kK * yr + 16.0) / 116.0;
- const fz = zr > kE ? Math.pow(zr, 1.0 / 3.0) : (kK * zr + 16.0) / 116.0;
-
- return [116.0 * fy - 16.0, 500.0 * (fx - fy), 200.0 * (fy - fz)];
- }
-
- function gammaAdjustSRGB(companded) {
- const sign = Math.sign(companded);
- companded = Math.abs(companded);
- const linear =
- companded <= 0.04045
- ? companded / 12.92
- : Math.pow((companded + 0.055) / 1.055, 2.4);
- return linear * sign;
- }
-
- const rgb2xyz = (r, g, b) => {
- // normalize and gamma adjust
- r = gammaAdjustSRGB(r / 255);
- g = gammaAdjustSRGB(g / 255);
- b = gammaAdjustSRGB(b / 255);
-
- const { MtxRGB2XYZ, MtxAdaptMa, MtxAdaptMaI, Xn, Yn, Zn, As, Bs, Cs } =
- labConstants$2;
-
- let x = r * MtxRGB2XYZ.m00 + g * MtxRGB2XYZ.m10 + b * MtxRGB2XYZ.m20;
- let y = r * MtxRGB2XYZ.m01 + g * MtxRGB2XYZ.m11 + b * MtxRGB2XYZ.m21;
- let z = r * MtxRGB2XYZ.m02 + g * MtxRGB2XYZ.m12 + b * MtxRGB2XYZ.m22;
-
- const Ad = Xn * MtxAdaptMa.m00 + Yn * MtxAdaptMa.m10 + Zn * MtxAdaptMa.m20;
- const Bd = Xn * MtxAdaptMa.m01 + Yn * MtxAdaptMa.m11 + Zn * MtxAdaptMa.m21;
- const Cd = Xn * MtxAdaptMa.m02 + Yn * MtxAdaptMa.m12 + Zn * MtxAdaptMa.m22;
-
- let X = x * MtxAdaptMa.m00 + y * MtxAdaptMa.m10 + z * MtxAdaptMa.m20;
- let Y = x * MtxAdaptMa.m01 + y * MtxAdaptMa.m11 + z * MtxAdaptMa.m21;
- let Z = x * MtxAdaptMa.m02 + y * MtxAdaptMa.m12 + z * MtxAdaptMa.m22;
-
- X *= Ad / As;
- Y *= Bd / Bs;
- Z *= Cd / Cs;
-
- x = X * MtxAdaptMaI.m00 + Y * MtxAdaptMaI.m10 + Z * MtxAdaptMaI.m20;
- y = X * MtxAdaptMaI.m01 + Y * MtxAdaptMaI.m11 + Z * MtxAdaptMaI.m21;
- z = X * MtxAdaptMaI.m02 + Y * MtxAdaptMaI.m12 + Z * MtxAdaptMaI.m22;
-
- return [x, y, z];
- };
-
- const { sqrt: sqrt$4, atan2: atan2$3, round: round$7 } = Math;
-
- const lab2lch$1 = (...args) => {
- const [l, a, b] = unpack(args, 'lab');
- const c = sqrt$4(a * a + b * b);
- let h = (atan2$3(b, a) * RAD2DEG + 360) % 360;
- if (round$7(c * 10000) === 0) h = Number.NaN;
- return [l, c, h];
- };
-
- const rgb2lch$1 = (...args) => {
- const [r, g, b, ...rest] = unpack(args, 'rgb');
- const [l, a, b_] = rgb2lab(r, g, b);
- const [L, c, h] = lab2lch$1(l, a, b_);
- return [L, c, h, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
- };
-
- Color$2.prototype.lch = function () {
- return rgb2lch$1(this._rgb);
- };
- Color$2.prototype.hcl = function () {
- return reverse3(rgb2lch$1(this._rgb));
- };
-
- const lch$1 = (...args) => new Color$2(...args, 'lch');
- const hcl$1 = (...args) => new Color$2(...args, 'hcl');
-
- Object.assign(chroma$1, { lch: lch$1, hcl: hcl$1 });
-
- input$1.format.lch = lch2rgb$1;
- input$1.format.hcl = hcl2rgb;
- ['lch', 'hcl'].forEach((m) =>
- input$1.autodetect.push({
- p: 2,
- test: (...args) => {
- args = unpack(args, m);
- if (type(args) === 'array' && args.length === 3) {
- return m;
- }
- }
- })
- );
-
- Color$1.prototype.saturate = function (amount = 1) {
- const me = this;
- const lch = me.lch();
- lch[1] += labConstants$1.Kn * amount;
- if (lch[1] < 0) lch[1] = 0;
- return new Color$1(lch, 'lch').alpha(me.alpha(), true);
- };
-
- Color$1.prototype.desaturate = function (amount = 1) {
- return this.saturate(-amount);
- };
-
- Color$1.prototype.set = function (mc, value, mutate = false) {
- const [mode, channel] = mc.split('.');
- const src = this[mode]();
- if (channel) {
- const i = mode.indexOf(channel) - (mode.substr(0, 2) === 'ok' ? 2 : 0);
- if (i > -1) {
- if (type(value) == 'string') {
- switch (value.charAt(0)) {
- case '+':
- src[i] += +value;
- break;
- case '-':
- src[i] += +value;
- break;
- case '*':
- src[i] *= +value.substr(1);
- break;
- case '/':
- src[i] /= +value.substr(1);
- break;
- default:
- src[i] = +value;
- }
- } else if (type(value) === 'number') {
- src[i] = value;
- } else {
- throw new Error(`unsupported value for Color.set`);
- }
- const out = new Color$1(src, mode);
- if (mutate) {
- this._rgb = out._rgb;
- return this;
- }
- return out;
- }
- throw new Error(`unknown channel ${channel} in mode ${mode}`);
- } else {
- return src;
- }
- };
-
- Color$1.prototype.tint = function (f = 0.5, ...rest) {
- return mix$1(this, 'white', f, ...rest);
- };
-
- Color$1.prototype.shade = function (f = 0.5, ...rest) {
- return mix$1(this, 'black', f, ...rest);
- };
-
- const num2rgb = (num) => {
- if (type(num) == 'number' && num >= 0 && num <= 0xffffff) {
- const r = num >> 16;
- const g = (num >> 8) & 0xff;
- const b = num & 0xff;
- return [r, g, b, 1];
- }
- throw new Error('unknown num color: ' + num);
- };
-
- const rgb2num = (...args) => {
- const [r, g, b] = unpack(args, 'rgb');
- return (r << 16) + (g << 8) + b;
- };
-
- Color$2.prototype.num = function () {
- return rgb2num(this._rgb);
- };
-
- const num$1 = (...args) => new Color$2(...args, 'num');
-
- Object.assign(chroma$1, { num: num$1 });
-
- input$1.format.num = num2rgb;
-
- input$1.autodetect.push({
- p: 5,
- test: (...args) => {
- if (
- args.length === 1 &&
- type(args[0]) === 'number' &&
- args[0] >= 0 &&
- args[0] <= 0xffffff
- ) {
- return 'num';
- }
- }
- });
-
- const { floor: floor$3 } = Math;
-
- /*
- * this is basically just HSV with some minor tweaks
- *
- * hue.. [0..360]
- * chroma .. [0..1]
- * grayness .. [0..1]
- */
-
- const hcg2rgb = (...args) => {
- args = unpack(args, 'hcg');
- let [h, c, _g] = args;
- let r, g, b;
- _g = _g * 255;
- const _c = c * 255;
- if (c === 0) {
- r = g = b = _g;
- } else {
- if (h === 360) h = 0;
- if (h > 360) h -= 360;
- if (h < 0) h += 360;
- h /= 60;
- const i = floor$3(h);
- const f = h - i;
- const p = _g * (1 - c);
- const q = p + _c * (1 - f);
- const t = p + _c * f;
- const v = p + _c;
- switch (i) {
- case 0:
- [r, g, b] = [v, t, p];
- break;
- case 1:
- [r, g, b] = [q, v, p];
- break;
- case 2:
- [r, g, b] = [p, v, t];
- break;
- case 3:
- [r, g, b] = [p, q, v];
- break;
- case 4:
- [r, g, b] = [t, p, v];
- break;
- case 5:
- [r, g, b] = [v, p, q];
- break;
- }
- }
- return [r, g, b, args.length > 3 ? args[3] : 1];
- };
-
- const rgb2hcg = (...args) => {
- const [r, g, b] = unpack(args, 'rgb');
- const minRgb = min$4(r, g, b);
- const maxRgb = max$4(r, g, b);
- const delta = maxRgb - minRgb;
- const c = (delta * 100) / 255;
- const _g = (minRgb / (255 - delta)) * 100;
- let h;
- if (delta === 0) {
- h = Number.NaN;
- } else {
- if (r === maxRgb) h = (g - b) / delta;
- if (g === maxRgb) h = 2 + (b - r) / delta;
- if (b === maxRgb) h = 4 + (r - g) / delta;
- h *= 60;
- if (h < 0) h += 360;
- }
- return [h, c, _g];
- };
-
- Color$2.prototype.hcg = function () {
- return rgb2hcg(this._rgb);
- };
-
- const hcg$1 = (...args) => new Color$2(...args, 'hcg');
- chroma$1.hcg = hcg$1;
-
- input$1.format.hcg = hcg2rgb;
-
- input$1.autodetect.push({
- p: 1,
- test: (...args) => {
- args = unpack(args, 'hcg');
- if (type(args) === 'array' && args.length === 3) {
- return 'hcg';
- }
- }
- });
-
- const { cos: cos$4 } = Math;
-
- /*
- * hue [0..360]
- * saturation [0..1]
- * intensity [0..1]
- */
- const hsi2rgb = (...args) => {
- /*
- borrowed from here:
- http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/hsi2rgb.cpp
- */
- args = unpack(args, 'hsi');
- let [h, s, i] = args;
- let r, g, b;
-
- if (isNaN(h)) h = 0;
- if (isNaN(s)) s = 0;
- // normalize hue
- if (h > 360) h -= 360;
- if (h < 0) h += 360;
- h /= 360;
- if (h < 1 / 3) {
- b = (1 - s) / 3;
- r = (1 + (s * cos$4(TWOPI$1 * h)) / cos$4(PITHIRD - TWOPI$1 * h)) / 3;
- g = 1 - (b + r);
- } else if (h < 2 / 3) {
- h -= 1 / 3;
- r = (1 - s) / 3;
- g = (1 + (s * cos$4(TWOPI$1 * h)) / cos$4(PITHIRD - TWOPI$1 * h)) / 3;
- b = 1 - (r + g);
- } else {
- h -= 2 / 3;
- g = (1 - s) / 3;
- b = (1 + (s * cos$4(TWOPI$1 * h)) / cos$4(PITHIRD - TWOPI$1 * h)) / 3;
- r = 1 - (g + b);
- }
- r = limit$1(i * r * 3);
- g = limit$1(i * g * 3);
- b = limit$1(i * b * 3);
- return [r * 255, g * 255, b * 255, args.length > 3 ? args[3] : 1];
- };
-
- const { min: min$3, sqrt: sqrt$3, acos } = Math;
-
- const rgb2hsi = (...args) => {
- /*
- borrowed from here:
- http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/rgb2hsi.cpp
- */
- let [r, g, b] = unpack(args, 'rgb');
- r /= 255;
- g /= 255;
- b /= 255;
- let h;
- const min_ = min$3(r, g, b);
- const i = (r + g + b) / 3;
- const s = i > 0 ? 1 - min_ / i : 0;
- if (s === 0) {
- h = NaN;
- } else {
- h = (r - g + (r - b)) / 2;
- h /= sqrt$3((r - g) * (r - g) + (r - b) * (g - b));
- h = acos(h);
- if (b > g) {
- h = TWOPI$1 - h;
- }
- h /= TWOPI$1;
- }
- return [h * 360, s, i];
- };
-
- Color$2.prototype.hsi = function () {
- return rgb2hsi(this._rgb);
- };
-
- const hsi$1 = (...args) => new Color$2(...args, 'hsi');
- chroma$1.hsi = hsi$1;
-
- input$1.format.hsi = hsi2rgb;
-
- input$1.autodetect.push({
- p: 2,
- test: (...args) => {
- args = unpack(args, 'hsi');
- if (type(args) === 'array' && args.length === 3) {
- return 'hsi';
- }
- }
- });
-
- const hsl2rgb$1 = (...args) => {
- args = unpack(args, 'hsl');
- const [h, s, l] = args;
- let r, g, b;
- if (s === 0) {
- r = g = b = l * 255;
- } else {
- const t3 = [0, 0, 0];
- const c = [0, 0, 0];
- const t2 = l < 0.5 ? l * (1 + s) : l + s - l * s;
- const t1 = 2 * l - t2;
- const h_ = h / 360;
- t3[0] = h_ + 1 / 3;
- t3[1] = h_;
- t3[2] = h_ - 1 / 3;
- for (let i = 0; i < 3; i++) {
- if (t3[i] < 0) t3[i] += 1;
- if (t3[i] > 1) t3[i] -= 1;
- if (6 * t3[i] < 1) c[i] = t1 + (t2 - t1) * 6 * t3[i];
- else if (2 * t3[i] < 1) c[i] = t2;
- else if (3 * t3[i] < 2) c[i] = t1 + (t2 - t1) * (2 / 3 - t3[i]) * 6;
- else c[i] = t1;
- }
- [r, g, b] = [c[0] * 255, c[1] * 255, c[2] * 255];
- }
- if (args.length > 3) {
- // keep alpha channel
- return [r, g, b, args[3]];
- }
- return [r, g, b, 1];
- };
-
- /*
- * supported arguments:
- * - rgb2hsl(r,g,b)
- * - rgb2hsl(r,g,b,a)
- * - rgb2hsl([r,g,b])
- * - rgb2hsl([r,g,b,a])
- * - rgb2hsl({r,g,b,a})
- */
- const rgb2hsl$2 = (...args) => {
- args = unpack(args, 'rgba');
- let [r, g, b] = args;
-
- r /= 255;
- g /= 255;
- b /= 255;
-
- const minRgb = min$4(r, g, b);
- const maxRgb = max$4(r, g, b);
-
- const l = (maxRgb + minRgb) / 2;
- let s, h;
-
- if (maxRgb === minRgb) {
- s = 0;
- h = Number.NaN;
- } else {
- s =
- l < 0.5
- ? (maxRgb - minRgb) / (maxRgb + minRgb)
- : (maxRgb - minRgb) / (2 - maxRgb - minRgb);
- }
-
- if (r == maxRgb) h = (g - b) / (maxRgb - minRgb);
- else if (g == maxRgb) h = 2 + (b - r) / (maxRgb - minRgb);
- else if (b == maxRgb) h = 4 + (r - g) / (maxRgb - minRgb);
-
- h *= 60;
- if (h < 0) h += 360;
- if (args.length > 3 && args[3] !== undefined) return [h, s, l, args[3]];
- return [h, s, l];
- };
-
- Color$2.prototype.hsl = function () {
- return rgb2hsl$2(this._rgb);
- };
-
- const hsl$1 = (...args) => new Color$2(...args, 'hsl');
- chroma$1.hsl = hsl$1;
-
- input$1.format.hsl = hsl2rgb$1;
-
- input$1.autodetect.push({
- p: 2,
- test: (...args) => {
- args = unpack(args, 'hsl');
- if (type(args) === 'array' && args.length === 3) {
- return 'hsl';
- }
- }
- });
-
- const { floor: floor$2 } = Math;
-
- const hsv2rgb = (...args) => {
- args = unpack(args, 'hsv');
- let [h, s, v] = args;
- let r, g, b;
- v *= 255;
- if (s === 0) {
- r = g = b = v;
- } else {
- if (h === 360) h = 0;
- if (h > 360) h -= 360;
- if (h < 0) h += 360;
- h /= 60;
-
- const i = floor$2(h);
- const f = h - i;
- const p = v * (1 - s);
- const q = v * (1 - s * f);
- const t = v * (1 - s * (1 - f));
-
- switch (i) {
- case 0:
- [r, g, b] = [v, t, p];
- break;
- case 1:
- [r, g, b] = [q, v, p];
- break;
- case 2:
- [r, g, b] = [p, v, t];
- break;
- case 3:
- [r, g, b] = [p, q, v];
- break;
- case 4:
- [r, g, b] = [t, p, v];
- break;
- case 5:
- [r, g, b] = [v, p, q];
- break;
- }
- }
- return [r, g, b, args.length > 3 ? args[3] : 1];
- };
-
- const { min: min$2, max: max$3 } = Math;
-
- /*
- * supported arguments:
- * - rgb2hsv(r,g,b)
- * - rgb2hsv([r,g,b])
- * - rgb2hsv({r,g,b})
- */
- const rgb2hsl$1 = (...args) => {
- args = unpack(args, 'rgb');
- let [r, g, b] = args;
- const min_ = min$2(r, g, b);
- const max_ = max$3(r, g, b);
- const delta = max_ - min_;
- let h, s, v;
- v = max_ / 255.0;
- if (max_ === 0) {
- h = Number.NaN;
- s = 0;
- } else {
- s = delta / max_;
- if (r === max_) h = (g - b) / delta;
- if (g === max_) h = 2 + (b - r) / delta;
- if (b === max_) h = 4 + (r - g) / delta;
- h *= 60;
- if (h < 0) h += 360;
- }
- return [h, s, v];
- };
-
- Color$2.prototype.hsv = function () {
- return rgb2hsl$1(this._rgb);
- };
-
- const hsv$1 = (...args) => new Color$2(...args, 'hsv');
- chroma$1.hsv = hsv$1;
-
- input$1.format.hsv = hsv2rgb;
-
- input$1.autodetect.push({
- p: 2,
- test: (...args) => {
- args = unpack(args, 'hsv');
- if (type(args) === 'array' && args.length === 3) {
- return 'hsv';
- }
- }
- });
-
- // from https://www.w3.org/TR/css-color-4/multiply-matrices.js
- function multiplyMatrices(A, B) {
- let m = A.length;
-
- if (!Array.isArray(A[0])) {
- // A is vector, convert to [[a, b, c, ...]]
- A = [A];
- }
-
- if (!Array.isArray(B[0])) {
- // B is vector, convert to [[a], [b], [c], ...]]
- B = B.map((x) => [x]);
- }
-
- let p = B[0].length;
- let B_cols = B[0].map((_, i) => B.map((x) => x[i])); // transpose B
- let product = A.map((row) =>
- B_cols.map((col) => {
- if (!Array.isArray(row)) {
- return col.reduce((a, c) => a + c * row, 0);
- }
-
- return row.reduce((a, c, i) => a + c * (col[i] || 0), 0);
- })
- );
-
- if (m === 1) {
- product = product[0]; // Avoid [[a, b, c, ...]]
- }
-
- if (p === 1) {
- return product.map((x) => x[0]); // Avoid [[a], [b], [c], ...]]
- }
-
- return product;
- }
-
- const oklab2rgb$1 = (...args) => {
- args = unpack(args, 'lab');
- const [L, a, b, ...rest] = args;
- const [X, Y, Z] = OKLab_to_XYZ$1([L, a, b]);
- const [r, g, b_] = xyz2rgb(X, Y, Z);
- return [r, g, b_, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
- };
-
- // from https://www.w3.org/TR/css-color-4/#color-conversion-code
- function OKLab_to_XYZ$1(OKLab) {
- // Given OKLab, convert to XYZ relative to D65
- var LMStoXYZ = [
- [1.2268798758459243, -0.5578149944602171, 0.2813910456659647],
- [-0.0405757452148008, 1.112286803280317, -0.0717110580655164],
- [-0.0763729366746601, -0.4214933324022432, 1.5869240198367816]
- ];
- var OKLabtoLMS = [
- [1.0, 0.3963377773761749, 0.2158037573099136],
- [1.0, -0.1055613458156586, -0.0638541728258133],
- [1.0, -0.0894841775298119, -1.2914855480194092]
- ];
-
- var LMSnl = multiplyMatrices(OKLabtoLMS, OKLab);
- return multiplyMatrices(
- LMStoXYZ,
- LMSnl.map((c) => c ** 3)
- );
- }
-
- const rgb2oklab$1 = (...args) => {
- const [r, g, b, ...rest] = unpack(args, 'rgb');
- const xyz = rgb2xyz(r, g, b);
- const oklab = XYZ_to_OKLab$1(xyz);
- return [...oklab, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
- };
-
- // from https://www.w3.org/TR/css-color-4/#color-conversion-code
- function XYZ_to_OKLab$1(XYZ) {
- // Given XYZ relative to D65, convert to OKLab
- 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 LMS = multiplyMatrices(XYZtoLMS, XYZ);
- // JavaScript Math.cbrt returns a sign-matched cube root
- // beware if porting to other languages
- // especially if tempted to use a general power function
- return multiplyMatrices(
- LMStoOKLab,
- LMS.map((c) => Math.cbrt(c))
- );
- // L in range [0,1]. For use in CSS, multiply by 100 and add a percent
- }
-
- Color$2.prototype.oklab = function () {
- return rgb2oklab$1(this._rgb);
- };
-
- const oklab$1 = (...args) => new Color$2(...args, 'oklab');
- Object.assign(chroma$1, { oklab: oklab$1 });
-
- input$1.format.oklab = oklab2rgb$1;
-
- input$1.autodetect.push({
- p: 2,
- test: (...args) => {
- args = unpack(args, 'oklab');
- if (type(args) === 'array' && args.length === 3) {
- return 'oklab';
- }
- }
- });
-
- const { pow: pow$7, sqrt: sqrt$2, PI: PI$1, cos: cos$3, sin: sin$3, atan2: atan2$2 } = Math;
-
- var average = (colors, mode = 'lrgb', weights = null) => {
- const l = colors.length;
- if (!weights) weights = Array.from(new Array(l)).map(() => 1);
- // normalize weights
- const k =
- l /
- weights.reduce(function (a, b) {
- return a + b;
- });
- weights.forEach((w, i) => {
- weights[i] *= k;
- });
- // convert colors to Color objects
- colors = colors.map((c) => new Color$1(c));
- if (mode === 'lrgb') {
- return _average_lrgb(colors, weights);
- }
- const first = colors.shift();
- const xyz = first.get(mode);
- const cnt = [];
- let dx = 0;
- let dy = 0;
- // initial color
- for (let i = 0; i < xyz.length; i++) {
- xyz[i] = (xyz[i] || 0) * weights[0];
- cnt.push(isNaN(xyz[i]) ? 0 : weights[0]);
- if (mode.charAt(i) === 'h' && !isNaN(xyz[i])) {
- const A = (xyz[i] / 180) * PI$1;
- dx += cos$3(A) * weights[0];
- dy += sin$3(A) * weights[0];
- }
- }
-
- let alpha = first.alpha() * weights[0];
- colors.forEach((c, ci) => {
- const xyz2 = c.get(mode);
- alpha += c.alpha() * weights[ci + 1];
- for (let i = 0; i < xyz.length; i++) {
- if (!isNaN(xyz2[i])) {
- cnt[i] += weights[ci + 1];
- if (mode.charAt(i) === 'h') {
- const A = (xyz2[i] / 180) * PI$1;
- dx += cos$3(A) * weights[ci + 1];
- dy += sin$3(A) * weights[ci + 1];
- } else {
- xyz[i] += xyz2[i] * weights[ci + 1];
- }
- }
- }
- });
-
- for (let i = 0; i < xyz.length; i++) {
- if (mode.charAt(i) === 'h') {
- let A = (atan2$2(dy / cnt[i], dx / cnt[i]) / PI$1) * 180;
- while (A < 0) A += 360;
- while (A >= 360) A -= 360;
- xyz[i] = A;
- } else {
- xyz[i] = xyz[i] / cnt[i];
- }
- }
- alpha /= l;
- return new Color$1(xyz, mode).alpha(alpha > 0.99999 ? 1 : alpha, true);
- };
-
- const _average_lrgb = (colors, weights) => {
- const l = colors.length;
- const xyz = [0, 0, 0, 0];
- for (let i = 0; i < colors.length; i++) {
- const col = colors[i];
- const f = weights[i] / l;
- const rgb = col._rgb;
- xyz[0] += pow$7(rgb[0], 2) * f;
- xyz[1] += pow$7(rgb[1], 2) * f;
- xyz[2] += pow$7(rgb[2], 2) * f;
- xyz[3] += rgb[3] * f;
- }
- xyz[0] = sqrt$2(xyz[0]);
- xyz[1] = sqrt$2(xyz[1]);
- xyz[2] = sqrt$2(xyz[2]);
- if (xyz[3] > 0.9999999) xyz[3] = 1;
- return new Color$1(clip_rgb(xyz));
- };
-
- const chroma = (...args) => {
- return new Color$3(...args);
- };
-
- chroma.version = version;
-
- // minimal multi-purpose interface
-
-
- const { pow: pow$6 } = Math;
-
- function scale$2 (colors) {
- // constructor
- let _mode = 'rgb';
- let _nacol = chroma('#ccc');
- let _spread = 0;
- // const _fixed = false;
- let _domain = [0, 1];
- let _pos = [];
- let _padding = [0, 0];
- let _classes = false;
- let _colors = [];
- let _out = false;
- let _min = 0;
- let _max = 1;
- let _correctLightness = false;
- let _colorCache = {};
- let _useCache = true;
- let _gamma = 1;
-
- // private methods
-
- const setColors = function (colors) {
- colors = colors || ['#fff', '#000'];
- if (
- colors &&
- type(colors) === 'string' &&
- chroma.brewer &&
- chroma.brewer[colors.toLowerCase()]
- ) {
- colors = chroma.brewer[colors.toLowerCase()];
- }
- if (type(colors) === 'array') {
- // handle single color
- if (colors.length === 1) {
- colors = [colors[0], colors[0]];
- }
- // make a copy of the colors
- colors = colors.slice(0);
- // convert to chroma classes
- for (let c = 0; c < colors.length; c++) {
- colors[c] = chroma(colors[c]);
- }
- // auto-fill color position
- _pos.length = 0;
- for (let c = 0; c < colors.length; c++) {
- _pos.push(c / (colors.length - 1));
- }
- }
- resetCache();
- return (_colors = colors);
- };
-
- const getClass = function (value) {
- if (_classes != null) {
- const n = _classes.length - 1;
- let i = 0;
- while (i < n && value >= _classes[i]) {
- i++;
- }
- return i - 1;
- }
- return 0;
- };
-
- let tMapLightness = (t) => t;
- let tMapDomain = (t) => t;
-
- // const classifyValue = function(value) {
- // let val = value;
- // if (_classes.length > 2) {
- // const n = _classes.length-1;
- // const i = getClass(value);
- // const minc = _classes[0] + ((_classes[1]-_classes[0]) * (0 + (_spread * 0.5))); // center of 1st class
- // const maxc = _classes[n-1] + ((_classes[n]-_classes[n-1]) * (1 - (_spread * 0.5))); // center of last class
- // val = _min + ((((_classes[i] + ((_classes[i+1] - _classes[i]) * 0.5)) - minc) / (maxc-minc)) * (_max - _min));
- // }
- // return val;
- // };
-
- const getColor = function (val, bypassMap) {
- let col, t;
- if (bypassMap == null) {
- bypassMap = false;
- }
- if (isNaN(val) || val === null) {
- return _nacol;
- }
- if (!bypassMap) {
- if (_classes && _classes.length > 2) {
- // find the class
- const c = getClass(val);
- t = c / (_classes.length - 2);
- } else if (_max !== _min) {
- // just interpolate between min/max
- t = (val - _min) / (_max - _min);
- } else {
- t = 1;
- }
- } else {
- t = val;
- }
-
- // domain map
- t = tMapDomain(t);
-
- if (!bypassMap) {
- t = tMapLightness(t); // lightness correction
- }
-
- if (_gamma !== 1) {
- t = pow$6(t, _gamma);
- }
-
- t = _padding[0] + t * (1 - _padding[0] - _padding[1]);
-
- t = limit$1(t, 0, 1);
-
- const k = Math.floor(t * 10000);
-
- if (_useCache && _colorCache[k]) {
- col = _colorCache[k];
- } else {
- if (type(_colors) === 'array') {
- //for i in [0.._pos.length-1]
- for (let i = 0; i < _pos.length; i++) {
- const p = _pos[i];
- if (t <= p) {
- col = _colors[i];
- break;
- }
- if (t >= p && i === _pos.length - 1) {
- col = _colors[i];
- break;
- }
- if (t > p && t < _pos[i + 1]) {
- t = (t - p) / (_pos[i + 1] - p);
- col = chroma.interpolate(
- _colors[i],
- _colors[i + 1],
- t,
- _mode
- );
- break;
- }
- }
- } else if (type(_colors) === 'function') {
- col = _colors(t);
- }
- if (_useCache) {
- _colorCache[k] = col;
- }
- }
- return col;
- };
-
- var resetCache = () => (_colorCache = {});
-
- setColors(colors);
-
- // public interface
-
- const f = function (v) {
- const c = chroma(getColor(v));
- if (_out && c[_out]) {
- return c[_out]();
- } else {
- return c;
- }
- };
-
- f.classes = function (classes) {
- if (classes != null) {
- if (type(classes) === 'array') {
- _classes = classes;
- _domain = [classes[0], classes[classes.length - 1]];
- } else {
- const d = chroma.analyze(_domain);
- if (classes === 0) {
- _classes = [d.min, d.max];
- } else {
- _classes = chroma.limits(d, 'e', classes);
- }
- }
- return f;
- }
- return _classes;
- };
-
- f.domain = function (domain) {
- if (!arguments.length) {
- return _domain;
- }
- _min = domain[0];
- _max = domain[domain.length - 1];
- _pos = [];
- const k = _colors.length;
- if (domain.length === k && _min !== _max) {
- // update positions
- for (let d of Array.from(domain)) {
- _pos.push((d - _min) / (_max - _min));
- }
- } else {
- for (let c = 0; c < k; c++) {
- _pos.push(c / (k - 1));
- }
- if (domain.length > 2) {
- // set domain map
- const tOut = domain.map((d, i) => i / (domain.length - 1));
- const tBreaks = domain.map((d) => (d - _min) / (_max - _min));
- if (!tBreaks.every((val, i) => tOut[i] === val)) {
- tMapDomain = (t) => {
- if (t <= 0 || t >= 1) return t;
- let i = 0;
- while (t >= tBreaks[i + 1]) i++;
- const f =
- (t - tBreaks[i]) / (tBreaks[i + 1] - tBreaks[i]);
- const out = tOut[i] + f * (tOut[i + 1] - tOut[i]);
- return out;
- };
- }
- }
- }
- _domain = [_min, _max];
- return f;
- };
-
- f.mode = function (_m) {
- if (!arguments.length) {
- return _mode;
- }
- _mode = _m;
- resetCache();
- return f;
- };
-
- f.range = function (colors, _pos) {
- setColors(colors);
- return f;
- };
-
- f.out = function (_o) {
- _out = _o;
- return f;
- };
-
- f.spread = function (val) {
- if (!arguments.length) {
- return _spread;
- }
- _spread = val;
- return f;
- };
-
- f.correctLightness = function (v) {
- if (v == null) {
- v = true;
- }
- _correctLightness = v;
- resetCache();
- if (_correctLightness) {
- tMapLightness = function (t) {
- const L0 = getColor(0, true).lab()[0];
- const L1 = getColor(1, true).lab()[0];
- const pol = L0 > L1;
- let L_actual = getColor(t, true).lab()[0];
- const L_ideal = L0 + (L1 - L0) * t;
- let L_diff = L_actual - L_ideal;
- let t0 = 0;
- let t1 = 1;
- let max_iter = 20;
- while (Math.abs(L_diff) > 1e-2 && max_iter-- > 0) {
- (function () {
- if (pol) {
- L_diff *= -1;
- }
- if (L_diff < 0) {
- t0 = t;
- t += (t1 - t) * 0.5;
- } else {
- t1 = t;
- t += (t0 - t) * 0.5;
- }
- L_actual = getColor(t, true).lab()[0];
- return (L_diff = L_actual - L_ideal);
- })();
- }
- return t;
- };
- } else {
- tMapLightness = (t) => t;
- }
- return f;
- };
-
- f.padding = function (p) {
- if (p != null) {
- if (type(p) === 'number') {
- p = [p, p];
- }
- _padding = p;
- return f;
- } else {
- return _padding;
- }
- };
-
- f.colors = function (numColors, out) {
- // If no arguments are given, return the original colors that were provided
- if (arguments.length < 2) {
- out = 'hex';
- }
- let result = [];
-
- if (arguments.length === 0) {
- result = _colors.slice(0);
- } else if (numColors === 1) {
- result = [f(0.5)];
- } else if (numColors > 1) {
- const dm = _domain[0];
- const dd = _domain[1] - dm;
- result = __range__$2(0, numColors).map((i) =>
- f(dm + (i / (numColors - 1)) * dd)
- );
- } else {
- // returns all colors based on the defined classes
- colors = [];
- let samples = [];
- if (_classes && _classes.length > 2) {
- for (
- let i = 1, end = _classes.length, asc = 1 <= end;
- asc ? i < end : i > end;
- asc ? i++ : i--
- ) {
- samples.push((_classes[i - 1] + _classes[i]) * 0.5);
- }
- } else {
- samples = _domain;
- }
- result = samples.map((v) => f(v));
- }
-
- if (chroma[out]) {
- result = result.map((c) => c[out]());
- }
- return result;
- };
-
- f.cache = function (c) {
- if (c != null) {
- _useCache = c;
- return f;
- } else {
- return _useCache;
- }
- };
-
- f.gamma = function (g) {
- if (g != null) {
- _gamma = g;
- return f;
- } else {
- return _gamma;
- }
- };
-
- f.nodata = function (d) {
- if (d != null) {
- _nacol = chroma(d);
- return f;
- } else {
- return _nacol;
- }
- };
-
- return f;
- }
-
- function __range__$2(left, right, inclusive) {
- let range = [];
- let ascending = left < right;
- let end = right ;
- for (let i = left; ascending ? i < end : i > end; ascending ? i++ : i--) {
- range.push(i);
- }
- return range;
- }
-
- //
- // interpolates between a set of colors uzing a bezier spline
- //
-
-
- // nth row of the pascal triangle
- const binom_row = function (n) {
- let row = [1, 1];
- for (let i = 1; i < n; i++) {
- let newrow = [1];
- for (let j = 1; j <= row.length; j++) {
- newrow[j] = (row[j] || 0) + row[j - 1];
- }
- row = newrow;
- }
- return row;
- };
-
- const bezier = function (colors) {
- let I, lab0, lab1, lab2;
- colors = colors.map((c) => new Color$1(c));
- if (colors.length === 2) {
- // linear interpolation
- [lab0, lab1] = colors.map((c) => c.lab());
- I = function (t) {
- const lab = [0, 1, 2].map((i) => lab0[i] + t * (lab1[i] - lab0[i]));
- return new Color$1(lab, 'lab');
- };
- } else if (colors.length === 3) {
- // quadratic bezier interpolation
- [lab0, lab1, lab2] = colors.map((c) => c.lab());
- I = function (t) {
- const lab = [0, 1, 2].map(
- (i) =>
- (1 - t) * (1 - t) * lab0[i] +
- 2 * (1 - t) * t * lab1[i] +
- t * t * lab2[i]
- );
- return new Color$1(lab, 'lab');
- };
- } else if (colors.length === 4) {
- // cubic bezier interpolation
- let lab3;
- [lab0, lab1, lab2, lab3] = colors.map((c) => c.lab());
- I = function (t) {
- const lab = [0, 1, 2].map(
- (i) =>
- (1 - t) * (1 - t) * (1 - t) * lab0[i] +
- 3 * (1 - t) * (1 - t) * t * lab1[i] +
- 3 * (1 - t) * t * t * lab2[i] +
- t * t * t * lab3[i]
- );
- return new Color$1(lab, 'lab');
- };
- } else if (colors.length >= 5) {
- // general case (degree n bezier)
- let labs, row, n;
- labs = colors.map((c) => c.lab());
- n = colors.length - 1;
- row = binom_row(n);
- I = function (t) {
- const u = 1 - t;
- const lab = [0, 1, 2].map((i) =>
- labs.reduce(
- (sum, el, j) =>
- sum + row[j] * u ** (n - j) * t ** j * el[i],
- 0
- )
- );
- return new Color$1(lab, 'lab');
- };
- } else {
- throw new RangeError('No point in running bezier with only one color.');
- }
- return I;
- };
-
- var bezier$1 = (colors) => {
- const f = bezier(colors);
- f.scale = () => scale$2(f);
- return f;
- };
-
- const { round: round$6 } = Math;
-
- Color$2.prototype.rgb = function (rnd = true) {
- if (rnd === false) return this._rgb.slice(0, 3);
- return this._rgb.slice(0, 3).map(round$6);
- };
-
- Color$2.prototype.rgba = function (rnd = true) {
- return this._rgb.slice(0, 4).map((v, i) => {
- return i < 3 ? (rnd === false ? v : round$6(v)) : v;
- });
- };
-
- const rgb$1 = (...args) => new Color$2(...args, 'rgb');
- Object.assign(chroma$1, { rgb: rgb$1 });
-
- input$1.format.rgb = (...args) => {
- const rgba = unpack(args, 'rgba');
- if (rgba[3] === undefined) rgba[3] = 1;
- return rgba;
- };
-
- input$1.autodetect.push({
- p: 3,
- test: (...args) => {
- args = unpack(args, 'rgba');
- if (
- type(args) === 'array' &&
- (args.length === 3 ||
- (args.length === 4 &&
- type(args[3]) == 'number' &&
- args[3] >= 0 &&
- args[3] <= 1))
- ) {
- return 'rgb';
- }
- }
- });
-
- /*
- * interpolates between a set of colors uzing a bezier spline
- * blend mode formulas taken from https://web.archive.org/web/20180110014946/http://www.venture-ware.com/kevin/coding/lets-learn-math-photoshop-blend-modes/
- */
-
-
- const blend = (bottom, top, mode) => {
- if (!blend[mode]) {
- throw new Error('unknown blend mode ' + mode);
- }
- return blend[mode](bottom, top);
- };
-
- const blend_f = (f) => (bottom, top) => {
- const c0 = chroma(top).rgb();
- const c1 = chroma(bottom).rgb();
- return chroma.rgb(f(c0, c1));
- };
-
- const each = (f) => (c0, c1) => {
- const out = [];
- out[0] = f(c0[0], c1[0]);
- out[1] = f(c0[1], c1[1]);
- out[2] = f(c0[2], c1[2]);
- return out;
- };
-
- const normal = (a) => a;
- const multiply = (a, b) => (a * b) / 255;
- const darken = (a, b) => (a > b ? b : a);
- const lighten = (a, b) => (a > b ? a : b);
- const screen = (a, b) => 255 * (1 - (1 - a / 255) * (1 - b / 255));
- const overlay = (a, b) =>
- b < 128 ? (2 * a * b) / 255 : 255 * (1 - 2 * (1 - a / 255) * (1 - b / 255));
- const burn = (a, b) => 255 * (1 - (1 - b / 255) / (a / 255));
- const dodge = (a, b) => {
- if (a === 255) return 255;
- a = (255 * (b / 255)) / (1 - a / 255);
- return a > 255 ? 255 : a;
- };
-
- // # add = (a,b) ->
- // # if (a + b > 255) then 255 else a + b
-
- blend.normal = blend_f(each(normal));
- blend.multiply = blend_f(each(multiply));
- blend.screen = blend_f(each(screen));
- blend.overlay = blend_f(each(overlay));
- blend.darken = blend_f(each(darken));
- blend.lighten = blend_f(each(lighten));
- blend.dodge = blend_f(each(dodge));
- blend.burn = blend_f(each(burn));
-
- // cubehelix interpolation
- // based on D.A. Green "A colour scheme for the display of astronomical intensity images"
- // http://astron-soc.in/bulletin/11June/289392011.pdf
- const { pow: pow$5, sin: sin$2, cos: cos$2 } = Math;
-
- function cubehelix (
- start = 300,
- rotations = -1.5,
- hue = 1,
- gamma = 1,
- lightness = [0, 1]
- ) {
- let dh = 0,
- dl;
- if (type(lightness) === 'array') {
- dl = lightness[1] - lightness[0];
- } else {
- dl = 0;
- lightness = [lightness, lightness];
- }
- const f = function (fract) {
- const a = TWOPI * ((start + 120) / 360 + rotations * fract);
- const l = pow$5(lightness[0] + dl * fract, gamma);
- const h = dh !== 0 ? hue[0] + fract * dh : hue;
- const amp = (h * l * (1 - l)) / 2;
- const cos_a = cos$2(a);
- const sin_a = sin$2(a);
- const r = l + amp * (-0.14861 * cos_a + 1.78277 * sin_a);
- const g = l + amp * (-0.29227 * cos_a - 0.90649 * sin_a);
- const b = l + amp * (1.97294 * cos_a);
- return chroma(clip_rgb([r * 255, g * 255, b * 255, 1]));
- };
- f.start = function (s) {
- if (s == null) {
- return start;
- }
- start = s;
- return f;
- };
- f.rotations = function (r) {
- if (r == null) {
- return rotations;
- }
- rotations = r;
- return f;
- };
- f.gamma = function (g) {
- if (g == null) {
- return gamma;
- }
- gamma = g;
- return f;
- };
- f.hue = function (h) {
- if (h == null) {
- return hue;
- }
- hue = h;
- if (type(hue) === 'array') {
- dh = hue[1] - hue[0];
- if (dh === 0) {
- hue = hue[1];
- }
- } else {
- dh = 0;
- }
- return f;
- };
- f.lightness = function (h) {
- if (h == null) {
- return lightness;
- }
- if (type(h) === 'array') {
- lightness = h;
- dl = h[1] - h[0];
- } else {
- lightness = [h, h];
- dl = 0;
- }
- return f;
- };
- f.scale = () => chroma.scale(f);
- f.hue(hue);
- return f;
- }
-
- var mix = (col1, col2, f = 0.5, ...rest) => {
- let mode = rest[0] || 'lrgb';
- if (!interpolator[mode] && !rest.length) {
- // fall back to the first supported mode
- mode = Object.keys(interpolator)[0];
- }
- if (!interpolator[mode]) {
- throw new Error(`interpolation mode ${mode} is not defined`);
- }
- if (type(col1) !== 'object') col1 = new Color$1(col1);
- if (type(col2) !== 'object') col2 = new Color$1(col2);
- return interpolator[mode](col1, col2, f).alpha(
- col1.alpha() + f * (col2.alpha() - col1.alpha())
- );
- };
-
- const digits = '0123456789abcdef';
-
- const { floor: floor$1, random } = Math;
-
- var random$1 = () => {
- let code = '#';
- for (let i = 0; i < 6; i++) {
- code += digits.charAt(floor$1(random() * 16));
- }
- return new Color$1(code, 'hex');
- };
-
- // minimal multi-purpose interface
-
-
- const { pow: pow$4 } = Math;
-
- function scale$1 (colors) {
- // constructor
- let _mode = 'rgb';
- let _nacol = chroma('#ccc');
- let _spread = 0;
- // const _fixed = false;
- let _domain = [0, 1];
- let _pos = [];
- let _padding = [0, 0];
- let _classes = false;
- let _colors = [];
- let _out = false;
- let _min = 0;
- let _max = 1;
- let _correctLightness = false;
- let _colorCache = {};
- let _useCache = true;
- let _gamma = 1;
-
- // private methods
-
- const setColors = function (colors) {
- colors = colors || ['#fff', '#000'];
- if (
- colors &&
- type(colors) === 'string' &&
- chroma.brewer &&
- chroma.brewer[colors.toLowerCase()]
- ) {
- colors = chroma.brewer[colors.toLowerCase()];
- }
- if (type(colors) === 'array') {
- // handle single color
- if (colors.length === 1) {
- colors = [colors[0], colors[0]];
- }
- // make a copy of the colors
- colors = colors.slice(0);
- // convert to chroma classes
- for (let c = 0; c < colors.length; c++) {
- colors[c] = chroma(colors[c]);
- }
- // auto-fill color position
- _pos.length = 0;
- for (let c = 0; c < colors.length; c++) {
- _pos.push(c / (colors.length - 1));
- }
- }
- resetCache();
- return (_colors = colors);
- };
-
- const getClass = function (value) {
- if (_classes != null) {
- const n = _classes.length - 1;
- let i = 0;
- while (i < n && value >= _classes[i]) {
- i++;
- }
- return i - 1;
- }
- return 0;
- };
-
- let tMapLightness = (t) => t;
- let tMapDomain = (t) => t;
-
- // const classifyValue = function(value) {
- // let val = value;
- // if (_classes.length > 2) {
- // const n = _classes.length-1;
- // const i = getClass(value);
- // const minc = _classes[0] + ((_classes[1]-_classes[0]) * (0 + (_spread * 0.5))); // center of 1st class
- // const maxc = _classes[n-1] + ((_classes[n]-_classes[n-1]) * (1 - (_spread * 0.5))); // center of last class
- // val = _min + ((((_classes[i] + ((_classes[i+1] - _classes[i]) * 0.5)) - minc) / (maxc-minc)) * (_max - _min));
- // }
- // return val;
- // };
-
- const getColor = function (val, bypassMap) {
- let col, t;
- if (bypassMap == null) {
- bypassMap = false;
- }
- if (isNaN(val) || val === null) {
- return _nacol;
- }
- if (!bypassMap) {
- if (_classes && _classes.length > 2) {
- // find the class
- const c = getClass(val);
- t = c / (_classes.length - 2);
- } else if (_max !== _min) {
- // just interpolate between min/max
- t = (val - _min) / (_max - _min);
- } else {
- t = 1;
- }
- } else {
- t = val;
- }
-
- // domain map
- t = tMapDomain(t);
-
- if (!bypassMap) {
- t = tMapLightness(t); // lightness correction
- }
-
- if (_gamma !== 1) {
- t = pow$4(t, _gamma);
- }
-
- t = _padding[0] + t * (1 - _padding[0] - _padding[1]);
-
- t = limit$1(t, 0, 1);
-
- const k = Math.floor(t * 10000);
-
- if (_useCache && _colorCache[k]) {
- col = _colorCache[k];
- } else {
- if (type(_colors) === 'array') {
- //for i in [0.._pos.length-1]
- for (let i = 0; i < _pos.length; i++) {
- const p = _pos[i];
- if (t <= p) {
- col = _colors[i];
- break;
- }
- if (t >= p && i === _pos.length - 1) {
- col = _colors[i];
- break;
- }
- if (t > p && t < _pos[i + 1]) {
- t = (t - p) / (_pos[i + 1] - p);
- col = chroma.interpolate(
- _colors[i],
- _colors[i + 1],
- t,
- _mode
- );
- break;
- }
- }
- } else if (type(_colors) === 'function') {
- col = _colors(t);
- }
- if (_useCache) {
- _colorCache[k] = col;
- }
- }
- return col;
- };
-
- var resetCache = () => (_colorCache = {});
-
- setColors(colors);
-
- // public interface
-
- const f = function (v) {
- const c = chroma(getColor(v));
- if (_out && c[_out]) {
- return c[_out]();
- } else {
- return c;
- }
- };
-
- f.classes = function (classes) {
- if (classes != null) {
- if (type(classes) === 'array') {
- _classes = classes;
- _domain = [classes[0], classes[classes.length - 1]];
- } else {
- const d = chroma.analyze(_domain);
- if (classes === 0) {
- _classes = [d.min, d.max];
- } else {
- _classes = chroma.limits(d, 'e', classes);
- }
- }
- return f;
- }
- return _classes;
- };
-
- f.domain = function (domain) {
- if (!arguments.length) {
- return _domain;
- }
- _min = domain[0];
- _max = domain[domain.length - 1];
- _pos = [];
- const k = _colors.length;
- if (domain.length === k && _min !== _max) {
- // update positions
- for (let d of Array.from(domain)) {
- _pos.push((d - _min) / (_max - _min));
- }
- } else {
- for (let c = 0; c < k; c++) {
- _pos.push(c / (k - 1));
- }
- if (domain.length > 2) {
- // set domain map
- const tOut = domain.map((d, i) => i / (domain.length - 1));
- const tBreaks = domain.map((d) => (d - _min) / (_max - _min));
- if (!tBreaks.every((val, i) => tOut[i] === val)) {
- tMapDomain = (t) => {
- if (t <= 0 || t >= 1) return t;
- let i = 0;
- while (t >= tBreaks[i + 1]) i++;
- const f =
- (t - tBreaks[i]) / (tBreaks[i + 1] - tBreaks[i]);
- const out = tOut[i] + f * (tOut[i + 1] - tOut[i]);
- return out;
- };
- }
- }
- }
- _domain = [_min, _max];
- return f;
- };
-
- f.mode = function (_m) {
- if (!arguments.length) {
- return _mode;
- }
- _mode = _m;
- resetCache();
- return f;
- };
-
- f.range = function (colors, _pos) {
- setColors(colors);
- return f;
- };
-
- f.out = function (_o) {
- _out = _o;
- return f;
- };
-
- f.spread = function (val) {
- if (!arguments.length) {
- return _spread;
- }
- _spread = val;
- return f;
- };
-
- f.correctLightness = function (v) {
- if (v == null) {
- v = true;
- }
- _correctLightness = v;
- resetCache();
- if (_correctLightness) {
- tMapLightness = function (t) {
- const L0 = getColor(0, true).lab()[0];
- const L1 = getColor(1, true).lab()[0];
- const pol = L0 > L1;
- let L_actual = getColor(t, true).lab()[0];
- const L_ideal = L0 + (L1 - L0) * t;
- let L_diff = L_actual - L_ideal;
- let t0 = 0;
- let t1 = 1;
- let max_iter = 20;
- while (Math.abs(L_diff) > 1e-2 && max_iter-- > 0) {
- (function () {
- if (pol) {
- L_diff *= -1;
- }
- if (L_diff < 0) {
- t0 = t;
- t += (t1 - t) * 0.5;
- } else {
- t1 = t;
- t += (t0 - t) * 0.5;
- }
- L_actual = getColor(t, true).lab()[0];
- return (L_diff = L_actual - L_ideal);
- })();
- }
- return t;
- };
- } else {
- tMapLightness = (t) => t;
- }
- return f;
- };
-
- f.padding = function (p) {
- if (p != null) {
- if (type(p) === 'number') {
- p = [p, p];
- }
- _padding = p;
- return f;
- } else {
- return _padding;
- }
- };
-
- f.colors = function (numColors, out) {
- // If no arguments are given, return the original colors that were provided
- if (arguments.length < 2) {
- out = 'hex';
- }
- let result = [];
-
- if (arguments.length === 0) {
- result = _colors.slice(0);
- } else if (numColors === 1) {
- result = [f(0.5)];
- } else if (numColors > 1) {
- const dm = _domain[0];
- const dd = _domain[1] - dm;
- result = __range__$1(0, numColors).map((i) =>
- f(dm + (i / (numColors - 1)) * dd)
- );
- } else {
- // returns all colors based on the defined classes
- colors = [];
- let samples = [];
- if (_classes && _classes.length > 2) {
- for (
- let i = 1, end = _classes.length, asc = 1 <= end;
- asc ? i < end : i > end;
- asc ? i++ : i--
- ) {
- samples.push((_classes[i - 1] + _classes[i]) * 0.5);
- }
- } else {
- samples = _domain;
- }
- result = samples.map((v) => f(v));
- }
-
- if (chroma[out]) {
- result = result.map((c) => c[out]());
- }
- return result;
- };
-
- f.cache = function (c) {
- if (c != null) {
- _useCache = c;
- return f;
- } else {
- return _useCache;
- }
- };
-
- f.gamma = function (g) {
- if (g != null) {
- _gamma = g;
- return f;
- } else {
- return _gamma;
- }
- };
-
- f.nodata = function (d) {
- if (d != null) {
- _nacol = chroma(d);
- return f;
- } else {
- return _nacol;
- }
- };
-
- return f;
- }
-
- function __range__$1(left, right, inclusive) {
- let range = [];
- let ascending = left < right;
- let end = right ;
- for (let i = left; ascending ? i < end : i > end; ascending ? i++ : i--) {
- range.push(i);
- }
- return range;
- }
-
- const { log: log$1, pow: pow$3, floor, abs: abs$1 } = Math;
-
- function analyze(data, key = null) {
- const r = {
- min: Number.MAX_VALUE,
- max: Number.MAX_VALUE * -1,
- sum: 0,
- values: [],
- count: 0
- };
- if (type(data) === 'object') {
- data = Object.values(data);
- }
- data.forEach((val) => {
- if (key && type(val) === 'object') val = val[key];
- if (val !== undefined && val !== null && !isNaN(val)) {
- r.values.push(val);
- r.sum += val;
- if (val < r.min) r.min = val;
- if (val > r.max) r.max = val;
- r.count += 1;
- }
- });
-
- r.domain = [r.min, r.max];
-
- r.limits = (mode, num) => limits(r, mode, num);
-
- return r;
- }
-
- function limits(data, mode = 'equal', num = 7) {
- if (type(data) == 'array') {
- data = analyze(data);
- }
- const { min, max } = data;
- const values = data.values.sort((a, b) => a - b);
-
- if (num === 1) {
- return [min, max];
- }
-
- const limits = [];
-
- if (mode.substr(0, 1) === 'c') {
- // continuous
- limits.push(min);
- limits.push(max);
- }
-
- if (mode.substr(0, 1) === 'e') {
- // equal interval
- limits.push(min);
- for (let i = 1; i < num; i++) {
- limits.push(min + (i / num) * (max - min));
- }
- limits.push(max);
- } else if (mode.substr(0, 1) === 'l') {
- // log scale
- if (min <= 0) {
- throw new Error(
- 'Logarithmic scales are only possible for values > 0'
- );
- }
- const min_log = Math.LOG10E * log$1(min);
- const max_log = Math.LOG10E * log$1(max);
- limits.push(min);
- for (let i = 1; i < num; i++) {
- limits.push(pow$3(10, min_log + (i / num) * (max_log - min_log)));
- }
- limits.push(max);
- } else if (mode.substr(0, 1) === 'q') {
- // quantile scale
- limits.push(min);
- for (let i = 1; i < num; i++) {
- const p = ((values.length - 1) * i) / num;
- const pb = floor(p);
- if (pb === p) {
- limits.push(values[pb]);
- } else {
- // p > pb
- const pr = p - pb;
- limits.push(values[pb] * (1 - pr) + values[pb + 1] * pr);
- }
- }
- limits.push(max);
- } else if (mode.substr(0, 1) === 'k') {
- // k-means clustering
- /*
- implementation based on
- http://code.google.com/p/figue/source/browse/trunk/figue.js#336
- simplified for 1-d input values
- */
- let cluster;
- const n = values.length;
- const assignments = new Array(n);
- const clusterSizes = new Array(num);
- let repeat = true;
- let nb_iters = 0;
- let centroids = null;
-
- // get seed values
- centroids = [];
- centroids.push(min);
- for (let i = 1; i < num; i++) {
- centroids.push(min + (i / num) * (max - min));
- }
- centroids.push(max);
-
- while (repeat) {
- // assignment step
- for (let j = 0; j < num; j++) {
- clusterSizes[j] = 0;
- }
- for (let i = 0; i < n; i++) {
- const value = values[i];
- let mindist = Number.MAX_VALUE;
- let best;
- for (let j = 0; j < num; j++) {
- const dist = abs$1(centroids[j] - value);
- if (dist < mindist) {
- mindist = dist;
- best = j;
- }
- clusterSizes[best]++;
- assignments[i] = best;
- }
- }
-
- // update centroids step
- const newCentroids = new Array(num);
- for (let j = 0; j < num; j++) {
- newCentroids[j] = null;
- }
- for (let i = 0; i < n; i++) {
- cluster = assignments[i];
- if (newCentroids[cluster] === null) {
- newCentroids[cluster] = values[i];
- } else {
- newCentroids[cluster] += values[i];
- }
- }
- for (let j = 0; j < num; j++) {
- newCentroids[j] *= 1 / clusterSizes[j];
- }
-
- // check convergence
- repeat = false;
- for (let j = 0; j < num; j++) {
- if (newCentroids[j] !== centroids[j]) {
- repeat = true;
- break;
- }
- }
-
- centroids = newCentroids;
- nb_iters++;
-
- if (nb_iters > 200) {
- repeat = false;
- }
- }
-
- // finished k-means clustering
- // the next part is borrowed from gabrielflor.it
- const kClusters = {};
- for (let j = 0; j < num; j++) {
- kClusters[j] = [];
- }
- for (let i = 0; i < n; i++) {
- cluster = assignments[i];
- kClusters[cluster].push(values[i]);
- }
- let tmpKMeansBreaks = [];
- for (let j = 0; j < num; j++) {
- tmpKMeansBreaks.push(kClusters[j][0]);
- tmpKMeansBreaks.push(kClusters[j][kClusters[j].length - 1]);
- }
- tmpKMeansBreaks = tmpKMeansBreaks.sort((a, b) => a - b);
- limits.push(tmpKMeansBreaks[0]);
- for (let i = 1; i < tmpKMeansBreaks.length; i += 2) {
- const v = tmpKMeansBreaks[i];
- if (!isNaN(v) && limits.indexOf(v) === -1) {
- limits.push(v);
- }
- }
- }
- return limits;
- }
-
- const { pow: pow$2 } = Math;
-
- const EPS = 1e-7;
- const MAX_ITER = 20;
-
- Color$1.prototype.luminance = function (lum, mode = 'rgb') {
- if (lum !== undefined && type(lum) === 'number') {
- if (lum === 0) {
- // return pure black
- return new Color$1([0, 0, 0, this._rgb[3]], 'rgb');
- }
- if (lum === 1) {
- // return pure white
- return new Color$1([255, 255, 255, this._rgb[3]], 'rgb');
- }
- // compute new color using...
- let cur_lum = this.luminance();
- let max_iter = MAX_ITER;
-
- const test = (low, high) => {
- const mid = low.interpolate(high, 0.5, mode);
- const lm = mid.luminance();
- if (Math.abs(lum - lm) < EPS || !max_iter--) {
- // close enough
- return mid;
- }
- return lm > lum ? test(low, mid) : test(mid, high);
- };
-
- const rgb = (
- cur_lum > lum
- ? test(new Color$1([0, 0, 0]), this)
- : test(this, new Color$1([255, 255, 255]))
- ).rgb();
- return new Color$1([...rgb, this._rgb[3]]);
- }
- return rgb2luminance(...this._rgb.slice(0, 3));
- };
-
- const rgb2luminance = (r, g, b) => {
- // relative luminance
- // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
- r = luminance_x(r);
- g = luminance_x(g);
- b = luminance_x(b);
- return 0.2126 * r + 0.7152 * g + 0.0722 * b;
- };
-
- const luminance_x = (x) => {
- x /= 255;
- return x <= 0.03928 ? x / 12.92 : pow$2((x + 0.055) / 1.055, 2.4);
- };
-
- var contrast = (a, b) => {
- // WCAG contrast ratio
- // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
- a = new Color$1(a);
- b = new Color$1(b);
- const l1 = a.luminance();
- const l2 = b.luminance();
- return l1 > l2 ? (l1 + 0.05) / (l2 + 0.05) : (l2 + 0.05) / (l1 + 0.05);
- };
-
- /**
- * @license
- *
- * The APCA contrast prediction algorithm is based of the formulas published
- * in the APCA-1.0.98G specification by Myndex. The specification is available at:
- * https://raw.githubusercontent.com/Myndex/apca-w3/master/images/APCAw3_0.1.17_APCA0.0.98G.svg
- *
- * Note that the APCA implementation is still beta, so please update to
- * future versions of chroma.js when they become available.
- *
- * You can read more about the APCA Readability Criterion at
- * https://readtech.org/ARC/
- */
-
- // constants
- const W_offset = 0.027;
- const P_in = 0.0005;
- const P_out = 0.1;
- const R_scale = 1.14;
- const B_threshold = 0.022;
- const B_exp = 1.414;
-
- var contrastAPCA = (text, bg) => {
- // parse input colors
- text = new Color$1(text);
- bg = new Color$1(bg);
- // if text color has alpha, blend against background
- if (text.alpha() < 1) {
- text = mix$1(bg, text, text.alpha(), 'rgb');
- }
- const l_text = lum(...text.rgb());
- const l_bg = lum(...bg.rgb());
-
- // soft clamp black levels
- const Y_text =
- l_text >= B_threshold
- ? l_text
- : l_text + Math.pow(B_threshold - l_text, B_exp);
- const Y_bg =
- l_bg >= B_threshold ? l_bg : l_bg + Math.pow(B_threshold - l_bg, B_exp);
-
- // normal polarity (dark text on light background)
- const S_norm = Math.pow(Y_bg, 0.56) - Math.pow(Y_text, 0.57);
- // reverse polarity (light text on dark background)
- const S_rev = Math.pow(Y_bg, 0.65) - Math.pow(Y_text, 0.62);
- // clamp noise then scale
- const C =
- Math.abs(Y_bg - Y_text) < P_in
- ? 0
- : Y_text < Y_bg
- ? S_norm * R_scale
- : S_rev * R_scale;
- // clamp minimum contrast then offset
- const S_apc = Math.abs(C) < P_out ? 0 : C > 0 ? C - W_offset : C + W_offset;
- // scale to 100
- return S_apc * 100;
- };
-
- function lum(r, g, b) {
- return (
- 0.2126729 * Math.pow(r / 255, 2.4) +
- 0.7151522 * Math.pow(g / 255, 2.4) +
- 0.072175 * Math.pow(b / 255, 2.4)
- );
- }
-
- const { sqrt: sqrt$1, pow: pow$1, min: min$1, max: max$2, atan2: atan2$1, abs, cos: cos$1, sin: sin$1, exp, PI } = Math;
-
- function deltaE (a, b, Kl = 1, Kc = 1, Kh = 1) {
- // Delta E (CIE 2000)
- // see http://www.brucelindbloom.com/index.html?Eqn_DeltaE_CIE2000.html
- var rad2deg = function (rad) {
- return (360 * rad) / (2 * PI);
- };
- var deg2rad = function (deg) {
- return (2 * PI * deg) / 360;
- };
- a = new Color$1(a);
- b = new Color$1(b);
- const [L1, a1, b1] = Array.from(a.lab());
- const [L2, a2, b2] = Array.from(b.lab());
- const avgL = (L1 + L2) / 2;
- const C1 = sqrt$1(pow$1(a1, 2) + pow$1(b1, 2));
- const C2 = sqrt$1(pow$1(a2, 2) + pow$1(b2, 2));
- const avgC = (C1 + C2) / 2;
- const G = 0.5 * (1 - sqrt$1(pow$1(avgC, 7) / (pow$1(avgC, 7) + pow$1(25, 7))));
- const a1p = a1 * (1 + G);
- const a2p = a2 * (1 + G);
- const C1p = sqrt$1(pow$1(a1p, 2) + pow$1(b1, 2));
- const C2p = sqrt$1(pow$1(a2p, 2) + pow$1(b2, 2));
- const avgCp = (C1p + C2p) / 2;
- const arctan1 = rad2deg(atan2$1(b1, a1p));
- const arctan2 = rad2deg(atan2$1(b2, a2p));
- const h1p = arctan1 >= 0 ? arctan1 : arctan1 + 360;
- const h2p = arctan2 >= 0 ? arctan2 : arctan2 + 360;
- const avgHp =
- abs(h1p - h2p) > 180 ? (h1p + h2p + 360) / 2 : (h1p + h2p) / 2;
- const T =
- 1 -
- 0.17 * cos$1(deg2rad(avgHp - 30)) +
- 0.24 * cos$1(deg2rad(2 * avgHp)) +
- 0.32 * cos$1(deg2rad(3 * avgHp + 6)) -
- 0.2 * cos$1(deg2rad(4 * avgHp - 63));
- let deltaHp = h2p - h1p;
- deltaHp =
- abs(deltaHp) <= 180
- ? deltaHp
- : h2p <= h1p
- ? deltaHp + 360
- : deltaHp - 360;
- deltaHp = 2 * sqrt$1(C1p * C2p) * sin$1(deg2rad(deltaHp) / 2);
- const deltaL = L2 - L1;
- const deltaCp = C2p - C1p;
- const sl = 1 + (0.015 * pow$1(avgL - 50, 2)) / sqrt$1(20 + pow$1(avgL - 50, 2));
- const sc = 1 + 0.045 * avgCp;
- const sh = 1 + 0.015 * avgCp * T;
- const deltaTheta = 30 * exp(-pow$1((avgHp - 275) / 25, 2));
- const Rc = 2 * sqrt$1(pow$1(avgCp, 7) / (pow$1(avgCp, 7) + pow$1(25, 7)));
- const Rt = -Rc * sin$1(2 * deg2rad(deltaTheta));
- const result = sqrt$1(
- pow$1(deltaL / (Kl * sl), 2) +
- pow$1(deltaCp / (Kc * sc), 2) +
- pow$1(deltaHp / (Kh * sh), 2) +
- Rt * (deltaCp / (Kc * sc)) * (deltaHp / (Kh * sh))
- );
- return max$2(0, min$1(100, result));
- }
-
- // simple Euclidean distance
- function distance (a, b, mode = 'lab') {
- // Delta E (CIE 1976)
- // see http://www.brucelindbloom.com/index.html?Equations.html
- a = new Color$1(a);
- b = new Color$1(b);
- const l1 = a.get(mode);
- const l2 = b.get(mode);
- let sum_sq = 0;
- for (let i in l1) {
- const d = (l1[i] || 0) - (l2[i] || 0);
- sum_sq += d * d;
- }
- return Math.sqrt(sum_sq);
- }
-
- var valid = (...args) => {
- try {
- new Color$1(...args);
- return true;
- // eslint-disable-next-line
- } catch (e) {
- return false;
- }
- };
-
- var input = {
- format: {},
- autodetect: []
- };
-
- // minimal multi-purpose interface
-
-
- const { pow } = Math;
-
- function scale (colors) {
- // constructor
- let _mode = 'rgb';
- let _nacol = chroma('#ccc');
- let _spread = 0;
- // const _fixed = false;
- let _domain = [0, 1];
- let _pos = [];
- let _padding = [0, 0];
- let _classes = false;
- let _colors = [];
- let _out = false;
- let _min = 0;
- let _max = 1;
- let _correctLightness = false;
- let _colorCache = {};
- let _useCache = true;
- let _gamma = 1;
-
- // private methods
-
- const setColors = function (colors) {
- colors = colors || ['#fff', '#000'];
- if (
- colors &&
- type(colors) === 'string' &&
- chroma.brewer &&
- chroma.brewer[colors.toLowerCase()]
- ) {
- colors = chroma.brewer[colors.toLowerCase()];
- }
- if (type(colors) === 'array') {
- // handle single color
- if (colors.length === 1) {
- colors = [colors[0], colors[0]];
- }
- // make a copy of the colors
- colors = colors.slice(0);
- // convert to chroma classes
- for (let c = 0; c < colors.length; c++) {
- colors[c] = chroma(colors[c]);
- }
- // auto-fill color position
- _pos.length = 0;
- for (let c = 0; c < colors.length; c++) {
- _pos.push(c / (colors.length - 1));
- }
- }
- resetCache();
- return (_colors = colors);
- };
-
- const getClass = function (value) {
- if (_classes != null) {
- const n = _classes.length - 1;
- let i = 0;
- while (i < n && value >= _classes[i]) {
- i++;
- }
- return i - 1;
- }
- return 0;
- };
-
- let tMapLightness = (t) => t;
- let tMapDomain = (t) => t;
-
- // const classifyValue = function(value) {
- // let val = value;
- // if (_classes.length > 2) {
- // const n = _classes.length-1;
- // const i = getClass(value);
- // const minc = _classes[0] + ((_classes[1]-_classes[0]) * (0 + (_spread * 0.5))); // center of 1st class
- // const maxc = _classes[n-1] + ((_classes[n]-_classes[n-1]) * (1 - (_spread * 0.5))); // center of last class
- // val = _min + ((((_classes[i] + ((_classes[i+1] - _classes[i]) * 0.5)) - minc) / (maxc-minc)) * (_max - _min));
- // }
- // return val;
- // };
-
- const getColor = function (val, bypassMap) {
- let col, t;
- if (bypassMap == null) {
- bypassMap = false;
- }
- if (isNaN(val) || val === null) {
- return _nacol;
- }
- if (!bypassMap) {
- if (_classes && _classes.length > 2) {
- // find the class
- const c = getClass(val);
- t = c / (_classes.length - 2);
- } else if (_max !== _min) {
- // just interpolate between min/max
- t = (val - _min) / (_max - _min);
- } else {
- t = 1;
- }
- } else {
- t = val;
- }
-
- // domain map
- t = tMapDomain(t);
-
- if (!bypassMap) {
- t = tMapLightness(t); // lightness correction
- }
-
- if (_gamma !== 1) {
- t = pow(t, _gamma);
- }
-
- t = _padding[0] + t * (1 - _padding[0] - _padding[1]);
-
- t = limit$1(t, 0, 1);
-
- const k = Math.floor(t * 10000);
-
- if (_useCache && _colorCache[k]) {
- col = _colorCache[k];
- } else {
- if (type(_colors) === 'array') {
- //for i in [0.._pos.length-1]
- for (let i = 0; i < _pos.length; i++) {
- const p = _pos[i];
- if (t <= p) {
- col = _colors[i];
- break;
- }
- if (t >= p && i === _pos.length - 1) {
- col = _colors[i];
- break;
- }
- if (t > p && t < _pos[i + 1]) {
- t = (t - p) / (_pos[i + 1] - p);
- col = chroma.interpolate(
- _colors[i],
- _colors[i + 1],
- t,
- _mode
- );
- break;
- }
- }
- } else if (type(_colors) === 'function') {
- col = _colors(t);
- }
- if (_useCache) {
- _colorCache[k] = col;
- }
- }
- return col;
- };
-
- var resetCache = () => (_colorCache = {});
-
- setColors(colors);
-
- // public interface
-
- const f = function (v) {
- const c = chroma(getColor(v));
- if (_out && c[_out]) {
- return c[_out]();
- } else {
- return c;
- }
- };
-
- f.classes = function (classes) {
- if (classes != null) {
- if (type(classes) === 'array') {
- _classes = classes;
- _domain = [classes[0], classes[classes.length - 1]];
- } else {
- const d = chroma.analyze(_domain);
- if (classes === 0) {
- _classes = [d.min, d.max];
- } else {
- _classes = chroma.limits(d, 'e', classes);
- }
- }
- return f;
- }
- return _classes;
- };
-
- f.domain = function (domain) {
- if (!arguments.length) {
- return _domain;
- }
- _min = domain[0];
- _max = domain[domain.length - 1];
- _pos = [];
- const k = _colors.length;
- if (domain.length === k && _min !== _max) {
- // update positions
- for (let d of Array.from(domain)) {
- _pos.push((d - _min) / (_max - _min));
- }
- } else {
- for (let c = 0; c < k; c++) {
- _pos.push(c / (k - 1));
- }
- if (domain.length > 2) {
- // set domain map
- const tOut = domain.map((d, i) => i / (domain.length - 1));
- const tBreaks = domain.map((d) => (d - _min) / (_max - _min));
- if (!tBreaks.every((val, i) => tOut[i] === val)) {
- tMapDomain = (t) => {
- if (t <= 0 || t >= 1) return t;
- let i = 0;
- while (t >= tBreaks[i + 1]) i++;
- const f =
- (t - tBreaks[i]) / (tBreaks[i + 1] - tBreaks[i]);
- const out = tOut[i] + f * (tOut[i + 1] - tOut[i]);
- return out;
- };
- }
- }
- }
- _domain = [_min, _max];
- return f;
- };
-
- f.mode = function (_m) {
- if (!arguments.length) {
- return _mode;
- }
- _mode = _m;
- resetCache();
- return f;
- };
-
- f.range = function (colors, _pos) {
- setColors(colors);
- return f;
- };
-
- f.out = function (_o) {
- _out = _o;
- return f;
- };
-
- f.spread = function (val) {
- if (!arguments.length) {
- return _spread;
- }
- _spread = val;
- return f;
- };
-
- f.correctLightness = function (v) {
- if (v == null) {
- v = true;
- }
- _correctLightness = v;
- resetCache();
- if (_correctLightness) {
- tMapLightness = function (t) {
- const L0 = getColor(0, true).lab()[0];
- const L1 = getColor(1, true).lab()[0];
- const pol = L0 > L1;
- let L_actual = getColor(t, true).lab()[0];
- const L_ideal = L0 + (L1 - L0) * t;
- let L_diff = L_actual - L_ideal;
- let t0 = 0;
- let t1 = 1;
- let max_iter = 20;
- while (Math.abs(L_diff) > 1e-2 && max_iter-- > 0) {
- (function () {
- if (pol) {
- L_diff *= -1;
- }
- if (L_diff < 0) {
- t0 = t;
- t += (t1 - t) * 0.5;
- } else {
- t1 = t;
- t += (t0 - t) * 0.5;
- }
- L_actual = getColor(t, true).lab()[0];
- return (L_diff = L_actual - L_ideal);
- })();
- }
- return t;
- };
- } else {
- tMapLightness = (t) => t;
- }
- return f;
- };
-
- f.padding = function (p) {
- if (p != null) {
- if (type(p) === 'number') {
- p = [p, p];
- }
- _padding = p;
- return f;
- } else {
- return _padding;
- }
- };
-
- f.colors = function (numColors, out) {
- // If no arguments are given, return the original colors that were provided
- if (arguments.length < 2) {
- out = 'hex';
- }
- let result = [];
-
- if (arguments.length === 0) {
- result = _colors.slice(0);
- } else if (numColors === 1) {
- result = [f(0.5)];
- } else if (numColors > 1) {
- const dm = _domain[0];
- const dd = _domain[1] - dm;
- result = __range__(0, numColors).map((i) =>
- f(dm + (i / (numColors - 1)) * dd)
- );
- } else {
- // returns all colors based on the defined classes
- colors = [];
- let samples = [];
- if (_classes && _classes.length > 2) {
- for (
- let i = 1, end = _classes.length, asc = 1 <= end;
- asc ? i < end : i > end;
- asc ? i++ : i--
- ) {
- samples.push((_classes[i - 1] + _classes[i]) * 0.5);
- }
- } else {
- samples = _domain;
- }
- result = samples.map((v) => f(v));
- }
-
- if (chroma[out]) {
- result = result.map((c) => c[out]());
- }
- return result;
- };
-
- f.cache = function (c) {
- if (c != null) {
- _useCache = c;
- return f;
- } else {
- return _useCache;
- }
- };
-
- f.gamma = function (g) {
- if (g != null) {
- _gamma = g;
- return f;
- } else {
- return _gamma;
- }
- };
-
- f.nodata = function (d) {
- if (d != null) {
- _nacol = chroma(d);
- return f;
- } else {
- return _nacol;
- }
- };
-
- return f;
- }
-
- function __range__(left, right, inclusive) {
- let range = [];
- let ascending = left < right;
- let end = right ;
- for (let i = left; ascending ? i < end : i > end; ascending ? i++ : i--) {
- range.push(i);
- }
- return range;
- }
-
- // some pre-defined color scales:
-
- var scales = {
- cool() {
- return scale([chroma.hsl(180, 1, 0.9), chroma.hsl(250, 0.7, 0.4)]);
- },
- hot() {
- return scale(['#000', '#f00', '#ff0', '#fff']).mode(
- 'rgb'
- );
- }
- };
-
- /**
- X11 color names
-
- http://www.w3.org/TR/css3-color/#svg-color
- */
-
- const w3cx11 = {
- aliceblue: '#f0f8ff',
- antiquewhite: '#faebd7',
- aqua: '#00ffff',
- aquamarine: '#7fffd4',
- azure: '#f0ffff',
- beige: '#f5f5dc',
- bisque: '#ffe4c4',
- black: '#000000',
- blanchedalmond: '#ffebcd',
- blue: '#0000ff',
- blueviolet: '#8a2be2',
- brown: '#a52a2a',
- burlywood: '#deb887',
- cadetblue: '#5f9ea0',
- chartreuse: '#7fff00',
- chocolate: '#d2691e',
- coral: '#ff7f50',
- cornflowerblue: '#6495ed',
- cornsilk: '#fff8dc',
- crimson: '#dc143c',
- cyan: '#00ffff',
- darkblue: '#00008b',
- darkcyan: '#008b8b',
- darkgoldenrod: '#b8860b',
- darkgray: '#a9a9a9',
- darkgreen: '#006400',
- darkgrey: '#a9a9a9',
- darkkhaki: '#bdb76b',
- darkmagenta: '#8b008b',
- darkolivegreen: '#556b2f',
- darkorange: '#ff8c00',
- darkorchid: '#9932cc',
- darkred: '#8b0000',
- darksalmon: '#e9967a',
- darkseagreen: '#8fbc8f',
- darkslateblue: '#483d8b',
- darkslategray: '#2f4f4f',
- darkslategrey: '#2f4f4f',
- darkturquoise: '#00ced1',
- darkviolet: '#9400d3',
- deeppink: '#ff1493',
- deepskyblue: '#00bfff',
- dimgray: '#696969',
- dimgrey: '#696969',
- dodgerblue: '#1e90ff',
- firebrick: '#b22222',
- floralwhite: '#fffaf0',
- forestgreen: '#228b22',
- fuchsia: '#ff00ff',
- gainsboro: '#dcdcdc',
- ghostwhite: '#f8f8ff',
- gold: '#ffd700',
- goldenrod: '#daa520',
- gray: '#808080',
- green: '#008000',
- greenyellow: '#adff2f',
- grey: '#808080',
- honeydew: '#f0fff0',
- hotpink: '#ff69b4',
- indianred: '#cd5c5c',
- indigo: '#4b0082',
- ivory: '#fffff0',
- khaki: '#f0e68c',
- laserlemon: '#ffff54',
- lavender: '#e6e6fa',
- lavenderblush: '#fff0f5',
- lawngreen: '#7cfc00',
- lemonchiffon: '#fffacd',
- lightblue: '#add8e6',
- lightcoral: '#f08080',
- lightcyan: '#e0ffff',
- lightgoldenrod: '#fafad2',
- lightgoldenrodyellow: '#fafad2',
- lightgray: '#d3d3d3',
- lightgreen: '#90ee90',
- lightgrey: '#d3d3d3',
- lightpink: '#ffb6c1',
- lightsalmon: '#ffa07a',
- lightseagreen: '#20b2aa',
- lightskyblue: '#87cefa',
- lightslategray: '#778899',
- lightslategrey: '#778899',
- lightsteelblue: '#b0c4de',
- lightyellow: '#ffffe0',
- lime: '#00ff00',
- limegreen: '#32cd32',
- linen: '#faf0e6',
- magenta: '#ff00ff',
- maroon: '#800000',
- maroon2: '#7f0000',
- maroon3: '#b03060',
- mediumaquamarine: '#66cdaa',
- mediumblue: '#0000cd',
- mediumorchid: '#ba55d3',
- mediumpurple: '#9370db',
- mediumseagreen: '#3cb371',
- mediumslateblue: '#7b68ee',
- mediumspringgreen: '#00fa9a',
- mediumturquoise: '#48d1cc',
- mediumvioletred: '#c71585',
- midnightblue: '#191970',
- mintcream: '#f5fffa',
- mistyrose: '#ffe4e1',
- moccasin: '#ffe4b5',
- navajowhite: '#ffdead',
- navy: '#000080',
- oldlace: '#fdf5e6',
- olive: '#808000',
- olivedrab: '#6b8e23',
- orange: '#ffa500',
- orangered: '#ff4500',
- orchid: '#da70d6',
- palegoldenrod: '#eee8aa',
- palegreen: '#98fb98',
- paleturquoise: '#afeeee',
- palevioletred: '#db7093',
- papayawhip: '#ffefd5',
- peachpuff: '#ffdab9',
- peru: '#cd853f',
- pink: '#ffc0cb',
- plum: '#dda0dd',
- powderblue: '#b0e0e6',
- purple: '#800080',
- purple2: '#7f007f',
- purple3: '#a020f0',
- rebeccapurple: '#663399',
- red: '#ff0000',
- rosybrown: '#bc8f8f',
- royalblue: '#4169e1',
- saddlebrown: '#8b4513',
- salmon: '#fa8072',
- sandybrown: '#f4a460',
- seagreen: '#2e8b57',
- seashell: '#fff5ee',
- sienna: '#a0522d',
- silver: '#c0c0c0',
- skyblue: '#87ceeb',
- slateblue: '#6a5acd',
- slategray: '#708090',
- slategrey: '#708090',
- snow: '#fffafa',
- springgreen: '#00ff7f',
- steelblue: '#4682b4',
- tan: '#d2b48c',
- teal: '#008080',
- thistle: '#d8bfd8',
- tomato: '#ff6347',
- turquoise: '#40e0d0',
- violet: '#ee82ee',
- wheat: '#f5deb3',
- white: '#ffffff',
- whitesmoke: '#f5f5f5',
- yellow: '#ffff00',
- yellowgreen: '#9acd32'
- };
-
- /**
- ColorBrewer colors for chroma.js
-
- Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The
- Pennsylvania State University.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software distributed
- under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- CONDITIONS OF ANY KIND, either express or implied. See the License for the
- specific language governing permissions and limitations under the License.
- */
-
- const colorbrewer = {
- // sequential
- OrRd: ['#fff7ec', '#fee8c8', '#fdd49e', '#fdbb84', '#fc8d59', '#ef6548', '#d7301f', '#b30000', '#7f0000'],
- PuBu: ['#fff7fb', '#ece7f2', '#d0d1e6', '#a6bddb', '#74a9cf', '#3690c0', '#0570b0', '#045a8d', '#023858'],
- BuPu: ['#f7fcfd', '#e0ecf4', '#bfd3e6', '#9ebcda', '#8c96c6', '#8c6bb1', '#88419d', '#810f7c', '#4d004b'],
- Oranges: ['#fff5eb', '#fee6ce', '#fdd0a2', '#fdae6b', '#fd8d3c', '#f16913', '#d94801', '#a63603', '#7f2704'],
- BuGn: ['#f7fcfd', '#e5f5f9', '#ccece6', '#99d8c9', '#66c2a4', '#41ae76', '#238b45', '#006d2c', '#00441b'],
- YlOrBr: ['#ffffe5', '#fff7bc', '#fee391', '#fec44f', '#fe9929', '#ec7014', '#cc4c02', '#993404', '#662506'],
- YlGn: ['#ffffe5', '#f7fcb9', '#d9f0a3', '#addd8e', '#78c679', '#41ab5d', '#238443', '#006837', '#004529'],
- Reds: ['#fff5f0', '#fee0d2', '#fcbba1', '#fc9272', '#fb6a4a', '#ef3b2c', '#cb181d', '#a50f15', '#67000d'],
- RdPu: ['#fff7f3', '#fde0dd', '#fcc5c0', '#fa9fb5', '#f768a1', '#dd3497', '#ae017e', '#7a0177', '#49006a'],
- Greens: ['#f7fcf5', '#e5f5e0', '#c7e9c0', '#a1d99b', '#74c476', '#41ab5d', '#238b45', '#006d2c', '#00441b'],
- YlGnBu: ['#ffffd9', '#edf8b1', '#c7e9b4', '#7fcdbb', '#41b6c4', '#1d91c0', '#225ea8', '#253494', '#081d58'],
- Purples: ['#fcfbfd', '#efedf5', '#dadaeb', '#bcbddc', '#9e9ac8', '#807dba', '#6a51a3', '#54278f', '#3f007d'],
- GnBu: ['#f7fcf0', '#e0f3db', '#ccebc5', '#a8ddb5', '#7bccc4', '#4eb3d3', '#2b8cbe', '#0868ac', '#084081'],
- Greys: ['#ffffff', '#f0f0f0', '#d9d9d9', '#bdbdbd', '#969696', '#737373', '#525252', '#252525', '#000000'],
- YlOrRd: ['#ffffcc', '#ffeda0', '#fed976', '#feb24c', '#fd8d3c', '#fc4e2a', '#e31a1c', '#bd0026', '#800026'],
- PuRd: ['#f7f4f9', '#e7e1ef', '#d4b9da', '#c994c7', '#df65b0', '#e7298a', '#ce1256', '#980043', '#67001f'],
- Blues: ['#f7fbff', '#deebf7', '#c6dbef', '#9ecae1', '#6baed6', '#4292c6', '#2171b5', '#08519c', '#08306b'],
- PuBuGn: ['#fff7fb', '#ece2f0', '#d0d1e6', '#a6bddb', '#67a9cf', '#3690c0', '#02818a', '#016c59', '#014636'],
- Viridis: ['#440154', '#482777', '#3f4a8a', '#31678e', '#26838f', '#1f9d8a', '#6cce5a', '#b6de2b', '#fee825'],
-
- // diverging
- Spectral: ['#9e0142', '#d53e4f', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#e6f598', '#abdda4', '#66c2a5', '#3288bd', '#5e4fa2'],
- RdYlGn: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#d9ef8b', '#a6d96a', '#66bd63', '#1a9850', '#006837'],
- RdBu: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#f7f7f7', '#d1e5f0', '#92c5de', '#4393c3', '#2166ac', '#053061'],
- PiYG: ['#8e0152', '#c51b7d', '#de77ae', '#f1b6da', '#fde0ef', '#f7f7f7', '#e6f5d0', '#b8e186', '#7fbc41', '#4d9221', '#276419'],
- PRGn: ['#40004b', '#762a83', '#9970ab', '#c2a5cf', '#e7d4e8', '#f7f7f7', '#d9f0d3', '#a6dba0', '#5aae61', '#1b7837', '#00441b'],
- RdYlBu: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee090', '#ffffbf', '#e0f3f8', '#abd9e9', '#74add1', '#4575b4', '#313695'],
- BrBG: ['#543005', '#8c510a', '#bf812d', '#dfc27d', '#f6e8c3', '#f5f5f5', '#c7eae5', '#80cdc1', '#35978f', '#01665e', '#003c30'],
- RdGy: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#ffffff', '#e0e0e0', '#bababa', '#878787', '#4d4d4d', '#1a1a1a'],
- PuOr: ['#7f3b08', '#b35806', '#e08214', '#fdb863', '#fee0b6', '#f7f7f7', '#d8daeb', '#b2abd2', '#8073ac', '#542788', '#2d004b'],
-
- // qualitative
- Set2: ['#66c2a5', '#fc8d62', '#8da0cb', '#e78ac3', '#a6d854', '#ffd92f', '#e5c494', '#b3b3b3'],
- Accent: ['#7fc97f', '#beaed4', '#fdc086', '#ffff99', '#386cb0', '#f0027f', '#bf5b17', '#666666'],
- Set1: ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00', '#ffff33', '#a65628', '#f781bf', '#999999'],
- Set3: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd', '#ccebc5', '#ffed6f'],
- Dark2: ['#1b9e77', '#d95f02', '#7570b3', '#e7298a', '#66a61e', '#e6ab02', '#a6761d', '#666666'],
- Paired: ['#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99', '#e31a1c', '#fdbf6f', '#ff7f00', '#cab2d6', '#6a3d9a', '#ffff99', '#b15928'],
- Pastel2: ['#b3e2cd', '#fdcdac', '#cbd5e8', '#f4cae4', '#e6f5c9', '#fff2ae', '#f1e2cc', '#cccccc'],
- Pastel1: ['#fbb4ae', '#b3cde3', '#ccebc5', '#decbe4', '#fed9a6', '#ffffcc', '#e5d8bd', '#fddaec', '#f2f2f2']
- };
-
- const colorbrewerTypes = Object.keys(colorbrewer);
- const typeMap = new Map(colorbrewerTypes.map((key) => [key.toLowerCase(), key]));
-
- // use Proxy to allow case-insensitive access to palettes
- const colorbrewerProxy =
- typeof Proxy === 'function'
- ? new Proxy(colorbrewer, {
- get(target, prop) {
- const lower = prop.toLowerCase();
- if (typeMap.has(lower)) {
- return target[typeMap.get(lower)];
- }
- },
- getOwnPropertyNames() {
- return Object.getOwnPropertyNames(colorbrewerTypes);
- }
- })
- : colorbrewer;
-
- class Color {
- constructor(...args) {
- const me = this;
- if (
- type(args[0]) === 'object' &&
- args[0].constructor &&
- args[0].constructor === this.constructor
- ) {
- // the argument is already a Color instance
- return args[0];
- }
- // last argument could be the mode
- let mode = last(args);
- let autodetect = false;
- if (!mode) {
- autodetect = true;
-
- if (!_input.sorted) {
- _input.autodetect = _input.autodetect.sort((a, b) => b.p - a.p);
- _input.sorted = true;
- }
-
- // auto-detect format
- for (let chk of _input.autodetect) {
- mode = chk.test(...args);
- if (mode) break;
- }
- }
- if (_input.format[mode]) {
- const rgb = _input.format[mode].apply(
- null,
- autodetect ? args : args.slice(0, -1)
- );
- me._rgb = clip_rgb(rgb);
- } else {
- throw new Error('unknown format: ' + args);
- }
- // add alpha channel
- if (me._rgb.length === 3) me._rgb.push(1);
- }
- toString() {
- if (type(this.hex) == 'function') return this.hex();
- return `[${this._rgb.join(',')}]`;
- }
- }
-
- const cmyk2rgb = (...args) => {
- args = unpack(args, 'cmyk');
- const [c, m, y, k] = args;
- const alpha = args.length > 4 ? args[4] : 1;
- if (k === 1) return [0, 0, 0, alpha];
- return [
- c >= 1 ? 0 : 255 * (1 - c) * (1 - k), // r
- m >= 1 ? 0 : 255 * (1 - m) * (1 - k), // g
- y >= 1 ? 0 : 255 * (1 - y) * (1 - k), // b
- alpha
- ];
- };
-
- const { max: max$1 } = Math;
-
- const rgb2cmyk = (...args) => {
- let [r, g, b] = unpack(args, 'rgb');
- r = r / 255;
- g = g / 255;
- b = b / 255;
- const k = 1 - max$1(r, max$1(g, b));
- const f = k < 1 ? 1 / (1 - k) : 0;
- const c = (1 - r - k) * f;
- const m = (1 - g - k) * f;
- const y = (1 - b - k) * f;
- return [c, m, y, k];
- };
-
- Color$2.prototype.cmyk = function () {
- return rgb2cmyk(this._rgb);
- };
-
- const cmyk = (...args) => new Color$2(...args, 'cmyk');
- Object.assign(chroma$1, { cmyk });
-
- input$1.format.cmyk = cmyk2rgb;
-
- input$1.autodetect.push({
- p: 2,
- test: (...args) => {
- args = unpack(args, 'cmyk');
- if (type(args) === 'array' && args.length === 4) {
- return 'cmyk';
- }
- }
- });
-
- /*
- * supported arguments:
- * - hsl2css(h,s,l)
- * - hsl2css(h,s,l,a)
- * - hsl2css([h,s,l], mode)
- * - hsl2css([h,s,l,a], mode)
- * - hsl2css({h,s,l,a}, mode)
- */
- const hsl2css = (...args) => {
- const hsla = unpack(args, 'hsla');
- let mode = last(args) || 'lsa';
- hsla[0] = rnd2(hsla[0] || 0) + 'deg';
- hsla[1] = rnd2(hsla[1] * 100) + '%';
- hsla[2] = rnd2(hsla[2] * 100) + '%';
- if (mode === 'hsla' || (hsla.length > 3 && hsla[3] < 1)) {
- hsla[3] = '/ ' + (hsla.length > 3 ? hsla[3] : 1);
- mode = 'hsla';
- } else {
- hsla.length = 3;
- }
- return `${mode.substr(0, 3)}(${hsla.join(' ')})`;
- };
-
- /*
- * supported arguments:
- * - rgb2hsl(r,g,b)
- * - rgb2hsl(r,g,b,a)
- * - rgb2hsl([r,g,b])
- * - rgb2hsl([r,g,b,a])
- * - rgb2hsl({r,g,b,a})
- */
- const rgb2hsl = (...args) => {
- args = unpack(args, 'rgba');
- let [r, g, b] = args;
-
- r /= 255;
- g /= 255;
- b /= 255;
-
- const minRgb = min$4(r, g, b);
- const maxRgb = max$4(r, g, b);
-
- const l = (maxRgb + minRgb) / 2;
- let s, h;
-
- if (maxRgb === minRgb) {
- s = 0;
- h = Number.NaN;
- } else {
- s =
- l < 0.5
- ? (maxRgb - minRgb) / (maxRgb + minRgb)
- : (maxRgb - minRgb) / (2 - maxRgb - minRgb);
- }
-
- if (r == maxRgb) h = (g - b) / (maxRgb - minRgb);
- else if (g == maxRgb) h = 2 + (b - r) / (maxRgb - minRgb);
- else if (b == maxRgb) h = 4 + (r - g) / (maxRgb - minRgb);
-
- h *= 60;
- if (h < 0) h += 360;
- if (args.length > 3 && args[3] !== undefined) return [h, s, l, args[3]];
- return [h, s, l];
- };
-
- /*
- * supported arguments:
- * - lab2css(l,a,b)
- * - lab2css(l,a,b,alpha)
- * - lab2css([l,a,b], mode)
- * - lab2css([l,a,b,alpha], mode)
- */
- const lab2css = (...args) => {
- const laba = unpack(args, 'lab');
- let mode = last(args) || 'lab';
- laba[0] = rnd2(laba[0]) + '%';
- laba[1] = rnd2(laba[1]);
- laba[2] = rnd2(laba[2]);
- if (mode === 'laba' || (laba.length > 3 && laba[3] < 1)) {
- laba[3] = '/ ' + (laba.length > 3 ? laba[3] : 1);
- } else {
- laba.length = 3;
- }
- return `lab(${laba.join(' ')})`;
- };
-
- /*
- * supported arguments:
- * - lab2css(l,a,b)
- * - lab2css(l,a,b,alpha)
- * - lab2css([l,a,b], mode)
- * - lab2css([l,a,b,alpha], mode)
- */
- const lch2css = (...args) => {
- const lcha = unpack(args, 'lch');
- let mode = last(args) || 'lab';
- lcha[0] = rnd2(lcha[0]) + '%';
- lcha[1] = rnd2(lcha[1]);
- lcha[2] = isNaN(lcha[2]) ? 'none' : rnd2(lcha[2]) + 'deg'; // add deg unit to hue
- if (mode === 'lcha' || (lcha.length > 3 && lcha[3] < 1)) {
- lcha[3] = '/ ' + (lcha.length > 3 ? lcha[3] : 1);
- } else {
- lcha.length = 3;
- }
- return `lch(${lcha.join(' ')})`;
- };
-
- const rgb2lch = (...args) => {
- const [r, g, b, ...rest] = unpack(args, 'rgb');
- const [l, a, b_] = rgb2lab(r, g, b);
- const [L, c, h] = lab2lch$1(l, a, b_);
- return [L, c, h, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
- };
-
- const rgb2oklab = (...args) => {
- const [r, g, b, ...rest] = unpack(args, 'rgb');
- const xyz = rgb2xyz(r, g, b);
- const oklab = XYZ_to_OKLab(xyz);
- return [...oklab, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
- };
-
- // from https://www.w3.org/TR/css-color-4/#color-conversion-code
- function XYZ_to_OKLab(XYZ) {
- // Given XYZ relative to D65, convert to OKLab
- 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 LMS = multiplyMatrices(XYZtoLMS, XYZ);
- // JavaScript Math.cbrt returns a sign-matched cube root
- // beware if porting to other languages
- // especially if tempted to use a general power function
- return multiplyMatrices(
- LMStoOKLab,
- LMS.map((c) => Math.cbrt(c))
- );
- // L in range [0,1]. For use in CSS, multiply by 100 and add a percent
- }
-
- const oklab2css = (...args) => {
- const laba = unpack(args, 'lab');
- laba[0] = rnd2(laba[0] * 100) + '%';
- laba[1] = rnd3(laba[1]);
- laba[2] = rnd3(laba[2]);
- if (laba.length > 3 && laba[3] < 1) {
- laba[3] = '/ ' + (laba.length > 3 ? laba[3] : 1);
- } else {
- laba.length = 3;
- }
- return `oklab(${laba.join(' ')})`;
- };
-
- const { sqrt, atan2, round: round$5 } = Math;
-
- const lab2lch = (...args) => {
- const [l, a, b] = unpack(args, 'lab');
- const c = sqrt(a * a + b * b);
- let h = (atan2(b, a) * RAD2DEG + 360) % 360;
- if (round$5(c * 10000) === 0) h = Number.NaN;
- return [l, c, h];
- };
-
- const rgb2oklch$1 = (...args) => {
- const [r, g, b, ...rest] = unpack(args, 'rgb');
- const [l, a, b_] = rgb2oklab(r, g, b);
- const [L, c, h] = lab2lch(l, a, b_);
- return [L, c, h, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
- };
-
- const oklch2css = (...args) => {
- const lcha = unpack(args, 'lch');
- lcha[0] = rnd2(lcha[0] * 100) + '%';
- lcha[1] = rnd3(lcha[1]);
- lcha[2] = isNaN(lcha[2]) ? 'none' : rnd2(lcha[2]) + 'deg'; // add deg unit to hue
- if (lcha.length > 3 && lcha[3] < 1) {
- lcha[3] = '/ ' + (lcha.length > 3 ? lcha[3] : 1);
- } else {
- lcha.length = 3;
- }
- return `oklch(${lcha.join(' ')})`;
- };
-
- const labConstants = {
- // D65 standard referent
- labWhitePoint: 'd65',
- Xn: 0.95047,
- Zn: 1.08883};
-
- // taken from https://de.mathworks.com/help/images/ref/whitepoint.html
- const ILLUMINANTS = new Map([
- // ASTM E308-01
- ['a', [1.0985, 0.35585]],
- // Wyszecki & Stiles, p. 769
- ['b', [1.0985, 0.35585]],
- // C ASTM E308-01
- ['c', [0.98074, 1.18232]],
- // D50 (ASTM E308-01)
- ['d50', [0.96422, 0.82521]],
- // D55 (ASTM E308-01)
- ['d55', [0.95682, 0.92149]],
- // D65 (ASTM E308-01)
- ['d65', [0.95047, 1.08883]],
- // E (ASTM E308-01)
- ['e', [1, 1, 1]],
- // F2 (ASTM E308-01)
- ['f2', [0.99186, 0.67393]],
- // F7 (ASTM E308-01)
- ['f7', [0.95041, 1.08747]],
- // F11 (ASTM E308-01)
- ['f11', [1.00962, 0.6435]],
- ['icc', [0.96422, 0.82521]]
- ]);
-
- function setLabWhitePoint(name) {
- const ill = ILLUMINANTS.get(String(name).toLowerCase());
- if (!ill) {
- throw new Error('unknown Lab illuminant ' + name);
- }
- labConstants.labWhitePoint = name;
- labConstants.Xn = ill[0];
- labConstants.Zn = ill[1];
- }
-
- function getLabWhitePoint() {
- return labConstants.labWhitePoint;
- }
-
- const { round: round$4 } = Math;
-
- /*
- * supported arguments:
- * - rgb2css(r,g,b)
- * - rgb2css(r,g,b,a)
- * - rgb2css([r,g,b], mode)
- * - rgb2css([r,g,b,a], mode)
- * - rgb2css({r,g,b,a}, mode)
- */
- const rgb2css = (...args) => {
- const rgba = unpack(args, 'rgba');
- let mode = last(args) || 'rgb';
- if (mode.substr(0, 3) === 'hsl') {
- return hsl2css(rgb2hsl(rgba), mode);
- }
- if (mode.substr(0, 3) === 'lab') {
- // change to D50 lab whitepoint since this is what W3C is using for CSS Lab colors
- const prevWhitePoint = getLabWhitePoint();
- setLabWhitePoint('d50');
- const cssColor = lab2css(rgb2lab(rgba), mode);
- setLabWhitePoint(prevWhitePoint);
- return cssColor;
- }
- if (mode.substr(0, 3) === 'lch') {
- // change to D50 lab whitepoint since this is what W3C is using for CSS Lab colors
- const prevWhitePoint = getLabWhitePoint();
- setLabWhitePoint('d50');
- const cssColor = lch2css(rgb2lch(rgba), mode);
- setLabWhitePoint(prevWhitePoint);
- return cssColor;
- }
- if (mode.substr(0, 5) === 'oklab') {
- return oklab2css(rgb2oklab(rgba));
- }
- if (mode.substr(0, 5) === 'oklch') {
- return oklch2css(rgb2oklch$1(rgba));
- }
- rgba[0] = round$4(rgba[0]);
- rgba[1] = round$4(rgba[1]);
- rgba[2] = round$4(rgba[2]);
- if (mode === 'rgba' || (rgba.length > 3 && rgba[3] < 1)) {
- rgba[3] = '/ ' + (rgba.length > 3 ? rgba[3] : 1);
- mode = 'rgba';
- }
- return `${mode.substr(0, 3)}(${rgba.slice(0, mode === 'rgb' ? 3 : 4).join(' ')})`;
- };
-
- const hsl2rgb = (...args) => {
- args = unpack(args, 'hsl');
- const [h, s, l] = args;
- let r, g, b;
- if (s === 0) {
- r = g = b = l * 255;
- } else {
- const t3 = [0, 0, 0];
- const c = [0, 0, 0];
- const t2 = l < 0.5 ? l * (1 + s) : l + s - l * s;
- const t1 = 2 * l - t2;
- const h_ = h / 360;
- t3[0] = h_ + 1 / 3;
- t3[1] = h_;
- t3[2] = h_ - 1 / 3;
- for (let i = 0; i < 3; i++) {
- if (t3[i] < 0) t3[i] += 1;
- if (t3[i] > 1) t3[i] -= 1;
- if (6 * t3[i] < 1) c[i] = t1 + (t2 - t1) * 6 * t3[i];
- else if (2 * t3[i] < 1) c[i] = t2;
- else if (3 * t3[i] < 2) c[i] = t1 + (t2 - t1) * (2 / 3 - t3[i]) * 6;
- else c[i] = t1;
- }
- [r, g, b] = [c[0] * 255, c[1] * 255, c[2] * 255];
- }
- if (args.length > 3) {
- // keep alpha channel
- return [r, g, b, args[3]];
- }
- return [r, g, b, 1];
- };
-
- const lch2rgb = (...args) => {
- args = unpack(args, 'lch');
- const [l, c, h] = args;
- const [L, a, b_] = lch2lab$1(l, c, h);
- const [r, g, b] = lab2rgb(L, a, b_);
- return [r, g, b, args.length > 3 ? args[3] : 1];
- };
-
- const oklab2rgb = (...args) => {
- args = unpack(args, 'lab');
- const [L, a, b, ...rest] = args;
- const [X, Y, Z] = OKLab_to_XYZ([L, a, b]);
- const [r, g, b_] = xyz2rgb(X, Y, Z);
- return [r, g, b_, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
- };
-
- // from https://www.w3.org/TR/css-color-4/#color-conversion-code
- function OKLab_to_XYZ(OKLab) {
- // Given OKLab, convert to XYZ relative to D65
- var LMStoXYZ = [
- [1.2268798758459243, -0.5578149944602171, 0.2813910456659647],
- [-0.0405757452148008, 1.112286803280317, -0.0717110580655164],
- [-0.0763729366746601, -0.4214933324022432, 1.5869240198367816]
- ];
- var OKLabtoLMS = [
- [1.0, 0.3963377773761749, 0.2158037573099136],
- [1.0, -0.1055613458156586, -0.0638541728258133],
- [1.0, -0.0894841775298119, -1.2914855480194092]
- ];
-
- var LMSnl = multiplyMatrices(OKLabtoLMS, OKLab);
- return multiplyMatrices(
- LMStoXYZ,
- LMSnl.map((c) => c ** 3)
- );
- }
-
- const { sin, cos } = Math;
-
- const lch2lab = (...args) => {
- /*
- Convert from a qualitative parameter h and a quantitative parameter l to a 24-bit pixel.
- These formulas were invented by David Dalrymple to obtain maximum contrast without going
- out of gamut if the parameters are in the range 0-1.
-
- A saturation multiplier was added by Gregor Aisch
- */
- let [l, c, h] = unpack(args, 'lch');
- if (isNaN(h)) h = 0;
- h = h * DEG2RAD;
- return [l, cos(h) * c, sin(h) * c];
- };
-
- const oklch2rgb$1 = (...args) => {
- args = unpack(args, 'lch');
- const [l, c, h, ...rest] = args;
- const [L, a, b_] = lch2lab(l, c, h);
- const [r, g, b] = oklab2rgb(L, a, b_);
- return [r, g, b, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
- };
-
- const { min, max } = Math;
-
- var limit = (x, low = 0, high = 1) => {
- return min(max(low, x), high);
- };
-
- const INT_OR_PCT = /((?:-?\d+)|(?:-?\d+(?:\.\d+)?)%|none)/.source;
- const FLOAT_OR_PCT = /((?:-?(?:\d+(?:\.\d*)?|\.\d+)%?)|none)/.source;
- const PCT = /((?:-?(?:\d+(?:\.\d*)?|\.\d+)%)|none)/.source;
- const RE_S = /\s*/.source;
- const SEP = /\s+/.source;
- const COMMA = /\s*,\s*/.source;
- const ANLGE = /((?:-?(?:\d+(?:\.\d*)?|\.\d+)(?:deg)?)|none)/.source;
- const ALPHA = /\s*(?:\/\s*((?:[01]|[01]?\.\d+)|\d+(?:\.\d+)?%))?/.source;
-
- // e.g. rgb(250 20 0), rgb(100% 50% 20%), rgb(100% 50% 20% / 0.5)
- const RE_RGB = new RegExp(
- '^rgba?\\(' +
- RE_S +
- [INT_OR_PCT, INT_OR_PCT, INT_OR_PCT].join(SEP) +
- ALPHA +
- '\\)$'
- );
- const RE_RGB_LEGACY = new RegExp(
- '^rgb\\(' +
- RE_S +
- [INT_OR_PCT, INT_OR_PCT, INT_OR_PCT].join(COMMA) +
- RE_S +
- '\\)$'
- );
- const RE_RGBA_LEGACY = new RegExp(
- '^rgba\\(' +
- RE_S +
- [INT_OR_PCT, INT_OR_PCT, INT_OR_PCT, FLOAT_OR_PCT].join(COMMA) +
- RE_S +
- '\\)$'
- );
-
- const RE_HSL = new RegExp(
- '^hsla?\\(' + RE_S + [ANLGE, PCT, PCT].join(SEP) + ALPHA + '\\)$'
- );
- const RE_HSL_LEGACY = new RegExp(
- '^hsl?\\(' + RE_S + [ANLGE, PCT, PCT].join(COMMA) + RE_S + '\\)$'
- );
- const RE_HSLA_LEGACY =
- /^hsla\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/;
-
- const RE_LAB = new RegExp(
- '^lab\\(' +
- RE_S +
- [FLOAT_OR_PCT, FLOAT_OR_PCT, FLOAT_OR_PCT].join(SEP) +
- ALPHA +
- '\\)$'
- );
- const RE_LCH = new RegExp(
- '^lch\\(' +
- RE_S +
- [FLOAT_OR_PCT, FLOAT_OR_PCT, ANLGE].join(SEP) +
- ALPHA +
- '\\)$'
- );
- const RE_OKLAB = new RegExp(
- '^oklab\\(' +
- RE_S +
- [FLOAT_OR_PCT, FLOAT_OR_PCT, FLOAT_OR_PCT].join(SEP) +
- ALPHA +
- '\\)$'
- );
- const RE_OKLCH = new RegExp(
- '^oklch\\(' +
- RE_S +
- [FLOAT_OR_PCT, FLOAT_OR_PCT, ANLGE].join(SEP) +
- ALPHA +
- '\\)$'
- );
-
- const { round: round$3 } = Math;
-
- const roundRGB = (rgb) => {
- return rgb.map((v, i) => (i <= 2 ? limit(round$3(v), 0, 255) : v));
- };
-
- const percentToAbsolute = (pct, min = 0, max = 100, signed = false) => {
- if (typeof pct === 'string' && pct.endsWith('%')) {
- pct = parseFloat(pct.substring(0, pct.length - 1)) / 100;
- if (signed) {
- // signed percentages are in the range -100% to 100%
- pct = min + (pct + 1) * 0.5 * (max - min);
- } else {
- pct = min + pct * (max - min);
- }
- }
- return +pct;
- };
-
- const noneToValue = (v, noneValue) => {
- return v === 'none' ? noneValue : v;
- };
-
- const css2rgb = (css) => {
- css = css.toLowerCase().trim();
-
- if (css === 'transparent') {
- return [0, 0, 0, 0];
- }
-
- let m;
-
- if (input$1.format.named) {
- try {
- return input$1.format.named(css);
- // eslint-disable-next-line
- } catch (e) {}
- }
-
- // rgb(250 20 0) or rgb(250,20,0)
- if ((m = css.match(RE_RGB)) || (m = css.match(RE_RGB_LEGACY))) {
- let rgb = m.slice(1, 4);
- for (let i = 0; i < 3; i++) {
- rgb[i] = +percentToAbsolute(noneToValue(rgb[i], 0), 0, 255);
- }
- rgb = roundRGB(rgb);
- const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
- rgb[3] = alpha; // default alpha
- return rgb;
- }
-
- // rgba(250,20,0,0.4)
- if ((m = css.match(RE_RGBA_LEGACY))) {
- const rgb = m.slice(1, 5);
- for (let i = 0; i < 4; i++) {
- rgb[i] = +percentToAbsolute(rgb[i], 0, 255);
- }
- return rgb;
- }
-
- // hsl(0,100%,50%)
- if ((m = css.match(RE_HSL)) || (m = css.match(RE_HSL_LEGACY))) {
- const hsl = m.slice(1, 4);
- hsl[0] = +noneToValue(hsl[0].replace('deg', ''), 0);
- hsl[1] = +percentToAbsolute(noneToValue(hsl[1], 0), 0, 100) * 0.01;
- hsl[2] = +percentToAbsolute(noneToValue(hsl[2], 0), 0, 100) * 0.01;
- const rgb = roundRGB(hsl2rgb(hsl));
- const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
- rgb[3] = alpha;
- return rgb;
- }
-
- // hsla(0,100%,50%,0.5)
- if ((m = css.match(RE_HSLA_LEGACY))) {
- const hsl = m.slice(1, 4);
- hsl[1] *= 0.01;
- hsl[2] *= 0.01;
- const rgb = hsl2rgb(hsl);
- for (let i = 0; i < 3; i++) {
- rgb[i] = round$3(rgb[i]);
- }
- rgb[3] = +m[4]; // default alpha = 1
- return rgb;
- }
-
- if ((m = css.match(RE_LAB))) {
- const lab = m.slice(1, 4);
- lab[0] = percentToAbsolute(noneToValue(lab[0], 0), 0, 100);
- lab[1] = percentToAbsolute(noneToValue(lab[1], 0), -125, 125, true);
- lab[2] = percentToAbsolute(noneToValue(lab[2], 0), -125, 125, true);
- // convert to D50 Lab whitepoint
- const wp = getLabWhitePoint();
- setLabWhitePoint('d50');
- const rgb = roundRGB(lab2rgb(lab));
- // convert back to original Lab whitepoint
- setLabWhitePoint(wp);
- const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
- rgb[3] = alpha;
- return rgb;
- }
-
- if ((m = css.match(RE_LCH))) {
- const lch = m.slice(1, 4);
- lch[0] = percentToAbsolute(lch[0], 0, 100);
- lch[1] = percentToAbsolute(noneToValue(lch[1], 0), 0, 150, false);
- lch[2] = +noneToValue(lch[2].replace('deg', ''), 0);
- // convert to D50 Lab whitepoint
- const wp = getLabWhitePoint();
- setLabWhitePoint('d50');
- const rgb = roundRGB(lch2rgb(lch));
- // convert back to original Lab whitepoint
- setLabWhitePoint(wp);
- const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
- rgb[3] = alpha;
- return rgb;
- }
-
- if ((m = css.match(RE_OKLAB))) {
- const oklab = m.slice(1, 4);
- oklab[0] = percentToAbsolute(noneToValue(oklab[0], 0), 0, 1);
- oklab[1] = percentToAbsolute(noneToValue(oklab[1], 0), -0.4, 0.4, true);
- oklab[2] = percentToAbsolute(noneToValue(oklab[2], 0), -0.4, 0.4, true);
- const rgb = roundRGB(oklab2rgb(oklab));
- const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
- rgb[3] = alpha;
- return rgb;
- }
-
- if ((m = css.match(RE_OKLCH))) {
- const oklch = m.slice(1, 4);
- oklch[0] = percentToAbsolute(noneToValue(oklch[0], 0), 0, 1);
- oklch[1] = percentToAbsolute(noneToValue(oklch[1], 0), 0, 0.4, false);
- oklch[2] = +noneToValue(oklch[2].replace('deg', ''), 0);
- const rgb = roundRGB(oklch2rgb$1(oklch));
- const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
- rgb[3] = alpha;
- return rgb;
- }
- };
-
- css2rgb.test = (s) => {
- return (
- // modern
- RE_RGB.test(s) ||
- RE_HSL.test(s) ||
- RE_LAB.test(s) ||
- RE_LCH.test(s) ||
- RE_OKLAB.test(s) ||
- RE_OKLCH.test(s) ||
- // legacy
- RE_RGB_LEGACY.test(s) ||
- RE_RGBA_LEGACY.test(s) ||
- RE_HSL_LEGACY.test(s) ||
- RE_HSLA_LEGACY.test(s) ||
- s === 'transparent'
- );
- };
-
- Color$2.prototype.css = function (mode) {
- return rgb2css(this._rgb, mode);
- };
-
- const css = (...args) => new Color$2(...args, 'css');
- chroma$1.css = css;
-
- input$1.format.css = css2rgb;
-
- input$1.autodetect.push({
- p: 5,
- test: (h, ...rest) => {
- if (!rest.length && type(h) === 'string' && css2rgb.test(h)) {
- return 'css';
- }
- }
- });
-
- input$1.format.gl = (...args) => {
- const rgb = unpack(args, 'rgba');
- rgb[0] *= 255;
- rgb[1] *= 255;
- rgb[2] *= 255;
- return rgb;
- };
-
- const gl = (...args) => new Color$2(...args, 'gl');
- chroma$1.gl = gl;
-
- Color$2.prototype.gl = function () {
- const rgb = this._rgb;
- return [rgb[0] / 255, rgb[1] / 255, rgb[2] / 255, rgb[3]];
- };
-
- Color$2.prototype.hcg = function () {
- return rgb2hcg(this._rgb);
- };
-
- const hcg = (...args) => new Color$2(...args, 'hcg');
- chroma$1.hcg = hcg;
-
- input$1.format.hcg = hcg2rgb;
-
- input$1.autodetect.push({
- p: 1,
- test: (...args) => {
- args = unpack(args, 'hcg');
- if (type(args) === 'array' && args.length === 3) {
- return 'hcg';
- }
- }
- });
-
- const RE_HEX = /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
- const RE_HEXA = /^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/;
-
- const hex2rgb = (hex) => {
- if (hex.match(RE_HEX)) {
- // remove optional leading #
- if (hex.length === 4 || hex.length === 7) {
- hex = hex.substr(1);
- }
- // expand short-notation to full six-digit
- if (hex.length === 3) {
- hex = hex.split('');
- hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
- }
- const u = parseInt(hex, 16);
- const r = u >> 16;
- const g = (u >> 8) & 0xff;
- const b = u & 0xff;
- return [r, g, b, 1];
- }
-
- // match rgba hex format, eg #FF000077
- if (hex.match(RE_HEXA)) {
- if (hex.length === 5 || hex.length === 9) {
- // remove optional leading #
- hex = hex.substr(1);
- }
- // expand short-notation to full eight-digit
- if (hex.length === 4) {
- hex = hex.split('');
- hex =
- hex[0] +
- hex[0] +
- hex[1] +
- hex[1] +
- hex[2] +
- hex[2] +
- hex[3] +
- hex[3];
- }
- const u = parseInt(hex, 16);
- const r = (u >> 24) & 0xff;
- const g = (u >> 16) & 0xff;
- const b = (u >> 8) & 0xff;
- const a = Math.round(((u & 0xff) / 0xff) * 100) / 100;
- return [r, g, b, a];
- }
-
- // we used to check for css colors here
- // if _input.css? and rgb = _input.css hex
- // return rgb
-
- throw new Error(`unknown hex color: ${hex}`);
- };
-
- const { round: round$2 } = Math;
-
- const rgb2hex = (...args) => {
- let [r, g, b, a] = unpack(args, 'rgba');
- let mode = last(args) || 'auto';
- if (a === undefined) a = 1;
- if (mode === 'auto') {
- mode = a < 1 ? 'rgba' : 'rgb';
- }
- r = round$2(r);
- g = round$2(g);
- b = round$2(b);
- const u = (r << 16) | (g << 8) | b;
- let str = '000000' + u.toString(16); //#.toUpperCase();
- str = str.substr(str.length - 6);
- let hxa = '0' + round$2(a * 255).toString(16);
- hxa = hxa.substr(hxa.length - 2);
- switch (mode.toLowerCase()) {
- case 'rgba':
- return `#${str}${hxa}`;
- case 'argb':
- return `#${hxa}${str}`;
- default:
- return `#${str}`;
- }
- };
-
- Color$2.prototype.hex = function (mode) {
- return rgb2hex(this._rgb, mode);
- };
-
- const hex = (...args) => new Color$2(...args, 'hex');
- chroma$1.hex = hex;
-
- input$1.format.hex = hex2rgb;
- input$1.autodetect.push({
- p: 4,
- test: (h, ...rest) => {
- if (
- !rest.length &&
- type(h) === 'string' &&
- [3, 4, 5, 6, 7, 8, 9].indexOf(h.length) >= 0
- ) {
- return 'hex';
- }
- }
- });
-
- Color$2.prototype.hsi = function () {
- return rgb2hsi(this._rgb);
- };
-
- const hsi = (...args) => new Color$2(...args, 'hsi');
- chroma$1.hsi = hsi;
-
- input$1.format.hsi = hsi2rgb;
-
- input$1.autodetect.push({
- p: 2,
- test: (...args) => {
- args = unpack(args, 'hsi');
- if (type(args) === 'array' && args.length === 3) {
- return 'hsi';
- }
- }
- });
-
- Color$2.prototype.hsl = function () {
- return rgb2hsl$2(this._rgb);
- };
-
- const hsl = (...args) => new Color$2(...args, 'hsl');
- chroma$1.hsl = hsl;
-
- input$1.format.hsl = hsl2rgb$1;
-
- input$1.autodetect.push({
- p: 2,
- test: (...args) => {
- args = unpack(args, 'hsl');
- if (type(args) === 'array' && args.length === 3) {
- return 'hsl';
- }
- }
- });
-
- Color$2.prototype.hsv = function () {
- return rgb2hsl$1(this._rgb);
- };
-
- const hsv = (...args) => new Color$2(...args, 'hsv');
- chroma$1.hsv = hsv;
-
- input$1.format.hsv = hsv2rgb;
-
- input$1.autodetect.push({
- p: 2,
- test: (...args) => {
- args = unpack(args, 'hsv');
- if (type(args) === 'array' && args.length === 3) {
- return 'hsv';
- }
- }
- });
-
- Color$2.prototype.lab = function () {
- return rgb2lab$1(this._rgb);
- };
-
- const lab = (...args) => new Color$2(...args, 'lab');
- Object.assign(chroma$1, { lab, getLabWhitePoint: getLabWhitePoint$1, setLabWhitePoint: setLabWhitePoint$1 });
-
- input$1.format.lab = lab2rgb$1;
-
- input$1.autodetect.push({
- p: 2,
- test: (...args) => {
- args = unpack(args, 'lab');
- if (type(args) === 'array' && args.length === 3) {
- return 'lab';
- }
- }
- });
-
- Color$2.prototype.lch = function () {
- return rgb2lch$1(this._rgb);
- };
- Color$2.prototype.hcl = function () {
- return reverse3(rgb2lch$1(this._rgb));
- };
-
- const lch = (...args) => new Color$2(...args, 'lch');
- const hcl = (...args) => new Color$2(...args, 'hcl');
-
- Object.assign(chroma$1, { lch, hcl });
-
- input$1.format.lch = lch2rgb$1;
- input$1.format.hcl = hcl2rgb;
- ['lch', 'hcl'].forEach((m) =>
- input$1.autodetect.push({
- p: 2,
- test: (...args) => {
- args = unpack(args, m);
- if (type(args) === 'array' && args.length === 3) {
- return m;
- }
- }
- })
- );
-
- Color$2.prototype.num = function () {
- return rgb2num(this._rgb);
- };
-
- const num = (...args) => new Color$2(...args, 'num');
-
- Object.assign(chroma$1, { num });
-
- input$1.format.num = num2rgb;
-
- input$1.autodetect.push({
- p: 5,
- test: (...args) => {
- if (
- args.length === 1 &&
- type(args[0]) === 'number' &&
- args[0] >= 0 &&
- args[0] <= 0xffffff
- ) {
- return 'num';
- }
- }
- });
-
- const { round: round$1 } = Math;
-
- Color$2.prototype.rgb = function (rnd = true) {
- if (rnd === false) return this._rgb.slice(0, 3);
- return this._rgb.slice(0, 3).map(round$1);
- };
-
- Color$2.prototype.rgba = function (rnd = true) {
- return this._rgb.slice(0, 4).map((v, i) => {
- return i < 3 ? (rnd === false ? v : round$1(v)) : v;
- });
- };
-
- const rgb = (...args) => new Color$2(...args, 'rgb');
- Object.assign(chroma$1, { rgb });
-
- input$1.format.rgb = (...args) => {
- const rgba = unpack(args, 'rgba');
- if (rgba[3] === undefined) rgba[3] = 1;
- return rgba;
- };
-
- input$1.autodetect.push({
- p: 3,
- test: (...args) => {
- args = unpack(args, 'rgba');
- if (
- type(args) === 'array' &&
- (args.length === 3 ||
- (args.length === 4 &&
- type(args[3]) == 'number' &&
- args[3] >= 0 &&
- args[3] <= 1))
- ) {
- return 'rgb';
- }
- }
- });
-
- /*
- * Based on implementation by Neil Bartlett
- * https://github.com/neilbartlett/color-temperature
- */
-
- const { log } = Math;
-
- const temperature2rgb = (kelvin) => {
- const temp = kelvin / 100;
- let r, g, b;
- if (temp < 66) {
- r = 255;
- g =
- temp < 6
- ? 0
- : -155.25485562709179 -
- 0.44596950469579133 * (g = temp - 2) +
- 104.49216199393888 * log(g);
- b =
- temp < 20
- ? 0
- : -254.76935184120902 +
- 0.8274096064007395 * (b = temp - 10) +
- 115.67994401066147 * log(b);
- } else {
- r =
- 351.97690566805693 +
- 0.114206453784165 * (r = temp - 55) -
- 40.25366309332127 * log(r);
- g =
- 325.4494125711974 +
- 0.07943456536662342 * (g = temp - 50) -
- 28.0852963507957 * log(g);
- b = 255;
- }
- return [r, g, b, 1];
- };
-
- /*
- * Based on implementation by Neil Bartlett
- * https://github.com/neilbartlett/color-temperature
- **/
-
- const { round } = Math;
-
- const rgb2temperature = (...args) => {
- const rgb = unpack(args, 'rgb');
- const r = rgb[0],
- b = rgb[2];
- let minTemp = 1000;
- let maxTemp = 40000;
- const eps = 0.4;
- let temp;
- while (maxTemp - minTemp > eps) {
- temp = (maxTemp + minTemp) * 0.5;
- const rgb = temperature2rgb(temp);
- if (rgb[2] / rgb[0] >= b / r) {
- maxTemp = temp;
- } else {
- minTemp = temp;
- }
- }
- return round(temp);
- };
-
- Color$2.prototype.temp =
- Color$2.prototype.kelvin =
- Color$2.prototype.temperature =
- function () {
- return rgb2temperature(this._rgb);
- };
-
- const temp = (...args) => new Color$2(...args, 'temp');
- Object.assign(chroma$1, { temp, kelvin: temp, temperature: temp });
-
- input$1.format.temp =
- input$1.format.kelvin =
- input$1.format.temperature =
- temperature2rgb;
-
- Color$2.prototype.oklab = function () {
- return rgb2oklab$1(this._rgb);
- };
-
- const oklab = (...args) => new Color$2(...args, 'oklab');
- Object.assign(chroma$1, { oklab });
-
- input$1.format.oklab = oklab2rgb$1;
-
- input$1.autodetect.push({
- p: 2,
- test: (...args) => {
- args = unpack(args, 'oklab');
- if (type(args) === 'array' && args.length === 3) {
- return 'oklab';
- }
- }
- });
-
- const oklch2rgb = (...args) => {
- args = unpack(args, 'lch');
- const [l, c, h, ...rest] = args;
- const [L, a, b_] = lch2lab(l, c, h);
- const [r, g, b] = oklab2rgb(L, a, b_);
- return [r, g, b, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
- };
-
- const rgb2oklch = (...args) => {
- const [r, g, b, ...rest] = unpack(args, 'rgb');
- const [l, a, b_] = rgb2oklab(r, g, b);
- const [L, c, h] = lab2lch(l, a, b_);
- return [L, c, h, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
- };
-
- Color$2.prototype.oklch = function () {
- return rgb2oklch(this._rgb);
- };
-
- const oklch = (...args) => new Color$2(...args, 'oklch');
- Object.assign(chroma$1, { oklch });
-
- input$1.format.oklch = oklch2rgb;
-
- input$1.autodetect.push({
- p: 2,
- test: (...args) => {
- args = unpack(args, 'oklch');
- if (type(args) === 'array' && args.length === 3) {
- return 'oklch';
- }
- }
- });
-
- // feel free to comment out anything to rollup
- // a smaller chroma.js bundle
-
- Object.assign(chroma$2, {
- analyze,
- average,
- bezier: bezier$1,
- blend,
- brewer: colorbrewerProxy,
- Color,
- colors: w3cx11,
- contrast,
- contrastAPCA,
- cubehelix,
- deltaE,
- distance,
- input,
- interpolate: mix,
- limits,
- mix,
- random: random$1,
- scale: scale$1,
- scales,
- valid
- });
-
- exports.Color = Color;
- exports.analyze = analyze;
- exports.average = average;
- exports.bezier = bezier$1;
- exports.blend = blend;
- exports.brewer = colorbrewerProxy;
- exports.cmyk = cmyk;
- exports.colors = w3cx11;
- exports.contrast = contrast;
- exports.contrastAPCA = contrastAPCA;
- exports.css = css;
- exports.cubehelix = cubehelix;
- exports.default = chroma$2;
- exports.deltaE = deltaE;
- exports.distance = distance;
- exports.getLabWhitePoint = getLabWhitePoint$1;
- exports.gl = gl;
- exports.hcg = hcg;
- exports.hcl = hcl;
- exports.hex = hex;
- exports.hsi = hsi;
- exports.hsl = hsl;
- exports.hsv = hsv;
- exports.input = input;
- exports.interpolate = mix;
- exports.kelvin = temp;
- exports.lab = lab;
- exports.lch = lch;
- exports.limits = limits;
- exports.mix = mix;
- exports.num = num;
- exports.oklab = oklab;
- exports.oklch = oklch;
- exports.random = random$1;
- exports.rgb = rgb;
- exports.scale = scale$1;
- exports.scales = scales;
- exports.setLabWhitePoint = setLabWhitePoint$1;
- exports.temp = temp;
- exports.temperature = temp;
- exports.valid = valid;
- }));