UNPKG

@esotericsoftware/spine-core

Version:
270 lines 35.6 kB
/****************************************************************************** * Spine Runtimes License Agreement * Last updated April 5, 2025. Replaces all prior versions. * * Copyright (c) 2013-2025, Esoteric Software LLC * * Integration of the Spine Runtimes into software or otherwise creating * derivative works of the Spine Runtimes is permitted under the terms and * conditions of Section 2 of the Spine Editor License Agreement: * http://esotericsoftware.com/spine-editor-license * * Otherwise, it is permitted to integrate the Spine Runtimes into software * or otherwise create derivative works of the Spine Runtimes (collectively, * "Products"), provided that each user of the Products must obtain their own * Spine Editor license and redistribution of the Products in any form must * include this license and copyright notice. * * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "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 ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) 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 * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ import { TextureFilter, TextureRegion, TextureWrap } from "./Texture.js"; import { Utils } from "./Utils.js"; export class TextureAtlas { pages = []; regions = []; constructor(atlasText) { const reader = new TextureAtlasReader(atlasText); const entry = new Array(4); const pageFields = {}; pageFields.size = (page) => { page.width = parseInt(entry[1]); page.height = parseInt(entry[2]); }; pageFields.format = () => { // page.format = Format[tuple[0]]; we don't need format in WebGL }; pageFields.filter = (page) => { page.minFilter = Utils.enumValue(TextureFilter, entry[1]); page.magFilter = Utils.enumValue(TextureFilter, entry[2]); }; pageFields.repeat = (page) => { if (entry[1].indexOf('x') !== -1) page.uWrap = TextureWrap.Repeat; if (entry[1].indexOf('y') !== -1) page.vWrap = TextureWrap.Repeat; }; pageFields.pma = (page) => { page.pma = entry[1] === "true"; }; var regionFields = {}; regionFields.xy = (region) => { region.x = parseInt(entry[1]); region.y = parseInt(entry[2]); }; regionFields.size = (region) => { region.width = parseInt(entry[1]); region.height = parseInt(entry[2]); }; regionFields.bounds = (region) => { region.x = parseInt(entry[1]); region.y = parseInt(entry[2]); region.width = parseInt(entry[3]); region.height = parseInt(entry[4]); }; regionFields.offset = (region) => { region.offsetX = parseInt(entry[1]); region.offsetY = parseInt(entry[2]); }; regionFields.orig = (region) => { region.originalWidth = parseInt(entry[1]); region.originalHeight = parseInt(entry[2]); }; regionFields.offsets = (region) => { region.offsetX = parseInt(entry[1]); region.offsetY = parseInt(entry[2]); region.originalWidth = parseInt(entry[3]); region.originalHeight = parseInt(entry[4]); }; regionFields.rotate = (region) => { const value = entry[1]; if (value === "true") region.degrees = 90; else if (value !== "false") region.degrees = parseInt(value); }; regionFields.index = (region) => { region.index = parseInt(entry[1]); }; let line = reader.readLine(); // Ignore empty lines before first entry. while (line && line.trim().length === 0) line = reader.readLine(); // Header entries. while (true) { if (!line || line.trim().length === 0) break; if (reader.readEntry(entry, line) === 0) break; // Silently ignore all header fields. line = reader.readLine(); } // Page and region entries. let page = null; let names = null; let values = null; while (true) { if (line === null) break; if (line.trim().length === 0) { page = null; line = reader.readLine(); } else if (!page) { page = new TextureAtlasPage(line.trim()); while (true) { if (reader.readEntry(entry, line = reader.readLine()) === 0) break; const field = pageFields[entry[0]]; if (field) field(page); } this.pages.push(page); } else { const region = new TextureAtlasRegion(page, line); while (true) { const count = reader.readEntry(entry, line = reader.readLine()); if (count === 0) break; const field = regionFields[entry[0]]; if (field) field(region); else { if (!names) names = []; if (!values) values = []; names.push(entry[0]); const entryValues = []; for (let i = 0; i < count; i++) entryValues.push(parseInt(entry[i + 1])); values.push(entryValues); } } if (region.originalWidth === 0 && region.originalHeight === 0) { region.originalWidth = region.width; region.originalHeight = region.height; } if (names && names.length > 0 && values && values.length > 0) { region.names = names; region.values = values; names = null; values = null; } region.u = region.x / page.width; region.v = region.y / page.height; if (region.degrees === 90) { region.u2 = (region.x + region.height) / page.width; region.v2 = (region.y + region.width) / page.height; } else { region.u2 = (region.x + region.width) / page.width; region.v2 = (region.y + region.height) / page.height; } this.regions.push(region); } } } findRegion(name) { for (let i = 0; i < this.regions.length; i++) { if (this.regions[i].name === name) { return this.regions[i]; } } return null; } setTextures(assetManager, pathPrefix = "") { for (const page of this.pages) page.setTexture(assetManager.get(pathPrefix + page.name)); } dispose() { for (let i = 0; i < this.pages.length; i++) { this.pages[i].texture?.dispose(); } } } class TextureAtlasReader { lines; index = 0; constructor(text) { this.lines = text.split(/\r\n|\r|\n/); } readLine() { if (this.index >= this.lines.length) return null; return this.lines[this.index++]; } readEntry(entry, line) { if (!line) return 0; line = line.trim(); if (line.length === 0) return 0; const colon = line.indexOf(':'); if (colon === -1) return 0; entry[0] = line.substr(0, colon).trim(); for (let i = 1, lastMatch = colon + 1;; i++) { const comma = line.indexOf(',', lastMatch); if (comma === -1) { entry[i] = line.substr(lastMatch).trim(); return i; } entry[i] = line.substr(lastMatch, comma - lastMatch).trim(); lastMatch = comma + 1; if (i === 4) return 4; } } } export class TextureAtlasPage { name; minFilter = TextureFilter.Nearest; magFilter = TextureFilter.Nearest; uWrap = TextureWrap.ClampToEdge; vWrap = TextureWrap.ClampToEdge; texture = null; width = 0; height = 0; pma = false; regions = []; constructor(name) { this.name = name; } setTexture(texture) { this.texture = texture; texture.setFilters(this.minFilter, this.magFilter); texture.setWraps(this.uWrap, this.vWrap); for (const region of this.regions) region.texture = texture; } } export class TextureAtlasRegion extends TextureRegion { page; name; x = 0; y = 0; offsetX = 0; offsetY = 0; originalWidth = 0; originalHeight = 0; index = 0; degrees = 0; names = null; values = null; constructor(page, name) { super(); this.page = page; this.name = name; page.regions.push(this); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVGV4dHVyZUF0bGFzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1RleHR1cmVBdGxhcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFHL0UsT0FBTyxFQUFnQixhQUFhLEVBQUUsYUFBYSxFQUFFLFdBQVcsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN2RixPQUFPLEVBQW1DLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQztBQUVwRSxNQUFNLE9BQU8sWUFBWTtJQUN4QixLQUFLLEdBQUcsRUFBd0IsQ0FBQztJQUNqQyxPQUFPLEdBQUcsRUFBMEIsQ0FBQztJQUVyQyxZQUFhLFNBQWlCO1FBQzdCLE1BQU0sTUFBTSxHQUFHLElBQUksa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakQsTUFBTSxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQVMsQ0FBQyxDQUFDLENBQUM7UUFFbkMsTUFBTSxVQUFVLEdBQWdELEVBQUUsQ0FBQztRQUNuRSxVQUFVLENBQUMsSUFBSSxHQUFHLENBQUMsSUFBc0IsRUFBRSxFQUFFO1lBQzVDLElBQUksQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hDLElBQUksQ0FBQyxNQUFNLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xDLENBQUMsQ0FBQztRQUNGLFVBQVUsQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFO1lBQ3hCLGdFQUFnRTtRQUNqRSxDQUFDLENBQUM7UUFDRixVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBc0IsRUFBRSxFQUFFO1lBQzlDLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDMUQsSUFBSSxDQUFDLFNBQVMsR0FB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LEtBQUssR0FBb0IsSUFBSSxDQUFDO0lBQzlCLE1BQU0sR0FBc0IsSUFBSSxDQUFDO0lBRWpDLFlBQWEsSUFBc0IsRUFBRSxJQUFZO1FBQ2hELEtBQUssRUFBRSxDQUFDO1FBQ1IsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDekIsQ0FBQztDQUNEIiwic291cmNlc0NvbnRlbnQiOlsiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogU3BpbmUgUnVudGltZXMgTGljZW5zZSBBZ3JlZW1lbnRcbiAqIExhc3QgdXBkYXRlZCBBcHJpbCA1LCAyMDI1LiBSZXBsYWNlcyBhbGwgcHJpb3IgdmVyc2lvbnMuXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEzLTIwMjUsIEVzb3RlcmljIFNvZnR3YXJlIExMQ1xuICpcbiAqIEludGVncmF0aW9uIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlIG9yIG90aGVyd2lzZSBjcmVhdGluZ1xuICogZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgaXMgcGVybWl0dGVkIHVuZGVyIHRoZSB0ZXJtcyBhbmRcbiAqIGNvbmRpdGlvbnMgb2YgU2VjdGlvbiAyIG9mIHRoZSBTcGluZSBFZGl0b3IgTGljZW5zZSBBZ3JlZW1lbnQ6XG4gKiBodHRwOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb20vc3BpbmUtZWRpdG9yLWxpY2Vuc2VcbiAqXG4gKiBPdGhlcndpc2UsIGl0IGlzIHBlcm1pdHRlZCB0byBpbnRlZ3JhdGUgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmVcbiAqIG9yIG90aGVyd2lzZSBjcmVhdGUgZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgKGNvbGxlY3RpdmVseSxcbiAqIFwiUHJvZHVjdHNcIiksIHByb3ZpZGVkIHRoYXQgZWFjaCB1c2VyIG9mIHRoZSBQcm9kdWN0cyBtdXN0IG9idGFpbiB0aGVpciBvd25cbiAqIFNwaW5lIEVkaXRvciBsaWNlbnNlIGFuZCByZWRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZHVjdHMgaW4gYW55IGZvcm0gbXVzdFxuICogaW5jbHVkZSB0aGlzIGxpY2Vuc2UgYW5kIGNvcHlyaWdodCBub3RpY2UuXG4gKlxuICogVEhFIFNQSU5FIFJVTlRJTUVTIEFSRSBQUk9WSURFRCBCWSBFU09URVJJQyBTT0ZUV0FSRSBMTEMgXCJBUyBJU1wiIEFORCBBTllcbiAqIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRURcbiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIEVTT1RFUklDIFNPRlRXQVJFIExMQyBCRSBMSUFCTEUgRk9SIEFOWVxuICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUyxcbiAqIEJVU0lORVNTIElOVEVSUlVQVElPTiwgT1IgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFMpIEhPV0VWRVIgQ0FVU0VEIEFORFxuICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuICogVEhFIFNQSU5FIFJVTlRJTUVTLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgdHlwZSB7IEFzc2V0TWFuYWdlckJhc2UgfSBmcm9tIFwiLi9Bc3NldE1hbmFnZXJCYXNlLmpzXCI7XG5pbXBvcnQgeyB0eXBlIFRleHR1cmUsIFRleHR1cmVGaWx0ZXIsIFRleHR1cmVSZWdpb24sIFRleHR1cmVXcmFwIH0gZnJvbSBcIi4vVGV4dHVyZS5qc1wiO1xuaW1wb3J0IHsgdHlwZSBEaXNwb3NhYmxlLCB0eXBlIFN0cmluZ01hcCwgVXRpbHMgfSBmcm9tIFwiLi9VdGlscy5qc1wiO1xuXG5leHBvcnQgY2xhc3MgVGV4dHVyZUF0bGFzIGltcGxlbWVudHMgRGlzcG9zYWJsZSB7XG5cdHBhZ2VzID0gW10gYXMgVGV4dHVyZUF0bGFzUGFnZVtdO1xuXHRyZWdpb25zID0gW10gYXMgVGV4dHVyZUF0bGFzUmVnaW9uW107XG5cblx0Y29uc3RydWN0b3IgKGF0bGFzVGV4dDogc3RyaW5nKSB7XG5cdFx0Y29uc3QgcmVhZGVyID0gbmV3IFRleHR1cmVBdGxhc1JlYWRlcihhdGxhc1RleHQpO1xuXHRcdGNvbnN0IGVudHJ5ID0gbmV3IEFycmF5PHN0cmluZz4oNCk7XG5cblx0XHRjb25zdCBwYWdlRmllbGRzOiBTdHJpbmdNYXA8KHBhZ2U6IFRleHR1cmVBdGxhc1BhZ2UpID0+IHZvaWQ+ID0ge307XG5cdFx0cGFnZUZpZWxkcy5zaXplID0gKHBhZ2U6IFRleHR1cmVBdGxhc1BhZ2UpID0+IHtcblx0XHRcdHBhZ2Uud2lkdGggPSBwYXJzZUludChlbnRyeVsxXSk7XG5cdFx0XHRwYWdlLmhlaWdodCA9IHBhcnNlSW50KGVudHJ5WzJdKTtcblx0XHR9O1xuXHRcdHBhZ2VGaWVsZHMuZm9ybWF0ID0gKCkgPT4ge1xuXHRcdFx0Ly8gcGFnZS5mb3JtYXQgPSBGb3JtYXRbdHVwbGVbMF1dOyB3ZSBkb24ndCBuZWVkIGZvcm1hdCBpbiBXZWJHTFxuXHRcdH07XG5cdFx0cGFnZUZpZWxkcy5maWx0ZXIgPSAocGFnZTogVGV4dHVyZUF0bGFzUGFnZSkgPT4ge1xuXHRcdFx0cGFnZS5taW5GaWx0ZXIgPSBVdGlscy5lbnVtVmFsdWUoVGV4dHVyZUZpbHRlciwgZW50cnlbMV0pO1xuXHRcdFx0cGFnZS5tYWdGaWx0ZXIgPSBVdGlscy5lbnVtVmFsdWUoVGV4dHVyZUZpbHRlciwgZW50cnlbMl0pO1xuXHRcdH07XG5cdFx0cGFnZUZpZWxkcy5yZXBlYXQgPSAocGFnZTogVGV4dHVyZUF0bGFzUGFnZSkgPT4ge1xuXHRcdFx0aWYgKGVudHJ5WzFdLmluZGV4T2YoJ3gnKSAhPT0gLTEpIHBhZ2UudVdyYXAgPSBUZXh0dXJlV3JhcC5SZXBlYXQ7XG5cdFx0XHRpZiAoZW50cnlbMV0uaW5kZXhPZigneScpICE9PSAtMSkgcGFnZS52V3JhcCA9IFRleHR1cmVXcmFwLlJlcGVhdDtcblx0XHR9O1xuXHRcdHBhZ2VGaWVsZHMucG1hID0gKHBhZ2U6IFRleHR1cmVBdGxhc1BhZ2UpID0+IHtcblx0XHRcdHBhZ2UucG1hID0gZW50cnlbMV0gPT09IFwidHJ1ZVwiO1xuXHRcdH07XG5cblx0XHR2YXIgcmVnaW9uRmllbGRzOiBTdHJpbmdNYXA8KHJlZ2lvbjogVGV4dHVyZUF0bGFzUmVnaW9uKSA9PiB2b2lkPiA9IHt9O1xuXHRcdHJlZ2lvbkZpZWxkcy54eSA9IChyZWdpb246IFRleHR1cmVBdGxhc1JlZ2lvbikgPT4geyAvLyBEZXByZWNhdGVkLCB1c2UgYm91bmRzLlxuXHRcdFx0cmVnaW9uLnggPSBwYXJzZUludChlbnRyeVsxXSk7XG5cdFx0XHRyZWdpb24ueSA9IHBhcnNlSW50KGVudHJ5WzJdKTtcblx0XHR9O1xuXHRcdHJlZ2lvbkZpZWxkcy5zaXplID0gKHJlZ2lvbjogVGV4dHVyZUF0bGFzUmVnaW9uKSA9PiB7IC8vIERlcHJlY2F0ZWQsIHVzZSBib3VuZHMuXG5cdFx0XHRyZWdpb24ud2lkdGggPSBwYXJzZUludChlbnRyeVsxXSk7XG5cdFx0XHRyZWdpb24uaGVpZ2h0ID0gcGFyc2VJbnQoZW50cnlbMl0pO1xuXHRcdH07XG5cdFx0cmVnaW9uRmllbGRzLmJvdW5kcyA9IChyZWdpb246IFRleHR1cmVBdGxhc1JlZ2lvbikgPT4ge1xuXHRcdFx0cmVnaW9uLnggPSBwYXJzZUludChlbnRyeVsxXSk7XG5cdFx0XHRyZWdpb24ueSA9IHBhcnNlSW50KGVudHJ5WzJdKTtcblx0XHRcdHJlZ2lvbi53aWR0aCA9IHBhcnNlSW50KGVudHJ5WzNdKTtcblx0XHRcdHJlZ2lvbi5oZWlnaHQgPSBwYXJzZUludChlbnRyeVs0XSk7XG5cdFx0fTtcblx0XHRyZWdpb25GaWVsZHMub2Zmc2V0ID0gKHJlZ2lvbjogVGV4dHVyZUF0bGFzUmVnaW9uKSA9PiB7IC8vIERlcHJlY2F0ZWQsIHVzZSBvZmZzZXRzLlxuXHRcdFx0cmVnaW9uLm9mZnNldFggPSBwYXJzZUludChlbnRyeVsxXSk7XG5cdFx0XHRyZWdpb24ub2Zmc2V0WSA9IHBhcnNlSW50KGVudHJ5WzJdKTtcblx0XHR9O1xuXHRcdHJlZ2lvbkZpZWxkcy5vcmlnID0gKHJlZ2lvbjogVGV4dHVyZUF0bGFzUmVnaW9uKSA9PiB7IC8vIERlcHJlY2F0ZWQsIHVzZSBvZmZzZXRzLlxuXHRcdFx0cmVnaW9uLm9yaWdpbmFsV2lkdGggPSBwYXJzZUludChlbnRyeVsxXSk7XG5cdFx0XHRyZWdpb24ub3JpZ2luYWxIZWlnaHQgPSBwYXJzZUludChlbnRyeVsyXSk7XG5cdFx0fTtcblx0XHRyZWdpb25GaWVsZHMub2Zmc2V0cyA9IChyZWdpb246IFRleHR1cmVBdGxhc1JlZ2lvbikgPT4ge1xuXHRcdFx0cmVnaW9uLm9mZnNldFggPSBwYXJzZUludChlbnRyeVsxXSk7XG5cdFx0XHRyZWdpb24ub2Zmc2V0WSA9IHBhcnNlSW50KGVudHJ5WzJdKTtcblx0XHRcdHJlZ2lvbi5vcmlnaW5hbFdpZHRoID0gcGFyc2VJbnQoZW50cnlbM10pO1xuXHRcdFx0cmVnaW9uLm9yaWdpbmFsSGVpZ2h0ID0gcGFyc2VJbnQoZW50cnlbNF0pO1xuXHRcdH07XG5cdFx0cmVnaW9uRmllbGRzLnJvdGF0ZSA9IChyZWdpb246IFRleHR1cmVBdGxhc1JlZ2lvbikgPT4ge1xuXHRcdFx0Y29uc3QgdmFsdWUgPSBlbnRyeVsxXTtcblx0XHRcdGlmICh2YWx1ZSA9PT0gXCJ0cnVlXCIpXG5cdFx0XHRcdHJlZ2lvbi5kZWdyZWVzID0gOTA7XG5cdFx0XHRlbHNlIGlmICh2YWx1ZSAhPT0gXCJmYWxzZVwiKVxuXHRcdFx0XHRyZWdpb24uZGVncmVlcyA9IHBhcnNlSW50KHZhbHVlKTtcblx0XHR9O1xuXHRcdHJlZ2lvbkZpZWxkcy5pbmRleCA9IChyZWdpb246IFRleHR1cmVBdGxhc1JlZ2lvbikgPT4ge1xuXHRcdFx0cmVnaW9uLmluZGV4ID0gcGFyc2VJbnQoZW50cnlbMV0pO1xuXHRcdH07XG5cblx0XHRsZXQgbGluZSA9IHJlYWRlci5yZWFkTGluZSgpO1xuXHRcdC8vIElnbm9yZSBlbXB0eSBsaW5lcyBiZWZvcmUgZmlyc3QgZW50cnkuXG5cdFx0d2hpbGUgKGxpbmUgJiYgbGluZS50cmltKCkubGVuZ3RoID09PSAwKVxuXHRcdFx0bGluZSA9IHJlYWRlci5yZWFkTGluZSgpO1xuXHRcdC8vIEhlYWRlciBlbnRyaWVzLlxuXHRcdHdoaWxlICh0cnVlKSB7XG5cdFx0XHRpZiAoIWxpbmUgfHwgbGluZS50cmltKCkubGVuZ3RoID09PSAwKSBicmVhaztcblx0XHRcdGlmIChyZWFkZXIucmVhZEVudHJ5KGVudHJ5LCBsaW5lKSA9PT0gMCkgYnJlYWs7IC8vIFNpbGVudGx5IGlnbm9yZSBhbGwgaGVhZGVyIGZpZWxkcy5cblx0XHRcdGxpbmUgPSByZWFkZXIucmVhZExpbmUoKTtcblx0XHR9XG5cblx0XHQvLyBQYWdlIGFuZCByZWdpb24gZW50cmllcy5cblx0XHRsZXQgcGFnZTogVGV4dHVyZUF0bGFzUGFnZSB8IG51bGwgPSBudWxsO1xuXHRcdGxldCBuYW1lczogc3RyaW5nW10gfCBudWxsID0gbnVsbDtcblx0XHRsZXQgdmFsdWVzOiBudW1iZXJbXVtdIHwgbnVsbCA9IG51bGw7XG5cdFx0d2hpbGUgKHRydWUpIHtcblx0XHRcdGlmIChsaW5lID09PSBudWxsKSBicmVhaztcblx0XHRcdGlmIChsaW5lLnRyaW0oKS5sZW5ndGggPT09IDApIHtcblx0XHRcdFx0cGFnZSA9IG51bGw7XG5cdFx0XHRcdGxpbmUgPSByZWFkZXIucmVhZExpbmUoKTtcblx0XHRcdH0gZWxzZSBpZiAoIXBhZ2UpIHtcblx0XHRcdFx0cGFnZSA9IG5ldyBUZXh0dXJlQXRsYXNQYWdlKGxpbmUudHJpbSgpKTtcblx0XHRcdFx0d2hpbGUgKHRydWUpIHtcblx0XHRcdFx0XHRpZiAocmVhZGVyLnJlYWRFbnRyeShlbnRyeSwgbGluZSA9IHJlYWRlci5yZWFkTGluZSgpKSA9PT0gMCkgYnJlYWs7XG5cdFx0XHRcdFx0Y29uc3QgZmllbGQgPSBwYWdlRmllbGRzW2VudHJ5WzBdXTtcblx0XHRcdFx0XHRpZiAoZmllbGQpIGZpZWxkKHBhZ2UpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRoaXMucGFnZXMucHVzaChwYWdlKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNvbnN0IHJlZ2lvbiA9IG5ldyBUZXh0dXJlQXRsYXNSZWdpb24ocGFnZSwgbGluZSk7XG5cblx0XHRcdFx0d2hpbGUgKHRydWUpIHtcblx0XHRcdFx0XHRjb25zdCBjb3VudCA9IHJlYWRlci5yZWFkRW50cnkoZW50cnksIGxpbmUgPSByZWFkZXIucmVhZExpbmUoKSk7XG5cdFx0XHRcdFx0aWYgKGNvdW50ID09PSAwKSBicmVhaztcblx0XHRcdFx0XHRjb25zdCBmaWVsZCA9IHJlZ2lvbkZpZWxkc1tlbnRyeVswXV07XG5cdFx0XHRcdFx0aWYgKGZpZWxkKVxuXHRcdFx0XHRcdFx0ZmllbGQocmVnaW9uKTtcblx0XHRcdFx0XHRlbHNlIHtcblx0XHRcdFx0XHRcdGlmICghbmFtZXMpIG5hbWVzID0gW107XG5cdFx0XHRcdFx0XHRpZiAoIXZhbHVlcykgdmFsdWVzID0gW107XG5cdFx0XHRcdFx0XHRuYW1lcy5wdXNoKGVudHJ5WzBdKTtcblx0XHRcdFx0XHRcdGNvbnN0IGVudHJ5VmFsdWVzOiBudW1iZXJbXSA9IFtdO1xuXHRcdFx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKVxuXHRcdFx0XHRcdFx0XHRlbnRyeVZhbHVlcy5wdXNoKHBhcnNlSW50KGVudHJ5W2kgKyAxXSkpO1xuXHRcdFx0XHRcdFx0dmFsdWVzLnB1c2goZW50cnlWYWx1ZXMpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAocmVnaW9uLm9yaWdpbmFsV2lkdGggPT09IDAgJiYgcmVnaW9uLm9yaWdpbmFsSGVpZ2h0ID09PSAwKSB7XG5cdFx0XHRcdFx0cmVnaW9uLm9yaWdpbmFsV2lkdGggPSByZWdpb24ud2lkdGg7XG5cdFx0XHRcdFx0cmVnaW9uLm9yaWdpbmFsSGVpZ2h0ID0gcmVnaW9uLmhlaWdodDtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAobmFtZXMgJiYgbmFtZXMubGVuZ3RoID4gMCAmJiB2YWx1ZXMgJiYgdmFsdWVzLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0XHRyZWdpb24ubmFtZXMgPSBuYW1lcztcblx0XHRcdFx0XHRyZWdpb24udmFsdWVzID0gdmFsdWVzO1xuXHRcdFx0XHRcdG5hbWVzID0gbnVsbDtcblx0XHRcdFx0XHR2YWx1ZXMgPSBudWxsO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJlZ2lvbi51ID0gcmVnaW9uLnggLyBwYWdlLndpZHRoO1xuXHRcdFx0XHRyZWdpb24udiA9IHJlZ2lvbi55IC8gcGFnZS5oZWlnaHQ7XG5cdFx0XHRcdGlmIChyZWdpb24uZGVncmVlcyA9PT0gOTApIHtcblx0XHRcdFx0XHRyZWdpb24udTIgPSAocmVnaW9uLnggKyByZWdpb24uaGVpZ2h0KSAvIHBhZ2Uud2lkdGg7XG5cdFx0XHRcdFx0cmVnaW9uLnYyID0gKHJlZ2lvbi55ICsgcmVnaW9uLndpZHRoKSAvIHBhZ2UuaGVpZ2h0O1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlZ2lvbi51MiA9IChyZWdpb24ueCArIHJlZ2lvbi53aWR0aCkgLyBwYWdlLndpZHRoO1xuXHRcdFx0XHRcdHJlZ2lvbi52MiA9IChyZWdpb24ueSArIHJlZ2lvbi5oZWlnaHQpIC8gcGFnZS5oZWlnaHQ7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5yZWdpb25zLnB1c2gocmVnaW9uKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRmaW5kUmVnaW9uIChuYW1lOiBzdHJpbmcpOiBUZXh0dXJlQXRsYXNSZWdpb24gfCBudWxsIHtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucmVnaW9ucy5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKHRoaXMucmVnaW9uc1tpXS5uYW1lID09PSBuYW1lKSB7XG5cdFx0XHRcdHJldHVybiB0aGlzLnJlZ2lvbnNbaV07XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0c2V0VGV4dHVyZXMgKGFzc2V0TWFuYWdlcjogQXNzZXRNYW5hZ2VyQmFzZSwgcGF0aFByZWZpeDogc3RyaW5nID0gXCJcIikge1xuXHRcdGZvciAoY29uc3QgcGFnZSBvZiB0aGlzLnBhZ2VzKVxuXHRcdFx0cGFnZS5zZXRUZXh0dXJlKGFzc2V0TWFuYWdlci5nZXQocGF0aFByZWZpeCArIHBhZ2UubmFtZSkgYXMgVGV4dHVyZSk7XG5cdH1cblxuXHRkaXNwb3NlICgpIHtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucGFnZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMucGFnZXNbaV0udGV4dHVyZT8uZGlzcG9zZSgpO1xuXHRcdH1cblx0fVxufVxuXG5jbGFzcyBUZXh0dXJlQXRsYXNSZWFkZXIge1xuXHRsaW5lczogQXJyYXk8c3RyaW5nPjtcblx0aW5kZXg6IG51bWJlciA9IDA7XG5cblx0Y29uc3RydWN0b3IgKHRleHQ6IHN0cmluZykge1xuXHRcdHRoaXMubGluZXMgPSB0ZXh0LnNwbGl0KC9cXHJcXG58XFxyfFxcbi8pO1xuXHR9XG5cblx0cmVhZExpbmUgKCk6IHN0cmluZyB8IG51bGwge1xuXHRcdGlmICh0aGlzLmluZGV4ID49IHRoaXMubGluZXMubGVuZ3RoKVxuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0cmV0dXJuIHRoaXMubGluZXNbdGhpcy5pbmRleCsrXTtcblx0fVxuXG5cdHJlYWRFbnRyeSAoZW50cnk6IHN0cmluZ1tdLCBsaW5lOiBzdHJpbmcgfCBudWxsKTogbnVtYmVyIHtcblx0XHRpZiAoIWxpbmUpIHJldHVybiAwO1xuXHRcdGxpbmUgPSBsaW5lLnRyaW0oKTtcblx0XHRpZiAobGluZS5sZW5ndGggPT09IDApIHJldHVybiAwO1xuXG5cdFx0Y29uc3QgY29sb24gPSBsaW5lLmluZGV4T2YoJzonKTtcblx0XHRpZiAoY29sb24gPT09IC0xKSByZXR1cm4gMDtcblx0XHRlbnRyeVswXSA9IGxpbmUuc3Vic3RyKDAsIGNvbG9uKS50cmltKCk7XG5cdFx0Zm9yIChsZXQgaSA9IDEsIGxhc3RNYXRjaCA9IGNvbG9uICsgMTsgOyBpKyspIHtcblx0XHRcdGNvbnN0IGNvbW1hID0gbGluZS5pbmRleE9mKCcsJywgbGFzdE1hdGNoKTtcblx0XHRcdGlmIChjb21tYSA9PT0gLTEpIHtcblx0XHRcdFx0ZW50cnlbaV0gPSBsaW5lLnN1YnN0cihsYXN0TWF0Y2gpLnRyaW0oKTtcblx0XHRcdFx0cmV0dXJuIGk7XG5cdFx0XHR9XG5cdFx0XHRlbnRyeVtpXSA9IGxpbmUuc3Vic3RyKGxhc3RNYXRjaCwgY29tbWEgLSBsYXN0TWF0Y2gpLnRyaW0oKTtcblx0XHRcdGxhc3RNYXRjaCA9IGNvbW1hICsgMTtcblx0XHRcdGlmIChpID09PSA0KSByZXR1cm4gNDtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGNsYXNzIFRleHR1cmVBdGxhc1BhZ2Uge1xuXHRuYW1lOiBzdHJpbmc7XG5cdG1pbkZpbHRlcjogVGV4dHVyZUZpbHRlciA9IFRleHR1cmVGaWx0ZXIuTmVhcmVzdDtcblx0bWFnRmlsdGVyOiBUZXh0dXJlRmlsdGVyID0gVGV4dHVyZUZpbHRlci5OZWFyZXN0O1xuXHR1V3JhcDogVGV4dHVyZVdyYXAgPSBUZXh0dXJlV3JhcC5DbGFtcFRvRWRnZTtcblx0dldyYXA6IFRleHR1cmVXcmFwID0gVGV4dHVyZVdyYXAuQ2xhbXBUb0VkZ2U7XG5cdHRleHR1cmU6IFRleHR1cmUgfCBudWxsID0gbnVsbDtcblx0d2lkdGg6IG51bWJlciA9IDA7XG5cdGhlaWdodDogbnVtYmVyID0gMDtcblx0cG1hOiBib29sZWFuID0gZmFsc2U7XG5cdHJlZ2lvbnMgPSBbXSBhcyBUZXh0dXJlQXRsYXNSZWdpb25bXTtcblxuXHRjb25zdHJ1Y3RvciAobmFtZTogc3RyaW5nKSB7XG5cdFx0dGhpcy5uYW1lID0gbmFtZTtcblx0fVxuXG5cdHNldFRleHR1cmUgKHRleHR1cmU6IFRleHR1cmUpIHtcblx0XHR0aGlzLnRleHR1cmUgPSB0ZXh0dXJlO1xuXHRcdHRleHR1cmUuc2V0RmlsdGVycyh0aGlzLm1pbkZpbHRlciwgdGhpcy5tYWdGaWx0ZXIpO1xuXHRcdHRleHR1cmUuc2V0V3JhcHModGhpcy51V3JhcCwgdGhpcy52V3JhcCk7XG5cdFx0Zm9yIChjb25zdCByZWdpb24gb2YgdGhpcy5yZWdpb25zKVxuXHRcdFx0cmVnaW9uLnRleHR1cmUgPSB0ZXh0dXJlO1xuXHR9XG59XG5cbmV4cG9ydCBjbGFzcyBUZXh0dXJlQXRsYXNSZWdpb24gZXh0ZW5kcyBUZXh0dXJlUmVnaW9uIHtcblx0cGFnZTogVGV4dHVyZUF0bGFzUGFnZTtcblx0bmFtZTogc3RyaW5nO1xuXHR4OiBudW1iZXIgPSAwO1xuXHR5OiBudW1iZXIgPSAwO1xuXHRvZmZzZXRYOiBudW1iZXIgPSAwO1xuXHRvZmZzZXRZOiBudW1iZXIgPSAwO1xuXHRvcmlnaW5hbFdpZHRoOiBudW1iZXIgPSAwO1xuXHRvcmlnaW5hbEhlaWdodDogbnVtYmVyID0gMDtcblx0aW5kZXg6IG51bWJlciA9IDA7XG5cdGRlZ3JlZXM6IG51bWJlciA9IDA7XG5cdG5hbWVzOiBzdHJpbmdbXSB8IG51bGwgPSBudWxsO1xuXHR2YWx1ZXM6IG51bWJlcltdW10gfCBudWxsID0gbnVsbDtcblxuXHRjb25zdHJ1Y3RvciAocGFnZTogVGV4dHVyZUF0bGFzUGFnZSwgbmFtZTogc3RyaW5nKSB7XG5cdFx0c3VwZXIoKTtcblx0XHR0aGlzLnBhZ2UgPSBwYWdlO1xuXHRcdHRoaXMubmFtZSA9IG5hbWU7XG5cdFx0cGFnZS5yZWdpb25zLnB1c2godGhpcyk7XG5cdH1cbn1cbiJdfQ==