UNPKG

@esotericsoftware/spine-player

Version:
1,153 lines 214 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 { AnimationState, AnimationStateData, AtlasAttachmentLoader, Color, MathUtils, MixFrom, Physics, Skeleton, SkeletonBinary, SkeletonJson, Skin, TextureFilter, TimeKeeper, Vector2 } from "@esotericsoftware/spine-core";
import { AssetManager, Input, LoadingScreen, ManagedWebGLRenderingContext, ResizeMode, SceneRenderer, Vector3 } from "@esotericsoftware/spine-webgl";
export class SpinePlayer {
    config;
    parent;
    dom;
    canvas = null;
    context = null;
    sceneRenderer = null;
    loadingScreen = null;
    assetManager = null;
    bg = new Color();
    bgFullscreen = new Color();
    playerControls = null;
    timelineSlider = null;
    playButton = null;
    skinButton = null;
    pinnedSkins = new Set();
    animationButton = null;
    playTime = 0;
    selectedBones = [];
    cancelId = 0;
    popup = null;
    /* True if the player is unable to load or render the skeleton. */
    error = false;
    /* The player's skeleton. Null until loading is complete (access after config.success). */
    skeleton = null;
    /* The animation state controlling the skeleton. Null until loading is complete (access after config.success). */
    animationState = null;
    paused = true;
    speed = 1;
    time = new TimeKeeper();
    stopRequestAnimationFrame = false;
    disposed = false;
    viewport = {};
    currentViewport = {};
    previousViewport = {};
    viewportTransitionStart = 0;
    eventListeners = [];
    input;
    constructor(parent, config) {
        this.config = config;
        const parentDom = typeof parent === "string" ? document.getElementById(parent) : parent;
        if (parentDom == null)
            throw new Error(`SpinePlayer parent not found: ${parent}`);
        this.parent = parentDom;
        if (config.showControls === void 0)
            config.showControls = true;
        const controls = config.showControls ? /*html*/ `
<div class="spine-player-controls spine-player-popup-parent spine-player-controls-hidden">
<div class="spine-player-timeline"></div>
<div class="spine-player-buttons">
<button class="spine-player-button spine-player-button-icon-pause"></button>
<div class="spine-player-button-spacer"></div>
<button class="spine-player-button spine-player-button-icon-speed"></button>
<button class="spine-player-button spine-player-button-icon-animations"></button>
<button class="spine-player-button spine-player-button-icon-skins"></button>
<button class="spine-player-button spine-player-button-icon-settings"></button>
<button class="spine-player-button spine-player-button-icon-fullscreen"></button>
<img class="spine-player-button-icon-spine-logo" src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20104%2031.16%22%3E%3Cpath%20d%3D%22M104%2012.68a1.31%201.31%200%200%201-.37%201%201.28%201.28%200%200%201-.85.31H91.57a10.51%2010.51%200%200%200%20.29%202.55%204.92%204.92%200%200%200%201%202%204.27%204.27%200%200%200%201.64%201.26%206.89%206.89%200%200%200%202.6.44%2010.66%2010.66%200%200%200%202.17-.2%2012.81%2012.81%200%200%200%201.64-.44q.69-.25%201.14-.44a1.87%201.87%200%200%201%20.68-.2.44.44%200%200%201%20.27.04.43.43%200%200%201%20.16.2%201.38%201.38%200%200%201%20.09.37%204.89%204.89%200%200%201%200%20.58%204.14%204.14%200%200%201%200%20.43v.32a.83.83%200%200%201-.09.26%201.1%201.1%200%200%201-.17.22%202.77%202.77%200%200%201-.61.34%208.94%208.94%200%200%201-1.32.46%2018.54%2018.54%200%200%201-1.88.41%2013.78%2013.78%200%200%201-2.28.18%2010.55%2010.55%200%200%201-3.68-.59%206.82%206.82%200%200%201-2.66-1.74%207.44%207.44%200%200%201-1.63-2.89%2013.48%2013.48%200%200%201-.55-4%2012.76%2012.76%200%200%201%20.57-3.94%208.35%208.35%200%200%201%201.64-3%207.15%207.15%200%200%201%202.58-1.87%208.47%208.47%200%200%201%203.39-.65%208.19%208.19%200%200%201%203.41.64%206.46%206.46%200%200%201%202.32%201.73%207%207%200%200%201%201.3%202.54%2011.17%2011.17%200%200%201%20.43%203.13zm-3.14-.93a5.69%205.69%200%200%200-1.09-3.86%204.17%204.17%200%200%200-3.42-1.4%204.52%204.52%200%200%200-2%20.44%204.41%204.41%200%200%200-1.47%201.15A5.29%205.29%200%200%200%2092%209.75a7%207%200%200%200-.36%202zM80.68%2021.94a.42.42%200%200%201-.08.26.59.59%200%200%201-.25.18%201.74%201.74%200%200%201-.47.11%206.31%206.31%200%200%201-.76%200%206.5%206.5%200%200%201-.78%200%201.74%201.74%200%200%201-.47-.11.59.59%200%200%201-.25-.18.42.42%200%200%201-.08-.26V12a9.8%209.8%200%200%200-.23-2.35%204.86%204.86%200%200%200-.66-1.53%202.88%202.88%200%200%200-1.13-1%203.57%203.57%200%200%200-1.6-.34%204%204%200%200%200-2.35.83A12.71%2012.71%200%200%200%2069.11%2010v11.9a.42.42%200%200%201-.08.26.59.59%200%200%201-.25.18%201.74%201.74%200%200%201-.47.11%206.51%206.51%200%200%201-.78%200%206.31%206.31%200%200%201-.76%200%201.88%201.88%200%200%201-.48-.11.52.52%200%200%201-.25-.18.46.46%200%200%201-.07-.26v-17a.53.53%200%200%201%20.03-.21.5.5%200%200%201%20.23-.19%201.28%201.28%200%200%201%20.44-.11%208.53%208.53%200%200%201%201.39%200%201.12%201.12%200%200%201%20.43.11.6.6%200%200%201%20.22.19.47.47%200%200%201%20.07.26V7.2a10.46%2010.46%200%200%201%202.87-2.36%206.17%206.17%200%200%201%202.88-.75%206.41%206.41%200%200%201%202.87.58%205.16%205.16%200%200%201%201.88%201.54%206.15%206.15%200%200%201%201%202.26%2013.46%2013.46%200%200%201%20.31%203.11z%22%20fill%3D%22%23fff%22%2F%3E%3Cpath%20d%3D%22M43.35%202.86c.09%202.6%201.89%204%205.48%204.61%203%20.48%205.79.24%206.69-2.37%201.75-5.09-2.4-3.82-6-4.39s-6.31-2.03-6.17%202.15zm1.08%2010.69c.33%201.94%202.14%203.06%204.91%203s4.84-1.16%205.13-3.25c.53-3.88-2.53-2.38-5.3-2.3s-5.4-1.26-4.74%202.55zM48%2022.44c.55%201.45%202.06%202.06%204.1%201.63s3.45-1.11%203.33-2.76c-.21-3.06-2.22-2.1-4.26-1.66S47%2019.6%2048%2022.44zm1.78%206.78c.16%201.22%201.22%202%202.88%201.93s2.92-.67%203.13-2c.4-2.43-1.46-1.53-3.12-1.51s-3.17-.82-2.89%201.58z%22%20fill%3D%22%23ff4000%22%2F%3E%3Cpath%20d%3D%22M35.28%2013.16a15.33%2015.33%200%200%201-.48%204%208.75%208.75%200%200%201-1.42%203%206.35%206.35%200%200%201-2.32%201.91%207.14%207.14%200%200%201-3.16.67%206.1%206.1%200%200%201-1.4-.15%205.34%205.34%200%200%201-1.26-.47%207.29%207.29%200%200%201-1.24-.81q-.61-.49-1.29-1.15v8.51a.47.47%200%200%201-.08.26.56.56%200%200%201-.25.19%201.74%201.74%200%200%201-.47.11%206.47%206.47%200%200%201-.78%200%206.26%206.26%200%200%201-.76%200%201.89%201.89%200%200%201-.48-.11.49.49%200%200%201-.25-.19.51.51%200%200%201-.07-.26V4.91a.57.57%200%200%201%20.06-.27.46.46%200%200%201%20.23-.18%201.47%201.47%200%200%201%20.44-.1%207.41%207.41%200%200%201%201.3%200%201.45%201.45%200%200%201%20.43.1.52.52%200%200%201%20.24.18.51.51%200%200%201%20.07.27V7.2a18.06%2018.06%200%200%201%201.49-1.38%209%209%200%200%201%201.45-1%206.82%206.82%200%200%201%201.49-.59%207.09%207.09%200%200%201%204.78.52%206%206%200%200%201%202.13%202%208.79%208.79%200%200%201%201.2%202.9%2015.72%2015.72%200%200%201%20.4%203.51zm-3.28.36a15.64%2015.64%200%200%200-.2-2.53%207.32%207.32%200%200%200-.69-2.17%204.06%204.06%200%200%200-1.3-1.51%203.49%203.49%200%200%200-2-.57%204.1%204.1%200%200%200-1.2.18%204.92%204.92%200%200%200-1.2.57%208.54%208.54%200%200%200-1.28%201A15.77%2015.77%200%200%200%2022.76%2010v6.77a13.53%2013.53%200%200%200%202.46%202.4%204.12%204.12%200%200%200%202.44.83%203.56%203.56%200%200%200%202-.57A4.28%204.28%200%200%200%2031%2018a7.58%207.58%200%200%200%20.77-2.12%2011.43%2011.43%200%200%200%20.23-2.36zM12%2017.3a5.39%205.39%200%200%201-.48%202.33%204.73%204.73%200%200%201-1.37%201.72%206.19%206.19%200%200%201-2.12%201.06%209.62%209.62%200%200%201-2.71.36%2010.38%2010.38%200%200%201-3.21-.5A7.63%207.63%200%200%201%201%2021.82a3.25%203.25%200%200%201-.66-.43%201.09%201.09%200%200%201-.3-.53%203.59%203.59%200%200%201-.04-.93%204.06%204.06%200%200%201%200-.61%202%202%200%200%201%20.09-.4.42.42%200%200%201%20.16-.22.43.43%200%200%201%20.24-.07%201.35%201.35%200%200%201%20.61.26q.41.26%201%20.56a9.22%209.22%200%200%200%201.41.55%206.25%206.25%200%200%200%201.87.26%205.62%205.62%200%200%200%201.44-.17%203.48%203.48%200%200%200%201.12-.5%202.23%202.23%200%200%200%20.73-.84%202.68%202.68%200%200%200%20.26-1.21%202%202%200%200%200-.37-1.21%203.55%203.55%200%200%200-1-.87%208.09%208.09%200%200%200-1.36-.66l-1.56-.61a16%2016%200%200%201-1.57-.73%206%206%200%200%201-1.37-1%204.52%204.52%200%200%201-1-1.4%204.69%204.69%200%200%201-.37-2%204.88%204.88%200%200%201%20.39-1.87%204.46%204.46%200%200%201%201.16-1.61%205.83%205.83%200%200%201%201.94-1.11A8.06%208.06%200%200%201%206.53%204a8.28%208.28%200%200%201%201.36.11%209.36%209.36%200%200%201%201.23.28%205.92%205.92%200%200%201%20.94.37%204.09%204.09%200%200%201%20.59.35%201%201%200%200%201%20.26.26.83.83%200%200%201%20.09.26%201.32%201.32%200%200%200%20.06.35%203.87%203.87%200%200%201%200%20.51%204.76%204.76%200%200%201%200%20.56%201.39%201.39%200%200%201-.09.39.5.5%200%200%201-.16.22.35.35%200%200%201-.21.07%201%201%200%200%201-.49-.21%207%207%200%200%200-.83-.44%209.26%209.26%200%200%200-1.2-.44%205.49%205.49%200%200%200-1.58-.16%204.93%204.93%200%200%200-1.4.18%202.69%202.69%200%200%200-1%20.51%202.16%202.16%200%200%200-.59.83%202.43%202.43%200%200%200-.2%201%202%202%200%200%200%20.38%201.24%203.6%203.6%200%200%200%201%20.88%208.25%208.25%200%200%200%201.38.68l1.58.62q.8.32%201.59.72a6%206%200%200%201%201.39%201%204.37%204.37%200%200%201%201%201.36%204.46%204.46%200%200%201%20.37%201.8z%22%20fill%3D%22%23fff%22%2F%3E%3C%2Fsvg%3E">
</div></div>` : "";
        this.parent.appendChild(this.dom = createElement(
        /*html*/ `<div class="spine-player" style="position:relative;height:100%"><canvas class="spine-player-canvas" style="display:block;width:100%;height:100%"></canvas>${controls}</div>`));
        try {
            this.validateConfig(config);
        }
        catch (e) {
            this.showError(e.message, e);
        }
        this.initialize();
        // Register a global resize handler to redraw, avoiding flicker.
        this.addEventListener(window, "resize", () => this.drawFrame(false));
        // Start the rendering loop.
        requestAnimationFrame(() => this.drawFrame());
    }
    dispose() {
        this.sceneRenderer?.dispose();
        this.loadingScreen?.dispose();
        this.assetManager?.dispose();
        this.context?.dispose();
        for (let i = 0; i < this.eventListeners.length; i++) {
            const eventListener = this.eventListeners[i];
            eventListener.target.removeEventListener(eventListener.event, eventListener.func);
        }
        this.input?.dispose();
        if (this.canvas) {
            this.canvas.width = 0;
            this.canvas.height = 0;
        }
        this.parent.removeChild(this.dom);
        this.disposed = true;
    }
    addEventListener(target, event, func) {
        this.eventListeners.push({ target: target, event: event, func: func });
        target.addEventListener(event, func);
    }
    validateConfig(config) {
        if (!config)
            throw new Error("A configuration object must be passed to to new SpinePlayer().");
        if (config.skelUrl)
            config.skeleton = config.skelUrl;
        if (!config.skeleton)
            throw new Error("A URL must be specified for the skeleton JSON or binary file.");
        if (!config.scale)
            config.scale = 1;
        if (!config.atlas && !config.atlasUrl)
            throw new Error("A URL must be specified for the atlas file.");
        if (config.atlasUrl && !config.atlas)
            config.atlas = config.atlasUrl;
        if (!config.backgroundColor)
            config.backgroundColor = config.alpha ? "00000000" : "000000";
        if (!config.fullScreenBackgroundColor)
            config.fullScreenBackgroundColor = config.backgroundColor;
        if (config.backgroundImage && !config.backgroundImage.url)
            config.backgroundImage = undefined;
        if (config.preserveDrawingBuffer === void 0)
            config.preserveDrawingBuffer = false;
        if (config.mipmaps === void 0)
            config.mipmaps = true;
        if (config.interactive === void 0)
            config.interactive = true;
        if (typeof config.debug !== "object") {
            const d = !!config.debug;
            config.debug = { bones: d, regions: d, meshes: d, bounds: d, paths: d, clipping: d, points: d, hulls: d };
        }
        if (config.animations && config.animation && config.animations.indexOf(config.animation) < 0)
            throw new Error(`Animation '${config.animation}' is not in the config animation list: ${print(config.animations)}`);
        if (config.skin) {
            if (!Array.isArray(config.skin))
                config.skin = [config.skin];
            if (config.skins) {
                for (const s of config.skin) {
                    if (config.skins.indexOf(s) < 0)
                        throw new Error(`Default skin '${s}' is not in the config skins list: ${print(config.skins)}`);
                }
            }
        }
        if (!config.viewport)
            config.viewport = {};
        if (!config.viewport.animations)
            config.viewport.animations = {};
        if (config.viewport.debugRender === void 0)
            config.viewport.debugRender = false;
        if (config.viewport.transitionTime === void 0)
            config.viewport.transitionTime = 0.25;
        if (!config.controlBones)
            config.controlBones = [];
        if (config.showLoading === void 0)
            config.showLoading = true;
        if (config.defaultMix === void 0)
            config.defaultMix = 0.25;
    }
    initialize() {
        const config = this.config;
        const dom = this.dom;
        if (!config.alpha) { // Prevents a flash before the first frame is drawn.
            const hex = config.backgroundColor;
            this.dom.style.backgroundColor = (hex.charAt(0) === '#' ? hex : `#${hex}`).substring(0, 7);
        }
        try {
            // Setup the OpenGL context.
            this.canvas = findWithClass(dom, "spine-player-canvas");
            this.context = new ManagedWebGLRenderingContext(this.canvas, { alpha: config.alpha, preserveDrawingBuffer: config.preserveDrawingBuffer });
            // Setup the scene renderer and loading screen.
            this.sceneRenderer = new SceneRenderer(this.canvas, this.context, true);
            if (config.showLoading)
                this.loadingScreen = new LoadingScreen(this.sceneRenderer);
        }
        catch (e) {
            this.showError("Sorry, your browser does not support WebGL, or you have disabled WebGL in your browser settings.\nPlease use the latest version of Firefox, Chrome, Edge, or Safari.", e);
            return null;
        }
        // Load the assets.
        this.assetManager = new AssetManager(this.context, "", config.downloader);
        if (config.rawDataURIs) {
            for (const path in config.rawDataURIs)
                this.assetManager.setRawDataURI(path, config.rawDataURIs[path]);
        }
        if (config.skeleton.endsWith(".json"))
            this.assetManager.loadJson(config.skeleton);
        else
            this.assetManager.loadBinary(config.skeleton);
        this.assetManager.loadTextureAtlas(config.atlas);
        if (config.backgroundImage)
            this.assetManager.loadTexture(config.backgroundImage.url);
        // Setup the UI elements.
        this.bg.setFromString(config.backgroundColor);
        this.bgFullscreen.setFromString(config.fullScreenBackgroundColor);
        if (config.showControls) {
            this.playerControls = dom.children[1];
            const controls = this.playerControls.children;
            const timeline = controls[0];
            const buttons = controls[1].children;
            this.playButton = buttons[0];
            const speedButton = buttons[2];
            this.animationButton = buttons[3];
            this.skinButton = buttons[4];
            const settingsButton = buttons[5];
            const fullscreenButton = buttons[6];
            const logoButton = buttons[7];
            this.timelineSlider = new Slider();
            timeline.appendChild(this.timelineSlider.create());
            this.timelineSlider.change = (percentage) => {
                this.pause();
                const animationDuration = this.animationState.getTrack(0).animation.duration;
                const time = animationDuration * percentage;
                this.animationState.update(time - this.playTime);
                this.animationState.apply(this.skeleton);
                this.skeleton.update(time - this.playTime);
                this.skeleton.updateWorldTransform(Physics.update);
                this.playTime = time;
            };
            this.playButton.onclick = () => (this.paused ? this.play() : this.pause());
            speedButton.onclick = () => this.showSpeedDialog(speedButton);
            this.animationButton.onclick = () => this.showAnimationsDialog(this.animationButton);
            this.skinButton.onclick = () => this.showSkinsDialog(this.skinButton);
            settingsButton.onclick = () => this.showSettingsDialog(settingsButton);
            let oldWidth = this.canvas.clientWidth, oldHeight = this.canvas.clientHeight;
            let oldStyleWidth = this.canvas.style.width, oldStyleHeight = this.canvas.style.height;
            let isFullscreen = false;
            fullscreenButton.onclick = () => {
                const fullscreenChanged = () => {
                    isFullscreen = !isFullscreen;
                    if (!isFullscreen) {
                        this.canvas.style.width = `${oldWidth}px`;
                        this.canvas.style.height = `${oldHeight}px`;
                        this.drawFrame(false);
                        // Got to reset the style to whatever the user set after the next layouting.
                        requestAnimationFrame(() => {
                            this.canvas.style.width = oldStyleWidth;
                            this.canvas.style.height = oldStyleHeight;
                        });
                    }
                };
                const player = dom;
                player.onfullscreenchange = fullscreenChanged;
                player.onwebkitfullscreenchange = fullscreenChanged;
                const doc = document;
                if (doc.fullscreenElement || doc.webkitFullscreenElement || doc.mozFullScreenElement || doc.msFullscreenElement) {
                    if (doc.exitFullscreen)
                        doc.exitFullscreen();
                    else if (doc.mozCancelFullScreen)
                        doc.mozCancelFullScreen();
                    else if (doc.webkitExitFullscreen)
                        doc.webkitExitFullscreen();
                    else if (doc.msExitFullscreen)
                        doc.msExitFullscreen();
                }
                else {
                    oldWidth = this.canvas.clientWidth;
                    oldHeight = this.canvas.clientHeight;
                    oldStyleWidth = this.canvas.style.width;
                    oldStyleHeight = this.canvas.style.height;
                    if (player.requestFullscreen)
                        player.requestFullscreen();
                    else if (player.webkitRequestFullScreen)
                        player.webkitRequestFullScreen();
                    else if (player.mozRequestFullScreen)
                        player.mozRequestFullScreen();
                    else if (player.msRequestFullscreen)
                        player.msRequestFullscreen();
                }
            };
            logoButton.onclick = () => window.open("http://esotericsoftware.com");
        }
        return dom;
    }
    loadSkeleton() {
        if (this.error)
            return;
        if (this.assetManager.hasErrors())
            this.showError(`Error: Assets could not be loaded.\n${print(this.assetManager.getErrors())}`);
        const config = this.config;
        // Configure filtering, don't use mipmaps in WebGL1 if the atlas page is non-POT
        const atlas = this.assetManager.require(config.atlas);
        const gl = this.context.gl, anisotropic = gl.getExtension("EXT_texture_filter_anisotropic");
        const isWebGL1 = gl.getParameter(gl.VERSION).indexOf("WebGL 1.0") !== -1;
        for (const page of atlas.pages) {
            let minFilter = page.minFilter;
            let useMipMaps = config.mipmaps;
            const isPOT = MathUtils.isPowerOfTwo(page.width) && MathUtils.isPowerOfTwo(page.height);
            if (isWebGL1 && !isPOT)
                useMipMaps = false;
            if (useMipMaps) {
                if (anisotropic) {
                    gl.texParameterf(gl.TEXTURE_2D, anisotropic.TEXTURE_MAX_ANISOTROPY_EXT, 8);
                    minFilter = TextureFilter.MipMapLinearLinear;
                }
                else
                    minFilter = TextureFilter.Linear; // Don't use mipmaps without anisotropic.
                page.texture.setFilters(minFilter, TextureFilter.Nearest);
            }
            if (minFilter !== TextureFilter.Nearest && minFilter !== TextureFilter.Linear)
                page.texture.update(true);
        }
        // Load skeleton data.
        let skeletonData;
        try {
            let loader, data, attachmentLoader = new AtlasAttachmentLoader(atlas);
            if (config.skeleton.endsWith(".json")) {
                data = this.assetManager.remove(config.skeleton);
                if (!data)
                    throw new Error("Empty JSON data.");
                if (config.jsonField) {
                    data = data[config.jsonField];
                    if (!data)
                        throw new Error(`JSON field does not exist: ${config.jsonField}`);
                }
                loader = new SkeletonJson(attachmentLoader);
            }
            else {
                data = this.assetManager.remove(config.skeleton);
                loader = new SkeletonBinary(attachmentLoader);
            }
            loader.scale = config.scale;
            skeletonData = loader.readSkeletonData(data);
        }
        catch (e) {
            this.showError(`Error: Could not load skeleton data.\n${e.message}`, e);
            return;
        }
        this.skeleton = new Skeleton(skeletonData);
        const stateData = new AnimationStateData(skeletonData);
        stateData.defaultMix = config.defaultMix;
        this.animationState = new AnimationState(stateData);
        // Check if all control bones are in the skeleton
        config.controlBones.forEach(bone => {
            if (!skeletonData.findBone(bone))
                this.showError(`Error: Control bone does not exist in skeleton: ${bone}`);
        });
        // Setup skin.
        if ((!config.skin || !config.skin.length) && skeletonData.skins.length)
            config.skin = [skeletonData.skins[0].name];
        if (config.skins && config.skin.length) {
            config.skins.forEach(skin => {
                if (!this.skeleton.data.findSkin(skin))
                    this.showError(`Error: Skin in config list does not exist in skeleton: ${skin}`);
            });
        }
        const skinList = config.skin;
        if (skinList?.length) {
            for (const s of skinList) {
                if (!this.skeleton.data.findSkin(s))
                    this.showError(`Error: Skin does not exist in skeleton: ${s}`);
                if (this.skeleton.data.findSkin(s) !== this.skeleton.data.defaultSkin)
                    this.pinnedSkins.add(s);
            }
            this.applyCombinedSkin();
        }
        // Check if all animations given a viewport exist.
        Object.getOwnPropertyNames(config.viewport.animations).forEach((animation) => {
            if (!skeletonData.findAnimation(animation))
                this.showError(`Error: Animation for which a viewport was specified does not exist in skeleton: ${animation}`);
        });
        // Setup the animations after the viewport, so default bounds don't get messed up.
        if (config.animations && config.animations.length) {
            config.animations.forEach(animation => {
                if (!this.skeleton.data.findAnimation(animation))
                    this.showError(`Error: Animation in config list does not exist in skeleton: ${animation}`);
            });
            if (!config.animation)
                config.animation = config.animations[0];
        }
        if (config.animation && !skeletonData.findAnimation(config.animation))
            this.showError(`Error: Animation does not exist in skeleton: ${config.animation}`);
        // Setup input processing and control bones.
        this.setupInput();
        if (config.showControls) {
            // Hide skin and animation if there's only the default skin / no animation
            if (skeletonData.skins.length === 1 || (config.skins && config.skins.length === 1))
                this.skinButton.classList.add("spine-player-hidden");
            if (skeletonData.animations.length === 1 || (config.animations && config.animations.length === 1))
                this.animationButton.classList.add("spine-player-hidden");
        }
        if (config.success)
            config.success(this);
        let entry = this.animationState.getTrack(0);
        if (!entry) {
            if (config.animation) {
                entry = this.setAnimation(config.animation);
                this.play();
            }
            else {
                entry = this.animationState.setEmptyAnimation(0);
                entry.trackEnd = 100000000;
                this.skeleton.updateWorldTransform(Physics.update);
                this.setViewport(entry.animation);
                this.pause();
            }
        }
        else {
            if (this.currentViewport.x === undefined) {
                this.setViewport(entry.animation);
            }
            if (!config.animation) {
                config.animation = entry.animation?.name;
            }
            this.play();
        }
    }
    setupInput() {
        const config = this.config;
        const controlBones = config.controlBones;
        if (!controlBones.length && !config.showControls)
            return;
        const selectedBones = this.selectedBones = new Array(controlBones.length);
        const canvas = this.canvas;
        let target = null;
        const offset = new Vector2();
        const coords = new Vector3();
        const mouse = new Vector3();
        const position = new Vector2();
        const skeleton = this.skeleton;
        const renderer = this.sceneRenderer;
        if (config.interactive) {
            const closest = (x, y) => {
                mouse.set(x, canvas.clientHeight - y, 0);
                offset.x = offset.y = 0;
                let bestDistance = 24, index = 0;
                let best = null;
                for (let i = 0; i < controlBones.length; i++) {
                    selectedBones[i] = null;
                    const bone = skeleton.findBone(controlBones[i]);
                    if (!bone)
                        continue;
                    const distance = renderer.camera.worldToScreen(coords.set(bone.appliedPose.worldX, bone.appliedPose.worldY, 0), canvas.clientWidth, canvas.clientHeight).distance(mouse);
                    if (distance < bestDistance) {
                        bestDistance = distance;
                        best = bone;
                        index = i;
                        offset.x = coords.x - mouse.x;
                        offset.y = coords.y - mouse.y;
                    }
                }
                if (best)
                    selectedBones[index] = best;
                return best;
            };
            this.input = new Input(canvas);
            this.input.addListener({
                down: (x, y) => {
                    target = closest(x, y);
                },
                up: () => {
                    if (target)
                        target = null;
                    else if (config.showControls)
                        (this.paused ? this.play() : this.pause());
                },
                dragged: (x, y) => {
                    if (target) {
                        x = MathUtils.clamp(x + offset.x, 0, canvas.clientWidth);
                        y = MathUtils.clamp(y - offset.y, 0, canvas.clientHeight);
                        renderer.camera.screenToWorld(coords.set(x, y, 0), canvas.clientWidth, canvas.clientHeight);
                        const applied = target.appliedPose;
                        if (target.parent) {
                            target.parent.appliedPose.worldToLocal(position.set(coords.x - skeleton.x, coords.y - skeleton.y));
                            applied.x = position.x;
                            applied.y = position.y;
                        }
                        else {
                            applied.x = coords.x - skeleton.x;
                            applied.y = coords.y - skeleton.y;
                        }
                    }
                },
                moved: (x, y) => closest(x, y)
            });
        }
        if (config.showControls) {
            // For manual hover to work, we need to disable hidding controls if the mouse/touch entered the clickable area of a child of the controls.
            // For this we need to register a mouse handler on the document and see if we are within the canvas area.
            this.addEventListener(document, "mousemove", (ev) => {
                if (ev instanceof MouseEvent)
                    handleHover(ev.clientX, ev.clientY);
            });
            this.addEventListener(document, "touchmove", (ev) => {
                if (ev instanceof TouchEvent) {
                    const touches = ev.changedTouches;
                    if (touches.length) {
                        const touch = touches[0];
                        handleHover(touch.clientX, touch.clientY);
                    }
                }
            });
            const overlap = (mouseX, mouseY, rect) => {
                const x = mouseX - rect.left, y = mouseY - rect.top;
                return x >= 0 && x <= rect.width && y >= 0 && y <= rect.height;
            };
            let mouseOverControls = true, mouseOverCanvas = false;
            const handleHover = (mouseX, mouseY) => {
                const popup = findWithClass(this.dom, "spine-player-popup");
                mouseOverControls = overlap(mouseX, mouseY, this.playerControls.getBoundingClientRect());
                mouseOverCanvas = overlap(mouseX, mouseY, canvas.getBoundingClientRect());
                clearTimeout(this.cancelId);
                const hide = !popup && !mouseOverControls && !mouseOverCanvas && !this.paused;
                if (hide)
                    this.playerControls.classList.add("spine-player-controls-hidden");
                else
                    this.playerControls.classList.remove("spine-player-controls-hidden");
                if (!mouseOverControls && !popup && !this.paused) {
                    this.cancelId = setTimeout(() => {
                        if (!this.paused)
                            this.playerControls.classList.add("spine-player-controls-hidden");
                    }, 1000);
                }
            };
        }
    }
    play() {
        this.paused = false;
        const config = this.config;
        if (config.showControls) {
            this.cancelId = setTimeout(() => {
                if (!this.paused)
                    this.playerControls.classList.add("spine-player-controls-hidden");
            }, 1000);
            this.playButton.classList.remove("spine-player-button-icon-play");
            this.playButton.classList.add("spine-player-button-icon-pause");
            // If no config animation, set one when first clicked.
            if (!config.animation) {
                if (config.animations && config.animations.length)
                    config.animation = config.animations[0];
                else if (this.skeleton.data.animations.length)
                    config.animation = this.skeleton.data.animations[0].name;
                if (config.animation)
                    this.setAnimation(config.animation);
            }
        }
    }
    pause() {
        this.paused = true;
        if (this.config.showControls) {
            this.playerControls.classList.remove("spine-player-controls-hidden");
            clearTimeout(this.cancelId);
            this.playButton.classList.remove("spine-player-button-icon-pause");
            this.playButton.classList.add("spine-player-button-icon-play");
        }
    }
    /* Sets a new animation and viewport on track 0. */
    setAnimation(animation, loop = true) {
        animation = this.setViewport(animation);
        return this.animationState.setAnimation(0, animation, loop);
    }
    /* Adds a new animation and viewport on track 0. */
    addAnimation(animation, loop = true, delay = 0) {
        animation = this.setViewport(animation);
        return this.animationState.addAnimation(0, animation, loop, delay);
    }
    /* Sets the viewport for the specified animation. */
    setViewport(animation) {
        if (typeof animation === "string") {
            const foundAnimation = this.skeleton.data.findAnimation(animation);
            if (!foundAnimation)
                throw new Error(`Animation not found: ${animation}`);
            animation = foundAnimation;
        }
        this.previousViewport = this.currentViewport;
        // Determine the base viewport.
        const globalViewport = this.config.viewport;
        const viewport = this.currentViewport = {
            clip: globalViewport.clip,
            padLeft: globalViewport.padLeft !== void 0 ? globalViewport.padLeft : "10%",
            padRight: globalViewport.padRight !== void 0 ? globalViewport.padRight : "10%",
            padTop: globalViewport.padTop !== void 0 ? globalViewport.padTop : "10%",
            padBottom: globalViewport.padBottom !== void 0 ? globalViewport.padBottom : "10%"
        };
        if (globalViewport.x !== void 0 && globalViewport.y !== void 0 && globalViewport.width && globalViewport.height) {
            viewport.x = globalViewport.x;
            viewport.y = globalViewport.y;
            viewport.width = globalViewport.width;
            viewport.height = globalViewport.height;
        }
        else
            this.calculateAnimationViewport(animation, viewport);
        // Override with the animation specific viewport for the final result.
        const userAnimViewport = this.config.viewport.animations[animation.name];
        if (userAnimViewport) {
            if (userAnimViewport.x !== void 0 && userAnimViewport.y !== void 0 && userAnimViewport.width && userAnimViewport.height) {
                viewport.x = userAnimViewport.x;
                viewport.y = userAnimViewport.y;
                viewport.width = userAnimViewport.width;
                viewport.height = userAnimViewport.height;
            }
            if (userAnimViewport.clip !== void 0)
                viewport.clip = userAnimViewport.clip;
            if (userAnimViewport.padLeft !== void 0)
                viewport.padLeft = userAnimViewport.padLeft;
            if (userAnimViewport.padRight !== void 0)
                viewport.padRight = userAnimViewport.padRight;
            if (userAnimViewport.padTop !== void 0)
                viewport.padTop = userAnimViewport.padTop;
            if (userAnimViewport.padBottom !== void 0)
                viewport.padBottom = userAnimViewport.padBottom;
        }
        // Translate percentage padding to world units.
        viewport.padLeft = this.percentageToWorldUnit(viewport.width, viewport.padLeft);
        viewport.padRight = this.percentageToWorldUnit(viewport.width, viewport.padRight);
        viewport.padBottom = this.percentageToWorldUnit(viewport.height, viewport.padBottom);
        viewport.padTop = this.percentageToWorldUnit(viewport.height, viewport.padTop);
        this.viewportTransitionStart = performance.now();
        return animation;
    }
    percentageToWorldUnit(size, percentageOrAbsolute) {
        if (typeof percentageOrAbsolute === "string")
            return size * parseFloat(percentageOrAbsolute.slice(0, -1)) / 100;
        return percentageOrAbsolute;
    }
    calculateAnimationViewport(animation, viewport) {
        this.skeleton.setupPose();
        let steps = 100, stepTime = animation.duration ? animation.duration / steps : 0, time = 0;
        let minX = 100000000, maxX = -100000000, minY = 100000000, maxY = -100000000;
        const offset = new Vector2(), size = new Vector2();
        const tempArray = [0, 0];
        for (let i = 0; i < steps; i++, time += stepTime) {
            animation.apply(this.skeleton, time, time, false, [], 1, MixFrom.setup, false, false, false);
            this.skeleton.updateWorldTransform(Physics.update);
            this.skeleton.getBounds(offset, size, tempArray, this.sceneRenderer.skeletonRenderer.getSkeletonClipping());
            if (Number.isFinite(offset.x) && Number.isFinite(offset.y) && Number.isFinite(size.x) && Number.isFinite(size.y)) {
                minX = Math.min(offset.x, minX);
                maxX = Math.max(offset.x + size.x, maxX);
                minY = Math.min(offset.y, minY);
                maxY = Math.max(offset.y + size.y, maxY);
            }
        }
        viewport.x = minX;
        viewport.y = minY;
        viewport.width = maxX - minX;
        viewport.height = maxY - minY;
        if (!Number.isFinite(viewport.width) || !Number.isFinite(viewport.height))
            this.showError(`Animation bounds are invalid: ${animation.name}`);
    }
    drawFrame(requestNextFrame = true) {
        try {
            if (this.error)
                return;
            if (this.disposed)
                return;
            if (requestNextFrame && !this.stopRequestAnimationFrame)
                requestAnimationFrame(() => this.drawFrame());
            const doc = document;
            const isFullscreen = doc.fullscreenElement || doc.webkitFullscreenElement || doc.mozFullScreenElement || doc.msFullscreenElement;
            const bg = isFullscreen ? this.bgFullscreen : this.bg;
            this.time.update();
            const delta = this.time.delta;
            // Load the skeleton if the assets are ready.
            const loading = !this.assetManager.isLoadingComplete();
            if (!this.skeleton && !loading)
                this.loadSkeleton();
            const skeleton = this.skeleton;
            const config = this.config;
            if (skeleton) {
                const playDelta = this.paused ? 0 : delta * this.speed;
                if (config.frame)
                    config.frame(this, playDelta);
                // Update animation time and pose the skeleton.
                if (!this.paused) {
                    skeleton.update(playDelta);
                    this.animationState.update(playDelta);
                    this.animationState.apply(skeleton);
                    if (config.updateWorldTransform)
                        config.updateWorldTransform(this, playDelta);
                    else
                        skeleton.updateWorldTransform(Physics.update);
                    if (config.showControls) {
                        this.playTime += playDelta;
                        const entry = this.animationState.getTrack(0);
                        if (entry) {
                            const duration = entry.animation.duration;
                            while (this.playTime >= duration && duration !== 0)
                                this.playTime -= duration;
                            this.playTime = Math.max(0, Math.min(this.playTime, duration));
                            this.timelineSlider.setValue(this.playTime / duration);
                        }
                    }
                }
                // Determine the viewport.
                const viewport = this.viewport;
                viewport.x = this.currentViewport.x - this.currentViewport.padLeft;
                viewport.y = this.currentViewport.y - this.currentViewport.padBottom;
                viewport.width = this.currentViewport.width + this.currentViewport.padLeft + this.currentViewport.padRight;
                viewport.height = this.currentViewport.height + this.currentViewport.padBottom + this.currentViewport.padTop;
                if (this.previousViewport) {
                    const transitionAlpha = (performance.now() - this.viewportTransitionStart) / 1000 / config.viewport.transitionTime;
                    if (transitionAlpha < 1) {
                        const x = this.previousViewport.x - this.previousViewport.padLeft;
                        const y = this.previousViewport.y - this.previousViewport.padBottom;
                        const width = this.previousViewport.width + this.previousViewport.padLeft + this.previousViewport.padRight;
                        const height = this.previousViewport.height + this.previousViewport.padBottom + this.previousViewport.padTop;
                        viewport.x = x + (viewport.x - x) * transitionAlpha;
                        viewport.y = y + (viewport.y - y) * transitionAlpha;
                        viewport.width = width + (viewport.width - width) * transitionAlpha;
                        viewport.height = height + (viewport.height - height) * transitionAlpha;
                    }
                }
                const renderer = this.sceneRenderer;
                renderer.camera.zoom = this.canvas.height / this.canvas.width > viewport.height / viewport.width
                    ? viewport.width / this.canvas.width : viewport.height / this.canvas.height;
                renderer.camera.position.x = viewport.x + viewport.width / 2;
                renderer.camera.position.y = viewport.y + viewport.height / 2;
                // Resize the canvas.
                renderer.resize(this.currentViewport.clip ? ResizeMode.FitClip : ResizeMode.Expand, viewport.width, viewport.height);
                // Clear the screen.
                const gl = this.context.gl;
                gl.clearColor(bg.r, bg.g, bg.b, bg.a);
                gl.clear(gl.COLOR_BUFFER_BIT);
                if (config.update)
                    config.update(this, playDelta);
                renderer.begin();
                // Draw the background image.
                const bgImage = config.backgroundImage;
                if (bgImage) {
                    const texture = this.assetManager.require(bgImage.url);
                    if (bgImage.x !== void 0 && bgImage.y !== void 0 && bgImage.width && bgImage.height)
                        renderer.drawTexture(texture, bgImage.x, bgImage.y, bgImage.width, bgImage.height);
                    else
                        renderer.drawTexture(texture, viewport.x, viewport.y, viewport.width, viewport.height);
                }
                // Draw the skeleton and debug output.
                renderer.drawSkeleton(skeleton);
                const debug = config.debug;
                if (Number(renderer.skeletonDebugRenderer.drawBones = debug.bones)
                    + Number(renderer.skeletonDebugRenderer.drawBoundingBoxes = debug.bounds)
                    + Number(renderer.skeletonDebugRenderer.drawClipping = debug.clipping)
                    + Number(renderer.skeletonDebugRenderer.drawMeshHull = debug.hulls)
                    + Number(renderer.skeletonDebugRenderer.drawPaths = debug.paths)
                    + Number(renderer.skeletonDebugRenderer.drawRegionAttachments = debug.regions)
                    + Number(renderer.skeletonDebugRenderer.drawMeshTriangles = debug.meshes) > 0) {
                    renderer.drawSkeletonDebug(skeleton);
                }
                // Draw the control bones.
                const controlBones = config.controlBones;
                if (controlBones.length) {
                    const selectedBones = this.selectedBones;
                    gl.lineWidth(2);
                    for (let i = 0; i < controlBones.length; i++) {
                        const bone = skeleton.findBone(controlBones[i]);
                        if (!bone)
                            continue;
                        const colorInner = selectedBones[i] ? BONE_INNER_OVER : BONE_INNER;
                        const colorOuter = selectedBones[i] ? BONE_OUTER_OVER : BONE_OUTER;
                        const applied = bone.appliedPose;
                        renderer.circle(true, skeleton.x + applied.worldX, skeleton.y + applied.worldY, 20, colorInner);
                        renderer.circle(false, skeleton.x + applied.worldX, skeleton.y + applied.worldY, 20, colorOuter);
                    }
                }
                // Draw the viewport bounds.
                if (config.viewport.debugRender) {
                    gl.lineWidth(1);
                    renderer.rect(false, this.currentViewport.x, this.currentViewport.y, this.currentViewport.width, this.currentViewport.height, Color.GREEN);
                    renderer.rect(false, viewport.x, viewport.y, viewport.width, viewport.height, Color.RED);
                }
                renderer.end();
                if (config.draw)
                    config.draw(this, playDelta);
            }
            // Draw the loading screen.
            if (config.showLoading) {
                this.loadingScreen.backgroundColor.setFromColor(bg);
                this.loadingScreen.draw(!loading);
            }
            if (loading && config.loading)
                config.loading(this, delta);
        }
        catch (e) {
            this.showError(`Error: Unable to render skeleton.\n${e.message}`, e);
        }
    }
    startRendering() {
        this.stopRequestAnimationFrame = false;
        requestAnimationFrame(() => this.drawFrame());
    }
    stopRendering() {
        this.stopRequestAnimationFrame = true;
    }
    hidePopup(id) {
        return this.popup != null && this.popup.hide(id);
    }
    showSpeedDialog(speedButton) {
        const id = "speed";
        if (this.hidePopup(id))
            return;
        const popup = new Popup(id, speedButton, this, this.playerControls, /*html*/ `
<div class="spine-player-popup-title">Speed</div>
<hr>
<div class="spine-player-row" style="align-items:center;padding:8px">
<div class="spine-player-column">
	<div class="spine-player-speed-slider" style="margin-bottom:4px"></div>
	<div class="spine-player-row" style="justify-content:space-between"><div>0.1x</div><div>1x</div><div>2x</div></div>
</div>
</div>`);
        const slider = new Slider(2, 0.1, true);
        findWithClass(popup.dom, "spine-player-speed-slider").appendChild(slider.create());
        slider.setValue(this.speed / 2);
        slider.change = (percentage) => this.speed = percentage * 2;
        popup.show();
    }
    showAnimationsDialog(animationsButton) {
        const id = "animations";
        if (this.hidePopup(id))
            return;
        if (!this.skeleton || !this.skeleton.data.animations.length)
            return;
        const popup = new Popup(id, animationsButton, this, this.playerControls, 
        /*html*/ `<div class="spine-player-popup-title">Animations</div><hr><ul class="spine-player-list"></ul>`);
        const rows = findWithClass(popup.dom, "spine-player-list");
        this.skeleton.data.animations.forEach((animation) => {
            // Skip animations not whitelisted if a whitelist was given.
            if (this.config.animations && this.config.animations.indexOf(animation.name) < 0)
                return;
            const row = createElement(
            /*html*/ `<li class="spine-player-list-item selectable"><div class="selectable-circle"></div><div class="selectable-text"></div></li>`);
            if (animation.name === this.config.animation)
                row.classList.add("selected");
            findWithClass(row, "selectable-text").innerText = animation.name;
            rows.appendChild(row);
            row.onclick = () => {
                removeClass(rows.children, "selected");
                row.classList.add("selected");
                this.config.animation = animation.name;
                this.playTime = 0;
                this.setAnimation(animation.name);
                this.play();
            };
        });
        popup.show();
    }
    applyCombinedSkin() {
        if (!this.skeleton)
            return;
        if (this.pinnedSkins.size === 0) {
            this.skeleton.setSkin(this.skeleton.data.defaultSkin);
        }
        else if (this.pinnedSkins.size === 1) {
            this.skeleton.setSkin(this.pinnedSkins.values().next().value);
        }
        else {
            const combined = new Skin("combined");
            for (const name of this.pinnedSkins) {
                const skin = this.skeleton.data.findSkin(name);
                if (skin)
                    combined.addSkin(skin);
            }
            this.skeleton.setSkin(combined);
        }
        this.skeleton.setupPoseSlots();
        this.skeleton.updateWorldTransform(Physics.pose);
        // Recalculate the viewport for the current animation since skin changes affect bounds.
        const entry = this.animationState?.getTrack(0);
        if (entry && entry.animation)
            this.setViewport(entry.animation);
    }
    showSkinsDialog(skinButton) {
        const id = "skins";
        if (this.hidePopup(id))
            return;
        if (!this.skeleton || !this.skeleton.data.skins.length)
            return;
        const popup = new Popup(id, skinButton, this, this.playerControls, 
        /*html*/ `<div class="spine-player-popup-title">Skins</div><hr><ul class="spine-player-list"></ul>`);
        const rows = findWithClass(popup.dom, "spine-player-list");
        this.skeleton.data.skins.forEach((skin) => {
            if (skin === this.skeleton.data.defaultSkin)
                return;
            // Skip skins not whitelisted if a whitelist was given.
            if (this.config.skins && this.config.skins.indexOf(skin.name) < 0)
                return;
            const row = createElement(/*html*/ `<li class="spine-player-list-item selectable"><div class="selectable-pin"></div><div class="selectable-text"></div></li>`);
            if (this.pinnedSkins.has(skin.name))
                row.classList.add("pinned");
            const pinElement = findWithClass(row, "selectable-pin");
            const textElement = findWithClass(row, "selectable-text");
            textElement.innerText = skin.name;
            rows.appendChild(row);
            pinElement.onclick = (e) => {
                e.stopPropagation();
                if (this.pinnedSkins.has(skin.name)) {
                    this.pinnedSkins.delete(skin.name);
                    row.classList.remove("pinned");
                }
                else {
                    this.pinnedSkins.add(skin.name);
                    row.classList.add("pinned");
                }
                this.applyCombinedSkin();
            };
            row.onclick = () => {
                this.pinnedSkins.clear();
                this.pinnedSkins.add(skin.name);
                for (let i = 0; i < rows.children.length; i++)
                    rows.children[i].classList.remove("pinned");
                row.classList.add("pinned");
                this.applyCombinedSkin();
            };
        });
        popup.show();
    }
    showSettingsDialog(settingsButton) {
        const id = "settings";
        if (this.hidePopup(id))
            return;
        if (!this.skeleton || !this.skeleton.data.animations.length)
            return;
        const popup = new Popup(id, settingsButton, this, this.playerControls, /*html*/ `<div class="spine-player-popup-title">Debug</div><hr><ul class="spine-player-list"></ul>`);
        const rows = findWithClass(popup.dom, "spine-player-list");
        const makeItem = (label, name) => {
            const row = createElement(/*html*/ `<li class="spine-player-list-item"></li>`);
            const s = new Switch(label);
            row.appendChild(s.create());
            const debug = this.config.debug;
            s.setEnabled(debug[name]);
            s.change = (value) => debug[name] = value;
            rows.appendChild(row);
        };
        makeItem("Bones", "bones");
        makeItem("Regions", "regions");
        makeItem("Meshes", "meshes");
        makeItem("Bounds", "bounds");
        makeItem("Paths", "paths");
        makeItem("Clipping", "clipping");
        makeItem("Points", "points");
        makeItem("Hulls", "hulls");
        popup.show();
    }
    showError(message, error) {
        if (this.error) {
            if (error)
                throw error; // Don't lose error if showError throws, is caught, and showError is called again.
        }
        else {
            this.error = true;
            this.dom.appendChild(createElement(
            /*html*/ `<div class="spine-player-error" style="background:#000;color:#fff;position:absolute;top:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;overflow:auto;z-index:999">`
                + message.replace("\n", "<br><br>") + `</div>`));
            if (this.config.error)
                this.config.error(this, message);
            throw (error ? error : new Error(message));
        }
    }
}
class Popup {
    id;
    button;
    player;
    parent;
    dom;
    className;
    constructor(id, button, player, parent, htmlContent) {
        this.id = id;
        this.button = button;
        this.player = player;
        this.parent = parent;
        this.dom = createElement(/*html*/ `<div class="spine-player-popup spine-player-hidden"></div>`);
        this.dom.innerHTML = htmlContent;
        parent.appendChild(this.dom);
        this.className = `spine-player-button-icon-${id}-selected`;
    }
    dispose() {
    }
    hide(id) {
        this.dom.remove();
        this.button.classList.remove(this.className);
        if (this.id === id) {
            this.player.popup = null;
            return true;
        }
        return false;
    }
    show() {
        this.player.popup = this;
        this.button.classList.add(this.className);
        this.dom.classList.remove("spine-player-hidden");
        // Make sure the popup isn't bigger than the player.
        let dismissed = false;
        const resize = () => {
            if (!dismissed)
                requestAnimationFrame(resize);
            this.dom.style.maxHeight = `${this.player.dom.clientHeight - this.parent.getBoundingClientRect().height}px`;
        };
        requestAnimationFrame(resize);
        // Dismiss when clicking somewhere outside the popup.
        let justClicked = true;
        const windowClickListener = (event) => {
            if (justClicked || this.player.popup !== this) {
                justClicked = false;
                return;
            }
            if (!this.dom.contains(event.target)) {
                this.dom.remove();
                window.removeEventListener("click", windowClickListener);
                this.button.classList.remove(this.className);
                this.player.popup = null;
                dismissed = true;
            }
        };
        this.player.addEventListener(window, "click", windowClickListener);
    }
}
class Switch {
    text;
    switch = null;
    enabled = false;
    change = () => { };
    constructor(text) {
        this.text = text;
    }
    create() {
        this.switch = createElement(/*html*/ `
<div class="spine-player-switch">
	<span class="spine-player-switch-text">${this.text}</span>
	<div class="spine-player-switch-knob-area">
		<div class="spine-player-switch-knob"></div>
	</div>
</div>`);
        this.switch.addEventListener("click", () => {
            this.setEnabled(!this.enabled);
            if (this.change)
                this.change(this.enabled);
        });
        return this.switch;
    }
    setEnabled(enabled) {
        if (enabled)
            this.switch?.classList.add("active");
        else
            this.switch?.classList.remove("active");
        this.enabled = enabled;
    }
    isEnabled() {
        return this.enabled;
    }
}
class Slider {
    snaps;
    snapPercentage;
    big;
    slider = null;
    value = null;
    knob = null;
    change = () => { };
    constructor(snaps = 0, snapPercentage = 0.1, big = false) {
        this.snaps = snaps;
        this.snapPercentage = snapPercentage;
        this.big = big;
    }
    create() {
        this.slider = createElement(/*html*/ `
<div class="spine-player-slider ${this.big ? "big" : ""}">
	<div class="spine-player-slider-value"></div>
	<!--<div class="spine-player-slider-knob"></div>-->
</div>`);
        this.value = findWithClass(this.slider, "spine-player-slider-value");
        // this.knob = findWithClass(this.slider, "spine-player-slider-knob");
        this.setValue(0);
        let rect;
        const update = (ev) => {
            const clientX = ev instanceof MouseEvent ? ev.clientX : ev.changedTouches[0].clientX;
            if (this.change)
                this.change(this.setValue((clientX - rect.left) / rect.width));
        };
        const onEnd = (ev) => {
            update(ev);
            this.value?.classList.remove("hovering");
            this.slider?.parentElement?.classList.remove("dragging");
            document.removeEventListener("mousemove", update, true);
            document.removeEventListener("mouseup", onEnd, true);
            document.removeEventListener("touchmove", update, true);
            document.removeEventListener("touchend", onEnd, true);
        };
        const onStart = (ev) => {
            rect = this.slider.getBoundingClientRect();
            this.value?.classList.add("hovering");
            this.slider?.parentElement?.classList.add("dragging");
            update(ev);
            document.addEventListener("mousemove", update, true);
            document.addEventListener("mouseup", onEnd, true);
            document.addEventListener("touchmove", update, true);
            document.addEventListener("touchend", onEnd, true);
        };
        this.slider.addEventListener("mousedown", onStart, true);
        this.slider.addEventListener("touchstart", onStart, true);
        return this.slider;
    }
    setValue(percentage) {
        percentage = Math.max(0, Math.min(1, percentage));
        if (this.snaps) {
            const snap = 1 / this.snaps;
            const modulo = percentage % snap;
            // floor
            if (modulo < snap * this.snapPercentage)
                percentage = percentage - modulo;
            else if (modulo > snap - snap * this.snapPercentage)
                percentage = percentage - modulo + snap;
            percentage = Math.max(0, Math.min(1, percentage));
        }
        this.value.style.width = `${percentage * 100}%`;
        // this.knob.style.left = "" + (-8 + percentage * this.slider.clientWidth) + "px";
        return percentage;
    }
}
function findWithClass(element, className) {
    return element.getElementsByClassName(className)[0];
}
function createElement(html) {
    const div = document.createElement("div");
    div.innerHTML = html;
    return div.children[0];
}
function removeClass(elements, clazz) {
    for (let i = 0; i < elements.length; i++)
        elements[i].classList.remove(clazz);
}
function print(object) {
    return JSON.stringify(object)
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&#34;")
        .replace(/'/g, "&#39;");
}
const BONE_INNER_OVER = new Color(0.478, 0, 0, 0.25);
const BONE_OUTER_OVER = new Color(1, 1, 1, 1);
const BONE_INNER = new Color(0.478, 0, 0, 0.5);
const BONE_OUTER = new Color(1, 0, 0, 0.8);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGxheWVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1BsYXllci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OytFQTJCK0U7QUFFL0UsT0FBTyxFQUFrQixjQUFjLEVBQUUsa0JBQWtCLEVBQUUscUJBQXFCLEVBQWEsS0FBSyxFQUFvQyxTQUFTLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsY0FBYyxFQUFxQixZQUFZLEVBQUUsSUFBSSxFQUFxQyxhQUFhLEVBQUUsVUFBVSxFQUFtQixPQUFPLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQTtBQUNsVyxPQUFPLEVBQUUsWUFBWSxFQUFrQixLQUFLLEVBQUUsYUFBYSxFQUFFLDRCQUE0QixFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLE1BQU0sK0JBQStCLENBQUE7QUFzS3BLLE1BQU0sT0FBTyxXQUFXO0lBMkM0QjtJQTFDNUMsTUFBTSxDQUFjO0lBQ3BCLEdBQUcsQ0FBYztJQUNqQixNQUFNLEdBQTZCLElBQUksQ0FBQztJQUN4QyxPQUFPLEdBQXdDLElBQUksQ0FBQztJQUNwRCxhQUFhLEdBQXlCLElBQUksQ0FBQztJQUMzQyxhQUFhLEdBQXlCLElBQUksQ0FBQztJQUMzQyxZQUFZLEdBQXdCLElBQUksQ0FBQztJQUN6QyxFQUFFLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztJQUNqQixZQUFZLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztJQUUxQixjQUFjLEdBQXVCLElBQUksQ0FBQztJQUMxQyxjQUFjLEdBQWtCLElBQUksQ0FBQztJQUNyQyxVQUFVLEdBQXVCLElBQUksQ0FBQztJQUN0QyxVQUFVLEdBQXVCLElBQUksQ0FBQztJQUN0QyxXQUFXLEdBQWdCLElBQUksR0FBRyxFQUFFLENBQUM7SUFDckMsZUFBZSxHQUF1QixJQUFJLENBQUM7SUFFM0MsUUFBUSxHQUFHLENBQUMsQ0FBQztJQUNi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SyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFO1FBQ3ZDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3RDLENBQUM7QUFFRCxTQUFTLEtBQUssQ0FBRSxNQUFXO0lBQzFCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7U0FDM0IsT0FBTyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUM7U0FDdEIsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUM7U0FDckIsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUM7U0FDckIsT0FBTyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUM7U0FDdEIsT0FBTyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztBQUMxQixDQUFDO0FBRUQsTUFBTSxlQUFlLEdBQUcsSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDckQsTUFBTSxlQUFlLEdBQUcsSUFBSSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDOUMsTUFBTSxVQUFVLEdBQUcsSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDL0MsTUFBTSxVQUFVLEdBQUcsSUFBSSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiBTcGluZSBSdW50aW1lcyBMaWNlbnNlIEFncmVlbWVudFxuICogTGFzdCB1cGRhdGVkIEFwcmlsIDUsIDIwMjUuIFJlcGxhY2VzIGFsbCBwcmlvciB2ZXJzaW9ucy5cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMtMjAyNSwgRXNvdGVyaWMgU29mdHdhcmUgTExDXG4gKlxuICogSW50ZWdyYXRpb24gb2YgdGhlIFNwaW5lIFJ1bnRpbWVzIGludG8gc29mdHdhcmUgb3Igb3RoZXJ3aXNlIGNyZWF0aW5nXG4gKiBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyBpcyBwZXJtaXR0ZWQgdW5kZXIgdGhlIHRlcm1zIGFuZFxuICogY29uZGl0aW9ucyBvZiBTZWN0aW9uIDIgb2YgdGhlIFNwaW5lIEVkaXRvciBMaWNlbnNlIEFncmVlbWVudDpcbiAqIGh0dHA6Ly9lc290ZXJpY3NvZnR3YXJlLmNvbS9zcGluZS1lZGl0b3ItbGljZW5zZVxuICpcbiAqIE90aGVyd2lzZSwgaXQgaXMgcGVybWl0dGVkIHRvIGludGVncmF0ZSB0aGUgU3BpbmUgUnVudGltZXMgaW50byBzb2Z0d2FyZVxuICogb3Igb3RoZXJ3aXNlIGNyZWF0ZSBkZXJpdmF0aXZlIHdvcmtzIG9mIHRoZSBTcGluZSBSdW50aW1lcyAoY29sbGVjdGl2ZWx5LFxuICogXCJQcm9kdWN0c1wiKSwgcHJvdmlkZWQgdGhhdCBlYWNoIHVzZXIgb2YgdGhlIFByb2R1Y3RzIG11c3Qgb2J0YWluIHRoZWlyIG93blxuICogU3BpbmUgRWRpdG9yIGxpY2Vuc2UgYW5kIHJlZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9kdWN0cyBpbiBhbnkgZm9ybSBtdXN0XG4gKiBpbmNsdWRlIHRoaXMgbGljZW5zZSBhbmQgY29weXJpZ2h0IG5vdGljZS5cbiAqXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMgQVJFIFBST1ZJREVEIEJZIEVTT1RFUklDIFNPRlRXQVJFIExMQyBcIkFTIElTXCIgQU5EIEFOWVxuICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRFxuICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxuICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgRVNPVEVSSUMgU09GVFdBUkUgTExDIEJFIExJQUJMRSBGT1IgQU5ZXG4gKiBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTLFxuICogQlVTSU5FU1MgSU5URVJSVVBUSU9OLCBPUiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUykgSE9XRVZFUiBDQVVTRUQgQU5EXG4gKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gKiBUSEUgU1BJTkUgUlVOVElNRVMsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbmltcG9ydCB7IHR5cGUgQW5pbWF0aW9uLCBBbmltYXRpb25TdGF0ZSwgQW5pbWF0aW9uU3RhdGVEYXRhLCBBdGxhc0F0dGFjaG1lbnRMb2FkZXIsIHR5cGUgQm9uZSwgQ29sb3IsIHR5cGUgRGlzcG9zYWJsZSwgdHlwZSBEb3dubG9hZGVyLCBNYXRoVXRpbHMsIE1peEZyb20sIFBoeXNpY3MsIFNrZWxldG9uLCBTa2VsZXRvbkJpbmFyeSwgdHlwZSBTa2VsZXRvbkRhdGEsIFNrZWxldG9uSnNvbiwgU2tpbiwgdHlwZSBTdHJpbmdNYXAsIHR5cGUgVGV4dHVyZUF0bGFzLCBUZXh0dXJlRmlsdGVyLCBUaW1lS2VlcGVyLCB0eXBlIFRyYWNrRW50cnksIFZlY3RvcjIgfSBmcm9tIFwiQGVzb3Rlcmljc29mdHdhcmUvc3BpbmUtY29yZVwiXG5pbXBvcnQgeyBBc3NldE1hbmFnZXIsIHR5cGUgR0xUZXh0dXJlLCBJbnB1dCwgTG9hZGluZ1NjcmVlbiwgTWFuYWdlZFdlYkdMUmVuZGVyaW5nQ29udGV4dCwgUmVzaXplTW9kZSwgU2NlbmVSZW5kZXJlciwgVmVjdG9yMyB9IGZyb20gXCJAZXNvdGVyaWNzb2Z0d2FyZS9zcGluZS13ZWJnbFwiXG5cbmV4cG9ydCBpbnRlcmZhY2UgU3BpbmVQbGF5ZXJDb25maWcge1xuXHQvKiBUaGUgVVJMIG9mIHRoZSBza2VsZXRvbiBKU09OICguanNvbikgb3IgYmluYXJ5ICguc2tlbCkgZmlsZSAqL1xuXHRza2VsZXRvbj86IHN0cmluZztcblxuXHQvKiBPcHRpb25hbDogVGhlIG5hbWUgb2YgYSBmaWVsZCBpbiB0aGUgSlNPTiB0aGF0IGhvbGRzIHRoZSBza2VsZXRvbiBkYXRhLiBEZWZhdWx0OiBub25lICovXG5cdGpzb25GaWVsZD86IHN0cmluZ1xuXG5cdC8qIFRoZSBzY2FsZSB3aGVuIGxvYWRpbmcgdGhlIHNrZWxldG9uIGRhdGEuIERlZmF1bHQ6IDEgKi9cblx0c2NhbGU/OiBudW1iZXJcblxuXHQvKiBAZGVwcmVjYXRlZCBVc2UgYXRsYXMgaW5zdGVhZC4gVGhlIFVSTCBvZiB0aGUgc2tlbGV0b24gYXRsYXMgZmlsZSAoLmF0bGFzKS4gQXRsYXMgcGFnZSBpbWFnZXMgYXJlIGF1dG9tYXRpY2FsbHkgcmVzb2x2ZWQuICovXG5cdGF0bGFzVXJsPzogc3RyaW5nXG5cblx0LyogVGhlIFVSTCBvZiB0aGUgc2tlbGV0b24gYXRsYXMgZmlsZSAoLmF0bGFzKS4gQXRsYXMgcGFnZSBpbWFnZXMgYXJlIGF1dG9tYXRpY2FsbHkgcmVzb2x2ZWQuICovXG5cdGF0bGFzPzogc3RyaW5nO1xuXG5cdC8qIFJhdyBkYXRhIFVSSXMsIG1hcHBpbmcgYSBwYXRoIHRvIGJhc2U2NCBlbmNvZGVkIHJhdyBkYXRhLiBXaGVuIHBsYXllcidzIGFzc2V0IG1hbmFnZXIgcmVzb2x2ZXMgdGhlIHNrZWxldG9uLFxuXHQgICBhdGxhcywgb3IgdGhlIGltYWdlIHBhdGhzIHJlZmVyZW5jZWQgaW4gdGhlIGF0bGFzLCBpdCB3aWxsIGZpcnN0IGxvb2sgZm9yIHRoYXQgcGF0aCBpbiB0aGUgcmF3IGRhdGEgVVJJcy4gVGhpc1xuXHQgICBhbGxvd3MgZW1iZWRkaW5nIGFzc2V0cyBkaXJlY3RseSBpbiBIVE1ML0pTLiBEZWZhdWx0OiBub25lICovXG5cdHJhd0RhdGFVUklzPzogU3RyaW5nTWFwPHN0cmluZz5cblxuXHQvKiBPcHRpb25hbDogVGhlIG5hbWUgb2YgdGhlIGFuaW1hdGlvbiB0byBiZSBwbGF5ZWQuIERlZmF1bHQ6IGVtcHR5IGFuaW1hdGlvbiAqL1xuXHRhbmltYXRpb24/OiBzdHJpbmdcblxuXHQvKiBPcHRpb25hbDogTGlzdCBvZiBhbmltYXRpb24gbmFtZXMgZnJvbSB3aGljaCB0aGUgdXNlciBjYW4gY2hvb3NlLiBEZWZhdWx0OiBhbGwgYW5pbWF0aW9ucyAqL1xuXHRhbmltYXRpb25zPzogc3RyaW5nW11cblxuXHQvKiBPcHRpb25hbDogVGhlIGRlZmF1bHQgbWl4IHRpbWUgdXNlZCB0byBzd2l0Y2ggYmV0d2VlbiB0d28gYW5pbWF0aW9ucy4gRGVmYXVsdDogMC4yNSAqL1xuXHRkZWZhdWx0TWl4PzogbnVtYmVyXG5cblx0LyogT3B0aW9uYWw6IFRoZSBuYW1lIG9mIHRoZSBza2luIG9yIGxpc3Qgb2Ygc2tpbnMgdG8gYmUgc2V0LiBEZWZhdWx0OiB0aGUgZGVmYXVsdCBza2luICovXG5cdHNraW4/OiBzdHJpbmcgfCBzdHJpbmdbXVxuXG5cdC8qIE9wdGlvbmFsOiBMaXN0IG9mIHNraW4gbmFtZXMgZnJvbSB3aGljaCB0aGUgdXNlciBjYW4gY2hvb3NlLiBEZWZhdWx0OiBhbGwgc2tpbnMgKi9cblx0c2tpbnM/OiBzdHJpbmdbXVxuXG5cdC8qIE9wdGlvbmFsOiBXaGV0aGVyIHRvIHNob3cgdGhlIHBsYXllciBjb250cm9scy4gV2hlbiBmYWxzZSwgbm8gZXh0ZXJuYWwgQ1NTIGZpbGUgaXMgbmVlZGVkLiBEZWZhdWx0OiB0cnVlICovXG5cdHNob3dDb250cm9scz86IGJvb2xlYW5cblxuXHQvKiBPcHRpb25hbDogV2hldGhlciB0byBzaG93IHRoZSBsb2FkaW5nIGFuaW1hdGlvbi4gRGVmYXVsdDogdHJ1ZSAqL1xuXHRzaG93TG9hZGluZz86IGJvb2xlYW5cblxuXHQvKiBPcHRpb25hbDogV2hpY2ggZGVidWdnaW5nIHZpc3VhbGl6YXRpb25zIGFyZSBzaG93bi4gU2V0IHRvIHRydWUvZmFsc2UgdG8gZW5hYmxlL2Rpc2FibGUgYWxsLCBvciBhbiBvYmplY3QgdG8gZW5hYmxlIHNwZWNpZmljIHZpc3VhbGl6YXRpb25zLiBEZWZhdWx0OiBub25lICovXG5cdGRlYnVnPzogYm9vbGVhbiB8IHtcblx0XHRba2V5OiBzdHJpbmddOiBib29sZWFuXG5cdFx0Ym9uZXM6IGJvb2xlYW5cblx0XHRyZWdpb25zOiBib29sZWFuXG5cdFx0bWVzaGVzOiBib29sZWFuXG5cdFx0Ym91bmRzOiBib29sZWFuXG5cdFx0cGF0aHM6IGJvb2xlYW5cblx0XHRjbGlwcGluZzogYm9vbGVhblxuXHRcdHBvaW50czogYm9vbGVhblxuXHRcdGh1bGxzOiBib29sZWFuXG5cdH1cblxuXHQvKiBPcHRpb25hbDogVGhlIHBvc2l0aW9uIGFuZCBzaXplIG9mIHRoZSB2aWV3cG9ydCBpbiB0aGUgc2tlbGV0b24ncyB3b3JsZCBjb29yZGluYXRlcy4gRGVmYXVsdDogdGhlIGJvdW5kaW5nIGJveCB0aGF0IGZpdHNcblx0ICB0aGUgY3VycmVudCBhbmltYXRpb24sIDEwJSBwYWRkaW5nLCAwLjI1IHRyYW5zaXRpb24gdGltZSAqL1xuXHR2aWV3cG9ydD86IHtcblx0XHQvKiBPcHRpb25hbDogVGhlIHBvc2l0aW9uIGFuZCBzaXplIG9mIHRoZSB2aWV3cG9ydCBpbiB0aGUgc2tlbGV0b24ncyB3b3JsZCBjb29yZGluYXRlcy4gRGVmYXVsdDogdGhlIGJvdW5kaW5nIGJveCB0aGF0XG5cdFx0ICAgZml0cyB0aGUgY3VycmVudCBhbmltYXRpb24gKi9cblx0XHR4PzogbnVtYmVyXG5cdFx0eT86IG51bWJlclxuXHRcdHdpZHRoPzogbnVtYmVyXG5cdFx0aGVpZ2h0PzogbnVtYmVyXG5cblx0XHQvKiBPcHRpb25hbDogV2hlbiB0cnVlLCBkcmF3aW5nIHdvbid0IGdvIG91dHNpZGUgdGhlIHZpZXdwb3J0LiBEZWZhdWx0OiBmYWxzZSAqL1xuXHRcdGNsaXA/OiBib29sZWFuXG5cblx0XHQvKiBPcHRpb25hbDogUGFkZGluZyBhcm91bmQgdGhlIHZpZXdwb3J0IHNpemUsIGdpdmVuIGFzIGEgbnVtYmVyIG9yIHBlcmNlbnRhZ2UgKGVnIFwiMjUlXCIpLiBEZWZhdWx0OiAxMCUgKi9cblx0XHRwYWRMZWZ0Pzogc3RyaW5nIHwgbnVtYmVyXG5cdFx0cGFkUmlnaHQ/OiBzdHJpbmcgfCBudW1iZXJcblx0XHRwYWRUb3A/OiBzdHJpbmcgfCBudW1iZXJcblx0XHRwYWRCb3R0b20/OiBzdHJpbmcgfCBudW1iZXJcblxuXHRcdC8qIE9wdGlvbmFsOiBXaGV0aGVyIHRvIGRyYXcgbGluZXMgc2hvd2luZyB0aGUgdmlld3BvcnQgYm91bmRzLiBEZWZhdWx0OiBmYWxzZSAqL1xuXHRcdGRlYnVnUmVuZGVyPzogYm9vbGVhbixcblxuXHRcdC8qIE9wdGlvbmFsOiBXaGVuIHRoZSBjdXJyZW50IHZpZXdwb3J0IGNoYW5nZXMsIHRoZSB0aW1lIHRvIGFuaW1hdGUgdG8gdGhlIG5ldyB2aWV3cG9ydC4gRGVmYXVsdDogMC4yNSAqL1xuXHRcdHRyYW5zaXRpb25UaW1lPzogbnVtYmVyXG5cblx0XHQvKiBPcHRpb25hbDogVmlld3BvcnRzIGZvciBzcGVjaWZpYyBhbmltYXRpb25zLiBEZWZhdWx0OiBub25lICovXG5cdFx0YW5pbWF0aW9ucz86IFN0cmluZ01hcDxWaWV3cG9ydD5cblx0fVxuXG5cdC8qIE9wdGlvbmFsOiBXaGV0aGVyIHRoZSBjYW52YXMgaXMgdHJhbnNwYXJlbnQsIGFsbG93aW5nIHRoZSB3ZWIgcGFnZSBiZWhpbmQgdGhlIGNhbnZhcyB0byBzaG93IHRocm91Z2ggd2hlblxuXHQgICBiYWNrZ3JvdW5kQ29sb3IgYWxwaGEgaXMgPCBmZi4gRGVmYXVsdDogZmFsc2UgKi9cblx0YWxwaGE/OiBib29sZWFuXG5cblx0LyogT3B0aW9uYWw6IFdoZXRoZXIgdG8gcHJlc2VydmUgdGhlIGRyYXdpbmcgYnVmZmVyLiBUaGlzIGlzIG5lZWRlZCBpZiB5b3Ugd2FudCB0byB0YWtlIGEgc2NyZWVuc2hvdCB2aWEgY2FudmFzLmdldERhdGFVUkwoKSwgRGVmYXVsdDogZmFsc2UgKi9cblx0cHJlc2VydmVEcmF3aW5nQnVmZmVyOiBib29sZWFuXG5cblx0LyogT3B0aW9uYWw6IFRoZSBjYW52YXMgYmFja2dyb3VuZCBjb2xvciwgZ2l2ZW4gaW4gdGhlIGZvcm1hdCAjcnJnZ2JiIG9yICNycmdnYmJhYS4gRGVmYXVsdDogIzAwMDAwMGZmIChibGFjaykgb3Igd2hlblxuXHQgICBhbHBoYSBpcyB0cnVlICMwMDAwMDAwMCAodHJhbnNwYXJlbnQpICovXG5cdGJhY2tncm91bmRDb2xvcj86IHN0cmluZ1xuXG5cdC8qIE9wdGlvbmFsOiBUaGUgYmFja2dyb3VuZCBjb2xvciB1c2VkIGluIGZ1bGxzY3JlZW4gbW9kZSwgZ2l2ZW4gaW4gdGhlIGZvcm1hdCAjcnJnZ2JiIG9yICNycmdnYmJhYS4gRGVmYXVsdDogYmFja2dyb3VuZENvbG9yICovXG5cdGZ1bGxTY3JlZW5CYWNrZ3JvdW5kQ29sb3I/OiBzdHJpbmdcblxuXHQvKiBPcHRpb25hbDogQW4gaW1hZ2UgdG8gZHJhdyBiZWhpbmQgdGhlIHNrZWxldG9uLiBEZWZhdWx0OiBub25lICovXG5cdGJhY2tncm91bmRJbWFnZT86IHtcblx0XHR1cmw6IHN0cmluZ1xuXG5cdFx0LyogT3B0aW9uYWw6IFRoZSBwb3NpdGlvbiBhbmQgc2l6ZSBvZiB0aGUgYmFja2dyb3VuZCBpbWFnZSBpbiB0aGUgc2tlbGV0b24ncyB3b3JsZCBjb29yZGluYXRlcy4gRGVmYXVsdDogZmlsbHMgdGhlIHZpZXdwb3J0ICovXG5cdFx0eD86IG51bWJlclxuXHRcdHk/OiBudW1iZXJcblx0XHR3aWR0aD86IG51bWJlclxuXHRcdGhlaWdodD86IG51bWJlclxuXHR9XG5cblx0LyogT3B0aW9uYWw6IFdoZXRoZXIgbWlwbWFwcGluZyBhbmQgYW5pc290cm9waWMgZmlsdGVyaW5nIGFyZSB1c2VkIGZvciBoaWdoZXN0IHF1YWxpdHkgc2NhbGluZyB3aGVuIGF2YWlsYWJsZSwgb3RoZXJ3aXNlIHRoZVxuXHQgICBmaWx0ZXIgc2V0dGluZ3MgZnJvbSB0aGUgdGV4dHVyZSBhdGxhcyBhcmUgdXNlZC4gRGVmYXVsdDogdHJ1ZSAqL1xuXHRtaXBtYXBzPzogYm9vbGVhblxuXG5cdC8qIE9wdGlvbmFsOiBXaGV0aGVyIHRoZSBwbGF5ZXIgcmVzcG9uZHMgdG8gdXNlciBjbGljay90b3VjaCAocGxheS9wYXVzZSwgb3IgY29udHJvbCBib25lcykuIERlZmF1bHQ6IHRydWUgKi9cblx0aW50ZXJhY3RpdmU/OiBib29sZWFuXG5cblx0LyogT3B0aW9uYWw6IExpc3Qgb2YgYm9uZSBuYW1lcyB0aGF0IHRoZSB1c2VyIGNhbiBkcmFnIHRvIHBvc2l0aW9uLiBEZWZhdWx0OiBub25lICovXG5cdGNvbnRyb2xCb25lcz86IHN0cmluZ1tdXG5cblx0LyogT3B0aW9uYWw6IENhbGxiYWNrIHdoZW4gdGhlIHNrZWxldG9uIGFuZCBpdHMgYXNzZXRzIGhhdmUgYmVlbiBzdWNjZXNzZnVsbHkgbG9hZGVkLiBJZiBhbiBhbmltYXRpb24gaXMgc2V0IG9uIHRyYWNrIDAsXG5cdCAgIHRoZSBwbGF5ZXIgd29uJ3Qgc2V0IGl0cyBvd24gYW5pbWF0aW9uLiBEZWZhdWx0OiBub25lICovXG5cdHN1Y2Nlc3M/OiAocGxheWVyOiBTcGluZVBsYXllcikgPT4gdm9pZFxuXG5cdC8qIE9wdGlvbmFsOiBDYWxsYmFjayB3aGVuIHRoZSBza2VsZXRvbiBjb3VsZCBub3QgYmUgbG9hZGVkIG9yIHJlbmRlcmVkLiBEZWZhdWx0OiBub25lICovXG5cdGVycm9yPzogKHBsYXllcjogU3BpbmVQbGF5ZXIsIG1zZzogc3RyaW5nKSA9PiB2b2lkXG5cblx0LyogT3B0aW9uYWw6IENhbGxiYWNrIGF0IHRoZSBzdGFydCBvZiBlYWNoIGZyYW1lLCBiZWZvcmUgdGhlIHNrZWxldG9uIGlzIHBvc2VkIG9yIGRyYXduLiBEZWZhdWx0OiBub25lICovXG5cdGZyYW1lPzogKHBsYXllcjogU3BpbmVQbGF5ZXIsIGRlbHRhOiBudW1iZXIpID0+IHZvaWRcblxuXHQvKiBPcHRpb25hbDogQ2FsbGJhY2sgdG8gdXBkYXRlIHRoZSBza2VsZXRvbidzIHdvcmxkIHRyYW5zZm9ybS4gRGVmYXVsdDogcGxheWVyLnNrZWxldG9uLnVwZGF0ZVdvcmxkVHJhbnNmb3JtKHNwaW5lLlBoeXNpY3MudXBkYXRlKSBpcyBjYWxsZWQgKi9cblx0dXBkYXRlV29ybGRUcmFuc2Zvcm0/OiAocGxheWVyOiBTcGluZVBsYXllciwgZGVsdGE6IG51bWJlcikgPT4gdm9pZFxuXG5cdC8qIE9wdGlvbmFsOiBDYWxsYmFjayBhZnRlciB0aGUgc2tlbGV0b24gaXMgcG9zZWQgZWFjaCBmcmFtZSwgYmVmb3JlIGl0IGlzIGRyYXduLiBEZWZhdWx0OiBub25lICovXG5cdHVwZGF0ZT86IChwbGF5ZXI6IFNwaW5lUGxheWVyLCBkZWx0YTogbnVtYmVyKSA9PiB2b2lkXG5cblx0LyogT3B0aW9uYWw6IENhbGxiYWNrIGFmdGVyIHRoZSBza2VsZXRvbiBpcyBkcmF3biBlYWNoIGZyYW1lLiBEZWZhdWx0OiBub25lICovXG5cdGRyYXc/OiAocGxheWVyOiBTcGluZVBsYXllciwgZGVsdGE6IG51bWJlcikgPT4gdm9pZFxuXG5cdC8qIE9wdGlvbmFsOiBDYWxsYmFjayBlYWNoIGZyYW1lIGJlZm9yZSB0aGUgc2tlbGV0b24gaXMgbG9hZGVkLiBEZWZhdWx0OiBub25lICovXG5cdGxvYWRpbmc/OiAocGxheWVyOiBTcGluZVBsYXllciwgZGVsdGE6IG51bWJlcikgPT4gdm9pZFxuXG5cdC8qIE9wdGlvbmFsOiBUaGUgZG93bmxvYWRlciB1c2VkIGJ5IHRoZSBwbGF5ZXIncyBhc3NldCBtYW5hZ2VyLiBQYXNzaW5nIHRoZSBzYW1lIGRvd25sb2FkZXIgdG8gbXVsdGlwbGUgcGxheWVycyB1c2luZyB0aGVcblx0ICAgc2FtZSBhc3NldHMgZW5zdXJlcyB0aGUgYXNzZXRzIGFyZSBvbmx5IGRvd25sb2FkZWQgb25jZS4gRGVmYXVsdDogbmV3IGluc3RhbmNlICovXG5cdGRvd25sb2FkZXI/OiBEb3dubG9hZGVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVmlld3BvcnQge1xuXHQvKiBPcHRpb25hbDogVGhlIHBvc2l0aW9uIGFuZCBzaXplIG9mIHRoZSB2aWV3cG9ydCBpbiB0aGUgc2tlbGV0b24ncyB3b3JsZCBjb29yZGluYXRlcy4gRGVmYXVsdDogdGhlIGJvdW5kaW5nIGJveCB0aGF0IGZpdHNcblx0ICAgdGhlIGN1cnJlbnQgYW5pbWF0aW9uICovXG5cdHg6IG51bWJlclxuXHR5OiBudW1iZXJcblx0d2lkdGg6IG51bWJlclxuXHRoZWlnaHQ6IG51bWJlclxuXG5cdC8qIE9wdGlvbmFsOiBQYWRkaW5nIGFyb3VuZCB0aGUgdmlld3BvcnQgc2l6ZSwgZ2l2ZW4gYXMgYSBudW1iZXIgb3IgcGVyY2VudGFnZSAoZWcgXCIyNSVcIikuIERlZmF1bHQ6IDEwJSAqL1xuXHRwYWRMZWZ0OiBzdHJpbmcgfCBudW1iZXJcblx0cGFkUmlnaHQ6IHN0cmluZyB8IG51bWJlclxuXHRwYWRUb3A6IHN0cmluZyB8IG51bWJlclxuXHRwYWRCb3R0b206IHN0cmluZyB8IG51bWJlclxuXG5cdC8qIE9wdGlvbmFsOiBpZiB0cnVlLCByZW5kZXJpbmcgb2NjdXJzIG9ubHkgd2l0aGluIHRoZSB2aWV3cG9ydCAqL1xuXHRjbGlwPzogYm9vbGVhblxufVxuXG5leHBvcnQgY2xhc3MgU3BpbmVQbGF5ZXIgaW1wbGVtZW50cyBEaXNwb3NhYmxlIHtcblx0cHVibGljIHBhcmVudDogSFRNTEVsZW1lbnQ7XG5cdHB1YmxpYyBkb206IEhUTUxFbGVtZW50O1xuXHRwdWJsaWMgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IG51bGwgPSBudWxsO1xuXHRwdWJsaWMgY29udGV4dDogTWFuYWdlZFdlYkdMUmVuZGVyaW5nQ29udGV4dCB8IG51bGwgPSBudWxsO1xuXHRwdWJsaWMgc2NlbmVSZW5kZXJlcjogU2NlbmVSZW5kZXJlciB8IG51bGwgPSBudWxsO1xuXHRwdWJsaWMgbG9hZGluZ1NjcmVlbjogTG9hZGluZ1NjcmVlbiB8IG51bGwgPSBudWxsO1xuXHRwdWJsaWMgYXNzZXRNYW5hZ2VyOiBBc3NldE1hbmFnZXIgfCBudWxsID0gbnVsbDtcblx0cHVibGljIGJnID0gbmV3IENvbG9yKCk7XG5cdHB1YmxpYyBiZ0Z1bGxzY3JlZW4gPSBuZXcgQ29sb3IoKTtcblxuXHRwcml2YXRlIHBsYXllckNvbnRyb2xzOiBIVE1MRWxlbWVudCB8IG51bGwgPSBudWxsO1xuXHRwcml2YXRlIHRpbWVsaW5lU2xpZGVyOiBTbGlkZXIgfCBudWxsID0gbnVsbDtcblx0cHJpdmF0ZSBwbGF5QnV0dG9uOiBIVE1MRWxlbWVudCB8IG51bGwgPSBudWxsO1xuXHRwcml2YXRlIHNraW5CdXR0b246IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XG5cdHByaXZhdGUgcGlubmVkU2tpbnM6IFNldDxzdHJpbmc+ID0gbmV3IFNldCgpO1xuXHRwcml2YXRlIGFuaW1hdGlvbkJ1dHRvbjogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcblxuXHRwcml2YXRlIHBsYXlUaW1lID0gMDtcblx0cHJpdmF0ZSBzZWxlY3RlZEJvbmVzOiAoQm9uZSB8IG51bGwpW10gPSBbXTtcblx0cHJpdmF0ZSBjYW5jZWxJZDogYW55ID0gMDtcblx0cG9wdXA6IFBvcHVwIHwgbnVsbCA9IG51bGw7XG5cblx0LyogVHJ1ZSBpZiB0aGUgcGxheWVyIGlzIHVuYWJsZSB0byBsb2FkIG9yIHJlbmRlciB0aGUgc2tlbGV0b24uICovXG5cdHB1YmxpYyBlcnJvcjogYm9vbGVhbiA9IGZhbHNlO1xuXHQvKiBUaGUgcGxheWVyJ3Mgc2tlbGV0b24uIE51bGwgdW50aWwgbG9hZGluZyBpcyBjb21wbGV0ZSAoYWNjZXNzIGFmdGVyIGNvbmZpZy5zdWNjZXNzKS4gKi9cblx0cHVibGljIHNrZWxldG9uOiBTa2VsZXRvbiB8IG51bGwgPSBudWxsO1xuXHQvKiBUaGUgYW5pbWF0aW9uIHN0YXRlIGNvbnRyb2xsaW5nIHRoZSBza2VsZXRvbi4gTnVsbCB1bnRpbCBsb2FkaW5nIGlzIGNvbXBsZXRlIChhY2Nlc3MgYWZ0ZXIgY29uZmlnLnN1Y2Nlc3MpLiAqL1xuXHRwdWJsaWMgYW5pbWF0aW9uU3RhdGU6IEFuaW1hdGlvblN0YXRlIHwgbnVsbCA9IG51bGw7XG5cblx0cHVibGljIHBhdXNlZCA9IHRydWU7XG5cdHB1YmxpYyBzcGVlZCA9IDE7XG5cdHB1YmxpYyB0aW1lID0gbmV3IFRpbWVLZWVwZXIoKTtcblx0cHJpdmF0ZSBzdG9wUmVxdWVzdEFuaW1hdGlvbkZyYW1lID0gZmFsc2U7XG5cdHByaXZhdGUgZGlzcG9zZWQgPSBmYWxzZTtcblxuXHRwcml2YXRlIHZpZXdwb3J0OiBWaWV3cG9ydCA9IHt9IGFzIFZpZXdwb3J0O1xuXHRwcml2YXRlIGN1cnJlbnRWaWV3cG9ydDogVmlld3BvcnQgPSB7fSBhcyBWaWV3cG9ydDtcblx0cHJpdmF0ZSBwcmV2aW91c1ZpZXdwb3J0OiBWaWV3cG9ydCA9IHt9IGFzIFZpZXdwb3J0O1xuXHRwcml2YXRlIHZpZXdwb3J0VHJhbnNpdGlvblN0YXJ0ID0gMDtcblx0cHJpdmF0ZSBldmVudExpc3RlbmVyczogQXJyYXk8eyB0YXJnZXQ6IGFueSwgZXZlbnQ6IGFueSwgZnVuYzogYW55IH0+ID0gW107XG5cdHByaXZhdGUgaW5wdXQ/OiBJbnB1dDtcblxuXHRjb25zdHJ1Y3RvciAocGFyZW50OiBIVE1MRWxlbWVudCB8IHN0cmluZywgcHJpdmF0ZSBjb25maWc6IFNwaW5lUGxheWVyQ29uZmlnKSB7XG5cdFx0Y29uc3QgcGFyZW50RG9tID0gdHlwZW9mIHBhcmVudCA9PT0gXCJzdHJpbmdcIiA/IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHBhcmVudCkgOiBwYXJlbnQ7XG5cdFx0aWYgKHBhcmVudERvbSA9PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoYFNwaW5lUGxheWVyIHBhcmVudCBub3QgZm91bmQ6ICR7cGFyZW50fWApO1xuXHRcdHRoaXMucGFyZW50ID0gcGFyZW50RG9tO1xuXG5cdFx0aWYgKGNvbmZpZy5zaG93Q29udHJvbHMgPT09IHZvaWQgMCkgY29uZmlnLnNob3dDb250cm9scyA9IHRydWU7XG5cdFx0Y29uc3QgY29udHJvbHMgPSBjb25maWcuc2hvd0NvbnRyb2xzID8gLypodG1sKi9gXG48ZGl2IGNsYXNzPVwic3BpbmUtcGxheWVyLWNvbnRyb2xzIHNwaW5lLXBsYXllci1wb3B1cC1wYXJlbnQgc3BpbmUtcGxheWVyLWNvbnRyb2xzLWhpZGRlblwiPlxuPGRpdiBjbGFzcz1cInNwaW5lLXBsYXllci10aW1lbGluZVwiPjwvZGl2PlxuPGRpdiBjbGFzcz1cInNwaW5lLXBsYXllci1idXR0b25zXCI+XG48YnV0dG9uIGNsYXNzPVwic3BpbmUtcGxheWVyLWJ1dHRvbiBzcGluZS1wbGF5ZXItYnV0dG9uLWljb24tcGF1c2VcIj48L2J1dHRvbj5cbjxkaXYgY2xhc3M9XCJzcGluZS1wbGF5ZXItYnV0dG9uLXNwYWNlclwiPjwvZGl2PlxuPGJ1dHRvbiBjbGFzcz1cInNwaW5lLXBsYXllci1idXR0b24gc3BpbmUtcGxheWVyLWJ1dHRvbi1pY29uLXNwZWVkXCI+PC9idXR0b24+XG48YnV0dG9uIGNsYXNzPVwic3BpbmUtcGxheWVyLWJ1dHRvbiBzcGluZS1wbGF5ZXItYnV0dG9uLWljb24tYW5pbWF0aW9uc1wiPjwvYnV0dG9uPlxuPGJ1dHRvbiBjbGFzcz1cInNwaW5lLXBsYXllci1idXR0b24gc3BpbmUtcGxheWVyLWJ1dHRvbi1pY29uLXNraW5zXCI+PC9idXR0b24+XG48YnV0dG9uIGNsYXNzPVwic3BpbmUtcGxheWVyLWJ1dHRvbiBzcGluZS1wbGF5ZXItYnV0dG9uLWljb24tc2V0dGluZ3NcIj48L2J1dHRvbj5cbjxidXR0b24gY2xhc3M9XCJzcGluZS1wbGF5ZXItYnV0dG9uIHNwaW5lLXBsYXllci1idXR0b24taWNvbi1mdWxsc2NyZWVuXCI+PC9idXR0b24+XG48aW1nIGNsYXNzPVwic3BpbmUtcGxheWVyLWJ1dHRvbi1pY29uLXNwaW5lLWxvZ29cIiBzcmM9XCJkYXRhOmltYWdlL3N2Zyt4bWwsJTNDc3ZnJTIweG1sbnMlM0QlMjJodHRwJTNBJTJGJTJGd3d3LnczLm9yZyUyRjIwMDAlMkZzdmclMjIlMjB2aWV3Qm94JTNEJTIyMCUyMDAlMjAxMDQlMjAzMS4xNiUyMiUzRSUzQ3BhdGglMjBkJTNEJTIyTTEwNCUyMDEyLjY4YTEuMzElMjAxLjMxJTIwMCUyMDAlMjAxLS4zNyUyMDElMjAxLjI4JTIwMS4yOCUyMDAlMjAwJTIwMS0uODUuMzFIOTEuNTdhMTAuNTElMjAxMC41MSUyMDAlMjAwJTIwMCUyMC4yOSUyMDIuNTUlMjA0LjkyJTIwNC45MiUyMDAlMjAwJTIwMCUyMDElMjAyJTIwNC4yNyUyMDQuMjclMjAwJTIwMCUyMDAlMjAxLjY0JTIwMS4yNiUyMDYuODklMjA2Ljg5JTIwMCUyMDAlMjAwJTIwMi42LjQ0JTIwMTAuNjYlMjAxMC42NiUyMDAlMjAwJTIwMCUyMDIuMTctLjIlMjAxMi44MSUyMDEyLjgxJTIwMCUyMDAlMjAwJTIwMS42NC0uNDRxLjY5LS4yNSUyMDEuMTQtLjQ0YTEuODclMjAxLjg3JTIwMCUyMDAlMjAxJTIwLjY4LS4yLjQ0LjQ0JTIwMCUyMDAlMjAxJTIwLjI3LjA0LjQzLjQzJTIwMCUyMDAlMjAxJTIwLjE2LjIlMjAxLjM4JTIwMS4zOCUyMDAlMjAwJTIwMSUyMC4wOS4zNyUyMDQuODklMjA0Ljg5JTIwMCUyMDAlMjAxJTIwMCUyMC41OCUyMDQuMTQlMjA0LjE0JTIwMCUyMDAlMjAxJTIwMCUyMC40M3YuMzJhLjgzLjgzJTIwMCUyMDAlMjAxLS4wOS4yNiUyMDEuMSUyMDEuMSUyMDAlMjAwJTIwMS0uMTcuMjIlMjAyLjc3JTIwMi43NyUyMDAlMjAwJTIwMS0uNjEuMzQlMjA4Ljk0JTIwOC45NCUyMDAlMjAwJTIwMS0xLjMyLjQ2JTIwMTguNTQlMjAxOC41NCUyMDAlMjAwJTIwMS0xLjg4LjQxJTIwMTMuNzglMjAxMy43OCUyMDAlMjAwJTIwMS0yLjI4LjE4JTIwMTAuNTUlMjAxMC41NSUyMDAlMjAwJTIwMS0zLjY4LS41OSUyMDYuODIlMjA2LjgyJTIwMCUyMDAlMjAxLTIuNjYtMS43NCUyMDcuNDQlMjA3LjQ0JTIwMCUyMDAlMjAxLTEuNjMtMi44OSUyMDEzLjQ4JTIwMTMuNDglMjAwJTIwMCUyMDEtLjU1LTQlMjAxMi43NiUyMDEyLjc2JTIwMCUyMDAlMjAxJTIwLjU3LTMuOTQlMjA4LjM1JTIwOC4zNSUyMDAlMjAwJTIwMSUyMDEuNjQtMyUyMDcuMTUlMjA3LjE1JTIwMCUyMDAlMjAxJTIwMi41OC0xLjg3JTIwOC40NyUyMDguNDclMjAwJTIwMCUyMDElMjAzLjM5LS42NSUyMDguMTklMjA4LjE5JTIwMCUyMDAlMjAxJTIwMy40MS42NCUyMDYuNDYlMjA2LjQ2JTIwMCUyMDAlMjAxJTIwMi4zMiUyMDEuNzMlMjA3JTIwNyUyMDAlMjAwJTIwMSUyMDEuMyUyMDIuNTQlMjAxMS4xNyUyMDExLjE3JTIwMCUyMDAlMjAxJTIwLjQzJTIwMy4xM3ptLTMuMTQtLjkzYTUuNjklMjA1LjY5JTIwMCUyMDAlMjAwLTEuMDktMy44NiUyMDQuMTclMjA0LjE3JTIwMCUyMDAlMjAwLTMuNDItMS40JTIwNC41MiUyMDQuNTIlMjAwJTIwMCUyMDAtMiUyMC40NCUyMDQuNDElMjA0LjQxJTIwMCUyMDAlMjAwLTEuNDclMjAxLjE1QTUuMjklMjA1LjI5JTIwMCUyMDAlMjAwJTIwOTIlMjA5Ljc1YTclMjA3JTIwMCUyMDAlMjAwLS4zNiUyMDJ6TTgwLjY4JTIwMjEuOTRhLjQyLjQyJTIwMCUyMDAlMjAxLS4wOC4yNi41OS41OSUyMDAlMjAwJTIwMS0uMjUuMTglMjAxLjc0JTIwMS43NCUyMDAlMjAwJTIwMS0uNDcuMTElMjA2LjMxJTIwNi4zMSUyMDAlMjAwJTIwMS0uNzYlMjAwJTIwNi41JTIwNi41JTIwMCUyMDAlMjAxLS43OCUyMDAlMjAxLjc0JTIwMS43NCUyMDAlMjAwJTIwMS0uNDctLjExLjU5LjU5JTIwMCUyMDAlMjAxLS4yNS0uMTguNDIuNDIlMjAwJTIwMCUyMDEtLjA4LS4yNlYxMmE5LjglMjA5LjglMjAwJTIwMCUyMDAtLjIzLTIuMzUlMjA0Ljg2JTIwNC44NiUyMDAlMjAwJTIwMC0uNjYtMS41MyUyMDIuODglMjAyLjg4JTIwMCUyMDAlMjAwLTEuMTMtMSUyMDMuNTclMjAzLjU3JTIwMCUyMDAlMjAwLTEuNi0uMzQlMjA0JTIwNCUyMDAlMjAwJTIwMC0yLjM1LjgzQTEyLjcxJTIwMTIuNzElMjAwJTIwMCUyMDAlMjA2OS4xMSUyMDEwdjExLjlhLjQyLjQyJTIwMCUyMDAlMjAxLS4wOC4yNi41OS41OSUyMDAlMjAwJTIwMS0uMjUuMTglMjAxLjc0JTIwMS43NCUyMDAlMjAwJTIwMS0uNDcuMTElMjA2LjUxJTIwNi41MSUyMDAlMjAwJTIwMS0uNzglMjAwJTIwNi4zMSUyMDYuMzElMjAwJTIwMCUyMDEtLjc2JTIwMCUyMDEuODglMjAxLjg4JTIwMCUyMDAlMjAxLS40OC0uMTEuNTIuNTIlMjAwJTIwMCUyMDEtLjI1LS4xOC40Ni40NiUyMDAlMjAwJTIwMS0uMDctLjI2di0xN2EuNTMuNTMlMjAwJTIwMCUyMDElMjAuMDMtLjIxLjUuNSUyMDAlMjAwJTIwMSUyMC4yMy0uMTklMjAxLjI4JTIwMS4yOCUyMDAlMjAwJTIwMSUyMC40NC0uMTElMjA4LjUzJTIwOC41MyUyMDAlMjAwJTIwMSUyMDEuMzklMjAwJTIwMS4xMiUyMDEuMTIlMjAwJTIwMCUyMDElMjAuNDMuMTEuNi42JTIwMCUyMDAlMjAxJTIwLjIyLjE5LjQ3LjQ3JTIwMCUyMDAlMjAxJTIwLjA3LjI2VjcuMmExMC40NiUyMDEwLjQ2JTIwMCUyMDAlMjAxJTIwMi44Ny0yLjM2JTIwNi4xNyUyMDYuMTclMjAwJTIwMCUyMDElMjAyLjg4LS43NSUyMDYuNDElMjA2LjQxJTIwMCUyMDAlMjAxJTIwMi44Ny41OCUyMDUuMTYlMjA1LjE2JTIwMCUyMDAlMjAxJTIwMS44OCUyMDEuNTQlMjA2LjE1JTIwNi4xNSUyMDAlMjAwJTIwMSUyMDElMjAyLjI2JTIwMTMuNDYlMjAxMy40NiUyMDAlMjAwJTIwMSUyMC4zMSUyMDMuMTF6JTIyJTIwZmlsbCUzRCUyMiUyM2ZmZiUyMiUyRiUzRSUzQ3BhdGglMjBkJTNEJTIyTTQzLjM1JTIwMi44NmMuMDklMjAyLjYlMjAxLjg5JTIwNCUyMDUuNDglMjA0LjYxJTIwMyUyMC40OCUyMDUuNzkuMjQlMjA2LjY5LTIuMzclMjAxLjc1LTUuMDktMi40LTMuODItNi00LjM5cy02LjMxLTIuMDMtNi4xNyUyMDIuMTV6bTEuMDglMjAxMC42OWMuMzMlMjAxLjk0JTIwMi4xNCUyMDMuMDYlMjA0LjkxJTIwM3M0Ljg0LTEuMTYlMjA1LjEzLTMuMjVjLjUzLTMuODgtMi41My0yLjM4LTUuMy0yLjNzLTUuNC0xLjI2LTQuNzQlMjAyLjU1ek00OCUyMDIyLjQ0Yy41NSUyMDEuNDUlMjAyLjA2JTIwMi4wNiUyMDQuMSUyMDEuNjNzMy40NS0xLjExJTIwMy4zMy0yLjc2Yy0uMjEtMy4wNi0yLjIyLTIuMS00LjI2LTEuNjZTNDclMjAxOS42JTIwNDglMjAyMi40NHptMS43OCUyMDYuNzhjLjE2JTIwMS4yMiUyMDEuMjIlMjAyJTIwMi44OCUyMDEuOTNzMi45Mi0uNjclMjAzLjEzLTJjLjQtMi40My0xLjQ2LTEuNTMtMy4xMi0xLjUxcy0zLjE3LS44Mi0yLjg5JTIwMS41OHolMjIlMjBmaWxsJTNEJTIyJTIzZmY0MDAwJTIyJTJGJTNFJTNDcGF0aCUyMGQlM0QlMjJNMzUuMjglMjAxMy4xNmExNS4zMyUyMDE1LjMzJTIwMCUyMDAlMjAxLS40OCUyMDQlMjA4Ljc1JTIwOC43NSUyMDAlMjAwJTIwMS0xLjQyJTIwMyUyMDYuMzUlMjA2LjM1JTIwMCUyMDAlMjAxLTIuMzIlMjAxLjkxJTIwNy4xNCUyMDcuMTQlMjAwJTIwMCUyMDEtMy4xNi42NyUyMDYuMSUyMDYuMSUyMDAlMjAwJTIwMS0xLjQtLjE1JTIwNS4zNCUyMDUuMzQlMjAwJTIwMCUyMDEtMS4yNi0uNDclMjA3LjI5JTIwNy4yOSUyMDAlMjAwJTIwMS0xLjI0LS44MXEtLjYxLS40OS0xLjI5LTEuMTV2OC41MWEuNDcuNDclMjAwJTIwMCUyMDEtLjA4LjI2LjU2LjU2JTIwMCUyMDAlMjAxLS4yNS4xOSUyMDEuNzQlMjAxLjc0JTIwMCUyMDAlMjAxLS40Ny4xMSUyMDYuNDclMjA2LjQ3JTIwMCUyMDAlMjAxLS43OCUyMDAlMjA2LjI2JTIwNi4yNiUyMDAlMjAwJTIwMS0uNzYlMjAwJTIwMS44OSUyMDEuODklMjAwJTIwMCUyMDEtLjQ4LS4xMS40OS40OSUyMDAlMjAwJTIwMS0uMjUtLjE5LjUxLjUxJTIwMCUyMDAlMjAxLS4wNy0uMjZWNC45MWEuNTcuNTclMjAwJTIwMCUyMDElMjAuMDYtLjI3LjQ2LjQ2JTIwMCUyMDAlMjAxJTIwLjIzLS4xOCUyMDEuNDclMjAxLjQ3JTIwMCUyMDAlMjAxJTIwLjQ0LS4xJTIwNy40MSUyMDcuNDElMjAwJTIwMCUyMDElMjAxLjMlMjAwJTIwMS40NSUyMDEuNDUlMjAwJTIwMCUyMDElMjAuNDMuMS41Mi41MiUyMDAlMjAwJTIwMSUyMC4yNC4xOC41MS41MSUyMDAlMjAwJTIwMSUyMC4wNy4yN1Y3LjJhMTguMDYlMjAxOC4wNiUyMDAlMjAwJTIwMSUyMDEuNDktMS4zOCUyMDklMjA5JTIwMCUyMDAlMjAxJTIwMS40NS0xJTIwNi44MiUyMDYuODIlMjAwJTIwMCUyMDElMjAxLjQ5LS41OSUyMDcuMDklMjA3LjA5JTIwMCUyMDAlMjAxJTIwNC43OC41MiUyMDYlMjA2JTIwMCUyMDAlMjAxJTIwMi4xMyUyMDIlMjA4Ljc5JTIwOC43OSUyMDAlMjAwJTIwMSUyMDEuMiUyMDIuOSUyMDE1LjcyJTIwMTUuNzIlMjAwJTIwMCUyMDElMjAuNCUyMDMuNTF6bS0zLjI4LjM2YTE1LjY0JTIwMTUuNjQlMjAwJTIwMCUyMDAtLjItMi41MyUyMDcuMzIlMjA3LjMyJTIwMCUyMDAlMjAwLS42OS0yLjE3JTIwNC4wNiUyMDQuMDYlMjAwJTIwMCUyMDAtMS4zLTEuNTElMjAzLjQ5JTIwMy40OSUyMDAlMjAwJTIwMC0yLS41NyUyMDQuMSUyMDQuMSUyMDAlMjAwJTIwMC0xLjIuMTglMjA0LjkyJTIwNC45MiUyMDAlMjAwJTIwMC0xLjIuNTclMjA4LjU0JTIwOC41NCUyMDAlMjAwJTIwMC0xLjI4JTIwMUExNS43NyUyMDE1Ljc3JTIwMCUyMDAlMjAwJTIwMjIuNzYlMjAxMHY2Ljc3YTEzLjUzJTIwMTMuNTMlMjAwJTIwMCUyMDAlMjAyLjQ2JTIwMi40JTIwNC4xMiUyMDQuMTIlMjAwJTIwMCUyMDAlMjAyLjQ0LjgzJTIwMy41NiUyMDMuNTYlMjAwJTIwMCUyMDAlMjAyLS41N0E0LjI4JTIwNC4yOCUyMDAlMjAwJTIwMCUyMDMxJTIwMThhNy41OCUyMDcuNTglMjAwJTIwMCUyMDAlMjAuNzctMi4xMiUyMDExLjQzJTIwMTEuNDMlMjAwJTIwMCUyMDAlMjAuMjMtMi4zNnpNMTIlMjAxNy4zYTUuMzklMjA1LjM5JTIwMCUyMDAlMjAxLS40OCUyMDIuMzMlMjA0LjczJTIwNC43MyUyMDAlMjAwJTIwMS0xLjM3JTIwMS43MiUyMDYuMTklMjA2LjE5JTIwMCUyMDAlMjAxLTIuMTIlMjAxLjA2JTIwOS42MiUyMDkuNjIlMjAwJTIwMCUyMDEtMi43MS4zNiUyMDEwLjM4JTIwMTAuMzglMjAwJTIwMCUyMDEtMy4yMS0uNUE3LjYzJTIwNy42MyUyMDAlMjAwJTIwMSUyMDElMjAyMS44MmEzLjI1JTIwMy4yNSUyMDAlMjAwJTIwMS0uNjYtLjQzJTIwMS4wOSUyMDEuMDklMjAwJTIwMCUyMDEtLjMtLjUzJTIwMy41OSUyMDMuNTklMjAwJTIwMCUyMDEtLjA0LS45MyUyMDQuMDYlMjA0LjA2JTIwMCUyMDAlMjAxJTIwMC0uNjElMjAyJTIwMiUyMDAlMjAwJTIwMSUyMC4wOS0uNC40Mi40MiUyMDAlMjAwJTIwMSUyMC4xNi0uMjIuNDMuNDMlMjAwJTIwMCUyMDElMjAuMjQtLjA3JTIwMS4zNSUyMDEuMzUlMjAwJTIwMCUyMDElMjAuNjEuMjZxLjQxLjI2JTIwMSUyMC41NmE5LjIyJTIwOS4yMiUyMDAlMjAwJTIwMCUyMDEuNDEuNTUlMjA2LjI1JTIwNi4yNSUyMDAlMjAwJTIwMCUyMDEuODcuMjYlMjA1LjYyJTIwNS42MiUyMDAlMjAwJTIwMCUyMDEuNDQtLjE3JTIwMy40OCUyMDMuNDglMjAwJTIwMCUyMDAlMjAxLjEyLS41JTIwMi4yMyUyMDIuMjMlMjAwJTIwMCUyMDAlMjAuNzMtLjg0JTIwMi42OCUyMDIuNjglMjAwJTIwMCUyMDAlMjAuMjYtMS4yMSUyMDIlMjAyJTIwMCUyMDAlMjAwLS4zNy0xLjIxJTIwMy41NSUyMDMuNTUlMjAwJTIwMCUyMDAtMS0uODclMjA4LjA5JTIwOC4wOSUyMDAlMjAwJTIwMC0xLjM2LS42NmwtMS41Ni0uNjFhMTYlMjAxNiUyMDAlMjAwJTIwMS0xLjU3LS43MyUyMDYlMjA2JTIwMCUyMDAlMjAxLTEuMzctMSUyMDQuNTIlMjA0LjUyJTIwMCUyMDAlMjAxLTEtMS40JTIwNC42OSUyMDQuNjklMjAwJTIwMCUyMDEtLjM3LTIlMjA0Ljg4JTIwNC44OCUyMDAlMjAwJTIwMSUyMC4zOS0xLjg3JTIwNC40NiUyMDQuNDYlMjAwJTIwMCUyMDElMjAxLjE2LTEuNjElMjA1LjgzJTIwNS44MyUyMDAlMjAwJTIwMSUyMDEuOTQtMS4xMUE4LjA2JTIwOC4wNiUyMDAlMjAwJTIwMSUyMDYuNTMlMjA0YTguMjglMjA4LjI4JTIwMCUyMDAlMjAxJTIwMS4zNi4xMSUyMDkuMzYlMjA5LjM2JTIwMCUyMDAlMjAxJTIwMS4yMy4yOCUyMDUuOTIlMjA1LjkyJTIwMCUyMDAlMjAxJTIwLjk0LjM3JTIwNC4wOSUyMDQuMDklMjAwJTIwMCUyMDElMjAuNTkuMzUlMjAxJTIwMSUyMDAlMjAwJTIwMSUyMC4yNi4yNi44My44MyUyMDAlMjAwJTIwMSUyMC4wOS4yNiUyMDEuMzIlMjAxLjMyJTIwMCUyMDAlMjAwJTIwLjA2LjM1JTIwMy44NyUyMDMuODclMjAwJTIwMCUyMDElMjAwJTIwLjUxJTIwNC43NiUyMDQuNzYlMjAwJTIwMCUyMDElMjAwJTIwLjU2JTIwMS4zOSUyMDEuMzklMjAwJTIwMCUyMDEtLjA5LjM5LjUuNSUyMDAlMjAwJTIwMS0uMTYuMjIuMzUuMzUlMjAwJTIwMCUyMDEtLjIxLjA3JTIwMSUyMDElMjAwJTIwMCUyMDEtLjQ5LS4yMSUyMDclMjA3JTIwMCUyMDAlMjAwLS44My0uNDQlMjA5LjI2JTIwOS4yNiUyMDAlMjAwJTIwMC0xLjItLjQ0JTIwNS40OSUyMDUuNDklMjAwJTIwMCUyMDAtMS41OC0uMTYlMjA0LjkzJTIwNC45MyUyMDAlMjAwJTIwMC0xLjQuMTglMjAyLjY5JTIwMi42OSUyMDAlMjAwJTIwMC0xJTIwLjUxJTIwMi4xNiUyMDIuMTYlMjAwJTIwMCUyMDAtLjU5LjgzJTIwMi40MyUyMDIuNDMlMjAwJTIwMCUyMDAtLjIlMjAxJTIwMiUyMDIlMjAwJTIwMCUyMDAlMjAuMzglMjAxLjI0JTIwMy42JTIwMy42JTIwMCUyMDAlMjAwJTIwMSUyMC44OCUyMDguMjUlMjA4LjI1JTIwMCUyMDAlMjAwJTIwMS4zOC42OGwxLjU4LjYycS44LjMyJTIwMS41OS43MmE2JTIwNiUyMDAlMjAwJTIwMSUyMDEuMzklMjAxJTIwNC4zNyUyMDQuMzclMjAwJTIwMCUyMDElMjAxJTIwMS4zNiUyMDQuNDYlMjA0LjQ2JTIwMCUyMDAlMjAxJTIwLjM3JTIwMS44eiUyMiUyMGZpbGwlM0QlMjIlMjNmZmYlMjIlMkYlM0UlM0MlMkZzdmclM0VcIj5cbjwvZGl2PjwvZGl2PmAgOiBcIlwiO1xuXG5cdFx0dGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5kb20gPSBjcmVhdGVFbGVtZW50KFxuXHRcdFx0XHQvKmh0bWwqL2A8ZGl2IGNsYXNzPVwic3BpbmUtcGxheWVyXCIgc3R5bGU9XCJwb3NpdGlvbjpyZWxhdGl2ZTtoZWlnaHQ6MTAwJVwiPjxjYW52YXMgY2xhc3M9XCJzcGluZS1wbGF5ZXItY2FudmFzXCIgc3R5bGU9XCJkaXNwbGF5OmJsb2NrO3dpZHRoOjEwMCU7aGVpZ2h0OjEwMCVcIj48L2NhbnZhcz4ke2NvbnRyb2xzfTwvZGl2PmApKTtcblxuXHRcdHRyeSB7XG5cdFx0XHR0aGlzLnZhbGlkYXRlQ29uZmlnKGNvbmZpZyk7XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0dGhpcy5zaG93RXJyb3IoKGUgYXMgYW55KS5tZXNzYWdlLCBlIGFzIGFueSk7XG5cdFx0fVxuXG5cdFx0dGhpcy5pbml0aWFsaXplKCk7XG5cblx0XHQvLyBSZWdpc3RlciBhIGdsb2JhbCByZXNpemUgaGFuZGxlciB0byByZWRyYXcsIGF2b2lkaW5nIGZsaWNrZXIuXG5cdFx0dGhpcy5hZGRFdmVudExpc3RlbmVyKHdpbmRvdywgXCJyZXNpemVcIiwgKCkgPT4gdGhpcy5kcmF3RnJhbWUoZmFsc2UpKTtcblxuXHRcdC8vIFN0YXJ0IHRoZSByZW5kZXJpbmcgbG9vcC5cblx0XHRyZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gdGhpcy5kcmF3RnJhbWUoKSk7XG5cdH1cblxuXHRkaXNwb3NlICgpOiB2b2lkIHtcblx0XHR0aGlzLnNjZW5lUmVuZGVyZXI/LmRpc3Bvc2UoKTtcblx0XHR0aGlzLmxvYWRpbmdTY3JlZW4/LmRpc3Bvc2UoKTtcblx0XHR0aGlzLmFzc2V0TWFuYWdlcj8uZGlzcG9zZSgpO1xuXHRcdHRoaXMuY29udGV4dD8uZGlzcG9zZSgpO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ldmVudExpc3RlbmVycy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3QgZXZlbnRMaXN0ZW5lciA9IHRoaXMuZXZlbnRMaXN0ZW5lcnNbaV07XG5cdFx0XHRldmVudExpc3RlbmVyLnRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50TGlzdGVuZXIuZXZlbnQsIGV2ZW50TGlzdGVuZXIuZnVuYyk7XG5cdFx0fVxuXHRcdHRoaXMuaW5wdXQ/LmRpc3Bvc2UoKTtcblx0XHRpZiAodGhpcy5jYW52YXMpIHtcblx0XHRcdHRoaXMuY2FudmFzLndpZHRoID0gMDtcblx0XHRcdHRoaXMuY2FudmFzLmhlaWdodCA9IDA7XG5cdFx0fVxuXHRcdHRoaXMucGFyZW50LnJlbW92ZUNoaWxkKHRoaXMuZG9tKTtcblx0XHR0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcblx0fVxuXG5cdGFkZEV2ZW50TGlzdGVuZXIgKHRhcmdldDogYW55LCBldmVudDogYW55LCBmdW5jOiBhbnkpIHtcblx0XHR0aGlzLmV2ZW50TGlzdGVuZXJzLnB1c2goeyB0YXJnZXQ6IHRhcmdldCwgZXZlbnQ6IGV2ZW50LCBmdW5jOiBmdW5jIH0pO1xuXHRcdHRhcmdldC5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBmdW5jKTtcblx0fVxuXG5cdHByaXZhdGUgdmFsaWRhdGVDb25maWcgKGNvbmZpZzogU3BpbmVQbGF5ZXJDb25maWcpIHtcblx0XHRpZiAoIWNvbmZpZykgdGhyb3cgbmV3IEVycm9yKFwiQSBjb25maWd1cmF0aW9uIG9iamVjdCBtdXN0IGJlIHBhc3NlZCB0byB0byBuZXcgU3BpbmVQbGF5ZXIoKS5cIik7XG5cdFx0aWYgKChjb25maWcgYXMgYW55KS5za2VsVXJsKSBjb25maWcuc2tlbGV0b24gPSAoY29uZmlnIGFzIGFueSkuc2tlbFVybDtcblx0XHRpZiAoIWNvbmZpZy5za2VsZXRvbikgdGhyb3cgbmV3IEVycm9yKFwiQSBVUkwgbXVzdCBiZSBzcGVjaWZpZWQgZm9yIHRoZSBza2VsZXRvbiBKU09OIG9yIGJpbmFyeSBmaWxlLlwiKTtcblx0XHRpZiAoIWNvbmZpZy5zY2FsZSkgY29uZmlnLnNjYWxlID0gMTtcblx0XHRpZiAoIWNvbmZpZy5hdGxhcyAmJiAhY29uZmlnLmF0bGFzVXJsKSB0aHJvdyBuZXcgRXJyb3IoXCJBIFVSTCBtdXN0IGJlIHNwZWNpZmllZCBmb3IgdGhlIGF0bGFzIGZpbGUuXCIpO1xuXG5cdFx0aWYgKGNvbmZpZy5hdGxhc1VybCAmJiAhY29uZmlnLmF0bGFzKSBjb25maWcuYXRsYXMgPSBjb25maWcuYXRsYXNVcmw7XG5cblx0XHRpZiAoIWNvbmZpZy5iYWNrZ3JvdW5kQ29sb3IpIGNvbmZpZy5iYWNrZ3JvdW5kQ29sb3IgPSBjb25maWcuYWxwaGEgPyBcIjAwMDAwMDAwXCIgOiBcIjAwMDAwMFwiO1xuXHRcdGlmICghY29uZmlnLmZ1bGxTY3JlZW5CYWNrZ3JvdW5kQ29sb3IpIGNvbmZpZy5mdWxsU2NyZWVuQmFja2dyb3VuZENvbG9yID0gY29uZmlnLmJhY2tncm91bmRDb2xvcjtcblx0XHRpZiAoY29uZmlnLmJhY2tncm91bmRJbWFnZSAmJiAhY29uZmlnLmJhY2tncm91bmRJbWFnZS51cmwpIGNvbmZpZy5iYWNrZ3JvdW5kSW1hZ2UgPSB1bmRlZmluZWQ7XG5cdFx0aWYgKGNvbmZpZy5wcmVzZXJ2ZURyYXdpbmdCdWZmZXIgPT09IHZvaWQgMCkgY29uZmlnLnByZXNlcnZlRHJhd2luZ0J1ZmZlciA9IGZhbHNlO1xuXHRcdGlmIChjb25maWcubWlwbWFwcyA9PT0gdm9pZCAwKSBjb25maWcubWlwbWFwcyA9IHRydWU7XG5cdFx0aWYgKGNvbmZpZy5pbnRlcmFjdGl2ZSA9PT0gdm9pZCAwKSBjb25maWcuaW50ZXJhY3RpdmUgPSB0cnVlO1xuXHRcdGlmICh0eXBlb2YgY29uZmlnLmRlYnVnICE9PSBcIm9iamVjdFwiKSB7XG5cdFx0XHRjb25zdCBkID0gISFjb25maWcuZGVidWc7XG5cdFx0XHRjb25maWcuZGVidWcgPSB7IGJvbmVzOiBkLCByZWdpb25zOiBkLCBtZXNoZXM6IGQsIGJvdW5kczogZCwgcGF0aHM6IGQsIGNsaXBwaW5nOiBkLCBwb2ludHM6IGQsIGh1bGxzOiBkIH07XG5cdFx0fVxuXHRcdGlmIChjb25maWcuYW5pbWF0aW9ucyAmJiBjb25maWcuYW5pbWF0aW9uICYmIGNvbmZpZy5hbmltYXRpb25zLmluZGV4T2YoY29uZmlnLmFuaW1hdGlvbikgPCAwKVxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKGBBbmltYXRpb24gJyR7Y29uZmlnLmFuaW1hdGlvbn0nIGlzIG5vdCBpbiB0aGUgY29uZmlnIGFuaW1hdGlvbiBsaXN0OiAke3ByaW50KGNvbmZpZy5hbmltYXRpb25zKX1gKTtcblx0XHRpZiAoY29uZmlnLnNraW4pIHtcblx0XHRcdGlmICghQXJyYXkuaXNBcnJheShjb25maWcuc2tpbikpIGNvbmZpZy5za2luID0gW2NvbmZpZy5za2luXTtcblx0XHRcdGlmIChjb25maWcuc2tpbnMpIHtcblx0XHRcdFx0Zm9yIChjb25zdCBzIG9mIGNvbmZpZy5za2luKSB7XG5cdFx0XHRcdFx0aWYgKGNvbmZpZy5za2lucy5pbmRleE9mKHMpIDwgMClcblx0XHRcdFx0XHRcdHRocm93IG5ldyBFcnJvcihgRGVmYXVsdCBza2luICcke3N9JyBpcyBub3QgaW4gdGhlIGNvbmZpZyBza2lucyBsaXN0OiAke3ByaW50KGNvbmZpZy5za2lucyl9YCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0aWYgKCFjb25maWcudmlld3BvcnQpIGNvbmZpZy52aWV3cG9ydCA9IHt9IGFzIGFueTtcblx0XHRpZiAoIWNvbmZpZy52aWV3cG9ydCEuYW5pbWF0aW9ucykgY29uZmlnLnZpZXdwb3J0IS5hbmltYXRpb25zID0ge307XG5cdFx0aWYgKGNvbmZpZy52aWV3cG9ydCEuZGVidWdSZW5kZXIgPT09IHZvaWQgMCkgY29uZmlnLnZpZXdwb3J0IS5kZWJ1Z1JlbmRlciA9IGZhbHNlO1xuXHRcdGlmIChjb25maWcudmlld3BvcnQhLnRyYW5zaXRpb25UaW1lID09PSB2b2lkIDApIGNvbmZpZy52aWV3cG9ydCEudHJhbnNpdGlvblRpbWUgPSAwLjI1O1xuXHRcdGlmICghY29uZmlnLmNvbnRyb2xCb25lcykgY29uZmlnLmNvbnRyb2xCb25lcyA9IFtdO1xuXHRcdGlmIChjb25maWcuc2hvd0xvYWRpbmcgPT09IHZvaWQgMCkgY29uZmlnLnNob3dMb2FkaW5nID0gdHJ1ZTtcblx0XHRpZiAoY29uZmlnLmRlZmF1bHRNaXggPT09IHZvaWQgMCkgY29uZmlnLmRlZmF1bHRNaXggPSAwLjI1O1xuXHR9XG5cblx0cHJpdmF0ZSBpbml0aWFsaXplICgpOiBIVE1MRWxlbWVudCB8IG51bGwge1xuXHRcdGNvbnN0IGNvbmZpZyA9IHRoaXMuY29uZmlnO1xuXHRcdGNvbnN0IGRvbSA9IHRoaXMuZG9tO1xuXG5cdFx0aWYgKCFjb25maWcuYWxwaGEpIHsgLy8gUHJldmVudHMgYSBmbGFzaCBiZWZvcmUgdGhlIGZpcnN0IGZyYW1lIGlzIGRyYXduLlxuXHRcdFx0Y29uc3QgaGV4ID0gY29uZmlnLmJhY2tncm91bmRDb2xvciE7XG5cdFx0XHR0aGlzLmRvbS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAoaGV4LmNoYXJBdCgwKSA9PT0gJyMnID8gaGV4IDogYCMke2hleH1gKS5zdWJzdHJpbmcoMCwgNyk7XG5cdFx0fVxuXG5cdFx0dHJ5IHtcblx0XHRcdC8vIFNldHVwIHRoZSBPcGVuR0wgY29udGV4dC5cblx0XHRcdHRoaXMuY2FudmFzID0gZmluZFdpdGhDbGFzcyhkb20sIFwic3BpbmUtcGxheWVyLWNhbnZhc1wiKSBhcyBIVE1MQ2FudmFzRWxlbWVudDtcblx0XHRcdHRoaXMuY29udGV4dCA9IG5ldyBNYW5hZ2VkV2ViR0xSZW5kZXJpbmdDb250ZXh0KHRoaXMuY2FudmFzLCB7IGFscGhhOiBjb25maWcuYWxwaGEsIHByZXNlcnZlRHJhd2luZ0J1ZmZlcjogY29uZmlnLnByZXNlcnZlRHJhd2luZ0J1ZmZlciB9KTtcblxuXHRcdFx0Ly8gU2V0dXAgdGhlIHNjZW5lIHJlbmRlcmVyIGFuZCBsb2FkaW5nIHNjcmVlbi5cblx0XHRcdHRoaXMuc2NlbmVSZW5kZXJlciA9IG5ldyBTY2VuZVJlbmRlcmVyKHRoaXMuY2FudmFzLCB0aGlzLmNvbnRleHQsIHRydWUpO1xuXHRcdFx0aWYgKGNvbmZpZy5zaG93TG9hZGluZykgdGhpcy5sb2FkaW5nU2NyZWVuID0gbmV3IExvYWRpbmdTY3JlZW4odGhpcy5zY2VuZVJlbmRlcmVyKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHR0aGlzLnNob3dFcnJvcihcIlNvcnJ5LCB5b3VyIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBXZWJHTCwgb3IgeW91IGhhdmUgZGlzYWJsZWQgV2ViR0wgaW4geW91ciBicm93c2VyIHNldHRpbmdzLlxcblBsZWFzZSB1c2UgdGhlIGxhdGVzdCB2ZXJzaW9uIG9mIEZpcmVmb3gsIENocm9tZSwgRWRnZSwgb3IgU2FmYXJpLlwiLCBlIGFzIGFueSk7XG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9XG5cblx0XHQvLyBMb2FkIHRoZSBhc3NldHMuXG5cdFx0dGhpcy5hc3NldE1hbmFnZXIgPSBuZXcgQXNzZXRNYW5hZ2VyKHRoaXMuY29udGV4dCwgXCJcIiwgY29uZmlnLmRvd25sb2FkZXIpO1xuXHRcdGlmIChjb25maWcucmF3RGF0YVVSSXMpIHtcblx0XHRcdGZvciAoY29uc3QgcGF0aCBpbiBjb25maWcucmF3RGF0YVVSSXMpXG5cdFx0XHRcdHRoaXMuYXNzZXRNYW5hZ2VyLnNldFJhd0RhdGFVUkkocGF0aCwgY29uZmlnLnJhd0RhdGFVUklzW3BhdGhdKTtcblx0XHR9XG5cdFx0aWYgKGNvbmZpZy5za2VsZXRvbiEuZW5kc1dpdGgoXCIuanNvblwiKSlcblx0XHRcdHRoaXMuYXNzZXRNYW5hZ2VyLmxvYWRKc29uKGNvbmZpZy5za2VsZXRvbiEpO1xuXHRcdGVsc2Vcblx0XHRcdHRoaXMuYXNzZXRNYW5hZ2VyLmxvYWRCaW5hcnkoY29uZmlnLnNrZWxldG9uISk7XG5cdFx0dGhpcy5hc3NldE1hbmFnZXIubG9hZFRleHR1cmVBdGxhcyhjb25maWcuYXRsYXMhKTtcblx0XHRpZiAoY29uZmlnLmJhY2tncm91bmRJbWFnZSkgdGhpcy5hc3NldE1hbmFnZXIubG9hZFRleHR1cmUoY29uZmlnLmJhY2tncm91bmRJbWFnZS51cmwpO1xuXG5cdFx0Ly8gU2V0dXAgdGhlIFVJIGVsZW1lbnRzLlxuXHRcdHRoaXMuYmcuc2V0RnJvbVN0cmluZyhjb25maWcuYmFja2dyb3VuZENvbG9yISk7XG5cdFx0dGhpcy5iZ0Z1bGxzY3JlZW4uc2V0RnJvbVN0cmluZyhjb25maWcuZnVsbFNjcmVlbkJhY2tncm91bmRDb2xvciEpO1xuXHRcdGlmIChjb25maWcuc2hvd0NvbnRyb2xzKSB7XG5cdFx0XHR0aGlzLnBsYXllckNvbnRyb2xzID0gZG9tLmNoaWxkcmVuWzFdIGFzIEhUTUxFbGVtZW50O1xuXHRcdFx0Y29uc3QgY29udHJvbHMgPSB0aGlzLnBsYXllckNvbnRyb2xzLmNoaWxkcmVuO1xuXHRcdFx0Y29uc3QgdGltZWxpbmUgPSBjb250cm9sc1swXSBhcyBIVE1MRWxlbWVudDtcblx0XHRcdGNvbnN0IGJ1dHRvbnMgPSBjb250cm9sc1sxXS5jaGlsZHJlbjtcblx0XHRcdHRoaXMucGxheUJ1dHRvbiA9IGJ1dHRvbnNbMF0gYXMgSFRNTEVsZW1lbnQ7XG5cdFx0XHRjb25zdCBzcGVlZEJ1dHRvbiA9IGJ1dHRvbnNbMl0gYXMgSFRNTEVsZW1lbnQ7XG5cdFx0XHR0aGlzLmFuaW1hdGlvbkJ1dHRvbiA9IGJ1dHRvbnNbM10gYXMgSFRNTEVsZW1lbnQ7XG5cdFx0XHR0aGlzLnNraW5CdXR0b24gPSBidXR0b25zWzRdIGFzIEhUTUxFbGVtZW50O1xuXHRcdFx0Y29uc3Qgc2V0dGluZ3NCdXR0b24gPSBidXR0b25zWzVdIGFzIEhUTUxFbGVtZW50O1xuXHRcdFx0Y29uc3QgZnVsbHNjcmVlbkJ1dHRvbiA9IGJ1dHRvbnNbNl0gYXMgSFRNTEVsZW1lbnQ7XG5cdFx0XHRjb25zdCBsb2dvQnV0dG9uID0gYnV0dG9uc1s3XSBhcyBIVE1MRWxlbWVudDtcblxuXHRcdFx0dGhpcy50aW1lbGluZVNsaWRlciA9IG5ldyBTbGlkZXIoKTtcblx0XHRcdHRpbWVsaW5lLmFwcGVuZENoaWxkKHRoaXMudGltZWxpbmVTbGlkZXIuY3JlYXRlKCkpO1xuXHRcdFx0dGhpcy50aW1lbGluZVNsaWRlci5jaGFuZ2UgPSAocGVyY2VudGFnZSkgPT4ge1xuXHRcdFx0XHR0aGlzLnBhdXNlKCk7XG5cdFx0XHRcdGNvbnN0IGFuaW1hdGlvbkR1cmF0aW9uID0gdGhpcy5hbmltYXRpb25TdGF0ZSEuZ2V0VHJhY2soMCkhLmFuaW1hdGlvbiEuZHVyYXRpb247XG5cdFx0XHRcdGNvbnN0IHRpbWUgPSBhbmltYXRpb25EdXJhdGlvbiAqIHBlcmNlbnRhZ2U7XG5cdFx0XHRcdHRoaXMuYW5pbWF0aW9uU3RhdGUhLnVwZGF0ZSh0aW1lIC0gdGhpcy5wbGF5VGltZSk7XG5cdFx0XHRcdHRoaXMuYW5pbWF0aW9uU3RhdGUhLmFwcGx5KHRoaXMuc2tlbGV0b24hKTtcblx0XHRcdFx0dGhpcy5za2VsZXRvbiEudXBkYXRlKHRpbWUgLSB0aGlzLnBsYXlUaW1lKTtcblx0XHRcdFx0dGhpcy5za2VsZXRvbiEudXBkYXRlV29ybGRUcmFuc2Zvcm0oUGh5c2ljcy51cGRhdGUpO1xuXHRcdFx0XHR0aGlzLnBsYXlUaW1lID0gdGltZTtcblx0XHRcdH07XG5cblx0XHRcdHRoaXMucGxheUJ1dHRvbi5vbmNsaWNrID0gKCkgPT4gKHRoaXMucGF1c2VkID8gdGhpcy5wbGF5KCkgOiB0aGlzLnBhdXNlKCkpO1xuXHRcdFx0c3BlZWRCdXR0b24ub25jbGljayA9ICgpID0+IHRoaXMuc2hvd1NwZWVkRGlhbG9nKHNwZWVkQnV0dG9uKTtcblx0XHRcdHRoaXMuYW5pbWF0aW9uQnV0dG9uLm9uY2xpY2sgPSAoKSA9PiB0aGlzLnNob3dBbmltYXRpb25zRGlhbG9nKHRoaXMuYW5pbWF0aW9uQnV0dG9uISk7XG5cdFx0XHR0aGlzLnNraW5CdXR0b24ub25jbGljayA9ICgpID0+IHRoaXMuc2hvd1NraW5zRGlhbG9nKHRoaXMuc2tpbkJ1dHRvbiEpO1xuXHRcdFx0c2V0dGluZ3NCdXR0b24ub25jbGljayA9ICgpID0+IHRoaXMuc2hvd1NldHRpbmdzRGlhbG9nKHNldHRpbmdzQnV0dG9uKTtcblxuXHRcdFx0bGV0IG9sZFdpZHRoID0gdGhpcy5jYW52YXMuY2xpZW50V2lkdGgsIG9sZEhlaWdodCA9IHRoaXMuY2FudmFzLmNsaWVudEhlaWdodDtcblx0XHRcdGxldCBvbGRTdHlsZVdpZHRoID0gdGhpcy5jYW52YXMuc3R5bGUud2lkdGgsIG9sZFN0eWxlSGVpZ2h0ID0gdGhpcy5jYW52YXMuc3R5bGUuaGVpZ2h0O1xuXHRcdFx0bGV0IGlzRnVsbHNjcmVlbiA9IGZhbHNlO1xuXHRcdFx0ZnVsbHNjcmVlbkJ1dHRvbi5vbmNsaWNrID0gKCkgPT4ge1xuXHRcdFx0XHRjb25zdCBmdWxsc2NyZWVuQ2hhbmdlZCA9ICgpID0+IHtcblx0XHRcdFx0XHRpc0Z1bGxzY3JlZW4gPSAhaXNGdWxsc2NyZWVuO1xuXHRcdFx0XHRcdGlmICghaXNGdWxsc2NyZWVuKSB7XG5cdFx0XHRcdFx0XHR0aGlzLmNhbnZhcyEuc3R5bGUud2lkdGggPSBgJHtvbGRXaWR0aH1weGA7XG5cdFx0XHRcdFx0XHR0aGlzLmNhbnZhcyEuc3R5bGUuaGVpZ2h0ID0gYCR7b2xkSGVpZ2h0fXB4YDtcblx0XHRcdFx0XHRcdHRoaXMuZHJhd0ZyYW1lKGZhbHNlKTtcblx0XHRcdFx0XHRcdC8vIEdvdCB0byByZXNldCB0aGUgc3R5bGUgdG8gd2hhdGV2ZXIgdGhlIHVzZXIgc2V0IGFmdGVyIHRoZSBuZXh0IGxheW91dGluZy5cblx0XHRcdFx0XHRcdHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdHRoaXMuY2FudmFzIS5zdHlsZS53aWR0aCA9IG9sZFN0eWxlV2lkdGg7XG5cdFx0XHRcdFx0XHRcdHRoaXMuY2FudmFzIS5zdHlsZS5oZWlnaHQgPSBvbGRTdHlsZUhlaWdodDtcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblxuXHRcdFx0XHRjb25zdCBwbGF5ZXIgPSBkb20gYXMgYW55O1xuXHRcdFx0XHRwbGF5ZXIub25mdWxsc2NyZWVuY2hhbmdlID0gZnVsbHNjcmVlbkNoYW5nZWQ7XG5cdFx0XHRcdHBsYXllci5vbndlYmtpdGZ1bGxzY3JlZW5jaGFuZ2UgPSBmdWxsc2NyZWVuQ2hhbmdlZDtcblxuXHRcdFx0XHRjb25zdCBkb2MgPSBkb2N1bWVudCBhcyBhbnk7XG5cdFx0XHRcdGlmIChkb2MuZnVsbHNjcmVlbkVsZW1lbnQgfHwgZG9jLndlYmtpdEZ1bGxzY3JlZW5FbGVtZW50IHx8IGRvYy5tb3pGdWxsU2NyZWVuRWxlbWVudCB8fCBkb2MubXNGdWxsc2NyZWVuRWxlbWVudCkge1xuXHRcdFx0XHRcdGlmIChkb2MuZXhpdEZ1bGxzY3JlZW4pIGRvYy5leGl0RnVsbHNjcmVlbigpO1xuXHRcdFx0XHRcdGVsc2UgaWYgKGRvYy5tb3pDYW5jZWxGdWxsU2NyZWVuKSBkb2MubW96Q2FuY2VsRnVsbFNjcmVlbigpO1xuXHRcdFx0XHRcdGVsc2UgaWYgKGRvYy53ZWJraXRFeGl0RnVsbHNjcmVlbikgZG9jLndlYmtpdEV4aXRGdWxsc2NyZWVuKClcblx0XHRcdFx0XHRlbHNlIGlmIChkb2MubXNFeGl0RnVsbHNjcmVlbikgZG9jLm1zRXhpdEZ1bGxzY3JlZW4oKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRvbGRXaWR0aCA9IHRoaXMuY2FudmFzIS5jbGllbnRXaWR0aDtcblx0XHRcdFx0XHRvbGRIZWlnaHQgPSB0aGlzLmNhbnZhcyEuY2xpZW50SGVpZ2h0O1xuXHRcdFx0XHRcdG9sZFN0eWxlV2lkdGggPSB0aGlzLmNhbnZhcyEuc3R5bGUud2lkdGg7XG5cdFx0XHRcdFx0b2xkU3R5bGVIZWlnaHQgPSB0aGlzLmNhbnZhcyEuc3R5bGUuaGVpZ2h0O1xuXHRcdFx0XHRcdGlmIChwbGF5ZXIucmVxdWVzdEZ1bGxzY3JlZW4pIHBsYXllci5yZXF1ZXN0RnVsbHNjcmVlbigpO1xuXHRcdFx0XHRcdGVsc2UgaWYgKHBsYXllci53ZWJraXRSZXF1ZXN0RnVsbFNjcmVlbikgcGxheWVyLndlYmtpdFJlcXVlc3RGdWxsU2NyZWVuKCk7XG5cdFx0XHRcdFx0ZWxzZSBpZiAocGxheWVyLm1velJlcXVlc3RGdWxsU2NyZWVuKSBwbGF5ZXIubW96UmVxdWVzdEZ1bGxTY3JlZW4oKTtcblx0XHRcdFx0XHRlbHNlIGlmIChwbGF5ZXIubXNSZXF1ZXN0RnVsbHNjcmVlbikgcGxheWVyLm1zUmVxdWVzdEZ1bGxzY3JlZW4oKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdFx0bG9nb0J1dHRvbi5vbmNsaWNrID0gKCkgPT4gd2luZG93Lm9wZW4oXCJodHRwOi8vZXNvdGVyaWNzb2Z0d2FyZS5jb21cIik7XG5cdFx0fVxuXHRcdHJldHVybiBkb207XG5cdH1cblxuXHRwcml2YXRlIGxvYWRTa2VsZXRvbiAoKSB7XG5cdFx0aWYgKHRoaXMuZXJyb3IpIHJldHVybjtcblxuXHRcdGlmICh0aGlzLmFzc2V0TWFuYWdlciEuaGFzRXJyb3JzKCkpXG5cdFx0XHR0aGlzLnNob3dFcnJvcihgRXJyb3I6IEFzc2V0cyBjb3VsZCBub3QgYmUgbG9hZGVkLlxcbiR7cHJpbnQodGhpcy5hc3NldE1hbmFnZXIhLmdldEVycm9ycygpKX1gKTtcblxuXHRcdGNvbnN0IGNvbmZpZyA9IHRoaXMuY29uZmlnO1xuXG5cdFx0Ly8gQ29uZmlndXJlIGZpbHRlcmluZywgZG9uJ3QgdXNlIG1pcG1hcHMgaW4gV2ViR0wxIGlmIHRoZSBhdGxhcyBwYWdlIGlzIG5vbi1QT1Rcblx0XHRjb25zdCBhdGxhcyA9IHRoaXMuYXNzZXRNYW5hZ2VyIS5yZXF1aXJlKGNvbmZpZy5hdGxhcyEpIGFzIFRleHR1cmVBdGxhcztcblx0XHRjb25zdCBnbCA9IHRoaXMuY29udGV4dCEuZ2wsIGFuaXNvdHJvcGljID0gZ2wuZ2V0RXh0ZW5zaW9uKFwiRVhUX3RleHR1cmVfZmlsdGVyX2FuaXNvdHJvcGljXCIpO1xuXHRcdGNvbnN0IGlzV2ViR0wxID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLlZFUlNJT04pLmluZGV4T2YoXCJXZWJHTCAxLjBcIikgIT09IC0xO1xuXHRcdGZvciAoY29uc3QgcGFnZSBvZiBhdGxhcy5wYWdlcykge1xuXHRcdFx0bGV0IG1pbkZpbHRlciA9IHBhZ2UubWluRmlsdGVyO1xuXHRcdFx0bGV0IHVzZU1pcE1hcHM6IGJvb2xlYW4gPSBjb25maWcubWlwbWFwcyE7XG5cdFx0XHRjb25zdCBpc1BPVCA9IE1hdGhVdGlscy5pc1Bvd2VyT2ZUd28ocGFnZS53aWR0aCkgJiYgTWF0aFV0aWxzLmlzUG93ZXJPZlR3byhwYWdlLmhlaWdodCk7XG5cdFx0XHRpZiAoaXNXZWJHTDEgJiYgIWlzUE9UKSB1c2VNaXBNYXBzID0gZmFsc2U7XG5cblx0XHRcdGlmICh1c2VNaXBNYXBzKSB7XG5cdFx0XHRcdGlmIChhbmlzb3Ryb3BpYykge1xuXHRcdFx0XHRcdGdsLnRleFBhcmFtZXRlcmYoZ2wuVEVYVFVSRV8yRCwgYW5pc290cm9waWMuVEVYVFVSRV9NQVhfQU5JU09UUk9QWV9FWFQsIDgpO1xuXHRcdFx0XHRcdG1pbkZpbHRlciA9IFRleHR1cmVGaWx0ZXIuTWlwTWFwTGluZWFyTGluZWFyO1xuXHRcdFx0XHR9IGVsc2Vcblx0XHRcdFx0XHRtaW5GaWx0ZXIgPSBUZXh0dXJlRmlsdGVyLkxpbmVhcjsgLy8gRG9uJ3QgdXNlIG1pcG1hcHMgd2l0aG91dCBhbmlzb3Ryb3BpYy5cblx0XHRcdFx0cGFnZS50ZXh0dXJlIS5zZXRGaWx0ZXJzKG1pbkZpbHRlciwgVGV4dHVyZUZpbHRlci5OZWFyZXN0KTtcblx0XHRcdH1cblx0XHRcdGlmIChtaW5GaWx0ZXIgIT09IFRleHR1cmVGaWx0ZXIuTmVhcmVzdCAmJiBtaW5GaWx0ZXIgIT09IFRleHR1cmVGaWx0ZXIuTGluZWFyKSAocGFnZS50ZXh0dXJlIGFzIEdMVGV4dHVyZSkudXBkYXRlKHRydWUpO1xuXHRcdH1cblxuXHRcdC8vIExvYWQgc2tlbGV0b24gZGF0YS5cblx0XHRsZXQgc2tlbGV0b25EYXRhOiBTa2VsZXRvbkRhdGE7XG5cdFx0dHJ5IHtcblx0XHRcdGxldCBsb2FkZXI6IGFueSwgZGF0YTogYW55LCBhdHRhY2htZW50TG9hZGVyID0gbmV3IEF0bGFzQXR0YWNobWVudExvYWRlcihhdGxhcyk7XG5cdFx0XHRpZiAoY29uZmlnLnNrZWxldG9uIS5lbmRzV2l0aChcIi5qc29uXCIpKSB7XG5cdFx0XHRcdGRhdGEgPSB0aGlzLmFzc2V0TWFuYWdlciEucmVtb3ZlKGNvbmZpZy5za2VsZXRvbiEpO1xuXHRcdFx0XHRpZiAoIWRhdGEpIHRocm93IG5ldyBFcnJvcihcIkVtcHR5IEpTT04gZGF0YS5cIik7XG5cdFx0XHRcdGlmIChjb25maWcuanNvbkZpZWxkKSB7XG5cdFx0XHRcdFx0ZGF0YSA9IGRhdGFbY29uZmlnLmpzb25GaWVsZF07XG5cdFx0XHRcdFx0aWYgKCFkYXRhKSB0aHJvdyBuZXcgRXJyb3IoYEpTT04gZmllbGQgZG9lcyBub3QgZXhpc3Q6ICR7Y29uZmlnLmpzb25GaWVsZH1gKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRsb2FkZXIgPSBuZXcgU2tlbGV0b25Kc29uKGF0dGFjaG1lbnRMb2FkZXIpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZGF0YSA9IHRoaXMuYXNzZXRNYW5hZ2VyIS5yZW1vdmUoY29uZmlnLnNrZWxldG9uISk7XG5cdFx0XHRcdGxvYWRlciA9IG5ldyBTa2VsZXRvbkJpbmFyeShhdHRhY2htZW50TG9hZGVyKTtcblx0XHRcdH1cblx0XHRcdGxvYWRlci5zY2FsZSA9IGNvbmZpZy5zY2FsZTtcblx0XHRcdHNrZWxldG9uRGF0YSA9IGxvYWRlci5yZWFkU2tlbGV0b25EYXRhKGRhdGEpO1xuXHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdHRoaXMuc2hvd0Vycm9yKGBFcnJvcjogQ291bGQgbm90IGxvYWQgc2tlbGV0b24gZGF0YS5cXG4keyhlIGFzIGFueSkubWVzc2FnZX1gLCBlIGFzIGFueSk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMuc2tlbGV0b24gPSBuZXcgU2tlbGV0b24oc2tlbGV0b25EYXRhKTtcblx0XHRjb25zdCBzdGF0ZURhdGEgPSBuZXcgQW5pbWF0aW9uU3RhdGVEYXRhKHNrZWxldG9uRGF0YSk7XG5cdFx0c3RhdGVEYXRhLmRlZmF1bHRNaXggPSBjb25maWcuZGVmYXVsdE1peCE7XG5cdFx0dGhpcy5hbmltYXRpb25TdGF0ZSA9IG5ldyBBbmltYXRpb25TdGF0ZShzdGF0ZURhdGEpO1xuXG5cdFx0Ly8gQ2hlY2sgaWYgYWxsIGNvbnRyb2wgYm9uZXMgYXJlIGluIHRoZSBza2VsZXRvblxuXHRcdGNvbmZpZy5jb250cm9sQm9uZXMhLmZvckVhY2goYm9uZSA9PiB7XG5cdFx0XHRpZiAoIXNrZWxldG9uRGF0YS5maW5kQm9uZShib25lKSkgdGhpcy5zaG93RXJyb3IoYEVycm9yOiBDb250cm9sIGJvbmUgZG9lcyBub3QgZXhpc3QgaW4gc2tlbGV0b246ICR7Ym9uZX1gKTtcblx0XHR9KVxuXG5cdFx0Ly8gU2V0dXAgc2tpbi5cblx0XHRpZiAoKCFjb25maWcuc2tpbiB8fCAhY29uZmlnLnNraW4ubGVuZ3RoKSAmJiBza2VsZXRvbkRhdGEuc2tpbnMubGVuZ3RoKSBjb25maWcuc2tpbiA9IFtza2VsZXRvbkRhdGEuc2tpbnNbMF0ubmFtZV07XG5cdFx0aWYgKGNvbmZpZy5za2lucyAmJiBjb25maWcuc2tpbiEubGVuZ3RoKSB7XG5cdFx0XHRjb25maWcuc2tpbnMuZm9yRWFjaChza2luID0+IHtcblx0XHRcdFx0aWYgKCF0aGlzLnNrZWxldG9uIS5kYXRhLmZpbmRTa2luKHNraW4pKVxuXHRcdFx0XHRcdHRoaXMuc2hvd0Vycm9yKGBFcnJvcjogU2tpbiBpbiBjb25maWcgbGlzdCBkb2VzIG5vdCBleGlzdCBpbiBza2VsZXRvbjogJHtza2lufWApO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdGNvbnN0IHNraW5MaXN0ID0gY29uZmlnLnNraW4gYXMgc3RyaW5nW107XG5cdFx0aWYgKHNraW5MaXN0Py5sZW5ndGgpIHtcblx0XHRcdGZvciAoY29uc3QgcyBvZiBza2luTGlzdCkge1xuXHRcdFx0XHRpZiAoIXRoaXMuc2tlbGV0b24uZGF0YS5maW5kU2tpbihzKSlcblx0XHRcdFx0XHR0aGlzLnNob3dFcnJvcihgRXJyb3I6IFNraW4gZG9lcyBub3QgZXhpc3QgaW4gc2tlbGV0b246ICR7c31gKTtcblx0XHRcdFx0aWYgKHRoaXMuc2tlbGV0b24uZGF0YS5maW5kU2tpbihzKSAhPT0gdGhpcy5za2VsZXRvbi5kYXRhLmRlZmF1bHRTa2luKVxuXHRcdFx0XHRcdHRoaXMucGlubmVkU2tpbnMuYWRkKHMpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5hcHBseUNvbWJpbmVkU2tpbigpO1xuXHRcdH1cblxuXHRcdC8vIENoZWNrIGlmIGFsbCBhbmltYXRpb25zIGdpdmVuIGEgdmlld3BvcnQgZXhpc3QuXG5cdFx0T2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoY29uZmlnLnZpZXdwb3J0IS5hbmltYXRpb25zKS5mb3JFYWNoKChhbmltYXRpb246IHN0cmluZykgPT4ge1xuXHRcdFx0aWYgKCFza2VsZXRvbkRhdGEuZmluZEFuaW1hdGlvbihhbmltYXRpb24pKVxuXHRcdFx0XHR0aGlzLnNob3dFcnJvcihgRXJyb3I6IEFuaW1hdGlvbiBmb3Igd2hpY2ggYSB2aWV3cG9ydCB3YXMgc3BlY2lmaWVkIGRvZXMgbm90IGV4aXN0IGluIHNrZWxldG9uOiAke2FuaW1hdGlvbn1gKTtcblx0XHR9KTtcblxuXHRcdC8vIFNldHVwIHRoZSBhbmltYXRpb25zIGFmdGVyIHRoZSB2aWV3cG9ydCwgc28gZGVmYXVsdCBib3VuZHMgZG9uJ3QgZ2V0IG1lc3NlZCB1cC5cblx0XHRpZiAoY29uZmlnLmFuaW1hdGlvbnMgJiYgY29uZmlnLmFuaW1hdGlvbnMubGVuZ3RoKSB7XG5cdFx0XHRjb25maWcuYW5pbWF0aW9ucy5mb3JFYWNoKGFuaW1hdGlvbiA9PiB7XG5cdFx0XHRcdGlmICghdGhpcy5za2VsZXRvbiEuZGF0YS5maW5kQW5pbWF0aW9uKGFuaW1hdGlvbikpXG5cdFx0XHRcdFx0dGhpcy5zaG93RXJyb3IoYEVycm9yOiBBbmltYXRpb24gaW4gY29uZmlnIGxpc3QgZG9lcyBub3QgZXhpc3QgaW4gc2tlbGV0b246ICR7YW5pbWF0aW9ufWApO1xuXHRcdFx0fSk7XG5cdFx0XHRpZiAoIWNvbmZpZy5hbmltYXRpb24pIGNvbmZpZy5hbmltYXRpb24gPSBjb25maWcuYW5pbWF0aW9uc1swXTtcblx0XHR9XG5cblx0XHRpZiAoY29uZmlnLmFuaW1hdGlvbiAmJiAhc2tlbGV0b25EYXRhLmZpbmRBbmltYXRpb24oY29uZmlnLmFuaW1hdGlvbikpXG5cdFx0XHR0aGlzLnNob3dFcnJvcihgRXJyb3I6IEFuaW1hdGlvbiBkb2VzIG5vdCBleGlzdCBpbiBza2VsZXRvbjogJHtjb25maWcuYW5pbWF0aW9ufWApO1xuXG5cdFx0Ly8gU2V0dXAgaW5wdXQgcHJvY2Vzc2luZyBhbmQgY29udHJvbCBib25lcy5cblx0XHR0aGlzLnNldHVwSW5wdXQoKTtcblxuXHRcdGlmIChjb25maWcuc2hvd0NvbnRyb2xzKSB7XG5cdFx0XHQvLyBIaWRlIHNraW4gYW5kIGFuaW1hdGlvbiBpZiB0aGVyZSdzIG9ubHkgdGhlIGRlZmF1bHQgc2tpbiAvIG5vIGFuaW1hdGlvblxuXHRcdFx0aWYgKHNrZWxldG9uRGF0YS5za2lucy5sZW5ndGggPT09IDEgfHwgKGNvbmZpZy5za2lucyAmJiBjb25maWcuc2tpbnMubGVuZ3RoID09PSAxKSkgdGhpcy5za2luQnV0dG9uIS5jbGFzc0xpc3QuYWRkKFwic3BpbmUtcGxheWVyLWhpZGRlblwiKTtcblx0XHRcdGlmIChza2VsZXRvbkRhdGEuYW5pbWF0aW9ucy5sZW5ndGggPT09IDEgfHwgKGNvbmZpZy5hbmltYXRpb25zICYmIGNvbmZpZy5hbmltYXRpb25zLmxlbmd0aCA9PT0gMSkpIHRoaXMuYW5pbWF0aW9uQnV0dG9uIS5jbGFzc0xpc3QuYWRkKFwic3BpbmUtcGxheWVyLWhpZGRlblwiKTtcblx0XHR9XG5cblx0XHRpZiAoY29uZmlnLnN1Y2Nlc3MpIGNvbmZpZy5zdWNjZXNzKHRoaXMpO1xuXG5cdFx0bGV0IGVudHJ5ID0gdGhpcy5hbmltYXRpb25TdGF0ZS5nZXRUcmFjaygwKTtcblx0XHRpZiAoIWVudHJ5KSB7XG5cdFx0XHRpZiAoY29uZmlnLmFuaW1hdGlvbikge1xuXHRcdFx0XHRlbnRyeSA9IHRoaXMuc2V0QW5pbWF0aW9uKGNvbmZpZy5hbmltYXRpb24pO1xuXHRcdFx0XHR0aGlzLnBsYXkoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVudHJ5ID0gdGhpcy5hbmltYXRpb25TdGF0ZS5zZXRFbXB0eUFuaW1hdGlvbigwKTtcblx0XHRcdFx0ZW50cnkudHJhY2tFbmQgPSAxMDAwMDAwMDA7XG5cdFx0XHRcdHRoaXMuc2tlbGV0b24udXBkYXRlV29ybGRUcmFuc2Zvcm0oUGh5c2ljcy51cGRhdGUpO1xuXHRcdFx0XHR0aGlzLnNldFZpZXdwb3J0KGVudHJ5LmFuaW1hdGlvbiEpO1xuXHRcdFx0XHR0aGlzLnBhdXNlKCk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGlmICh0aGlzLmN1cnJlbnRWaWV3cG9ydC54ID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0dGhpcy5zZXRWaWV3cG9ydChlbnRyeS5hbmltYXRpb24hKTtcblx0XHRcdH1cblx0XHRcdGlmICghY29uZmlnLmFuaW1hdGlvbikge1xuXHRcdFx0XHRjb25maWcuYW5pbWF0aW9uID0gZW50cnkuYW5pbWF0aW9uPy5uYW1lXG5cdFx0XHR9XG5cdFx0XHR0aGlzLnBsYXkoKTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIHNldHVwSW5wdXQgKCkge1xuXHRcdGNvbnN0IGNvbmZpZyA9IHRoaXMuY29uZmlnO1xuXHRcdGNvbnN0IGNvbnRyb2xCb25lcyA9IGNvbmZpZy5jb250cm9sQm9uZXMhO1xuXHRcdGlmICghY29udHJvbEJvbmVzLmxlbmd0aCAmJiAhY29uZmlnLnNob3dDb250cm9scykgcmV0dXJuO1xuXHRcdGNvbnN0IHNlbGVjdGVkQm9uZXMgPSB0aGlzLnNlbGVjdGVkQm9uZXMgPSBuZXcgQXJyYXk8Qm9uZSB8IG51bGw+KGNvbnRyb2xCb25lcy5sZW5ndGgpO1xuXHRcdGNvbnN0IGNhbnZhcyA9IHRoaXMuY2FudmFzITtcblx0XHRsZXQgdGFyZ2V0OiBCb25lIHwgbnVsbCA9IG51bGw7XG5cdFx0Y29uc3Qgb2Zmc2V0ID0gbmV3IFZlY3RvcjIoKTtcblx0XHRjb25zdCBjb29yZHMgPSBuZXcgVmVjdG9yMygpO1xuXHRcdGNvbnN0IG1vdXNlID0gbmV3IFZlY3RvcjMoKTtcblx0XHRjb25zdCBwb3NpdGlvbiA9IG5ldyBWZWN0b3IyKCk7XG5cdFx0Y29uc3Qgc2tlbGV0b24gPSB0aGlzLnNrZWxldG9uITtcblx0XHRjb25zdCByZW5kZXJlciA9IHRoaXMuc2NlbmVSZW5kZXJlciE7XG5cblx0XHRpZiAoY29uZmlnLmludGVyYWN0aXZlKSB7XG5cdFx0XHRjb25zdCBjbG9zZXN0ID0gKHg6IG51bWJlciwgeTogbnVtYmVyKTogQm9uZSB8IG51bGwgPT4ge1xuXHRcdFx0XHRtb3VzZS5zZXQoeCwgY2FudmFzLmNsaWVudEhlaWdodCAtIHksIDApXG5cdFx0XHRcdG9mZnNldC54ID0gb2Zmc2V0LnkgPSAwO1xuXHRcdFx0XHRsZXQgYmVzdERpc3RhbmNlID0gMjQsIGluZGV4ID0gMDtcblx0XHRcdFx0bGV0IGJlc3Q6IEJvbmUgfCBudWxsID0gbnVsbDtcblx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBjb250cm9sQm9uZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRzZWxlY3RlZEJvbmVzW2ldID0gbnVsbDtcblx0XHRcdFx0XHRjb25zdCBib25lID0gc2tlbGV0b24uZmluZEJvbmUoY29udHJvbEJvbmVzW2ldKTtcblx0XHRcdFx0XHRpZiAoIWJvbmUpIGNvbnRpbnVlO1xuXHRcdFx0XHRcdGNvbnN0IGRpc3RhbmNlID0gcmVuZGVyZXIuY2FtZXJhLndvcmxkVG9TY3JlZW4oXG5cdFx0XHRcdFx0XHRjb29yZHMuc2V0KGJvbmUuYXBwbGllZFBvc2Uud29ybGRYLCBib25lLmFwcGxpZWRQb3NlLndvcmxkWSwgMCksXG5cdFx0XHRcdFx0XHRjYW52YXMuY2xpZW50V2lkdGgsIGNhbnZhcy5jbGllbnRIZWlnaHQpLmRpc3RhbmNlKG1vdXNlKTtcblx0XHRcdFx0XHRpZiAoZGlzdGFuY2UgPCBiZXN0RGlzdGFuY2UpIHtcblx0XHRcdFx0XHRcdGJlc3REaXN0YW5jZSA9IGRpc3RhbmNlO1xuXHRcdFx0XHRcdFx0YmVzdCA9IGJvbmU7XG5cdFx0XHRcdFx0XHRpbmRleCA9IGk7XG5cdFx0XHRcdFx0XHRvZmZzZXQueCA9IGNvb3Jkcy54IC0gbW91c2UueDtcblx0XHRcdFx0XHRcdG9mZnNldC55ID0gY29vcmRzLnkgLSBtb3VzZS55O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoYmVzdCkgc2VsZWN0ZWRCb25lc1tpbmRleF0gPSBiZXN0O1xuXHRcdFx0XHRyZXR1cm4gYmVzdDtcblx0XHRcdH07XG5cblx0XHRcdHRoaXMuaW5wdXQgPSBuZXcgSW5wdXQoY2FudmFzKTtcblx0XHRcdHRoaXMuaW5wdXQuYWRkTGlzdGVuZXIoe1xuXHRcdFx0XHRkb3duOiAoeCwgeSkgPT4ge1xuXHRcdFx0XHRcdHRhcmdldCA9IGNsb3Nlc3QoeCwgeSk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHVwOiAoKSA9PiB7XG5cdFx0XHRcdFx0aWYgKHRhcmdldClcblx0XHRcdFx0XHRcdHRhcmdldCA9IG51bGw7XG5cdFx0XHRcdFx0ZWxzZSBpZiAoY29uZmlnLnNob3dDb250cm9scylcblx0XHRcdFx0XHRcdCh0aGlzLnBhdXNlZCA/IHRoaXMucGxheSgpIDogdGhpcy5wYXVzZSgpKTtcblx0XHRcdFx0fSxcblx0XHRcdFx0ZHJhZ2dlZDogKHgsIHkpID0+IHtcblx0XHRcdFx0XHRpZiAodGFyZ2V0KSB7XG5cdFx0XHRcdFx0XHR4ID0gTWF0aFV0aWxzLmNsYW1wKHggKyBvZmZzZXQueCwgMCwgY2FudmFzLmNsaWVudFdpZHRoKVxuXHRcdFx0XHRcdFx0eSA9IE1hdGhVdGlscy5jbGFtcCh5IC0gb2Zmc2V0LnksIDAsIGNhbnZhcy5jbGllbnRIZWlnaHQpO1xuXHRcdFx0XHRcdFx0cmVuZGVyZXIuY2FtZXJhLnNjcmVlblRvV29ybGQoY29vcmRzLnNldCh4LCB5LCAwKSwgY2FudmFzLmNsaWVudFdpZHRoLCBjYW52YXMuY2xpZW50SGVpZ2h0KTtcblx0XHRcdFx0XHRcdGNvbnN0IGFwcGxpZWQgPSB0YXJnZXQuYXBwbGllZFBvc2U7XG5cdFx0XHRcdFx0XHRpZiAodGFyZ2V0LnBhcmVudCkge1xuXHRcdFx0XHRcdFx0XHR0YXJnZXQucGFyZW50LmFwcGxpZWRQb3NlLndvcmxkVG9Mb2NhbChwb3NpdGlvbi5zZXQoY29vcmRzLnggLSBza2VsZXRvbi54LCBjb29yZHMueSAtIHNrZWxldG9uLnkpKTtcblx0XHRcdFx0XHRcdFx0YXBwbGllZC54ID0gcG9zaXRpb24ueDtcblx0XHRcdFx0XHRcdFx0YXBwbGllZC55ID0gcG9zaXRpb24ueTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGFwcGxpZWQueCA9IGNvb3Jkcy54IC0gc2tlbGV0b24ueDtcblx0XHRcdFx0XHRcdFx0YXBwbGllZC55ID0gY29vcmRzLnkgLSBza2VsZXRvbi55O1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSxcblx0XHRcdFx0bW92ZWQ6ICh4LCB5KSA9PiBjbG9zZXN0KHgsIHkpXG5cdFx0XHR9KTtcblx0XHR9XG5cblxuXHRcdGlmIChjb25maWcuc2hvd0NvbnRyb2xzKSB7XG5cdFx0XHQvLyBGb3IgbWFudWFsIGhvdmVyIHRvIHdvcmssIHdlIG5lZWQgdG8gZGlzYWJsZSBoaWRkaW5nIGNvbnRyb2xzIGlmIHRoZSBtb3VzZS90b3VjaCBlbnRlcmVkIHRoZSBjbGlja2FibGUgYXJlYSBvZiBhIGNoaWxkIG9mIHRoZSBjb250cm9scy5cblx0XHRcdC8vIEZvciB0aGlzIHdlIG5lZWQgdG8gcmVnaXN0ZXIgYSBtb3VzZSBoYW5kbGVyIG9uIHRoZSBkb2N1bWVudCBhbmQgc2VlIGlmIHdlIGFyZSB3aXRoaW4gdGhlIGNhbnZhcyBhcmVhLlxuXHRcdFx0dGhpcy5hZGRFdmVudExpc3RlbmVyKGRvY3VtZW50LCBcIm1vdXNlbW92ZVwiLCAoZXY6IFVJRXZlbnQpID0+IHtcblx0XHRcdFx0aWYgKGV2IGluc3RhbmNlb2YgTW91c2VFdmVudCkgaGFuZGxlSG92ZXIoZXYuY2xpZW50WCwgZXYuY2xpZW50WSk7XG5cdFx0XHR9KTtcblx0XHRcdHRoaXMuYWRkRXZlbnRMaXN0ZW5lcihkb2N1bWVudCwgXCJ0b3VjaG1vdmVcIiwgKGV2OiBVSUV2ZW50KSA9PiB7XG5cdFx0XHRcdGlmIChldiBpbnN0YW5jZW9mIFRvdWNoRXZlbnQpIHtcblx0XHRcdFx0XHRjb25zdCB0b3VjaGVzID0gZXYuY2hhbmdlZFRvdWNoZXM7XG5cdFx0XHRcdFx0aWYgKHRvdWNoZXMubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRjb25zdCB0b3VjaCA9IHRvdWNoZXNbMF07XG5cdFx0XHRcdFx0XHRoYW5kbGVIb3Zlcih0b3VjaC5jbGllbnRYLCB0b3VjaC5jbGllbnRZKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdGNvbnN0IG92ZXJsYXAgPSAobW91c2VYOiBudW1iZXIsIG1vdXNlWTogbnVtYmVyLCByZWN0OiBET01SZWN0IHwgQ2xpZW50UmVjdCk6IGJvb2xlYW4gPT4ge1xuXHRcdFx0XHRjb25zdCB4ID0gbW91c2VYIC0gcmVjdC5sZWZ0LCB5ID0gbW91c2VZIC0gcmVjdC50b3A7XG5cdFx0XHRcdHJldHVybiB4ID49IDAgJiYgeCA8PSByZWN0LndpZHRoICYmIHkgPj0gMCAmJiB5IDw9IHJlY3QuaGVpZ2h0O1xuXHRcdFx0fVxuXG5cdFx0XHRsZXQgbW91c2VPdmVyQ29udHJvbHMgPSB0cnVlLCBtb3VzZU92ZXJDYW52YXMgPSBmYWxzZTtcblx0XHRcdGNvbnN0IGhhbmRsZUhvdmVyID0gKG1vdXNlWDogbnVtYmVyLCBtb3VzZVk6IG51bWJlcikgPT4ge1xuXHRcdFx0XHRjb25zdCBwb3B1cCA9IGZpbmRXaXRoQ2xhc3ModGhpcy5kb20sIFwic3BpbmUtcGxheWVyLXBvcHVwXCIpO1xuXHRcdFx0XHRtb3VzZU92ZXJDb250cm9scyA9IG92ZXJsYXAobW91c2VYLCBtb3VzZVksIHRoaXMucGxheWVyQ29udHJvbHMhLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKTtcblx0XHRcdFx0bW91c2VPdmVyQ2FudmFzID0gb3ZlcmxhcChtb3VzZVgsIG1vdXNlWSwgY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKTtcblx0XHRcdFx0Y2xlYXJUaW1lb3V0KHRoaXMuY2FuY2VsSWQpO1xuXHRcdFx0XHRjb25zdCBoaWRlID0gIXBvcHVwICYmICFtb3VzZU92ZXJDb250cm9scyAmJiAhbW91c2VPdmVyQ2FudmFzICYmICF0aGlzLnBhdXNlZDtcblx0XHRcdFx0aWYgKGhpZGUpXG5cdFx0XHRcdFx0dGhpcy5wbGF5ZXJDb250cm9scyEuY2xhc3NMaXN0LmFkZChcInNwaW5lLXBsYXllci1jb250cm9scy1oaWRkZW5cIik7XG5cdFx0XHRcdGVsc2Vcblx0XHRcdFx0XHR0aGlzLnBsYXllckNvbnRyb2xzIS5jbGFzc0xpc3QucmVtb3ZlKFwic3BpbmUtcGxheWVyLWNvbnRyb2xzLWhpZGRlblwiKTtcblx0XHRcdFx0aWYgKCFtb3VzZU92ZXJDb250cm9scyAmJiAhcG9wdXAgJiYgIXRoaXMucGF1c2VkKSB7XG5cdFx0XHRcdFx0dGhpcy5jYW5jZWxJZCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRcdFx0aWYgKCF0aGlzLnBhdXNlZCkgdGhpcy5wbGF5ZXJDb250cm9scyEuY2xhc3NMaXN0LmFkZChcInNwaW5lLXBsYXllci1jb250cm9scy1oaWRkZW5cIik7XG5cdFx0XHRcdFx0fSwgMTAwMCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRwbGF5ICgpIHtcblx0XHR0aGlzLnBhdXNlZCA9IGZhbHNlO1xuXHRcdGNvbnN0IGNvbmZpZyA9IHRoaXMuY29uZmlnO1xuXHRcdGlmIChjb25maWcuc2hvd0NvbnRyb2xzKSB7XG5cdFx0XHR0aGlzLmNhbmNlbElkID0gc2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRcdGlmICghdGhpcy5wYXVzZWQpIHRoaXMucGxheWVyQ29udHJvbHMhLmNsYXNzTGlzdC5hZGQoXCJzcGluZS1wbGF5ZXItY29udHJvbHMtaGlkZGVuXCIpO1xuXHRcdFx0fSwgMTAwMCk7XG5cdFx0XHR0aGlzLnBsYXlCdXR0b24hLmNsYXNzTGlzdC5yZW1vdmUoXCJzcGluZS1wbGF5ZXItYnV0dG9uLWljb24tcGxheVwiKTtcblx0XHRcdHRoaXMucGxheUJ1dHRvbiEuY2xhc3NMaXN0LmFkZChcInNwaW5lLXBsYXllci1idXR0b24taWNvbi1wYXVzZVwiKTtcblxuXHRcdFx0Ly8gSWYgbm8gY29uZmlnIGFuaW1hdGlvbiwgc2V0IG9uZSB3aGVuIGZpcnN0IGNsaWNrZWQuXG5cdFx0XHRpZiAoIWNvbmZpZy5hbmltYXRpb24pIHtcblx0XHRcdFx0aWYgKGNvbmZpZy5hbmltYXRpb25zICYmIGNvbmZpZy5hbmltYXRpb25zLmxlbmd0aClcblx0XHRcdFx0XHRjb25maWcuYW5pbWF0aW9uID0gY29uZmlnLmFuaW1hdGlvbnNbMF07XG5cdFx0XHRcdGVsc2UgaWYgKHRoaXMuc2tlbGV0b24hLmRhdGEuYW5pbWF0aW9ucy5sZW5ndGgpXG5cdFx0XHRcdFx0Y29uZmlnLmFuaW1hdGlvbiA9IHRoaXMuc2tlbGV0b24hLmRhdGEuYW5pbWF0aW9uc1swXS5uYW1lO1xuXHRcdFx0XHRpZiAoY29uZmlnLmFuaW1hdGlvbikgdGhpcy5zZXRBbmltYXRpb24oY29uZmlnLmFuaW1hdGlvbik7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cGF1c2UgKCkge1xuXHRcdHRoaXMucGF1c2VkID0gdHJ1ZTtcblx0XHRpZiAodGhpcy5jb25maWcuc2hvd0NvbnRyb2xzKSB7XG5cdFx0XHR0aGlzLnBsYXllckNvbnRyb2xzIS5jbGFzc0xpc3QucmVtb3ZlKFwic3BpbmUtcGxheWVyLWNvbnRyb2xzLWhpZGRlblwiKTtcblx0XHRcdGNsZWFyVGltZW91dCh0aGlzLmNhbmNlbElkKTtcblx0XHRcdHRoaXMucGxheUJ1dHRvbiEuY2xhc3NMaXN0LnJlbW92ZShcInNwaW5lLXBsYXllci1idXR0b24taWNvbi1wYXVzZVwiKTtcblx0XHRcdHRoaXMucGxheUJ1dHRvbiEuY2xhc3NMaXN0LmFkZChcInNwaW5lLXBsYXllci1idXR0b24taWNvbi1wbGF5XCIpO1xuXHRcdH1cblx0fVxuXG5cdC8qIFNldHMgYSBuZXcgYW5pbWF0aW9uIGFuZCB2aWV3cG9ydCBvbiB0cmFjayAwLiAqL1xuXHRzZXRBbmltYXRpb24gKGFuaW1hdGlvbjogc3RyaW5nIHwgQW5pbWF0aW9uLCBsb29wOiBib29sZWFuID0gdHJ1ZSk6IFRyYWNrRW50cnkge1xuXHRcdGFuaW1hdGlvbiA9IHRoaXMuc2V0Vmlld3BvcnQoYW5pbWF0aW9uKTtcblx0XHRyZXR1cm4gdGhpcy5hbmltYXRpb25TdGF0ZSEuc2V0QW5pbWF0aW9uKDAsIGFuaW1hdGlvbiwgbG9vcCk7XG5cdH1cblxuXHQvKiBBZGRzIGEgbmV3IGFuaW1hdGlvbiBhbmQgdmlld3BvcnQgb24gdHJhY2sgMC4gKi9cblx0YWRkQW5pbWF0aW9uIChhbmltYXRpb246IHN0cmluZyB8IEFuaW1hdGlvbiwgbG9vcDogYm9vbGVhbiA9IHRydWUsIGRlbGF5OiBudW1iZXIgPSAwKTogVHJhY2tFbnRyeSB7XG5cdFx0YW5pbWF0aW9uID0gdGhpcy5zZXRWaWV3cG9ydChhbmltYXRpb24pO1xuXHRcdHJldHVybiB0aGlzLmFuaW1hdGlvblN0YXRlIS5hZGRBbmltYXRpb24oMCwgYW5pbWF0aW9uLCBsb29wLCBkZWxheSk7XG5cdH1cblxuXHQvKiBTZXRzIHRoZSB2aWV3cG9ydCBmb3IgdGhlIHNwZWNpZmllZCBhbmltYXRpb24uICovXG5cdHNldFZpZXdwb3J0IChhbmltYXRpb246IHN0cmluZyB8IEFuaW1hdGlvbik6IEFuaW1hdGlvbiB7XG5cdFx0aWYgKHR5cGVvZiBhbmltYXRpb24gPT09IFwic3RyaW5nXCIpIHtcblx0XHRcdGNvbnN0IGZvdW5kQW5pbWF0aW9uID0gdGhpcy5za2VsZXRvbiEuZGF0YS5maW5kQW5pbWF0aW9uKGFuaW1hdGlvbik7XG5cdFx0XHRpZiAoIWZvdW5kQW5pbWF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoYEFuaW1hdGlvbiBub3QgZm91bmQ6ICR7YW5pbWF0aW9ufWApO1xuXHRcdFx0YW5pbWF0aW9uID0gZm91bmRBbmltYXRpb247XG5cdFx0fVxuXG5cdFx0dGhpcy5wcmV2aW91c1ZpZXdwb3J0ID0gdGhpcy5jdXJyZW50Vmlld3BvcnQ7XG5cblx0XHQvLyBEZXRlcm1pbmUgdGhlIGJhc2Ugdmlld3BvcnQuXG5cdFx0Y29uc3QgZ2xvYmFsVmlld3BvcnQgPSB0aGlzLmNvbmZpZy52aWV3cG9ydCE7XG5cdFx0Y29uc3Qgdmlld3BvcnQgPSB0aGlzLmN1cnJlbnRWaWV3cG9ydCA9IHtcblx0XHRcdGNsaXA6IGdsb2JhbFZpZXdwb3J0LmNsaXAsXG5cdFx0XHRwYWRMZWZ0OiBnbG9iYWxWaWV3cG9ydC5wYWRMZWZ0ICE9PSB2b2lkIDAgPyBnbG9iYWxWaWV3cG9ydC5wYWRMZWZ0IDogXCIxMCVcIixcblx0XHRcdHBhZFJpZ2h0OiBnbG9iYWxWaWV3cG9ydC5wYWRSaWdodCAhPT0gdm9pZCAwID8gZ2xvYmFsVmlld3BvcnQucGFkUmlnaHQgOiBcIjEwJVwiLFxuXHRcdFx0cGFkVG9wOiBnbG9iYWxWaWV3cG9ydC5wYWRUb3AgIT09IHZvaWQgMCA/IGdsb2JhbFZpZXdwb3J0LnBhZFRvcCA6IFwiMTAlXCIsXG5cdFx0XHRwYWRCb3R0b206IGdsb2JhbFZpZXdwb3J0LnBhZEJvdHRvbSAhPT0gdm9pZCAwID8gZ2xvYmFsVmlld3BvcnQucGFkQm90dG9tIDogXCIxMCVcIlxuXHRcdH0gYXMgVmlld3BvcnQ7XG5cdFx0aWYgKGdsb2JhbFZpZXdwb3J0LnggIT09IHZvaWQgMCAmJiBnbG9iYWxWaWV3cG9ydC55ICE9PSB2b2lkIDAgJiYgZ2xvYmFsVmlld3BvcnQud2lkdGggJiYgZ2xvYmFsVmlld3BvcnQuaGVpZ2h0KSB7XG5cdFx0XHR2aWV3cG9ydC54ID0gZ2xvYmFsVmlld3BvcnQueDtcblx0XHRcdHZpZXdwb3J0LnkgPSBnbG9iYWxWaWV3cG9ydC55O1xuXHRcdFx0dmlld3BvcnQud2lkdGggPSBnbG9iYWxWaWV3cG9ydC53aWR0aDtcblx0XHRcdHZpZXdwb3J0LmhlaWdodCA9IGdsb2JhbFZpZXdwb3J0LmhlaWdodDtcblx0XHR9IGVsc2Vcblx0XHRcdHRoaXMuY2FsY3VsYXRlQW5pbWF0aW9uVmlld3BvcnQoYW5pbWF0aW9uLCB2aWV3cG9ydCk7XG5cblx0XHQvLyBPdmVycmlkZSB3aXRoIHRoZSBhbmltYXRpb24gc3BlY2lmaWMgdmlld3BvcnQgZm9yIHRoZSBmaW5hbCByZXN1bHQuXG5cdFx0Y29uc3QgdXNlckFuaW1WaWV3cG9ydCA9IHRoaXMuY29uZmlnLnZpZXdwb3J0IS5hbmltYXRpb25zIVthbmltYXRpb24ubmFtZV07XG5cdFx0aWYgKHVzZXJBbmltVmlld3BvcnQpIHtcblx0XHRcdGlmICh1c2VyQW5pbVZpZXdwb3J0LnggIT09IHZvaWQgMCAmJiB1c2VyQW5pbVZpZXdwb3J0LnkgIT09IHZvaWQgMCAmJiB1c2VyQW5pbVZpZXdwb3J0LndpZHRoICYmIHVzZXJBbmltVmlld3BvcnQuaGVpZ2h0KSB7XG5cdFx0XHRcdHZpZXdwb3J0LnggPSB1c2VyQW5pbVZpZXdwb3J0Lng7XG5cdFx0XHRcdHZpZXdwb3J0LnkgPSB1c2VyQW5pbVZpZXdwb3J0Lnk7XG5cdFx0XHRcdHZpZXdwb3J0LndpZHRoID0gdXNlckFuaW1WaWV3cG9ydC53aWR0aDtcblx0XHRcdFx0dmlld3BvcnQuaGVpZ2h0ID0gdXNlckFuaW1WaWV3cG9ydC5oZWlnaHQ7XG5cdFx0XHR9XG5cdFx0XHRpZiAodXNlckFuaW1WaWV3cG9ydC5jbGlwICE9PSB2b2lkIDApIHZpZXdwb3J0LmNsaXAgPSB1c2VyQW5pbVZpZXdwb3J0LmNsaXA7XG5cdFx0XHRpZiAodXNlckFuaW1WaWV3cG9ydC5wYWRMZWZ0ICE9PSB2b2lkIDApIHZpZXdwb3J0LnBhZExlZnQgPSB1c2VyQW5pbVZpZXdwb3J0LnBhZExlZnQ7XG5cdFx0XHRpZiAodXNlckFuaW1WaWV3cG9ydC5wYWRSaWdodCAhPT0gdm9pZCAwKSB2aWV3cG9ydC5wYWRSaWdodCA9IHVzZXJBbmltVmlld3BvcnQucGFkUmlnaHQ7XG5cdFx0XHRpZiAodXNlckFuaW1WaWV3cG9ydC5wYWRUb3AgIT09IHZvaWQgMCkgdmlld3BvcnQucGFkVG9wID0gdXNlckFuaW1WaWV3cG9ydC5wYWRUb3A7XG5cdFx0XHRpZiAodXNlckFuaW1WaWV3cG9ydC5wYWRCb3R0b20gIT09IHZvaWQgMCkgdmlld3BvcnQucGFkQm90dG9tID0gdXNlckFuaW1WaWV3cG9ydC5wYWRCb3R0b207XG5cdFx0fVxuXG5cdFx0Ly8gVHJhbnNsYXRlIHBlcmNlbnRhZ2UgcGFkZGluZyB0byB3b3JsZCB1bml0cy5cblx0XHR2aWV3cG9ydC5wYWRMZWZ0ID0gdGhpcy5wZXJjZW50YWdlVG9Xb3JsZFVuaXQodmlld3BvcnQud2lkdGgsIHZpZXdwb3J0LnBhZExlZnQpO1xuXHRcdHZpZXdwb3J0LnBhZFJpZ2h0ID0gdGhpcy5wZXJjZW50YWdlVG9Xb3JsZFVuaXQodmlld3BvcnQud2lkdGgsIHZpZXdwb3J0LnBhZFJpZ2h0KTtcblx0XHR2aWV3cG9ydC5wYWRCb3R0b20gPSB0aGlzLnBlcmNlbnRhZ2VUb1dvcmxkVW5pdCh2aWV3cG9ydC5oZWlnaHQsIHZpZXdwb3J0LnBhZEJvdHRvbSk7XG5cdFx0dmlld3BvcnQucGFkVG9wID0gdGhpcy5wZXJjZW50YWdlVG9Xb3JsZFVuaXQodmlld3BvcnQuaGVpZ2h0LCB2aWV3cG9ydC5wYWRUb3ApO1xuXG5cdFx0dGhpcy52aWV3cG9ydFRyYW5zaXRpb25TdGFydCA9IHBlcmZvcm1hbmNlLm5vdygpO1xuXHRcdHJldHVybiBhbmltYXRpb247XG5cdH1cblxuXHRwcml2YXRlIHBlcmNlbnRhZ2VUb1dvcmxkVW5pdCAoc2l6ZTogbnVtYmVyLCBwZXJjZW50YWdlT3JBYnNvbHV0ZTogc3RyaW5nIHwgbnVtYmVyKTogbnVtYmVyIHtcblx0XHRpZiAodHlwZW9mIHBlcmNlbnRhZ2VPckFic29sdXRlID09PSBcInN0cmluZ1wiKVxuXHRcdFx0cmV0dXJuIHNpemUgKiBwYXJzZUZsb2F0KHBlcmNlbnRhZ2VPckFic29sdXRlLnNsaWNlKDAsIC0xKSkgLyAxMDA7XG5cdFx0cmV0dXJuIHBlcmNlbnRhZ2VPckFic29sdXRlO1xuXHR9XG5cblx0cHJpdmF0ZSBjYWxjdWxhdGVBbmltYXRpb25WaWV3cG9ydCAoYW5pbWF0aW9uOiBBbmltYXRpb24sIHZpZXdwb3J0OiBWaWV3cG9ydCkge1xuXHRcdHRoaXMuc2tlbGV0b24hLnNldHVwUG9zZSgpO1xuXG5cdFx0bGV0IHN0ZXBzID0gMTAwLCBzdGVwVGltZSA9IGFuaW1hdGlvbi5kdXJhdGlvbiA/IGFuaW1hdGlvbi5kdXJhdGlvbiAvIHN0ZXBzIDogMCwgdGltZSA9IDA7XG5cdFx0bGV0IG1pblggPSAxMDAwMDAwMDAsIG1heFggPSAtMTAwMDAwMDAwLCBtaW5ZID0gMTAwMDAwMDAwLCBtYXhZID0gLTEwMDAwMDAwMDtcblx0XHRjb25zdCBvZmZzZXQgPSBuZXcgVmVjdG9yMigpLCBzaXplID0gbmV3IFZlY3RvcjIoKTtcblxuXHRcdGNvbnN0IHRlbXBBcnJheSA9IFswLCAwXTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHN0ZXBzOyBpKyssIHRpbWUgKz0gc3RlcFRpbWUpIHtcblx0XHRcdGFuaW1hdGlvbi5hcHBseSh0aGlzLnNrZWxldG9uISwgdGltZSwgdGltZSwgZmFsc2UsIFtdLCAxLCBNaXhGcm9tLnNldHVwLCBmYWxzZSwgZmFsc2UsIGZhbHNlKTtcblx0XHRcdHRoaXMuc2tlbGV0b24hLnVwZGF0ZVdvcmxkVHJhbnNmb3JtKFBoeXNpY3MudXBkYXRlKTtcblx0XHRcdHRoaXMuc2tlbGV0b24hLmdldEJvdW5kcyhvZmZzZXQsIHNpemUsIHRlbXBBcnJheSwgdGhpcy5zY2VuZVJlbmRlcmVyIS5za2VsZXRvblJlbmRlcmVyLmdldFNrZWxldG9uQ2xpcHBpbmcoKSk7XG5cblx0XHRcdGlmIChOdW1iZXIuaXNGaW5pdGUob2Zmc2V0LngpICYmIE51bWJlci5pc0Zpbml0ZShvZmZzZXQueSkgJiYgTnVtYmVyLmlzRmluaXRlKHNpemUueCkgJiYgTnVtYmVyLmlzRmluaXRlKHNpemUueSkpIHtcblx0XHRcdFx0bWluWCA9IE1hdGgubWluKG9mZnNldC54LCBtaW5YKTtcblx0XHRcdFx0bWF4WCA9IE1hdGgubWF4KG9mZnNldC54ICsgc2l6ZS54LCBtYXhYKTtcblx0XHRcdFx0bWluWSA9IE1hdGgubWluKG9mZnNldC55LCBtaW5ZKTtcblx0XHRcdFx0bWF4WSA9IE1hdGgubWF4KG9mZnNldC55ICsgc2l6ZS55LCBtYXhZKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR2aWV3cG9ydC54ID0gbWluWDtcblx0XHR2aWV3cG9ydC55ID0gbWluWTtcblx0XHR2aWV3cG9ydC53aWR0aCA9IG1heFggLSBtaW5YO1xuXHRcdHZpZXdwb3J0LmhlaWdodCA9IG1heFkgLSBtaW5ZO1xuXG5cdFx0aWYgKCFOdW1iZXIuaXNGaW5pdGUodmlld3BvcnQud2lkdGgpIHx8ICFOdW1iZXIuaXNGaW5pdGUodmlld3BvcnQuaGVpZ2h0KSlcblx0XHRcdHRoaXMuc2hvd0Vycm9yKGBBbmltYXRpb24gYm91bmRzIGFyZSBpbnZhbGlkOiAke2FuaW1hdGlvbi5uYW1lfWApO1xuXHR9XG5cblx0cHJpdmF0ZSBkcmF3RnJhbWUgKHJlcXVlc3ROZXh0RnJhbWUgPSB0cnVlKSB7XG5cdFx0dHJ5IHtcblx0XHRcdGlmICh0aGlzLmVycm9yKSByZXR1cm47XG5cdFx0XHRpZiAodGhpcy5kaXNwb3NlZCkgcmV0dXJuO1xuXHRcdFx0aWYgKHJlcXVlc3ROZXh0RnJhbWUgJiYgIXRoaXMuc3RvcFJlcXVlc3RBbmltYXRpb25GcmFtZSkgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHRoaXMuZHJhd0ZyYW1lKCkpO1xuXG5cdFx0XHRjb25zdCBkb2MgPSBkb2N1bWVudCBhcyBhbnk7XG5cdFx0XHRjb25zdCBpc0Z1bGxzY3JlZW4gPSBkb2MuZnVsbHNjcmVlbkVsZW1lbnQgfHwgZG9jLndlYmtpdEZ1bGxzY3JlZW5FbGVtZW50IHx8IGRvYy5tb3pGdWxsU2NyZWVuRWxlbWVudCB8fCBkb2MubXNGdWxsc2NyZWVuRWxlbWVudDtcblx0XHRcdGNvbnN0IGJnID0gaXNGdWxsc2NyZWVuID8gdGhpcy5iZ0Z1bGxzY3JlZW4gOiB0aGlzLmJnO1xuXG5cdFx0XHR0aGlzLnRpbWUudXBkYXRlKCk7XG5cdFx0XHRjb25zdCBkZWx0YSA9IHRoaXMudGltZS5kZWx0YTtcblxuXHRcdFx0Ly8gTG9hZCB0aGUgc2tlbGV0b24gaWYgdGhlIGFzc2V0cyBhcmUgcmVhZHkuXG5cdFx0XHRjb25zdCBsb2FkaW5nID0gIXRoaXMuYXNzZXRNYW5hZ2VyIS5pc0xvYWRpbmdDb21wbGV0ZSgpO1xuXHRcdFx0aWYgKCF0aGlzLnNrZWxldG9uICYmICFsb2FkaW5nKSB0aGlzLmxvYWRTa2VsZXRvbigpO1xuXHRcdFx0Y29uc3Qgc2tlbGV0b24gPSB0aGlzLnNrZWxldG9uITtcblx0XHRcdGNvbnN0IGNvbmZpZyA9IHRoaXMuY29uZmlnITtcblx0XHRcdGlmIChza2VsZXRvbikge1xuXHRcdFx0XHRjb25zdCBwbGF5RGVsdGEgPSB0aGlzLnBhdXNlZCA/IDAgOiBkZWx0YSAqIHRoaXMuc3BlZWQ7XG5cdFx0XHRcdGlmIChjb25maWcuZnJhbWUpIGNvbmZpZy5mcmFtZSh0aGlzLCBwbGF5RGVsdGEpO1xuXG5cdFx0XHRcdC8vIFVwZGF0ZSBhbmltYXRpb24gdGltZSBhbmQgcG9zZSB0aGUgc2tlbGV0b24uXG5cdFx0XHRcdGlmICghdGhpcy5wYXVzZWQpIHtcblx0XHRcdFx0XHRza2VsZXRvbi51cGRhdGUocGxheURlbHRhKTtcblx0XHRcdFx0XHR0aGlzLmFuaW1hdGlvblN0YXRlIS51cGRhdGUocGxheURlbHRhKTtcblx0XHRcdFx0XHR0aGlzLmFuaW1hdGlvblN0YXRlIS5hcHBseShza2VsZXRvbik7XG5cdFx0XHRcdFx0aWYgKGNvbmZpZy51cGRhdGVXb3JsZFRyYW5zZm9ybSlcblx0XHRcdFx0XHRcdGNvbmZpZy51cGRhdGVXb3JsZFRyYW5zZm9ybSh0aGlzLCBwbGF5RGVsdGEpO1xuXHRcdFx0XHRcdGVsc2Vcblx0XHRcdFx0XHRcdHNrZWxldG9uLnVwZGF0ZVdvcmxkVHJhbnNmb3JtKFBoeXNpY3MudXBkYXRlKTtcblxuXHRcdFx0XHRcdGlmIChjb25maWcuc2hvd0NvbnRyb2xzKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnBsYXlUaW1lICs9IHBsYXlEZWx0YTtcblx0XHRcdFx0XHRcdGNvbnN0IGVudHJ5ID0gdGhpcy5hbmltYXRpb25TdGF0ZSEuZ2V0VHJhY2soMCk7XG5cdFx0XHRcdFx0XHRpZiAoZW50cnkpIHtcblx0XHRcdFx0XHRcdFx0Y29uc3QgZHVyYXRpb24gPSBlbnRyeS5hbmltYXRpb24hLmR1cmF0aW9uO1xuXHRcdFx0XHRcdFx0XHR3aGlsZSAodGhpcy5wbGF5VGltZSA+PSBkdXJhdGlvbiAmJiBkdXJhdGlvbiAhPT0gMClcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnBsYXlUaW1lIC09IGR1cmF0aW9uO1xuXHRcdFx0XHRcdFx0XHR0aGlzLnBsYXlUaW1lID0gTWF0aC5tYXgoMCwgTWF0aC5taW4odGhpcy5wbGF5VGltZSwgZHVyYXRpb24pKTtcblx0XHRcdFx0XHRcdFx0dGhpcy50aW1lbGluZVNsaWRlciEuc2V0VmFsdWUodGhpcy5wbGF5VGltZSAvIGR1cmF0aW9uKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBEZXRlcm1pbmUgdGhlIHZpZXdwb3J0LlxuXHRcdFx0XHRjb25zdCB2aWV3cG9ydCA9IHRoaXMudmlld3BvcnQ7XG5cdFx0XHRcdHZpZXdwb3J0LnggPSB0aGlzLmN1cnJlbnRWaWV3cG9ydC54IC0gKHRoaXMuY3VycmVudFZpZXdwb3J0LnBhZExlZnQgYXMgbnVtYmVyKTtcblx0XHRcdFx0dmlld3BvcnQueSA9IHRoaXMuY3VycmVudFZpZXdwb3J0LnkgLSAodGhpcy5jdXJyZW50Vmlld3BvcnQucGFkQm90dG9tIGFzIG51bWJlcik7XG5cdFx0XHRcdHZpZXdwb3J0LndpZHRoID0gdGhpcy5jdXJyZW50Vmlld3BvcnQud2lkdGggKyAodGhpcy5jdXJyZW50Vmlld3BvcnQucGFkTGVmdCBhcyBudW1iZXIpICsgKHRoaXMuY3VycmVudFZpZXdwb3J0LnBhZFJpZ2h0IGFzIG51bWJlcik7XG5cdFx0XHRcdHZpZXdwb3J0LmhlaWdodCA9IHRoaXMuY3VycmVudFZpZXdwb3J0LmhlaWdodCArICh0aGlzLmN1cnJlbnRWaWV3cG9ydC5wYWRCb3R0b20gYXMgbnVtYmVyKSArICh0aGlzLmN1cnJlbnRWaWV3cG9ydC5wYWRUb3AgYXMgbnVtYmVyKTtcblxuXHRcdFx0XHRpZiAodGhpcy5wcmV2aW91c1ZpZXdwb3J0KSB7XG5cdFx0XHRcdFx0Y29uc3QgdHJhbnNpdGlvbkFscGhhID0gKHBlcmZvcm1hbmNlLm5vdygpIC0gdGhpcy52aWV3cG9ydFRyYW5zaXRpb25TdGFydCkgLyAxMDAwIC8gY29uZmlnLnZpZXdwb3J0IS50cmFuc2l0aW9uVGltZSE7XG5cdFx0XHRcdFx0aWYgKHRyYW5zaXRpb25BbHBoYSA8IDEpIHtcblx0XHRcdFx0XHRcdGNvbnN0IHggPSB0aGlzLnByZXZpb3VzVmlld3BvcnQueCAtICh0aGlzLnByZXZpb3VzVmlld3BvcnQucGFkTGVmdCBhcyBudW1iZXIpO1xuXHRcdFx0XHRcdFx0Y29uc3QgeSA9IHRoaXMucHJldmlvdXNWaWV3cG9ydC55IC0gKHRoaXMucHJldmlvdXNWaWV3cG9ydC5wYWRCb3R0b20gYXMgbnVtYmVyKTtcblx0XHRcdFx0XHRcdGNvbnN0IHdpZHRoID0gdGhpcy5wcmV2aW91c1ZpZXdwb3J0LndpZHRoICsgKHRoaXMucHJldmlvdXNWaWV3cG9ydC5wYWRMZWZ0IGFzIG51bWJlcikgKyAodGhpcy5wcmV2aW91c1ZpZXdwb3J0LnBhZFJpZ2h0IGFzIG51bWJlcik7XG5cdFx0XHRcdFx0XHRjb25zdCBoZWlnaHQgPSB0aGlzLnByZXZpb3VzVmlld3BvcnQuaGVpZ2h0ICsgKHRoaXMucHJldmlvdXNWaWV3cG9ydC5wYWRCb3R0b20gYXMgbnVtYmVyKSArICh0aGlzLnByZXZpb3VzVmlld3BvcnQucGFkVG9wIGFzIG51bWJlcik7XG5cdFx0XHRcdFx0XHR2aWV3cG9ydC54ID0geCArICh2aWV3cG9ydC54IC0geCkgKiB0cmFuc2l0aW9uQWxwaGE7XG5cdFx0XHRcdFx0XHR2aWV3cG9ydC55ID0geSArICh2aWV3cG9ydC55IC0geSkgKiB0cmFuc2l0aW9uQWxwaGE7XG5cdFx0XHRcdFx0XHR2aWV3cG9ydC53aWR0aCA9IHdpZHRoICsgKHZpZXdwb3J0LndpZHRoIC0gd2lkdGgpICogdHJhbnNpdGlvbkFscGhhO1xuXHRcdFx0XHRcdFx0dmlld3BvcnQuaGVpZ2h0ID0gaGVpZ2h0ICsgKHZpZXdwb3J0LmhlaWdodCAtIGhlaWdodCkgKiB0cmFuc2l0aW9uQWxwaGE7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Y29uc3QgcmVuZGVyZXIgPSB0aGlzLnNjZW5lUmVuZGVyZXIhO1xuXHRcdFx0XHRyZW5kZXJlci5jYW1lcmEuem9vbSA9IHRoaXMuY2FudmFzIS5oZWlnaHQgLyB0aGlzLmNhbnZhcyEud2lkdGggPiB2aWV3cG9ydC5oZWlnaHQgLyB2aWV3cG9ydC53aWR0aFxuXHRcdFx0XHRcdD8gdmlld3BvcnQud2lkdGggLyB0aGlzLmNhbnZhcyEud2lkdGggOiB2aWV3cG9ydC5oZWlnaHQgLyB0aGlzLmNhbnZhcyEuaGVpZ2h0O1xuXHRcdFx0XHRyZW5kZXJlci5jYW1lcmEucG9zaXRpb24ueCA9IHZpZXdwb3J0LnggKyB2aWV3cG9ydC53aWR0aCAvIDI7XG5cdFx0XHRcdHJlbmRlcmVyLmNhbWVyYS5wb3NpdGlvbi55ID0gdmlld3BvcnQueSArIHZpZXdwb3J0LmhlaWdodCAvIDI7XG5cblx0XHRcdFx0Ly8gUmVzaXplIHRoZSBjYW52YXMuXG5cdFx0XHRcdHJlbmRlcmVyLnJlc2l6ZSh0aGlzLmN1cnJlbnRWaWV3cG9ydC5jbGlwID8gUmVzaXplTW9kZS5GaXRDbGlwIDogUmVzaXplTW9kZS5FeHBhbmQsIHZpZXdwb3J0LndpZHRoLCB2aWV3cG9ydC5oZWlnaHQpO1xuXG5cdFx0XHRcdC8vIENsZWFyIHRoZSBzY3JlZW4uXG5cdFx0XHRcdGNvbnN0IGdsID0gdGhpcy5jb250ZXh0IS5nbDtcblx0XHRcdFx0Z2wuY2xlYXJDb2xvcihiZy5yLCBiZy5nLCBiZy5iLCBiZy5hKTtcblx0XHRcdFx0Z2wuY2xlYXIoZ2wuQ09MT1JfQlVGRkVSX0JJVCk7XG5cblx0XHRcdFx0aWYgKGNvbmZpZy51cGRhdGUpIGNvbmZpZy51cGRhdGUodGhpcywgcGxheURlbHRhKTtcblxuXHRcdFx0XHRyZW5kZXJlci5iZWdpbigpO1xuXG5cdFx0XHRcdC8vIERyYXcgdGhlIGJhY2tncm91bmQgaW1hZ2UuXG5cdFx0XHRcdGNvbnN0IGJnSW1hZ2UgPSBjb25maWcuYmFja2dyb3VuZEltYWdlO1xuXHRcdFx0XHRpZiAoYmdJbWFnZSkge1xuXHRcdFx0XHRcdGNvbnN0IHRleHR1cmUgPSB0aGlzLmFzc2V0TWFuYWdlciEucmVxdWlyZShiZ0ltYWdlLnVybCkgYXMgR0xUZXh0dXJlO1xuXHRcdFx0XHRcdGlmIChiZ0ltYWdlLnggIT09IHZvaWQgMCAmJiBiZ0ltYWdlLnkgIT09IHZvaWQgMCAmJiBiZ0ltYWdlLndpZHRoICYmIGJnSW1hZ2UuaGVpZ2h0KVxuXHRcdFx0XHRcdFx0cmVuZGVyZXIuZHJhd1RleHR1cmUodGV4dHVyZSwgYmdJbWFnZS54LCBiZ0ltYWdlLnksIGJnSW1hZ2Uud2lkdGgsIGJnSW1hZ2UuaGVpZ2h0KTtcblx0XHRcdFx0XHRlbHNlXG5cdFx0XHRcdFx0XHRyZW5kZXJlci5kcmF3VGV4dHVyZSh0ZXh0dXJlLCB2aWV3cG9ydC54LCB2aWV3cG9ydC55LCB2aWV3cG9ydC53aWR0aCwgdmlld3BvcnQuaGVpZ2h0KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIERyYXcgdGhlIHNrZWxldG9uIGFuZCBkZWJ1ZyBvdXRwdXQuXG5cdFx0XHRcdHJlbmRlcmVyLmRyYXdTa2VsZXRvbihza2VsZXRvbik7XG5cdFx0XHRcdGNvbnN0IGRlYnVnID0gY29uZmlnLmRlYnVnIGFzIGFueTtcblx0XHRcdFx0aWYgKE51bWJlcihyZW5kZXJlci5za2VsZXRvbkRlYnVnUmVuZGVyZXIuZHJhd0JvbmVzID0gZGVidWcuYm9uZXMpXG5cdFx0XHRcdFx0KyBOdW1iZXIocmVuZGVyZXIuc2tlbGV0b25EZWJ1Z1JlbmRlcmVyLmRyYXdCb3VuZGluZ0JveGVzID0gZGVidWcuYm91bmRzKVxuXHRcdFx0XHRcdCsgTnVtYmVyKHJlbmRlcmVyLnNrZWxldG9uRGVidWdSZW5kZXJlci5kcmF3Q2xpcHBpbmcgPSBkZWJ1Zy5jbGlwcGluZylcblx0XHRcdFx0XHQrIE51bWJlcihyZW5kZXJlci5za2VsZXRvbkRlYnVnUmVuZGVyZXIuZHJhd01lc2hIdWxsID0gZGVidWcuaHVsbHMpXG5cdFx0XHRcdFx0KyBOdW1iZXIocmVuZGVyZXIuc2tlbGV0b25EZWJ1Z1JlbmRlcmVyLmRyYXdQYXRocyA9IGRlYnVnLnBhdGhzKVxuXHRcdFx0XHRcdCsgTnVtYmVyKHJlbmRlcmVyLnNrZWxldG9uRGVidWdSZW5kZXJlci5kcmF3UmVnaW9uQXR0YWNobWVudHMgPSBkZWJ1Zy5yZWdpb25zKVxuXHRcdFx0XHRcdCsgTnVtYmVyKHJlbmRlcmVyLnNrZWxldG9uRGVidWdSZW5kZXJlci5kcmF3TWVzaFRyaWFuZ2xlcyA9IGRlYnVnLm1lc2hlcykgPiAwXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdHJlbmRlcmVyLmRyYXdTa2VsZXRvbkRlYnVnKHNrZWxldG9uKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIERyYXcgdGhlIGNvbnRyb2wgYm9uZXMuXG5cdFx0XHRcdGNvbnN0IGNvbnRyb2xCb25lcyA9IGNvbmZpZy5jb250cm9sQm9uZXMhO1xuXHRcdFx0XHRpZiAoY29udHJvbEJvbmVzLmxlbmd0aCkge1xuXHRcdFx0XHRcdGNvbnN0IHNlbGVjdGVkQm9uZXMgPSB0aGlzLnNlbGVjdGVkQm9uZXM7XG5cdFx0XHRcdFx0Z2wubGluZVdpZHRoKDIpO1xuXHRcdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgY29udHJvbEJvbmVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0XHRjb25zdCBib25lID0gc2tlbGV0b24uZmluZEJvbmUoY29udHJvbEJvbmVzW2ldKTtcblx0XHRcdFx0XHRcdGlmICghYm9uZSkgY29udGludWU7XG5cdFx0XHRcdFx0XHRjb25zdCBjb2xvcklubmVyID0gc2VsZWN0ZWRCb25lc1tpXSA/IEJPTkVfSU5ORVJfT1ZFUiA6IEJPTkVfSU5ORVI7XG5cdFx0XHRcdFx0XHRjb25zdCBjb2xvck91dGVyID0gc2VsZWN0ZWRCb25lc1tpXSA/IEJPTkVfT1VURVJfT1ZFUiA6IEJPTkVfT1VURVI7XG5cdFx0XHRcdFx0XHRjb25zdCBhcHBsaWVkID0gYm9uZS5hcHBsaWVkUG9zZTtcblx0XHRcdFx0XHRcdHJlbmRlcmVyLmNpcmNsZSh0cnVlLCBza2VsZXRvbi54ICsgYXBwbGllZC53b3JsZFgsIHNrZWxldG9uLnkgKyBhcHBsaWVkLndvcmxkWSwgMjAsIGNvbG9ySW5uZXIpO1xuXHRcdFx0XHRcdFx0cmVuZGVyZXIuY2lyY2xlKGZhbHNlLCBza2VsZXRvbi54ICsgYXBwbGllZC53b3JsZFgsIHNrZWxldG9uLnkgKyBhcHBsaWVkLndvcmxkWSwgMjAsIGNvbG9yT3V0ZXIpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIERyYXcgdGhlIHZpZXdwb3J0IGJvdW5kcy5cblx0XHRcdFx0aWYgKGNvbmZpZy52aWV3cG9ydCEuZGVidWdSZW5kZXIpIHtcblx0XHRcdFx0XHRnbC5saW5lV2lkdGgoMSk7XG5cdFx0XHRcdFx0cmVuZGVyZXIucmVjdChmYWxzZSwgdGhpcy5jdXJyZW50Vmlld3BvcnQueCwgdGhpcy5jdXJyZW50Vmlld3BvcnQueSwgdGhpcy5jdXJyZW50Vmlld3BvcnQud2lkdGgsIHRoaXMuY3VycmVudFZpZXdwb3J0LmhlaWdodCwgQ29sb3IuR1JFRU4pO1xuXHRcdFx0XHRcdHJlbmRlcmVyLnJlY3QoZmFsc2UsIHZpZXdwb3J0LngsIHZpZXdwb3J0LnksIHZpZXdwb3J0LndpZHRoLCB2aWV3cG9ydC5oZWlnaHQsIENvbG9yLlJFRCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZW5kZXJlci5lbmQoKTtcblxuXHRcdFx0XHRpZiAoY29uZmlnLmRyYXcpIGNvbmZpZy5kcmF3KHRoaXMsIHBsYXlEZWx0YSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIERyYXcgdGhlIGxvYWRpbmcgc2NyZWVuLlxuXHRcdFx0aWYgKGNvbmZpZy5zaG93TG9hZGluZykge1xuXHRcdFx0XHR0aGlzLmxvYWRpbmdTY3JlZW4hLmJhY2tncm91bmRDb2xvci5zZXRGcm9tQ29sb3IoYmcpO1xuXHRcdFx0XHR0aGlzLmxvYWRpbmdTY3JlZW4hLmRyYXcoIWxvYWRpbmcpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKGxvYWRpbmcgJiYgY29uZmlnLmxvYWRpbmcpIGNvbmZpZy5sb2FkaW5nKHRoaXMsIGRlbHRhKTtcblx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHR0aGlzLnNob3dFcnJvcihgRXJyb3I6IFVuYWJsZSB0byByZW5kZXIgc2tlbGV0b24uXFxuJHsoZSBhcyBhbnkpLm1lc3NhZ2V9YCwgZSBhcyBhbnkpO1xuXHRcdH1cblx0fVxuXG5cdHN0YXJ0UmVuZGVyaW5nICgpIHtcblx0XHR0aGlzLnN0b3BSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPSBmYWxzZTtcblx0XHRyZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gdGhpcy5kcmF3RnJhbWUoKSk7XG5cdH1cblxuXHRzdG9wUmVuZGVyaW5nICgpIHtcblx0XHR0aGlzLnN0b3BSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPSB0cnVlO1xuXHR9XG5cblx0cHJpdmF0ZSBoaWRlUG9wdXAgKGlkOiBzdHJpbmcpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5wb3B1cCAhPSBudWxsICYmIHRoaXMucG9wdXAuaGlkZShpZCk7XG5cdH1cblxuXHRwcml2YXRlIHNob3dTcGVlZERpYWxvZyAoc3BlZWRCdXR0b246IEhUTUxFbGVtZW50KSB7XG5cdFx0Y29uc3QgaWQgPSBcInNwZWVkXCI7XG5cdFx0aWYgKHRoaXMuaGlkZVBvcHVwKGlkKSkgcmV0dXJuO1xuXG5cdFx0Y29uc3QgcG9wdXAgPSBuZXcgUG9wdXAoaWQsIHNwZWVkQnV0dG9uLCB0aGlzLCB0aGlzLnBsYXllckNvbnRyb2xzISwgLypodG1sKi9gXG48ZGl2IGNsYXNzPVwic3BpbmUtcGxheWVyLXBvcHVwLXRpdGxlXCI+U3BlZWQ8L2Rpdj5cbjxocj5cbjxkaXYgY2xhc3M9XCJzcGluZS1wbGF5ZXItcm93XCIgc3R5bGU9XCJhbGlnbi1pdGVtczpjZW50ZXI7cGFkZGluZzo4cHhcIj5cbjxkaXYgY2xhc3M9XCJzcGluZS1wbGF5ZXItY29sdW1uXCI+XG5cdDxkaXYgY2xhc3M9XCJzcGluZS1wbGF5ZXItc3BlZWQtc2xpZGVyXCIgc3R5bGU9XCJtYXJnaW4tYm90dG9tOjRweFwiPjwvZGl2PlxuXHQ8ZGl2IGNsYXNzPVwic3BpbmUtcGxheWVyLXJvd1wiIHN0eWxlPVwianVzdGlmeS1jb250ZW50OnNwYWNlLWJldHdlZW5cIj48ZGl2PjAuMXg8L2Rpdj48ZGl2PjF4PC9kaXY+PGRpdj4yeDwvZGl2PjwvZGl2PlxuPC9kaXY+XG48L2Rpdj5gKTtcblx0XHRjb25zdCBzbGlkZXIgPSBuZXcgU2xpZGVyKDIsIDAuMSwgdHJ1ZSk7XG5cdFx0ZmluZFdpdGhDbGFzcyhwb3B1cC5kb20sIFwic3BpbmUtcGxheWVyLXNwZWVkLXNsaWRlclwiKS5hcHBlbmRDaGlsZChzbGlkZXIuY3JlYXRlKCkpO1xuXHRcdHNsaWRlci5zZXRWYWx1ZSh0aGlzLnNwZWVkIC8gMik7XG5cdFx0c2xpZGVyLmNoYW5nZSA9IChwZXJjZW50YWdlKSA9PiB0aGlzLnNwZWVkID0gcGVyY2VudGFnZSAqIDI7XG5cdFx0cG9wdXAuc2hvdygpO1xuXHR9XG5cblx0cHJpdmF0ZSBzaG93QW5pbWF0aW9uc0RpYWxvZyAoYW5pbWF0aW9uc0J1dHRvbjogSFRNTEVsZW1lbnQpIHtcblx0XHRjb25zdCBpZCA9IFwiYW5pbWF0aW9uc1wiO1xuXHRcdGlmICh0aGlzLmhpZGVQb3B1cChpZCkpIHJldHVybjtcblx0XHRpZiAoIXRoaXMuc2tlbGV0b24gfHwgIXRoaXMuc2tlbGV0b24uZGF0YS5hbmltYXRpb25zLmxlbmd0aCkgcmV0dXJuO1xuXG5cdFx0Y29uc3QgcG9wdXAgPSBuZXcgUG9wdXAoaWQsIGFuaW1hdGlvbnNCdXR0b24sIHRoaXMsIHRoaXMucGxheWVyQ29udHJvbHMhLFxuXHRcdFx0XHQvKmh0bWwqL2A8ZGl2IGNsYXNzPVwic3BpbmUtcGxheWVyLXBvcHVwLXRpdGxlXCI+QW5pbWF0aW9uczwvZGl2Pjxocj48dWwgY2xhc3M9XCJzcGluZS1wbGF5ZXItbGlzdFwiPjwvdWw+YCk7XG5cblx0XHRjb25zdCByb3dzID0gZmluZFdpdGhDbGFzcyhwb3B1cC5kb20sIFwic3BpbmUtcGxheWVyLWxpc3RcIik7XG5cdFx0dGhpcy5za2VsZXRvbi5kYXRhLmFuaW1hdGlvbnMuZm9yRWFjaCgoYW5pbWF0aW9uKSA9PiB7XG5cdFx0XHQvLyBTa2lwIGFuaW1hdGlvbnMgbm90IHdoaXRlbGlzdGVkIGlmIGEgd2hpdGVsaXN0IHdhcyBnaXZlbi5cblx0XHRcdGlmICh0aGlzLmNvbmZpZy5hbmltYXRpb25zICYmIHRoaXMuY29uZmlnLmFuaW1hdGlvbnMuaW5kZXhPZihhbmltYXRpb24ubmFtZSkgPCAwKSByZXR1cm47XG5cblx0XHRcdGNvbnN0IHJvdyA9IGNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRcdFx0LypodG1sKi9gPGxpIGNsYXNzPVwic3BpbmUtcGxheWVyLWxpc3QtaXRlbSBzZWxlY3RhYmxlXCI+PGRpdiBjbGFzcz1cInNlbGVjdGFibGUtY2lyY2xlXCI+PC9kaXY+PGRpdiBjbGFzcz1cInNlbGVjdGFibGUtdGV4dFwiPjwvZGl2PjwvbGk+YCk7XG5cdFx0XHRpZiAoYW5pbWF0aW9uLm5hbWUgPT09IHRoaXMuY29uZmlnLmFuaW1hdGlvbikgcm93LmNsYXNzTGlzdC5hZGQoXCJzZWxlY3RlZFwiKTtcblx0XHRcdGZpbmRXaXRoQ2xhc3Mocm93LCBcInNlbGVjdGFibGUtdGV4dFwiKS5pbm5lclRleHQgPSBhbmltYXRpb24ubmFtZTtcblx0XHRcdHJvd3MuYXBwZW5kQ2hpbGQocm93KTtcblx0XHRcdHJvdy5vbmNsaWNrID0gKCkgPT4ge1xuXHRcdFx0XHRyZW1vdmVDbGFzcyhyb3dzLmNoaWxkcmVuLCBcInNlbGVjdGVkXCIpO1xuXHRcdFx0XHRyb3cuY2xhc3NMaXN0LmFkZChcInNlbGVjdGVkXCIpO1xuXHRcdFx0XHR0aGlzLmNvbmZpZy5hbmltYXRpb24gPSBhbmltYXRpb24ubmFtZTtcblx0XHRcdFx0dGhpcy5wbGF5VGltZSA9IDA7XG5cdFx0XHRcdHRoaXMuc2V0QW5pbWF0aW9uKGFuaW1hdGlvbi5uYW1lKTtcblx0XHRcdFx0dGhpcy5wbGF5KCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0cG9wdXAuc2hvdygpO1xuXHR9XG5cblx0cHJpdmF0ZSBhcHBseUNvbWJpbmVkU2tpbiAoKSB7XG5cdFx0aWYgKCF0aGlzLnNrZWxldG9uKSByZXR1cm47XG5cdFx0aWYgKHRoaXMucGlubmVkU2tpbnMuc2l6ZSA9PT0gMCkge1xuXHRcdFx0dGhpcy5za2VsZXRvbi5zZXRTa2luKHRoaXMuc2tlbGV0b24uZGF0YS5kZWZhdWx0U2tpbiEpO1xuXHRcdH0gZWxzZSBpZiAodGhpcy5waW5uZWRTa2lucy5zaXplID09PSAxKSB7XG5cdFx0XHR0aGlzLnNrZWxldG9uLnNldFNraW4odGhpcy5waW5uZWRTa2lucy52YWx1ZXMoKS5uZXh0KCkudmFsdWUhKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y29uc3QgY29tYmluZWQgPSBuZXcgU2tpbihcImNvbWJpbmVkXCIpO1xuXHRcdFx0Zm9yIChjb25zdCBuYW1lIG9mIHRoaXMucGlubmVkU2tpbnMpIHtcblx0XHRcdFx0Y29uc3Qgc2tpbiA9IHRoaXMuc2tlbGV0b24uZGF0YS5maW5kU2tpbihuYW1lKTtcblx0XHRcdFx0aWYgKHNraW4pIGNvbWJpbmVkLmFkZFNraW4oc2tpbik7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnNrZWxldG9uLnNldFNraW4oY29tYmluZWQpO1xuXHRcdH1cblx0XHR0aGlzLnNrZWxldG9uLnNldHVwUG9zZVNsb3RzKCk7XG5cdFx0dGhpcy5za2VsZXRvbi51cGRhdGVXb3JsZFRyYW5zZm9ybShQaHlzaWNzLnBvc2UpO1xuXG5cdFx0Ly8gUmVjYWxjdWxhdGUgdGhlIHZpZXdwb3J0IGZvciB0aGUgY3VycmVudCBhbmltYXRpb24gc2luY2Ugc2tpbiBjaGFuZ2VzIGFmZmVjdCBib3VuZHMuXG5cdFx0Y29uc3QgZW50cnkgPSB0aGlzLmFuaW1hdGlvblN0YXRlPy5nZXRUcmFjaygwKTtcblx0XHRpZiAoZW50cnkgJiYgZW50cnkuYW5pbWF0aW9uKSB0aGlzLnNldFZpZXdwb3J0KGVudHJ5LmFuaW1hdGlvbik7XG5cdH1cblxuXHRwcml2YXRlIHNob3dTa2luc0RpYWxvZyAoc2tpbkJ1dHRvbjogSFRNTEVsZW1lbnQpIHtcblx0XHRjb25zdCBpZCA9IFwic2tpbnNcIjtcblx0XHRpZiAodGhpcy5oaWRlUG9wdXAoaWQpKSByZXR1cm47XG5cdFx0aWYgKCF0aGlzLnNrZWxldG9uIHx8ICF0aGlzLnNrZWxldG9uLmRhdGEuc2tpbnMubGVuZ3RoKSByZXR1cm47XG5cblx0XHRjb25zdCBwb3B1cCA9IG5ldyBQb3B1cChpZCwgc2tpbkJ1dHRvbiwgdGhpcywgdGhpcy5wbGF5ZXJDb250cm9scyEsXG5cdFx0XHRcdC8qaHRtbCovYDxkaXYgY2xhc3M9XCJzcGluZS1wbGF5ZXItcG9wdXAtdGl0bGVcIj5Ta2luczwvZGl2Pjxocj48dWwgY2xhc3M9XCJzcGluZS1wbGF5ZXItbGlzdFwiPjwvdWw+YCk7XG5cblx0XHRjb25zdCByb3dzID0gZmluZFdpdGhDbGFzcyhwb3B1cC5kb20sIFwic3BpbmUtcGxheWVyLWxpc3RcIik7XG5cdFx0dGhpcy5za2VsZXRvbi5kYXRhLnNraW5zLmZvckVhY2goKHNraW4pID0+IHtcblx0XHRcdGlmIChza2luID09PSB0aGlzLnNrZWxldG9uIS5kYXRhLmRlZmF1bHRTa2luKSByZXR1cm47XG5cdFx0XHQvLyBTa2lwIHNraW5zIG5vdCB3aGl0ZWxpc3RlZCBpZiBhIHdoaXRlbGlzdCB3YXMgZ2l2ZW4uXG5cdFx0XHRpZiAodGhpcy5jb25maWcuc2tpbnMgJiYgdGhpcy5jb25maWcuc2tpbnMuaW5kZXhPZihza2luLm5hbWUpIDwgMCkgcmV0dXJuO1xuXG5cdFx0XHRjb25zdCByb3cgPSBjcmVhdGVFbGVtZW50KC8qaHRtbCovYDxsaSBjbGFzcz1cInNwaW5lLXBsYXllci1saXN0LWl0ZW0gc2VsZWN0YWJsZVwiPjxkaXYgY2xhc3M9XCJzZWxlY3RhYmxlLXBpblwiPjwvZGl2PjxkaXYgY2xhc3M9XCJzZWxlY3RhYmxlLXRleHRcIj48L2Rpdj48L2xpPmApO1xuXHRcdFx0aWYgKHRoaXMucGlubmVkU2tpbnMuaGFzKHNraW4ubmFtZSkpIHJvdy5jbGFzc0xpc3QuYWRkKFwicGlubmVkXCIpO1xuXHRcdFx0Y29uc3QgcGluRWxlbWVudCA9IGZpbmRXaXRoQ2xhc3Mocm93LCBcInNlbGVjdGFibGUtcGluXCIpO1xuXHRcdFx0Y29uc3QgdGV4dEVsZW1lbnQgPSBmaW5kV2l0aENsYXNzKHJvdywgXCJzZWxlY3RhYmxlLXRleHRcIik7XG5cdFx0XHR0ZXh0RWxlbWVudC5pbm5lclRleHQgPSBza2luLm5hbWU7XG5cdFx0XHRyb3dzLmFwcGVuZENoaWxkKHJvdyk7XG5cdFx0XHRwaW5FbGVtZW50Lm9uY2xpY2sgPSAoZSkgPT4ge1xuXHRcdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHRpZiAodGhpcy5waW5uZWRTa2lucy5oYXMoc2tpbi5uYW1lKSkge1xuXHRcdFx0XHRcdHRoaXMucGlubmVkU2tpbnMuZGVsZXRlKHNraW4ubmFtZSk7XG5cdFx0XHRcdFx0cm93LmNsYXNzTGlzdC5yZW1vdmUoXCJwaW5uZWRcIik7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGhpcy5waW5uZWRTa2lucy5hZGQoc2tpbi5uYW1lKTtcblx0XHRcdFx0XHRyb3cuY2xhc3NMaXN0LmFkZChcInBpbm5lZFwiKTtcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLmFwcGx5Q29tYmluZWRTa2luKCk7XG5cdFx0XHR9O1xuXHRcdFx0cm93Lm9uY2xpY2sgPSAoKSA9PiB7XG5cdFx0XHRcdHRoaXMucGlubmVkU2tpbnMuY2xlYXIoKTtcblx0XHRcdFx0dGhpcy5waW5uZWRTa2lucy5hZGQoc2tpbi5uYW1lKTtcblx0XHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCByb3dzLmNoaWxkcmVuLmxlbmd0aDsgaSsrKVxuXHRcdFx0XHRcdHJvd3MuY2hpbGRyZW5baV0uY2xhc3NMaXN0LnJlbW92ZShcInBpbm5lZFwiKTtcblx0XHRcdFx0cm93LmNsYXNzTGlzdC5hZGQoXCJwaW5uZWRcIik7XG5cdFx0XHRcdHRoaXMuYXBwbHlDb21iaW5lZFNraW4oKTtcblx0XHRcdH07XG5cdFx0fSk7XG5cdFx0cG9wdXAuc2hvdygpO1xuXHR9XG5cblx0cHJpdmF0ZSBzaG93U2V0dGluZ3NEaWFsb2cgKHNldHRpbmdzQnV0dG9uOiBIVE1MRWxlbWVudCkge1xuXHRcdGNvbnN0IGlkID0gXCJzZXR0aW5nc1wiO1xuXHRcdGlmICh0aGlzLmhpZGVQb3B1cChpZCkpIHJldHVybjtcblx0XHRpZiAoIXRoaXMuc2tlbGV0b24gfHwgIXRoaXMuc2tlbGV0b24uZGF0YS5hbmltYXRpb25zLmxlbmd0aCkgcmV0dXJuO1xuXG5cdFx0Y29uc3QgcG9wdXAgPSBuZXcgUG9wdXAoaWQsIHNldHRpbmdzQnV0dG9uLCB0aGlzLCB0aGlzLnBsYXllckNvbnRyb2xzISwgLypodG1sKi9gPGRpdiBjbGFzcz1cInNwaW5lLXBsYXllci1wb3B1cC10aXRsZVwiPkRlYnVnPC9kaXY+PGhyPjx1bCBjbGFzcz1cInNwaW5lLXBsYXllci1saXN0XCI+PC91bD5gKTtcblxuXHRcdGNvbnN0IHJvd3MgPSBmaW5kV2l0aENsYXNzKHBvcHVwLmRvbSwgXCJzcGluZS1wbGF5ZXItbGlzdFwiKTtcblx0XHRjb25zdCBtYWtlSXRlbSA9IChsYWJlbDogc3RyaW5nLCBuYW1lOiBzdHJpbmcpID0+IHtcblx0XHRcdGNvbnN0IHJvdyA9IGNyZWF0ZUVsZW1lbnQoLypodG1sKi9gPGxpIGNsYXNzPVwic3BpbmUtcGxheWVyLWxpc3QtaXRlbVwiPjwvbGk+YCk7XG5cdFx0XHRjb25zdCBzID0gbmV3IFN3aXRjaChsYWJlbCk7XG5cdFx0XHRyb3cuYXBwZW5kQ2hpbGQocy5jcmVhdGUoKSk7XG5cdFx0XHRjb25zdCBkZWJ1ZyA9IHRoaXMuY29uZmlnLmRlYnVnIGFzIGFueTtcblx0XHRcdHMuc2V0RW5hYmxlZChkZWJ1Z1tuYW1lXSk7XG5cdFx0XHRzLmNoYW5nZSA9ICh2YWx1ZSkgPT4gZGVidWdbbmFtZV0gPSB2YWx1ZTtcblx0XHRcdHJvd3MuYXBwZW5kQ2hpbGQocm93KTtcblx0XHR9O1xuXHRcdG1ha2VJdGVtKFwiQm9uZXNcIiwgXCJib25lc1wiKTtcblx0XHRtYWtlSXRlbShcIlJlZ2lvbnNcIiwgXCJyZWdpb25zXCIpO1xuXHRcdG1ha2VJdGVtKFwiTWVzaGVzXCIsIFwibWVzaGVzXCIpO1xuXHRcdG1ha2VJdGVtKFwiQm91bmRzXCIsIFwiYm91bmRzXCIpO1xuXHRcdG1ha2VJdGVtKFwiUGF0aHNcIiwgXCJwYXRoc1wiKTtcblx0XHRtYWtlSXRlbShcIkNsaXBwaW5nXCIsIFwiY2xpcHBpbmdcIik7XG5cdFx0bWFrZUl0ZW0oXCJQb2ludHNcIiwgXCJwb2ludHNcIik7XG5cdFx0bWFrZUl0ZW0oXCJIdWxsc1wiLCBcImh1bGxzXCIpO1xuXHRcdHBvcHVwLnNob3coKTtcblx0fVxuXG5cdHByaXZhdGUgc2hvd0Vycm9yIChtZXNzYWdlOiBzdHJpbmcsIGVycm9yPzogRXJyb3IpIHtcblx0XHRpZiAodGhpcy5lcnJvcikge1xuXHRcdFx0aWYgKGVycm9yKSB0aHJvdyBlcnJvcjsgLy8gRG9uJ3QgbG9zZSBlcnJvciBpZiBzaG93RXJyb3IgdGhyb3dzLCBpcyBjYXVnaHQsIGFuZCBzaG93RXJyb3IgaXMgY2FsbGVkIGFnYWluLlxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLmVycm9yID0gdHJ1ZTtcblx0XHRcdHRoaXMuZG9tLmFwcGVuZENoaWxkKGNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRcdFx0LypodG1sKi9gPGRpdiBjbGFzcz1cInNwaW5lLXBsYXllci1lcnJvclwiIHN0eWxlPVwiYmFja2dyb3VuZDojMDAwO2NvbG9yOiNmZmY7cG9zaXRpb246YWJzb2x1dGU7dG9wOjA7d2lkdGg6MTAwJTtoZWlnaHQ6MTAwJTtkaXNwbGF5OmZsZXg7anVzdGlmeS1jb250ZW50OmNlbnRlcjthbGlnbi1pdGVtczpjZW50ZXI7b3ZlcmZsb3c6YXV0bzt6LWluZGV4Ojk5OVwiPmBcblx0XHRcdFx0KyBtZXNzYWdlLnJlcGxhY2UoXCJcXG5cIiwgXCI8YnI+PGJyPlwiKSArIGA8L2Rpdj5gKSk7XG5cdFx0XHRpZiAodGhpcy5jb25maWcuZXJyb3IpIHRoaXMuY29uZmlnLmVycm9yKHRoaXMsIG1lc3NhZ2UpO1xuXHRcdFx0dGhyb3cgKGVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IobWVzc2FnZSkpO1xuXHRcdH1cblx0fVxufVxuXG5jbGFzcyBQb3B1cCB7XG5cdHB1YmxpYyBkb206IEhUTUxFbGVtZW50O1xuXHRwcml2YXRlIGNsYXNzTmFtZTogc3RyaW5nO1xuXG5cdGNvbnN0cnVjdG9yIChwcml2YXRlIGlkOiBzdHJpbmcsIHByaXZhdGUgYnV0dG9uOiBIVE1MRWxlbWVudCwgcHJpdmF0ZSBwbGF5ZXI6IFNwaW5lUGxheWVyLCBwcml2YXRlIHBhcmVudDogSFRNTEVsZW1lbnQsIGh0bWxDb250ZW50OiBzdHJpbmcpIHtcblx0XHR0aGlzLmRvbSA9IGNyZWF0ZUVsZW1lbnQoLypodG1sKi9gPGRpdiBjbGFzcz1cInNwaW5lLXBsYXllci1wb3B1cCBzcGluZS1wbGF5ZXItaGlkZGVuXCI+PC9kaXY+YCk7XG5cdFx0dGhpcy5kb20uaW5uZXJIVE1MID0gaHRtbENvbnRlbnQ7XG5cdFx0cGFyZW50LmFwcGVuZENoaWxkKHRoaXMuZG9tKTtcblx0XHR0aGlzLmNsYXNzTmFtZSA9IGBzcGluZS1wbGF5ZXItYnV0dG9uLWljb24tJHtpZH0tc2VsZWN0ZWRgO1xuXHR9XG5cblx0ZGlzcG9zZSAoKSB7XG5cblx0fVxuXG5cdGhpZGUgKGlkOiBzdHJpbmcpOiBib29sZWFuIHtcblx0XHR0aGlzLmRvbS5yZW1vdmUoKTtcblx0XHR0aGlzLmJ1dHRvbi5jbGFzc0xpc3QucmVtb3ZlKHRoaXMuY2xhc3NOYW1lKTtcblx0XHRpZiAodGhpcy5pZCA9PT0gaWQpIHtcblx0XHRcdHRoaXMucGxheWVyLnBvcHVwID0gbnVsbDtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRzaG93ICgpIHtcblx0XHR0aGlzLnBsYXllci5wb3B1cCA9IHRoaXM7XG5cdFx0dGhpcy5idXR0b24uY2xhc3NMaXN0LmFkZCh0aGlzLmNsYXNzTmFtZSk7XG5cdFx0dGhpcy5kb20uY2xhc3NMaXN0LnJlbW92ZShcInNwaW5lLXBsYXllci1oaWRkZW5cIik7XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhlIHBvcHVwIGlzbid0IGJpZ2dlciB0aGFuIHRoZSBwbGF5ZXIuXG5cdFx0bGV0IGRpc21pc3NlZCA9IGZhbHNlO1xuXHRcdGNvbnN0IHJlc2l6ZSA9ICgpID0+IHtcblx0XHRcdGlmICghZGlzbWlzc2VkKSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUocmVzaXplKTtcblx0XHRcdHRoaXMuZG9tLnN0eWxlLm1heEhlaWdodCA9IGAke3RoaXMucGxheWVyLmRvbS5jbGllbnRIZWlnaHQgLSB0aGlzLnBhcmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHR9cHhgO1xuXHRcdH1cblx0XHRyZXF1ZXN0QW5pbWF0aW9uRnJhbWUocmVzaXplKTtcblxuXHRcdC8vIERpc21pc3Mgd2hlbiBjbGlja2luZyBzb21ld2hlcmUgb3V0c2lkZSB0aGUgcG9wdXAuXG5cdFx0bGV0IGp1c3RDbGlja2VkID0gdHJ1ZTtcblx0XHRjb25zdCB3aW5kb3dDbGlja0xpc3RlbmVyID0gKGV2ZW50OiBhbnkpID0+IHtcblx0XHRcdGlmIChqdXN0Q2xpY2tlZCB8fCB0aGlzLnBsYXllci5wb3B1cCAhPT0gdGhpcykge1xuXHRcdFx0XHRqdXN0Q2xpY2tlZCA9IGZhbHNlO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHRpZiAoIXRoaXMuZG9tLmNvbnRhaW5zKGV2ZW50LnRhcmdldCkpIHtcblx0XHRcdFx0dGhpcy5kb20ucmVtb3ZlKCk7XG5cdFx0XHRcdHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgd2luZG93Q2xpY2tMaXN0ZW5lcik7XG5cdFx0XHRcdHRoaXMuYnV0dG9uLmNsYXNzTGlzdC5yZW1vdmUodGhpcy5jbGFzc05hbWUpO1xuXHRcdFx0XHR0aGlzLnBsYXllci5wb3B1cCA9IG51bGw7XG5cdFx0XHRcdGRpc21pc3NlZCA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fTtcblx0XHR0aGlzLnBsYXllci5hZGRFdmVudExpc3RlbmVyKHdpbmRvdywgXCJjbGlja1wiLCB3aW5kb3dDbGlja0xpc3RlbmVyKTtcblx0fVxufVxuXG5jbGFzcyBTd2l0Y2gge1xuXHRwcml2YXRlIHN3aXRjaDogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcblx0cHJpdmF0ZSBlbmFibGVkID0gZmFsc2U7XG5cdHB1YmxpYyBjaGFuZ2U6ICh2YWx1ZTogYm9vbGVhbikgPT4gdm9pZCA9ICgpID0+IHsgfTtcblxuXHRjb25zdHJ1Y3RvciAocHJpdmF0ZSB0ZXh0OiBzdHJpbmcpIHsgfVxuXG5cblx0Y3JlYXRlICgpOiBIVE1MRWxlbWVudCB7XG5cdFx0dGhpcy5zd2l0Y2ggPSBjcmVhdGVFbGVtZW50KC8qaHRtbCovYFxuPGRpdiBjbGFzcz1cInNwaW5lLXBsYXllci1zd2l0Y2hcIj5cblx0PHNwYW4gY2xhc3M9XCJzcGluZS1wbGF5ZXItc3dpdGNoLXRleHRcIj4ke3RoaXMudGV4dH08L3NwYW4+XG5cdDxkaXYgY2xhc3M9XCJzcGluZS1wbGF5ZXItc3dpdGNoLWtub2ItYXJlYVwiPlxuXHRcdDxkaXYgY2xhc3M9XCJzcGluZS1wbGF5ZXItc3dpdGNoLWtub2JcIj48L2Rpdj5cblx0PC9kaXY+XG48L2Rpdj5gKTtcblx0XHR0aGlzLnN3aXRjaC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKCkgPT4ge1xuXHRcdFx0dGhpcy5zZXRFbmFibGVkKCF0aGlzLmVuYWJsZWQpO1xuXHRcdFx0aWYgKHRoaXMuY2hhbmdlKSB0aGlzLmNoYW5nZSh0aGlzLmVuYWJsZWQpO1xuXHRcdH0pXG5cdFx0cmV0dXJuIHRoaXMuc3dpdGNoO1xuXHR9XG5cblx0c2V0RW5hYmxlZCAoZW5hYmxlZDogYm9vbGVhbikge1xuXHRcdGlmIChlbmFibGVkKSB0aGlzLnN3aXRjaD8uY2xhc3NMaXN0LmFkZChcImFjdGl2ZVwiKTtcblx0XHRlbHNlIHRoaXMuc3dpdGNoPy5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpO1xuXHRcdHRoaXMuZW5hYmxlZCA9IGVuYWJsZWQ7XG5cdH1cblxuXHRpc0VuYWJsZWQgKCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiB0aGlzLmVuYWJsZWQ7XG5cdH1cbn1cblxuY2xhc3MgU2xpZGVyIHtcblx0cHJpdmF0ZSBzbGlkZXI6IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XG5cdHByaXZhdGUgdmFsdWU6IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XG5cdHByaXZhdGUga25vYjogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcblx0cHVibGljIGNoYW5nZTogKHBlcmNlbnRhZ2U6IG51bWJlcikgPT4gdm9pZCA9ICgpID0+IHsgfTtcblxuXHRjb25zdHJ1Y3RvciAocHVibGljIHNuYXBzID0gMCwgcHVibGljIHNuYXBQZXJjZW50YWdlID0gMC4xLCBwdWJsaWMgYmlnID0gZmFsc2UpIHsgfVxuXG5cdGNyZWF0ZSAoKTogSFRNTEVsZW1lbnQge1xuXHRcdHRoaXMuc2xpZGVyID0gY3JlYXRlRWxlbWVudCgvKmh0bWwqL2BcbjxkaXYgY2xhc3M9XCJzcGluZS1wbGF5ZXItc2xpZGVyICR7dGhpcy5iaWcgPyBcImJpZ1wiIDogXCJcIn1cIj5cblx0PGRpdiBjbGFzcz1cInNwaW5lLXBsYXllci1zbGlkZXItdmFsdWVcIj48L2Rpdj5cblx0PCEtLTxkaXYgY2xhc3M9XCJzcGluZS1wbGF5ZXItc2xpZGVyLWtub2JcIj48L2Rpdj4tLT5cbjwvZGl2PmApO1xuXHRcdHRoaXMudmFsdWUgPSBmaW5kV2l0aENsYXNzKHRoaXMuc2xpZGVyLCBcInNwaW5lLXBsYXllci1zbGlkZXItdmFsdWVcIik7XG5cdFx0Ly8gdGhpcy5rbm9iID0gZmluZFdpdGhDbGFzcyh0aGlzLnNsaWRlciwgXCJzcGluZS1wbGF5ZXItc2xpZGVyLWtub2JcIik7XG5cdFx0dGhpcy5zZXRWYWx1ZSgwKTtcblxuXHRcdGxldCByZWN0OiBET01SZWN0O1xuXG5cdFx0Y29uc3QgdXBkYXRlID0gKGV2OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCkgPT4ge1xuXHRcdFx0Y29uc3QgY2xpZW50WCA9IGV2IGluc3RhbmNlb2YgTW91c2VFdmVudCA/IGV2LmNsaWVudFggOiBldi5jaGFuZ2VkVG91Y2hlc1swXS5jbGllbnRYO1xuXHRcdFx0aWYgKHRoaXMuY2hhbmdlKSB0aGlzLmNoYW5nZSh0aGlzLnNldFZhbHVlKChjbGllbnRYIC0gcmVjdC5sZWZ0KSAvIHJlY3Qud2lkdGgpKTtcblx0XHR9O1xuXG5cdFx0Y29uc3Qgb25FbmQgPSAoZXY6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KSA9PiB7XG5cdFx0XHR1cGRhdGUoZXYpO1xuXHRcdFx0dGhpcy52YWx1ZT8uY2xhc3NMaXN0LnJlbW92ZShcImhvdmVyaW5nXCIpO1xuXHRcdFx0dGhpcy5zbGlkZXI/LnBhcmVudEVsZW1lbnQ/LmNsYXNzTGlzdC5yZW1vdmUoXCJkcmFnZ2luZ1wiKTtcblx0XHRcdGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgdXBkYXRlLCB0cnVlKTtcblx0XHRcdGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIG9uRW5kLCB0cnVlKTtcblx0XHRcdGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgdXBkYXRlLCB0cnVlKTtcblx0XHRcdGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLCBvbkVuZCwgdHJ1ZSk7XG5cdFx0fTtcblxuXHRcdGNvbnN0IG9uU3RhcnQgPSAoZXY6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KSA9PiB7XG5cdFx0XHRyZWN0ID0gdGhpcy5zbGlkZXIhLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHRcdFx0dGhpcy52YWx1ZT8uY2xhc3NMaXN0LmFkZChcImhvdmVyaW5nXCIpO1xuXHRcdFx0dGhpcy5zbGlkZXI/LnBhcmVudEVsZW1lbnQ/LmNsYXNzTGlzdC5hZGQoXCJkcmFnZ2luZ1wiKTtcblx0XHRcdHVwZGF0ZShldik7XG5cdFx0XHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsIHVwZGF0ZSwgdHJ1ZSk7XG5cdFx0XHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCBvbkVuZCwgdHJ1ZSk7XG5cdFx0XHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsIHVwZGF0ZSwgdHJ1ZSk7XG5cdFx0XHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgb25FbmQsIHRydWUpO1xuXHRcdH07XG5cblx0XHR0aGlzLnNsaWRlci5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vkb3duXCIsIG9uU3RhcnQsIHRydWUpO1xuXHRcdHRoaXMuc2xpZGVyLmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsIG9uU3RhcnQsIHRydWUpO1xuXG5cdFx0cmV0dXJuIHRoaXMuc2xpZGVyO1xuXHR9XG5cblx0c2V0VmFsdWUgKHBlcmNlbnRhZ2U6IG51bWJlcik6IG51bWJlciB7XG5cdFx0cGVyY2VudGFnZSA9IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIHBlcmNlbnRhZ2UpKTtcblx0XHRpZiAodGhpcy5zbmFwcykge1xuXHRcdFx0Y29uc3Qgc25hcCA9IDEgLyB0aGlzLnNuYXBzO1xuXHRcdFx0Y29uc3QgbW9kdWxvID0gcGVyY2VudGFnZSAlIHNuYXA7XG5cdFx0XHQvLyBmbG9vclxuXHRcdFx0aWYgKG1vZHVsbyA8IHNuYXAgKiB0aGlzLnNuYXBQZXJjZW50YWdlKVxuXHRcdFx0XHRwZXJjZW50YWdlID0gcGVyY2VudGFnZSAtIG1vZHVsbztcblx0XHRcdGVsc2UgaWYgKG1vZHVsbyA+IHNuYXAgLSBzbmFwICogdGhpcy5zbmFwUGVyY2VudGFnZSlcblx0XHRcdFx0cGVyY2VudGFnZSA9IHBlcmNlbnRhZ2UgLSBtb2R1bG8gKyBzbmFwO1xuXHRcdFx0cGVyY2VudGFnZSA9IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIHBlcmNlbnRhZ2UpKTtcblx0XHR9XG5cdFx0dGhpcy52YWx1ZSEuc3R5bGUud2lkdGggPSBgJHtwZXJjZW50YWdlICogMTAwfSVgO1xuXHRcdC8vIHRoaXMua25vYi5zdHlsZS5sZWZ0ID0gXCJcIiArICgtOCArIHBlcmNlbnRhZ2UgKiB0aGlzLnNsaWRlci5jbGllbnRXaWR0aCkgKyBcInB4XCI7XG5cdFx0cmV0dXJuIHBlcmNlbnRhZ2U7XG5cdH1cbn1cblxuZnVuY3Rpb24gZmluZFdpdGhDbGFzcyAoZWxlbWVudDogSFRNTEVsZW1lbnQsIGNsYXNzTmFtZTogc3RyaW5nKTogSFRNTEVsZW1lbnQge1xuXHRyZXR1cm4gZWxlbWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKGNsYXNzTmFtZSlbMF0gYXMgSFRNTEVsZW1lbnQ7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnQgKGh0bWw6IHN0cmluZyk6IEhUTUxFbGVtZW50IHtcblx0Y29uc3QgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcblx0ZGl2LmlubmVySFRNTCA9IGh0bWw7XG5cdHJldHVybiBkaXYuY2hpbGRyZW5bMF0gYXMgSFRNTEVsZW1lbnQ7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUNsYXNzIChlbGVtZW50czogSFRNTENvbGxlY3Rpb24sIGNsYXp6OiBzdHJpbmcpIHtcblx0Zm9yIChsZXQgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKylcblx0XHRlbGVtZW50c1tpXS5jbGFzc0xpc3QucmVtb3ZlKGNsYXp6KTtcbn1cblxuZnVuY3Rpb24gcHJpbnQgKG9iamVjdDogYW55KSB7XG5cdHJldHVybiBKU09OLnN0cmluZ2lmeShvYmplY3QpXG5cdFx0LnJlcGxhY2UoLyYvZywgXCImYW1wO1wiKVxuXHRcdC5yZXBsYWNlKC88L2csIFwiJmx0O1wiKVxuXHRcdC5yZXBsYWNlKC8+L2csIFwiJmd0O1wiKVxuXHRcdC5yZXBsYWNlKC9cIi9nLCBcIiYjMzQ7XCIpXG5cdFx0LnJlcGxhY2UoLycvZywgXCImIzM5O1wiKTtcbn1cblxuY29uc3QgQk9ORV9JTk5FUl9PVkVSID0gbmV3IENvbG9yKDAuNDc4LCAwLCAwLCAwLjI1KTtcbmNvbnN0IEJPTkVfT1VURVJfT1ZFUiA9IG5ldyBDb2xvcigxLCAxLCAxLCAxKTtcbmNvbnN0IEJPTkVfSU5ORVIgPSBuZXcgQ29sb3IoMC40NzgsIDAsIDAsIDAuNSk7XG5jb25zdCBCT05FX09VVEVSID0gbmV3IENvbG9yKDEsIDAsIDAsIDAuOCk7XG4iXX0=