function tohex(n) { var s = Math.floor(n).toString(16); if (s.length === 1) s = "0" + s; return s.toUpperCase(); }; var Color = { white: [1, 1, 1], black: [0, 0, 0], blue: [0, 0, 1], green: [0, 1, 0], yellow: [1, 1, 0], red: [1, 0, 0], gray: [0.71, 0.71, 0.71], cyan: [0, 1, 1], purple: [0.635, 0.365, 0.89], orange: [1, 0.565, 0.251], magenta: [1, 0, 1], }; Color.editor = {}; Color.editor.ur = Color.green; Color.tohtml = function (v) { var html = v.map(function (n) { return tohex(n * 255); }); return "#" + html.join(""); }; var esc = {}; esc.reset = "\x1b[0"; esc.color = function (v) { var c = v.map(function (n) { return Math.floor(n * 255); }); var truecolor = "\x1b[38;2;" + c.join(";") + ";"; return truecolor; }; esc.doc = "Functions and constants for ANSI escape sequences."; Color.Arkanoid = { orange: [1, 0.561, 0], teal: [0, 1, 1], green: [0, 1, 0], red: [1, 0, 0], blue: [0, 0.439, 1], purple: [1, 0, 1], yellow: [1, 1, 0], silver: [0.616, 0.616, 0.616], gold: [0.737, 0.682, 0], }; Color.Arkanoid.Powerups = { red: [0.682, 0, 0] /* laser */, blue: [0, 0, 0.682] /* enlarge */, green: [0, 0.682, 0] /* catch */, orange: [0.878, 0.561, 0] /* slow */, purple: [0.824, 0, 0.824] /* break */, cyan: [0, 0.682, 1] /* disruption */, gray: [0.561, 0.561, 0.561] /* 1up */, }; Color.Gameboy = { darkest: [0.898, 0.42, 0.102], dark: [0.898, 0.741, 0.102], light: [0.741, 0.898, 0.102], lightest: [0.42, 0.898, 0.102], }; Color.Apple = { green: [0.369, 0.741, 0.243], yellow: [1, 0.725, 0], orange: [0.969, 0.51, 0], red: [0.886, 0.22, 0.22], purple: [0.592, 0.224, 0.6], blue: [0, 0.612, 0.875], }; Color.Debug = { boundingbox: Color.white, names: [0.329, 0.431, 1], }; Color.Editor = { grid: [0.388, 1, 0.502], select: [1, 1, 0.216], newgroup: [0.471, 1, 0.039], }; /* Detects the format of all colors and munges them into a floating point format */ Color.normalize = function (c) { var add_a = function (a) { var n = this.slice(); n[3] = a; return n; }; for (var p of Object.keys(c)) { if (typeof c[p] !== "object") continue; if (!Array.isArray(c[p])) { Color.normalize(c[p]); continue; } // Add alpha channel if not present if (c[p].length === 3) { c[p][3] = 1; } // Check if any values are > 1 (meaning they're in 0-255 format) var needs_conversion = false; for (var color of c[p]) { if (color > 1) { needs_conversion = true; break; } } // Convert from 0-255 to 0-1 if needed if (needs_conversion) { c[p] = c[p].map(function (x) { return x / 255; }); } c[p].alpha = add_a; } }; Color.normalize(Color); var ColorMap = {}; ColorMap.makemap = function (map) { var newmap = Object.create(ColorMap); Object.assign(newmap, map); return newmap; }; ColorMap.Jet = ColorMap.makemap({ 0: [0, 0, 0.514], 0.125: [0, 0.235, 0.667], 0.375: [0.02, 1, 1], 0.625: [1, 1, 0], 0.875: [0.98, 0, 0], 1: [0.502, 0, 0], }); ColorMap.BlueRed = ColorMap.makemap({ 0: [0, 0, 1], 1: [1, 0, 0], }); ColorMap.Inferno = ColorMap.makemap({ 0: [0, 0, 0.016], 0.13: [0.122, 0.047, 0.282], 0.25: [0.333, 0.059, 0.427], 0.38: [0.533, 0.133, 0.416], 0.5: [0.729, 0.212, 0.333], 0.63: [0.89, 0.349, 0.2], 0.75: [0.976, 0.549, 0.039], 0.88: [0.976, 0.788, 0.196], 1: [0.988, 1, 0.643], }); ColorMap.Bathymetry = ColorMap.makemap({ 0: [0.157, 0.102, 0.173], 0.13: [0.233, 0.192, 0.353], 0.25: [0.251, 0.298, 0.545], 0.38: [0.247, 0.431, 0.592], 0.5: [0.282, 0.557, 0.62], 0.63: [0.333, 0.682, 0.639], 0.75: [0.471, 0.808, 0.639], 0.88: [0.733, 0.902, 0.675], 1: [0.992, 0.996, 0.8], }); ColorMap.Viridis = ColorMap.makemap({ 0: [0.267, 0.004, 0.329], 0.13: [0.278, 0.173, 0.478], 0.25: [0.231, 0.318, 0.545], 0.38: [0.173, 0.443, 0.557], 0.5: [0.129, 0.565, 0.553], 0.63: [0.153, 0.678, 0.506], 0.75: [0.361, 0.784, 0.388], 0.88: [0.667, 0.863, 0.196], 1: [0.992, 0.906, 0.145], }); Color.normalize(ColorMap); ColorMap.sample = function (t, map = this) { if (t < 0) return map[0]; if (t > 1) return map[1]; var lastkey = 0; for (var key of Object.keys(map).sort()) { if (t < key) { var b = map[key]; var a = map[lastkey]; var tt = (key - lastkey) * t; return a.lerp(b, tt); } lastkey = key; } return map[1]; }; ColorMap.doc = { sample: "Sample a given colormap at the given percentage (0 to 1).", }; Color.maps = ColorMap Color.utils = esc return Color