UNPKG

@esotericsoftware/spine-core

Version:
320 lines 43.6 kB
/****************************************************************************** * Spine Runtimes License Agreement * Last updated July 28, 2023. Replaces all prior versions. * * Copyright (c) 2013-2023, 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 { TextureAtlas } from "./TextureAtlas.js"; export class AssetManagerBase { pathPrefix = ""; textureLoader; downloader; assets = {}; errors = {}; toLoad = 0; loaded = 0; constructor(textureLoader, pathPrefix = "", downloader = new Downloader()) { this.textureLoader = textureLoader; this.pathPrefix = pathPrefix; this.downloader = downloader; } start(path) { this.toLoad++; return this.pathPrefix + path; } success(callback, path, asset) { this.toLoad--; this.loaded++; this.assets[path] = asset; if (callback) callback(path, asset); } error(callback, path, message) { this.toLoad--; this.loaded++; this.errors[path] = message; if (callback) callback(path, message); } loadAll() { let promise = new Promise((resolve, reject) => { let check = () => { if (this.isLoadingComplete()) { if (this.hasErrors()) reject(this.errors); else resolve(this); return; } requestAnimationFrame(check); }; requestAnimationFrame(check); }); return promise; } setRawDataURI(path, data) { this.downloader.rawDataUris[this.pathPrefix + path] = data; } loadBinary(path, success = () => { }, error = () => { }) { path = this.start(path); this.downloader.downloadBinary(path, (data) => { this.success(success, path, data); }, (status, responseText) => { this.error(error, path, `Couldn't load binary ${path}: status ${status}, ${responseText}`); }); } loadText(path, success = () => { }, error = () => { }) { path = this.start(path); this.downloader.downloadText(path, (data) => { this.success(success, path, data); }, (status, responseText) => { this.error(error, path, `Couldn't load text ${path}: status ${status}, ${responseText}`); }); } loadJson(path, success = () => { }, error = () => { }) { path = this.start(path); this.downloader.downloadJson(path, (data) => { this.success(success, path, data); }, (status, responseText) => { this.error(error, path, `Couldn't load JSON ${path}: status ${status}, ${responseText}`); }); } loadTexture(path, success = () => { }, error = () => { }) { path = this.start(path); let isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document); let isWebWorker = !isBrowser; // && typeof importScripts !== 'undefined'; if (isWebWorker) { fetch(path, { mode: "cors" }).then((response) => { if (response.ok) return response.blob(); this.error(error, path, `Couldn't load image: ${path}`); return null; }).then((blob) => { return blob ? createImageBitmap(blob, { premultiplyAlpha: "none", colorSpaceConversion: "none" }) : null; }).then((bitmap) => { if (bitmap) this.success(success, path, this.textureLoader(bitmap)); }); } else { let image = new Image(); image.crossOrigin = "anonymous"; image.onload = () => { this.success(success, path, this.textureLoader(image)); }; image.onerror = () => { this.error(error, path, `Couldn't load image: ${path}`); }; if (this.downloader.rawDataUris[path]) path = this.downloader.rawDataUris[path]; image.src = path; } } loadTextureAtlas(path, success = () => { }, error = () => { }, fileAlias) { let index = path.lastIndexOf("/"); let parent = index >= 0 ? path.substring(0, index + 1) : ""; path = this.start(path); this.downloader.downloadText(path, (atlasText) => { try { let atlas = new TextureAtlas(atlasText); let toLoad = atlas.pages.length, abort = false; for (let page of atlas.pages) { this.loadTexture(!fileAlias ? parent + page.name : fileAlias[page.name], (imagePath, texture) => { if (!abort) { page.setTexture(texture); if (--toLoad == 0) this.success(success, path, atlas); } }, (imagePath, message) => { if (!abort) this.error(error, path, `Couldn't load texture atlas ${path} page image: ${imagePath}`); abort = true; }); } } catch (e) { this.error(error, path, `Couldn't parse texture atlas ${path}: ${e.message}`); } }, (status, responseText) => { this.error(error, path, `Couldn't load texture atlas ${path}: status ${status}, ${responseText}`); }); } get(path) { return this.assets[this.pathPrefix + path]; } require(path) { path = this.pathPrefix + path; let asset = this.assets[path]; if (asset) return asset; let error = this.errors[path]; throw Error("Asset not found: " + path + (error ? "\n" + error : "")); } remove(path) { path = this.pathPrefix + path; let asset = this.assets[path]; if (asset.dispose) asset.dispose(); delete this.assets[path]; return asset; } removeAll() { for (let key in this.assets) { let asset = this.assets[key]; if (asset.dispose) asset.dispose(); } this.assets = {}; } isLoadingComplete() { return this.toLoad == 0; } getToLoad() { return this.toLoad; } getLoaded() { return this.loaded; } dispose() { this.removeAll(); } hasErrors() { return Object.keys(this.errors).length > 0; } getErrors() { return this.errors; } } export class Downloader { callbacks = {}; rawDataUris = {}; dataUriToString(dataUri) { if (!dataUri.startsWith("data:")) { throw new Error("Not a data URI."); } let base64Idx = dataUri.indexOf("base64,"); if (base64Idx != -1) { base64Idx += "base64,".length; return atob(dataUri.substr(base64Idx)); } else { return dataUri.substr(dataUri.indexOf(",") + 1); } } base64ToUint8Array(base64) { var binary_string = window.atob(base64); var len = binary_string.length; var bytes = new Uint8Array(len); for (var i = 0; i < len; i++) { bytes[i] = binary_string.charCodeAt(i); } return bytes; } dataUriToUint8Array(dataUri) { if (!dataUri.startsWith("data:")) { throw new Error("Not a data URI."); } let base64Idx = dataUri.indexOf("base64,"); if (base64Idx == -1) throw new Error("Not a binary data URI."); base64Idx += "base64,".length; return this.base64ToUint8Array(dataUri.substr(base64Idx)); } downloadText(url, success, error) { if (this.start(url, success, error)) return; if (this.rawDataUris[url]) { try { let dataUri = this.rawDataUris[url]; this.finish(url, 200, this.dataUriToString(dataUri)); } catch (e) { this.finish(url, 400, JSON.stringify(e)); } return; } let request = new XMLHttpRequest(); request.overrideMimeType("text/html"); request.open("GET", url, true); let done = () => { this.finish(url, request.status, request.responseText); }; request.onload = done; request.onerror = done; request.send(); } downloadJson(url, success, error) { this.downloadText(url, (data) => { success(JSON.parse(data)); }, error); } downloadBinary(url, success, error) { if (this.start(url, success, error)) return; if (this.rawDataUris[url]) { try { let dataUri = this.rawDataUris[url]; this.finish(url, 200, this.dataUriToUint8Array(dataUri)); } catch (e) { this.finish(url, 400, JSON.stringify(e)); } return; } let request = new XMLHttpRequest(); request.open("GET", url, true); request.responseType = "arraybuffer"; let onerror = () => { this.finish(url, request.status, request.response); }; request.onload = () => { if (request.status == 200 || request.status == 0) this.finish(url, 200, new Uint8Array(request.response)); else onerror(); }; request.onerror = onerror; request.send(); } start(url, success, error) { let callbacks = this.callbacks[url]; try { if (callbacks) return true; this.callbacks[url] = callbacks = []; } finally { callbacks.push(success, error); } } finish(url, status, data) { let callbacks = this.callbacks[url]; delete this.callbacks[url]; let args = status == 200 || status == 0 ? [data] : [status, data]; for (let i = args.length - 1, n = callbacks.length; i < n; i += 2) callbacks[i].apply(null, args); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXNzZXRNYW5hZ2VyQmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Bc3NldE1hbmFnZXJCYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7K0VBMkIrRTtBQUcvRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHakQsTUFBTSxPQUFPLGdCQUFnQjtJQUNwQixVQUFVLEdBQVcsRUFBRSxDQUFDO0lBQ3hCLGFBQWEsQ0FBcUQ7SUFDbEUsVUFBVSxDQUFhO0lBQ3ZCLE1BQU0sR0FBbUIsRUFBRSxDQUFDO0lBQzVCLE1BQU0sR0FBc0IsRUFBRSxDQUFDO0lBQy9CLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDWCxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRW5CLFlBQWEsYUFBaUUsRUFBRSxhQUFxQixFQUFFLEVBQUUsYUFBeUIsSUFBSSxVQUFVLEVBQUU7UUFDakosSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7UUFDbkMsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7SUFDOUIsQ0FBQztJQUVPLEtBQUssQ0FBRSxJQUFZO1FBQzFCLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNkLE9BQU8sSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7SUFDL0IsQ0FBQztJQUVPLE9BQU8sQ0FBRSxRQUEyQyxFQUFFLElBQVksRUFBRSxLQUFVO1FBQ3JGLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNkLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNkLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQzFCLElBQUksUUFBUTtZQUFFLFFBQVEsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVPLEtBQUss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Q0FBQztJQUVPLE1BQU0sQ0FBRSxHQUFXLEVBQUUsTUFBYyxFQUFFLElBQVM7UUFDckQsSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNwQyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDM0IsSUFBSSxJQUFJLEdBQUcsTUFBTSxJQUFJLEdBQUcsSUFBSSxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNsRSxLQUFLLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUM7WUFDaEUsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDakMsQ0FBQztDQUNEIiwic291cmNlc0NvbnRlbnQiOlsiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogU3BpbmUgUnVudGltZXMgTGljZW5zZSBBZ3JlZW1lbnRcbiAqIExhc3QgdXBkYXRlZCBKdWx5IDI4LCAyMDIzLiBSZXBsYWNlcyBhbGwgcHJpb3IgdmVyc2lvbnMuXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEzLTIwMjMsIEVzb3RlcmljIFNvZnR3YXJlIExMQ1xuICpcbiAqIEludGVncmF0aW9uIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpbnRvIHNvZnR3YXJlIG9yIG90aGVyd2lzZSBjcmVhdGluZ1xuICogZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgaXMgcGVybWl0dGVkIHVuZGVyIHRoZSB0ZXJtcyBhbmRcbiAqIGNvbmRpdGlvbnMgb2YgU2VjdGlvbiAyIG9mIHRoZSBTcGluZSBFZGl0b3IgTGljZW5zZSBBZ3JlZW1lbnQ6XG4gKiBodHRwOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb20vc3BpbmUtZWRpdG9yLWxpY2Vuc2VcbiAqXG4gKiBPdGhlcndpc2UsIGl0IGlzIHBlcm1pdHRlZCB0byBpbnRlZ3JhdGUgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmUgb3JcbiAqIG90aGVyd2lzZSBjcmVhdGUgZGVyaXZhdGl2ZSB3b3JrcyBvZiB0aGUgU3BpbmUgUnVudGltZXMgKGNvbGxlY3RpdmVseSxcbiAqIFwiUHJvZHVjdHNcIiksIHByb3ZpZGVkIHRoYXQgZWFjaCB1c2VyIG9mIHRoZSBQcm9kdWN0cyBtdXN0IG9idGFpbiB0aGVpciBvd25cbiAqIFNwaW5lIEVkaXRvciBsaWNlbnNlIGFuZCByZWRpc3RyaWJ1dGlvbiBvZiB0aGUgUHJvZHVjdHMgaW4gYW55IGZvcm0gbXVzdFxuICogaW5jbHVkZSB0aGlzIGxpY2Vuc2UgYW5kIGNvcHlyaWdodCBub3RpY2UuXG4gKlxuICogVEhFIFNQSU5FIFJVTlRJTUVTIEFSRSBQUk9WSURFRCBCWSBFU09URVJJQyBTT0ZUV0FSRSBMTEMgXCJBUyBJU1wiIEFORCBBTllcbiAqIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRURcbiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkVcbiAqIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIEVTT1RFUklDIFNPRlRXQVJFIExMQyBCRSBMSUFCTEUgRk9SIEFOWVxuICogRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUyxcbiAqIEJVU0lORVNTIElOVEVSUlVQVElPTiwgT1IgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFMpIEhPV0VWRVIgQ0FVU0VEIEFORFxuICogT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSEVcbiAqIFNQSU5FIFJVTlRJTUVTLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyBUZXh0dXJlIH0gZnJvbSBcIi4vVGV4dHVyZS5qc1wiO1xuaW1wb3J0IHsgVGV4dHVyZUF0bGFzIH0gZnJvbSBcIi4vVGV4dHVyZUF0bGFzLmpzXCI7XG5pbXBvcnQgeyBEaXNwb3NhYmxlLCBTdHJpbmdNYXAgfSBmcm9tIFwiLi9VdGlscy5qc1wiO1xuXG5leHBvcnQgY2xhc3MgQXNzZXRNYW5hZ2VyQmFzZSBpbXBsZW1lbnRzIERpc3Bvc2FibGUge1xuXHRwcml2YXRlIHBhdGhQcmVmaXg6IHN0cmluZyA9IFwiXCI7XG5cdHByaXZhdGUgdGV4dHVyZUxvYWRlcjogKGltYWdlOiBIVE1MSW1hZ2VFbGVtZW50IHwgSW1hZ2VCaXRtYXApID0+IFRleHR1cmU7XG5cdHByaXZhdGUgZG93bmxvYWRlcjogRG93bmxvYWRlcjtcblx0cHJpdmF0ZSBhc3NldHM6IFN0cmluZ01hcDxhbnk+ID0ge307XG5cdHByaXZhdGUgZXJyb3JzOiBTdHJpbmdNYXA8c3RyaW5nPiA9IHt9O1xuXHRwcml2YXRlIHRvTG9hZCA9IDA7XG5cdHByaXZhdGUgbG9hZGVkID0gMDtcblxuXHRjb25zdHJ1Y3RvciAodGV4dHVyZUxvYWRlcjogKGltYWdlOiBIVE1MSW1hZ2VFbGVtZW50IHwgSW1hZ2VCaXRtYXApID0+IFRleHR1cmUsIHBhdGhQcmVmaXg6IHN0cmluZyA9IFwiXCIsIGRvd25sb2FkZXI6IERvd25sb2FkZXIgPSBuZXcgRG93bmxvYWRlcigpKSB7XG5cdFx0dGhpcy50ZXh0dXJlTG9hZGVyID0gdGV4dHVyZUxvYWRlcjtcblx0XHR0aGlzLnBhdGhQcmVmaXggPSBwYXRoUHJlZml4O1xuXHRcdHRoaXMuZG93bmxvYWRlciA9IGRvd25sb2FkZXI7XG5cdH1cblxuXHRwcml2YXRlIHN0YXJ0IChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuXHRcdHRoaXMudG9Mb2FkKys7XG5cdFx0cmV0dXJuIHRoaXMucGF0aFByZWZpeCArIHBhdGg7XG5cdH1cblxuXHRwcml2YXRlIHN1Y2Nlc3MgKGNhbGxiYWNrOiAocGF0aDogc3RyaW5nLCBkYXRhOiBhbnkpID0+IHZvaWQsIHBhdGg6IHN0cmluZywgYXNzZXQ6IGFueSkge1xuXHRcdHRoaXMudG9Mb2FkLS07XG5cdFx0dGhpcy5sb2FkZWQrKztcblx0XHR0aGlzLmFzc2V0c1twYXRoXSA9IGFzc2V0O1xuXHRcdGlmIChjYWxsYmFjaykgY2FsbGJhY2socGF0aCwgYXNzZXQpO1xuXHR9XG5cblx0cHJpdmF0ZSBlcnJvciAoY2FsbGJhY2s6IChwYXRoOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZCwgcGF0aDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpIHtcblx0XHR0aGlzLnRvTG9hZC0tO1xuXHRcdHRoaXMubG9hZGVkKys7XG5cdFx0dGhpcy5lcnJvcnNbcGF0aF0gPSBtZXNzYWdlO1xuXHRcdGlmIChjYWxsYmFjaykgY2FsbGJhY2socGF0aCwgbWVzc2FnZSk7XG5cdH1cblxuXHRsb2FkQWxsICgpIHtcblx0XHRsZXQgcHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlOiAoYXNzZXRNYW5hZ2VyOiBBc3NldE1hbmFnZXJCYXNlKSA9PiB2b2lkLCByZWplY3Q6IChlcnJvcnM6IFN0cmluZ01hcDxzdHJpbmc+KSA9PiB2b2lkKSA9PiB7XG5cdFx0XHRsZXQgY2hlY2sgPSAoKSA9PiB7XG5cdFx0XHRcdGlmICh0aGlzLmlzTG9hZGluZ0NvbXBsZXRlKCkpIHtcblx0XHRcdFx0XHRpZiAodGhpcy5oYXNFcnJvcnMoKSkgcmVqZWN0KHRoaXMuZXJyb3JzKTtcblx0XHRcdFx0XHRlbHNlIHJlc29sdmUodGhpcyk7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJlcXVlc3RBbmltYXRpb25GcmFtZShjaGVjayk7XG5cdFx0XHR9XG5cdFx0XHRyZXF1ZXN0QW5pbWF0aW9uRnJhbWUoY2hlY2spO1xuXHRcdH0pO1xuXHRcdHJldHVybiBwcm9taXNlO1xuXHR9XG5cblx0c2V0UmF3RGF0YVVSSSAocGF0aDogc3RyaW5nLCBkYXRhOiBzdHJpbmcpIHtcblx0XHR0aGlzLmRvd25sb2FkZXIucmF3RGF0YVVyaXNbdGhpcy5wYXRoUHJlZml4ICsgcGF0aF0gPSBkYXRhO1xuXHR9XG5cblx0bG9hZEJpbmFyeSAocGF0aDogc3RyaW5nLFxuXHRcdHN1Y2Nlc3M6IChwYXRoOiBzdHJpbmcsIGJpbmFyeTogVWludDhBcnJheSkgPT4gdm9pZCA9ICgpID0+IHsgfSxcblx0XHRlcnJvcjogKHBhdGg6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkID0gKCkgPT4geyB9KSB7XG5cdFx0cGF0aCA9IHRoaXMuc3RhcnQocGF0aCk7XG5cblx0XHR0aGlzLmRvd25sb2FkZXIuZG93bmxvYWRCaW5hcnkocGF0aCwgKGRhdGE6IFVpbnQ4QXJyYXkpOiB2b2lkID0+IHtcblx0XHRcdHRoaXMuc3VjY2VzcyhzdWNjZXNzLCBwYXRoLCBkYXRhKTtcblx0XHR9LCAoc3RhdHVzOiBudW1iZXIsIHJlc3BvbnNlVGV4dDogc3RyaW5nKTogdm9pZCA9PiB7XG5cdFx0XHR0aGlzLmVycm9yKGVycm9yLCBwYXRoLCBgQ291bGRuJ3QgbG9hZCBiaW5hcnkgJHtwYXRofTogc3RhdHVzICR7c3RhdHVzfSwgJHtyZXNwb25zZVRleHR9YCk7XG5cdFx0fSk7XG5cdH1cblxuXHRsb2FkVGV4dCAocGF0aDogc3RyaW5nLFxuXHRcdHN1Y2Nlc3M6IChwYXRoOiBzdHJpbmcsIHRleHQ6IHN0cmluZykgPT4gdm9pZCA9ICgpID0+IHsgfSxcblx0XHRlcnJvcjogKHBhdGg6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkID0gKCkgPT4geyB9KSB7XG5cdFx0cGF0aCA9IHRoaXMuc3RhcnQocGF0aCk7XG5cblx0XHR0aGlzLmRvd25sb2FkZXIuZG93bmxvYWRUZXh0KHBhdGgsIChkYXRhOiBzdHJpbmcpOiB2b2lkID0+IHtcblx0XHRcdHRoaXMuc3VjY2VzcyhzdWNjZXNzLCBwYXRoLCBkYXRhKTtcblx0XHR9LCAoc3RhdHVzOiBudW1iZXIsIHJlc3BvbnNlVGV4dDogc3RyaW5nKTogdm9pZCA9PiB7XG5cdFx0XHR0aGlzLmVycm9yKGVycm9yLCBwYXRoLCBgQ291bGRuJ3QgbG9hZCB0ZXh0ICR7cGF0aH06IHN0YXR1cyAke3N0YXR1c30sICR7cmVzcG9uc2VUZXh0fWApO1xuXHRcdH0pO1xuXHR9XG5cblx0bG9hZEpzb24gKHBhdGg6IHN0cmluZyxcblx0XHRzdWNjZXNzOiAocGF0aDogc3RyaW5nLCBvYmplY3Q6IG9iamVjdCkgPT4gdm9pZCA9ICgpID0+IHsgfSxcblx0XHRlcnJvcjogKHBhdGg6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkID0gKCkgPT4geyB9KSB7XG5cdFx0cGF0aCA9IHRoaXMuc3RhcnQocGF0aCk7XG5cblx0XHR0aGlzLmRvd25sb2FkZXIuZG93bmxvYWRKc29uKHBhdGgsIChkYXRhOiBvYmplY3QpOiB2b2lkID0+IHtcblx0XHRcdHRoaXMuc3VjY2VzcyhzdWNjZXNzLCBwYXRoLCBkYXRhKTtcblx0XHR9LCAoc3RhdHVzOiBudW1iZXIsIHJlc3BvbnNlVGV4dDogc3RyaW5nKTogdm9pZCA9PiB7XG5cdFx0XHR0aGlzLmVycm9yKGVycm9yLCBwYXRoLCBgQ291bGRuJ3QgbG9hZCBKU09OICR7cGF0aH06IHN0YXR1cyAke3N0YXR1c30sICR7cmVzcG9uc2VUZXh0fWApO1xuXHRcdH0pO1xuXHR9XG5cblx0bG9hZFRleHR1cmUgKHBhdGg6IHN0cmluZyxcblx0XHRzdWNjZXNzOiAocGF0aDogc3RyaW5nLCB0ZXh0dXJlOiBUZXh0dXJlKSA9PiB2b2lkID0gKCkgPT4geyB9LFxuXHRcdGVycm9yOiAocGF0aDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQgPSAoKSA9PiB7IH0pIHtcblx0XHRwYXRoID0gdGhpcy5zdGFydChwYXRoKTtcblxuXHRcdGxldCBpc0Jyb3dzZXIgPSAhISh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuZG9jdW1lbnQpO1xuXHRcdGxldCBpc1dlYldvcmtlciA9ICFpc0Jyb3dzZXI7IC8vICYmIHR5cGVvZiBpbXBvcnRTY3JpcHRzICE9PSAndW5kZWZpbmVkJztcblx0XHRpZiAoaXNXZWJXb3JrZXIpIHtcblx0XHRcdGZldGNoKHBhdGgsIHsgbW9kZTogPFJlcXVlc3RNb2RlPlwiY29yc1wiIH0pLnRoZW4oKHJlc3BvbnNlKSA9PiB7XG5cdFx0XHRcdGlmIChyZXNwb25zZS5vaykgcmV0dXJuIHJlc3BvbnNlLmJsb2IoKTtcblx0XHRcdFx0dGhpcy5lcnJvcihlcnJvciwgcGF0aCwgYENvdWxkbid0IGxvYWQgaW1hZ2U6ICR7cGF0aH1gKTtcblx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHR9KS50aGVuKChibG9iKSA9PiB7XG5cdFx0XHRcdHJldHVybiBibG9iID8gY3JlYXRlSW1hZ2VCaXRtYXAoYmxvYiwgeyBwcmVtdWx0aXBseUFscGhhOiBcIm5vbmVcIiwgY29sb3JTcGFjZUNvbnZlcnNpb246IFwibm9uZVwiIH0pIDogbnVsbDtcblx0XHRcdH0pLnRoZW4oKGJpdG1hcCkgPT4ge1xuXHRcdFx0XHRpZiAoYml0bWFwKSB0aGlzLnN1Y2Nlc3Moc3VjY2VzcywgcGF0aCwgdGhpcy50ZXh0dXJlTG9hZGVyKGJpdG1hcCkpO1xuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGxldCBpbWFnZSA9IG5ldyBJbWFnZSgpO1xuXHRcdFx0aW1hZ2UuY3Jvc3NPcmlnaW4gPSBcImFub255bW91c1wiO1xuXHRcdFx0aW1hZ2Uub25sb2FkID0gKCkgPT4ge1xuXHRcdFx0XHR0aGlzLnN1Y2Nlc3Moc3VjY2VzcywgcGF0aCwgdGhpcy50ZXh0dXJlTG9hZGVyKGltYWdlKSk7XG5cdFx0XHR9O1xuXHRcdFx0aW1hZ2Uub25lcnJvciA9ICgpID0+IHtcblx0XHRcdFx0dGhpcy5lcnJvcihlcnJvciwgcGF0aCwgYENvdWxkbid0IGxvYWQgaW1hZ2U6ICR7cGF0aH1gKTtcblx0XHRcdH07XG5cdFx0XHRpZiAodGhpcy5kb3dubG9hZGVyLnJhd0RhdGFVcmlzW3BhdGhdKSBwYXRoID0gdGhpcy5kb3dubG9hZGVyLnJhd0RhdGFVcmlzW3BhdGhdO1xuXHRcdFx0aW1hZ2Uuc3JjID0gcGF0aDtcblx0XHR9XG5cdH1cblxuXHRsb2FkVGV4dHVyZUF0bGFzIChwYXRoOiBzdHJpbmcsXG5cdFx0c3VjY2VzczogKHBhdGg6IHN0cmluZywgYXRsYXM6IFRleHR1cmVBdGxhcykgPT4gdm9pZCA9ICgpID0+IHsgfSxcblx0XHRlcnJvcjogKHBhdGg6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkID0gKCkgPT4geyB9LFxuXHRcdGZpbGVBbGlhcz86IHsgW2tleXdvcmQ6IHN0cmluZ106IHN0cmluZyB9XG5cdCkge1xuXHRcdGxldCBpbmRleCA9IHBhdGgubGFzdEluZGV4T2YoXCIvXCIpO1xuXHRcdGxldCBwYXJlbnQgPSBpbmRleCA+PSAwID8gcGF0aC5zdWJzdHJpbmcoMCwgaW5kZXggKyAxKSA6IFwiXCI7XG5cdFx0cGF0aCA9IHRoaXMuc3RhcnQocGF0aCk7XG5cblx0XHR0aGlzLmRvd25sb2FkZXIuZG93bmxvYWRUZXh0KHBhdGgsIChhdGxhc1RleHQ6IHN0cmluZyk6IHZvaWQgPT4ge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0bGV0IGF0bGFzID0gbmV3IFRleHR1cmVBdGxhcyhhdGxhc1RleHQpO1xuXHRcdFx0XHRsZXQgdG9Mb2FkID0gYXRsYXMucGFnZXMubGVuZ3RoLCBhYm9ydCA9IGZhbHNlO1xuXHRcdFx0XHRmb3IgKGxldCBwYWdlIG9mIGF0bGFzLnBhZ2VzKSB7XG5cdFx0XHRcdFx0dGhpcy5sb2FkVGV4dHVyZSghZmlsZUFsaWFzID8gcGFyZW50ICsgcGFnZS5uYW1lIDogZmlsZUFsaWFzW3BhZ2UubmFtZSFdLFxuXHRcdFx0XHRcdFx0KGltYWdlUGF0aDogc3RyaW5nLCB0ZXh0dXJlOiBUZXh0dXJlKSA9PiB7XG5cdFx0XHRcdFx0XHRcdGlmICghYWJvcnQpIHtcblx0XHRcdFx0XHRcdFx0XHRwYWdlLnNldFRleHR1cmUodGV4dHVyZSk7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKC0tdG9Mb2FkID09IDApIHRoaXMuc3VjY2VzcyhzdWNjZXNzLCBwYXRoLCBhdGxhcyk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHQoaW1hZ2VQYXRoOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZykgPT4ge1xuXHRcdFx0XHRcdFx0XHRpZiAoIWFib3J0KSB0aGlzLmVycm9yKGVycm9yLCBwYXRoLCBgQ291bGRuJ3QgbG9hZCB0ZXh0dXJlIGF0bGFzICR7cGF0aH0gcGFnZSBpbWFnZTogJHtpbWFnZVBhdGh9YCk7XG5cdFx0XHRcdFx0XHRcdGFib3J0ID0gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdHRoaXMuZXJyb3IoZXJyb3IsIHBhdGgsIGBDb3VsZG4ndCBwYXJzZSB0ZXh0dXJlIGF0bGFzICR7cGF0aH06ICR7KGUgYXMgYW55KS5tZXNzYWdlfWApO1xuXHRcdFx0fVxuXHRcdH0sIChzdGF0dXM6IG51bWJlciwgcmVzcG9uc2VUZXh0OiBzdHJpbmcpOiB2b2lkID0+IHtcblx0XHRcdHRoaXMuZXJyb3IoZXJyb3IsIHBhdGgsIGBDb3VsZG4ndCBsb2FkIHRleHR1cmUgYXRsYXMgJHtwYXRofTogc3RhdHVzICR7c3RhdHVzfSwgJHtyZXNwb25zZVRleHR9YCk7XG5cdFx0fSk7XG5cdH1cblxuXHRnZXQgKHBhdGg6IHN0cmluZykge1xuXHRcdHJldHVybiB0aGlzLmFzc2V0c1t0aGlzLnBhdGhQcmVmaXggKyBwYXRoXTtcblx0fVxuXG5cdHJlcXVpcmUgKHBhdGg6IHN0cmluZykge1xuXHRcdHBhdGggPSB0aGlzLnBhdGhQcmVmaXggKyBwYXRoO1xuXHRcdGxldCBhc3NldCA9IHRoaXMuYXNzZXRzW3BhdGhdO1xuXHRcdGlmIChhc3NldCkgcmV0dXJuIGFzc2V0O1xuXHRcdGxldCBlcnJvciA9IHRoaXMuZXJyb3JzW3BhdGhdO1xuXHRcdHRocm93IEVycm9yKFwiQXNzZXQgbm90IGZvdW5kOiBcIiArIHBhdGggKyAoZXJyb3IgPyBcIlxcblwiICsgZXJyb3IgOiBcIlwiKSk7XG5cdH1cblxuXHRyZW1vdmUgKHBhdGg6IHN0cmluZykge1xuXHRcdHBhdGggPSB0aGlzLnBhdGhQcmVmaXggKyBwYXRoO1xuXHRcdGxldCBhc3NldCA9IHRoaXMuYXNzZXRzW3BhdGhdO1xuXHRcdGlmICgoPGFueT5hc3NldCkuZGlzcG9zZSkgKDxhbnk+YXNzZXQpLmRpc3Bvc2UoKTtcblx0XHRkZWxldGUgdGhpcy5hc3NldHNbcGF0aF07XG5cdFx0cmV0dXJuIGFzc2V0O1xuXHR9XG5cblx0cmVtb3ZlQWxsICgpIHtcblx0XHRmb3IgKGxldCBrZXkgaW4gdGhpcy5hc3NldHMpIHtcblx0XHRcdGxldCBhc3NldCA9IHRoaXMuYXNzZXRzW2tleV07XG5cdFx0XHRpZiAoKDxhbnk+YXNzZXQpLmRpc3Bvc2UpICg8YW55PmFzc2V0KS5kaXNwb3NlKCk7XG5cdFx0fVxuXHRcdHRoaXMuYXNzZXRzID0ge307XG5cdH1cblxuXHRpc0xvYWRpbmdDb21wbGV0ZSAoKTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMudG9Mb2FkID09IDA7XG5cdH1cblxuXHRnZXRUb0xvYWQgKCk6IG51bWJlciB7XG5cdFx0cmV0dXJuIHRoaXMudG9Mb2FkO1xuXHR9XG5cblx0Z2V0TG9hZGVkICgpOiBudW1iZXIge1xuXHRcdHJldHVybiB0aGlzLmxvYWRlZDtcblx0fVxuXG5cdGRpc3Bvc2UgKCkge1xuXHRcdHRoaXMucmVtb3ZlQWxsKCk7XG5cdH1cblxuXHRoYXNFcnJvcnMgKCkge1xuXHRcdHJldHVybiBPYmplY3Qua2V5cyh0aGlzLmVycm9ycykubGVuZ3RoID4gMDtcblx0fVxuXG5cdGdldEVycm9ycyAoKSB7XG5cdFx0cmV0dXJuIHRoaXMuZXJyb3JzO1xuXHR9XG59XG5cbmV4cG9ydCBjbGFzcyBEb3dubG9hZGVyIHtcblx0cHJpdmF0ZSBjYWxsYmFja3M6IFN0cmluZ01hcDxBcnJheTxGdW5jdGlvbj4+ID0ge307XG5cdHJhd0RhdGFVcmlzOiBTdHJpbmdNYXA8c3RyaW5nPiA9IHt9O1xuXG5cdGRhdGFVcmlUb1N0cmluZyAoZGF0YVVyaTogc3RyaW5nKSB7XG5cdFx0aWYgKCFkYXRhVXJpLnN0YXJ0c1dpdGgoXCJkYXRhOlwiKSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiTm90IGEgZGF0YSBVUkkuXCIpO1xuXHRcdH1cblxuXHRcdGxldCBiYXNlNjRJZHggPSBkYXRhVXJpLmluZGV4T2YoXCJiYXNlNjQsXCIpO1xuXHRcdGlmIChiYXNlNjRJZHggIT0gLTEpIHtcblx0XHRcdGJhc2U2NElkeCArPSBcImJhc2U2NCxcIi5sZW5ndGg7XG5cdFx0XHRyZXR1cm4gYXRvYihkYXRhVXJpLnN1YnN0cihiYXNlNjRJZHgpKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIGRhdGFVcmkuc3Vic3RyKGRhdGFVcmkuaW5kZXhPZihcIixcIikgKyAxKTtcblx0XHR9XG5cdH1cblxuXHRiYXNlNjRUb1VpbnQ4QXJyYXkgKGJhc2U2NDogc3RyaW5nKSB7XG5cdFx0dmFyIGJpbmFyeV9zdHJpbmcgPSB3aW5kb3cuYXRvYihiYXNlNjQpO1xuXHRcdHZhciBsZW4gPSBiaW5hcnlfc3RyaW5nLmxlbmd0aDtcblx0XHR2YXIgYnl0ZXMgPSBuZXcgVWludDhBcnJheShsZW4pO1xuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcblx0XHRcdGJ5dGVzW2ldID0gYmluYXJ5X3N0cmluZy5jaGFyQ29kZUF0KGkpO1xuXHRcdH1cblx0XHRyZXR1cm4gYnl0ZXM7XG5cdH1cblxuXHRkYXRhVXJpVG9VaW50OEFycmF5IChkYXRhVXJpOiBzdHJpbmcpIHtcblx0XHRpZiAoIWRhdGFVcmkuc3RhcnRzV2l0aChcImRhdGE6XCIpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJOb3QgYSBkYXRhIFVSSS5cIik7XG5cdFx0fVxuXG5cdFx0bGV0IGJhc2U2NElkeCA9IGRhdGFVcmkuaW5kZXhPZihcImJhc2U2NCxcIik7XG5cdFx0aWYgKGJhc2U2NElkeCA9PSAtMSkgdGhyb3cgbmV3IEVycm9yKFwiTm90IGEgYmluYXJ5IGRhdGEgVVJJLlwiKTtcblx0XHRiYXNlNjRJZHggKz0gXCJiYXNlNjQsXCIubGVuZ3RoO1xuXHRcdHJldHVybiB0aGlzLmJhc2U2NFRvVWludDhBcnJheShkYXRhVXJpLnN1YnN0cihiYXNlNjRJZHgpKTtcblx0fVxuXG5cdGRvd25sb2FkVGV4dCAodXJsOiBzdHJpbmcsIHN1Y2Nlc3M6IChkYXRhOiBzdHJpbmcpID0+IHZvaWQsIGVycm9yOiAoc3RhdHVzOiBudW1iZXIsIHJlc3BvbnNlVGV4dDogc3RyaW5nKSA9PiB2b2lkKSB7XG5cdFx0aWYgKHRoaXMuc3RhcnQodXJsLCBzdWNjZXNzLCBlcnJvcikpIHJldHVybjtcblx0XHRpZiAodGhpcy5yYXdEYXRhVXJpc1t1cmxdKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRsZXQgZGF0YVVyaSA9IHRoaXMucmF3RGF0YVVyaXNbdXJsXTtcblx0XHRcdFx0dGhpcy5maW5pc2godXJsLCAyMDAsIHRoaXMuZGF0YVVyaVRvU3RyaW5nKGRhdGFVcmkpKTtcblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0dGhpcy5maW5pc2godXJsLCA0MDAsIEpTT04uc3RyaW5naWZ5KGUpKTtcblx0XHRcdH1cblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0bGV0IHJlcXVlc3QgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcblx0XHRyZXF1ZXN0Lm92ZXJyaWRlTWltZVR5cGUoXCJ0ZXh0L2h0bWxcIik7XG5cdFx0cmVxdWVzdC5vcGVuKFwiR0VUXCIsIHVybCwgdHJ1ZSk7XG5cdFx0bGV0IGRvbmUgPSAoKSA9PiB7XG5cdFx0XHR0aGlzLmZpbmlzaCh1cmwsIHJlcXVlc3Quc3RhdHVzLCByZXF1ZXN0LnJlc3BvbnNlVGV4dCk7XG5cdFx0fTtcblx0XHRyZXF1ZXN0Lm9ubG9hZCA9IGRvbmU7XG5cdFx0cmVxdWVzdC5vbmVycm9yID0gZG9uZTtcblx0XHRyZXF1ZXN0LnNlbmQoKTtcblx0fVxuXG5cdGRvd25sb2FkSnNvbiAodXJsOiBzdHJpbmcsIHN1Y2Nlc3M6IChkYXRhOiBvYmplY3QpID0+IHZvaWQsIGVycm9yOiAoc3RhdHVzOiBudW1iZXIsIHJlc3BvbnNlVGV4dDogc3RyaW5nKSA9PiB2b2lkKSB7XG5cdFx0dGhpcy5kb3dubG9hZFRleHQodXJsLCAoZGF0YTogc3RyaW5nKTogdm9pZCA9PiB7XG5cdFx0XHRzdWNjZXNzKEpTT04ucGFyc2UoZGF0YSkpO1xuXHRcdH0sIGVycm9yKTtcblx0fVxuXG5cdGRvd25sb2FkQmluYXJ5ICh1cmw6IHN0cmluZywgc3VjY2VzczogKGRhdGE6IFVpbnQ4QXJyYXkpID0+IHZvaWQsIGVycm9yOiAoc3RhdHVzOiBudW1iZXIsIHJlc3BvbnNlVGV4dDogc3RyaW5nKSA9PiB2b2lkKSB7XG5cdFx0aWYgKHRoaXMuc3RhcnQodXJsLCBzdWNjZXNzLCBlcnJvcikpIHJldHVybjtcblx0XHRpZiAodGhpcy5yYXdEYXRhVXJpc1t1cmxdKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRsZXQgZGF0YVVyaSA9IHRoaXMucmF3RGF0YVVyaXNbdXJsXTtcblx0XHRcdFx0dGhpcy5maW5pc2godXJsLCAyMDAsIHRoaXMuZGF0YVVyaVRvVWludDhBcnJheShkYXRhVXJpKSk7XG5cdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdHRoaXMuZmluaXNoKHVybCwgNDAwLCBKU09OLnN0cmluZ2lmeShlKSk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGxldCByZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG5cdFx0cmVxdWVzdC5vcGVuKFwiR0VUXCIsIHVybCwgdHJ1ZSk7XG5cdFx0cmVxdWVzdC5yZXNwb25zZVR5cGUgPSBcImFycmF5YnVmZmVyXCI7XG5cdFx0bGV0IG9uZXJyb3IgPSAoKSA9PiB7XG5cdFx0XHR0aGlzLmZpbmlzaCh1cmwsIHJlcXVlc3Quc3RhdHVzLCByZXF1ZXN0LnJlc3BvbnNlKTtcblx0XHR9O1xuXHRcdHJlcXVlc3Qub25sb2FkID0gKCkgPT4ge1xuXHRcdFx0aWYgKHJlcXVlc3Quc3RhdHVzID09IDIwMCB8fCByZXF1ZXN0LnN0YXR1cyA9PSAwKVxuXHRcdFx0XHR0aGlzLmZpbmlzaCh1cmwsIDIwMCwgbmV3IFVpbnQ4QXJyYXkocmVxdWVzdC5yZXNwb25zZSBhcyBBcnJheUJ1ZmZlcikpO1xuXHRcdFx0ZWxzZVxuXHRcdFx0XHRvbmVycm9yKCk7XG5cdFx0fTtcblx0XHRyZXF1ZXN0Lm9uZXJyb3IgPSBvbmVycm9yO1xuXHRcdHJlcXVlc3Quc2VuZCgpO1xuXHR9XG5cblx0cHJpdmF0ZSBzdGFydCAodXJsOiBzdHJpbmcsIHN1Y2Nlc3M6IGFueSwgZXJyb3I6IGFueSkge1xuXHRcdGxldCBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1t1cmxdO1xuXHRcdHRyeSB7XG5cdFx0XHRpZiAoY2FsbGJhY2tzKSByZXR1cm4gdHJ1ZTtcblx0XHRcdHRoaXMuY2FsbGJhY2tzW3VybF0gPSBjYWxsYmFja3MgPSBbXTtcblx0XHR9IGZpbmFsbHkge1xuXHRcdFx0Y2FsbGJhY2tzLnB1c2goc3VjY2VzcywgZXJyb3IpO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgZmluaXNoICh1cmw6IHN0cmluZywgc3RhdHVzOiBudW1iZXIsIGRhdGE6IGFueSkge1xuXHRcdGxldCBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1t1cmxdO1xuXHRcdGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1t1cmxdO1xuXHRcdGxldCBhcmdzID0gc3RhdHVzID09IDIwMCB8fCBzdGF0dXMgPT0gMCA/IFtkYXRhXSA6IFtzdGF0dXMsIGRhdGFdO1xuXHRcdGZvciAobGV0IGkgPSBhcmdzLmxlbmd0aCAtIDEsIG4gPSBjYWxsYmFja3MubGVuZ3RoOyBpIDwgbjsgaSArPSAyKVxuXHRcdFx0Y2FsbGJhY2tzW2ldLmFwcGx5KG51bGwsIGFyZ3MpO1xuXHR9XG59XG4iXX0=