@teaui/core
Version:
A high-level terminal UI library for Node
285 lines • 8.72 kB
JavaScript
;
/**
* colors.js - color-related functions for blessed.
* Copyright (c) 2013-2015, Christopher Jeffrey and contributors (MIT License).
* https://github.com/chjj/blessed
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.reduce = exports.hexToRGB = exports.HSBtoRGB = exports.RGBtoHSB = exports.RGBtoHex = exports.match = exports.indexToHex = exports.indexToRGB = exports.toHex = exports.nameToIndex = void 0;
var colorNames = {
// special
default: -1,
// normal
black: 0,
red: 1,
green: 2,
yellow: 3,
blue: 4,
magenta: 5,
cyan: 6,
white: 7,
grey: 8,
gray: 8,
brightRed: 9,
brightGreen: 10,
brightYellow: 11,
brightBlue: 12,
brightMagenta: 13,
brightCyan: 14,
brightWhite: 15,
};
const nameToIndex = name => exports.nameToIndex[name] ?? -1;
exports.nameToIndex = nameToIndex;
const toHex = function (n) {
n = n.toString(16);
if (n.length < 2)
n = '0' + n;
return n;
};
exports.toHex = toHex;
// Seed all 256 colors. Assume xterm defaults.
// Ported from the xterm color generation script.
const [indexToRGB_table, indexToHex_table] = (function () {
var rgb = [], hex = [], r, g, b, i, l;
const xtermColors = [
'#000000', // black
'#800000', // red3
'#008000', // green3
'#808000', // yellow3
'#000080', // blue2
'#800080', // magenta3
'#008080', // cyan3
'#c0c0c0', // gray90
'#808080', // gray50
'#ff0000', // red
'#00ff00', // green
'#ffff00', // yellow
'#0000ff', // rgb:5c/5c/ff
'#ff00ff', // magenta
'#00ffff', // cyan
'#ffffff', // white
];
function set(i, r, g, b) {
rgb[i] = [r, g, b];
hex[i] = '#' + (0, exports.toHex)(r) + (0, exports.toHex)(g) + (0, exports.toHex)(b);
}
// 0 - 15
xtermColors.forEach(function (c, i) {
c = parseInt(c.substring(1), 16);
set(i, (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff);
});
// 16 - 231
for (r = 0; r < 6; r++) {
for (g = 0; g < 6; g++) {
for (b = 0; b < 6; b++) {
i = 16 + r * 36 + g * 6 + b;
set(i, r ? r * 40 + 55 : 0, g ? g * 40 + 55 : 0, b ? b * 40 + 55 : 0);
}
}
}
// 232 - 255 are grey.
for (g = 0; g < 24; g++) {
l = g * 10 + 8;
i = 232 + g;
set(i, l, l, l);
}
return [rgb, hex];
})();
const indexToRGB = index => indexToRGB_table[~~index % 255];
exports.indexToRGB = indexToRGB;
const indexToHex = index => indexToHex_table[~~index % 255];
exports.indexToHex = indexToHex;
const _cache = {};
const match = function (r1, g1, b1, lookup) {
if (typeof r1 === 'string') {
const colorName = r1.replace(/[\- ]/g, '').toLowerCase();
if (colorNames[colorName] != null) {
return colorNames[colorName];
}
if (r1[0] !== '#') {
return -1;
}
const match = /^#([a-zA-Z0-9]+)\((\d+)\)$/.exec(r1);
if (match) {
return +match[2];
}
;
[r1, g1, b1] = (0, exports.hexToRGB)(r1);
}
else if (Array.isArray(r1)) {
;
(b1 = r1[2]), (g1 = r1[1]), (r1 = r1[0]);
}
const hash = (r1 << 16) | (g1 << 8) | b1;
if (_cache[hash] !== undefined) {
return _cache[hash];
}
// assign (or convert) lookup as a list of color index (using the 8-bit table)
// 0-15: user configurable
// 16-231: 6-bit color cube (16 === black, 231 === white)
// 232-255: grayscale
let setCache = false;
if (!lookup) {
setCache = true;
// special handling for grayscale, uses black and grays from the color cube,
// and the grayscale palette
if (r1 === g1 && g1 === b1) {
lookup = indexToRGB_table
.slice(231, 256)
.map((rgb, index) => [231 + index, rgb]);
lookup.push([16, [0, 0, 0]]);
lookup.push([59, [95, 95, 95]]);
lookup.push([102, [135, 135, 135]]);
lookup.push([139, [175, 135, 175]]);
lookup.push([145, [175, 175, 175]]);
lookup.push([188, [215, 215, 215]]);
}
else {
// default case: don't rely on colors 0-15, they are user-configurable
lookup = indexToRGB_table.slice(16).map((rgb, index) => [16 + index, rgb]);
}
}
else {
lookup = lookup.map((rgb, index) => [index, rgb]);
}
var ldiff = Infinity, li = lookup[0][0];
for (const [index, rgb] of lookup) {
const r2 = rgb[0];
const g2 = rgb[1];
const b2 = rgb[2];
const diff = colorDistance(r1, g1, b1, r2, g2, b2);
if (diff === 0) {
li = index;
break;
}
if (diff < ldiff) {
ldiff = diff;
li = index;
}
}
if (setCache) {
_cache[hash] = li;
}
return li;
};
exports.match = match;
const RGBtoHex = function (r, g, b) {
if (Array.isArray(r)) {
;
(b = r[2]), (g = r[1]), (r = r[0]);
}
return '#' + (0, exports.toHex)(r) + (0, exports.toHex)(g) + (0, exports.toHex)(b);
};
exports.RGBtoHex = RGBtoHex;
const RGBtoHSB = function (r, g, b) {
if (Array.isArray(r)) {
;
(b = r[2]), (g = r[1]), (r = r[0]);
}
const max = Math.max(r, g, b), min = Math.min(r, g, b), d = max - min, s = max === 0 ? 0 : d / max, v = max / 255;
let h;
switch (max) {
case min:
h = 0;
break;
case r:
h = g - b + d * (g < b ? 6 : 0);
h /= 6 * d;
break;
case g:
h = b - r + d * 2;
h /= 6 * d;
break;
case b:
h = r - g + d * 4;
h /= 6 * d;
break;
}
return [h, s, v];
};
exports.RGBtoHSB = RGBtoHSB;
const HSBtoRGB = function (h, s, v) {
if (Array.isArray(h)) {
;
(v = h[2]), (s = h[1]), (h = h[0]);
}
const i = Math.floor(h * 6), f = h * 6 - i, p = v * (1 - s), q = v * (1 - f * s), t = v * (1 - (1 - f) * s);
let r, g, b;
switch (i % 6) {
case 0:
;
(r = v), (g = t), (b = p);
break;
case 1:
;
(r = q), (g = v), (b = p);
break;
case 2:
;
(r = p), (g = v), (b = t);
break;
case 3:
;
(r = p), (g = q), (b = v);
break;
case 4:
;
(r = t), (g = p), (b = v);
break;
case 5:
;
(r = v), (g = p), (b = q);
break;
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
};
exports.HSBtoRGB = HSBtoRGB;
const hexToRGB = function (hex) {
if (hex[0] !== '#') {
hex = '#' + hex;
}
// #rgb
if (hex.length === 4) {
hex = hex[0] + hex[1] + hex[1] + hex[2] + hex[2] + hex[3] + hex[3];
}
var col = parseInt(hex.substring(1), 16), r = (col >> 16) & 0xff, g = (col >> 8) & 0xff, b = col & 0xff;
return [r, g, b];
};
exports.hexToRGB = hexToRGB;
// As it happens, comparing how similar two colors are is really hard. Here is
// one of the simplest solutions, which doesn't require conversion to another
// color space, posted on stackoverflow[1]. Maybe someone better at math can
// propose a superior solution.
// [1] http://stackoverflow.com/questions/1633828
function colorDistance(r1, g1, b1, r2, g2, b2) {
// return (
// Math.pow(30 * (r1 - r2), 2) +
// Math.pow(59 * (g1 - g2), 2) +
// Math.pow(11 * (b1 - b2), 2)
// )
return Math.pow(r1 - r2, 2) + Math.pow(g1 - g2, 2) + Math.pow(b1 - b2, 2);
}
// Map higher colors to the first 8 colors.
// This allows translation of high colors to low colors on 8-color terminals.
const fourBitColors = (function () {
const lookupCopy = indexToRGB_table.slice(0, 16);
return indexToHex_table.map(color => (0, exports.match)(color, undefined, undefined, lookupCopy));
})();
const threeBitColors = (function () {
const lookupCopy = indexToRGB_table.slice(0, 8);
return indexToHex_table.map(color => (0, exports.match)(color, undefined, undefined, lookupCopy));
})();
const reduce = function (color, total) {
if (total <= 16) {
return color >= 16 ? fourBitColors[color] : color;
}
else if (total <= 8) {
return color >= 8 ? threeBitColors[color] : color;
}
else if (total <= 2) {
return color % 2;
}
return color;
};
exports.reduce = reduce;
//# sourceMappingURL=colors.js.map