UNPKG

photoeditorsdk-server

Version:

The most comprehensive photo editor SDK for Server Applications based on NodeJs

1,562 lines (1,550 loc) 1.2 MB
var __create = Object.create; var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __reExport = (target, module2, copyDefault, desc) => { if (module2 && typeof module2 === "object" || typeof module2 === "function") { for (let key of __getOwnPropNames(module2)) if (!__hasOwnProp.call(target, key) && (copyDefault || key !== "default")) __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); } return target; }; var __toESM = (module2, isNodeMode) => { return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", !isNodeMode && module2 && module2.__esModule ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); }; var __toCommonJS = /* @__PURE__ */ ((cache) => { return (module2, temp) => { return cache && cache.get(module2) || (temp = __reExport(__markAsModule({}), module2, 1), cache && cache.set(module2, temp), temp); }; })(typeof WeakMap !== "undefined" ? /* @__PURE__ */ new WeakMap() : 0); var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // engine/sdk/core/constants.ts var constants_exports = {}; __export(constants_exports, { FragmentPrecision: () => FragmentPrecision, ImageFormat: () => ImageFormat, OptionType: () => OptionType, RenderType: () => RenderType, RendererType: () => RendererType, UniformType: () => UniformType }); var RenderType, ImageFormat, OptionType, UniformType, RendererType, FragmentPrecision; var init_constants = __esm({ "engine/sdk/core/constants.ts"() { RenderType = { IMAGE: "image", DATAURL: "data-url", BUFFER: "buffer", BLOB: "blob", MSBLOB: "ms-blob" }; ImageFormat = { PNG: "image/png", JPEG: "image/jpeg", RAW: "raw" }; OptionType = /* @__PURE__ */ ((OptionType9) => { OptionType9["NUMBER"] = "number"; OptionType9["VECTOR2"] = "vector2"; OptionType9["COLOR_MATRIX"] = "color-matrix"; OptionType9["COLOR"] = "color"; OptionType9["ARRAY"] = "array"; OptionType9["OBJECT"] = "object"; OptionType9["STRING"] = "string"; OptionType9["BOOLEAN"] = "boolean"; OptionType9["CONFIGURABLE"] = "configurable"; OptionType9["IMAGE"] = "image"; OptionType9["FUNCTION"] = "function"; OptionType9["TEXTURE"] = "texture"; OptionType9["ALL"] = "*"; return OptionType9; })(OptionType || {}); UniformType = /* @__PURE__ */ ((UniformType8) => { UniformType8["SAMPLER2D"] = "sampler2d"; UniformType8["INT"] = "i"; UniformType8["INT1"] = "1i"; UniformType8["INT2"] = "2i"; UniformType8["INT3"] = "3i"; UniformType8["INT4"] = "4i"; UniformType8["FLOAT"] = "f"; UniformType8["FLOAT1"] = "1f"; UniformType8["FLOAT2"] = "2f"; UniformType8["FLOAT_VECTOR2"] = "2fv"; UniformType8["FLOAT3"] = "3f"; UniformType8["FLOAT4"] = "4f"; UniformType8["MAT3"] = "mat3"; UniformType8["MAT3FV"] = "mat3fv"; UniformType8["MAT4"] = "mat4"; return UniformType8; })(UniformType || {}); RendererType = /* @__PURE__ */ ((RendererType4) => { RendererType4["WEBGL"] = "webgl"; RendererType4["CANVAS"] = "canvas"; return RendererType4; })(RendererType || {}); FragmentPrecision = /* @__PURE__ */ ((FragmentPrecision2) => { FragmentPrecision2["High"] = "highp"; FragmentPrecision2["Medium"] = "mediump"; FragmentPrecision2["Low"] = "lowp"; return FragmentPrecision2; })(FragmentPrecision || {}); } }); // engine/sdk/core/engine/utils/pixel-array-image.ts var PixelArrayImage; var init_pixel_array_image = __esm({ "engine/sdk/core/engine/utils/pixel-array-image.ts"() { PixelArrayImage = class { constructor(width, height, data) { this.width = width; this.height = height; this.data = data; } }; } }); // engine/sdk/core/engine/utils/render/serverUtils.ts var serverUtils_exports = {}; __export(serverUtils_exports, { serverUtils: () => serverUtils }); var import_canvas, import_gl, nodeCanvasToPixelArray, glTexImage, serverUtils; var init_serverUtils = __esm({ "engine/sdk/core/engine/utils/render/serverUtils.ts"() { import_canvas = require("canvas"); import_gl = __toESM(require("gl")); init_pixel_array_image(); nodeCanvasToPixelArray = (image) => { const canvas = new import_canvas.Canvas(image.width, image.height); const context = canvas.getContext("2d"); context.drawImage(image, 0, 0); const imageData = context.getImageData(0, 0, image.width, image.height); return new PixelArrayImage(image.width, image.height, imageData.data); }; glTexImage = (gl, source) => { const image = source instanceof PixelArrayImage ? source : nodeCanvasToPixelArray(source); const canvas = new import_canvas.Canvas(image.width, image.height); const ctx = canvas.getContext("2d"); ctx.drawImage(source, 0, 0); const imageData = ctx.getImageData(0, 0, image.width, image.height); const pixels = new PixelArrayImage(image.width, image.height, imageData.data); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, image.width, image.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels.data); }; serverUtils = { isSupported: () => true, isCanvas: (node) => node instanceof import_canvas.Canvas, isImage: (node) => false, Image: import_canvas.Image, createCanvas: () => { return new import_canvas.Canvas(300, 150); }, glMaxTexture: (gl) => gl.getParameter(gl.MAX_TEXTURE_SIZE), glGet: (canvas) => (0, import_gl.default)(canvas.width, canvas.height, { preserveDrawingBuffer: true }), glResize(gl, vector) { const ext = gl.getExtension("STACKGL_resize_drawingbuffer"); if (ext) { ext.resize(vector.x, vector.y); } return gl; }, glTexImage }; } }); // engine/sdk/core/engine/utils/render/index.ts var utils, renderUtils, isWebGLRenderer, isWebCanvas, isWebImage; var init_render = __esm({ "engine/sdk/core/engine/utils/render/index.ts"() { init_constants(); if (false) { utils = null.webUtils; } if (true) { utils = (init_serverUtils(), __toCommonJS(serverUtils_exports)).serverUtils; } renderUtils = utils; isWebGLRenderer = (renderer) => renderer._type === "webgl" /* WEBGL */; isWebCanvas = (node) => Boolean(node && "tagName" in node && node.tagName && node.tagName.toUpperCase() === "CANVAS"); isWebImage = (image) => Boolean("tagName" in image && image.tagName.toUpperCase() === "IMG"); } }); // engine/sdk/core/lib/array-utils.js var ArrayUtils, array_utils_default; var init_array_utils = __esm({ "engine/sdk/core/lib/array-utils.js"() { ArrayUtils = class { static head(arr) { return arr[0]; } static tail(arr) { return arr.slice(1); } static last(arr) { return arr[arr.length - 1]; } static init(arr) { return arr.slice(0, arr.length - 1); } static remove(arr, func) { return arr.filter((v, i, arr2) => !func(v, i, arr2)); } static findIndex(array, func) { for (let i = 0; i < array.length; i++) { if (func(array[i])) { return i; } } return -1; } static find(array, func) { for (let i = 0; i < array.length; i++) { if (func(array[i])) { return array[i]; } } return void 0; } static flatten(array) { return array.reduce(function(flat, toFlatten) { return flat.concat(Array.isArray(toFlatten) ? ArrayUtils.flatten(toFlatten) : toFlatten); }, []); } static range(start, end) { const arr = []; if (end > start) { for (let i = start; i < end; i++) { arr.push(i); } } return arr; } static repeat(val, n) { const arr = []; for (let i = 0; i < n; i++) { arr[i] = val; } return arr; } static zip(a, b) { const len = Math.min(a.length, b.length); const arr = []; for (let i = 0; i < len; i++) { arr[i] = [a[i], b[i]]; } return arr; } }; array_utils_default = ArrayUtils; } }); // engine/sdk/core/lib/base64.js var KEY_STR, Base64, base64_default; var init_base64 = __esm({ "engine/sdk/core/lib/base64.js"() { KEY_STR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; Base64 = { encode(input) { let output = ""; let chr1; let chr2; let chr3; let enc1; let enc2; let enc3; let enc4; let i = 0; do { chr1 = input[i++]; chr2 = input[i++]; chr3 = input[i++]; enc1 = chr1 >> 2; enc2 = (chr1 & 3) << 4 | chr2 >> 4; enc3 = (chr2 & 15) << 2 | chr3 >> 6; enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + KEY_STR.charAt(enc1) + KEY_STR.charAt(enc2) + KEY_STR.charAt(enc3) + KEY_STR.charAt(enc4); chr1 = chr2 = chr3 = ""; enc1 = enc2 = enc3 = enc4 = ""; } while (i < input.length); return output; }, decode(input) { let chr1; let chr2; let chr3; let enc1; let enc2; let enc3; let enc4; let i = 0; const buf = []; const base64test = /[^A-Za-z0-9+/=]/g; if (base64test.exec(input)) { throw new Error("There were invalid base64 characters in the input text.\nValid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\nExpect errors in decoding."); } input = input.replace(/[^A-Za-z0-9+/=]/g, ""); do { enc1 = KEY_STR.indexOf(input.charAt(i++)); enc2 = KEY_STR.indexOf(input.charAt(i++)); enc3 = KEY_STR.indexOf(input.charAt(i++)); enc4 = KEY_STR.indexOf(input.charAt(i++)); chr1 = enc1 << 2 | enc2 >> 4; chr2 = (enc2 & 15) << 4 | enc3 >> 2; chr3 = (enc3 & 3) << 6 | enc4; buf.push(chr1); if (enc3 !== 64) { buf.push(chr2); } if (enc4 !== 64) { buf.push(chr3); } chr1 = chr2 = chr3 = ""; enc1 = enc2 = enc3 = enc4 = ""; } while (i < input.length); return buf; } }; base64_default = Base64; } }); // engine/sdk/core/lib/utils.js var _Utils, Utils, utils_default; var init_utils = __esm({ "engine/sdk/core/lib/utils.js"() { init_render(); init_array_utils(); init_base64(); _Utils = class { static mapRange(value, fromRange, toRange) { return (value - fromRange.getMin()) * toRange.getLength() / fromRange.getLength() + toRange.getMin(); } static isPlainObject(object) { if (typeof object !== "object" || !object) { return false; } if (typeof Object.getPrototypeOf === "function") { const proto = Object.getPrototypeOf(object); return proto === Object.prototype || proto === null; } return Object.prototype.toString.call(object) === "[object Object]"; } static isMobile() { if (typeof navigator === "undefined") return false; const a = navigator.userAgent || navigator.vendor || window.opera; return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4)); } static isBrowser() { return typeof window !== "undefined"; } static values(object) { const values = []; for (const key in object) { values.push(object[key]); } return values; } static generateUUID() { let d = new Date().getTime(); if (false) { if (typeof window.performance !== "undefined" && typeof window.performance.now === "function") { d += window.performance.now(); } } return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { const r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16); return (c === "x" ? r : r & 3 | 8).toString(16); }); } static resizeVectorToFit(vector, max) { const scale = Math.min(max.x / vector.x, max.y / vector.y); const newSize = vector.clone().multiply(scale); return newSize; } static resizeVectorToFill(vector, container) { const vectorRatio = vector.x / vector.y; const containerRatio = container.x / container.y; if (vectorRatio > containerRatio) { return container.clone().set(container.y * vectorRatio, container.y); } return container.clone().set(container.x, container.x / vectorRatio); } static isExtendable(val) { return typeof val !== "undefined" && val !== null && (typeof val === "object" || typeof val === "function"); } static defaults(object, ...sources) { const newObject = {}; for (const key in object) { newObject[key] = object[key]; } for (let i = 0; i < sources.length; i++) { const source = sources[i]; for (const key in source) { if (typeof newObject[key] === "undefined") { newObject[key] = source[key]; } } } return newObject; } static deepMerge(dest, ...sources) { const _deepMerge = (dest2, source) => { if (source === void 0) { return _deepMerge(null, dest2); } if (Array.isArray(source)) { return [...source]; } if (!_Utils.isPlainObject(source)) { return source; } if (!_Utils.isPlainObject(dest2)) { return __spreadValues({}, source); } const result = __spreadValues({}, dest2); Object.keys(source).forEach((key) => { const value = source[key]; if (value === void 0) { return; } result[key] = _deepMerge(dest2[key], value); }); return result; }; return sources.reduce(_deepMerge, dest); } static deepDefaults(object, ...sources) { const reversedSources = [...sources].reverse(); return _Utils.deepMerge(...reversedSources, object); } static deepClone(object) { const newObject = {}; for (const key in object) { if (_Utils.isExtendable(object[key])) { newObject[key] = _Utils.deepClone(object[key]); } else { newObject[key] = object[key]; } } return newObject; } static extend(object, ...sources) { const newObject = {}; for (const key in object) { newObject[key] = object[key]; } for (let i = 0; i < sources.length; i++) { const source = sources[i]; for (const key in source) { newObject[key] = source[key]; } } return newObject; } static clone(object) { return this.extend({}, object); } static getUUID() { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { const r = Math.random() * 16 | 0; const v = c === "x" ? r : r & 3 | 8; return v.toString(16); }); } static createCanvas() { return renderUtils.createCanvas(); } static isPowerOfTwo(dimensions) { return (dimensions.x & dimensions.x - 1) === 0 && (dimensions.y & dimensions.y - 1) === 0; } static nextLowestPOT(x) { for (let i = 1; i < 32; i <<= 1) { x |= x >> i; } return x - (x >> 1); } static nextHighestPOT(x) { x--; for (let i = 1; i < 32; i <<= 1) { x |= x >> i; } return x + 1; } static moveArrayItem(arr, oldIndex, newIndex) { if (newIndex >= arr.length) { let k = newIndex - arr.length; while (k-- + 1) { arr.push(void 0); } } arr.splice(newIndex, 0, arr.splice(oldIndex, 1)[0]); } static ensureCanvasDimensions(canvas, dimensions) { if (canvas.width !== dimensions.x || canvas.height !== dimensions.y) { canvas.width = dimensions.x; canvas.height = dimensions.y; return true; } return false; } static byteArrayToString(byteArray) { return byteArray.map((byte) => String.fromCharCode(byte)).join(""); } static clamp(number, min, max) { return Math.max(min, Math.min(number, max)); } static wildCardMatch(str, rule) { return new RegExp(`^${rule.split("*").join(".*")}$`).test(str); } static flipObject(obj) { const newObj = {}; for (const key in obj) { newObj[obj[key]] = key; } return newObj; } static ISODateString(date) { function pad(n) { return n < 10 ? `0${n}` : n; } return `${date.getUTCFullYear()}-${pad(date.getUTCMonth() + 1)}-${pad(date.getUTCDate())}T${pad(date.getUTCHours())}:${pad(date.getUTCMinutes())}:${pad(date.getUTCSeconds())}Z`; } static getCrossOriginValue(crossOrigin) { if (!crossOrigin) { return "anonymous"; } if (crossOrigin === "none") { return void 0; } return crossOrigin; } static invariant(condition, message) { if (!condition) { const error = new Error(message); throw error; } } static executePromises(promises) { const count = promises.length; let counter = 0; const values = []; const errors = []; return new Promise((resolve, reject) => { const onFinnish = () => { counter++; if (counter >= count) { if (errors.length <= 0) { resolve(values); } else { reject(errors); } } }; const onSuccess = (value) => { values.push(value); onFinnish(); }; const onError = (value) => { errors.push(value); onFinnish(); }; promises.forEach((promise) => { promise.then(onSuccess).catch(onError); }); }); } }; Utils = _Utils; __publicField(Utils, "Array", array_utils_default); utils_default = Utils; } }); // node_modules/escape-string-regexp/index.js var require_escape_string_regexp = __commonJS({ "node_modules/escape-string-regexp/index.js"(exports, module2) { "use strict"; var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; module2.exports = function(str) { if (typeof str !== "string") { throw new TypeError("Expected a string"); } return str.replace(matchOperatorsRe, "\\$&"); }; } }); // node_modules/color-convert/node_modules/color-name/index.js var require_color_name = __commonJS({ "node_modules/color-convert/node_modules/color-name/index.js"(exports, module2) { "use strict"; module2.exports = { "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] }; } }); // node_modules/color-convert/conversions.js var require_conversions = __commonJS({ "node_modules/color-convert/conversions.js"(exports, module2) { var cssKeywords = require_color_name(); var reverseKeywords = {}; for (key in cssKeywords) { if (cssKeywords.hasOwnProperty(key)) { reverseKeywords[cssKeywords[key]] = key; } } var key; var convert = module2.exports = { rgb: { channels: 3, labels: "rgb" }, hsl: { channels: 3, labels: "hsl" }, hsv: { channels: 3, labels: "hsv" }, hwb: { channels: 3, labels: "hwb" }, cmyk: { channels: 4, labels: "cmyk" }, xyz: { channels: 3, labels: "xyz" }, lab: { channels: 3, labels: "lab" }, lch: { channels: 3, labels: "lch" }, hex: { channels: 1, labels: ["hex"] }, keyword: { channels: 1, labels: ["keyword"] }, ansi16: { channels: 1, labels: ["ansi16"] }, ansi256: { channels: 1, labels: ["ansi256"] }, hcg: { channels: 3, labels: ["h", "c", "g"] }, apple: { channels: 3, labels: ["r16", "g16", "b16"] }, gray: { channels: 1, labels: ["gray"] } }; for (model in convert) { if (convert.hasOwnProperty(model)) { if (!("channels" in convert[model])) { throw new Error("missing channels property: " + model); } if (!("labels" in convert[model])) { throw new Error("missing channel labels property: " + model); } if (convert[model].labels.length !== convert[model].channels) { throw new Error("channel and label counts mismatch: " + model); } channels = convert[model].channels; labels = convert[model].labels; delete convert[model].channels; delete convert[model].labels; Object.defineProperty(convert[model], "channels", { value: channels }); Object.defineProperty(convert[model], "labels", { value: labels }); } } var channels; var labels; var model; convert.rgb.hsl = function(rgb) { var r = rgb[0] / 255; var g = rgb[1] / 255; var b = rgb[2] / 255; var min = Math.min(r, g, b); var max = Math.max(r, g, b); var delta = max - min; var h; var s; var l; if (max === min) { h = 0; } else if (r === max) { h = (g - b) / delta; } else if (g === max) { h = 2 + (b - r) / delta; } else if (b === max) { h = 4 + (r - g) / delta; } h = Math.min(h * 60, 360); if (h < 0) { h += 360; } l = (min + max) / 2; if (max === min) { s = 0; } else if (l <= 0.5) { s = delta / (max + min); } else { s = delta / (2 - max - min); } return [h, s * 100, l * 100]; }; convert.rgb.hsv = function(rgb) { var rdif; var gdif; var bdif; var h; var s; var r = rgb[0] / 255; var g = rgb[1] / 255; var b = rgb[2] / 255; var v = Math.max(r, g, b); var diff = v - Math.min(r, g, b); var diffc = function(c) { return (v - c) / 6 / diff + 1 / 2; }; if (diff === 0) { h = s = 0; } else { s = diff / v; rdif = diffc(r); gdif = diffc(g); bdif = diffc(b); if (r === v) { h = bdif - gdif; } else if (g === v) { h = 1 / 3 + rdif - bdif; } else if (b === v) { h = 2 / 3 + gdif - rdif; } if (h < 0) { h += 1; } else if (h > 1) { h -= 1; } } return [ h * 360, s * 100, v * 100 ]; }; convert.rgb.hwb = function(rgb) { var r = rgb[0]; var g = rgb[1]; var b = rgb[2]; var h = convert.rgb.hsl(rgb)[0]; var w = 1 / 255 * Math.min(r, Math.min(g, b)); b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); return [h, w * 100, b * 100]; }; convert.rgb.cmyk = function(rgb) { var r = rgb[0] / 255; var g = rgb[1] / 255; var b = rgb[2] / 255; var c; var m; var y; var k; k = Math.min(1 - r, 1 - g, 1 - b); c = (1 - r - k) / (1 - k) || 0; m = (1 - g - k) / (1 - k) || 0; y = (1 - b - k) / (1 - k) || 0; return [c * 100, m * 100, y * 100, k * 100]; }; function comparativeDistance(x, y) { return Math.pow(x[0] - y[0], 2) + Math.pow(x[1] - y[1], 2) + Math.pow(x[2] - y[2], 2); } convert.rgb.keyword = function(rgb) { var reversed = reverseKeywords[rgb]; if (reversed) { return reversed; } var currentClosestDistance = Infinity; var currentClosestKeyword; for (var keyword in cssKeywords) { if (cssKeywords.hasOwnProperty(keyword)) { var value = cssKeywords[keyword]; var distance = comparativeDistance(rgb, value); if (distance < currentClosestDistance) { currentClosestDistance = distance; currentClosestKeyword = keyword; } } } return currentClosestKeyword; }; convert.keyword.rgb = function(keyword) { return cssKeywords[keyword]; }; convert.rgb.xyz = function(rgb) { var r = rgb[0] / 255; var g = rgb[1] / 255; var b = rgb[2] / 255; r = r > 0.04045 ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92; g = g > 0.04045 ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92; b = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92; var x = r * 0.4124 + g * 0.3576 + b * 0.1805; var y = r * 0.2126 + g * 0.7152 + b * 0.0722; var z = r * 0.0193 + g * 0.1192 + b * 0.9505; return [x * 100, y * 100, z * 100]; }; convert.rgb.lab = function(rgb) { var xyz = convert.rgb.xyz(rgb); var x = xyz[0]; var y = xyz[1]; var z = xyz[2]; var l; var a; var b; x /= 95.047; y /= 100; z /= 108.883; x = x > 8856e-6 ? Math.pow(x, 1 / 3) : 7.787 * x + 16 / 116; y = y > 8856e-6 ? Math.pow(y, 1 / 3) : 7.787 * y + 16 / 116; z = z > 8856e-6 ? Math.pow(z, 1 / 3) : 7.787 * z + 16 / 116; l = 116 * y - 16; a = 500 * (x - y); b = 200 * (y - z); return [l, a, b]; }; convert.hsl.rgb = function(hsl) { var h = hsl[0] / 360; var s = hsl[1] / 100; var l = hsl[2] / 100; var t1; var t2; var t3; var rgb; var val; if (s === 0) { val = l * 255; return [val, val, val]; } if (l < 0.5) { t2 = l * (1 + s); } else { t2 = l + s - l * s; } t1 = 2 * l - t2; rgb = [0, 0, 0]; for (var i = 0; i < 3; i++) { t3 = h + 1 / 3 * -(i - 1); if (t3 < 0) { t3++; } if (t3 > 1) { t3--; } if (6 * t3 < 1) { val = t1 + (t2 - t1) * 6 * t3; } else if (2 * t3 < 1) { val = t2; } else if (3 * t3 < 2) { val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; } else { val = t1; } rgb[i] = val * 255; } return rgb; }; convert.hsl.hsv = function(hsl) { var h = hsl[0]; var s = hsl[1] / 100; var l = hsl[2] / 100; var smin = s; var lmin = Math.max(l, 0.01); var sv; var v; l *= 2; s *= l <= 1 ? l : 2 - l; smin *= lmin <= 1 ? lmin : 2 - lmin; v = (l + s) / 2; sv = l === 0 ? 2 * smin / (lmin + smin) : 2 * s / (l + s); return [h, sv * 100, v * 100]; }; convert.hsv.rgb = function(hsv) { var h = hsv[0] / 60; var s = hsv[1] / 100; var v = hsv[2] / 100; var hi = Math.floor(h) % 6; var f = h - Math.floor(h); var p = 255 * v * (1 - s); var q = 255 * v * (1 - s * f); var t = 255 * v * (1 - s * (1 - f)); v *= 255; switch (hi) { case 0: return [v, t, p]; case 1: return [q, v, p]; case 2: return [p, v, t]; case 3: return [p, q, v]; case 4: return [t, p, v]; case 5: return [v, p, q]; } }; convert.hsv.hsl = function(hsv) { var h = hsv[0]; var s = hsv[1] / 100; var v = hsv[2] / 100; var vmin = Math.max(v, 0.01); var lmin; var sl; var l; l = (2 - s) * v; lmin = (2 - s) * vmin; sl = s * vmin; sl /= lmin <= 1 ? lmin : 2 - lmin; sl = sl || 0; l /= 2; return [h, sl * 100, l * 100]; }; convert.hwb.rgb = function(hwb) { var h = hwb[0] / 360; var wh = hwb[1] / 100; var bl = hwb[2] / 100; var ratio = wh + bl; var i; var v; var f; var n; if (ratio > 1) { wh /= ratio; bl /= ratio; } i = Math.floor(6 * h); v = 1 - bl; f = 6 * h - i; if ((i & 1) !== 0) { f = 1 - f; } n = wh + f * (v - wh); var r; var g; var b; switch (i) { default: case 6: case 0: r = v; g = n; b = wh; break; case 1: r = n; g = v; b = wh; break; case 2: r = wh; g = v; b = n; break; case 3: r = wh; g = n; b = v; break; case 4: r = n; g = wh; b = v; break; case 5: r = v; g = wh; b = n; break; } return [r * 255, g * 255, b * 255]; }; convert.cmyk.rgb = function(cmyk) { var c = cmyk[0] / 100; var m = cmyk[1] / 100; var y = cmyk[2] / 100; var k = cmyk[3] / 100; var r; var g; var b; r = 1 - Math.min(1, c * (1 - k) + k); g = 1 - Math.min(1, m * (1 - k) + k); b = 1 - Math.min(1, y * (1 - k) + k); return [r * 255, g * 255, b * 255]; }; convert.xyz.rgb = function(xyz) { var x = xyz[0] / 100; var y = xyz[1] / 100; var z = xyz[2] / 100; var r; var g; var b; r = x * 3.2406 + y * -1.5372 + z * -0.4986; g = x * -0.9689 + y * 1.8758 + z * 0.0415; b = x * 0.0557 + y * -0.204 + z * 1.057; r = r > 31308e-7 ? 1.055 * Math.pow(r, 1 / 2.4) - 0.055 : r * 12.92; g = g > 31308e-7 ? 1.055 * Math.pow(g, 1 / 2.4) - 0.055 : g * 12.92; b = b > 31308e-7 ? 1.055 * Math.pow(b, 1 / 2.4) - 0.055 : b * 12.92; r = Math.min(Math.max(0, r), 1); g = Math.min(Math.max(0, g), 1); b = Math.min(Math.max(0, b), 1); return [r * 255, g * 255, b * 255]; }; convert.xyz.lab = function(xyz) { var x = xyz[0]; var y = xyz[1]; var z = xyz[2]; var l; var a; var b; x /= 95.047; y /= 100; z /= 108.883; x = x > 8856e-6 ? Math.pow(x, 1 / 3) : 7.787 * x + 16 / 116; y = y > 8856e-6 ? Math.pow(y, 1 / 3) : 7.787 * y + 16 / 116; z = z > 8856e-6 ? Math.pow(z, 1 / 3) : 7.787 * z + 16 / 116; l = 116 * y - 16; a = 500 * (x - y); b = 200 * (y - z); return [l, a, b]; }; convert.lab.xyz = function(lab) { var l = lab[0]; var a = lab[1]; var b = lab[2]; var x; var y; var z; y = (l + 16) / 116; x = a / 500 + y; z = y - b / 200; var y2 = Math.pow(y, 3); var x2 = Math.pow(x, 3); var z2 = Math.pow(z, 3); y = y2 > 8856e-6 ? y2 : (y - 16 / 116) / 7.787; x = x2 > 8856e-6 ? x2 : (x - 16 / 116) / 7.787; z = z2 > 8856e-6 ? z2 : (z - 16 / 116) / 7.787; x *= 95.047; y *= 100; z *= 108.883; return [x, y, z]; }; convert.lab.lch = function(lab) { var l = lab[0]; var a = lab[1]; var b = lab[2]; var hr; var h; var c; hr = Math.atan2(b, a); h = hr * 360 / 2 / Math.PI; if (h < 0) { h += 360; } c = Math.sqrt(a * a + b * b); return [l, c, h]; }; convert.lch.lab = function(lch) { var l = lch[0]; var c = lch[1]; var h = lch[2]; var a; var b; var hr; hr = h / 360 * 2 * Math.PI; a = c * Math.cos(hr); b = c * Math.sin(hr); return [l, a, b]; }; convert.rgb.ansi16 = function(args) { var r = args[0]; var g = args[1]; var b = args[2]; var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; value = Math.round(value / 50); if (value === 0) { return 30; } var ansi = 30 + (Math.round(b / 255) << 2 | Math.round(g / 255) << 1 | Math.round(r / 255)); if (value === 2) { ansi += 60; } return ansi; }; convert.hsv.ansi16 = function(args) { return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); }; convert.rgb.ansi256 = function(args) { var r = args[0]; var g = args[1]; var b = args[2]; if (r === g && g === b) { if (r < 8) { return 16; } if (r > 248) { return 231; } return Math.round((r - 8) / 247 * 24) + 232; } var ansi = 16 + 36 * Math.round(r / 255 * 5) + 6 * Math.round(g / 255 * 5) + Math.round(b / 255 * 5); return ansi; }; convert.ansi16.rgb = function(args) { var color = args % 10; if (color === 0 || color === 7) { if (args > 50) { color += 3.5; } color = color / 10.5 * 255; return [color, color, color]; } var mult = (~~(args > 50) + 1) * 0.5; var r = (color & 1) * mult * 255; var g = (color >> 1 & 1) * mult * 255; var b = (color >> 2 & 1) * mult * 255; return [r, g, b]; }; convert.ansi256.rgb = function(args) { if (args >= 232) { var c = (args - 232) * 10 + 8; return [c, c, c]; } args -= 16; var rem; var r = Math.floor(args / 36) / 5 * 255; var g = Math.floor((rem = args % 36) / 6) / 5 * 255; var b = rem % 6 / 5 * 255; return [r, g, b]; }; convert.rgb.hex = function(args) { var integer = ((Math.round(args[0]) & 255) << 16) + ((Math.round(args[1]) & 255) << 8) + (Math.round(args[2]) & 255); var string = integer.toString(16).toUpperCase(); return "000000".substring(string.length) + string; }; convert.hex.rgb = function(args) { var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); if (!match) { return [0, 0, 0]; } var colorString = match[0]; if (match[0].length === 3) { colorString = colorString.split("").map(function(char) { return char + char; }).join(""); } var integer = parseInt(colorString, 16); var r = integer >> 16 & 255; var g = integer >> 8 & 255; var b = integer & 255; return [r, g, b]; }; convert.rgb.hcg = function(rgb) { var r = rgb[0] / 255; var g = rgb[1] / 255; var b = rgb[2] / 255; var max = Math.max(Math.max(r, g), b); var min = Math.min(Math.min(r, g), b); var chroma = max - min; var grayscale; var hue; if (chroma < 1) { grayscale = min / (1 - chroma); } else { grayscale = 0; } if (chroma <= 0) { hue = 0; } else if (max === r) { hue = (g - b) / chroma % 6; } else if (max === g) { hue = 2 + (b - r) / chroma; } else { hue = 4 + (r - g) / chroma + 4; } hue /= 6; hue %= 1; return [hue * 360, chroma * 100, grayscale * 100]; }; convert.hsl.hcg = function(hsl) { var s = hsl[1] / 100; var l = hsl[2] / 100; var c = 1; var f = 0; if (l < 0.5) { c = 2 * s * l; } else { c = 2 * s * (1 - l); } if (c < 1) { f = (l - 0.5 * c) / (1 - c); } return [hsl[0], c * 100, f * 100]; }; convert.hsv.hcg = function(hsv) { var s = hsv[1] / 100; var v = hsv[2] / 100; var c = s * v; var f = 0; if (c < 1) { f = (v - c) / (1 - c); } return [hsv[0], c * 100, f * 100]; }; convert.hcg.rgb = function(hcg) { var h = hcg[0] / 360; var c = hcg[1] / 100; var g = hcg[2] / 100; if (c === 0) { return [g * 255, g * 255, g * 255]; } var pure = [0, 0, 0]; var hi = h % 1 * 6; var v = hi % 1; var w = 1 - v; var mg = 0; switch (Math.floor(hi)) { case 0: pure[0] = 1; pure[1] = v; pure[2] = 0; break; case 1: pure[0] = w; pure[1] = 1; pure[2] = 0; break; case 2: pure[0] = 0; pure[1] = 1; pure[2] = v; break; case 3: pure[0] = 0; pure[1] = w; pure[2] = 1; break; case 4: pure[0] = v; pure[1] = 0; pure[2] = 1; break; default: pure[0] = 1; pure[1] = 0; pure[2] = w; } mg = (1 - c) * g; return [ (c * pure[0] + mg) * 255, (c * pure[1] + mg) * 255, (c * pure[2] + mg) * 255 ]; }; convert.hcg.hsv = function(hcg) { var c = hcg[1] / 100; var g = hcg[2] / 100; var v = c + g * (1 - c); var f = 0; if (v > 0) { f = c / v; } return [hcg[0], f * 100, v * 100]; }; convert.hcg.hsl = function(hcg) { var c = hcg[1] / 100; var g = hcg[2] / 100; var l = g * (1 - c) + 0.5 * c; var s = 0; if (l > 0 && l < 0.5) { s = c / (2 * l); } else if (l >= 0.5 && l < 1) { s = c / (2 * (1 - l)); } return [hcg[0], s * 100, l * 100]; }; convert.hcg.hwb = function(hcg) { var c = hcg[1] / 100; var g = hcg[2] / 100; var v = c + g * (1 - c); return [hcg[0], (v - c) * 100, (1 - v) * 100]; }; convert.hwb.hcg = function(hwb) { var w = hwb[1] / 100; var b = hwb[2] / 100; var v = 1 - b; var c = v - w; var g = 0; if (c < 1) { g = (v - c) / (1 - c); } return [hwb[0], c * 100, g * 100]; }; convert.apple.rgb = function(apple) { return [apple[0] / 65535 * 255, apple[1] / 65535 * 255, apple[2] / 65535 * 255]; }; convert.rgb.apple = function(rgb) { return [rgb[0] / 255 * 65535, rgb[1] / 255 * 65535, rgb[2] / 255 * 65535]; }; convert.gray.rgb = function(args) { return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; }; convert.gray.hsl = convert.gray.hsv = function(args) { return [0, 0, args[0]]; }; convert.gray.hwb = function(gray) { return [0, 100, gray[0]]; }; convert.gray.cmyk = function(gray) { return [0, 0, 0, gray[0]]; }; convert.gray.lab = function(gray) { return [gray[0], 0, 0]; }; convert.gray.hex = function(gray) { var val = Math.round(gray[0] / 100 * 255) & 255; var integer = (val << 16) + (val << 8) + val; var string = integer.toString(16).toUpperCase(); return "000000".substring(string.length) + string; }; convert.rgb.gray = function(rgb) { var val = (rgb[0] + rgb[1] + rgb[2]) / 3; return [val / 255 * 100]; }; } }); // node_modules/color-convert/route.js var require_route = __commonJS({ "node_modules/color-convert/route.js"(exports, module2) { var conversions = require_conversions(); function buildGraph() { var graph = {}; var models = Object.keys(conversions); for (var len = models.length, i = 0; i < len; i++) { graph[models[i]] = { distance: -1, parent: null }; } return graph; } function deriveBFS(fromModel) { var graph = buildGraph(); var queue = [fromModel]; graph[fromModel].distance = 0; while (queue.length) { var current = queue.pop(); var adjacents = Object.keys(conversions[current]); for (var len = adjacents.length, i = 0; i < len; i++) { var adjacent = adjacents[i]; var node = graph[adjacent]; if (node.distance === -1) { node.distance = graph[current].distance + 1; node.parent = current; queue.unshift(adjacent); } } } return graph; } function link(from, to) { return function(args) { return to(from(args)); }; } function wrapConversion(toModel, graph) { var path = [graph[toModel].parent, toModel]; var fn = conversions[graph[toModel].parent][toModel]; var cur = graph[toModel].parent; while (graph[cur].parent) { path.unshift(graph[cur].parent); fn = link(conversions[graph[cur].parent][cur], fn); cur = graph[cur].parent;