UNPKG

@visulima/colorize

Version:

Terminal and Console string styling done right.

506 lines (496 loc) 15.7 kB
'use strict'; Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } }); const convertHexToRgb = require('./convertHexToRgb-DDy3Eccg.cjs'); const colorNames = { aliceblue: [240, 248, 255], antiquewhite: [250, 235, 215], aqua: [0, 255, 255], aquamarine: [127, 255, 212], azure: [240, 255, 255], beige: [245, 245, 220], bisque: [255, 228, 196], black: [0, 0, 0], blanchedalmond: [255, 235, 205], blue: [0, 0, 255], blueviolet: [138, 43, 226], brown: [165, 42, 42], burlywood: [222, 184, 135], cadetblue: [95, 158, 160], chartreuse: [127, 255, 0], chocolate: [210, 105, 30], coral: [255, 127, 80], cornflowerblue: [100, 149, 237], cornsilk: [255, 248, 220], crimson: [220, 20, 60], cyan: [0, 255, 255], darkblue: [0, 0, 139], darkcyan: [0, 139, 139], darkgoldenrod: [184, 134, 11], darkgray: [169, 169, 169], darkgreen: [0, 100, 0], darkgrey: [169, 169, 169], darkkhaki: [189, 183, 107], darkmagenta: [139, 0, 139], darkolivegreen: [85, 107, 47], darkorange: [255, 140, 0], darkorchid: [153, 50, 204], darkred: [139, 0, 0], darksalmon: [233, 150, 122], darkseagreen: [143, 188, 143], darkslateblue: [72, 61, 139], darkslategray: [47, 79, 79], darkslategrey: [47, 79, 79], darkturquoise: [0, 206, 209], darkviolet: [148, 0, 211], deeppink: [255, 20, 147], deepskyblue: [0, 191, 255], dimgray: [105, 105, 105], dimgrey: [105, 105, 105], dodgerblue: [30, 144, 255], firebrick: [178, 34, 34], floralwhite: [255, 250, 240], forestgreen: [34, 139, 34], fuchsia: [255, 0, 255], gainsboro: [220, 220, 220], ghostwhite: [248, 248, 255], gold: [255, 215, 0], goldenrod: [218, 165, 32], gray: [128, 128, 128], green: [0, 128, 0], greenyellow: [173, 255, 47], grey: [128, 128, 128], honeydew: [240, 255, 240], hotpink: [255, 105, 180], indianred: [205, 92, 92], indigo: [75, 0, 130], ivory: [255, 255, 240], khaki: [240, 230, 140], lavender: [230, 230, 250], lavenderblush: [255, 240, 245], lawngreen: [124, 252, 0], lemonchiffon: [255, 250, 205], lightblue: [173, 216, 230], lightcoral: [240, 128, 128], lightcyan: [224, 255, 255], lightgoldenrodyellow: [250, 250, 210], lightgray: [211, 211, 211], lightgreen: [144, 238, 144], lightgrey: [211, 211, 211], lightpink: [255, 182, 193], lightsalmon: [255, 160, 122], lightseagreen: [32, 178, 170], lightskyblue: [135, 206, 250], lightslategray: [119, 136, 153], lightslategrey: [119, 136, 153], lightsteelblue: [176, 196, 222], lightyellow: [255, 255, 224], lime: [0, 255, 0], limegreen: [50, 205, 50], linen: [250, 240, 230], magenta: [255, 0, 255], maroon: [128, 0, 0], mediumaquamarine: [102, 205, 170], mediumblue: [0, 0, 205], mediumorchid: [186, 85, 211], mediumpurple: [147, 112, 219], mediumseagreen: [60, 179, 113], mediumslateblue: [123, 104, 238], mediumspringgreen: [0, 250, 154], mediumturquoise: [72, 209, 204], mediumvioletred: [199, 21, 133], midnightblue: [25, 25, 112], mintcream: [245, 255, 250], mistyrose: [255, 228, 225], moccasin: [255, 228, 181], navajowhite: [255, 222, 173], navy: [0, 0, 128], oldlace: [253, 245, 230], olive: [128, 128, 0], olivedrab: [107, 142, 35], orange: [255, 165, 0], orangered: [255, 69, 0], orchid: [218, 112, 214], palegoldenrod: [238, 232, 170], palegreen: [152, 251, 152], paleturquoise: [175, 238, 238], palevioletred: [219, 112, 147], papayawhip: [255, 239, 213], peachpuff: [255, 218, 185], peru: [205, 133, 63], pink: [255, 192, 203], plum: [221, 160, 221], powderblue: [176, 224, 230], purple: [128, 0, 128], rebeccapurple: [102, 51, 153], red: [255, 0, 0], rosybrown: [188, 143, 143], royalblue: [65, 105, 225], saddlebrown: [139, 69, 19], salmon: [250, 128, 114], sandybrown: [244, 164, 96], seagreen: [46, 139, 87], seashell: [255, 245, 238], sienna: [160, 82, 45], silver: [192, 192, 192], skyblue: [135, 206, 235], slateblue: [106, 90, 205], slategray: [112, 128, 144], slategrey: [112, 128, 144], snow: [255, 250, 250], springgreen: [0, 255, 127], steelblue: [70, 130, 180], tan: [210, 180, 140], teal: [0, 128, 128], thistle: [216, 191, 216], tomato: [255, 99, 71], turquoise: [64, 224, 208], violet: [238, 130, 238], wheat: [245, 222, 179], white: [255, 255, 255], whitesmoke: [245, 245, 245], yellow: [255, 255, 0], yellowgreen: [154, 205, 50] }; var __defProp$4 = Object.defineProperty; var __name$4 = (target, value) => __defProp$4(target, "name", { value, configurable: true }); const computeSubSteps = /* @__PURE__ */ __name$4((stops, steps) => { const l = stops.length; steps = Number.parseInt(steps.toString(), 10); if (Number.isNaN(steps) || steps < 2) { throw new Error("Invalid number of steps (< 2)"); } if (steps < l) { throw new Error("Number of steps cannot be inferior to number of stops"); } const substeps = []; for (let index = 1; index < l; index++) { const step = (steps - 1) * (stops[index].position - stops[index - 1].position); substeps.push(Math.max(1, Math.round(step))); } let totalSubsteps = 1; for (let n = l - 1; n--; ) { totalSubsteps += substeps[n]; } while (totalSubsteps !== steps) { if (totalSubsteps < steps) { const min = Math.min(...substeps); substeps[substeps.indexOf(min)]++; totalSubsteps++; } else { const max = Math.max(...substeps); substeps[substeps.indexOf(max)]--; totalSubsteps--; } } return substeps; }, "computeSubSteps"); var __defProp$3 = Object.defineProperty; var __name$3 = (target, value) => __defProp$3(target, "name", { value, configurable: true }); const hsvToRgb = /* @__PURE__ */ __name$3((h, s, v) => { let r = 0; let g = 0; let b = 0; const index = Math.floor(h / 60); const f = h / 60 - index; const p = v * (1 - s); const q = v * (1 - f * s); const t = v * (1 - (1 - f) * s); if (index % 6 === 0) { r = v; g = t; b = p; } else if (index % 6 === 1) { r = q; g = v; b = p; } else if (index % 6 === 2) { r = p; g = v; b = t; } else if (index % 6 === 3) { r = p; g = q; b = v; } else if (index % 6 === 4) { r = t; g = p; b = v; } else if (index % 6 === 5) { r = v; g = p; b = q; } return { b: Math.round(b * 255), g: Math.round(g * 255), r: Math.round(r * 255) }; }, "hsvToRgb"); var __defProp$2 = Object.defineProperty; var __name$2 = (target, value) => __defProp$2(target, "name", { value, configurable: true }); const rgbToHsv = /* @__PURE__ */ __name$2(({ b, g, r }) => { let rdif; let gdif; let bdif; let h = 0; let s = 0; r /= 255; g /= 255; b /= 255; const v = Math.max(r, g, b); const diff = v - Math.min(r, g, b); const diffc = /* @__PURE__ */ __name$2((c) => (v - c) / 6 / diff + 1 / 2, "diffc"); if (diff !== 0) { s = diff / v; rdif = diffc(r); gdif = diffc(g); bdif = diffc(b); if (v === r) { h = bdif - gdif; } else if (v === g) { h = 1 / 3 + rdif - bdif; } else if (v === b) { h = 2 / 3 + gdif - rdif; } if (h < 0) { h += 1; } else if (h > 1) { h -= 1; } } return { h: h * 360, s, v }; }, "rgbToHsv"); var __defProp$1 = Object.defineProperty; var __name$1 = (target, value) => __defProp$1(target, "name", { value, configurable: true }); const RGBA_MAX = { b: 256, g: 256, r: 256 }; const HSV_MAX = { h: 360, s: 1, v: 1 }; const calculateStepSize = /* @__PURE__ */ __name$1((start, end, steps) => { const step = {}; for (const k in start) { if (Object.prototype.hasOwnProperty.call(start, k)) { step[k] = steps === 0 ? 0 : (end[k] - start[k]) / steps; } } return step; }, "calculateStepSize"); const interpolate = /* @__PURE__ */ __name$1((step, start, index, max) => { const color = {}; for (const k in start) { if (Object.prototype.hasOwnProperty.call(start, k)) { color[k] = step[k] * index + start[k]; color[k] = // eslint-disable-next-line security/detect-object-injection color[k] < 0 ? ( // eslint-disable-next-line security/detect-object-injection color[k] + max[k] ) : ( // eslint-disable-next-line security/detect-object-injection max[k] === 1 ? ( // eslint-disable-next-line security/detect-object-injection color[k] ) : ( // eslint-disable-next-line security/detect-object-injection color[k] % max[k] ) ); } } return color; }, "interpolate"); const interpolateRgb = /* @__PURE__ */ __name$1((stop1, stop2, steps) => { const start = { b: stop1.color[2], g: stop1.color[1], r: stop1.color[0] }; const end = { b: stop2.color[2], g: stop2.color[1], r: stop2.color[0] }; const step = calculateStepSize(start, end, steps); const gradient = [{ ...start }]; for (let index = 1; index < steps; index++) { const color = interpolate(step, start, index, RGBA_MAX); gradient.push({ b: Math.floor(color.b), g: Math.floor(color.g), r: Math.floor(color.r) }); } return gradient; }, "interpolateRgb"); const interpolateHsv = /* @__PURE__ */ __name$1((stop1, stop2, steps, mode) => { const start = rgbToHsv({ b: stop1.color[2], g: stop1.color[1], r: stop1.color[0] }); const end = rgbToHsv({ b: stop2.color[2], g: stop2.color[1], r: stop2.color[0] }); if (start.s === 0 || end.s === 0) { return interpolateRgb(stop1, stop2, steps); } let trigonometric; if (typeof mode === "boolean") { trigonometric = mode; } else { const trigShortest = start.h < end.h && end.h - start.h < 180 || start.h > end.h && start.h - end.h > 180; trigonometric = mode === "long" && trigShortest || mode === "short" && !trigShortest; } const step = calculateStepSize(start, end, steps); const gradient = [ { b: stop1.color[2], g: stop1.color[1], r: stop1.color[0] } ]; let diff; if (start.h <= end.h && !trigonometric || start.h >= end.h && trigonometric) { diff = end.h - start.h; } else if (trigonometric) { diff = 360 - end.h + start.h; } else { diff = 360 - start.h + end.h; } step.h = (-1) ** (trigonometric ? 1 : 0) * Math.abs(diff) / steps; for (let index = 1; index < steps; index++) { const color = interpolate(step, start, index, HSV_MAX); gradient.push(hsvToRgb(color.h, color.s, color.v)); } return gradient; }, "interpolateHsv"); var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); class GradientBuilder { static { __name(this, "GradientBuilder"); } #colorize; stops; // eslint-disable-next-line sonarjs/cognitive-complexity constructor(colorize, stops) { this.#colorize = colorize; this.stops = []; if (stops.length < 2) { throw new Error("Invalid number of stops (< 2)"); } const havingPositions = stops[0].position !== void 0; let l = stops.length; let p = -1; let lastColorLess = false; for (const [index, stop_] of stops.entries()) { let stop = {}; const hasPosition = stop_.position !== void 0; if (havingPositions !== hasPosition) { throw new Error("Cannot mix positioned and non-positioned color stops"); } if (hasPosition) { const stopInput = stop_; const hasColor = stopInput.color !== void 0; if (!hasColor && (lastColorLess || index === 0 || index === l - 1)) { throw new Error("Cannot define two consecutive position-only stops"); } lastColorLess = !hasColor; let color; if (hasColor) { if (Array.isArray(stopInput.color)) { color = stopInput.color; } else if (typeof stopInput.color === "string") { color = stopInput.color.includes("#") ? convertHexToRgb.convertHexToRgb(stopInput.color) : colorNames[stopInput.color]; } else if (stopInput.color.r !== void 0 && stopInput.color.g !== void 0 && stopInput.color.b) { color = [stopInput.color.r, stopInput.color.g, stopInput.color.b]; } } stop = { color, colorLess: !hasColor, position: stopInput.position }; if (stop.position < 0 || stop.position > 1) { throw new Error("Color stops positions must be between 0 and 1"); } else if (stop.position < p) { throw new Error("Color stops positions are not ordered"); } p = stop.position; } else if (Array.isArray(stop_)) { stop = { color: stop_, position: index / (l - 1) }; } else if (typeof stop_ === "string") { stop = { color: stop_.includes("#") ? convertHexToRgb.convertHexToRgb(stop_) : colorNames[stop_], position: index / (l - 1) }; } else if (stop_.r !== void 0 && stop_.g !== void 0 && stop_.b !== void 0) { stop = { color: [stop_.r, stop_.g, stop_.b], position: index / (l - 1) }; } else { throw new Error("Invalid color stop"); } this.stops.push(stop); } if (this.stops[0].position !== 0) { this.stops.unshift({ color: this.stops[0].color, position: 0 }); l++; } if (this.stops[l - 1].position !== 1) { this.stops.push({ color: this.stops[l - 1].color, position: 1 }); } } reverse() { const stops = []; for (const stop of this.stops) { const stop_ = { ...stop }; stop_.position = 1 - stop.position; stops.push(stop_); } return new GradientBuilder(this.#colorize, stops.reverse()); } loop() { const stops1 = []; const stops2 = []; for (const stop of this.stops) { stops1.push({ color: stop.color, position: (stop.position || 0) / 2 }); } for (const stop of this.stops.slice(0, -1)) { stops2.push({ color: stop.color, position: 1 - (stop.position || 0) / 2 }); } return new GradientBuilder(this.#colorize, [...stops1, ...stops2.reverse()]); } rgb(steps) { const subSteps = computeSubSteps(this.stops, steps); const gradient = []; this.stops.forEach((stop, index) => { if (stop.colorLess) { const rgbs = interpolateRgb(this.stops[index - 1], this.stops[index + 1], 2); stop.color = [rgbs[1].r, rgbs[1].g, rgbs[1].b]; } }); for (let index = 0, l = this.stops.length; index < l - 1; index++) { const rgbs = interpolateRgb(this.stops[index], this.stops[index + 1], subSteps[index]); gradient.splice(gradient.length, 0, ...rgbs.map((rgb) => this.#colorize.rgb(rgb.r, rgb.g, rgb.b))); } gradient.push(this.#colorize.rgb(...this.stops.at(-1).color)); return gradient; } hsv(steps, mode = false) { const subSteps = computeSubSteps(this.stops, steps); const gradient = []; this.stops.forEach((stop, index) => { if (stop.colorLess) { const rgbs = interpolateHsv(this.stops[index - 1], this.stops[index + 1], 2, mode); stop.color = [rgbs[1].r, rgbs[1].g, rgbs[1].b]; } }); for (let index = 0, l = this.stops.length; index < l - 1; index++) { const rgbs = interpolateHsv(this.stops[index], this.stops[index + 1], subSteps[index], mode); gradient.splice(gradient.length, 0, ...rgbs.map((rgb) => this.#colorize.rgb(rgb.r, rgb.g, rgb.b))); } gradient.push(this.#colorize.rgb(...this.stops.at(-1).color)); return gradient; } } exports.GradientBuilder = GradientBuilder;