| /* |
| * Copyright (C) 2009, 2013 Apple Inc. All rights reserved. |
| * Copyright (C) 2009 Joseph Pecoraro |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of Apple Inc. ("Apple") nor the names of |
| * its contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| WebInspector.Color = class Color |
| { |
| constructor(format, components) |
| { |
| this.format = format; |
| |
| if (format === WebInspector.Color.Format.HSL || format === WebInspector.Color.Format.HSLA) |
| this._hsla = components; |
| else |
| this._rgba = components; |
| |
| this.valid = !components.some(isNaN); |
| } |
| |
| // Static |
| |
| static fromString(colorString) |
| { |
| let value = colorString.toLowerCase().replace(/%|\s+/g, ""); |
| let transparentKeywords = ["transparent", "rgba(0,0,0,0)", "hsla(0,0,0,0)"]; |
| if (transparentKeywords.includes(value)) { |
| let color = new WebInspector.Color(WebInspector.Color.Format.Keyword, [0, 0, 0, 0]); |
| color.keyword = "transparent"; |
| color.original = colorString; |
| return color; |
| } |
| |
| // Simple - #hex, rgb(), keyword, hsl() |
| let simple = /^(?:#([0-9a-f]{3,8})|rgb\(([^)]+)\)|(\w+)|hsl\(([^)]+)\))$/i; |
| let match = colorString.match(simple); |
| if (match) { |
| if (match[1]) { // hex |
| let hex = match[1].toUpperCase(); |
| let len = hex.length; |
| if (len === 3) { |
| return new WebInspector.Color(WebInspector.Color.Format.ShortHEX, [ |
| parseInt(hex.charAt(0) + hex.charAt(0), 16), |
| parseInt(hex.charAt(1) + hex.charAt(1), 16), |
| parseInt(hex.charAt(2) + hex.charAt(2), 16), |
| 1 |
| ]); |
| } else if (len === 6) { |
| return new WebInspector.Color(WebInspector.Color.Format.HEX, [ |
| parseInt(hex.substring(0, 2), 16), |
| parseInt(hex.substring(2, 4), 16), |
| parseInt(hex.substring(4, 6), 16), |
| 1 |
| ]); |
| } else if (len === 4) { |
| return new WebInspector.Color(WebInspector.Color.Format.ShortHEXAlpha, [ |
| parseInt(hex.charAt(0) + hex.charAt(0), 16), |
| parseInt(hex.charAt(1) + hex.charAt(1), 16), |
| parseInt(hex.charAt(2) + hex.charAt(2), 16), |
| parseInt(hex.charAt(3) + hex.charAt(3), 16) / 255 |
| ]); |
| } else if (len === 8) { |
| return new WebInspector.Color(WebInspector.Color.Format.HEXAlpha, [ |
| parseInt(hex.substring(0, 2), 16), |
| parseInt(hex.substring(2, 4), 16), |
| parseInt(hex.substring(4, 6), 16), |
| parseInt(hex.substring(6, 8), 16) / 255 |
| ]); |
| } else |
| return null; |
| } else if (match[2]) { // rgb |
| let rgb = match[2].split(/\s*,\s*/); |
| if (rgb.length !== 3) |
| return null; |
| return new WebInspector.Color(WebInspector.Color.Format.RGB, [ |
| parseInt(rgb[0]), |
| parseInt(rgb[1]), |
| parseInt(rgb[2]), |
| 1 |
| ]); |
| } else if (match[3]) { // keyword |
| let keyword = match[3].toLowerCase(); |
| if (!WebInspector.Color.Keywords.hasOwnProperty(keyword)) |
| return null; |
| let color = new WebInspector.Color(WebInspector.Color.Format.Keyword, WebInspector.Color.Keywords[keyword].concat(1)); |
| color.keyword = keyword; |
| color.original = colorString; |
| return color; |
| } else if (match[4]) { // hsl |
| let hsl = match[4].replace(/%/g, "").split(/\s*,\s*/); |
| if (hsl.length !== 3) |
| return null; |
| return new WebInspector.Color(WebInspector.Color.Format.HSL, [ |
| parseInt(hsl[0]), |
| parseInt(hsl[1]), |
| parseInt(hsl[2]), |
| 1 |
| ]); |
| } |
| } |
| |
| // Advanced - rgba(), hsla() |
| let advanced = /^(?:rgba\(([^)]+)\)|hsla\(([^)]+)\))$/i; |
| match = colorString.match(advanced); |
| if (match) { |
| if (match[1]) { // rgba |
| let rgba = match[1].split(/\s*,\s*/); |
| if (rgba.length !== 4) |
| return null; |
| return new WebInspector.Color(WebInspector.Color.Format.RGBA, [ |
| parseInt(rgba[0]), |
| parseInt(rgba[1]), |
| parseInt(rgba[2]), |
| Number.constrain(parseFloat(rgba[3]), 0, 1) |
| ]); |
| } else if (match[2]) { // hsla |
| let hsla = match[2].replace(/%/g, "").split(/\s*,\s*/); |
| if (hsla.length !== 4) |
| return null; |
| return new WebInspector.Color(WebInspector.Color.Format.HSLA, [ |
| parseInt(hsla[0]), |
| parseInt(hsla[1]), |
| parseInt(hsla[2]), |
| Number.constrain(parseFloat(hsla[3]), 0, 1) |
| ]); |
| } |
| } |
| |
| return null; |
| } |
| |
| static rgb2hsv(r, g, b) |
| { |
| r /= 255; |
| g /= 255; |
| b /= 255; |
| |
| let min = Math.min(Math.min(r, g), b); |
| let max = Math.max(Math.max(r, g), b); |
| let delta = max - min; |
| |
| let h; |
| let s; |
| let v = max; |
| |
| if (delta === 0) |
| h = 0; |
| else if (max === r) |
| h = (60 * ((g - b) / delta)) % 360; |
| else if (max === g) |
| h = 60 * ((b - r) / delta) + 120; |
| else if (max === b) |
| h = 60 * ((r - g) / delta) + 240; |
| |
| if (h < 0) |
| h += 360; |
| |
| // Saturation |
| if (max === 0) |
| s = 0; |
| else |
| s = 1 - (min / max); |
| |
| return [h, s, v]; |
| } |
| |
| static hsv2rgb(h, s, v) |
| { |
| if (s === 0) |
| return [v, v, v]; |
| |
| h /= 60; |
| let i = Math.floor(h); |
| let data = [ |
| v * (1 - s), |
| v * (1 - s * (h - i)), |
| v * (1 - s * (1 - (h - i))) |
| ]; |
| let rgb; |
| |
| switch (i) { |
| case 0: |
| rgb = [v, data[2], data[0]]; |
| break; |
| case 1: |
| rgb = [data[1], v, data[0]]; |
| break; |
| case 2: |
| rgb = [data[0], v, data[2]]; |
| break; |
| case 3: |
| rgb = [data[0], data[1], v]; |
| break; |
| case 4: |
| rgb = [data[2], data[0], v]; |
| break; |
| default: |
| rgb = [v, data[0], data[1]]; |
| break; |
| } |
| |
| return rgb; |
| } |
| |
| |
| // Public |
| |
| nextFormat(format) |
| { |
| format = format || this.format; |
| |
| switch (format) { |
| case WebInspector.Color.Format.Original: |
| return this.simple ? WebInspector.Color.Format.RGB : WebInspector.Color.Format.RGBA; |
| |
| case WebInspector.Color.Format.RGB: |
| case WebInspector.Color.Format.RGBA: |
| return this.simple ? WebInspector.Color.Format.HSL : WebInspector.Color.Format.HSLA; |
| |
| case WebInspector.Color.Format.HSL: |
| case WebInspector.Color.Format.HSLA: |
| if (this.keyword) |
| return WebInspector.Color.Format.Keyword; |
| if (this.simple) |
| return this.canBeSerializedAsShortHEX() ? WebInspector.Color.Format.ShortHEX : WebInspector.Color.Format.HEX; |
| return this.canBeSerializedAsShortHEX() ? WebInspector.Color.Format.ShortHEXAlpha : WebInspector.Color.Format.HEXAlpha; |
| |
| case WebInspector.Color.Format.ShortHEX: |
| return WebInspector.Color.Format.HEX; |
| |
| case WebInspector.Color.Format.ShortHEXAlpha: |
| return WebInspector.Color.Format.HEXAlpha; |
| |
| case WebInspector.Color.Format.HEX: |
| case WebInspector.Color.Format.HEXAlpha: |
| return WebInspector.Color.Format.Original; |
| |
| case WebInspector.Color.Format.Keyword: |
| if (this.simple) |
| return this.canBeSerializedAsShortHEX() ? WebInspector.Color.Format.ShortHEX : WebInspector.Color.Format.HEX; |
| return this.canBeSerializedAsShortHEX() ? WebInspector.Color.Format.ShortHEXAlpha : WebInspector.Color.Format.HEXAlpha; |
| |
| default: |
| console.error("Unknown color format."); |
| return null; |
| } |
| } |
| |
| get alpha() |
| { |
| return this._rgba ? this._rgba[3] : this._hsla[3]; |
| } |
| |
| get simple() |
| { |
| return this.alpha === 1; |
| } |
| |
| get rgb() |
| { |
| let rgb = this.rgba.slice(); |
| rgb.pop(); |
| return rgb; |
| } |
| |
| get hsl() |
| { |
| let hsl = this.hsla.slice(); |
| hsl.pop(); |
| return hsl; |
| } |
| |
| get rgba() |
| { |
| if (!this._rgba) |
| this._rgba = this._hslaToRGBA(this._hsla); |
| return this._rgba; |
| } |
| |
| get hsla() |
| { |
| if (!this._hsla) |
| this._hsla = this._rgbaToHSLA(this.rgba); |
| return this._hsla; |
| } |
| |
| copy() |
| { |
| switch (this.format) { |
| case WebInspector.Color.Format.RGB: |
| case WebInspector.Color.Format.HEX: |
| case WebInspector.Color.Format.ShortHEX: |
| case WebInspector.Color.Format.HEXAlpha: |
| case WebInspector.Color.Format.ShortHEXAlpha: |
| case WebInspector.Color.Format.Keyword: |
| case WebInspector.Color.Format.RGBA: |
| return new WebInspector.Color(this.format, this.rgba); |
| case WebInspector.Color.Format.HSL: |
| case WebInspector.Color.Format.HSLA: |
| return new WebInspector.Color(this.format, this.hsla); |
| } |
| } |
| |
| toString(format) |
| { |
| if (!format) |
| format = this.format; |
| |
| switch (format) { |
| case WebInspector.Color.Format.Original: |
| return this._toOriginalString(); |
| case WebInspector.Color.Format.RGB: |
| return this._toRGBString(); |
| case WebInspector.Color.Format.RGBA: |
| return this._toRGBAString(); |
| case WebInspector.Color.Format.HSL: |
| return this._toHSLString(); |
| case WebInspector.Color.Format.HSLA: |
| return this._toHSLAString(); |
| case WebInspector.Color.Format.HEX: |
| return this._toHEXString(); |
| case WebInspector.Color.Format.ShortHEX: |
| return this._toShortHEXString(); |
| case WebInspector.Color.Format.HEXAlpha: |
| return this._toHEXAlphaString(); |
| case WebInspector.Color.Format.ShortHEXAlpha: |
| return this._toShortHEXAlphaString(); |
| case WebInspector.Color.Format.Keyword: |
| return this._toKeywordString(); |
| } |
| |
| throw "invalid color format"; |
| } |
| |
| isKeyword() |
| { |
| if (this.keyword) |
| return true; |
| |
| if (!this.simple) |
| return Array.shallowEqual(this._rgba, [0, 0, 0, 0]) || Array.shallowEqual(this._hsla, [0, 0, 0, 0]); |
| |
| let rgb = (this._rgba && this._rgba.slice(0, 3)) || this._hslToRGB(this._hsla); |
| return Object.keys(WebInspector.Color.Keywords).some(key => Array.shallowEqual(WebInspector.Color.Keywords[key], rgb)); |
| } |
| |
| canBeSerializedAsShortHEX() |
| { |
| let rgba = this.rgba || this._hslaToRGBA(this._hsla); |
| |
| let r = this._componentToHexValue(rgba[0]); |
| if (r[0] !== r[1]) |
| return false; |
| |
| let g = this._componentToHexValue(rgba[1]); |
| if (g[0] !== g[1]) |
| return false; |
| |
| let b = this._componentToHexValue(rgba[2]); |
| if (b[0] !== b[1]) |
| return false; |
| |
| if (!this.simple) { |
| let a = this._componentToHexValue(Math.round(rgba[3] * 255)); |
| if (a[0] !== a[1]) |
| return false; |
| } |
| |
| return true; |
| } |
| |
| // Private |
| |
| _toOriginalString() |
| { |
| return this.original || this._toKeywordString(); |
| } |
| |
| _toKeywordString() |
| { |
| if (this.keyword) |
| return this.keyword; |
| |
| let rgba = this.rgba; |
| if (!this.simple) { |
| if (rgba[0] === 0 && rgba[1] === 0 && rgba[2] === 0 && rgba[3] === 0) |
| return "transparent"; |
| return this._toRGBAString(); |
| } |
| |
| let keywords = WebInspector.Color.Keywords; |
| for (let keyword in keywords) { |
| if (!keywords.hasOwnProperty(keyword)) |
| continue; |
| |
| let keywordRGB = keywords[keyword]; |
| if (keywordRGB[0] === rgba[0] && keywordRGB[1] === rgba[1] && keywordRGB[2] === rgba[2]) |
| return keyword; |
| } |
| |
| return this._toRGBString(); |
| } |
| |
| _toShortHEXString() |
| { |
| if (!this.simple) |
| return this._toRGBAString(); |
| |
| let rgba = this.rgba; |
| let r = this._componentToHexValue(rgba[0]); |
| let g = this._componentToHexValue(rgba[1]); |
| let b = this._componentToHexValue(rgba[2]); |
| |
| if (r[0] === r[1] && g[0] === g[1] && b[0] === b[1]) |
| return "#" + r[0] + g[0] + b[0]; |
| else |
| return "#" + r + g + b; |
| } |
| |
| _toHEXString() |
| { |
| if (!this.simple) |
| return this._toRGBAString(); |
| |
| let rgba = this.rgba; |
| let r = this._componentToHexValue(rgba[0]); |
| let g = this._componentToHexValue(rgba[1]); |
| let b = this._componentToHexValue(rgba[2]); |
| |
| return "#" + r + g + b; |
| } |
| |
| _toShortHEXAlphaString() |
| { |
| let rgba = this.rgba; |
| let r = this._componentToHexValue(rgba[0]); |
| let g = this._componentToHexValue(rgba[1]); |
| let b = this._componentToHexValue(rgba[2]); |
| let a = this._componentToHexValue(Math.round(rgba[3] * 255)); |
| |
| if (r[0] === r[1] && g[0] === g[1] && b[0] === b[1] && a[0] === a[1]) |
| return "#" + r[0] + g[0] + b[0] + a[0]; |
| else |
| return "#" + r + g + b + a; |
| } |
| |
| _toHEXAlphaString() |
| { |
| let rgba = this.rgba; |
| let r = this._componentToHexValue(rgba[0]); |
| let g = this._componentToHexValue(rgba[1]); |
| let b = this._componentToHexValue(rgba[2]); |
| let a = this._componentToHexValue(Math.round(rgba[3] * 255)); |
| |
| return "#" + r + g + b + a; |
| } |
| |
| _toRGBString() |
| { |
| if (!this.simple) |
| return this._toRGBAString(); |
| |
| let rgba = this.rgba.slice(0, -1); |
| return "rgb(" + rgba.join(", ") + ")"; |
| } |
| |
| _toRGBAString() |
| { |
| return "rgba(" + this.rgba.join(", ") + ")"; |
| } |
| |
| _toHSLString() |
| { |
| if (!this.simple) |
| return this._toHSLAString(); |
| |
| let hsla = this.hsla; |
| return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)"; |
| } |
| |
| _toHSLAString() |
| { |
| let hsla = this.hsla; |
| return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, " + hsla[3] + ")"; |
| } |
| |
| _componentToNumber(value) |
| { |
| return Number.constrain(value, 0, 255); |
| } |
| |
| _componentToHexValue(value) |
| { |
| let hex = this._componentToNumber(value).toString(16); |
| if (hex.length === 1) |
| hex = "0" + hex; |
| return hex; |
| } |
| |
| _rgbToHSL(rgb) |
| { |
| let r = this._componentToNumber(rgb[0]) / 255; |
| let g = this._componentToNumber(rgb[1]) / 255; |
| let b = this._componentToNumber(rgb[2]) / 255; |
| let max = Math.max(r, g, b); |
| let min = Math.min(r, g, b); |
| let diff = max - min; |
| let add = max + min; |
| |
| let h; |
| let s; |
| let l = 0.5 * add; |
| |
| if (min === max) |
| h = 0; |
| else if (r === max) |
| h = ((60 * (g - b) / diff) + 360) % 360; |
| else if (g === max) |
| h = (60 * (b - r) / diff) + 120; |
| else |
| h = (60 * (r - g) / diff) + 240; |
| |
| if (l === 0) |
| s = 0; |
| else if (l === 1) |
| s = 1; |
| else if (l <= 0.5) |
| s = diff / add; |
| else |
| s = diff / (2 - add); |
| |
| return [ |
| Math.round(h), |
| Math.round(s * 100), |
| Math.round(l * 100) |
| ]; |
| } |
| |
| _hslToRGB(hsl) |
| { |
| let h = parseFloat(hsl[0]) / 360; |
| let s = parseFloat(hsl[1]) / 100; |
| let l = parseFloat(hsl[2]) / 100; |
| |
| h *= 6; |
| let sArray = [ |
| l += s *= l < .5 ? l : 1 - l, |
| l - h % 1 * s * 2, |
| l -= s *= 2, |
| l, |
| l + h % 1 * s, |
| l + s |
| ]; |
| return [ |
| Math.round(sArray[ ~~h % 6 ] * 255), |
| Math.round(sArray[ (h | 16) % 6 ] * 255), |
| Math.round(sArray[ (h | 8) % 6 ] * 255) |
| ]; |
| } |
| |
| _rgbaToHSLA(rgba) |
| { |
| let hsl = this._rgbToHSL(rgba); |
| hsl.push(rgba[3]); |
| return hsl; |
| } |
| |
| _hslaToRGBA(hsla) |
| { |
| let rgba = this._hslToRGB(hsla); |
| rgba.push(hsla[3]); |
| return rgba; |
| } |
| }; |
| |
| WebInspector.Color.Format = { |
| Original: "color-format-original", |
| Keyword: "color-format-keyword", |
| HEX: "color-format-hex", |
| ShortHEX: "color-format-short-hex", |
| HEXAlpha: "color-format-hex-alpha", |
| ShortHEXAlpha: "color-format-short-hex-alpha", |
| RGB: "color-format-rgb", |
| RGBA: "color-format-rgba", |
| HSL: "color-format-hsl", |
| HSLA: "color-format-hsla" |
| }; |
| |
| WebInspector.Color.Keywords = { |
| "aliceblue": [240, 248, 255], |
| "antiquewhite": [250, 235, 215], |
| "aquamarine": [127, 255, 212], |
| "azure": [240, 255, 255], |
| "beige": [245, 245, 220], |
| "bisque": [255, 228, 196], |
| "black": [0, 0, 0], |
| "blanchedalmond": [255, 235, 205], |
| "blue": [0, 0, 255], |
| "blueviolet": [138, 43, 226], |
| "brown": [165, 42, 42], |
| "burlywood": [222, 184, 135], |
| "cadetblue": [95, 158, 160], |
| "chartreuse": [127, 255, 0], |
| "chocolate": [210, 105, 30], |
| "coral": [255, 127, 80], |
| "cornflowerblue": [100, 149, 237], |
| "cornsilk": [255, 248, 220], |
| "crimson": [237, 164, 61], |
| "cyan": [0, 255, 255], |
| "darkblue": [0, 0, 139], |
| "darkcyan": [0, 139, 139], |
| "darkgoldenrod": [184, 134, 11], |
| "darkgray": [169, 169, 169], |
| "darkgreen": [0, 100, 0], |
| "darkkhaki": [189, 183, 107], |
| "darkmagenta": [139, 0, 139], |
| "darkolivegreen": [85, 107, 47], |
| "darkorange": [255, 140, 0], |
| "darkorchid": [153, 50, 204], |
| "darkred": [139, 0, 0], |
| "darksalmon": [233, 150, 122], |
| "darkseagreen": [143, 188, 143], |
| "darkslateblue": [72, 61, 139], |
| "darkslategray": [47, 79, 79], |
| "darkturquoise": [0, 206, 209], |
| "darkviolet": [148, 0, 211], |
| "deeppink": [255, 20, 147], |
| "deepskyblue": [0, 191, 255], |
| "dimgray": [105, 105, 105], |
| "dodgerblue": [30, 144, 255], |
| "firebrick": [178, 34, 34], |
| "floralwhite": [255, 250, 240], |
| "forestgreen": [34, 139, 34], |
| "gainsboro": [220, 220, 220], |
| "ghostwhite": [248, 248, 255], |
| "gold": [255, 215, 0], |
| "goldenrod": [218, 165, 32], |
| "gray": [128, 128, 128], |
| "green": [0, 128, 0], |
| "greenyellow": [173, 255, 47], |
| "honeydew": [240, 255, 240], |
| "hotpink": [255, 105, 180], |
| "indianred": [205, 92, 92], |
| "indigo": [75, 0, 130], |
| "ivory": [255, 255, 240], |
| "khaki": [240, 230, 140], |
| "lavender": [230, 230, 250], |
| "lavenderblush": [255, 240, 245], |
| "lawngreen": [124, 252, 0], |
| "lemonchiffon": [255, 250, 205], |
| "lightblue": [173, 216, 230], |
| "lightcoral": [240, 128, 128], |
| "lightcyan": [224, 255, 255], |
| "lightgoldenrodyellow": [250, 250, 210], |
| "lightgreen": [144, 238, 144], |
| "lightgrey": [211, 211, 211], |
| "lightpink": [255, 182, 193], |
| "lightsalmon": [255, 160, 122], |
| "lightseagreen": [32, 178, 170], |
| "lightskyblue": [135, 206, 250], |
| "lightslategray": [119, 136, 153], |
| "lightsteelblue": [176, 196, 222], |
| "lightyellow": [255, 255, 224], |
| "lime": [0, 255, 0], |
| "limegreen": [50, 205, 50], |
| "linen": [250, 240, 230], |
| "magenta": [255, 0, 255], |
| "maroon": [128, 0, 0], |
| "mediumaquamarine": [102, 205, 170], |
| "mediumblue": [0, 0, 205], |
| "mediumorchid": [186, 85, 211], |
| "mediumpurple": [147, 112, 219], |
| "mediumseagreen": [60, 179, 113], |
| "mediumslateblue": [123, 104, 238], |
| "mediumspringgreen": [0, 250, 154], |
| "mediumturquoise": [72, 209, 204], |
| "mediumvioletred": [199, 21, 133], |
| "midnightblue": [25, 25, 112], |
| "mintcream": [245, 255, 250], |
| "mistyrose": [255, 228, 225], |
| "moccasin": [255, 228, 181], |
| "navajowhite": [255, 222, 173], |
| "navy": [0, 0, 128], |
| "oldlace": [253, 245, 230], |
| "olive": [128, 128, 0], |
| "olivedrab": [107, 142, 35], |
| "orange": [255, 165, 0], |
| "orangered": [255, 69, 0], |
| "orchid": [218, 112, 214], |
| "palegoldenrod": [238, 232, 170], |
| "palegreen": [152, 251, 152], |
| "paleturquoise": [175, 238, 238], |
| "palevioletred": [219, 112, 147], |
| "papayawhip": [255, 239, 213], |
| "peachpuff": [255, 218, 185], |
| "peru": [205, 133, 63], |
| "pink": [255, 192, 203], |
| "plum": [221, 160, 221], |
| "powderblue": [176, 224, 230], |
| "purple": [128, 0, 128], |
| "rebeccapurple": [102, 51, 153], |
| "red": [255, 0, 0], |
| "rosybrown": [188, 143, 143], |
| "royalblue": [65, 105, 225], |
| "saddlebrown": [139, 69, 19], |
| "salmon": [250, 128, 114], |
| "sandybrown": [244, 164, 96], |
| "seagreen": [46, 139, 87], |
| "seashell": [255, 245, 238], |
| "sienna": [160, 82, 45], |
| "silver": [192, 192, 192], |
| "skyblue": [135, 206, 235], |
| "slateblue": [106, 90, 205], |
| "slategray": [112, 128, 144], |
| "snow": [255, 250, 250], |
| "springgreen": [0, 255, 127], |
| "steelblue": [70, 130, 180], |
| "tan": [210, 180, 140], |
| "teal": [0, 128, 128], |
| "thistle": [216, 191, 216], |
| "tomato": [255, 99, 71], |
| "turquoise": [64, 224, 208], |
| "violet": [238, 130, 238], |
| "wheat": [245, 222, 179], |
| "white": [255, 255, 255], |
| "whitesmoke": [245, 245, 245], |
| "yellow": [255, 255, 0], |
| "yellowgreen": [154, 205, 50] |
| }; |